diff --git a/AppKit/CMakeLists.txt b/AppKit/CMakeLists.txt index 6e379d40..e4e76373 100644 --- a/AppKit/CMakeLists.txt +++ b/AppKit/CMakeLists.txt @@ -340,7 +340,6 @@ set(AppKit_sources NSDrawer.subproj/NSDrawerWindow.m NSPrinter.m - NSOpenPanel.m NSTableHeaderCell.m NSColorPanel.m NSCell.m @@ -353,7 +352,10 @@ set(AppKit_sources NSSystemInfoPanel/NSSystemInfoPanel.m - NSSavePanel.m + NSSavePanel.subproj/_NSFileSystemDataSource.m + NSSavePanel.subproj/NSOpenPanel.m + NSSavePanel.subproj/NSSavePanel.m + NSDockTile.m NSGraphics.m NSColorWell.m @@ -433,6 +435,9 @@ set(AppKit_resources en.lproj/NSFontPanel.nib en.lproj/NSFontPanel.nib/keyedobjects.nib en.lproj/NSSystemInfoPanel.nib NSSystemInfoPanel/en.lproj/NSSystemInfoPanel.nib/keyedobjects.nib en.lproj/NSToolbarCustomizationPalette.nib en.lproj/NSToolbarCustomizationPalette.nib/keyedobjects.nib + + en.lproj/NSSavePanel.nib en.lproj/NSSavePanel.nib + en.lproj/NSOpenPanel.nib en.lproj/NSOpenPanel.nib ) add_framework(AppKit diff --git a/AppKit/NSDisplay.m b/AppKit/NSDisplay.m index a58eff43..e83a89c8 100644 --- a/AppKit/NSDisplay.m +++ b/AppKit/NSDisplay.m @@ -246,6 +246,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI return nil; } +- (BOOL) implementsCustomPanelForClass: (Class) panelClass { + return NO; +} + -(int)savePanel:(NSSavePanel *)savePanel runModalForDirectory:(NSString *)directory file:(NSString *)file { NSInvalidAbstractInvocation(); return 0; diff --git a/AppKit/NSOpenPanel.m b/AppKit/NSSavePanel.subproj/NSOpenPanel.m similarity index 66% rename from AppKit/NSOpenPanel.m rename to AppKit/NSSavePanel.subproj/NSOpenPanel.m index 72022a12..d0292926 100644 --- a/AppKit/NSOpenPanel.m +++ b/AppKit/NSSavePanel.subproj/NSOpenPanel.m @@ -10,26 +10,50 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #import #import -@interface NSSavePanel (Private) +@interface NSSavePanel (Private) -(void)_setFilename:(NSString*)filename; @end @implementation NSOpenPanel -+(NSOpenPanel *)openPanel { - return [[self new] autorelease]; +- (id) resetToDefaultValues { + self = [super resetToDefaultValues]; + _filenames=[NSArray new]; + [_dialogTitle release]; + _dialogTitle= [NSLocalizedStringFromTableInBundle(@"Open", nil, [NSBundle bundleForClass: [NSOpenPanel class]], @"The title of the open panel") copy]; + _allowsMultipleSelection=NO; + _canChooseDirectories=NO; + _canChooseFiles=YES; + _resolvesAliases=YES; + return self; } --init { - [super init]; - _filenames=[NSArray new]; - [_dialogTitle release]; - _dialogTitle= [NSLocalizedStringFromTableInBundle(@"Open", nil, [NSBundle bundleForClass: [NSOpenPanel class]], @"The title of the open panel") copy]; - _allowsMultipleSelection=NO; - _canChooseDirectories=NO; - _canChooseFiles=YES; - _resolvesAliases=YES; - return self; +static NSOpenPanel *_newPanel = nil; + ++ (void) set_newPanel: (NSOpenPanel *) newPanel { + _newPanel = newPanel; +} + ++ (NSSavePanel *) openPanel { + if ([[NSDisplay currentDisplay] implementsCustomPanelForClass: self]) + { + _newPanel = [[self alloc] + initWithContentRect: NSMakeRect(0, 0, 1, 1) + styleMask: NSTitledWindowMask|NSResizableWindowMask + backing: NSBackingStoreBuffered + defer: YES]; + } + else + { + [NSBundle loadNibNamed: @"NSOpenPanel" owner: self]; + } + // FIXME: release it? + return [_newPanel resetToDefaultValues]; +} + +- init { + [self release]; + return [[NSOpenPanel openPanel] retain]; } -(void)dealloc { @@ -50,29 +74,49 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI NSArray *paths=[self filenames]; NSMutableArray *result=[NSMutableArray arrayWithCapacity:[paths count]]; int i,count=[paths count]; - + for(i=0;i #import #import @@ -13,20 +14,42 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI @implementation NSSavePanel -+(NSSavePanel *)savePanel { - return [[self new] autorelease]; +- (id) resetToDefaultValues { + _dialogTitle=@"Save"; + _filename=@""; + _directory=[NSHomeDirectory() copy]; + _requiredFileType=@""; + _treatsFilePackagesAsDirectories=NO; + _accessoryView=nil; + return self; +} + +static NSSavePanel *_newPanel = nil; + ++ (void) set_newPanel: (NSSavePanel *) newPanel { + _newPanel = newPanel; +} + ++ (NSSavePanel *) savePanel { + if ([[NSDisplay currentDisplay] implementsCustomPanelForClass: self]) + { + _newPanel = [[self alloc] + initWithContentRect: NSMakeRect(0, 0, 1, 1) + styleMask: NSTitledWindowMask|NSResizableWindowMask + backing: NSBackingStoreBuffered + defer: YES]; + } + else + { + [NSBundle loadNibNamed: @"NSSavePanel" owner: self]; + } + // FIXME: release it? + return [_newPanel resetToDefaultValues]; } -init { - [super initWithContentRect:NSMakeRect(0,0,1,1) styleMask:NSTitledWindowMask|NSResizableWindowMask backing:NSBackingStoreBuffered defer:YES]; - - _dialogTitle=@"Save"; - _filename=@""; - _directory=[NSHomeDirectory() copy]; - _requiredFileType=@""; - _treatsFilePackagesAsDirectories=NO; - _accessoryView=nil; - return self; + [self release]; + return [[NSSavePanel savePanel] retain]; } -(void)dealloc { @@ -63,14 +86,37 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI return ret; } --(int)runModalForDirectory:(NSString *)directory file:(NSString *)file { - [self _setFilename:file]; - [self setDirectory:directory]; - return [[NSDisplay currentDisplay] savePanel:self runModalForDirectory:directory file:file]; +- (IBAction) _selectFile: (id) sender { + NSURL *url = [_outlineView itemAtRow: [_outlineView selectedRow]]; + [self _setFilename: [url path]]; + + [NSApp stopModalWithCode: NSOKButton]; } --(int)runModal { - return [[NSDisplay currentDisplay] savePanel:self runModalForDirectory:[self directory] file:@""]; +- (IBAction) _cancel: (id) sender { + [NSApp stopModalWithCode: NSCancelButton]; +} + +- (NSInteger) runModalForDirectory: (NSString *) directory + file: (NSString *) file { + [self _setFilename: file]; + [self setDirectory: directory]; + + return [self runModal]; +} + +- (NSInteger) runModal { + NSInteger res; + if ([[NSDisplay currentDisplay] implementsCustomPanelForClass: [self class]]) + { + res = [[NSDisplay currentDisplay] savePanel: self + runModalForDirectory: [self directory] + file: [self filename]]; + } else { + res = [NSApp runModalForWindow: self]; + [self close]; + } + return res; } -(NSString *)directory { @@ -176,7 +222,12 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI } -(void)setAllowedFileTypes:(NSArray *)value { - NSUnimplementedMethod(); + [_allowedFileTypes release]; + _allowedFileTypes = [value copy]; +} + +- (NSArray *) allowedFileTypes { + return [[_allowedFileTypes copy] autorelease]; } -(void)setAllowsOtherFileTypes:(BOOL)value { diff --git a/AppKit/NSSavePanel.subproj/_NSFileSystemDataSource.h b/AppKit/NSSavePanel.subproj/_NSFileSystemDataSource.h new file mode 100644 index 00000000..033531d1 --- /dev/null +++ b/AppKit/NSSavePanel.subproj/_NSFileSystemDataSource.h @@ -0,0 +1,8 @@ +#import + +@interface _NSFileSystemDataSource : NSObject { + NSMutableSet *_cachedPaths; + NSFileManager *_fileManager; +} + +@end diff --git a/AppKit/NSSavePanel.subproj/_NSFileSystemDataSource.m b/AppKit/NSSavePanel.subproj/_NSFileSystemDataSource.m new file mode 100644 index 00000000..4594a7a6 --- /dev/null +++ b/AppKit/NSSavePanel.subproj/_NSFileSystemDataSource.m @@ -0,0 +1,72 @@ +#import "_NSFileSystemDataSource.h" +#import + +@implementation _NSFileSystemDataSource + +- (id) init { + self = [super init]; + _cachedPaths = [[NSMutableSet alloc] init]; + _fileManager = [[NSFileManager defaultManager] retain]; + return self; +} + +- (void) dealloc { + [_cachedPaths release]; + [_fileManager release]; + [super dealloc]; +} + +- (NSInteger) outlineView: (NSOutlineView *) outlineView + numberOfChildrenOfItem: (NSURL *) url { + + if (url == nil) { + url = [NSURL URLWithString: @"/"]; + } + return [[_fileManager contentsOfDirectoryAtURL: url + includingPropertiesForKeys: nil + options: 0 + error: nil] count]; +} + +- (BOOL) outlineView: (NSOutlineView *) outlineView + isItemExpandable: (NSURL *) url { + + if (url == nil) { + return YES; + } + + BOOL isDirectory; + [_fileManager fileExistsAtPath: [url path] isDirectory: &isDirectory]; + return isDirectory; +} + +- (NSURL *) outlineView: (NSOutlineView *) outlineView + child: (NSInteger) index + ofItem: (NSURL *) url { + + if (url == nil) { + url = [NSURL URLWithString: @"/"]; + } + NSArray *items = [_fileManager contentsOfDirectoryAtURL: url + includingPropertiesForKeys: nil + options: 0 + error: nil]; + // TODO: sort + NSURL *preRes = [items objectAtIndex: index]; + NSURL *res = [_cachedPaths member: preRes]; + if (res == nil) { + [_cachedPaths addObject: preRes]; + res = preRes; + } + + return res; +} + +- (NSString *) outlineView: (NSOutlineView *) outlineView + objectValueForTableColumn: (NSTableColumn *) tableColumn + byItem: (NSURL *) url { + + return [[url pathComponents] lastObject]; +} + +@end diff --git a/AppKit/en.lproj/NSOpenPanel.nib b/AppKit/en.lproj/NSOpenPanel.nib new file mode 100644 index 00000000..a6dc86e2 Binary files /dev/null and b/AppKit/en.lproj/NSOpenPanel.nib differ diff --git a/AppKit/en.lproj/NSSavePanel.nib b/AppKit/en.lproj/NSSavePanel.nib new file mode 100644 index 00000000..93ab267a Binary files /dev/null and b/AppKit/en.lproj/NSSavePanel.nib differ diff --git a/AppKit/include/AppKit/NSDisplay.h b/AppKit/include/AppKit/NSDisplay.h index abac63bb..cd4885ce 100644 --- a/AppKit/include/AppKit/NSDisplay.h +++ b/AppKit/include/AppKit/NSDisplay.h @@ -59,6 +59,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI - (CGContextRef)graphicsPortForPrintOperationWithView:(NSView *)view printInfo:(NSPrintInfo *)printInfo pageRange:(NSRange)pageRange; +- (BOOL) implementsCustomPanelForClass: (Class) panelClass; + - (int)savePanel:(NSSavePanel *)savePanel runModalForDirectory:(NSString *)directory file:(NSString *)file; - (int)openPanel:(NSOpenPanel *)openPanel runModalForDirectory:(NSString *)directory file:(NSString *)file types:(NSArray *)types; diff --git a/AppKit/include/AppKit/NSSavePanel.h b/AppKit/include/AppKit/NSSavePanel.h index 61b9f084..7a859fb5 100644 --- a/AppKit/include/AppKit/NSSavePanel.h +++ b/AppKit/include/AppKit/NSSavePanel.h @@ -7,8 +7,9 @@ The above copyright notice and this permission notice shall be included in all c THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #import +#import -@class NSView; +@class NSView, NSOutlineView; enum { NSFileHandlingPanelCancelButton = NSCancelButton, @@ -21,11 +22,14 @@ enum { NSString *_filename; NSString *_directory; NSString *_requiredFileType; + NSArray *_allowedFileTypes; NSString *_message; NSString *_prompt; BOOL _treatsFilePackagesAsDirectories; NSView *_accessoryView; + + IBOutlet NSOutlineView *_outlineView; } + (NSSavePanel *)savePanel; @@ -47,6 +51,8 @@ enum { - (void)setRequiredFileType:(NSString *)type; - (void)setTreatsFilePackagesAsDirectories:(BOOL)flag; +- (NSArray *) allowedFileTypes; + - (void)setAccessoryView:(NSView *)view; - (void)setCanCreateDirectories:(BOOL)value; - (void)setAllowedFileTypes:(NSArray *)value; @@ -64,4 +70,7 @@ enum { modalDelegate:(id)modalDelegate didEndSelector:(SEL)didEndSelector contextInfo:(void *)contextInfo; + +- (IBAction) _selectFile: (id) sender; +- (IBAction) _cancel: (id) sender; @end