mirror of
https://github.com/darlinghq/darling-cocotron.git
synced 2024-12-03 17:51:25 +00:00
Implement basic NSSavePanel & NSOpenPanel-s directly in Cocoa
The upstream Cocotron assumes that the implementation of the file panels is provided by the display, i.e. by the native toolkit. That is what we ultimately want as well, but we're far from being there yet, and we also don't want to make any toolkit a hard requirement. So in order to have our cake and eat it too, these panel implementations are designed work entirely inside Cocoa but also let the display provide a native implementation instead if one is available.
This commit is contained in:
parent
26a2c08c8b
commit
f965e69721
@ -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
|
||||
|
@ -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;
|
||||
|
@ -10,26 +10,50 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
||||
#import <AppKit/NSDisplay.h>
|
||||
#import <Foundation/NSURL.h>
|
||||
|
||||
@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<count;i++)
|
||||
[result addObject:[NSURL fileURLWithPath:[paths objectAtIndex:i]]];
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
-(int)runModalForDirectory:(NSString *)directory file:(NSString *)file types:(NSArray *)types {
|
||||
- (void) _setFilename: (NSString *) filename {
|
||||
[super _setFilename: filename];
|
||||
_filenames = [@[filename] retain];
|
||||
}
|
||||
|
||||
- (NSInteger) runModalForDirectory:(NSString *)directory file:(NSString *)file types:(NSArray *)types {
|
||||
[self _setFilename:file];
|
||||
[self setDirectory:directory];
|
||||
return [[NSDisplay currentDisplay] openPanel:self runModalForDirectory:directory file:file types:types];
|
||||
[self setAllowedFileTypes: types];
|
||||
return [self runModal];
|
||||
}
|
||||
|
||||
-(int)runModalForTypes:(NSArray *)types {
|
||||
return [self runModalForDirectory:[self directory] file:nil types:types];
|
||||
- (NSInteger) runModalForTypes:(NSArray *)types {
|
||||
[self setAllowedFileTypes: types];
|
||||
return [self runModal];
|
||||
}
|
||||
|
||||
-(int)runModalForDirectory:(NSString *)directory file:(NSString *)file {
|
||||
return [self runModalForDirectory:directory file:file types:nil];
|
||||
- (NSInteger) runModalForDirectory:(NSString *)directory file:(NSString *)file {
|
||||
[self setDirectory: directory];
|
||||
[self _setFilename:file];
|
||||
return [self runModal];
|
||||
}
|
||||
|
||||
-(int)runModal {
|
||||
return [self runModalForDirectory:nil file:nil types:nil];
|
||||
- (NSInteger) runModal {
|
||||
NSInteger res;
|
||||
if ([[NSDisplay currentDisplay] implementsCustomPanelForClass: [self class]])
|
||||
{
|
||||
res = [[NSDisplay currentDisplay] openPanel: self
|
||||
runModalForDirectory: [self directory]
|
||||
file: [self filename]
|
||||
types: [self allowedFileTypes]];
|
||||
} else {
|
||||
res = [NSApp runModalForWindow: self];
|
||||
[self close];
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
-(BOOL)allowsMultipleSelection {
|
@ -5,6 +5,7 @@ Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
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 <AppKit/NSSavePanel.h>
|
||||
#import <AppKit/NSView.h>
|
||||
#import <AppKit/NSApplication.h>
|
||||
@ -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 {
|
8
AppKit/NSSavePanel.subproj/_NSFileSystemDataSource.h
Normal file
8
AppKit/NSSavePanel.subproj/_NSFileSystemDataSource.h
Normal file
@ -0,0 +1,8 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface _NSFileSystemDataSource : NSObject {
|
||||
NSMutableSet *_cachedPaths;
|
||||
NSFileManager *_fileManager;
|
||||
}
|
||||
|
||||
@end
|
72
AppKit/NSSavePanel.subproj/_NSFileSystemDataSource.m
Normal file
72
AppKit/NSSavePanel.subproj/_NSFileSystemDataSource.m
Normal file
@ -0,0 +1,72 @@
|
||||
#import "_NSFileSystemDataSource.h"
|
||||
#import <AppKit/NSOutlineView.h>
|
||||
|
||||
@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
|
BIN
AppKit/en.lproj/NSOpenPanel.nib
generated
Normal file
BIN
AppKit/en.lproj/NSOpenPanel.nib
generated
Normal file
Binary file not shown.
BIN
AppKit/en.lproj/NSSavePanel.nib
generated
Normal file
BIN
AppKit/en.lproj/NSSavePanel.nib
generated
Normal file
Binary file not shown.
@ -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;
|
||||
|
||||
|
@ -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 <AppKit/NSPanel.h>
|
||||
#import <AppKit/NSNibLoading.h>
|
||||
|
||||
@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
|
||||
|
Loading…
Reference in New Issue
Block a user