From 242e1f7ee9dbc38013fb8fd3398a44851e0f8be3 Mon Sep 17 00:00:00 2001 From: gcasa Date: Fri, 2 Jun 2006 00:31:14 +0000 Subject: [PATCH] Changes to allow proper document type selection in the save panel for document oriented applications. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@23013 72102866-910b-0410-8b05-ffd578937521 --- ChangeLog | 15 +++ Headers/AppKit/NSDocument.h | 1 + Headers/AppKit/NSDocumentFrameworkPrivate.h | 3 + Source/NSDocument.m | 124 ++++++++++++-------- Source/NSDocumentController.m | 42 ++++++- 5 files changed, 136 insertions(+), 49 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8790c61ab..858ca11cc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2006-06-01 00:13 Gregory John Casamento + + * Headers/AppKit/NSDocumentFrameworkPrivate.h: Addition of new + private methods to manage file types. + * Headers/AppKit/NSDocument.h: New ivar _saveType. + * Source/NSDocumentController.m: Implementation of new private + methods. + * Source/NSDocument.m: Changed writeWithBackupToFile:ofType: + saveOperation: to use new methods to get the human readable + filetypes to be listed in the dropdown in the savepanel and to + properly retrieve the extension for the specified filetype + and apply it to the backup filename and filename being saved. + Also modified changeSaveType: to update the save panel's + requiredFileType when the type is changed. + 2006-05-21 Richard Frith-Macdonald * Source/NSApplication.m: Implement MacOS-X behavior (as determined diff --git a/Headers/AppKit/NSDocument.h b/Headers/AppKit/NSDocument.h index 165bda9fc..a21bdc935 100644 --- a/Headers/AppKit/NSDocument.h +++ b/Headers/AppKit/NSDocument.h @@ -80,6 +80,7 @@ typedef enum _NSSaveOperationType { NSPopUpButton *spaButton; // outlet for "the File Format:" button in the save panel. int _documentIndex; // Untitled index NSUndoManager *_undoManager; // Undo manager for this document + NSString *_saveType; // the currently selected extension. struct __docFlags { unsigned int inClose:1; unsigned int hasUndoManager:1; diff --git a/Headers/AppKit/NSDocumentFrameworkPrivate.h b/Headers/AppKit/NSDocumentFrameworkPrivate.h index a724fa7dc..2ce0ebf31 100644 --- a/Headers/AppKit/NSDocumentFrameworkPrivate.h +++ b/Headers/AppKit/NSDocumentFrameworkPrivate.h @@ -34,6 +34,9 @@ - (NSArray *)_editorAndViewerTypesForClass:(Class)documentClass; - (NSArray *)_editorTypesForClass:(Class)fp12; - (NSArray *)_exportableTypesForClass:(Class)documentClass; +- (NSString *)_nameForHumanReadableType: (NSString *)type; +- (NSArray *)_displayNamesForTypes: (NSArray *)types; +- (NSArray *)_displayNamesForClass: (Class)documentClass; @end diff --git a/Source/NSDocument.m b/Source/NSDocument.m index b8c0350ad..47979305f 100644 --- a/Source/NSDocument.m +++ b/Source/NSDocument.m @@ -78,6 +78,7 @@ if ([fileTypes count]) { [self setFileType: [fileTypes objectAtIndex: 0]]; + ASSIGN(_saveType, [fileTypes objectAtIndex: 0]); } } return self; @@ -146,6 +147,7 @@ RELEASE(_printInfo); RELEASE(savePanelAccessory); RELEASE(spaButton); + RELEASE(_saveType); [super dealloc]; } @@ -457,7 +459,17 @@ - (IBAction)changeSaveType: (id)sender { - [self setFileType: [sender titleOfSelectedItem]]; + NSDocumentController *controller = + [NSDocumentController sharedDocumentController]; + NSArray *extensions = nil; + + ASSIGN(_saveType, [controller _nameForHumanReadableType: + [sender titleOfSelectedItem]]); + extensions = [controller fileExtensionsFromType: _saveType]; + if([extensions count] > 0) + { + [(NSSavePanel *)[sender window] setRequiredFileType: [extensions objectAtIndex:0]]; + } } - (int)runModalSavePanel: (NSSavePanel *)savePanel @@ -509,7 +521,9 @@ // if we have some items, select the current filetype. if(i > 0) { - [spaButton selectItemWithTitle: [self fileType]]; + NSString *title = [[NSDocumentController sharedDocumentController] + displayNameForType: [self fileType]]; + [spaButton selectItemWithTitle: title]; } } @@ -518,25 +532,32 @@ NSView *accessory = nil; NSString *title; NSString *directory; - NSArray *extensions; + NSArray *displayNames; NSDocumentController *controller; NSSavePanel *savePanel = [NSSavePanel savePanel]; controller = [NSDocumentController sharedDocumentController]; - extensions = [controller fileExtensionsFromType:[self fileType]]; + displayNames = [controller _displayNamesForClass: [self class]]; if ([self shouldRunSavePanelWithAccessoryView]) { if (savePanelAccessory == nil) [self _createPanelAccessory]; - [self _addItemsToSpaButtonFromArray: extensions]; + [self _addItemsToSpaButtonFromArray: displayNames]; accessory = savePanelAccessory; } - if ([extensions count] > 0) - [savePanel setRequiredFileType:[extensions objectAtIndex:0]]; + if ([displayNames count] > 0) + { + NSArray *extensions = [[NSDocumentController sharedDocumentController] + fileExtensionsFromType: [self fileTypeFromLastRunSavePanel]]; + if([extensions count] > 0) + { + [savePanel setRequiredFileType:[extensions objectAtIndex:0]]; + } + } switch (saveOperation) { @@ -678,8 +699,7 @@ - (NSString *)fileTypeFromLastRunSavePanel { - // return [self fileType]; - return [spaButton title]; + return _saveType; } - (NSDictionary *)fileAttributesToWriteToFile: (NSString *)fullDocumentPath @@ -707,51 +727,59 @@ if (fileName) { - if ([fileManager fileExistsAtPath: fileName]) + NSArray *extensions = [[NSDocumentController sharedDocumentController] + fileExtensionsFromType: fileType]; + + if([extensions count] > 0) { - NSString *extension = [fileName pathExtension]; + NSString *extension = [extensions objectAtIndex: 0]; + NSString *newFileName = [[fileName stringByDeletingPathExtension] + stringByAppendingPathExtension: extension]; - backupFilename = [fileName stringByDeletingPathExtension]; - backupFilename = [backupFilename stringByAppendingString:@"~"]; - backupFilename = [backupFilename stringByAppendingPathExtension: extension]; - - /* Save panel has already asked if the user wants to replace it */ - - /* NSFileManager movePath: will fail if destination exists */ - if ([fileManager fileExistsAtPath: backupFilename]) - [fileManager removeFileAtPath: backupFilename handler: nil]; - - // Move or copy? - if (![fileManager movePath: fileName toPath: backupFilename handler: nil] && - [self keepBackupFile]) - { - int result = NSRunAlertPanel(_(@"File Error"), - _(@"Can't create backup file. Save anyways?"), - _(@"Save"), _(@"Cancel"), nil); + if ([fileManager fileExistsAtPath: newFileName]) + { + backupFilename = [newFileName stringByDeletingPathExtension]; + backupFilename = [backupFilename stringByAppendingString:@"~"]; + backupFilename = [backupFilename stringByAppendingPathExtension: extension]; - if (result != NSAlertDefaultReturn) return NO; - } - } - if ([self writeToFile: fileName - ofType: fileType - originalFile: backupFilename - saveOperation: saveOp]) - { - if (saveOp != NSSaveToOperation) - { - [self setFileName: fileName]; - [self setFileType: fileType]; - [self updateChangeCount: NSChangeCleared]; + /* Save panel has already asked if the user wants to replace it */ + + /* NSFileManager movePath: will fail if destination exists */ + if ([fileManager fileExistsAtPath: backupFilename]) + [fileManager removeFileAtPath: backupFilename handler: nil]; + + // Move or copy? + if (![fileManager movePath: newFileName toPath: backupFilename handler: nil] && + [self keepBackupFile]) + { + int result = NSRunAlertPanel(_(@"File Error"), + _(@"Can't create backup file. Save anyways?"), + _(@"Save"), _(@"Cancel"), nil); + + if (result != NSAlertDefaultReturn) return NO; + } } - - // FIXME: Should set the file attributes - - if (backupFilename && ![self keepBackupFile]) + if ([self writeToFile: fileName + ofType: fileType + originalFile: backupFilename + saveOperation: saveOp]) { - [fileManager removeFileAtPath: backupFilename handler: nil]; + if (saveOp != NSSaveToOperation) + { + [self setFileName: newFileName]; + [self setFileType: fileType]; + [self updateChangeCount: NSChangeCleared]; + } + + // FIXME: Should set the file attributes + + if (backupFilename && ![self keepBackupFile]) + { + [fileManager removeFileAtPath: backupFilename handler: nil]; + } + + return YES; } - - return YES; } } diff --git a/Source/NSDocumentController.m b/Source/NSDocumentController.m index 060b826b7..0b3e099ee 100644 --- a/Source/NSDocumentController.m +++ b/Source/NSDocumentController.m @@ -53,6 +53,7 @@ static NSString *NSDefaultOpenDirectory = @"NSDefaultOpenDirectory"; static NSDocumentController *sharedController = nil; #define TYPE_INFO(name) TypeInfoForName(_types, name) +#define HR_TYPE_INFO(name) TypeInfoForHumanReadableName(_types, name) static NSDictionary *TypeInfoForName (NSArray *types, NSString *typeName) { @@ -70,6 +71,22 @@ static NSDictionary *TypeInfoForName (NSArray *types, NSString *typeName) return nil; } +static NSDictionary *TypeInfoForHumanReadableName (NSArray *types, NSString *typeName) +{ + int i, count = [types count]; + for (i = 0; i < count; i++) + { + NSDictionary *dict = [types objectAtIndex: i]; + + if ([[dict objectForKey: NSHumanReadableNameKey] isEqualToString: typeName]) + { + return dict; + } + } + + return nil; +} + /**

