)info row:(int)row dropOperation:(NSTableViewDropOperation)operation
{
int originalRow;
int destinationRow;
NSMutableDictionary *draggedRow;
if ( aTableView == queryFavoritesView ) {
originalRow = [[[info draggingPasteboard] stringForType:@"SequelProPasteboard"] intValue];
destinationRow = row;
if ( destinationRow > originalRow )
destinationRow--;
draggedRow = [queryFavorites objectAtIndex:originalRow];
[queryFavorites removeObjectAtIndex:originalRow];
[queryFavorites insertObject:draggedRow atIndex:destinationRow];
[queryFavoritesView reloadData];
[queryFavoritesView selectRow:destinationRow byExtendingSelection:NO];
return YES;
} else {
return NO;
}
}
//tableView delegate methods
- (BOOL)tableView:(NSTableView *)aTableView shouldEditTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex
/*
opens sheet with value when double clicking on a field
*/
{
if ( aTableView == customQueryView ) {
NSArray *theRow;
NSString *theValue;
NSNumber *theIdentifier = [aTableColumn identifier];
//get the value
theRow = [queryResult objectAtIndex:rowIndex];
if ( [[theRow objectAtIndex:[theIdentifier intValue]] isKindOfClass:[NSData class]] ) {
theValue = [[NSString alloc] initWithData:[theRow objectAtIndex:[theIdentifier intValue]]
encoding:[mySQLConnection encoding]];
if (theValue == nil) {
theValue = [[NSString alloc] initWithData:[theRow objectAtIndex:[theIdentifier intValue]]
encoding:NSASCIIStringEncoding];
}
[theValue autorelease];
} else if ( [[theRow objectAtIndex:[theIdentifier intValue]] isMemberOfClass:[NSNull class]] ) {
theValue = [prefs objectForKey:@"NullValue"];
} else {
theValue = [theRow objectAtIndex:[theIdentifier intValue]];
}
[valueTextField setString:[theValue description]];
[valueTextField selectAll:self];
[NSApp beginSheet:valueSheet
modalForWindow:tableWindow modalDelegate:self
didEndSelector:nil contextInfo:nil];
[NSApp runModalForWindow:valueSheet];
[NSApp endSheet:valueSheet];
[valueSheet orderOut:nil];
return NO;
} else {
return YES;
}
}
#pragma mark -
#pragma mark SplitView delegate methods
- (BOOL)splitView:(NSSplitView *)sender canCollapseSubview:(NSView *)subview
/*
tells the splitView that it can collapse views
*/
{
return YES;
}
- (float)splitView:(NSSplitView *)sender constrainMaxCoordinate:(float)proposedMax ofSubviewAt:(int)offset
/*
defines max position of splitView
*/
{
if ( offset == 0 ) {
return proposedMax - 100;
} else {
return proposedMax - 73;
}
}
- (float)splitView:(NSSplitView *)sender constrainMinCoordinate:(float)proposedMin ofSubviewAt:(int)offset
/*
defines min position of splitView
*/
{
if ( offset == 0 ) {
return proposedMin + 100;
} else {
return proposedMin + 100;
}
}
#pragma mark -
#pragma mark TextView delegate methods
- (BOOL)textView:(NSTextView *)aTextView doCommandBySelector:(SEL)aSelector
/*
traps enter key and
performs query instead of inserting a line break if aTextView == textView
closes valueSheet if aTextView == valueTextField
*/
{
if ( aTextView == textView ) {
if ( [aTextView methodForSelector:aSelector] == [aTextView methodForSelector:@selector(insertNewline:)] &&
[[[NSApp currentEvent] characters] isEqualToString:@"\003"] )
{
[self runAllQueries:self];
return YES;
} else {
return NO;
}
} else if ( aTextView == valueTextField ) {
if ( [aTextView methodForSelector:aSelector] == [aTextView methodForSelector:@selector(insertNewline:)] )
{
[self closeSheet:self];
return YES;
} else {
return NO;
}
}
return NO;
}
/*
* A notification posted when the selection changes within the text view;
* used to control the run-currentrun-selection button state and action.
*/
- (void)textViewDidChangeSelection:(NSNotification *)aNotification
{
// Ensure that the notification is from the custom query text view
if ( [aNotification object] != textView ) return;
// If no text is selected, disable the button and action menu.
if ( [textView selectedRange].location == NSNotFound ) {
[runSelectionButton setEnabled:NO];
[runSelectionMenuItem setEnabled:NO];
return;
}
// If the current selection is a single caret position, update the button based on
// whether the caret is inside a valid query.
if ([textView selectedRange].length == 0) {
int selectionPosition = [textView selectedRange].location;
int movedRangeStart, movedRangeLength;
BOOL updateQueryButtons = FALSE;
NSRange oldSelection;
NSCharacterSet *whitespaceAndNewlineCharset = [NSCharacterSet whitespaceAndNewlineCharacterSet];
// Retrieve the old selection position
[[[aNotification userInfo] objectForKey:@"NSOldSelectedCharacterRange"] getValue:&oldSelection];
// Only process the query text if the selection previously had length, or moved more than 100 characters,
// or the intervening space contained a semicolon, or typing has been performed with no current query.
// This adds more checks to every keypress, but ensures the majority of the actions don't incur a
// parsing overhead - which is cheap on small text strings but heavy of large queries.
movedRangeStart = (selectionPosition < oldSelection.location)?selectionPosition:oldSelection.location;
movedRangeLength = abs(selectionPosition - oldSelection.location);
if (oldSelection.length > 0) updateQueryButtons = TRUE;
if (!updateQueryButtons && movedRangeLength > 100) updateQueryButtons = TRUE;
if (!updateQueryButtons && oldSelection.location > [[textView string] length]) updateQueryButtons = TRUE;
if (!updateQueryButtons && [[textView string] rangeOfString:@";" options:0 range:NSMakeRange(movedRangeStart, movedRangeLength)].location != NSNotFound) updateQueryButtons = TRUE;
if (!updateQueryButtons && ![runSelectionButton isEnabled] && selectionPosition > oldSelection.location
&& [[[[textView string] substringWithRange:NSMakeRange(movedRangeStart, movedRangeLength)] stringByTrimmingCharactersInSet:whitespaceAndNewlineCharset] length]) updateQueryButtons = TRUE;
if (!updateQueryButtons && [[runSelectionButton title] isEqualToString:NSLocalizedString(@"Run Current", @"Title of button to run current query in custom query view")]) {
int charPosition;
unichar theChar;
for (charPosition = selectionPosition; charPosition > 0; charPosition--) {
theChar = [[textView string] characterAtIndex:charPosition-1];
if (theChar == ';') {
updateQueryButtons = TRUE;
break;
}
if (![whitespaceAndNewlineCharset characterIsMember:theChar]) break;
}
}
if (!updateQueryButtons && [[runSelectionButton title] isEqualToString:NSLocalizedString(@"Run Previous", @"Title of button to run query just before text caret in custom query view")]) {
updateQueryButtons = TRUE;
}
if (updateQueryButtons) {
[runSelectionButton setTitle:NSLocalizedString(@"Run Current", @"Title of button to run current query in custom query view")];
[runSelectionMenuItem setTitle:NSLocalizedString(@"Run Current Query", @"Title of action menu item to run current query in custom query view")];
// If a valid query is present at the cursor position, enable the button
BOOL isLookBehind = YES;
if ([self queryAtPosition:selectionPosition lookBehind:&isLookBehind]) {
if (isLookBehind) {
[runSelectionButton setTitle:NSLocalizedString(@"Run Previous", @"Title of button to run query just before text caret in custom query view")];
[runSelectionMenuItem setTitle:NSLocalizedString(@"Run Previous Query", @"Title of action menu item to run query just before text caret in custom query view")];
}
[runSelectionButton setEnabled:YES];
[runSelectionMenuItem setEnabled:YES];
} else {
[runSelectionButton setEnabled:NO];
[runSelectionMenuItem setEnabled:NO];
}
}
// For selection ranges, enable the button.
} else {
[runSelectionButton setTitle:NSLocalizedString(@"Run Selection", @"Title of button to run selected text in custom query view")];
[runSelectionButton setEnabled:YES];
[runSelectionMenuItem setTitle:NSLocalizedString(@"Run Selected Text", @"Title of action menu item to run selected text in custom query view")];
[runSelectionMenuItem setEnabled:YES];
}
}
#pragma mark -
#pragma mark TableView notifications
/*
* Updates various interface elements based on the current table view selection.
*/
- (void)tableViewSelectionDidChange:(NSNotification *)notification
{
if ([notification object] == queryFavoritesView) {
// Enable/disable buttons
[removeQueryFavoriteButton setEnabled:([queryFavoritesView numberOfSelectedRows] == 1)];
[copyQueryFavoriteButton setEnabled:([queryFavoritesView numberOfSelectedRows] == 1)];
}
}
/*
* Save the custom query editor font if it is changed.
*/
- (void)textViewDidChangeTypingAttributes:(NSNotification *)aNotification
{
// Only save the font if prefs have been loaded, ensuring the saved font has been applied once.
if (prefs)
[prefs setObject:[NSArchiver archivedDataWithRootObject:[textView font]] forKey:@"CustomQueryEditorFont"];
}
#pragma mark -
#pragma mark MySQL Help
/*
* Set the MySQL version as X.Y for Help window title and online search
*/
- (void)setMySQLversion:(NSString *)theVersion
{
mySQLversion = [[theVersion substringToIndex:3] retain];
}
/*
* Return the Help window.
*/
- (NSWindow *)helpWebViewWindow
{
return helpWebViewWindow;
}
/*
* Show the data for "HELP 'searchString'".
*/
- (void)showHelpFor:(NSString *)searchString addToHistory:(BOOL)addToHistory
{
NSString * helpString = [self getHTMLformattedMySQLHelpFor:searchString];
// Order out resp. init the Help window if not visible
if(![helpWebViewWindow isVisible])
{
// set title of the Help window
[helpWebViewWindow setTitle:[NSString stringWithFormat:@"%@ (%@ %@)", NSLocalizedString(@"MySQL Help", @"mysql help"), NSLocalizedString(@"version", @"version"), mySQLversion]];
// init goback/forward buttons
if([[helpWebView backForwardList] backListCount] < 1)
{
[helpNavigator setEnabled:NO forSegment:SP_HELP_GOBACK_BUTTON];
[helpNavigator setEnabled:NO forSegment:SP_HELP_GOFORWARD_BUTTON];
} else {
[helpNavigator setEnabled:[[helpWebView backForwardList] backListCount] forSegment:SP_HELP_GOBACK_BUTTON];
[helpNavigator setEnabled:[[helpWebView backForwardList] forwardListCount] forSegment:SP_HELP_GOFORWARD_BUTTON];
}
// set default to search in MySQL help
helpTarget = SP_HELP_SEARCH_IN_MYSQL;
[helpTargetSelector setSelectedSegment:SP_HELP_SEARCH_IN_MYSQL];
[self helpTargetValidation];
// order out Help window if Help is available
if(![helpString isEqualToString:SP_HELP_NOT_AVAILABLE])
[helpWebViewWindow orderFront:helpWebView];
}
// close Help window if no Help avaiable
if([helpString isEqualToString:SP_HELP_NOT_AVAILABLE])
[helpWebViewWindow close];
if(![helpString length]) return;
// add searchString to history list
if(addToHistory)
{
WebHistoryItem *aWebHistoryItem = [[WebHistoryItem alloc] initWithURLString:[NSString stringWithFormat:@"applewebdata://%@", searchString] title:searchString lastVisitedTimeInterval:[[NSDate date] timeIntervalSinceDate:[NSDate distantFuture]]];
[[helpWebView backForwardList] addItem:aWebHistoryItem];
}
// validate goback/forward buttons
[helpNavigator setEnabled:[[helpWebView backForwardList] backListCount] forSegment:SP_HELP_GOBACK_BUTTON];
[helpNavigator setEnabled:[[helpWebView backForwardList] forwardListCount] forSegment:SP_HELP_GOFORWARD_BUTTON];
// load HTML formatted help into the webview
[[helpWebView mainFrame] loadHTMLString:helpString baseURL:nil];
}
/*
* Show the data for "HELP 'search word'" according to helpTarget
*/
- (IBAction)showHelpForSearchString:(id)sender
{
NSString *searchString = [[helpSearchField stringValue] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
switch(helpTarget)
{
case SP_HELP_SEARCH_IN_PAGE:
if(![helpWebView searchFor:searchString direction:YES caseSensitive:NO wrap:YES])
if([searchString length]) NSBeep();
break;
case SP_HELP_SEARCH_IN_WEB:
if(![searchString length])
break;
[self openMySQLonlineDocumentationWithString:searchString];
break;
case SP_HELP_SEARCH_IN_MYSQL:
[self showHelpFor:searchString addToHistory:YES];
break;
}
}
/*
* Show the Help for the selected text in the webview
*/
- (IBAction)showHelpForWebViewSelection:(id)sender
{
[self showHelpFor:[[helpWebView selectedDOMRange] text] addToHistory:YES];
}
/*
* Show MySQL's online documentation for the selected text in the webview
*/
- (IBAction)searchInDocForWebViewSelection:(id)sender
{
NSString *searchString = [[[helpWebView selectedDOMRange] text] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
if(![searchString length])
{
NSBeep();
return;
}
[self openMySQLonlineDocumentationWithString:searchString];
}
/*
* Show the data for "HELP 'currentWord'"
*/
- (IBAction)showHelpForCurrentWord:(id)sender
{
NSString *searchString = [[textView string] substringWithRange:[textView getRangeForCurrentWord]];
[self showHelpFor:searchString addToHistory:YES];
}
/*
* Find Next/Previous in current page
*/
- (IBAction)helpSearchFindNextInPage:(id)sender
{
if(helpTarget == SP_HELP_SEARCH_IN_PAGE)
if(![helpWebView searchFor:[[helpSearchField stringValue] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] direction:YES caseSensitive:NO wrap:YES])
NSBeep();
}
- (IBAction)helpSearchFindPreviousInPage:(id)sender
{
if(helpTarget == SP_HELP_SEARCH_IN_PAGE)
if(![helpWebView searchFor:[[helpSearchField stringValue] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] direction:NO caseSensitive:NO wrap:YES])
NSBeep();
}
/*
* Navigation for back/TOC/forward
*/
- (IBAction)helpSegmentDispatcher:(id)sender
{
switch([helpNavigator selectedSegment])
{
case SP_HELP_GOBACK_BUTTON:
[helpWebView goBack];
break;
case SP_HELP_SHOW_TOC_BUTTON:
[self showHelpFor:SP_HELP_TOC_SEARCH_STRING addToHistory:YES];
break;
case SP_HELP_GOFORWARD_BUTTON:
[helpWebView goForward];
break;
}
// validate goback and goforward buttons according history
[helpNavigator setEnabled:[[helpWebView backForwardList] backListCount] forSegment:SP_HELP_GOBACK_BUTTON];
[helpNavigator setEnabled:[[helpWebView backForwardList] forwardListCount] forSegment:SP_HELP_GOFORWARD_BUTTON];
}
/*
* Set helpTarget according user choice via mouse and keyboard short-cuts.
*/
- (IBAction)helpSelectHelpTargetMySQL:(id)sender
{
helpTarget = SP_HELP_SEARCH_IN_MYSQL;
[helpTargetSelector setSelectedSegment:SP_HELP_SEARCH_IN_MYSQL];
[self helpTargetValidation];
}
- (IBAction)helpSelectHelpTargetPage:(id)sender
{
helpTarget = SP_HELP_SEARCH_IN_PAGE;
[helpTargetSelector setSelectedSegment:SP_HELP_SEARCH_IN_PAGE];
[self helpTargetValidation];
}
- (IBAction)helpSelectHelpTargetWeb:(id)sender
{
helpTarget = SP_HELP_SEARCH_IN_WEB;
[helpTargetSelector setSelectedSegment:SP_HELP_SEARCH_IN_WEB];
[self helpTargetValidation];
}
- (IBAction)helpTargetDispatcher:(id)sender
{
helpTarget = [helpTargetSelector selectedSegment];
[self helpTargetValidation];
}
/*
* Control the help search field behaviour.
*/
- (void)helpTargetValidation
{
switch(helpTarget)
{
case SP_HELP_SEARCH_IN_PAGE:
case SP_HELP_SEARCH_IN_WEB:
[helpSearchFieldCell setSendsWholeSearchString:YES];
break;
case SP_HELP_SEARCH_IN_MYSQL:
[helpSearchFieldCell setSendsWholeSearchString:NO];
break;
}
}
- (void)openMySQLonlineDocumentationWithString:(NSString *)searchString
{
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:
[[NSString stringWithFormat:
SP_MYSQL_DEV_SEARCH_URL,
searchString,
[mySQLversion stringByReplacingOccurrencesOfString:@"." withString:@""]]
stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding]]];
}
/*
* Return the help string HTML formatted from executing "HELP 'searchString'".
* If more than one help topic was found return a link list.
*/
- (NSString *)getHTMLformattedMySQLHelpFor:(NSString *)searchString
{
if(![searchString length]) return @"";
NSRange aRange;
CMMCPResult *theResult = nil;
NSDictionary *tableDetails;
NSMutableString *theHelp = [NSMutableString string];
[theHelp setString:@""];
// search via: HELP 'searchString'
theResult = [mySQLConnection queryString:[NSString stringWithFormat:@"HELP '%@'", [searchString stringByReplacingOccurrencesOfString:@"'" withString:@"\\'"]]];
if ( ![[mySQLConnection getLastErrorMessage] isEqualToString:@""])
{
// if an error or HELP is not supported fall back to online search
NSLog(@"Error in HELP statement for '%@'", searchString);
[self openMySQLonlineDocumentationWithString:searchString];
return SP_HELP_NOT_AVAILABLE;
}
// nothing found?
if(![theResult numOfRows]) {
// try to search via: HELP 'searchString%'
theResult = [mySQLConnection queryString:[NSString stringWithFormat:@"HELP '%@%%'", [searchString stringByReplacingOccurrencesOfString:@"'" withString:@"\\'"]]];
// really nothing found?
if(![theResult numOfRows])
return @"";
}
tableDetails = [[NSDictionary alloc] initWithDictionary:[theResult fetchRowAsDictionary]];
if ([tableDetails objectForKey:@"description"]) { // one single help topic found
if ([tableDetails objectForKey:@"name"]) {
[theHelp appendString:@""];
}
if ([tableDetails objectForKey:@"description"]) {
NSMutableString *desc = [NSMutableString string];
NSError *err1 = NULL;
NSString *aUrl;
[desc setString:[[[tableDetails objectForKey:@"description"] copy] autorelease]];
//[desc replaceOccurrencesOfString:[searchString uppercaseString] withString:[NSString stringWithFormat:@"%@", [searchString uppercaseString]] options:NSLiteralSearch range:NSMakeRange(0,[desc length])];
// detect and generate http links
aRange = NSMakeRange(0,0);
int safeCnt = 0; // safety counter - not more than 200 loops allowed
while(1){
aRange = [desc rangeOfRegex:@"\\s((https?|ftp|file)://.*?html)" options:RKLNoOptions inRange:NSMakeRange(aRange.location+aRange.length, [desc length]-aRange.location-aRange.length) capture:1 error:&err1];
if(aRange.location != NSNotFound) {
aUrl = [desc substringWithRange:aRange];
[desc replaceCharactersInRange:aRange withString:[NSString stringWithFormat:@"%@", aUrl, aUrl]];
}
else
break;
safeCnt++;
if(safeCnt > 200)
break;
}
// detect and generate mysql links for "[HELP keyword]"
aRange = NSMakeRange(0,0);
safeCnt = 0;
while(1){
// TODO how to catch in HELP 'grant' last see [HELP SHOW GRANTS] ?? it's ridiculous
aRange = [desc rangeOfRegex:@"\\[HELP ([^ ]*?)\\]" options:RKLNoOptions inRange:NSMakeRange(aRange.location+aRange.length+53, [desc length]-53-aRange.location-aRange.length) capture:1 error:&err1];
if(aRange.location != NSNotFound) {
aUrl = [[desc substringWithRange:aRange] stringByReplacingOccurrencesOfString:@"\n" withString:@" "];
[desc replaceCharactersInRange:aRange withString:[NSString stringWithFormat:@"%@", NSLocalizedString(@"Show MySQL help for", @"show mysql help for"), aUrl, aUrl, aUrl]];
}
else
break;
safeCnt++;
if(safeCnt > 200)
break;
}
// detect and generate mysql links for capitalzed letters
// aRange = NSMakeRange(0,0);
// safeCnt = 0;
// while(1){
// aRange = [desc rangeOfRegex:@"(?%@", NSLocalizedString(@"Show MySQL help for", @"show mysql help for"), aUrl, aUrl, aUrl]];
// }
// else
// break;
// safeCnt++;
// if(safeCnt > 200)
// break;
// }
[theHelp appendString:@""];
[theHelp appendString:desc];
[theHelp appendString:@"
"];
}
// are examples available?
if([tableDetails objectForKey:@"example"]){
NSString *examples = [[[tableDetails objectForKey:@"example"] copy] autorelease];
if([examples length]){
[theHelp appendString:@"
Example:
"];
[theHelp appendString:examples];
[theHelp appendString:@"
"];
}
}
} else { // list all found topics
int i;
int r = [theResult numOfRows];
if (r) [theResult dataSeek:0];
// check if HELP 'contents' is called
if(![searchString isEqualToString:SP_HELP_TOC_SEARCH_STRING])
[theHelp appendString:[NSString stringWithFormat:@"
%@ “%@”
", NSLocalizedString(@"Help topics for", @"help topics for"), searchString]];
else
[theHelp appendString:[NSString stringWithFormat:@"
%@:
", NSLocalizedString(@"MySQL Help – Categories", @"mysql help categories"), searchString]];
// iterate through all found rows and print them as HTML ul/li list
[theHelp appendString:@""];
for ( i = 0 ; i < r ; i++ ) {
NSArray *anArray = [theResult fetchRowAsArray];
NSString *topic = [anArray objectAtIndex:[anArray count]-2];
[theHelp appendString:
[NSString stringWithFormat:@"- %@
", NSLocalizedString(@"Show MySQL help for", @"show mysql help for"), topic, topic, topic]];
}
[theHelp appendString:@"
"];
}
[tableDetails release];
return [NSString stringWithFormat:helpHTMLTemplate, theHelp];
}
//////////////////////////////
// WebView delegate methods //
//////////////////////////////
/*
* Link detector: If user clicked at an http link open it in the default browser,
* otherwise search for it in the MySQL help. Additionally handle back/forward events from
* keyboard and context menu.
*/
- (void)webView:(WebView *)webView decidePolicyForNavigationAction:(NSDictionary *)actionInformation request:(NSURLRequest *)request frame:(WebFrame *)frame decisionListener:(id)listener
{
int navigationType = [[actionInformation objectForKey:WebActionNavigationTypeKey] intValue];
if([[[request URL] scheme] isEqualToString:@"applewebdata"] && navigationType == WebNavigationTypeLinkClicked){
[self showHelpFor:[[[request URL] path] lastPathComponent] addToHistory:YES];
[listener ignore];
} else {
if (navigationType == WebNavigationTypeOther) {
// catch reload event
// if([[[actionInformation objectForKey:WebActionOriginalURLKey] absoluteString] isEqualToString:@"about:blank"])
// [listener use];
// else
[listener use];
} else if (navigationType == WebNavigationTypeLinkClicked) {
// show http in browser
[[NSWorkspace sharedWorkspace] openURL:[actionInformation objectForKey:WebActionOriginalURLKey]];
[listener ignore];
} else if (navigationType == WebNavigationTypeBackForward) {
// catch back/forward events from contextual menu
[self showHelpFor:[[[[actionInformation objectForKey:WebActionOriginalURLKey] absoluteString] lastPathComponent] stringByReplacingPercentEscapesUsingEncoding:NSASCIIStringEncoding] addToHistory:NO];
[listener ignore];
} else if (navigationType == WebNavigationTypeReload) {
// just in case
[listener ignore];
} else {
// Ignore WebNavigationTypeFormSubmitted, WebNavigationTypeFormResubmitted.
[listener ignore];
}
}
}
/*
* Manage contextual menu in helpWebView
* Ignore "Reload", "Open Link", "Open Link in new Window", "Download link" etc.
*/
- (NSArray *)webView:(WebView *)sender contextMenuItemsForElement:(NSDictionary *)element defaultMenuItems:(NSArray *)defaultMenuItems
{
NSMutableArray *webViewMenuItems = [[defaultMenuItems mutableCopy] autorelease];
if (webViewMenuItems)
{
// Remove all needless default menu items
NSEnumerator *itemEnumerator = [defaultMenuItems objectEnumerator];
NSMenuItem *menuItem = nil;
while (menuItem = [itemEnumerator nextObject])
{
int tag = [menuItem tag];
switch (tag)
{
case 2000: // WebMenuItemTagOpenLink
case WebMenuItemTagOpenLinkInNewWindow:
case WebMenuItemTagDownloadLinkToDisk:
case WebMenuItemTagOpenImageInNewWindow:
case WebMenuItemTagDownloadImageToDisk:
case WebMenuItemTagCopyImageToClipboard:
case WebMenuItemTagOpenFrameInNewWindow:
case WebMenuItemTagStop:
case WebMenuItemTagReload:
case WebMenuItemTagCut:
case WebMenuItemTagPaste:
case WebMenuItemTagSpellingGuess:
case WebMenuItemTagNoGuessesFound:
case WebMenuItemTagIgnoreSpelling:
case WebMenuItemTagLearnSpelling:
case WebMenuItemTagOther:
case WebMenuItemTagOpenWithDefaultApplication:
[webViewMenuItems removeObjectIdenticalTo: menuItem];
break;
}
}
}
// Add two menu items for a selection if no link is given
if(webViewMenuItems
&& [[element objectForKey:@"WebElementIsSelected"] boolValue]
&& ![[element objectForKey:@"WebElementLinkIsLive"] boolValue])
{
NSMenuItem *searchInMySQL;
NSMenuItem *searchInMySQLonline;
[webViewMenuItems insertObject:[NSMenuItem separatorItem] atIndex:0];
searchInMySQLonline = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Search in MySQL Documentation", @"Search in MySQL Documentation") action:@selector(searchInDocForWebViewSelection:) keyEquivalent:@""];
[searchInMySQLonline setEnabled:YES];
[searchInMySQLonline setTarget:self];
[webViewMenuItems insertObject:searchInMySQLonline atIndex:0];
searchInMySQL = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Search in MySQL Help", @"Search in MySQL Help") action:@selector(showHelpForWebViewSelection:) keyEquivalent:@""];
[searchInMySQL setEnabled:YES];
[searchInMySQL setTarget:self];
[webViewMenuItems insertObject:searchInMySQL atIndex:0];
}
return webViewMenuItems;
}
#pragma mark -
// Last but not least
- (id)init;
{
self = [super init];
prefs = nil;
usedQuery = [[NSString stringWithString:@""] retain];
// init helpHTMLTemplate
NSError *error;
helpHTMLTemplate = [[NSString alloc]
initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"sequel-pro-mysql-help-template" ofType:@"html"]
encoding:NSUTF8StringEncoding
error:&error];
// an error occurred while reading
if (helpHTMLTemplate == nil)
{
NSLog(@"%@", [NSString stringWithFormat:@"Error reading “sequel-pro-mysql-help-template.html”!
%@", [error localizedFailureReason]]);
NSBeep();
}
// init search history
[helpWebView setMaintainsBackForwardList:YES];
[[helpWebView backForwardList] setCapacity:20];
return self;
}
- (void)dealloc
{
[queryResult release];
[prefs release];
[queryFavorites release];
[usedQuery release];
[super dealloc];
}
@end