diff options
author | Bibiko <bibiko@eva.mpg.de> | 2010-09-15 13:58:10 +0000 |
---|---|---|
committer | Bibiko <bibiko@eva.mpg.de> | 2010-09-15 13:58:10 +0000 |
commit | 00ac602d8ca381ce2086b3aa10ca21861e61aa6a (patch) | |
tree | 79ad2cfa74fdd17168a7c3ec23dd39aa91da0c9c /Source | |
parent | c5d5b115cae8eb5f8295365ffa463a6561b9cccb (diff) | |
download | sequelpro-00ac602d8ca381ce2086b3aa10ca21861e61aa6a.tar.gz sequelpro-00ac602d8ca381ce2086b3aa10ca21861e61aa6a.tar.bz2 sequelpro-00ac602d8ca381ce2086b3aa10ca21861e61aa6a.zip |
• some further bit field editing preparations
• re-enabled length checking while editing in FieldEditorSheet
• FieldEditorSheet now shows field type declaration
• some preparations for BINARY editing in FieldEditorSheet
Diffstat (limited to 'Source')
-rw-r--r-- | Source/SPDataCellFormatter.h | 2 | ||||
-rw-r--r-- | Source/SPDataCellFormatter.m | 25 | ||||
-rw-r--r-- | Source/SPFieldEditorController.h | 99 | ||||
-rw-r--r-- | Source/SPFieldEditorController.m | 491 | ||||
-rw-r--r-- | Source/SPTableContent.m | 43 |
5 files changed, 437 insertions, 223 deletions
diff --git a/Source/SPDataCellFormatter.h b/Source/SPDataCellFormatter.h index a669fdc6..66bf442e 100644 --- a/Source/SPDataCellFormatter.h +++ b/Source/SPDataCellFormatter.h @@ -28,10 +28,12 @@ @interface SPDataCellFormatter : NSFormatter { NSInteger textLimit; + NSString *fieldType; } #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 @property NSInteger textLimit; + @property NSString* fieldType; #else -(NSInteger)textLimit; -(void)setTextLimit:(NSInteger)limit; diff --git a/Source/SPDataCellFormatter.m b/Source/SPDataCellFormatter.m index d373d608..9e7944f8 100644 --- a/Source/SPDataCellFormatter.m +++ b/Source/SPDataCellFormatter.m @@ -31,6 +31,7 @@ #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 @synthesize textLimit; + @synthesize fieldType; #else -(NSInteger)textLimit { @@ -71,28 +72,40 @@ return [[[NSAttributedString alloc] initWithString:[self stringForObjectValue:anObject] attributes:attributes] autorelease]; } - - - (BOOL)isPartialStringValid:(NSString *)partialString newEditingString:(NSString **)newString errorDescription:(NSString **)error { // No limit set or partialString is NULL value string allow editing if (textLimit == 0 || [partialString isEqualToString:[[NSUserDefaults standardUserDefaults] objectForKey:SPNullValue]]) return YES; - + // A single character over the length of the string - likely typed. Prevent the change. if ([partialString length] == textLimit + 1) { [SPTooltip showWithObject:[NSString stringWithFormat:NSLocalizedString(@"Maximum text length is set to %ld.", @"Maximum text length is set to %ld."), (long)textLimit]]; return NO; } - + // If the string is considerably longer than the limit, likely pasted. Accept but truncate. if ([partialString length] > textLimit) { [SPTooltip showWithObject:[NSString stringWithFormat:NSLocalizedString(@"Maximum text length is set to %ld. Inserted text was truncated.", @"Maximum text length is set to %ld. Inserted text was truncated."), (long)textLimit]]; *newString = [NSString stringWithString:[partialString substringToIndex:textLimit]]; return NO; } - - // Length inside limit. + + // Check for BIT fields whether 1 or 0 are typed + if(fieldType && [fieldType length] && [[fieldType uppercaseString] isEqualToString:@"BIT"]) { + + if(partialString == nil || ![partialString length]) return YES; + + // TODO HansJB + return YES; + // if() { + // [SPTooltip showWithObject:NSLocalizedString(@"For BIT fields only “1” or “0” are allowed.", @"For BIT fields only “1” or “0” are allowed.")]; + // return NO; + // } + + } + + return YES; } diff --git a/Source/SPFieldEditorController.h b/Source/SPFieldEditorController.h index 6ba9018b..e3877a2d 100644 --- a/Source/SPFieldEditorController.h +++ b/Source/SPFieldEditorController.h @@ -24,7 +24,7 @@ #import <Cocoa/Cocoa.h> -@interface SPFieldEditorController : NSWindowController +@interface SPFieldEditorController : NSWindowController { IBOutlet id editSheetProgressBar; IBOutlet id editSheetSegmentControl; @@ -41,11 +41,94 @@ IBOutlet id editSheetOpenButton; IBOutlet id editSheetFieldName; + IBOutlet id bitSheet; + IBOutlet NSTextField *bitSheetFieldName; + IBOutlet NSTextField *bitSheetHexTextField; + IBOutlet NSTextField *bitSheetIntegerTextField; + IBOutlet NSTextField *bitSheetOctalTextField; + IBOutlet NSButton *bitSheetOkButton; + IBOutlet NSButton *bitSheetCloseButton; + IBOutlet NSButton *bitSheetBitButton0; + IBOutlet NSButton *bitSheetBitButton1; + IBOutlet NSButton *bitSheetBitButton2; + IBOutlet NSButton *bitSheetBitButton3; + IBOutlet NSButton *bitSheetBitButton4; + IBOutlet NSButton *bitSheetBitButton5; + IBOutlet NSButton *bitSheetBitButton6; + IBOutlet NSButton *bitSheetBitButton7; + IBOutlet NSButton *bitSheetBitButton8; + IBOutlet NSButton *bitSheetBitButton9; + IBOutlet NSButton *bitSheetBitButton10; + IBOutlet NSButton *bitSheetBitButton11; + IBOutlet NSButton *bitSheetBitButton12; + IBOutlet NSButton *bitSheetBitButton13; + IBOutlet NSButton *bitSheetBitButton14; + IBOutlet NSButton *bitSheetBitButton15; + IBOutlet NSButton *bitSheetBitButton16; + IBOutlet NSButton *bitSheetBitButton17; + IBOutlet NSButton *bitSheetBitButton18; + IBOutlet NSButton *bitSheetBitButton19; + IBOutlet NSButton *bitSheetBitButton20; + IBOutlet NSButton *bitSheetBitButton21; + IBOutlet NSButton *bitSheetBitButton22; + IBOutlet NSButton *bitSheetBitButton23; + IBOutlet NSButton *bitSheetBitButton24; + IBOutlet NSButton *bitSheetBitButton25; + IBOutlet NSButton *bitSheetBitButton26; + IBOutlet NSButton *bitSheetBitButton27; + IBOutlet NSButton *bitSheetBitButton28; + IBOutlet NSButton *bitSheetBitButton29; + IBOutlet NSButton *bitSheetBitButton30; + IBOutlet NSButton *bitSheetBitButton31; + IBOutlet NSButton *bitSheetBitButton32; + IBOutlet NSButton *bitSheetBitButton33; + IBOutlet NSButton *bitSheetBitButton34; + IBOutlet NSButton *bitSheetBitButton35; + IBOutlet NSButton *bitSheetBitButton36; + IBOutlet NSButton *bitSheetBitButton37; + IBOutlet NSButton *bitSheetBitButton38; + IBOutlet NSButton *bitSheetBitButton39; + IBOutlet NSButton *bitSheetBitButton40; + IBOutlet NSButton *bitSheetBitButton41; + IBOutlet NSButton *bitSheetBitButton42; + IBOutlet NSButton *bitSheetBitButton43; + IBOutlet NSButton *bitSheetBitButton44; + IBOutlet NSButton *bitSheetBitButton45; + IBOutlet NSButton *bitSheetBitButton46; + IBOutlet NSButton *bitSheetBitButton47; + IBOutlet NSButton *bitSheetBitButton48; + IBOutlet NSButton *bitSheetBitButton49; + IBOutlet NSButton *bitSheetBitButton50; + IBOutlet NSButton *bitSheetBitButton51; + IBOutlet NSButton *bitSheetBitButton52; + IBOutlet NSButton *bitSheetBitButton53; + IBOutlet NSButton *bitSheetBitButton54; + IBOutlet NSButton *bitSheetBitButton55; + IBOutlet NSButton *bitSheetBitButton56; + IBOutlet NSButton *bitSheetBitButton57; + IBOutlet NSButton *bitSheetBitButton58; + IBOutlet NSButton *bitSheetBitButton59; + IBOutlet NSButton *bitSheetBitButton60; + IBOutlet NSButton *bitSheetBitButton61; + IBOutlet NSButton *bitSheetBitButton62; + IBOutlet NSButton *bitSheetBitButton63; + IBOutlet NSTextField *bitSheetBitLabel0; + IBOutlet NSTextField *bitSheetBitLabel8; + IBOutlet NSTextField *bitSheetBitLabel16; + IBOutlet NSTextField *bitSheetBitLabel24; + IBOutlet NSTextField *bitSheetBitLabel32; + IBOutlet NSTextField *bitSheetBitLabel40; + IBOutlet NSTextField *bitSheetBitLabel48; + IBOutlet NSTextField *bitSheetBitLabel56; + id sheetEditData; BOOL editSheetWillBeInitialized; - BOOL isBlob; + BOOL _isBlob; + BOOL _isEditable; NSInteger quickLookCloseMarker; NSStringEncoding encoding; + NSString *fieldType; + NSString *fieldEncoding; NSString *stringValue; NSString *tmpFileName; NSString *tmpDirPath; @@ -57,6 +140,8 @@ BOOL wasCutPaste; BOOL selectionChanged; + NSArray *bitSheetBitButtonsArray; + NSUserDefaults *prefs; NSDictionary *qlTypes; @@ -74,10 +159,18 @@ - (IBAction)quickLookFormatButton:(id)sender; - (IBAction)dropImage:(id)sender; -- (id)editWithObject:(id)data fieldName:(NSString*)fieldName usingEncoding:(NSStringEncoding)anEncoding +- (IBAction)closeBitSheet:(id)sender; +- (IBAction)bitSheetSelectBit0:(id)sender; +- (IBAction)bitSheetBitButtonWasClicked:(id)sender; +- (IBAction)bitSheetOperatorButtonWasClicked:(id)sender; + + +- (id)editWithObject:(id)data fieldName:(NSString*)fieldName usingEncoding:(NSStringEncoding)anEncoding isObjectBlob:(BOOL)isFieldBlob isEditable:(BOOL)isEditable withWindow:(NSWindow *)theWindow; - (void)setTextMaxLength:(unsigned long long)length; +- (void)setFieldType:(NSString*)aType; +- (void)setFieldEncoding:(NSString*)aEncoding; - (void)processPasteImageData; - (void)processUpdatedImageData:(NSData *)data; diff --git a/Source/SPFieldEditorController.m b/Source/SPFieldEditorController.m index 7bef2719..fa3029e1 100644 --- a/Source/SPFieldEditorController.m +++ b/Source/SPFieldEditorController.m @@ -44,7 +44,9 @@ counter = 0; maxTextLength = 0; stringValue = nil; - + _isEditable = NO; + _isBlob = NO; + prefs = [NSUserDefaults standardUserDefaults]; // Used for max text length recognition if last typed char is a non-space char @@ -52,13 +54,13 @@ // Allow the user to enter cmd+return to close the edit sheet in addition to fn+return [editSheetOkButton setKeyEquivalentModifierMask:NSCommandKeyMask]; - + allowUndo = NO; selectionChanged = NO; - + tmpDirPath = NSTemporaryDirectory(); tmpFileName = nil; - + NSMenu *menu = [editSheetQuickLookButton menu]; [menu setAutoenablesItems:NO]; NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Interpret data as:", @"Interpret data as:") action:NULL keyEquivalent:@""]; @@ -74,10 +76,10 @@ NSString *convError = nil; NSPropertyListFormat format; - NSData *defaultTypeData = [NSData dataWithContentsOfFile:[NSBundle pathForResource:@"EditorQuickLookTypes.plist" ofType:nil inDirectory:[[NSBundle mainBundle] bundlePath]] + NSData *defaultTypeData = [NSData dataWithContentsOfFile:[NSBundle pathForResource:@"EditorQuickLookTypes.plist" ofType:nil inDirectory:[[NSBundle mainBundle] bundlePath]] options:NSMappedRead error:&readError]; - NSDictionary *defaultQLTypes = [NSPropertyListSerialization propertyListFromData:defaultTypeData + NSDictionary *defaultQLTypes = [NSPropertyListSerialization propertyListFromData:defaultTypeData mutabilityOption:NSPropertyListImmutable format:&format errorDescription:&convError]; if(defaultQLTypes == nil || readError != nil || convError != nil) NSLog(@"Error while reading 'EditorQuickLookTypes.plist':\n%@\n%@", [readError localizedDescription], convError); @@ -106,9 +108,14 @@ } qlTypes = [NSDictionary dictionaryWithObject:qlTypesItems forKey:SPQuickLookTypes]; [qlTypesItems release]; + + bitSheetBitButtonsArray = nil; + fieldType = @""; + fieldEncoding = @""; + } return self; - + } - (void)dealloc @@ -130,118 +137,134 @@ maxTextLength = length; } -- (id)editWithObject:(id)data fieldName:(NSString*)fieldName usingEncoding:(NSStringEncoding)anEncoding +- (void)setFieldType:(NSString*)aType +{ + fieldType = aType; +} + +- (void)setFieldEncoding:(NSString*)aEncoding +{ + fieldEncoding = aEncoding; +} + +- (id)editWithObject:(id)data fieldName:(NSString*)fieldName usingEncoding:(NSStringEncoding)anEncoding isObjectBlob:(BOOL)isFieldBlob isEditable:(BOOL)isEditable withWindow:(NSWindow *)theWindow { - // If required, use monospaced fonts - if (![prefs objectForKey:SPFieldEditorSheetFont]) { - [editTextView setFont:([prefs boolForKey:SPUseMonospacedFonts]) ? [NSFont fontWithName:SPDefaultMonospacedFontName size:[NSFont smallSystemFontSize]] : [NSFont systemFontOfSize:[NSFont smallSystemFontSize]]]; - } - else { - [editTextView setFont:[NSUnarchiver unarchiveObjectWithData:[prefs dataForKey:@"FieldEditorSheetFont"]]]; - } - [editTextView setContinuousSpellCheckingEnabled:[prefs boolForKey:SPBlobTextEditorSpellCheckingEnabled]]; + id usedSheet; - [hexTextView setFont:[NSFont fontWithName:SPDefaultMonospacedFontName size:[NSFont smallSystemFontSize]]]; + _isEditable = isEditable; - [editSheetFieldName setStringValue:[NSString stringWithFormat:@"%@: %@", NSLocalizedString(@"Field", @"Field"), fieldName]]; + if(NO && [fieldType length] && [fieldType isEqualToString:@"BIT"]) { + + usedSheet = bitSheet; + + [NSApp beginSheet:usedSheet modalForWindow:theWindow modalDelegate:self didEndSelector:nil contextInfo:nil]; - // hide all views in editSheet - [hexTextView setHidden:YES]; - [hexTextScrollView setHidden:YES]; - [editImage setHidden:YES]; - [editTextView setHidden:YES]; - [editTextScrollView setHidden:YES]; - - if (!isEditable) { - [editSheetOkButton setHidden:YES]; - [editSheetCancelButton setHidden:YES]; - [editSheetIsNotEditableCancelButton setHidden:NO]; - [editSheetOpenButton setEnabled:NO]; - } - - editSheetWillBeInitialized = YES; - - encoding = anEncoding; - - isBlob = isFieldBlob; - - sheetEditData = [data retain]; - - // hide all views in editSheet - [hexTextView setHidden:YES]; - [hexTextScrollView setHidden:YES]; - [editImage setHidden:YES]; - [editTextView setHidden:YES]; - [editTextScrollView setHidden:YES]; - - // Hide QuickLook button and text/iamge/hex control for text data - [editSheetQuickLookButton setHidden:(!isBlob)]; - [editSheetSegmentControl setHidden:(!isBlob)]; - - // Set window's min size since no segment and quicklook buttons are hidden - if (isBlob) { - [editSheet setFrameAutosaveName:@"SPFieldEditorBlobSheet"]; - [editSheet setMinSize:NSMakeSize(560, 200)]; } else { - [editSheet setFrameAutosaveName:@"SPFieldEditorTextSheet"]; - [editSheet setMinSize:NSMakeSize(340, 150)]; - } - - [editTextView setEditable:isEditable]; - [editImage setEditable:isEditable]; - - [NSApp beginSheet:editSheet modalForWindow:theWindow modalDelegate:self didEndSelector:nil contextInfo:nil]; - - [editSheetProgressBar startAnimation:self]; - - NSImage *image = nil; - if ( [sheetEditData isKindOfClass:[NSData class]] ) { - image = [[[NSImage alloc] initWithData:sheetEditData] autorelease]; - - // Set hex view to "" - load on demand only - [hexTextView setString:@""]; - - stringValue = [[NSString alloc] initWithData:sheetEditData encoding:encoding]; - if (stringValue == nil) - stringValue = [[NSString alloc] initWithData:sheetEditData encoding:NSASCIIStringEncoding]; - - [hexTextView setHidden:NO]; - [hexTextScrollView setHidden:NO]; + + usedSheet = editSheet; + + // If required, use monospaced fonts + if (![prefs objectForKey:SPFieldEditorSheetFont]) { + [editTextView setFont:([prefs boolForKey:SPUseMonospacedFonts]) ? [NSFont fontWithName:SPDefaultMonospacedFontName size:[NSFont smallSystemFontSize]] : [NSFont systemFontOfSize:[NSFont smallSystemFontSize]]]; + } + else { + [editTextView setFont:[NSUnarchiver unarchiveObjectWithData:[prefs dataForKey:@"FieldEditorSheetFont"]]]; + } + + [editTextView setContinuousSpellCheckingEnabled:[prefs boolForKey:SPBlobTextEditorSpellCheckingEnabled]]; + + [hexTextView setFont:[NSFont fontWithName:SPDefaultMonospacedFontName size:[NSFont smallSystemFontSize]]]; + + // Set field label + NSMutableString *label = [NSMutableString string]; + [label appendFormat:@"“%@”", fieldName]; + if([fieldType length] || maxTextLength > 0 || [fieldEncoding length]) + [label appendString:@" – "]; + if([fieldType length]) + [label appendString:fieldType]; + if(maxTextLength > 0) + [label appendFormat:@"(%ld) ", maxTextLength]; + if([fieldEncoding length]) + [label appendString:fieldEncoding]; + + [editSheetFieldName setStringValue:[NSString stringWithFormat:@"%@: %@%", NSLocalizedString(@"Field", @"Field"), label]]; + + // hide all views in editSheet + [hexTextView setHidden:YES]; + [hexTextScrollView setHidden:YES]; [editImage setHidden:YES]; [editTextView setHidden:YES]; [editTextScrollView setHidden:YES]; - [editSheetSegmentControl setSelectedSegment:2]; - } else { - stringValue = [sheetEditData retain]; - - [hexTextView setString:@""]; - + + if (!_isEditable) { + [editSheetOkButton setHidden:YES]; + [editSheetCancelButton setHidden:YES]; + [editSheetIsNotEditableCancelButton setHidden:NO]; + [editSheetOpenButton setEnabled:NO]; + } + + editSheetWillBeInitialized = YES; + + encoding = anEncoding; + + _isBlob = isFieldBlob; + BOOL _isBINARY = ([fieldType isEqualToString:@"BINARY"] || [fieldType isEqualToString:@"VARBINARY"]); + + sheetEditData = [data retain]; + + // hide all views in editSheet [hexTextView setHidden:YES]; [hexTextScrollView setHidden:YES]; [editImage setHidden:YES]; - [editTextView setHidden:NO]; - [editTextScrollView setHidden:NO]; - [editSheetSegmentControl setSelectedSegment:0]; - } - - if (image) { - [editImage setImage:image]; - - [hexTextView setHidden:YES]; - [hexTextScrollView setHidden:YES]; - [editImage setHidden:NO]; [editTextView setHidden:YES]; [editTextScrollView setHidden:YES]; - [editSheetSegmentControl setSelectedSegment:1]; - } else { - [editImage setImage:nil]; - } - if (stringValue) { - [editTextView setString:stringValue]; - if(image == nil) { + // Hide QuickLook button and text/iamge/hex control for text data + [editSheetQuickLookButton setHidden:(!_isBlob && !_isBINARY)]; + [editSheetSegmentControl setHidden:(!_isBlob && !_isBINARY)]; + + [editSheetSegmentControl setEnabled:YES forSegment:1]; + + // Set window's min size since no segment and quicklook buttons are hidden + if (_isBlob || _isBINARY) { + [editSheet setFrameAutosaveName:@"SPFieldEditorBlobSheet"]; + [editSheet setMinSize:NSMakeSize(560, 200)]; + } else { + [editSheet setFrameAutosaveName:@"SPFieldEditorTextSheet"]; + [editSheet setMinSize:NSMakeSize(340, 150)]; + } + + [editTextView setEditable:_isEditable]; + [editImage setEditable:_isEditable]; + + [NSApp beginSheet:usedSheet modalForWindow:theWindow modalDelegate:self didEndSelector:nil contextInfo:nil]; + + [editSheetProgressBar startAnimation:self]; + + NSImage *image = nil; + if ( [sheetEditData isKindOfClass:[NSData class]] ) { + image = [[[NSImage alloc] initWithData:sheetEditData] autorelease]; + + // Set hex view to "" - load on demand only + [hexTextView setString:@""]; + + stringValue = [[NSString alloc] initWithData:sheetEditData encoding:encoding]; + if (stringValue == nil) + stringValue = [[NSString alloc] initWithData:sheetEditData encoding:NSASCIIStringEncoding]; + + [hexTextView setHidden:NO]; + [hexTextScrollView setHidden:NO]; + [editImage setHidden:YES]; + [editTextView setHidden:YES]; + [editTextScrollView setHidden:YES]; + [editSheetSegmentControl setSelectedSegment:2]; + } else { + stringValue = [sheetEditData retain]; + + [hexTextView setString:@""]; + [hexTextView setHidden:YES]; [hexTextScrollView setHidden:YES]; [editImage setHidden:YES]; @@ -250,45 +273,75 @@ [editSheetSegmentControl setSelectedSegment:0]; } - // Locate the caret in editTextView - // (to select all takes a bit time for large data) - [editTextView setSelectedRange:NSMakeRange(0,0)]; + if (image) { + [editImage setImage:image]; - // If the string content is NULL select NULL for convenience - if([stringValue isEqualToString:[prefs objectForKey:SPNullValue]]) - [editTextView setSelectedRange:NSMakeRange(0,[[editTextView string] length])]; + [hexTextView setHidden:YES]; + [hexTextScrollView setHidden:YES]; + [editImage setHidden:NO]; + [editTextView setHidden:YES]; + [editTextScrollView setHidden:YES]; + [editSheetSegmentControl setSelectedSegment:1]; + } else { + [editImage setImage:nil]; + } + if (stringValue) { + [editTextView setString:stringValue]; + + if(image == nil) { + if(!_isBINARY) { + [hexTextView setHidden:YES]; + [hexTextScrollView setHidden:YES]; + } else { + [editSheetSegmentControl setEnabled:NO forSegment:1]; + } + [editImage setHidden:YES]; + [editTextView setHidden:NO]; + [editTextScrollView setHidden:NO]; + [editSheetSegmentControl setSelectedSegment:0]; + } + + // Locate the caret in editTextView + // (to select all takes a bit time for large data) + [editTextView setSelectedRange:NSMakeRange(0,0)]; + + // If the string content is NULL select NULL for convenience + if([stringValue isEqualToString:[prefs objectForKey:SPNullValue]]) + [editTextView setSelectedRange:NSMakeRange(0,[[editTextView string] length])]; + + // Set focus + if(image == nil) + [editSheet makeFirstResponder:editTextView]; + else + [editSheet makeFirstResponder:editImage]; + + [stringValue release], stringValue = nil; + } + + editSheetWillBeInitialized = NO; + + [editSheetProgressBar stopAnimation:self]; - // Set focus - if(image == nil) - [editSheet makeFirstResponder:editTextView]; - else - [editSheet makeFirstResponder:editImage]; - - [stringValue release], stringValue = nil; } - - editSheetWillBeInitialized = NO; - - [editSheetProgressBar stopAnimation:self]; // wait for editSheet - NSModalSession session = [NSApp beginModalSessionForWindow:editSheet]; + NSModalSession session = [NSApp beginModalSessionForWindow:usedSheet]; NSInteger cycleCounter = 0; BOOL doGroupDueToChars = NO; for (;;) { // Break the run loop if editSheet was closed - if ([NSApp runModalSession:session] != NSRunContinuesResponse - || ![editSheet isVisible]) + if ([NSApp runModalSession:session] != NSRunContinuesResponse + || ![usedSheet isVisible]) break; // Execute code on DefaultRunLoop (like displaying a tooltip) - [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode + [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]; // 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 + if([[NSApp currentEvent] type] == NSKeyDown && ( [[[NSApp currentEvent] charactersIgnoringModifiers] isEqualToString:@" "] || [[NSApp currentEvent] keyCode] == 36 @@ -317,16 +370,16 @@ } [NSApp endModalSession:session]; - [editSheet orderOut:nil]; - [NSApp endSheet:editSheet]; + [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]; - - return ( editSheetReturnCode && isEditable ) ? sheetEditData : nil; + + return ( editSheetReturnCode && _isEditable ) ? sheetEditData : nil; } /* @@ -345,6 +398,25 @@ wasCutPaste = YES; } +- (IBAction)closeBitSheet:(id)sender +{ + + editSheetReturnCode = 0; + + if(sender == bitSheetOkButton && _isEditable) { + [NSApp stopModal]; + editSheetReturnCode = 1; + } + + [NSApp abortModal]; + +} + +- (IBAction)bitSheetOperatorButtonWasClicked:(id)sender +{ + +} + - (IBAction)closeEditSheet:(id)sender { @@ -363,7 +435,7 @@ [NSApp stopModal]; editSheetReturnCode = 1; } - + // Delete all QuickLook temp files if it was invoked if(tmpFileName != nil) { NSArray *dirContents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:tmpDirPath error:nil]; @@ -375,17 +447,17 @@ } } } - + [NSApp abortModal]; } - (IBAction)openEditSheet:(id)sender { - [[NSOpenPanel openPanel] beginSheetForDirectory:nil - file:@"" - modalForWindow:[self window] - modalDelegate:self didEndSelector:@selector(openPanelDidEnd:returnCode:contextInfo:) + [[NSOpenPanel openPanel] beginSheetForDirectory:nil + file:@"" + modalForWindow:[self window] + modalDelegate:self didEndSelector:@selector(openPanelDidEnd:returnCode:contextInfo:) contextInfo:NULL]; } @@ -435,12 +507,12 @@ * Saves a file containing the content of the editSheet */ - (IBAction)saveEditSheet:(id)sender -{ - [[NSSavePanel savePanel] beginSheetForDirectory:nil - file:@"" - modalForWindow:[self window] - modalDelegate:self - didEndSelector:@selector(savePanelDidEnd:returnCode:contextInfo:) +{ + [[NSSavePanel savePanel] beginSheetForDirectory:nil + file:@"" + modalForWindow:[self window] + modalDelegate:self + didEndSelector:@selector(savePanelDidEnd:returnCode:contextInfo:) contextInfo:NULL]; } @@ -450,24 +522,24 @@ - (void)savePanelDidEnd:(NSSavePanel *)panel returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo { if (returnCode == NSOKButton) { - + [editSheetProgressBar startAnimation:self]; - + NSString *fileName = [panel filename]; - + // Write binary field types directly to the file if ( [sheetEditData isKindOfClass:[NSData class]] ) { [sheetEditData writeToFile:fileName atomically:YES]; - + // Write other field types' representations to the file via the current encoding - } + } else { [[sheetEditData description] writeToFile:fileName atomically:YES encoding:encoding error:NULL]; } - + [editSheetProgressBar stopAnimation:self]; } } @@ -480,37 +552,37 @@ if (returnCode == NSOKButton) { NSString *fileName = [panel filename]; NSString *contents = nil; - + editSheetWillBeInitialized = YES; - + [editSheetProgressBar startAnimation:self]; - + // free old data if ( sheetEditData != nil ) { [sheetEditData release]; } - + // load new data/images sheetEditData = [[NSData alloc] initWithContentsOfFile:fileName]; - + NSImage *image = [[NSImage alloc] initWithData:sheetEditData]; contents = [[NSString alloc] initWithData:sheetEditData encoding:encoding]; if (contents == nil) contents = [[NSString alloc] initWithData:sheetEditData encoding:NSASCIIStringEncoding]; - + // set the image preview, string contents and hex representation [editImage setImage:image]; - - + + if(contents) [editTextView setString:contents]; else [editTextView setString:@""]; - + // Load hex data only if user has already displayed them if(![[hexTextView string] isEqualToString:@""]) [hexTextView setString:[sheetEditData dataToFormattedHexString]]; - + // If the image cell now contains a valid image, select the image view if (image) { [editSheetSegmentControl setSelectedSegment:1]; @@ -519,7 +591,7 @@ [editImage setHidden:NO]; [editTextView setHidden:YES]; [editTextScrollView setHidden:YES]; - + // Otherwise deselect the image view } else { [editSheetSegmentControl setSelectedSegment:0]; @@ -529,7 +601,7 @@ [editTextView setHidden:NO]; [editTextScrollView setHidden:NO]; } - + [image release]; if(contents) [contents release]; @@ -559,10 +631,10 @@ // if data are binary if ( [sheetEditData isKindOfClass:[NSData class]] && !isText) { [sheetEditData writeToFile:tmpFileName atomically:YES]; - + // write other field types' representations to the file via the current encoding } else { - + // if "html" type try to set the HTML charset - not yet completed if([type isEqualToString:@"html"]) { @@ -607,7 +679,7 @@ // Init QuickLook id ql = [NSClassFromString(@"QLPreviewPanel") sharedPreviewPanel]; - + [[ql delegate] setDelegate:self]; [ql setURLs:[NSArray arrayWithObject: [NSURL fileURLWithPath:tmpFileName]] currentIndex:0 preservingDisplayState:YES]; @@ -622,21 +694,21 @@ [ql setEnableDragNDrop:NO]; // Order out QuickLook with animation effect according to self:previewPanel:frameForURL: [ql makeKeyAndOrderFrontWithEffect:2]; // 1 = fade in - + // quickLookCloseMarker == 1 break the modal session quickLookCloseMarker = 0; - + [editSheetProgressBar stopAnimation:self]; // Run QuickLook in its own modal seesion for event handling NSModalSession session = [NSApp beginModalSessionForWindow:ql]; for (;;) { // Conditions for closing QuickLook - if ([NSApp runModalSession:session] != NSRunContinuesResponse - || quickLookCloseMarker == 1 - || ![ql isVisible]) + if ([NSApp runModalSession:session] != NSRunContinuesResponse + || quickLookCloseMarker == 1 + || ![ql isVisible]) break; - [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode + [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]; } @@ -649,7 +721,7 @@ // Load QL via framework (SDK 10.5 but SP runs on 10.6) // TODO: This is an hack in order to be able to support QuickLook on Mac OS X 10.5 and 10.6 // as long as SP will be compiled against SDK 10.5. - // If SP will be compiled against SDK 10.6 we can use the standard way by using + // If SP will be compiled against SDK 10.6 we can use the standard way by using // the QuickLookUI which is part of the Quartz.framework. See Developer example "QuickLookDownloader" // file:///Developer/Documentation/DocSets/com.apple.adc.documentation.AppleSnowLeopard.CoreReference.docset/Contents/Resources/Documents/samplecode/QuickLookDownloader/index.html#//apple_ref/doc/uid/DTS40009082 else if([[NSBundle bundleWithPath:@"/System/Library/Frameworks/Quartz.framework/Frameworks/QuickLookUI.framework"] load]) { @@ -720,18 +792,18 @@ // If an empty frame is returned then the panel will fade in/out instead - (NSRect)previewPanel:(NSPanel*)panel frameForURL:(NSURL*)URL { - + // Close modal session defined in invokeQuickLookOfType: // if user closes the QuickLook view quickLookCloseMarker = 1; - + // Return the App's middle point NSRect mwf = [[NSApp mainWindow] frame]; return NSMakeRect( mwf.origin.x+mwf.size.width/2, mwf.origin.y+mwf.size.height/2, 5, 5); - + } // QuickLook delegates for SDK 10.6 // It should return the frame for the item represented by the URL @@ -755,33 +827,33 @@ { editSheetWillBeInitialized = YES; - + NSImage *image = nil; - + image = [[[NSImage alloc] initWithPasteboard:[NSPasteboard generalPasteboard]] autorelease]; if (image) { - + if (nil != sheetEditData) [sheetEditData release]; - + [editImage setImage:image]; - + if( sheetEditData ) [sheetEditData release]; sheetEditData = [[NSData alloc] initWithData:[image TIFFRepresentationUsingCompression:NSTIFFCompressionLZW factor:1]]; - + NSString *contents = [[NSString alloc] initWithData:sheetEditData encoding:encoding]; if (contents == nil) contents = [[NSString alloc] initWithData:sheetEditData encoding:NSASCIIStringEncoding]; - + // Set the string contents and hex representation if(contents) [editTextView setString:contents]; if(![[hexTextView string] isEqualToString:@""]) [hexTextView setString:[sheetEditData dataToFormattedHexString]]; - + [contents release]; - + } - + editSheetWillBeInitialized = NO; } /* @@ -790,11 +862,11 @@ */ - (void)processUpdatedImageData:(NSData *)data { - + editSheetWillBeInitialized = YES; - + if (nil != sheetEditData) [sheetEditData release]; - + // If the image was not processed, set a blank string as the contents of the edit and hex views. if ( data == nil ) { sheetEditData = [[NSData alloc] init]; @@ -803,26 +875,26 @@ editSheetWillBeInitialized = NO; return; } - + // Process the provided image sheetEditData = [[NSData alloc] initWithData:data]; NSString *contents = [[NSString alloc] initWithData:data encoding:encoding]; if (contents == nil) contents = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]; - + // Set the string contents and hex representation if(contents) [editTextView setString:contents]; if(![[hexTextView string] isEqualToString:@""]) [hexTextView setString:[sheetEditData dataToFormattedHexString]]; - + [contents release]; editSheetWillBeInitialized = NO; } - (IBAction)dropImage:(id)sender { - + // If the image was deleted, set a blank string as the contents of the edit and hex views. // The actual dropped image processing is handled by processUpdatedImageData:. if ( [editImage image] == nil ) { @@ -835,6 +907,19 @@ } #pragma mark - +#pragma mark BIT Field Sheet + +- (IBAction)bitSheetSelectBit0:(id)sender +{ + +} + +- (IBAction)bitSheetBitButtonWasClicked:(id)sender +{ + +} + +#pragma mark - #pragma mark Delegates /* @@ -843,7 +928,7 @@ - (BOOL)textView:(NSTextView *)textView shouldChangeTextInRange:(NSRange)r replacementString:(NSString *)replacementString { - if(textView == editTextView && maxTextLength > 0 + if(textView == editTextView && (maxTextLength > 0) && ![ [[[editTextView textStorage] string] stringByAppendingString:replacementString] isEqualToString:[prefs objectForKey:SPNullValue]]) { NSInteger newLength; @@ -861,30 +946,30 @@ if (r.location==NSNotFound) return NO; // Length checking while using the Input Manager (eg for Japanese) - if ([textView hasMarkedText] && maxTextLength > 0 && r.location < maxTextLength) + if ([textView hasMarkedText] && (maxTextLength > 0) && (r.location < maxTextLength)) // User tries to insert a new char but max text length was already reached - return NO - if( !r.length && [[textView textStorage] length] >= maxTextLength ) { + if( !r.length && ([[textView textStorage] length] >= maxTextLength) ) { [SPTooltip showWithObject:[NSString stringWithFormat:NSLocalizedString(@"Maximum text length is set to %llu.", @"Maximum text length is set to %llu."), maxTextLength]]; [textView unmarkText]; return NO; } - // otherwise allow it if insertion point is valid for eg + // otherwise allow it if insertion point is valid for eg // a VARCHAR(3) field filled with two Chinese chars and one inserts the // third char by typing its pronounciation "wo" - 2 Chinese chars plus "wo" would give // 4 which is larger than max length. // TODO this doesn't solve the problem of inserting more than one char. For now // that part which won't be saved will be hilited if user pressed the OK button. - else if (r.location < maxTextLength) + else if (r.location < maxTextLength) return YES; // Calculate the length of the text after the change. - newLength=[[textView textStorage] length]+[replacementString length]-r.length; + newLength=[[[textView textStorage] string] length]+[replacementString length]-r.length; - // If it's too long, disallow the change but try + // If it's too long, disallow the change but try // to insert a text chunk partially to maxTextLength. - if (newLength>maxTextLength) { - - if(maxTextLength-[[textView textStorage] length]+[textView selectedRange].length <= [replacementString length]) { + if (newLength > maxTextLength) { + + if((maxTextLength-[[textView textStorage] length]+[textView selectedRange].length) <= [replacementString length]) { if(maxTextLength-[[textView textStorage] length]+[textView selectedRange].length) [SPTooltip showWithObject:[NSString stringWithFormat:NSLocalizedString(@"Maximum text length is set to %llu. Inserted text was truncated.", @"Maximum text length is set to %llu. Inserted text was truncated."), maxTextLength]]; else @@ -908,7 +993,7 @@ { // Do nothing if user really didn't changed text (e.g. for font size changing return) - if(!editTextViewWasChanged && (editSheetWillBeInitialized + if(!editTextViewWasChanged && (editSheetWillBeInitialized || (([[[notification object] textStorage] editedRange].length == 0) && ([[[notification object] textStorage] changeInLength] == 0)))) { // Inform the undo-grouping about the caret movement @@ -919,7 +1004,7 @@ // clear the image and hex (since i doubt someone can "type" a gif) [editImage setImage:nil]; [hexTextView setString:@""]; - + // free old data if ( sheetEditData != nil ) { [sheetEditData release]; @@ -927,7 +1012,7 @@ // set edit data to text sheetEditData = [[NSString stringWithString:[editTextView string]] retain]; - + } #pragma - @@ -946,7 +1031,7 @@ return YES; } } - + return NO; } diff --git a/Source/SPTableContent.m b/Source/SPTableContent.m index 90e7262a..79afe0a8 100644 --- a/Source/SPTableContent.m +++ b/Source/SPTableContent.m @@ -434,10 +434,14 @@ [dataCell setFormatter:[[SPDataCellFormatter new] autorelease]]; // Set field length limit if field is a varchar to match varchar length - if ([[columnDefinition objectForKey:@"typegrouping"] isEqualToString:@"string"]) { + if ([[columnDefinition objectForKey:@"typegrouping"] isEqualToString:@"string"] + || [[columnDefinition objectForKey:@"typegrouping"] isEqualToString:@"bit"]) { [[dataCell formatter] setTextLimit:[[columnDefinition objectForKey:@"length"] integerValue]]; } + // Set field type for validations + [[dataCell formatter] setFieldType:[columnDefinition objectForKey:@"type"]]; + // Set the data cell font according to the preferences [dataCell setFont:tableFont]; @@ -2485,7 +2489,7 @@ /** * Returns the WHERE argument to identify a row. * If "row" is -2, it uses the oldRow value. - * "excludeLimits" controls whether a LIMIT 1 is appended if no primary key was available to + * "excludeLimits" controls whether a LIMIT 1 is appended if no primary key was available to * uniquely identify the row. */ - (NSString *)argumentForRow:(NSInteger)row excludingLimits:(BOOL)excludeLimits @@ -2668,7 +2672,7 @@ [tableDocumentInstance startTaskWithDescription:NSLocalizedString(@"Checking field data for editing...", @"checking field data for editing task description")]; - // Actual check whether field can be identified bijectively + // Actual check whether field can be identified bijectively MCPResult *tempResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SELECT COUNT(1) FROM %@.%@ %@", [[columnDefinition objectForKey:@"db"] backtickQuotedString], [tableForColumn backtickQuotedString], @@ -2705,7 +2709,7 @@ [tableDocumentInstance endTask]; return [NSArray arrayWithObjects:[NSNumber numberWithInteger:-1], @"", nil]; } - + } [tableDocumentInstance endTask]; @@ -3480,7 +3484,7 @@ if ([tableDocumentInstance isWorking]) return NO; if ( aTableView == tableContentView ) { - + // Ensure that row is editable since it could contain "(not loaded)" columns together with // issue that the table has no primary key NSString *wherePart = [NSString stringWithString:[self argumentForRow:[tableContentView selectedRow]]]; @@ -3520,18 +3524,35 @@ isFieldEditable = ([[editStatus objectAtIndex:0] integerValue] == 1) ? YES : NO; } + NSString *fieldType = nil; + NSUInteger *fieldLength = 0; + NSString *fieldEncoding = nil; + // Retrieve the column defintion + for(id c in cqColumnDefinition) { + if([[c objectForKey:@"datacolumnindex"] isEqualToNumber:[aTableColumn identifier]]) { + fieldType = [c objectForKey:@"type"]; + if([c objectForKey:@"char_length"]) + fieldLength = [[c objectForKey:@"char_length"] integerValue]; + if([c objectForKey:@"charset_name"] && ![[c objectForKey:@"charset_name"] isEqualToString:@"binary"]) + fieldEncoding = [c objectForKey:@"charset_name"]; + break; + } + } + SPFieldEditorController *fieldEditor = [[SPFieldEditorController alloc] init]; - [fieldEditor setTextMaxLength:[[[aTableColumn dataCellForRow:rowIndex] formatter] textLimit]]; + [fieldEditor setTextMaxLength:fieldLength]; + [fieldEditor setFieldType:(fieldType==nil) ? @"" : fieldType]; + [fieldEditor setFieldEncoding:(fieldEncoding==nil) ? @"" : fieldEncoding]; id cellValue = [tableValues cellDataAtRow:rowIndex column:[[aTableColumn identifier] integerValue]]; if ([cellValue isNSNull]) cellValue = [NSString stringWithString:[prefs objectForKey:SPNullValue]]; id editData = [[fieldEditor editWithObject:cellValue - fieldName:[[aTableColumn headerCell] stringValue] + fieldName:[[aTableColumn headerCell] stringValue] usingEncoding:[mySQLConnection stringEncoding] - isObjectBlob:isBlob - isEditable:isFieldEditable + isObjectBlob:isBlob + isEditable:isFieldEditable withWindow:[tableDocumentInstance parentWindow]] retain]; if (editData) { @@ -3571,7 +3592,7 @@ return YES; } - + return YES; } @@ -3737,7 +3758,7 @@ row = [tableContentView editedRow]; column = [tableContentView editedColumn]; - // If cell editing mode and editing request comes + // If cell editing mode and editing request comes // from the keyboard show an error tooltip // or bypass if numberOfPossibleUpdateRows == 1 if([tableContentView isCellEditingMode]) { |