wxMessageBox off the main thread lost result code.
[wxWidgets.git] / src / osx / cocoa / dirdlg.mm
1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        src/osx/cocoa/dirdlg.mm
3 // Purpose:     wxDirDialog
4 // Author:      Stefan Csomor
5 // Modified by:
6 // Created:     2008-08-30
7 // Copyright:   (c) Stefan Csomor
8 // Licence:     wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10
11 // ============================================================================
12 // declarations
13 // ============================================================================
14
15 // ----------------------------------------------------------------------------
16 // headers
17 // ----------------------------------------------------------------------------
18
19 // For compilers that support precompilation, includes "wx.h".
20 #include "wx/wxprec.h"
21
22 #if wxUSE_DIRDLG && !defined(__WXUNIVERSAL__)
23
24 #include "wx/dirdlg.h"
25
26 #ifndef WX_PRECOMP
27     #include "wx/msgdlg.h"
28     #include "wx/filedlg.h"
29     #include "wx/app.h"
30 #endif
31
32 #include "wx/filename.h"
33 #include "wx/evtloop.h"
34 #include "wx/modalhook.h"
35
36 #include "wx/osx/private.h"
37
38 IMPLEMENT_CLASS(wxDirDialog, wxDialog)
39
40 void wxDirDialog::Init()
41 {
42     m_sheetDelegate = nil;
43 }
44
45 void wxDirDialog::Create(wxWindow *parent, const wxString& message,
46         const wxString& defaultPath, long style, const wxPoint& WXUNUSED(pos),
47         const wxSize& WXUNUSED(size), const wxString& WXUNUSED(name))
48 {
49     m_parent = parent;
50
51     SetMessage( message );
52     SetWindowStyle(style);
53     SetPath(defaultPath);
54     m_sheetDelegate = [[ModalDialogDelegate alloc] init];
55     [(ModalDialogDelegate*)m_sheetDelegate setImplementation: this];
56 }
57
58 wxDirDialog::~wxDirDialog()
59 {
60     [m_sheetDelegate release];
61 }
62
63 WX_NSOpenPanel wxDirDialog::OSXCreatePanel() const
64 {
65     NSOpenPanel *oPanel = [NSOpenPanel openPanel];
66     [oPanel setCanChooseDirectories:YES];
67     [oPanel setResolvesAliases:YES];
68     [oPanel setCanChooseFiles:NO];
69
70     wxCFStringRef cf( m_message );
71     [oPanel setMessage:cf.AsNSString()];
72
73     if ( !HasFlag(wxDD_DIR_MUST_EXIST) )
74         [oPanel setCanCreateDirectories:YES];
75
76     return oPanel;
77 }
78
79 void wxDirDialog::ShowWindowModal()
80 {
81     wxNonOwnedWindow* parentWindow = NULL;
82
83     if (GetParent())
84         parentWindow = dynamic_cast<wxNonOwnedWindow*>(wxGetTopLevelParent(GetParent()));
85
86     wxCHECK_RET(parentWindow, "Window modal display requires parent.");
87
88     m_modality = wxDIALOG_MODALITY_WINDOW_MODAL;
89
90     NSOpenPanel *oPanel = OSXCreatePanel();
91
92     NSWindow* nativeParent = parentWindow->GetWXWindow();
93     wxCFStringRef dir( m_path );
94     [oPanel beginSheetForDirectory:dir.AsNSString() file:nil types: nil
95         modalForWindow: nativeParent modalDelegate: m_sheetDelegate
96         didEndSelector: @selector(sheetDidEnd:returnCode:contextInfo:)
97         contextInfo: nil];
98 }
99
100 int wxDirDialog::ShowModal()
101 {
102     WX_HOOK_MODAL_DIALOG();
103
104     wxCFEventLoopPauseIdleEvents pause;
105
106     NSOpenPanel *oPanel = OSXCreatePanel();
107
108     wxCFStringRef dir( m_path );
109
110     m_path = wxEmptyString;
111
112     int returnCode = -1;
113
114     returnCode = (NSInteger)[oPanel runModalForDirectory:dir.AsNSString() file:nil types:nil];
115     ModalFinishedCallback(oPanel, returnCode);
116
117     return GetReturnCode();
118 }
119
120 void wxDirDialog::ModalFinishedCallback(void* panel, int returnCode)
121 {
122     int result = wxID_CANCEL;
123
124     if (returnCode == NSOKButton )
125     {
126         NSOpenPanel* oPanel = (NSOpenPanel*)panel;
127         SetPath( wxCFStringRef::AsStringWithNormalizationFormC([[oPanel filenames] objectAtIndex:0]));
128         result = wxID_OK;
129     }
130     SetReturnCode(result);
131
132     if (GetModality() == wxDIALOG_MODALITY_WINDOW_MODAL)
133         SendWindowModalDialogEvent ( wxEVT_WINDOW_MODAL_DIALOG_CLOSED  );
134 }
135
136 #endif // wxUSE_DIRDLG