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 --- Source/SPBundleEditorController.h | 5 ++ Source/SPBundleEditorController.m | 62 +++++++++++++- Source/SPConstants.h | 6 ++ Source/SPConstants.m | 6 ++ Source/SPCopyTable.h | 7 +- Source/SPCopyTable.m | 168 ++++++++++++++++++++++++++++++++------ 6 files changed, 228 insertions(+), 26 deletions(-) (limited to 'Source') 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