diff --git a/include/wx/osx/dirdlg.h b/include/wx/osx/dirdlg.h index 376905b029..66646c8a4f 100644 --- a/include/wx/osx/dirdlg.h +++ b/include/wx/osx/dirdlg.h @@ -61,8 +61,6 @@ private: // Create and initialize NSOpenPanel that we use in both ShowModal() and // ShowWindowModal(). WX_NSOpenPanel OSXCreatePanel() const; - - WX_NSObject m_sheetDelegate; #endif // Common part of all ctors. diff --git a/include/wx/osx/filedlg.h b/include/wx/osx/filedlg.h index d8a4490042..f2964d4de1 100644 --- a/include/wx/osx/filedlg.h +++ b/include/wx/osx/filedlg.h @@ -94,8 +94,6 @@ protected: bool m_useFileTypeFilter; int m_firstFileTypeFilter; wxArrayString m_currentExtensions; - WX_NSObject m_delegate; - WX_NSObject m_sheetDelegate; #endif private: diff --git a/include/wx/osx/msgdlg.h b/include/wx/osx/msgdlg.h index 61fa9d1422..7d453f661b 100644 --- a/include/wx/osx/msgdlg.h +++ b/include/wx/osx/msgdlg.h @@ -45,9 +45,6 @@ protected: int m_buttonId[4]; int m_buttonCount; -#if wxOSX_USE_COCOA - WX_NSObject m_sheetDelegate; -#endif wxDECLARE_DYNAMIC_CLASS(wxMessageDialog); }; diff --git a/src/generic/dirctrlg.cpp b/src/generic/dirctrlg.cpp index 2a432316b1..e372a850e5 100644 --- a/src/generic/dirctrlg.cpp +++ b/src/generic/dirctrlg.cpp @@ -98,6 +98,10 @@ wxDEFINE_EVENT( wxEVT_DIRCTRL_FILEACTIVATED, wxTreeEvent ); // wxGetAvailableDrives, for WINDOWS, OSX, UNIX (returns "/") // ---------------------------------------------------------------------------- +// since the macOS implementation needs objective-C this is dirdlg.mm +#ifdef __WXOSX__ +extern size_t wxGetAvailableDrives(wxArrayString &paths, wxArrayString &names, wxArrayInt &icon_ids); +#else size_t wxGetAvailableDrives(wxArrayString &paths, wxArrayString &names, wxArrayInt &icon_ids) { #ifdef wxHAS_FILESYSTEM_VOLUMES @@ -156,38 +160,6 @@ size_t wxGetAvailableDrives(wxArrayString &paths, wxArrayString &names, wxArrayI } #endif // __WIN32__/!__WIN32__ -#elif defined(__WXMAC__) && wxOSX_USE_COCOA_OR_CARBON - - ItemCount volumeIndex = 1; - OSErr err = noErr ; - - while( noErr == err ) - { - HFSUniStr255 volumeName ; - FSRef fsRef ; - FSVolumeInfo volumeInfo ; - err = FSGetVolumeInfo(0, volumeIndex, NULL, kFSVolInfoFlags , &volumeInfo , &volumeName, &fsRef); - if( noErr == err ) - { - wxString path = wxMacFSRefToPath( &fsRef ) ; - wxString name = wxMacHFSUniStrToString( &volumeName ) ; - - if ( (volumeInfo.flags & kFSVolFlagSoftwareLockedMask) || (volumeInfo.flags & kFSVolFlagHardwareLockedMask) ) - { - icon_ids.Add(wxFileIconsTable::cdrom); - } - else - { - icon_ids.Add(wxFileIconsTable::drive); - } - // todo other removable - - paths.Add(path); - names.Add(name); - volumeIndex++ ; - } - } - #elif defined(__UNIX__) paths.Add(wxT("/")); names.Add(wxT("/")); @@ -199,6 +171,7 @@ size_t wxGetAvailableDrives(wxArrayString &paths, wxArrayString &names, wxArrayI wxASSERT_MSG( (paths.GetCount() == icon_ids.GetCount()), wxT("Wrong number of icons for available drives.")); return paths.GetCount(); } +#endif // ---------------------------------------------------------------------------- // wxIsDriveAvailable diff --git a/src/osx/cocoa/dialog.mm b/src/osx/cocoa/dialog.mm index d34fa5cb0b..f53b9c29bc 100644 --- a/src/osx/cocoa/dialog.mm +++ b/src/osx/cocoa/dialog.mm @@ -32,11 +32,11 @@ void wxDialog::DoShowWindowModal() NSWindow* parentWindow = parent->GetWXWindow(); NSWindow* theWindow = GetWXWindow(); - [NSApp beginSheet: theWindow - modalForWindow: parentWindow - modalDelegate: theWindow - didEndSelector: nil - contextInfo: nil]; + [parentWindow beginSheet:theWindow completionHandler: + ^(NSModalResponse returnCode) + { + this->ModalFinishedCallback(theWindow, returnCode); + }]; } void wxDialog::EndWindowModal() diff --git a/src/osx/cocoa/dirdlg.mm b/src/osx/cocoa/dirdlg.mm index 373e1e8a94..156f067aa4 100644 --- a/src/osx/cocoa/dirdlg.mm +++ b/src/osx/cocoa/dirdlg.mm @@ -32,6 +32,7 @@ #include "wx/filename.h" #include "wx/evtloop.h" #include "wx/modalhook.h" +#include "wx/generic/dirctrlg.h" // for wxFileIconsTable #include "wx/osx/private.h" @@ -39,7 +40,6 @@ wxIMPLEMENT_CLASS(wxDirDialog, wxDialog); void wxDirDialog::Init() { - m_sheetDelegate = nil; } void wxDirDialog::Create(wxWindow *parent, const wxString& message, @@ -54,13 +54,10 @@ void wxDirDialog::Create(wxWindow *parent, const wxString& message, SetMessage( message ); SetWindowStyle(style); SetPath(defaultPath); - m_sheetDelegate = [[ModalDialogDelegate alloc] init]; - [(ModalDialogDelegate*)m_sheetDelegate setImplementation: this]; } wxDirDialog::~wxDirDialog() { - [m_sheetDelegate release]; } WX_NSOpenPanel wxDirDialog::OSXCreatePanel() const @@ -116,7 +113,7 @@ void wxDirDialog::ShowWindowModal() // Create the window and have it call the ModalFinishedCallback on completion [oPanel beginSheetModalForWindow: nativeParent completionHandler: ^(NSModalResponse returnCode){ - [(ModalDialogDelegate*)m_sheetDelegate sheetDidEnd: oPanel returnCode: returnCode contextInfo: nil]; + this->ModalFinishedCallback(oPanel, returnCode); }]; } @@ -128,14 +125,12 @@ int wxDirDialog::ShowModal() NSOpenPanel *oPanel = OSXCreatePanel(); - int returnCode = -1; - OSXBeginModalDialog(); // Display the panel and process the result on completion - returnCode = (NSInteger)[oPanel runModal]; + int returnCode = (NSInteger)[oPanel runModal]; ModalFinishedCallback(oPanel, returnCode); - + OSXEndModalDialog(); @@ -146,7 +141,7 @@ void wxDirDialog::ModalFinishedCallback(void* panel, int returnCode) { int result = wxID_CANCEL; - if (returnCode == NSOKButton ) + if (returnCode == NSModalResponseOK ) { NSOpenPanel* oPanel = (NSOpenPanel*)panel; @@ -154,7 +149,9 @@ void wxDirDialog::ModalFinishedCallback(void* panel, int returnCode) for ( NSURL* url in selectedURL ) { - m_paths.Add([url fileSystemRepresentation]); + NSString* unsafePath = [NSString stringWithUTF8String:[url fileSystemRepresentation]]; + wxCFStringRef safePath([[unsafePath precomposedStringWithCanonicalMapping] retain]); + m_paths.Add(safePath.AsString()); } if ( !HasFlag(wxDD_MULTIPLE) ) @@ -176,4 +173,35 @@ void wxDirDialog::SetTitle(const wxString &title) wxDialog::SetTitle(title); } +size_t wxGetAvailableDrives(wxArrayString &paths, wxArrayString &names, wxArrayInt &icon_ids) +{ + NSWorkspace *workspace = [NSWorkspace sharedWorkspace]; + NSArray *volumes = [workspace mountedLocalVolumePaths]; + NSFileManager *filemanager = [NSFileManager defaultManager]; + + for (NSString *path in volumes) + { + NSString *description, *type, *name; + BOOL removable, writable, unmountable; + + if ( [workspace getFileSystemInfoForPath:path isRemovable:&removable isWritable:&writable + isUnmountable:&unmountable description:&description type:&type] ) + { + if ( writable ) + icon_ids.Add(wxFileIconsTable::drive); + else + icon_ids.Add(wxFileIconsTable::cdrom); + + name = [filemanager displayNameAtPath:path]; + + paths.Add(wxCFStringRef(path).AsString()); + names.Add(wxCFStringRef(name).AsString()); + } + } + + wxASSERT_MSG( (paths.GetCount() == names.GetCount()), wxT("The number of paths and their human readable names should be equal in number.")); + wxASSERT_MSG( (paths.GetCount() == icon_ids.GetCount()), wxT("Wrong number of icons for available drives.")); + return paths.GetCount(); +} + #endif // wxUSE_DIRDLG diff --git a/src/osx/cocoa/filedlg.mm b/src/osx/cocoa/filedlg.mm index 4957487fb0..84dbf6f7eb 100644 --- a/src/osx/cocoa/filedlg.mm +++ b/src/osx/cocoa/filedlg.mm @@ -50,10 +50,10 @@ wxIMPLEMENT_CLASS(wxFileDialog, wxFileDialogBase); void wxFileDialog::Init() { m_filterIndex = -1; - m_delegate = nil; - m_sheetDelegate = nil; m_filterPanel = NULL; m_filterChoice = NULL; + m_useFileTypeFilter = false; + m_firstFileTypeFilter = 0; } void wxFileDialog::Create( @@ -63,13 +63,10 @@ void wxFileDialog::Create( { wxFileDialogBase::Create(parent, message, defaultDir, defaultFileName, wildCard, style, pos, sz, name); - m_sheetDelegate = [[ModalDialogDelegate alloc] init]; - [(ModalDialogDelegate*)m_sheetDelegate setImplementation: this]; } wxFileDialog::~wxFileDialog() { - [m_sheetDelegate release]; } bool wxFileDialog::SupportsExtraControl() const @@ -196,8 +193,6 @@ void wxFileDialog::ShowWindowModal() wxCHECK_RET(parentWindow, "Window modal display requires parent."); - wxGCC_WARNING_SUPPRESS(deprecated-declarations) - NSArray* types = GetTypesFromFilter( m_wildCard, m_filterNames, m_filterExtensions ) ; if ( HasFlag(wxFD_SAVE) ) { @@ -214,13 +209,20 @@ void wxFileDialog::ShowWindowModal() [sPanel setCanSelectHiddenExtension:YES]; [sPanel setAllowedFileTypes:types]; [sPanel setAllowsOtherFileTypes:NO]; - - NSWindow* nativeParent = parentWindow->GetWXWindow(); - [sPanel beginSheetForDirectory:dir.AsNSString() file:file.AsNSString() - modalForWindow: nativeParent modalDelegate: m_sheetDelegate - didEndSelector: @selector(sheetDidEnd:returnCode:contextInfo:) - contextInfo: nil]; [sPanel setShowsHiddenFiles: HasFlag(wxFD_SHOW_HIDDEN) ? YES : NO]; + + NSWindow* nativeParent = parentWindow->GetWXWindow(); + if ( !m_dir.IsEmpty() ) + [sPanel setDirectoryURL:[NSURL fileURLWithPath:dir.AsNSString() + isDirectory:YES]]; + if ( !m_fileName.IsEmpty() ) + [sPanel setNameFieldStringValue: file.AsNSString()]; + + [sPanel beginSheetModalForWindow:nativeParent completionHandler: + ^(NSModalResponse returnCode) + { + this->ModalFinishedCallback(sPanel, returnCode); + }]; } else { @@ -234,17 +236,19 @@ void wxFileDialog::ShowWindowModal() [oPanel setCanChooseFiles:YES]; [oPanel setMessage:cf.AsNSString()]; [oPanel setAllowsMultipleSelection: (HasFlag(wxFD_MULTIPLE) ? YES : NO )]; - - NSWindow* nativeParent = parentWindow->GetWXWindow(); - [oPanel beginSheetForDirectory:dir.AsNSString() file:file.AsNSString() - types: types modalForWindow: nativeParent - modalDelegate: m_sheetDelegate - didEndSelector: @selector(sheetDidEnd:returnCode:contextInfo:) - contextInfo: nil]; [oPanel setShowsHiddenFiles: HasFlag(wxFD_SHOW_HIDDEN) ? YES : NO]; + + NSWindow* nativeParent = parentWindow->GetWXWindow(); + if ( !m_dir.IsEmpty() ) + [oPanel setDirectoryURL:[NSURL fileURLWithPath:dir.AsNSString() + isDirectory:YES]]; + [oPanel beginSheetModalForWindow:nativeParent completionHandler: + ^(NSModalResponse returnCode) + { + this->ModalFinishedCallback(oPanel, returnCode); + }]; } - wxGCC_WARNING_RESTORE(deprecated-declarations) } // Create a panel with the file type drop down list @@ -293,10 +297,7 @@ void wxFileDialog::DoOnFilterSelected(int index) { NSArray* types = GetTypesFromExtension(m_filterExtensions[index],m_currentExtensions); NSSavePanel* panel = (NSSavePanel*) GetWXWindow(); - if ( m_delegate ) - [panel validateVisibleColumns]; - else - [panel setAllowedFileTypes:types]; + [panel setAllowedFileTypes:types]; } // An item has been selected in the file filter wxChoice: @@ -424,8 +425,6 @@ int wxFileDialog::ShowModal() } } - wxGCC_WARNING_SUPPRESS(deprecated-declarations) - OSXBeginModalDialog(); if ( HasFlag(wxFD_SAVE) ) @@ -462,7 +461,14 @@ int wxFileDialog::ShowModal() DoOnFilterSelected(m_firstFileTypeFilter); } - returnCode = [sPanel runModalForDirectory: m_dir.IsEmpty() ? nil : dir.AsNSString() file:file.AsNSString() ]; + if ( !m_dir.IsEmpty() ) + [sPanel setDirectoryURL:[NSURL fileURLWithPath:dir.AsNSString() + isDirectory:YES]]; + + if ( !m_fileName.IsEmpty() ) + [sPanel setNameFieldStringValue: file.AsNSString()]; + + returnCode = [sPanel runModal]; ModalFinishedCallback(sPanel, returnCode); } else @@ -489,7 +495,7 @@ int wxFileDialog::ShowModal() } else { - [oPanel setAllowedFileTypes: (m_delegate == nil ? types : nil)]; + [oPanel setAllowedFileTypes: types]; } if ( !m_dir.IsEmpty() ) [oPanel setDirectoryURL:[NSURL fileURLWithPath:dir.AsNSString() @@ -502,24 +508,21 @@ int wxFileDialog::ShowModal() OSXEndModalDialog(); - wxGCC_WARNING_RESTORE(deprecated-declarations) - return GetReturnCode(); } void wxFileDialog::ModalFinishedCallback(void* panel, int returnCode) { - wxGCC_WARNING_SUPPRESS(deprecated-declarations) - int result = wxID_CANCEL; if (HasFlag(wxFD_SAVE)) { - if (returnCode == NSOKButton ) + if (returnCode == NSModalResponseOK ) { NSSavePanel* sPanel = (NSSavePanel*)panel; result = wxID_OK; - m_path = wxCFStringRef::AsStringWithNormalizationFormC([sPanel filename]); + NSString* unsafePath = [NSString stringWithUTF8String:[[sPanel URL] fileSystemRepresentation]]; + m_path = wxCFStringRef([[unsafePath precomposedStringWithCanonicalMapping] retain]).AsString(); m_fileName = wxFileNameFromPath(m_path); m_dir = wxPathOnly( m_path ); if (m_filterChoice) @@ -531,7 +534,7 @@ void wxFileDialog::ModalFinishedCallback(void* panel, int returnCode) else { NSOpenPanel* oPanel = (NSOpenPanel*)panel; - if (returnCode == NSOKButton ) + if (returnCode == NSModalResponseOK ) { panel = oPanel; result = wxID_OK; @@ -541,38 +544,34 @@ void wxFileDialog::ModalFinishedCallback(void* panel, int returnCode) m_filterIndex = m_filterChoice->GetSelection(); } - NSArray* filenames = [oPanel filenames]; - for ( size_t i = 0 ; i < [filenames count] ; ++ i ) + bool isFirst = true; + for (NSURL* filename in [oPanel URLs]) { - wxString fnstr = wxCFStringRef::AsStringWithNormalizationFormC([filenames objectAtIndex:i]); + NSString* unsafePath = [NSString stringWithUTF8String:[filename fileSystemRepresentation]]; + wxString fnstr = wxCFStringRef([[unsafePath precomposedStringWithCanonicalMapping] retain]).AsString(); m_paths.Add( fnstr ); m_fileNames.Add( wxFileNameFromPath(fnstr) ); - if ( i == 0 ) + if ( isFirst ) { m_path = fnstr; m_fileName = wxFileNameFromPath(fnstr); m_dir = wxPathOnly( fnstr ); + isFirst = false; } } } - if ( m_delegate ) - { - [oPanel setDelegate:nil]; - [m_delegate release]; - m_delegate = nil; - } } SetReturnCode(result); + // workaround for sandboxed app, see above, must be executed before window modal handler + // because there this instance will be deleted + if ( m_isNativeWindowWrapper ) + UnsubclassWin(); + if (GetModality() == wxDIALOG_MODALITY_WINDOW_MODAL) SendWindowModalDialogEvent ( wxEVT_WINDOW_MODAL_DIALOG_CLOSED ); - // workaround for sandboxed app, see above - if ( m_isNativeWindowWrapper ) - UnsubclassWin(); [(NSSavePanel*) panel setAccessoryView:nil]; - - wxGCC_WARNING_RESTORE(deprecated-declarations) } #endif // wxUSE_FILEDLG diff --git a/src/osx/cocoa/msgdlg.mm b/src/osx/cocoa/msgdlg.mm index 83b3b74d4f..eadfa06e61 100644 --- a/src/osx/cocoa/msgdlg.mm +++ b/src/osx/cocoa/msgdlg.mm @@ -54,13 +54,10 @@ wxMessageDialog::wxMessageDialog(wxWindow *parent, const wxPoint& WXUNUSED(pos)) : wxMessageDialogBase(parent, message, caption, style) { - m_sheetDelegate = [[ModalDialogDelegate alloc] init]; - [(ModalDialogDelegate*)m_sheetDelegate setImplementation: this]; } wxMessageDialog::~wxMessageDialog() { - [m_sheetDelegate release]; } int wxMessageDialog::ShowModal() @@ -196,9 +193,11 @@ void wxMessageDialog::ShowWindowModal() NSAlert* alert = (NSAlert*)ConstructNSAlert(); NSWindow* nativeParent = parentWindow->GetWXWindow(); - [alert beginSheetModalForWindow: nativeParent modalDelegate: m_sheetDelegate - didEndSelector: @selector(sheetDidEnd:returnCode:contextInfo:) - contextInfo: nil]; + [alert beginSheetModalForWindow:nativeParent completionHandler: + ^(NSModalResponse returnCode) + { + this->ModalFinishedCallback(alert, returnCode); + }]; } }