diff options
author | Bibiko <bibiko@eva.mpg.de> | 2010-10-29 20:06:44 +0000 |
---|---|---|
committer | Bibiko <bibiko@eva.mpg.de> | 2010-10-29 20:06:44 +0000 |
commit | e93d9df70e29e53c4588a6d49bf3a056ac56e9db (patch) | |
tree | 96b774aaac21f4a81d3a573b109520859f5a908a | |
parent | 79f4bb582755adfdc9504830d3a8bf061e1e49c1 (diff) | |
download | sequelpro-e93d9df70e29e53c4588a6d49bf3a056ac56e9db.tar.gz sequelpro-e93d9df70e29e53c4588a6d49bf3a056ac56e9db.tar.bz2 sequelpro-e93d9df70e29e53c4588a6d49bf3a056ac56e9db.zip |
• convert the Field Editor Sheet into a document-modal sheet, i.e. now the sheet doesn't block the entire app
- fixed various layout issues
- fixed some tiny memory leaks
• fixed tiny memory leak in MCPStreamingResult
-rw-r--r-- | Frameworks/MCPKit/MCPFoundationKit/MCPStreamingResult.m | 7 | ||||
-rw-r--r-- | Interfaces/English.lproj/FieldEditorSheet.xib | 38 | ||||
-rw-r--r-- | Source/SPCustomQuery.h | 6 | ||||
-rw-r--r-- | Source/SPCustomQuery.m | 57 | ||||
-rw-r--r-- | Source/SPEditSheetTextView.m | 13 | ||||
-rw-r--r-- | Source/SPFieldEditorController.h | 10 | ||||
-rw-r--r-- | Source/SPFieldEditorController.m | 235 | ||||
-rw-r--r-- | Source/SPTableContent.h | 4 | ||||
-rw-r--r-- | Source/SPTableContent.m | 96 |
9 files changed, 246 insertions, 220 deletions
diff --git a/Frameworks/MCPKit/MCPFoundationKit/MCPStreamingResult.m b/Frameworks/MCPKit/MCPFoundationKit/MCPStreamingResult.m index d26dbafc..c15db6c6 100644 --- a/Frameworks/MCPKit/MCPFoundationKit/MCPStreamingResult.m +++ b/Frameworks/MCPKit/MCPFoundationKit/MCPStreamingResult.m @@ -246,11 +246,6 @@ void _bytes2bin(Byte *n, NSUInteger nbytes, NSUInteger len, char *buf); } } - // If the field is of type BIT, then allocate the binary buffer - if (fieldDefinitions[i].type == FIELD_TYPE_BIT) { - buf = malloc(fieldDefinitions[i].length + 1); - } - // If the data hasn't already been detected as NULL - in which case it will have been // set to NSNull - process the data by type @@ -293,6 +288,8 @@ void _bytes2bin(Byte *n, NSUInteger nbytes, NSUInteger len, char *buf); case FIELD_TYPE_BIT: // Get a binary representation of the data + + buf = malloc(fieldDefinitions[i].length + 1); _bytes2bin(theData, fieldLengths[i], fieldDefinitions[i].length, buf); cellData = (theData != NULL) ? [NSString stringWithUTF8String:buf] : @""; diff --git a/Interfaces/English.lproj/FieldEditorSheet.xib b/Interfaces/English.lproj/FieldEditorSheet.xib index a46ac1a8..9b24c5d2 100644 --- a/Interfaces/English.lproj/FieldEditorSheet.xib +++ b/Interfaces/English.lproj/FieldEditorSheet.xib @@ -3607,22 +3607,6 @@ </object> <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> - <string key="label">closeBitSheet:</string> - <reference key="source" ref="1001"/> - <reference key="destination" ref="824786228"/> - </object> - <int key="connectionID">328</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">closeBitSheet:</string> - <reference key="source" ref="1001"/> - <reference key="destination" ref="883245768"/> - </object> - <int key="connectionID">329</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> <string key="label">bitSheetSelectBit0:</string> <reference key="source" ref="1001"/> <reference key="destination" ref="656999524"/> @@ -4901,6 +4885,22 @@ </object> <int key="connectionID">529</int> </object> + <object class="IBConnectionRecord"> + <object class="IBActionConnection" key="connection"> + <string key="label">closeEditSheet:</string> + <reference key="source" ref="1001"/> + <reference key="destination" ref="883245768"/> + </object> + <int key="connectionID">530</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBActionConnection" key="connection"> + <string key="label">closeEditSheet:</string> + <reference key="source" ref="1001"/> + <reference key="destination" ref="824786228"/> + </object> + <int key="connectionID">531</int> + </object> </object> <object class="IBMutableOrderedSet" key="objectRecords"> <object class="NSArray" key="orderedObjects"> @@ -7180,9 +7180,9 @@ </object> </object> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <string>{{344, 658}, {411, 218}}</string> + <string>{{344, 538}, {411, 218}}</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <string>{{344, 658}, {411, 218}}</string> + <string>{{344, 538}, {411, 218}}</string> <boolean value="NO"/> <string>{196, 240}</string> <string>{{357, 418}, {480, 270}}</string> @@ -7256,7 +7256,7 @@ </object> </object> <nil key="sourceID"/> - <int key="maxID">529</int> + <int key="maxID">531</int> </object> <object class="IBClassDescriber" key="IBDocument.Classes"> <object class="NSMutableArray" key="referencedPartialClassDescriptions"> diff --git a/Source/SPCustomQuery.h b/Source/SPCustomQuery.h index 17c1a921..2af48886 100644 --- a/Source/SPCustomQuery.h +++ b/Source/SPCustomQuery.h @@ -46,7 +46,7 @@ #define SP_HISTORY_SAVE_MENUITEM_TAG 300001 #define SP_HISTORY_CLEAR_MENUITEM_TAG 300002 -@class SPCopyTable, SPQueryFavoriteManager, SPDataStorage, BWSplitView; +@class SPCopyTable, SPQueryFavoriteManager, SPDataStorage, BWSplitView, SPFieldEditorController; @interface SPCustomQuery : NSObject { @@ -110,6 +110,8 @@ IBOutlet NSButton *queryInfoButton; IBOutlet BWSplitView *queryInfoPaneSplitView; + SPFieldEditorController *fieldEditor; + SPQueryFavoriteManager *favoritesManager; NSUserDefaults *prefs; @@ -248,4 +250,6 @@ - (void)historyItemsHaveBeenUpdated:(id)manager; +- (void)processFieldEditorResult:(id)data contextInfo:(NSDictionary*)contextInfo; + @end diff --git a/Source/SPCustomQuery.m b/Source/SPCustomQuery.m index 31ff02d7..41a6b62f 100644 --- a/Source/SPCustomQuery.m +++ b/Source/SPCustomQuery.m @@ -2273,7 +2273,8 @@ if ([multipleLineEditingButton state] == NSOnState || isBlob) { - SPFieldEditorController *fieldEditor = [[SPFieldEditorController alloc] init]; + if(fieldEditor) [fieldEditor release], fieldEditor = nil; + fieldEditor = [[SPFieldEditorController alloc] init]; // Remember edited row for reselecting and setting the scroll view after reload editedRow = rowIndex; @@ -2305,19 +2306,18 @@ if ([originalData isNSNull]) originalData = [NSString stringWithString:[prefs objectForKey:SPNullValue]]; - id editData = [[fieldEditor editWithObject:originalData - fieldName:[columnDefinition objectForKey:@"name"] - usingEncoding:[mySQLConnection stringEncoding] - isObjectBlob:isBlob - isEditable:isFieldEditable - withWindow:[tableDocumentInstance parentWindow]] retain]; - - if ( editData ) - [self tableView:aTableView setObjectValue:[editData copy] forTableColumn:aTableColumn row:rowIndex]; - - [fieldEditor release]; - - if ( editData ) [editData release]; + [fieldEditor editWithObject:originalData + fieldName:[columnDefinition objectForKey:@"name"] + usingEncoding:[mySQLConnection stringEncoding] + isObjectBlob:isBlob + isEditable:isFieldEditable + withWindow:[tableDocumentInstance parentWindow] + sender:self + contextInfo:[NSDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithInteger:rowIndex], @"row", + [aTableColumn identifier], @"column", + [NSNumber numberWithBool:isFieldEditable], @"isFieldEditable", + nil]]; // Preserve focus and restore selection indexes if appropriate [[tableDocumentInstance parentWindow] makeFirstResponder:customQueryView]; @@ -3410,6 +3410,33 @@ return YES; } +- (void)processFieldEditorResult:(id)data contextInfo:(NSDictionary*)contextInfo +{ + + if (data && contextInfo) { + NSUInteger row = [[contextInfo objectForKey:@"row"] integerValue]; + NSUInteger column = [[contextInfo objectForKey:@"column"] integerValue]; + BOOL isFieldEditable = ([contextInfo objectForKey:@"isFieldEditable"]) ? YES : NO; + + // if ([data isKindOfClass:[NSString class]] + // && [data isEqualToString:[prefs objectForKey:SPNullValue]] + // && [[NSArrayObjectAtIndex(dataColumns, column) objectForKey:@"null"] boolValue]) + // { + // data = [[NSNull null] retain]; + // } + if(isFieldEditable) { + [self tableView:customQueryView setObjectValue:[[data copy] autorelease] forTableColumn:[customQueryView tableColumnWithIdentifier:[contextInfo objectForKey:@"column"]] row:row]; + } + } + + if(fieldEditor) { + [fieldEditor release]; + fieldEditor = nil; + } + + // [[tableDocumentInstance parentWindow] makeFirstResponder:tableContentView]; +} + #pragma mark - - (id)init @@ -3703,6 +3730,8 @@ [resultData release]; [favoritesManager release]; + if(fieldEditor) [fieldEditor release], fieldEditor = nil; + if (helpHTMLTemplate) [helpHTMLTemplate release]; if (mySQLversion) [mySQLversion release]; if (sortField) [sortField release]; diff --git a/Source/SPEditSheetTextView.m b/Source/SPEditSheetTextView.m index 0d309f35..e46868b7 100644 --- a/Source/SPEditSheetTextView.m +++ b/Source/SPEditSheetTextView.m @@ -64,7 +64,7 @@ [super cut:sender]; } -/* +/** * Validate undo and redo menu items */ - (BOOL)validateMenuItem:(NSMenuItem *)menuItem @@ -99,9 +99,7 @@ return; } - // NSString *characters = [theEvent characters]; NSString *charactersIgnMod = [theEvent charactersIgnoringModifiers]; - // unichar insertedCharacter = [characters characterAtIndex:0]; long curFlags = ([theEvent modifierFlags] & allFlags); if(curFlags & NSCommandKeyMask) { @@ -119,6 +117,15 @@ } } + // Allow undo grouping if user typed a ' ' (for word level undo) + // or a RETURN but not for each char due to writing speed + if([charactersIgnMod isEqualToString:@" "] + || [theEvent keyCode] == 36 + || [theEvent modifierFlags] & (NSCommandKeyMask|NSControlKeyMask|NSAlternateKeyMask) + ) { + [[self delegate] setDoGroupDueToChars]; + } + [super keyDown: theEvent]; } diff --git a/Source/SPFieldEditorController.h b/Source/SPFieldEditorController.h index af914f82..29605c51 100644 --- a/Source/SPFieldEditorController.h +++ b/Source/SPFieldEditorController.h @@ -131,12 +131,15 @@ IBOutlet NSTextField *bitSheetBitLabel56; id usedSheet; + id callerInstance; + NSDictionary *contextInfo; id sheetEditData; BOOL editSheetWillBeInitialized; BOOL _isBlob; BOOL _isEditable; BOOL _allowNULL; + BOOL doGroupDueToChars; NSInteger quickLookCloseMarker; NSStringEncoding encoding; NSString *fieldType; @@ -157,7 +160,7 @@ NSDictionary *qlTypes; NSInteger editSheetReturnCode; - + BOOL _isGeometry; NSUndoManager *esUndoManager; } @@ -169,7 +172,6 @@ - (IBAction)quickLookFormatButton:(id)sender; - (IBAction)dropImage:(id)sender; -- (IBAction)closeBitSheet:(id)sender; - (IBAction)bitSheetSelectBit0:(id)sender; - (IBAction)bitSheetBitButtonWasClicked:(id)sender; - (IBAction)bitSheetOperatorButtonWasClicked:(id)sender; @@ -177,7 +179,8 @@ - (void)updateBitSheet; - (id)editWithObject:(id)data fieldName:(NSString*)fieldName usingEncoding:(NSStringEncoding)anEncoding - isObjectBlob:(BOOL)isFieldBlob isEditable:(BOOL)isEditable withWindow:(NSWindow *)theWindow; + isObjectBlob:(BOOL)isFieldBlob isEditable:(BOOL)isEditable withWindow:(NSWindow *)theWindow + withSender:(id)sender contextInfo:(NSDictionary*)theContextInfo; - (void)setTextMaxLength:(NSUInteger)length; - (void)setFieldType:(NSString*)aType; @@ -193,5 +196,6 @@ - (void)textViewDidChangeSelection:(NSNotification *)notification; - (void)setWasCutPaste; +- (void)setDoGroupDueToChars; @end diff --git a/Source/SPFieldEditorController.m b/Source/SPFieldEditorController.m index 56f2407d..3d4dd15b 100644 --- a/Source/SPFieldEditorController.m +++ b/Source/SPFieldEditorController.m @@ -48,6 +48,10 @@ _isEditable = NO; _isBlob = NO; _allowNULL = YES; + _isGeometry = NO; + contextInfo = nil; + callerInstance = nil; + doGroupDueToChars = NO; prefs = [NSUserDefaults standardUserDefaults]; @@ -60,7 +64,7 @@ allowUndo = NO; selectionChanged = NO; - tmpDirPath = NSTemporaryDirectory(); + tmpDirPath = [NSTemporaryDirectory() retain]; tmpFileName = nil; NSMenu *menu = [editSheetQuickLookButton menu]; @@ -109,7 +113,7 @@ } } - qlTypes = [NSDictionary dictionaryWithObject:qlTypesItems forKey:SPQuickLookTypes]; + qlTypes = [[NSDictionary dictionaryWithObject:qlTypesItems forKey:SPQuickLookTypes] retain]; [qlTypesItems release]; fieldType = @""; @@ -131,8 +135,11 @@ if([[NSClassFromString(@"QLPreviewPanel") sharedPreviewPanel] isVisible]) [[NSClassFromString(@"QLPreviewPanel") sharedPreviewPanel] orderOut:nil]; - if ( esUndoManager ) [esUndoManager release]; if ( sheetEditData ) [sheetEditData release]; + if ( qlTypes ) [qlTypes release]; + if ( tmpDirPath ) [tmpDirPath release]; + if ( esUndoManager ) [esUndoManager release]; + if ( contextInfo ) [contextInfo release]; [super dealloc]; } @@ -191,17 +198,23 @@ * * @param theWindow The window for displaying the sheet. * - * @return If SPFieldEditorController was closed by "OK" and the field was editable it returns the edited value, otherwise it returns nil. + * @param sender The calling instance. + * + * @param contextInfo context info for processing the edited data in sender. + * */ -- (id)editWithObject:(id)data fieldName:(NSString*)fieldName usingEncoding:(NSStringEncoding)anEncoding - isObjectBlob:(BOOL)isFieldBlob isEditable:(BOOL)isEditable withWindow:(NSWindow *)theWindow +- (void)editWithObject:(id)data fieldName:(NSString*)fieldName usingEncoding:(NSStringEncoding)anEncoding + isObjectBlob:(BOOL)isFieldBlob isEditable:(BOOL)isEditable withWindow:(NSWindow *)theWindow + sender:(id)sender contextInfo:(NSDictionary*)theContextInfo { usedSheet = nil; _isEditable = isEditable; + contextInfo = [theContextInfo retain]; + callerInstance = sender; - BOOL _isGeometry = ([[fieldType uppercaseString] isEqualToString:@"GEOMETRY"]) ? YES : NO; + _isGeometry = ([[fieldType uppercaseString] isEqualToString:@"GEOMETRY"]) ? YES : NO; // Set field label NSMutableString *label = [NSMutableString string]; @@ -247,7 +260,7 @@ usedSheet = bitSheet; - [NSApp beginSheet:usedSheet modalForWindow:theWindow modalDelegate:self didEndSelector:nil contextInfo:nil]; + [NSApp beginSheet:usedSheet modalForWindow:theWindow modalDelegate:self didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:) contextInfo:nil]; } else { @@ -304,7 +317,7 @@ [editSheetSegmentControl setEnabled:YES forSegment:1]; // Set window's min size since no segment and quicklook buttons are hidden - if (_isBlob || _isBINARY) { + if (_isBlob || _isBINARY || _isGeometry) { [usedSheet setFrameAutosaveName:@"SPFieldEditorBlobSheet"]; [usedSheet setMinSize:NSMakeSize(560, 200)]; } else { @@ -315,7 +328,7 @@ [editTextView setEditable:_isEditable]; [editImage setEditable:_isEditable]; - [NSApp beginSheet:usedSheet modalForWindow:theWindow modalDelegate:self didEndSelector:nil contextInfo:nil]; + [NSApp beginSheet:usedSheet modalForWindow:theWindow modalDelegate:self didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:) contextInfo:nil]; [editSheetProgressBar startAnimation:self]; @@ -337,16 +350,16 @@ [editTextScrollView setHidden:YES]; [editSheetSegmentControl setSelectedSegment:2]; } else if ([sheetEditData isKindOfClass:[MCPGeometryData class]]) { - SPGeometryDataView *v = [[[SPGeometryDataView alloc] initWithCoordinates:[sheetEditData coordinates] targetDimension:2000.0] autorelease]; - image = [v thumbnailImage]; - stringValue = [[sheetEditData wktString] retain]; - [hexTextView setString:@""]; - [hexTextView setHidden:YES]; - [hexTextScrollView setHidden:YES]; - [editSheetSegmentControl setEnabled:NO forSegment:2]; - [editSheetSegmentControl setSelectedSegment:0]; - [editTextView setHidden:NO]; - [editTextScrollView setHidden:NO]; + SPGeometryDataView *v = [[[SPGeometryDataView alloc] initWithCoordinates:[sheetEditData coordinates] targetDimension:2000.0] autorelease]; + image = [v thumbnailImage]; + stringValue = [[sheetEditData wktString] retain]; + [hexTextView setString:@""]; + [hexTextView setHidden:YES]; + [hexTextScrollView setHidden:YES]; + [editSheetSegmentControl setEnabled:NO forSegment:2]; + [editSheetSegmentControl setSelectedSegment:0]; + [editTextView setHidden:NO]; + [editTextScrollView setHidden:NO]; } else { stringValue = [sheetEditData retain]; @@ -403,8 +416,8 @@ else [usedSheet makeFirstResponder:editImage]; - [stringValue release], stringValue = nil; } + if(stringValue) [stringValue release], stringValue = nil; editSheetWillBeInitialized = NO; @@ -412,102 +425,12 @@ } - // wait for editSheet - NSModalSession session = [NSApp beginModalSessionForWindow:usedSheet]; - NSInteger cycleCounter = 0; - BOOL doGroupDueToChars = NO; - BOOL findPanelIsOpen = NO; - - id textFinder = [objc_getClass("NSTextFinder") sharedTextFinder]; - id textFinderPanel = nil; - - for (;;) { - - - // Break the run loop if editSheet was closed - if ([NSApp runModalSession:session] != NSRunContinuesResponse - || ![usedSheet isVisible]) - break; - - // Execute code on DefaultRunLoop (like displaying a tooltip) - [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode - beforeDate:[NSDate distantFuture]]; - - - if([[textFinder findPanel:NO] isVisible]) { - textFinderPanel = [textFinder findPanel:NO]; - [textFinderPanel setWorksWhenModal:YES]; - // [textFinderPanel setLevel:NSDockWindowLevel]; - findPanelIsOpen = YES; - } else { - findPanelIsOpen = NO; - } - - // Allow undo grouping if user typed a ' ' (for word level undo) - // or a RETURN but not for each char due to writing speed - if([[NSApp currentEvent] type] == NSKeyDown - && ( - [[[NSApp currentEvent] charactersIgnoringModifiers] isEqualToString:@" "] - || [[NSApp currentEvent] keyCode] == 36 - || [[NSApp currentEvent] modifierFlags] & (NSCommandKeyMask|NSControlKeyMask|NSAlternateKeyMask) - )) { - doGroupDueToChars=YES; - } - - // If conditions match create an undo group - if( ( wasCutPaste || allowUndo || doGroupDueToChars ) && ![esUndoManager isUndoing] && ![esUndoManager isRedoing] ) { - allowUndo = NO; - wasCutPaste = NO; - doGroupDueToChars = NO; - selectionChanged = NO; - - cycleCounter = 0; - while([esUndoManager groupingLevel] > 0) { - [esUndoManager endUndoGrouping]; - cycleCounter++; - } - while([esUndoManager groupingLevel] < cycleCounter) - [esUndoManager beginUndoGrouping]; - - cycleCounter = 0; - } - - } - [NSApp endModalSession:session]; - [usedSheet orderOut:nil]; - [NSApp endSheet:usedSheet]; - - // For safety reasons inform QuickLook to quit - quickLookCloseMarker = 1; - - // Remember spell cheecker status - [prefs setBool:[editTextView isContinuousSpellCheckingEnabled] forKey:SPBlobTextEditorSpellCheckingEnabled]; - - // Close findPanel for convenience - if(findPanelIsOpen && textFinderPanel) { - [textFinderPanel close]; - } - - return ( editSheetReturnCode && _isEditable ) ? (_isGeometry) ? [editTextView string] : sheetEditData : nil; } -/** - * Establish and return an UndoManager for editTextView - */ -- (NSUndoManager*)undoManagerForTextView:(NSTextView*)aTextView -{ - if (!esUndoManager) - esUndoManager = [[NSUndoManager alloc] init]; - - return esUndoManager; -} - -/** - * Set variable if something in editTextView was cutted or pasted for creating better undo grouping. - */ -- (void)setWasCutPaste +- (void)sheetDidEnd:(id)sheet returnCode:(NSInteger)returnCode contextInfo:(NSString *)contextInfo { - wasCutPaste = YES; + // Remember spell cheecker status + [prefs setBool:[editTextView isContinuousSpellCheckingEnabled] forKey:SPBlobTextEditorSpellCheckingEnabled]; } /** @@ -530,7 +453,10 @@ [SPTooltip showWithObject:[NSString stringWithFormat:NSLocalizedString(@"Text is too long. Maximum text length is set to %llu.", @"Text is too long. Maximum text length is set to %llu."), maxTextLength]]; return; } - [NSApp stopModal]; + + editSheetReturnCode = 1; + } + else if(sender == bitSheetOkButton && _isEditable) { editSheetReturnCode = 1; } @@ -546,7 +472,13 @@ } } - [NSApp abortModal]; + [NSApp endSheet:usedSheet returnCode:1]; + [usedSheet orderOut:self]; + + if(callerInstance) { + id returnData = ( editSheetReturnCode && _isEditable ) ? (_isGeometry) ? [editTextView string] : sheetEditData : nil; + [callerInstance processFieldEditorResult:returnData contextInfo:contextInfo]; + } } @@ -766,6 +698,7 @@ */ - (void)createTemporaryQuickLookFileOfType:(NSString *)type treatAsText:(BOOL)isText { + // Create a temporary file name to store the data as file // since QuickLook only works on files. // Alternate the file name to suppress caching by using counter%2. @@ -1139,23 +1072,6 @@ } /** - * Close the bitSheet and abort the running modal session. - */ -- (IBAction)closeBitSheet:(id)sender -{ - - editSheetReturnCode = 0; - - if(sender == bitSheetOkButton && _isEditable) { - [NSApp stopModal]; - editSheetReturnCode = 1; - } - - [NSApp abortModal]; - -} - -/** * Selector of any operator in the bitSheet. The different buttons will be distinguished by the sender's tag. */ - (IBAction)bitSheetOperatorButtonWasClicked:(id)sender @@ -1428,18 +1344,69 @@ return NO; } +/** + * Establish and return an UndoManager for editTextView + */ +- (NSUndoManager*)undoManagerForTextView:(NSTextView*)aTextView +{ + if (!esUndoManager) + esUndoManager = [[NSUndoManager alloc] init]; + + return esUndoManager; +} + +/** + * Set variable if something in editTextView was cutted or pasted for creating better undo grouping. + */ +- (void)setWasCutPaste +{ + wasCutPaste = YES; +} + + - (void)setAllowedUndo { allowUndo = YES; } +- (void)setDoGroupDueToChars +{ + doGroupDueToChars = YES; +} + /** * Traps any editing in editTextView to allow undo grouping only if the text buffer was really changed. * Inform the run loop delayed for larger undo groups. */ - (void)textDidChange:(NSNotification *)aNotification { - [self performSelector:@selector(setAllowedUndo) withObject:nil afterDelay:0.2]; + + [NSObject cancelPreviousPerformRequestsWithTarget:self + selector:@selector(setAllowedUndo) + object:nil]; + + // If conditions match create an undo group + NSInteger cycleCounter; + if( ( wasCutPaste || allowUndo || doGroupDueToChars ) && ![esUndoManager isUndoing] && ![esUndoManager isRedoing] ) { + NSLog(@"did"); + allowUndo = NO; + wasCutPaste = NO; + doGroupDueToChars = NO; + selectionChanged = NO; + + cycleCounter = 0; + while([esUndoManager groupingLevel] > 0) { + [esUndoManager endUndoGrouping]; + cycleCounter++; + } + while([esUndoManager groupingLevel] < cycleCounter) + [esUndoManager beginUndoGrouping]; + + cycleCounter = 0; + } + + [self performSelector:@selector(setAllowedUndo) withObject:nil afterDelay:0.09]; + } @end diff --git a/Source/SPTableContent.h b/Source/SPTableContent.h index 2f139881..d1a70a5c 100644 --- a/Source/SPTableContent.h +++ b/Source/SPTableContent.h @@ -27,7 +27,7 @@ #import <MCPKit/MCPKit.h> -@class SPCopyTable, SPTextAndLinkCell, SPHistoryController, SPTableInfo, SPDataStorage, SPTextView; +@class SPCopyTable, SPTextAndLinkCell, SPHistoryController, SPTableInfo, SPDataStorage, SPTextView, SPFieldEditorController; @interface SPTableContent : NSObject { @@ -133,6 +133,7 @@ NSColor *blackColor; NSColor *lightGrayColor; + SPFieldEditorController *fieldEditor; } // Table loading methods and information @@ -200,6 +201,7 @@ - (void)autosizeColumns; - (BOOL)saveRowOnDeselect; - (void)sortTableTaskWithColumn:(NSTableColumn *)tableColumn; +- (void)processFieldEditorResult:(id)data contextInfo:(NSDictionary*)contextInfo; // Retrieving and setting table state - (NSString *) sortColumnName; diff --git a/Source/SPTableContent.m b/Source/SPTableContent.m index bab3cf0d..0ee639c8 100644 --- a/Source/SPTableContent.m +++ b/Source/SPTableContent.m @@ -2873,7 +2873,7 @@ * Show Error sheet (can be called from inside of a endSheet selector) * via [self performSelector:@selector(showErrorSheetWithTitle:) withObject: afterDelay:] */ --(void)showErrorSheetWith:(id)error +- (void)showErrorSheetWith:(id)error { // error := first object is the title , second the message, only one button OK SPBeginAlertSheet([error objectAtIndex:0], NSLocalizedString(@"OK", @"OK button"), @@ -2881,6 +2881,45 @@ [error objectAtIndex:1]); } +- (void)processFieldEditorResult:(id)data contextInfo:(NSDictionary*)contextInfo +{ + + if (data && contextInfo) { + NSUInteger row = [[contextInfo objectForKey:@"row"] integerValue]; + NSUInteger column = [[contextInfo objectForKey:@"column"] integerValue]; + BOOL isFieldEditable = ([contextInfo objectForKey:@"isFieldEditable"]) ? YES : NO; + if (!isEditingRow && [tablesListInstance tableType] != SPTableTypeView) { + [oldRow setArray:[tableValues rowContentsAtIndex:row]]; + isEditingRow = YES; + currentlyEditingRow = row; + } + + if ([data isKindOfClass:[NSString class]] + && [data isEqualToString:[prefs objectForKey:SPNullValue]] + && [[NSArrayObjectAtIndex(dataColumns, column) objectForKey:@"null"] boolValue]) + { + data = [[NSNull null] retain]; + } + if(isFieldEditable) { + if([tablesListInstance tableType] == SPTableTypeView) { + // since in a view we're editing a field rather than a row + isEditingRow = NO; + // update the field and refresh the table + [self tableView:tableContentView setObjectValue:[[data copy] autorelease] forTableColumn:[tableContentView tableColumnWithIdentifier:[contextInfo objectForKey:@"column"]] row:row]; + } else { + [tableValues replaceObjectInRow:row column:column withObject:[[data copy] autorelease]]; + } + } + } + + if(fieldEditor) { + [fieldEditor release]; + fieldEditor = nil; + } + + [[tableDocumentInstance parentWindow] makeFirstResponder:tableContentView]; +} + #pragma mark - #pragma mark Filter Table @@ -3899,7 +3938,8 @@ } } - SPFieldEditorController *fieldEditor = [[SPFieldEditorController alloc] init]; + if(fieldEditor) [fieldEditor release], fieldEditor = nil; + fieldEditor = [[SPFieldEditorController alloc] init]; [fieldEditor setTextMaxLength:fieldLength]; [fieldEditor setFieldType:(fieldType==nil) ? @"" : fieldType]; @@ -3910,44 +3950,18 @@ if ([cellValue isNSNull]) cellValue = [NSString stringWithString:[prefs objectForKey:SPNullValue]]; - id editData = [[fieldEditor editWithObject:cellValue - fieldName:[[aTableColumn headerCell] stringValue] - usingEncoding:[mySQLConnection stringEncoding] - isObjectBlob:isBlob - isEditable:isFieldEditable - withWindow:[tableDocumentInstance parentWindow]] retain]; - - if (editData) { - if (!isEditingRow && [tablesListInstance tableType] != SPTableTypeView) { - [oldRow setArray:[tableValues rowContentsAtIndex:rowIndex]]; - isEditingRow = YES; - currentlyEditingRow = rowIndex; - } - - if ([editData isKindOfClass:[NSString class]] - && [editData isEqualToString:[prefs objectForKey:SPNullValue]] - && [[NSArrayObjectAtIndex(dataColumns, [[aTableColumn identifier] integerValue]) objectForKey:@"null"] boolValue]) - { - [editData release]; - editData = [[NSNull null] retain]; - } - if(isFieldEditable) { - if([tablesListInstance tableType] == SPTableTypeView) { - // since in a view we're editing a field rather than a row - isEditingRow = NO; - // update the field and refresh the table - [self tableView:aTableView setObjectValue:[[editData copy] autorelease] forTableColumn:aTableColumn row:rowIndex]; - } else { - [tableValues replaceObjectInRow:rowIndex column:[[aTableColumn identifier] integerValue] withObject:[[editData copy] autorelease]]; - } - } - } - - [fieldEditor release]; - - if (editData) [editData release]; - - [[tableDocumentInstance parentWindow] makeFirstResponder:tableContentView]; + [fieldEditor editWithObject:cellValue + fieldName:[[aTableColumn headerCell] stringValue] + usingEncoding:[mySQLConnection stringEncoding] + isObjectBlob:isBlob + isEditable:isFieldEditable + withWindow:[tableDocumentInstance parentWindow] + sender:self + contextInfo:[NSDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithInteger:rowIndex], @"row", + [aTableColumn identifier], @"column", + [NSNumber numberWithBool:isFieldEditable], @"isFieldEditable", + nil]]; return NO; } @@ -4466,6 +4480,8 @@ [NSObject cancelPreviousPerformRequestsWithTarget:self]; [NSObject cancelPreviousPerformRequestsWithTarget:tableContentView]; + if(fieldEditor) [fieldEditor release], fieldEditor = nil; + [self clearTableLoadTimer]; [tableValues release]; pthread_mutex_destroy(&tableValuesLock); |