NSDocumentController is a class that controls a set of NSDocuments for an application. As an application delegate, it responds to the @@ -488,7 +505,7 @@ static NSDictionary *TypeInfoForName (NSArray *types, NSString *typeName) - (BOOL) reviewUnsavedDocumentsWithAlertTitle: (NSString *)title cancellable: (BOOL)cancellable { - NSString *cancelString = (cancellable)? _(@"Cancel") : nil; + NSString *cancelString = (cancellable)? ((NSString *)_(@"Cancel")) : ((NSString *)nil); int result; /* Probably as good a place as any to do this */ @@ -846,5 +863,28 @@ static NSString *NSViewerRole = @"Viewer"; return [self _editorTypesForClass: documentClass]; } +- (NSString *) _nameForHumanReadableType: (NSString *)type +{ + return [HR_TYPE_INFO(type) objectForKey: NSNameKey]; +} + +- (NSArray *) _displayNamesForTypes: (NSArray *)types +{ + NSEnumerator *en = [types objectEnumerator]; + NSString *type = nil; + NSMutableArray *result = [NSMutableArray arrayWithCapacity: 10]; + while((type = (NSString *)[en nextObject]) != nil) + { + NSString *name = [self displayNameForType: type]; + [result addObject: name]; + } + return result; +} + +- (NSArray *) _displayNamesForClass: (Class)documentClass +{ + return [self _displayNamesForTypes: + [self _editorTypesForClass: documentClass]]; +} @end