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 wxChar
* pzFilterBuffer
;
231 static wxChar zFileNameBuffer
[wxMAXPATH
]; // the file-name
233 wxChar zTitleBuffer
[wxMAXFILE
+ 1 + wxMAXEXT
]; // the file-name, without path
236 size_t nLen
= m_sDir
.length();
241 memset(&vFileDlg
, '\0', sizeof(FILEDLG
));
243 hWnd
= (HWND
) m_pParent
->GetHWND();
244 if (!hWnd
&& wxTheApp
->GetTopWindow())
245 hWnd
= (HWND
) wxTheApp
->GetTopWindow()->GetHWND();
248 *zFileNameBuffer
= wxT('\0');
249 *zTitleBuffer
= wxT('\0');
251 if (m_lDialogStyle
& wxSAVE
)
252 lFlags
= FDS_SAVEAS_DIALOG
;
254 lFlags
= FDS_OPEN_DIALOG
;
256 if ((m_lDialogStyle
& wxHIDE_READONLY
) || (m_lDialogStyle
& wxSAVE
))
257 lFlags
|= FDS_SAVEAS_DIALOG
;
258 if (m_lDialogStyle
& wxMULTIPLE
)
259 lFlags
|= FDS_OPEN_DIALOG
| FDS_MULTIPLESEL
;
261 vFileDlg
.cbSize
= sizeof(FILEDLG
);
262 vFileDlg
.fl
= lFlags
;
263 vFileDlg
.pszTitle
= zTitleBuffer
;
266 // Convert forward slashes to backslashes (file selector doesn't like
267 // forward slashes) and also squeeze multiple consecutive slashes into one
268 // as it doesn't like two backslashes in a row neither
271 for ( i
= 0; i
< nLen
; i
++ )
273 wxChar ch
= m_sDir
[i
];
279 // Convert to backslash
289 wxChar chNext
= m_sDir
[i
+ 1];
291 if (chNext
!= _T('\\') && chNext
!= _T('/'))
295 // Ignore the next one, unless it is at the start of a UNC path
313 if ( wxStrlen(m_sWildCard
) == 0 )
316 sTheFilter
= m_sWildCard
;
318 pzFilterBuffer
= strtok((char*)sTheFilter
.c_str(), "|");
319 while(pzFilterBuffer
!= NULL
)
321 if (nCount
> 0 && !(nCount
% 2))
325 sDir
+= pzFilterBuffer
;
327 pzFilterBuffer
= strtok(NULL
, "|");
334 wxStrcpy(vFileDlg
.szFullFile
, sDir
.c_str());
335 sFilterBuffer
= sDir
;
337 hWnd
= ::WinFileDlg( HWND_DESKTOP
338 ,GetHwndOf(m_pParent
)
341 if (hWnd
&& vFileDlg
.lReturn
== DID_OK
)
343 m_asFileNames
.Empty();
344 if ((m_lDialogStyle
& wxMULTIPLE
) && vFileDlg
.ulFQFCount
> 1)
346 for (int i
= 0; i
< vFileDlg
.ulFQFCount
; i
++)
350 m_sDir
= wxPathOnly(wxString((const char*)*vFileDlg
.papszFQFilename
[0]));
351 m_sPath
= (const char*)*vFileDlg
.papszFQFilename
[0];
353 m_sFileName
= wxFileNameFromPath(wxString((const char*)*vFileDlg
.papszFQFilename
[i
]));
354 m_asFileNames
.Add(m_sFileName
);
356 ::WinFreeFileDlgList(vFileDlg
.papszFQFilename
);
358 else if (!(m_lDialogStyle
& wxSAVE
))
360 m_sPath
= vFileDlg
.szFullFile
;
361 m_sFileName
= wxFileNameFromPath(vFileDlg
.szFullFile
);
362 m_sDir
= wxPathOnly(vFileDlg
.szFullFile
);
366 const wxChar
* pzExtension
= NULL
;
368 wxStrcpy(zFileNameBuffer
, vFileDlg
.szFullFile
);
370 int nIdx
= wxStrlen(zFileNameBuffer
) - 1;
373 wxSplitPath( zFileNameBuffer
378 if (zFileNameBuffer
[nIdx
] == wxT('.') || sExt
.IsEmpty())
380 zFileNameBuffer
[nIdx
] = wxT('\0');
383 // User has typed a filename without an extension:
385 // A filename can end in a "." here ("abc."), this means it
386 // does not have an extension. Because later on a "." with
387 // the default extension is appended we remove the "." if
388 // filename ends with one (We don't want files called
391 pzExtension
= sFilterBuffer
.c_str();
393 for( int i
= 0; i
< sFilterBuffer
.length(); i
++ )
398 pzExtension
= wxStrrchr(pzExtension
, wxT('.'));
400 !wxStrrchr(pzExtension
, wxT('*')) &&
401 !wxStrrchr(pzExtension
, wxT('?')) &&
403 pzExtension
[1] != wxT(' ')
407 // Now concat extension to the fileName:
409 m_sPath
= wxString(zFileNameBuffer
) + pzExtension
;
415 m_sPath
= vFileDlg
.szFullFile
;
417 m_sFileName
= wxFileNameFromPath(vFileDlg
.szFullFile
);
418 m_sDir
= wxPathOnly(vFileDlg
.szFullFile
);
421 // === Simulating the wxOVERWRITE_PROMPT >>============================
423 if ((m_lDialogStyle
& wxOVERWRITE_PROMPT
) &&
424 (m_lDialogStyle
& wxSAVE
) &&
425 (wxFileExists(m_sPath
.c_str())))
427 wxString sMessageText
;
429 sMessageText
.Printf( _("File '%s' already exists.\nDo you want to replace it?")
432 if (wxMessageBox( sMessageText
434 ,wxYES_NO
| wxICON_EXCLAMATION
444 } // end of wxFileDialog::ShowModal
447 // Generic file load/save dialog
449 static wxString
wxDefaultFileSelector (
452 , const char* pzExtension
453 , const char* pzDefaultName
457 char* pzExt
= (char *)pzExtension
;
463 sStr
= "Load %s file";
465 sStr
= "Save %s file";
466 sprintf(zPrompt
, wxGetTranslation(sStr
), pzWhat
);
470 sprintf(zWild
, "*.%s", pzExt
);
471 return wxFileSelector ( zPrompt
479 } // end of wxDefaultFileSelector
482 // Generic file load dialog
484 wxString
wxLoadFileSelector (
486 , const char* pzExtension
487 , const char* pzDefaultName
491 return wxDefaultFileSelector( TRUE
497 } // end of wxLoadFileSelector
501 // Generic file save dialog
503 wxString
wxSaveFileSelector (
505 , const char* pzExtension
506 , const char* pzDefaultName
510 return wxDefaultFileSelector( FALSE
516 } // end of wxSaveFileSelector