X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/1b447793ea73455bcec70ee39db841b28e6fc7cf..6178debcd342963974dbdce6ac2ddb2fbe89e42a:/src/osx/cocoa/filedlg.mm diff --git a/src/osx/cocoa/filedlg.mm b/src/osx/cocoa/filedlg.mm index c212ecea36..4d5aaad01f 100644 --- a/src/osx/cocoa/filedlg.mm +++ b/src/osx/cocoa/filedlg.mm @@ -30,6 +30,7 @@ #endif #include "wx/filename.h" +#include "wx/tokenzr.h" #include "wx/osx/private.h" @@ -37,6 +38,10 @@ // implementation // ============================================================================ +// Open Items: +// - support for old style MacOS creator / type combos +// - parameter support for descending into packages as directories (setTreatsFilePackagesAsDirectories) + IMPLEMENT_CLASS(wxFileDialog, wxFileDialogBase) wxFileDialog::wxFileDialog( @@ -47,6 +52,10 @@ wxFileDialog::wxFileDialog( { } +bool wxFileDialog::SupportsExtraControl() const +{ + return true; +} NSArray* GetTypesFromFilter( const wxString filter ) { @@ -99,288 +108,245 @@ NSArray* GetTypesFromFilter( const wxString filter ) const size_t extCount = extensions.GetCount(); for ( size_t i = 0 ; i < extCount; i++ ) { - wxString extension = extensions[i]; - - // Remove leading '*' - if (extension.length() && (extension.GetChar(0) == '*')) - extension = extension.Mid( 1 ); + wxString extensiongroup = extensions[i]; + wxStringTokenizer tokenizer( extensiongroup , wxT(";") ) ; + while ( tokenizer.HasMoreTokens() ) + { + wxString extension = tokenizer.GetNextToken() ; + // Remove leading '*' + if (extension.length() && (extension.GetChar(0) == '*')) + extension = extension.Mid( 1 ); - // Remove leading '.' - if (extension.length() && (extension.GetChar(0) == '.')) - extension = extension.Mid( 1 ); + // Remove leading '.' + if (extension.length() && (extension.GetChar(0) == '.')) + extension = extension.Mid( 1 ); - if ( extension.IsEmpty() ) - { - if ( types != nil ) - [types release]; - return nil; - } + // Remove leading '*', this is for handling *.* + if (extension.length() && (extension.GetChar(0) == '*')) + extension = extension.Mid( 1 ); + if ( extension.IsEmpty() ) + { + if ( types != nil ) + [types release]; + return nil; + } - if ( types == nil ) - types = [[NSMutableArray alloc] init]; + if ( types == nil ) + types = [[NSMutableArray alloc] init]; - wxCFStringRef cfext(extension); - [types addObject: (NSString*)cfext.AsNSString() ]; + wxCFStringRef cfext(extension); + [types addObject: (NSString*)cfext.AsNSString() ]; #if 0 - wxUint32 fileType, creator; - - // extension -> mactypes + // add support for classic fileType / creator here + wxUint32 fileType, creator; + // extension -> mactypes #endif + } + } } return types; } -int wxFileDialog::ShowModal() +void wxFileDialog::ShowWindowModal() { - int result = wxID_CANCEL; - - NSSavePanel *panel = nil; - wxCFStringRef cf( m_message ); - wxCFStringRef dir( m_dir ); wxCFStringRef file( m_fileName ); - m_path = wxEmptyString; - m_fileNames.Clear(); + wxNonOwnedWindow* parentWindow = NULL; + + m_modality = wxDIALOG_MODALITY_WINDOW_MODAL; + if (GetParent()) + parentWindow = dynamic_cast(wxGetTopLevelParent(GetParent())); + + wxASSERT_MSG(parentWindow, "Window modal display requires parent."); + if (HasFlag(wxFD_SAVE)) { NSSavePanel* sPanel = [NSSavePanel savePanel]; + + SetupExtraControls(sPanel); + // makes things more convenient: [sPanel setCanCreateDirectories:YES]; [sPanel setMessage:cf.AsNSString()]; + // if we should be able to descend into pacakges we must somehow + // be able to pass this in [sPanel setTreatsFilePackagesAsDirectories:NO]; - - if ( HasFlag(wxFD_OVERWRITE_PROMPT) ) - { - } - - if ( [sPanel runModalForDirectory:dir.AsNSString() file:file.AsNSString() ] == NSOKButton ) - { - panel = sPanel; - result = wxID_OK; - - wxCFStringRef filename( [[sPanel filename] retain] ); - - m_path = filename.AsString(); - m_fileName = wxFileNameFromPath(m_path); - m_dir = wxPathOnly( m_path ); - } + [sPanel setCanSelectHiddenExtension:YES]; + + NSWindow* nativeParent = parentWindow->GetWXWindow(); + ModalDialogDelegate* sheetDelegate = [[ModalDialogDelegate alloc] init]; + [sheetDelegate setImplementation: this]; + [sPanel beginSheetForDirectory:dir.AsNSString() file:file.AsNSString() + modalForWindow: nativeParent modalDelegate: sheetDelegate + didEndSelector: @selector(sheetDidEnd:returnCode:contextInfo:) + contextInfo: nil]; } - else + else { NSArray* types = GetTypesFromFilter( m_wildCard ) ; NSOpenPanel* oPanel = [NSOpenPanel openPanel]; + + SetupExtraControls(oPanel); + [oPanel setTreatsFilePackagesAsDirectories:NO]; [oPanel setCanChooseDirectories:NO]; [oPanel setResolvesAliases:YES]; [oPanel setCanChooseFiles:YES]; [oPanel setMessage:cf.AsNSString()]; + + NSWindow* nativeParent = parentWindow->GetWXWindow(); + ModalDialogDelegate* sheetDelegate = [[ModalDialogDelegate alloc] init]; + [sheetDelegate setImplementation: this]; + [oPanel beginSheetForDirectory:dir.AsNSString() file:file.AsNSString() + types: types modalForWindow: nativeParent + modalDelegate: sheetDelegate + didEndSelector: @selector(sheetDidEnd:returnCode:contextInfo:) + contextInfo: nil]; + } +} - if ( [oPanel runModalForDirectory:dir.AsNSString() file:file.AsNSString() types:types] == NSOKButton ) +void wxFileDialog::SetupExtraControls(WXWindow nativeWindow) +{ + NSSavePanel* panel = (NSSavePanel*) nativeWindow; + + wxNonOwnedWindow::Create( GetParent(), nativeWindow ); + + if (HasExtraControlCreator()) + { + CreateExtraControl(); + wxWindow* control = GetExtraControl(); + if ( control ) { - panel = oPanel; - result = wxID_OK; - NSArray* filenames = [oPanel filenames]; - for ( size_t i = 0 ; i < [filenames count] ; ++ i ) - { - wxCFStringRef filename( [(NSString*) [filenames objectAtIndex:i] retain] ); - wxString fnstr = filename.AsString(); - m_paths.Add( fnstr ); - m_fileNames.Add( wxFileNameFromPath(fnstr) ); - if ( i == 0 ) - { - m_path = fnstr; - m_fileName = wxFileNameFromPath(fnstr); - m_dir = wxPathOnly( fnstr ); - } - } + NSView* accView = control->GetHandle(); + [accView removeFromSuperview]; + [panel setAccessoryView:accView]; + } + else + { + [panel setAccessoryView:nil]; } - if ( types != nil ) - [types release]; } - - return result; } -#if 0 +int wxFileDialog::ShowModal() +{ + wxCFStringRef cf( m_message ); - wxASSERT(CreateBase(parent,wxID_ANY,pos,wxDefaultSize,style,wxDefaultValidator,wxDialogNameStr)); + wxCFStringRef dir( m_dir ); + wxCFStringRef file( m_fileName ); - if ( parent ) - parent->AddChild(this); + m_path = wxEmptyString; + m_fileNames.Clear(); + m_paths.Clear(); + // since we don't support retrieving the matching filter + m_filterIndex = -1; - m_cocoaNSWindow = nil; - m_cocoaNSView = nil; + wxNonOwnedWindow* parentWindow = NULL; + int returnCode = -1; - //Init the wildcard array - m_wildcards = [[NSMutableArray alloc] initWithCapacity:0]; + if (GetParent()) + { + parentWindow = dynamic_cast(wxGetTopLevelParent(GetParent())); + } - //If the user requests to save - use a NSSavePanel - //else use a NSOpenPanel if (HasFlag(wxFD_SAVE)) { - SetNSPanel([NSSavePanel savePanel]); - - [GetNSSavePanel() setTitle:wxNSStringWithWxString(message)]; + NSSavePanel* sPanel = [NSSavePanel savePanel]; - [GetNSSavePanel() setPrompt:@"Save"]; - [GetNSSavePanel() setTreatsFilePackagesAsDirectories:YES]; - [GetNSSavePanel() setCanSelectHiddenExtension:YES]; + SetupExtraControls(sPanel); -// Cached as per-app in obj-c -// [GetNSSavePanel() setExtensionHidden:YES]; + // makes things more convenient: + [sPanel setCanCreateDirectories:YES]; + [sPanel setMessage:cf.AsNSString()]; + // if we should be able to descend into pacakges we must somehow + // be able to pass this in + [sPanel setTreatsFilePackagesAsDirectories:NO]; + [sPanel setCanSelectHiddenExtension:YES]; - // - // NB: Note that only Panther supports wildcards - // with save dialogs - not that wildcards in save - // dialogs are all that useful, anyway :) - // - } - else //m_dialogStyle & wxFD_OPEN - { - SetNSPanel([NSOpenPanel openPanel]); - [m_cocoaNSWindow setTitle:wxNSStringWithWxString(message)]; - - [(NSOpenPanel*)m_cocoaNSWindow setAllowsMultipleSelection:(HasFlag(wxFD_MULTIPLE))]; - [(NSOpenPanel*)m_cocoaNSWindow setResolvesAliases:YES]; - [(NSOpenPanel*)m_cocoaNSWindow setCanChooseFiles:YES]; - [(NSOpenPanel*)m_cocoaNSWindow setCanChooseDirectories:NO]; - [GetNSSavePanel() setPrompt:@"Open"]; - - //convert wildcards - open panel only takes file extensions - - //no actual wildcards here :) - size_t lastwcpos = 0; - bool bDescription = true; - size_t i; - for(i = wildCard.find('|'); - i != wxString::npos; - i = wildCard.find('|', lastwcpos+1)) + if ( HasFlag(wxFD_OVERWRITE_PROMPT) ) { - size_t oldi = i; - - if(!bDescription) - { - bDescription = !bDescription; - - //work backwards looking for a period - while(i != lastwcpos && wildCard[--i] != '.') {} - - if(i == lastwcpos) - { - //no extension - can't use this wildcard - lastwcpos = oldi; - continue; - } - - [m_wildcards addObject:wxNSStringWithWxString(wildCard.substr(i+1, oldi-i-1))]; - } - else - bDescription = !bDescription; - lastwcpos = oldi; } - if (!bDescription) - { - //get last wildcard - size_t oldi = wildCard.length(); - i = oldi; - - //work backwards looking for a period - while(i != lastwcpos && wildCard[--i] != '.') {} - - if(i != lastwcpos) - [m_wildcards addObject:wxNSStringWithWxString(wildCard.substr(i+1, oldi-i-1))]; - } + returnCode = [sPanel runModalForDirectory:dir.AsNSString() file:file.AsNSString() ]; + ModalFinishedCallback(sPanel, returnCode); - if ([m_wildcards count] == 0) - { - [m_wildcards release]; - m_wildcards = nil; - } + [sPanel setAccessoryView:nil]; } -} - -wxFileDialog::~wxFileDialog() -{ - [m_wildcards release]; -} - -void wxFileDialog::GetPaths(wxArrayString& paths) const -{ - paths.Empty(); + else + { + NSArray* types = GetTypesFromFilter( m_wildCard ) ; + NSOpenPanel* oPanel = [NSOpenPanel openPanel]; + + SetupExtraControls(oPanel); + + [oPanel setTreatsFilePackagesAsDirectories:NO]; + [oPanel setCanChooseDirectories:NO]; + [oPanel setResolvesAliases:YES]; + [oPanel setCanChooseFiles:YES]; + [oPanel setMessage:cf.AsNSString()]; - wxString dir(m_dir); - if ( m_dir.Last() != _T('\\') ) - dir += _T('\\'); + returnCode = [oPanel runModalForDirectory:dir.AsNSString() + file:file.AsNSString() types:types]; - size_t count = m_fileNames.GetCount(); - for ( size_t n = 0; n < count; n++ ) - { - if (wxFileName(m_fileNames[n]).IsAbsolute()) - paths.Add(m_fileNames[n]); - else - paths.Add(dir + m_fileNames[n]); + ModalFinishedCallback(oPanel, returnCode); + + [oPanel setAccessoryView:nil]; + + if ( types != nil ) + [types release]; } -} -void wxFileDialog::GetFilenames(wxArrayString& files) const -{ - files = m_fileNames; + return GetReturnCode(); } -void wxFileDialog::SetPath(const wxString& path) -{ - wxString ext; - wxFileName::SplitPath(path, &m_dir, &m_fileName, &ext); - if ( !ext.empty() ) - m_fileName << _T('.') << ext; -} - -int wxFileDialog::ShowModal() +void wxFileDialog::ModalFinishedCallback(void* panel, int returnCode) { - wxAutoNSAutoreleasePool thePool; - - m_fileNames.Empty(); - - int nResult; - + int result = wxID_CANCEL; if (HasFlag(wxFD_SAVE)) { - nResult = [GetNSSavePanel() - runModalForDirectory:wxNSStringWithWxString(m_dir) - file:wxNSStringWithWxString(m_fileName)]; - - if (nResult == NSOKButton) + if (returnCode == NSOKButton ) { - m_fileNames.Add(wxStringWithNSString([GetNSSavePanel() filename])); - m_path = m_fileNames[0]; + NSSavePanel* sPanel = (NSSavePanel*)panel; + result = wxID_OK; + + m_path = wxCFStringRef::AsString([sPanel filename]); + m_fileName = wxFileNameFromPath(m_path); + m_dir = wxPathOnly( m_path ); } } - else //m_dialogStyle & wxFD_OPEN + else { - nResult = [(NSOpenPanel*)m_cocoaNSWindow - runModalForDirectory:wxNSStringWithWxString(m_dir) - file:wxNSStringWithWxString(m_fileName) - types:m_wildcards]; - - if (nResult == NSOKButton) + NSOpenPanel* oPanel = (NSOpenPanel*)panel; + if (returnCode == NSOKButton ) { - for(unsigned i = 0; i < [[(NSOpenPanel*)m_cocoaNSWindow filenames] count]; ++i) + panel = oPanel; + result = wxID_OK; + NSArray* filenames = [oPanel filenames]; + for ( size_t i = 0 ; i < [filenames count] ; ++ i ) { - m_fileNames.Add(wxStringWithNSString([[(NSOpenPanel*)m_cocoaNSWindow filenames] objectAtIndex:(i)])); + wxString fnstr = wxCFStringRef::AsString([filenames objectAtIndex:i]); + m_paths.Add( fnstr ); + m_fileNames.Add( wxFileNameFromPath(fnstr) ); + if ( i == 0 ) + { + m_path = fnstr; + m_fileName = wxFileNameFromPath(fnstr); + m_dir = wxPathOnly( fnstr ); + } } - - m_path = m_fileNames[0]; } } - - return nResult == NSOKButton ? wxID_OK : wxID_CANCEL; + SetReturnCode(result); + + if (GetModality() == wxDIALOG_MODALITY_WINDOW_MODAL) + SendWindowModalDialogEvent ( wxEVT_WINDOW_MODAL_DIALOG_CLOSED ); + + [(NSSavePanel*) panel setAccessoryView:nil]; } -#endif - #endif // wxUSE_FILEDLG