From f43ceef620d7d2f1325b4bbbdede58e5dc7d47f7 Mon Sep 17 00:00:00 2001 From: Bibiko Date: Thu, 2 Dec 2010 10:42:31 +0000 Subject: =?UTF-8?q?=E2=80=A2=20Bundle=20Command=20-=20for=20Data=20Table?= =?UTF-8?q?=20scope=20added=20the=20chance=20to=20specify=20the=20handling?= =?UTF-8?q?=20of=20BLOB=20fields=20(if=20underlying=20data=20are=20kind=20?= =?UTF-8?q?of=20NSData=20or=20GEOMETRY)=20as=20'Exclude',=20'Include',=20'?= =?UTF-8?q?save=20as=20image=20file=20-=20the=20data=20will=20be=20saved?= =?UTF-8?q?=20as=20tif=20file=20and=20the=20path=20will=20appear=20in=20th?= =?UTF-8?q?e=20table',=20'save=20as=20file=20-=20the=20data=20will=20be=20?= =?UTF-8?q?saved=20as=20raw=20dat=20file=20and=20the=20path=20will=20appea?= =?UTF-8?q?r=20in=20the=20table';=20for=20GEOMETRY=20fields=20if=20set=20t?= =?UTF-8?q?o=20'save=20as=20{image}=20file'=20the=20representation=20will?= =?UTF-8?q?=20be=20saved=20as=20PDF=20file=20otherwise=20the=20WKT=20strin?= =?UTF-8?q?g=20appears?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Interfaces/English.lproj/BundleEditor.xib | 232 +++++++++++++++++++++++++++++- Source/SPBundleEditorController.h | 5 + Source/SPBundleEditorController.m | 62 +++++++- Source/SPConstants.h | 6 + Source/SPConstants.m | 6 + Source/SPCopyTable.h | 7 +- Source/SPCopyTable.m | 168 +++++++++++++++++++--- 7 files changed, 456 insertions(+), 30 deletions(-) diff --git a/Interfaces/English.lproj/BundleEditor.xib b/Interfaces/English.lproj/BundleEditor.xib index 03cec12d..f3606a7b 100644 --- a/Interfaces/English.lproj/BundleEditor.xib +++ b/Interfaces/English.lproj/BundleEditor.xib @@ -23,7 +23,6 @@ YES - YES @@ -91,6 +90,7 @@ 4370 {143, 421} + YES @@ -191,6 +191,7 @@ {{1, 1}, {143, 421}} + @@ -201,6 +202,7 @@ -2147483392 {{-100, -100}, {15, 102}} + _doScroller: 0.99585062265396118 @@ -210,6 +212,7 @@ -2147483392 {{-100, -100}, {192, 15}} + 1 _doScroller: @@ -218,6 +221,7 @@ {{-1.5, 22.5}, {145, 423}} + 530 @@ -235,6 +239,7 @@ 292 {{-1, -1}, {32, 25}} + YES 67239424 @@ -263,6 +268,7 @@ 292 {{30, -1}, {32, 25}} + YES 67239424 @@ -287,6 +293,7 @@ 292 {{61, -1}, {32, 24}} + YES 71433792 @@ -392,6 +399,7 @@ {142, 23} + YES YES NO @@ -400,6 +408,7 @@ {142, 444} + NSView @@ -412,6 +421,7 @@ 288 {{17, 16}, {167, 22}} + YES -2076049856 @@ -445,6 +455,7 @@ 268 {{17, 280}, {167, 14}} + YES 68288064 @@ -466,6 +477,7 @@ 268 {{236, 332}, {167, 14}} + YES 68288064 @@ -482,6 +494,7 @@ 268 {{17, 332}, {167, 14}} + YES 68288064 @@ -531,6 +544,7 @@ {504, 110} + @@ -613,6 +627,7 @@ {{1, 1}, {504, 133}} + @@ -627,6 +642,7 @@ -2147483392 {{490, 1}, {15, 140}} + _doScroller: 1 @@ -637,6 +653,7 @@ -2147483392 {{-100, -100}, {87, 18}} + 1 _doScroller: @@ -646,6 +663,7 @@ {{20, 140}, {506, 135}} + 530 @@ -655,8 +673,9 @@ 268 - {{239, 308}, {161, 19}} + {{239, 309}, {161, 19}} + YES -1804468671 @@ -682,8 +701,9 @@ 268 - {{20, 308}, {161, 19}} + {{20, 309}, {161, 19}} + YES -1804468671 @@ -701,6 +721,7 @@ 265 {{440, 394}, {86, 17}} + YES 67239424 @@ -721,6 +742,7 @@ 268 {{236, 330}, {292, 18}} + YES -2080244224 @@ -781,6 +803,7 @@ {138, 69} + @@ -843,6 +866,7 @@ {{1, 1}, {504, 187}} + @@ -854,6 +878,7 @@ -2147483392 {{454, 1}, {15, 190}} + _doScroller: 1 @@ -864,6 +889,7 @@ -2147483392 {{-100, -100}, {87, 18}} + 1 _doScroller: @@ -873,6 +899,7 @@ {{20, 140}, {506, 189}} + 562 @@ -884,6 +911,7 @@ 289 {{435, 13}, {96, 28}} + 1 YES @@ -905,6 +933,7 @@ 289 {{309, 13}, {96, 28}} + YES 67239424 @@ -925,6 +954,7 @@ 292 {{20, 55}, {161, 22}} + YES 67239424 @@ -942,11 +972,46 @@ + + + 268 + {{236, 356}, {167, 22}} + + + YES + + -2076049856 + 133120 + + + 109199615 + 129 + + + 400 + 75 + + YES + + OtherViews + + YES + + + + -1 + 1 + YES + YES + 2 + + 268 {{236, 356}, {167, 22}} + YES -2076049856 @@ -980,6 +1045,7 @@ 292 {{17, 96}, {167, 22}} + YES -2076049856 @@ -1013,6 +1079,7 @@ 268 {{236, 391}, {167, 22}} + YES -2076049856 @@ -1046,6 +1113,7 @@ 268 {{17, 356}, {167, 22}} + YES -2076049856 @@ -1079,6 +1147,7 @@ 265 {{504, 354}, {25, 25}} + YES 67239424 @@ -1094,11 +1163,29 @@ 25 + + + 268 + {{186, 360}, {48, 14}} + + + YES + + 68288064 + 138544128 + and + + + + + + 268 {{186, 360}, {48, 14}} + YES 68288064 @@ -1115,6 +1202,7 @@ 292 {{239, 98}, {161, 19}} + YES -1804468671 @@ -1133,6 +1221,7 @@ 288 {{17, 78}, {95, 14}} + YES 68288064 @@ -1149,6 +1238,7 @@ 288 {{17, 38}, {167, 14}} + YES 68288064 @@ -1165,6 +1255,7 @@ 288 {{17, 118}, {167, 14}} + YES 68288064 @@ -1181,6 +1272,7 @@ 292 {{236, 118}, {167, 14}} + YES 68288064 @@ -1197,6 +1289,7 @@ 268 {{236, 414}, {167, 14}} + YES 68288064 @@ -1213,6 +1306,7 @@ 268 {{17, 332}, {167, 14}} + YES 68288064 @@ -1229,6 +1323,7 @@ 268 {{17, 379}, {167, 14}} + YES 68288064 @@ -1245,6 +1340,7 @@ 292 {{236, 78}, {167, 14}} + YES 68288064 @@ -1261,6 +1357,7 @@ 292 {{239, 57}, {161, 19}} + YES -1804468671 @@ -1279,6 +1376,7 @@ 264 {{17, 414}, {167, 14}} + YES 68288064 @@ -1295,6 +1393,7 @@ 268 {{20, 394}, {161, 19}} + YES -1804468671 @@ -1311,11 +1410,13 @@ {{143, 0}, {548, 444}} + NSView {691, 444} + YES 2 SPQueryFavoriteSplitView @@ -1382,6 +1483,7 @@ {691, 444} + {{0, 0}, {1920, 1058}} {691, 466} @@ -2200,6 +2302,38 @@ 1087 + + + withBlobLabelField + + + + 1090 + + + + nextKeyView + + + + 1094 + + + + withBlobPopupButton + + + + 1096 + + + + withBlobButtonChanged: + + + + 1097 + @@ -2488,6 +2622,8 @@ + + Bundle Content View @@ -3013,6 +3149,44 @@ + + 1088 + + + YES + + + + + + 1089 + + + + + 1091 + + + YES + + + + Pop Up Button (Input Fallback) + + + 1092 + + + YES + + + + + + 1093 + + + @@ -3047,6 +3221,14 @@ 1083.IBAttributePlaceholdersKey 1083.IBPluginDependency 1084.IBPluginDependency + 1088.IBAttributePlaceholdersKey + 1088.IBPluginDependency + 1089.IBPluginDependency + 1091.IBAttributePlaceholdersKey + 1091.IBPluginDependency + 1092.IBPluginDependency + 1093.IBEditorWindowLastContentRect + 1093.IBPluginDependency 521.IBEditorWindowLastContentRect 521.IBPluginDependency 521.IBWindowTemplateEditedContentRect @@ -3207,6 +3389,27 @@ com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin + + YES + + + YES + + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + ToolTip + + ToolTip + + Choose the handling of BLOB fields + + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + {{430, 598}, {167, 4}} + com.apple.InterfaceBuilder.CocoaPlugin {{172, 298}, {691, 444}} com.apple.InterfaceBuilder.CocoaPlugin {{172, 298}, {691, 444}} @@ -3444,7 +3647,7 @@ - 1087 + 1097 @@ -3602,6 +3805,7 @@ scopeButtonChanged: showHelp: triggerButtonChanged: + withBlobButtonChanged: YES @@ -3619,6 +3823,7 @@ id id id + id @@ -3639,6 +3844,7 @@ scopeButtonChanged: showHelp: triggerButtonChanged: + withBlobButtonChanged: YES @@ -3698,6 +3904,10 @@ triggerButtonChanged: id + + withBlobButtonChanged: + id + @@ -3736,6 +3946,8 @@ showHideMetaButton tooltipTextField triggerPopupButton + withBlobLabelField + withBlobPopupButton YES @@ -3771,6 +3983,8 @@ NSButton NSTextField NSPopUpButton + NSTextField + NSPopUpButton @@ -3809,6 +4023,8 @@ showHideMetaButton tooltipTextField triggerPopupButton + withBlobLabelField + withBlobPopupButton YES @@ -3940,6 +4156,14 @@ triggerPopupButton NSPopUpButton + + withBlobLabelField + NSTextField + + + withBlobPopupButton + NSPopUpButton + diff --git a/Source/SPBundleEditorController.h b/Source/SPBundleEditorController.h index 5ccd8a9a..7cc36de4 100644 --- a/Source/SPBundleEditorController.h +++ b/Source/SPBundleEditorController.h @@ -40,6 +40,7 @@ IBOutlet NSTextField *tooltipTextField; IBOutlet NSTextField *categoryTextField; IBOutlet NSTextField *fallbackLabelField; + IBOutlet NSTextField *withBlobLabelField; IBOutlet NSTextField *commandLabelField; IBOutlet NSTextField *authorLabelField; IBOutlet NSTextField *contactLabelField; @@ -49,6 +50,7 @@ IBOutlet NSPopUpButton *outputPopupButton; IBOutlet NSPopUpButton *scopePopupButton; IBOutlet NSPopUpButton *triggerPopupButton; + IBOutlet NSPopUpButton *withBlobPopupButton; IBOutlet NSButton *removeButton; IBOutlet NSButton *addButton; IBOutlet NSButton *saveButton; @@ -84,6 +86,7 @@ NSMenu *triggerInputFieldPopUpMenu; NSMenu *triggerDataTablePopUpMenu; NSMenu *triggerGeneralPopUpMenu; + NSMenu *withBlobDataTablePopUpMenu; NSArray *inputGeneralScopeArray; NSArray *inputInputFieldScopeArray; @@ -95,6 +98,7 @@ NSArray *triggerInputFieldArray; NSArray *triggerDataTableArray; NSArray *triggerGeneralArray; + NSArray *withBlobDataTableArray; BOOL doGroupDueToChars; BOOL allowUndo; @@ -109,6 +113,7 @@ - (IBAction)outputPopupButtonChanged:(id)sender; - (IBAction)scopeButtonChanged:(id)sender; - (IBAction)triggerButtonChanged:(id)sender; +- (IBAction)withBlobButtonChanged:(id)sender; - (IBAction)duplicateCommandBundle:(id)sender; - (IBAction)addCommandBundle:(id)sender; - (IBAction)removeCommandBundle:(id)sender; diff --git a/Source/SPBundleEditorController.m b/Source/SPBundleEditorController.m index 60f95f3b..56258ee3 100644 --- a/Source/SPBundleEditorController.m +++ b/Source/SPBundleEditorController.m @@ -93,6 +93,7 @@ [triggerInputFieldArray release]; [triggerDataTableArray release]; [triggerGeneralArray release]; + [withBlobDataTableArray release]; if(touchedBundleArray) [touchedBundleArray release], touchedBundleArray = nil; if(commandBundleTree) [commandBundleTree release], commandBundleTree = nil; @@ -134,6 +135,7 @@ triggerInputFieldPopUpMenu = [[NSMenu alloc] initWithTitle:@""]; triggerDataTablePopUpMenu = [[NSMenu alloc] initWithTitle:@""]; triggerGeneralPopUpMenu = [[NSMenu alloc] initWithTitle:@""]; + withBlobDataTablePopUpMenu = [[NSMenu alloc] initWithTitle:@""]; inputGeneralScopeArray = [[NSArray arrayWithObjects:SPBundleInputSourceNone, nil] retain]; inputInputFieldScopeArray = [[NSArray arrayWithObjects:SPBundleInputSourceNone, SPBundleInputSourceSelectedText, SPBundleInputSourceEntireContent, nil] retain]; @@ -145,6 +147,7 @@ triggerInputFieldArray = [[NSArray arrayWithObjects:SPBundleTriggerActionNone, nil] retain]; triggerDataTableArray = [[NSArray arrayWithObjects:SPBundleTriggerActionNone, SPBundleTriggerActionDatabaseChanged, SPBundleTriggerActionTableChanged, SPBundleTriggerActionTableRowChanged, nil] retain]; triggerGeneralArray = [[NSArray arrayWithObjects:SPBundleTriggerActionNone, SPBundleTriggerActionDatabaseChanged, SPBundleTriggerActionTableChanged, nil] retain]; + withBlobDataTableArray = [[NSArray arrayWithObjects:SPBundleInputSourceBlobHandlingExclude, SPBundleInputSourceBlobHandlingInclude, SPBundleInputSourceBlobHandlingImageFileReference, SPBundleInputSourceBlobHandlingFileReference, nil] retain]; NSMutableArray *allPopupScopeItems = [NSMutableArray array]; [allPopupScopeItems addObjectsFromArray:inputGeneralScopeArray]; @@ -157,6 +160,7 @@ [allPopupScopeItems addObjectsFromArray:triggerInputFieldArray]; [allPopupScopeItems addObjectsFromArray:triggerDataTableArray]; [allPopupScopeItems addObjectsFromArray:triggerGeneralArray]; + [allPopupScopeItems addObjectsFromArray:withBlobDataTableArray]; NSDictionary *menuItemTitles = [NSDictionary dictionaryWithObjects: [NSArray arrayWithObjects: @@ -210,6 +214,11 @@ NSLocalizedString(@"Database changed", @"database changed item label"), NSLocalizedString(@"Table changed", @"table changed item label"), + NSLocalizedString(@"exclude BLOB", @"exclude BLOB item label"), + NSLocalizedString(@"include BLOB", @"include BLOB item label"), + NSLocalizedString(@"save BLOB as image file", @"save BLOB as image file item label"), + NSLocalizedString(@"save BLOB as dat file", @"save BLOB as dat file item label"), + nil] forKeys:allPopupScopeItems]; @@ -264,6 +273,11 @@ [triggerGeneralPopUpMenu addItem:anItem]; [anItem release]; } + for(NSString* title in withBlobDataTableArray) { + anItem = [[NSMenuItem alloc] initWithTitle:[menuItemTitles objectForKey:title] action:@selector(withBlobButtonChanged:) keyEquivalent:@""]; + [withBlobDataTablePopUpMenu addItem:anItem]; + [anItem release]; + } anItem = [[NSMenuItem alloc] initWithTitle:[menuItemTitles objectForKey:SPBundleInputSourceNone] action:nil keyEquivalent:@""]; [inputNonePopUpMenu addItem:anItem]; [anItem release]; @@ -455,6 +469,28 @@ } +/** + * Store trigger in bundle dict since it is not bound + * via key binding and update various GUI elements + */ +- (IBAction)withBlobButtonChanged:(id)sender +{ + + id currentDict = [self _currentSelectedObject]; + + NSMenu* senderMenu = [sender menu]; + + NSInteger selectedIndex = [senderMenu indexOfItem:sender]; + NSString *input = SPBundleInputSourceBlobHandlingExclude; + + input = [withBlobDataTableArray objectAtIndex:selectedIndex]; + + [currentDict setObject:input forKey:SPBundleFileWithBlobKey]; + + [self _updateBundleDataView]; + +} + /** * Duplicate the selected bundle (processed in addCommandBundle:) */ @@ -1618,6 +1654,9 @@ NSString *trigger = [currentDict objectForKey:SPBundleFileTriggerKey]; if(!trigger) trigger = SPBundleTriggerActionNone; + NSString *withBlob = [currentDict objectForKey:SPBundleFileWithBlobKey]; + if(!withBlob) withBlob = SPBundleInputSourceBlobHandlingExclude; + // Update the scope popup button if([scope isEqualToString:SPBundleScopeGeneral]) [scopePopupButton selectItemWithTag:kGeneralScopeArrayIndex]; @@ -1647,6 +1686,8 @@ input = SPBundleInputSourceNone; [inputFallbackPopupButton setHidden:YES]; [fallbackLabelField setHidden:YES]; + [withBlobPopupButton setHidden:YES]; + [withBlobLabelField setHidden:YES]; break; case kInputFieldScopeArrayIndex: // Input Field @@ -1670,6 +1711,9 @@ if(anIndex == NSNotFound) anIndex = 0; [triggerPopupButton selectItemAtIndex:anIndex]; + [withBlobPopupButton setHidden:YES]; + [withBlobLabelField setHidden:YES]; + break; case kDataTableScopeArrayIndex: // Data Table [inputPopupButton setMenu:inputDataTableScopePopUpMenu]; @@ -1682,7 +1726,6 @@ if(anIndex == NSNotFound) anIndex = 0; [outputPopupButton selectItemAtIndex:anIndex]; - input = SPBundleInputSourceNone; [inputFallbackPopupButton setHidden:YES]; [fallbackLabelField setHidden:YES]; @@ -1691,6 +1734,23 @@ if(anIndex == NSNotFound) anIndex = 0; [triggerPopupButton selectItemAtIndex:anIndex]; + [withBlobPopupButton setMenu:withBlobDataTablePopUpMenu]; + anIndex = [withBlobDataTableArray indexOfObject:withBlob]; + if(anIndex == NSNotFound) anIndex = 0; + [withBlobPopupButton selectItemAtIndex:anIndex]; + + [inputFallbackPopupButton setHidden:YES]; + [fallbackLabelField setHidden:YES]; + + if([currentDict objectForKey:SPBundleFileInputSourceKey] && ([[currentDict objectForKey:SPBundleFileInputSourceKey] isEqualToString:SPBundleInputSourceNone] || [[currentDict objectForKey:SPBundleFileInputSourceKey] isEqualToString:SPBundleInputSourceTableRowsAsSqlInsert] || [[currentDict objectForKey:SPBundleFileInputSourceKey] isEqualToString:SPBundleInputSourceSelectedTableRowsAsSqlInsert])) { + [withBlobPopupButton setHidden:YES]; + [withBlobLabelField setHidden:YES]; + } else { + [withBlobPopupButton setHidden:NO]; + [withBlobLabelField setHidden:NO]; + } + input = SPBundleInputSourceNone; + break; case kDisabledScopeTag: // Disable command break; diff --git a/Source/SPConstants.h b/Source/SPConstants.h index 5327fd45..91777dbe 100644 --- a/Source/SPConstants.h +++ b/Source/SPConstants.h @@ -448,6 +448,10 @@ extern NSString *SPBundleInputSourceTableRowsAsTab; extern NSString *SPBundleInputSourceTableRowsAsCsv; extern NSString *SPBundleInputSourceTableRowsAsSqlInsert; extern NSString *SPBundleInputSourceNone; +extern NSString *SPBundleInputSourceBlobHandlingInclude; +extern NSString *SPBundleInputSourceBlobHandlingExclude; +extern NSString *SPBundleInputSourceBlobHandlingImageFileReference; +extern NSString *SPBundleInputSourceBlobHandlingFileReference; extern NSString *SPBundleOutputActionNone; extern NSString *SPBundleOutputActionInsertAsText; extern NSString *SPBundleOutputActionInsertAsSnippet; @@ -476,12 +480,14 @@ extern NSString *SPBundleFileContactKey; extern NSString *SPBundleFileUUIDKey; extern NSString *SPBundleFileDescriptionKey; extern NSString *SPBundleFileTriggerKey; +extern NSString *SPBundleFileWithBlobKey; extern NSString *SPBundleInternLabelKey; extern NSString *SPBundleInternPathToFileKey; extern NSString *SPBundleInternKeyEquivalentKey; extern NSString *SPBundleFileName; extern NSString *SPBundleTaskInputFilePath; extern NSString *SPBundleTaskScriptCommandFilePath; +extern NSString *SPBundleTaskCopyBlobFileDirectory; // sequel URL scheme extern NSString *SPURLSchemeQueryInputPathHeader; diff --git a/Source/SPConstants.m b/Source/SPConstants.m index 495a7580..94abe414 100644 --- a/Source/SPConstants.m +++ b/Source/SPConstants.m @@ -260,6 +260,10 @@ NSString *SPBundleInputSourceTableRowsAsTab = @"tablerowsastab"; NSString *SPBundleInputSourceTableRowsAsCsv = @"tablerowsascsv"; NSString *SPBundleInputSourceTableRowsAsSqlInsert = @"tablerowsassqlinsert"; NSString *SPBundleInputSourceNone = @"none"; +NSString *SPBundleInputSourceBlobHandlingInclude = @"include"; +NSString *SPBundleInputSourceBlobHandlingExclude = @"exclude"; +NSString *SPBundleInputSourceBlobHandlingImageFileReference = @"imagefilereference"; +NSString *SPBundleInputSourceBlobHandlingFileReference = @"filereference"; NSString *SPBundleOutputActionNone = @"none"; NSString *SPBundleOutputActionInsertAsText = @"insertastext"; NSString *SPBundleOutputActionInsertAsSnippet = @"insertassnippet"; @@ -288,6 +292,7 @@ NSString *SPBundleFileContactKey = @"contact"; NSString *SPBundleFileUUIDKey = @"uuid"; NSString *SPBundleFileDescriptionKey = @"description"; NSString *SPBundleFileTriggerKey = @"trigger"; +NSString *SPBundleFileWithBlobKey = @"withblob"; NSString *SPBundleInternLabelKey = @"label"; NSString *SPBundleInternPathToFileKey = @"path"; NSString *SPBundleInternKeyEquivalentKey = @"keyEquivalent"; @@ -295,6 +300,7 @@ NSString *SPBundleInternKeyEquivalentKey = @"keyEquivalent"; NSString *SPBundleFileName = @"command.plist"; NSString *SPBundleTaskInputFilePath = @"/tmp/SP_BUNDLE_TASK_INPUT"; NSString *SPBundleTaskScriptCommandFilePath = @"/tmp/SP_SCRIPT_COMMAND"; +NSString *SPBundleTaskCopyBlobFileDirectory = @"/tmp/SP_COPY_BLOB_FILES"; // sequel URL scheme NSString *SPURLSchemeQueryInputPathHeader = @"/tmp/SP_QUERY_"; diff --git a/Source/SPCopyTable.h b/Source/SPCopyTable.h index 89030976..4723dbc9 100644 --- a/Source/SPCopyTable.h +++ b/Source/SPCopyTable.h @@ -48,9 +48,12 @@ NSUserDefaults *prefs; NSRange fieldEditorSelectedRange; + NSString *copyBlobFileDirectory; } +@property(readwrite,assign) NSString *copyBlobFileDirectory; + @property(readwrite,assign) NSRange fieldEditorSelectedRange; /*! @@ -90,7 +93,7 @@ returns something meaningful. @result The above described string, or nil if nothing selected */ -- (NSString *)rowsAsTabStringWithHeaders:(BOOL)withHeaders onlySelectedRows:(BOOL)onlySelected; +- (NSString *)rowsAsTabStringWithHeaders:(BOOL)withHeaders onlySelectedRows:(BOOL)onlySelected blobHandling:(NSInteger)withBlobHandling; /*! @method rowsAsCsvStringWithHeaders:onlySelectedRows: @@ -101,7 +104,7 @@ returns something meaningful. @result The above described string, or nil if nothing selected */ -- (NSString *)rowsAsCsvStringWithHeaders:(BOOL)withHeaders onlySelectedRows:(BOOL)onlySelected; +- (NSString *)rowsAsCsvStringWithHeaders:(BOOL)withHeaders onlySelectedRows:(BOOL)onlySelected blobHandling:(NSInteger)withBlobHandling; /* * Generate a string in form of INSERT INTO VALUES () of diff --git a/Source/SPCopyTable.m b/Source/SPCopyTable.m index 687cb2e4..493c3fb4 100644 --- a/Source/SPCopyTable.m +++ b/Source/SPCopyTable.m @@ -34,11 +34,17 @@ #import "SPTooltip.h" #import "SPAlertSheets.h" #import "SPBundleHTMLOutputController.h" +#import "SPGeometryDataView.h" NSInteger MENU_EDIT_COPY = 2001; NSInteger MENU_EDIT_COPY_WITH_COLUMN = 2002; NSInteger MENU_EDIT_COPY_AS_SQL = 2003; +NSInteger kBlobExclude = 1; +NSInteger kBlobInclude = 2; +NSInteger kBlobAsFile = 3; +NSInteger kBlobAsImageFile = 4; + @implementation SPCopyTable @@ -47,6 +53,7 @@ NSInteger MENU_EDIT_COPY_AS_SQL = 2003; * selection in the field editor's editTextView */ @synthesize fieldEditorSelectedRange; +@synthesize copyBlobFileDirectory; /** * Cell editing in SPCustomQuery or for views in SPTableContent @@ -93,7 +100,7 @@ NSInteger MENU_EDIT_COPY_AS_SQL = 2003; [pb setString:tmp forType:NSStringPboardType]; } } else { - tmp = [self rowsAsTabStringWithHeaders:([sender tag] == MENU_EDIT_COPY_WITH_COLUMN) onlySelectedRows:YES]; + tmp = [self rowsAsTabStringWithHeaders:([sender tag] == MENU_EDIT_COPY_WITH_COLUMN) onlySelectedRows:YES blobHandling:kBlobInclude]; if ( nil != tmp ) { NSPasteboard *pb = [NSPasteboard generalPasteboard]; @@ -114,7 +121,7 @@ NSInteger MENU_EDIT_COPY_AS_SQL = 2003; * Get selected rows a string of newline separated lines of tab separated fields * the value in each field is from the objects description method */ -- (NSString *) rowsAsTabStringWithHeaders:(BOOL)withHeaders onlySelectedRows:(BOOL)onlySelected +- (NSString *) rowsAsTabStringWithHeaders:(BOOL)withHeaders onlySelectedRows:(BOOL)onlySelected blobHandling:(NSInteger)withBlobHandling { if (onlySelected && [self numberOfSelectedRows] == 0) return nil; @@ -152,6 +159,13 @@ NSInteger MENU_EDIT_COPY_AS_SQL = 2003; NSString *nullString = [prefs objectForKey:SPNullValue]; NSStringEncoding connectionEncoding = [mySQLConnection encoding]; Class mcpGeometryData = [MCPGeometryData class]; + NSUInteger rowCounter = 0; + + if((withBlobHandling == kBlobAsFile || withBlobHandling == kBlobAsImageFile) && copyBlobFileDirectory && [copyBlobFileDirectory length]) { + NSFileManager *fm = [NSFileManager defaultManager]; + [fm removeItemAtPath:copyBlobFileDirectory error:nil]; + [fm createDirectoryAtPath:copyBlobFileDirectory withIntermediateDirectories:YES attributes:nil error:nil]; + } while ( rowIndex != NSNotFound ) { @@ -159,22 +173,59 @@ NSInteger MENU_EDIT_COPY_AS_SQL = 2003; cellData = SPDataStorageObjectAtRowAndColumn(tableStorage, rowIndex, columnMappings[c]); // Copy the shown representation of the cell - custom NULL display strings, (not loaded), - // and the string representation of any blobs or binary texts. + // definable representation of any blobs or binary texts. if (cellData) { if ([cellData isNSNull]) [result appendFormat:@"%@\t", nullString]; else if ([cellData isSPNotLoaded]) [result appendFormat:@"%@\t", NSLocalizedString(@"(not loaded)", @"value shown for hidden blob and text fields")]; else if ([cellData isKindOfClass:[NSData class]]) { - NSString *displayString = [[NSString alloc] initWithData:cellData encoding:[mySQLConnection stringEncoding]]; - if (!displayString) displayString = [[NSString alloc] initWithData:cellData encoding:NSASCIIStringEncoding]; - if (displayString) { - [result appendFormat:@"%@\t", displayString]; - [displayString release]; + if(withBlobHandling == kBlobInclude) { + NSString *displayString = [[NSString alloc] initWithData:cellData encoding:[mySQLConnection stringEncoding]]; + if (!displayString) displayString = [[NSString alloc] initWithData:cellData encoding:NSASCIIStringEncoding]; + if (displayString) { + [result appendFormat:@"%@\t", displayString]; + [displayString release]; + } + } + else if(withBlobHandling == kBlobAsFile && copyBlobFileDirectory && [copyBlobFileDirectory length]) { + NSString *fp = [NSString stringWithFormat:@"%@/%ld_%ld.dat", copyBlobFileDirectory, rowCounter, c]; + [cellData writeToFile:fp atomically:NO]; + [result appendFormat:@"%@\t", fp]; + } + else if(withBlobHandling == kBlobAsImageFile && copyBlobFileDirectory && [copyBlobFileDirectory length]) { + NSString *fp = [NSString stringWithFormat:@"%@/%ld_%ld.tif", copyBlobFileDirectory, rowCounter, c]; + NSImage *image = [[NSImage alloc] initWithData:cellData]; + if (image) { + NSData *d = [[NSData alloc] initWithData:[image TIFFRepresentationUsingCompression:NSTIFFCompressionLZW factor:1]]; + [d writeToFile:fp atomically:NO]; + if(d) [d release], d = nil; + [image release]; + } else { + NSString *noData = @""; + [noData writeToFile:fp atomically:NO]; + } + [result appendFormat:@"%@\t", fp]; + } + else { + [result appendString:@"BLOB\t"]; } } else if ([cellData isKindOfClass:mcpGeometryData]) { - [result appendFormat:@"%@\t", [cellData wktString]]; + if((withBlobHandling == kBlobAsFile || withBlobHandling == kBlobAsImageFile) && copyBlobFileDirectory && [copyBlobFileDirectory length]) { + NSString *fp = [NSString stringWithFormat:@"%@/%ld_%ld.pdf", copyBlobFileDirectory, rowCounter, c]; + SPGeometryDataView *v = [[SPGeometryDataView alloc] initWithCoordinates:[cellData coordinates]]; + NSData *thePDF = [v pdfData]; + if(thePDF) { + [thePDF writeToFile:fp atomically:NO]; + [result appendFormat:@"%@\t", fp]; + } else { + [result appendFormat:@"%@\t", [cellData wktString]]; + } + if(v) [v release], v = nil; + } else { + [result appendFormat:@"%@\t", [cellData wktString]]; + } } else [result appendFormat:@"%@\t", [cellData description]]; @@ -183,6 +234,8 @@ NSInteger MENU_EDIT_COPY_AS_SQL = 2003; } } + rowCounter++; + // Remove the trailing tab and add the linebreak if ([result length]){ [result deleteCharactersInRange:NSMakeRange([result length]-1, 1)]; @@ -207,7 +260,7 @@ NSInteger MENU_EDIT_COPY_AS_SQL = 2003; * Get selected rows a string of newline separated lines of , separated fields wrapped into quotes * the value in each field is from the objects description method */ -- (NSString *) rowsAsCsvStringWithHeaders:(BOOL)withHeaders onlySelectedRows:(BOOL)onlySelected +- (NSString *) rowsAsCsvStringWithHeaders:(BOOL)withHeaders onlySelectedRows:(BOOL)onlySelected blobHandling:(NSInteger)withBlobHandling { if (onlySelected && [self numberOfSelectedRows] == 0) return nil; @@ -246,36 +299,83 @@ NSInteger MENU_EDIT_COPY_AS_SQL = 2003; NSStringEncoding connectionEncoding = [mySQLConnection encoding]; Class mcpGeometryData = [MCPGeometryData class]; + NSUInteger rowCounter = 0; + + if((withBlobHandling == kBlobAsFile || withBlobHandling == kBlobAsImageFile) && copyBlobFileDirectory && [copyBlobFileDirectory length]) { + NSFileManager *fm = [NSFileManager defaultManager]; + [fm removeItemAtPath:copyBlobFileDirectory error:nil]; + [fm createDirectoryAtPath:copyBlobFileDirectory withIntermediateDirectories:YES attributes:nil error:nil]; + } + while ( rowIndex != NSNotFound ) { for ( c = 0; c < numColumns; c++ ) { cellData = SPDataStorageObjectAtRowAndColumn(tableStorage, rowIndex, columnMappings[c]); // Copy the shown representation of the cell - custom NULL display strings, (not loaded), - // and the string representation of any blobs or binary texts. + // definable representation of any blobs or binary texts. if (cellData) { if ([cellData isNSNull]) [result appendFormat:@"\"%@\",", nullString]; else if ([cellData isSPNotLoaded]) [result appendFormat:@"\"%@\",", NSLocalizedString(@"(not loaded)", @"value shown for hidden blob and text fields")]; else if ([cellData isKindOfClass:[NSData class]]) { - NSString *displayString = [[NSString alloc] initWithData:cellData encoding:[mySQLConnection stringEncoding]]; - if (!displayString) displayString = [[NSString alloc] initWithData:cellData encoding:NSASCIIStringEncoding]; - if (displayString) { - [result appendFormat:@"\"%@\",", [displayString stringByReplacingOccurrencesOfString:@"\"" withString:@"\"\""]]; - [displayString release]; + if(withBlobHandling == kBlobInclude) { + NSString *displayString = [[NSString alloc] initWithData:cellData encoding:[mySQLConnection stringEncoding]]; + if (!displayString) displayString = [[NSString alloc] initWithData:cellData encoding:NSASCIIStringEncoding]; + if (displayString) { + [result appendFormat:@"\"%@\",", displayString]; + [displayString release]; + } + } + else if(withBlobHandling == kBlobAsFile && copyBlobFileDirectory && [copyBlobFileDirectory length]) { + NSString *fp = [NSString stringWithFormat:@"%@/%ld_%ld.dat", copyBlobFileDirectory, rowCounter, c]; + [cellData writeToFile:fp atomically:NO]; + [result appendFormat:@"\"%@\",", fp]; + } + else if(withBlobHandling == kBlobAsImageFile && copyBlobFileDirectory && [copyBlobFileDirectory length]) { + NSString *fp = [NSString stringWithFormat:@"%@/%ld_%ld.tif", copyBlobFileDirectory, rowCounter, c]; + NSImage *image = [[NSImage alloc] initWithData:cellData]; + if (image) { + NSData *d = [[NSData alloc] initWithData:[image TIFFRepresentationUsingCompression:NSTIFFCompressionLZW factor:1]]; + [d writeToFile:fp atomically:NO]; + if(d) [d release], d = nil; + [image release]; + } else { + NSString *noData = @""; + [noData writeToFile:fp atomically:NO]; + } + [result appendFormat:@"\"%@\",", fp]; + } + else { + [result appendString:@"\"BLOB\","]; } } else if ([cellData isKindOfClass:mcpGeometryData]) { - [result appendFormat:@"\"%@\",", [cellData wktString]]; + if((withBlobHandling == kBlobAsFile || withBlobHandling == kBlobAsImageFile) && copyBlobFileDirectory && [copyBlobFileDirectory length]) { + NSString *fp = [NSString stringWithFormat:@"%@/%ld_%ld.pdf", copyBlobFileDirectory, rowCounter, c]; + SPGeometryDataView *v = [[SPGeometryDataView alloc] initWithCoordinates:[cellData coordinates]]; + NSData *thePDF = [v pdfData]; + if(thePDF) { + [thePDF writeToFile:fp atomically:NO]; + [result appendFormat:@"\"%@\",", fp]; + } else { + [result appendFormat:@"\"%@\",", [cellData wktString]]; + } + if(v) [v release], v = nil; + } else { + [result appendFormat:@"\"%@\",", [cellData wktString]]; + } } else - [result appendFormat:@"\"%@\",", [[cellData description] stringByReplacingOccurrencesOfString:@"\"" withString:@"\"\""]]; + [result appendFormat:@"\"%@\",", [cellData description]]; } else { [result appendString:@","]; } } + rowCounter++; + // Remove the trailing tab and add the linebreak if ([result length]){ [result deleteCharactersInRange:NSMakeRange([result length]-1, 1)]; @@ -860,8 +960,10 @@ NSInteger MENU_EDIT_COPY_AS_SQL = 2003; NSString *cmd = [cmdData objectForKey:SPBundleFileCommandKey]; NSString *inputAction = @""; NSString *inputFallBackAction = @""; + NSString *withBlobHandling = @""; NSError *err = nil; - NSString *bundleInputFilePath = [NSString stringWithFormat:@"%@_%@", SPBundleTaskInputFilePath, [NSString stringWithNewUUID]]; + NSString *uuid = [NSString stringWithNewUUID]; + NSString *bundleInputFilePath = [NSString stringWithFormat:@"%@_%@", SPBundleTaskInputFilePath, uuid]; [[NSFileManager defaultManager] removeItemAtPath:bundleInputFilePath error:nil]; @@ -890,20 +992,40 @@ NSInteger MENU_EDIT_COPY_AS_SQL = 2003; NSError *inputFileError = nil; NSString *input = @""; + NSInteger blobHandling = kBlobExclude; + if([cmdData objectForKey:SPBundleFileWithBlobKey]) { + if([[cmdData objectForKey:SPBundleFileWithBlobKey] isEqualToString:SPBundleInputSourceBlobHandlingExclude]) + blobHandling = kBlobExclude; + else if([[cmdData objectForKey:SPBundleFileWithBlobKey] isEqualToString:SPBundleInputSourceBlobHandlingInclude]) + blobHandling = kBlobInclude; + else if([[cmdData objectForKey:SPBundleFileWithBlobKey] isEqualToString:SPBundleInputSourceBlobHandlingImageFileReference]) + blobHandling = kBlobAsImageFile; + else if([[cmdData objectForKey:SPBundleFileWithBlobKey] isEqualToString:SPBundleInputSourceBlobHandlingFileReference]) + blobHandling = kBlobAsFile; + } + + if(blobHandling != kBlobExclude) { + NSString *bundleBlobFilePath = [NSString stringWithFormat:@"%@_%@", SPBundleTaskCopyBlobFileDirectory, uuid]; + [env setObject:bundleBlobFilePath forKey:@"SP_BUNDLE_BLOB_FILES_DIRECTORY"]; + [self setCopyBlobFileDirectory:bundleBlobFilePath]; + } else { + [self setCopyBlobFileDirectory:@""]; + } + if([inputAction isEqualToString:SPBundleInputSourceSelectedTableRowsAsTab]) { - input = [self rowsAsTabStringWithHeaders:YES onlySelectedRows:YES]; + input = [self rowsAsTabStringWithHeaders:YES onlySelectedRows:YES blobHandling:blobHandling]; } else if([inputAction isEqualToString:SPBundleInputSourceSelectedTableRowsAsCsv]) { - input = [self rowsAsCsvStringWithHeaders:YES onlySelectedRows:YES]; + input = [self rowsAsCsvStringWithHeaders:YES onlySelectedRows:YES blobHandling:blobHandling]; } else if([inputAction isEqualToString:SPBundleInputSourceSelectedTableRowsAsSqlInsert]) { input = [self rowsAsSqlInsertsOnlySelectedRows:YES]; } else if([inputAction isEqualToString:SPBundleInputSourceTableRowsAsTab]) { - input = [self rowsAsTabStringWithHeaders:YES onlySelectedRows:NO]; + input = [self rowsAsTabStringWithHeaders:YES onlySelectedRows:NO blobHandling:blobHandling]; } else if([inputAction isEqualToString:SPBundleInputSourceTableRowsAsCsv]) { - input = [self rowsAsCsvStringWithHeaders:YES onlySelectedRows:NO]; + input = [self rowsAsCsvStringWithHeaders:YES onlySelectedRows:NO blobHandling:blobHandling]; } else if([inputAction isEqualToString:SPBundleInputSourceTableRowsAsSqlInsert]) { input = [self rowsAsSqlInsertsOnlySelectedRows:NO]; -- cgit v1.2.3