1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxFileDialog
4 // Author: David Webster
8 // Copyright: (c) David Webster
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
21 #include "wx/msgdlg.h"
22 #include "wx/dialog.h"
23 #include "wx/filedlg.h"
32 #include "wx/os2/private.h"
38 #include "wx/tokenzr.h"
40 #define wxMAXPATH 1024
41 #define wxMAXFILE 1024
59 IMPLEMENT_CLASS(wxFileDialog
, wxDialog
)
61 // ----------------------------------------------------------------------------
63 // ----------------------------------------------------------------------------
65 wxString
wxFileSelector(
67 , const char* pzDefaultDir
68 , const char* pzDefaultFileName
69 , const char* pzDefaultExtension
70 , const char* pzFilter
78 wxString sDefaultDirString
;
79 wxString sDefaultFilenameString
;
82 // If there's a default extension specified but no filter, we create
85 if (pzDefaultExtension
&& !pzFilter
)
86 sFilter
= wxString("*.") + wxString(pzDefaultExtension
);
91 sDefaultDirString
= pzDefaultDir
;
93 sDefaultDirString
= "";
95 if (pzDefaultFileName
)
96 sDefaultFilenameString
= pzDefaultFileName
;
98 sDefaultFilenameString
= "";
100 wxFileDialog
vFileDialog( pParent
103 ,sDefaultFilenameString
109 if (wxStrlen(pzDefaultExtension
) != 0)
112 int nFilterIndex
= 0;
114 for (unsigned int i
= 0; i
< sFilter
.Len(); i
++)
116 if (sFilter
.GetChar(i
) == wxT('|'))
119 // Save the start index of the new filter
120 unsigned int uIs
= i
++;
123 // Find the end of the filter
125 for(; i
< sFilter
.Len(); i
++)
127 if(sFilter
[i
] == wxT('|'))
131 if( i
- uIs
- 1 > 0 && uIs
+ 1 < sFilter
.Len() )
133 if(sFilter
.Mid(uIs
+ 1, i
- uIs
- 1).Contains(pzDefaultExtension
))
135 nFilterFind
= nFilterIndex
;
142 vFileDialog
.SetFilterIndex(nFilterFind
);
144 if (vFileDialog
.ShowModal() == wxID_OK
)
146 return vFileDialog
.GetPath();
149 return wxEmptyString
;
150 } // end of wxFileSelector
152 wxString
wxFileSelectorEx (
154 , const char* pzDefaultDir
155 , const char* pzDefaultFileName
156 , int* pnDefaultFilterIndex
157 , const char* pzFilter
164 wxFileDialog
vFileDialog( pParent
165 ,pzTitle ? pzTitle
: ""
166 ,pzDefaultDir ? pzDefaultDir
: ""
167 ,pzDefaultFileName ? pzDefaultFileName
: ""
168 ,pzFilter ? pzFilter
: ""
173 if (vFileDialog
.ShowModal() == wxID_OK
)
175 *pnDefaultFilterIndex
= vFileDialog
.GetFilterIndex();
176 return vFileDialog
.GetPath();
179 return wxEmptyString
;
180 } // end of wxFileSelectorEx
182 // ----------------------------------------------------------------------------
183 // CLASS wxFileDialog
184 // ----------------------------------------------------------------------------
186 wxFileDialog
::wxFileDialog (
188 , const wxString
& rsMessage
189 , const wxString
& rsDefaultDir
190 , const wxString
& rsDefaultFileName
191 , const wxString
& rsWildCard
193 , const wxPoint
& rPos
196 m_sMessage
= rsMessage
;
197 m_lDialogStyle
= lStyle
;
198 if ((m_lDialogStyle
& wxMULTIPLE
) && (m_lDialogStyle
& wxSAVE
))
199 m_lDialogStyle
&= ~wxMULTIPLE
;
202 m_sFileName
= rsDefaultFileName
;
203 m_sDir
= rsDefaultDir
;
204 m_sWildCard
= rsWildCard
;
207 } // end of wxFileDialog::wxFileDialog
209 void wxFileDialog
::GetPaths (
210 wxArrayString
& rasPaths
213 wxString
sDir(m_sDir
);
214 size_t nCount
= m_asFileNames
.GetCount();
217 if (m_sDir
.Last() != _T('\\'))
220 for ( size_t n
= 0; n
< nCount
; n
++ )
222 rasPaths
.Add(sDir
+ m_asFileNames
[n
]);
224 } // end of wxFileDialog::GetPaths
226 int wxFileDialog
::ShowModal()
229 wxString sFilterBuffer
;
230 static wxChar zFileNameBuffer
[wxMAXPATH
]; // the file-name
232 wxChar zTitleBuffer
[wxMAXFILE
+ 1 + wxMAXEXT
]; // the file-name, without path
235 size_t nLen
= m_sDir
.length();
239 memset(&vFileDlg
, '\0', sizeof(FILEDLG
));
241 hWnd
= (HWND
) m_pParent
->GetHWND();
242 if (!hWnd
&& wxTheApp
->GetTopWindow())
243 hWnd
= (HWND
) wxTheApp
->GetTopWindow()->GetHWND();
246 *zFileNameBuffer
= wxT('\0');
247 *zTitleBuffer
= wxT('\0');
249 m_lDialogStyle
& wxSAVE ? lFlags
!= FDS_SAVEAS_DIALOG
252 if ((m_lDialogStyle
& wxHIDE_READONLY
) || (m_lDialogStyle
& wxSAVE
))
253 lFlags
|= FDS_SAVEAS_DIALOG
;
254 if (m_lDialogStyle
& wxMULTIPLE
)
255 lFlags
|= FDS_OPEN_DIALOG
| FDS_MULTIPLESEL
;
257 vFileDlg
.cbSize
= sizeof(FILEDLG
);
258 vFileDlg
.fl
= lFlags
;
259 vFileDlg
.pszTitle
= zTitleBuffer
;
262 // Convert forward slashes to backslashes (file selector doesn't like
263 // forward slashes) and also squeeze multiple consecutive slashes into one
264 // as it doesn't like two backslashes in a row neither
267 for ( i
= 0; i
< nLen
; i
++ )
269 wxChar ch
= m_sDir
[i
];
275 // Convert to backslash
285 wxChar chNext
= m_sDir
[i
+ 1];
287 if (chNext
!= _T('\\') && chNext
!= _T('/'))
291 // Ignore the next one, unless it is at the start of a UNC path
309 if ( wxStrlen(m_sWildCard
) == 0 )
312 sTheFilter
= m_sWildCard
;
314 if (!wxStrchr(sTheFilter
, wxT('|') ) )
317 // Only one filter ==> default text
319 sFilterBuffer
.Printf( _("Files (%s)|%s")
325 { // more then one filter
326 sFilterBuffer
= sTheFilter
;
329 sFilterBuffer
+= wxT("|");
334 for (i
= 0; i
< sFilterBuffer
.Len(); i
++ )
336 if (sFilterBuffer
.GetChar(i
) == wxT('|'))
338 sFilterBuffer
[i
] = wxT('\0');
341 if (!sTheFilter
.IsEmpty())
345 wxStrcpy(vFileDlg
.szFullFile
, sDir
.c_str());
347 hWnd
= ::WinFileDlg( GetHwndOf(m_pParent
)
348 ,GetHwndOf(m_pParent
)
351 if (hWnd
&& vFileDlg
.lReturn
== DID_OK
)
353 m_asFileNames
.Empty();
354 if ((m_lDialogStyle
& wxMULTIPLE
) && vFileDlg
.ulFQFCount
> 1)
356 for (int i
= 0; i
< vFileDlg
.ulFQFCount
; i
++)
360 m_sDir
= wxPathOnly(wxString((const char*)vFileDlg
.papszFQFilename
[i
]));
361 m_sPath
= (const char*)vFileDlg
.papszFQFilename
[i
];
363 m_sFileName
= wxFileNameFromPath(wxString((const char*)vFileDlg
.papszFQFilename
[i
]));
364 m_asFileNames
.Add(m_sFileName
);
367 else if (!m_lDialogStyle
& wxSAVE
)
369 m_sPath
= vFileDlg
.szFullFile
;
370 m_sFileName
= wxFileNameFromPath(vFileDlg
.szFullFile
);
371 m_sDir
= wxPathOnly(vFileDlg
.szFullFile
);
375 const wxChar
* pzExtension
= NULL
;
377 wxStrcpy(zFileNameBuffer
, vFileDlg
.szFullFile
);
379 int nIdx
= wxStrlen(zFileNameBuffer
) - 1;
381 if (zFileNameBuffer
[nIdx
] == wxT('.') )
383 zFileNameBuffer
[nIdx
] = wxT('\0');
386 // User has typed a filename without an extension:
388 // A filename can end in a "." here ("abc."), this means it
389 // does not have an extension. Because later on a "." with
390 // the default extension is appended we remove the "." if
391 // filename ends with one (We don't want files called
394 pzExtension
= sFilterBuffer
.c_str();
396 for( int i
= 0; i
< sFilterBuffer
.length(); i
++ )
401 pzExtension
= wxStrrchr(pzExtension
, wxT('.'));
403 !wxStrrchr(pzExtension
, wxT('*')) &&
404 !wxStrrchr(pzExtension
, wxT('?')) &&
406 pzExtension
[1] != wxT(' ')
410 // Now concat extension to the fileName:
412 m_sPath
= wxString(zFileNameBuffer
) + pzExtension
;
418 m_sPath
= vFileDlg
.szFullFile
;
420 m_sFileName
= wxFileNameFromPath(vFileDlg
.szFullFile
);
421 m_sDir
= wxPathOnly(vFileDlg
.szFullFile
);
424 // === Simulating the wxOVERWRITE_PROMPT >>============================
426 if ((m_lDialogStyle
& wxOVERWRITE_PROMPT
) &&
427 (m_lDialogStyle
& wxSAVE
) &&
428 (wxFileExists(m_sPath
.c_str())))
430 wxString sMessageText
;
432 sMessageText
.Printf( _("File '%s' already exists.\nDo you want to replace it?")
435 if (wxMessageBox( sMessageText
437 ,wxYES_NO
| wxICON_EXCLAMATION
447 } // end of wxFileDialog::ShowModal
450 // Generic file load/save dialog
452 static wxString
wxDefaultFileSelector (
455 , const char* pzExtension
456 , const char* pzDefaultName
460 char* pzExt
= (char *)pzExtension
;
466 sStr
= "Load %s file";
468 sStr
= "Save %s file";
469 sprintf(zPrompt
, wxGetTranslation(sStr
), pzWhat
);
473 sprintf(zWild
, "*.%s", pzExt
);
474 return wxFileSelector ( zPrompt
482 } // end of wxDefaultFileSelector
485 // Generic file load dialog
487 wxString
wxLoadFileSelector (
489 , const char* pzExtension
490 , const char* pzDefaultName
494 return wxDefaultFileSelector( TRUE
500 } // end of wxLoadFileSelector
504 // Generic file save dialog
506 wxString
wxSaveFileSelector (
508 , const char* pzExtension
509 , const char* pzDefaultName
513 return wxDefaultFileSelector( FALSE
519 } // end of wxSaveFileSelector