diff options
Diffstat (limited to 'Source/SPServerVariablesController.m')
-rw-r--r-- | Source/SPServerVariablesController.m | 373 |
1 files changed, 373 insertions, 0 deletions
diff --git a/Source/SPServerVariablesController.m b/Source/SPServerVariablesController.m new file mode 100644 index 00000000..ca4f53b1 --- /dev/null +++ b/Source/SPServerVariablesController.m @@ -0,0 +1,373 @@ +// +// $Id$ +// +// SPServerVariablesController.m +// sequel-pro +// +// Created by Stuart Connolly (stuconnolly.com) on November 13, 2009 +// Copyright (c) 2009 Stuart Connolly. All rights reserved. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// More info at <http://code.google.com/p/sequel-pro/> + +#import <MCPKit/MCPKit.h> + +#import "SPServerVariablesController.h" +#import "SPArrayAdditions.h" +#import "TableDocument.h" +#import "SPConstants.h" + +@interface SPServerVariablesController (PrivateAPI) + +- (void)_getDatabaseServerVariables; +- (void)_updateServerVariablesFilterForFilterString:(NSString *)filterString; +- (void)_copyServerVariablesToPasteboardIncludingName:(BOOL)name andValue:(BOOL)value; + +@end + +@implementation SPServerVariablesController + +@synthesize connection; + +/** + * Initialisation + */ +- (id)init +{ + if ((self = [super initWithWindowNibName:@"DatabaseServerVariables"])) { + variables = [[NSMutableArray alloc] init]; + } + + return self; +} + +/** + * Interface initialisation + */ +- (void)awakeFromNib +{ + // Set the process table view's vertical gridlines if required + [variablesTableView setGridStyleMask:([[NSUserDefaults standardUserDefaults] boolForKey:SPDisplayTableViewVerticalGridlines]) ? NSTableViewSolidVerticalGridLineMask : NSTableViewGridNone]; +} + +#pragma mark - +#pragma mark IBAction methods + +/** + * Copy implementation for server variables table view. + */ +- (IBAction)copy:(id)sender +{ + [self _copyServerVariablesToPasteboardIncludingName:YES andValue:YES]; +} + +/** + * Copies the name(s) of the selected server variables. + */ +- (IBAction)copyServerVariableName:(id)sender +{ + [self _copyServerVariablesToPasteboardIncludingName:YES andValue:NO]; +} + +/** + * Copies the value(s) of the selected server variables. + */ +- (IBAction)copyServerVariableValue:(id)sender +{ + [self _copyServerVariablesToPasteboardIncludingName:NO andValue:YES]; +} + +/** + * Close the server variables sheet. + */ +- (IBAction)closeSheet:(id)sender +{ + [NSApp endSheet:[self window] returnCode:[sender tag]]; + [[self window] orderOut:self]; + + // If the filtered array is allocated and it's not a reference to the processes array get rid of it + if ((variablesFiltered) && (variablesFiltered != variables)) { + [variablesFiltered release], variablesFiltered = nil; + } +} + +/** + * Saves the server variables to the selected file. + */ +- (IBAction)saveServerVariables:(id)sender +{ + NSSavePanel *panel = [NSSavePanel savePanel]; + + [panel setRequiredFileType:@"cnf"]; + + [panel setExtensionHidden:NO]; + [panel setAllowsOtherFileTypes:YES]; + [panel setCanSelectHiddenExtension:YES]; + + [panel beginSheetForDirectory:nil file:@"ServerVariables" modalForWindow:[self window] modalDelegate:self didEndSelector:@selector(savePanelDidEnd:returnCode:contextInfo:) contextInfo:nil]; +} + + +#pragma mark - +#pragma mark Other methods + +/** + * Displays the process list sheet attached to the supplied window. + */ +- (void)displayServerVariablesSheetAttachedToWindow:(NSWindow *)window +{ + // Weak reference + variablesFiltered = variables; + + // Get the variables + [self _getDatabaseServerVariables]; + + // Reload the tableview + [variablesTableView reloadData]; + + // If the search field already has value from when the panel was previously open, apply the filter. + if ([[filterVariablesSearchField stringValue] length] > 0) { + [self _updateServerVariablesFilterForFilterString:[filterVariablesSearchField stringValue]]; + } + + // Open the sheet + [NSApp beginSheet:[self window] modalForWindow:window modalDelegate:self didEndSelector:nil contextInfo:nil]; +} + +/** + * Invoked when the save panel is dismissed. + */ +- (void)savePanelDidEnd:(NSSavePanel *)panel returnCode:(NSInteger)returnCode contextInfo:(NSString *)contextInfo +{ + if (returnCode == NSOKButton) { + if ([variablesFiltered count] > 0) { + NSMutableString *variablesString = [NSMutableString stringWithFormat:@"# MySQL server variables for %@\n\n", [(TableDocument *)[[NSApp mainWindow] delegate] host]]; + + for (NSDictionary *variable in variablesFiltered) + { + [variablesString appendString:[NSString stringWithFormat:@"%@ = %@\n", [variable objectForKey:@"Variable_name"], [variable objectForKey:@"Value"]]]; + } + + [variablesString writeToFile:[panel filename] atomically:YES encoding:NSUTF8StringEncoding error:NULL]; + } + } +} + +/** + * Menu item validation. + */ +- (BOOL)validateMenuItem:(NSMenuItem *)menuItem +{ + SEL action = [menuItem action]; + + if (action == @selector(copy:)) { + return ([variablesTableView numberOfSelectedRows] > 0); + } + + // Copy selected server variable name(s) + if ([menuItem action] == @selector(copyServerVariableName:)) { + [menuItem setTitle:([variablesTableView numberOfSelectedRows] > 1) ? NSLocalizedString(@"Copy Variable Names", @"copy server variable names menu item") : NSLocalizedString(@"Copy Variable Name", @"copy server variable name menu item")]; + + return ([variablesTableView numberOfSelectedRows] > 0); + } + + // Copy selected server variable value(s) + if ([menuItem action] == @selector(copyServerVariableValue:)) { + [menuItem setTitle:([variablesTableView numberOfSelectedRows] > 1) ? NSLocalizedString(@"Copy Variable Values", @"copy server variable values menu item") : NSLocalizedString(@"Copy Variable Value", @"copy server variable value menu item")]; + + return ([variablesTableView numberOfSelectedRows] > 0); + } + + return YES; +} + +/** + * This method is called as part of Key Value Observing which is used to watch for prefernce changes which effect the interface. + */ +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context +{ + if ([keyPath isEqualToString:SPDisplayTableViewVerticalGridlines]) { + [variablesTableView setGridStyleMask:([[change objectForKey:NSKeyValueChangeNewKey] boolValue]) ? NSTableViewSolidVerticalGridLineMask : NSTableViewGridNone]; + } +} + +#pragma mark - +#pragma mark Tableview delegate methods + +/** + * Table view delegate method. Returns the number of rows in the table veiw. + */ +- (int)numberOfRowsInTableView:(NSTableView *)tableView +{ + return [variablesFiltered count]; +} + +/** + * Table view delegate method. Returns the specific object for the request column and row. + */ +- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row +{ + return [[variablesFiltered objectAtIndex:row] valueForKey:[tableColumn identifier]]; +} + +#pragma mark - +#pragma mark Text field delegate methods + +/** + * Apply the filter string to the current process list. + */ +- (void)controlTextDidChange:(NSNotification *)notification +{ + id object = [notification object]; + + if (object == filterVariablesSearchField) { + [self _updateServerVariablesFilterForFilterString:[object stringValue]]; + } +} + +#pragma mark - + +/** + * Dealloc + */ +- (void)dealloc +{ + [variables release], variables = nil; + + [super dealloc]; +} + +@end + +@implementation SPServerVariablesController (PrivateAPI) + +/** + * Gets the database's current server variables. + */ +- (void)_getDatabaseServerVariables +{ + NSUInteger i = 0; + + // Get processes + MCPResult *serverVariables = [connection queryString:@"SHOW VARIABLES"]; + + if ([serverVariables numOfRows]) [serverVariables dataSeek:0]; + + [variables removeAllObjects]; + + for (i = 0; i < [serverVariables numOfRows]; i++) + { + [variables addObject:[serverVariables fetchRowAsDictionary]]; + } +} + +/** + * Filter the displayed server variables by matching the variable name and value against the + * filter string. + */ +- (void)_updateServerVariablesFilterForFilterString:(NSString *)filterString +{ + [saveVariablesButton setEnabled:NO]; + + filterString = [[filterString lowercaseString] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; + + // If the filtered array is allocated and its not a reference to the variables array + // relase it to prevent memory leaks upon the next allocation. + if ((variablesFiltered) && (variablesFiltered != variables)) { + [variablesFiltered release], variablesFiltered = nil; + } + + variablesFiltered = [[NSMutableArray alloc] init]; + + if ([filterString length] == 0) { + [variablesFiltered release]; + variablesFiltered = variables; + + [saveVariablesButton setEnabled:YES]; + [saveVariablesButton setTitle:@"Save As..."]; + [variablesCountTextField setStringValue:@""]; + + [variablesTableView reloadData]; + + return; + } + + for (NSDictionary *variable in variables) + { + if (([[variable objectForKey:@"Variable_name"] rangeOfString:filterString options:NSCaseInsensitiveSearch].location != NSNotFound) || + ([[variable objectForKey:@"Value"] rangeOfString:filterString options:NSCaseInsensitiveSearch].location != NSNotFound)) + { + [variablesFiltered addObject:variable]; + } + } + + [variablesTableView reloadData]; + + [variablesCountTextField setHidden:NO]; + [variablesCountTextField setStringValue:[NSString stringWithFormat:NSLocalizedString(@"%d of %d", "filtered server variables count"), [variablesFiltered count], [variables count]]]; + + if ([variablesFiltered count] == 0) return; + + [saveVariablesButton setEnabled:YES]; + [saveVariablesButton setTitle:@"Save View As..."]; +} + +/** + * Copies either the name or value or both (as name = value pairs) of the currently selected server variables. + */ +- (void)_copyServerVariablesToPasteboardIncludingName:(BOOL)name andValue:(BOOL)value +{ + // At least one of either name or value must be true + if ((!name) && (!value)) return; + + NSResponder *firstResponder = [[self window] firstResponder]; + + if ((firstResponder == variablesTableView) && ([variablesTableView numberOfSelectedRows] > 0)) { + + NSString *string = @""; + NSIndexSet *rows = [variablesTableView selectedRowIndexes]; + + NSUInteger i = [rows firstIndex]; + + while (i != NSNotFound) + { + if (i < [variablesFiltered count]) { + NSDictionary *variable = NSArrayObjectAtIndex(variablesFiltered, i); + + NSString *variableName = [variable objectForKey:@"Variable_name"]; + NSString *variableValue = [variable objectForKey:@"Value"]; + + // Decide what to include in the string + if (name && value) { + string = [string stringByAppendingFormat:@"%@ = %@\n", variableName, variableValue]; + } + else { + string = [string stringByAppendingFormat:@"%@\n", (name) ? variableName : variableValue]; + } + } + + i = [rows indexGreaterThanIndex:i]; + } + + NSPasteboard *pasteBoard = [NSPasteboard generalPasteboard]; + + // Copy the string to the pasteboard + [pasteBoard declareTypes:[NSArray arrayWithObjects:NSStringPboardType, nil] owner:nil]; + [pasteBoard setString:string forType:NSStringPboardType]; + } +} + +@end |