]> git.saurik.com Git - wxWidgets.git/blame - src/os2/filedlg.cpp
Applied patch [ 686843 ] File Dialog Wildcard Bug
[wxWidgets.git] / src / os2 / filedlg.cpp
CommitLineData
0e320a79
DW
1/////////////////////////////////////////////////////////////////////////////
2// Name: filedlg.cpp
3// Purpose: wxFileDialog
f0a56ab0 4// Author: David Webster
0e320a79 5// Modified by:
f0a56ab0 6// Created: 10/05/99
0e320a79 7// RCS-ID: $Id$
f0a56ab0 8// Copyright: (c) David Webster
0e320a79
DW
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
fb46a9a6
DW
12// For compilers that support precompilation, includes "wx.h".
13#include "wx/wxprec.h"
14
15#ifdef __BORLANDC__
16 #pragma hdrstop
17#endif
18
19#ifndef WX_PRECOMP
fb46a9a6
DW
20 #include "wx/utils.h"
21 #include "wx/msgdlg.h"
22 #include "wx/dialog.h"
23 #include "wx/filedlg.h"
24 #include "wx/intl.h"
25 #include "wx/log.h"
4efd4259 26 #include "wx/app.h"
fb46a9a6
DW
27#endif
28
29#define INCL_PM
30#include <os2.h>
31
32#include "wx/os2/private.h"
33
34#include <math.h>
35#include <stdlib.h>
36#include <string.h>
0e320a79 37
4efd4259
DW
38#include "wx/tokenzr.h"
39
40#define wxMAXPATH 1024
41#define wxMAXFILE 1024
42#define wxMAXEXT 5
43
44#ifndef MAXPATH
45# define MAXPATH 400
46#endif
47
48#ifndef MAXDRIVE
49# define MAXDRIVE 3
50#endif
51
52#ifndef MAXFILE
53# define MAXFILE 9
54#endif
55
56#ifndef MAXEXT
57# define MAXEXT 5
58#endif
0e320a79 59IMPLEMENT_CLASS(wxFileDialog, wxDialog)
0e320a79 60
4efd4259
DW
61// ----------------------------------------------------------------------------
62// global functions
63// ----------------------------------------------------------------------------
64
65wxString wxFileSelector(
66 const char* pzTitle
67, const char* pzDefaultDir
68, const char* pzDefaultFileName
69, const char* pzDefaultExtension
70, const char* pzFilter
71, int nFlags
72, wxWindow* pParent
73, int nX
74, int nY
75)
0e320a79 76{
4efd4259
DW
77 wxString sFilter("");
78 wxString sDefaultDirString;
79 wxString sDefaultFilenameString;
80
81 //
82 // If there's a default extension specified but no filter, we create
83 // a suitable filter.
84 //
85 if (pzDefaultExtension && !pzFilter)
86 sFilter = wxString("*.") + wxString(pzDefaultExtension);
87 else if (pzFilter)
88 sFilter = pzFilter;
89
90 if (pzDefaultDir)
91 sDefaultDirString = pzDefaultDir;
0e320a79 92 else
4efd4259 93 sDefaultDirString = "";
0e320a79 94
4efd4259
DW
95 if (pzDefaultFileName)
96 sDefaultFilenameString = pzDefaultFileName;
0e320a79 97 else
4efd4259
DW
98 sDefaultFilenameString = "";
99
100 wxFileDialog vFileDialog( pParent
101 ,pzTitle
102 ,sDefaultDirString
103 ,sDefaultFilenameString
104 ,sFilter
105 ,nFlags
106 ,wxPoint(nX, nY)
107 );
108
109 if (wxStrlen(pzDefaultExtension) != 0)
110 {
111 int nFilterFind = 0;
112 int nFilterIndex = 0;
113
114 for (unsigned int i = 0; i < sFilter.Len(); i++)
115 {
116 if (sFilter.GetChar(i) == wxT('|'))
117 {
118 //
119 // Save the start index of the new filter
120 unsigned int uIs = i++;
0e320a79 121
4efd4259
DW
122 //
123 // Find the end of the filter
124 //
125 for(; i < sFilter.Len(); i++)
126 {
127 if(sFilter[i] == wxT('|'))
128 break;
129 }
0e320a79 130
4efd4259
DW
131 if( i - uIs - 1 > 0 && uIs + 1 < sFilter.Len() )
132 {
133 if(sFilter.Mid(uIs + 1, i - uIs - 1).Contains(pzDefaultExtension))
134 {
135 nFilterFind = nFilterIndex;
136 break;
137 }
138 }
139 nFilterIndex++;
140 }
141 }
142 vFileDialog.SetFilterIndex(nFilterFind);
143 }
144 if (vFileDialog.ShowModal() == wxID_OK)
0e320a79 145 {
4efd4259 146 return vFileDialog.GetPath();
0e320a79
DW
147 }
148 else
149 return wxEmptyString;
4efd4259
DW
150} // end of wxFileSelector
151
152wxString wxFileSelectorEx (
153 const char* pzTitle
154, const char* pzDefaultDir
155, const char* pzDefaultFileName
156, int* pnDefaultFilterIndex
157, const char* pzFilter
158, int nFlags
159, wxWindow* pParent
160, int nX
161, int nY
162)
0e320a79 163{
4efd4259
DW
164 wxFileDialog vFileDialog( pParent
165 ,pzTitle ? pzTitle : ""
166 ,pzDefaultDir ? pzDefaultDir : ""
167 ,pzDefaultFileName ? pzDefaultFileName : ""
168 ,pzFilter ? pzFilter : ""
169 ,nFlags
170 ,wxPoint(nX, nY)
171 );
0e320a79 172
4efd4259 173 if (vFileDialog.ShowModal() == wxID_OK)
0e320a79 174 {
4efd4259
DW
175 *pnDefaultFilterIndex = vFileDialog.GetFilterIndex();
176 return vFileDialog.GetPath();
0e320a79
DW
177 }
178 else
179 return wxEmptyString;
4efd4259
DW
180} // end of wxFileSelectorEx
181
182// ----------------------------------------------------------------------------
183// CLASS wxFileDialog
184// ----------------------------------------------------------------------------
185
186wxFileDialog::wxFileDialog (
187 wxWindow* pParent
188, const wxString& rsMessage
189, const wxString& rsDefaultDir
190, const wxString& rsDefaultFileName
191, const wxString& rsWildCard
192, long lStyle
193, const wxPoint& rPos
194)
0e320a79 195{
4efd4259
DW
196 m_sMessage = rsMessage;
197 m_lDialogStyle = lStyle;
198 if ((m_lDialogStyle & wxMULTIPLE) && (m_lDialogStyle & wxSAVE))
199 m_lDialogStyle &= ~wxMULTIPLE;
200 m_pParent = pParent;
201 m_sPath = "";
202 m_sFileName = rsDefaultFileName;
203 m_sDir = rsDefaultDir;
204 m_sWildCard = rsWildCard;
205 m_nFilterIndex = 1;
206 m_vPos = rPos;
207} // end of wxFileDialog::wxFileDialog
208
209void wxFileDialog::GetPaths (
210 wxArrayString& rasPaths
211) const
212{
213 wxString sDir(m_sDir);
214 size_t nCount = m_asFileNames.GetCount();
215
216 rasPaths.Empty();
217 if (m_sDir.Last() != _T('\\'))
218 sDir += _T('\\');
219
220 for ( size_t n = 0; n < nCount; n++ )
221 {
222 rasPaths.Add(sDir + m_asFileNames[n]);
223 }
224} // end of wxFileDialog::GetPaths
0e320a79
DW
225
226int wxFileDialog::ShowModal()
227{
4efd4259
DW
228 wxString sTheFilter;
229 wxString sFilterBuffer;
b93f4bb9 230 wxChar* pzFilterBuffer;
4efd4259
DW
231 static wxChar zFileNameBuffer[wxMAXPATH]; // the file-name
232 HWND hWnd = 0;
233 wxChar zTitleBuffer[wxMAXFILE + 1 + wxMAXEXT]; // the file-name, without path
b93f4bb9
DW
234 wxString sDir;
235 size_t i;
4efd4259 236 size_t nLen = m_sDir.length();
b93f4bb9 237 int nCount = 0;
4efd4259
DW
238 FILEDLG vFileDlg;
239 ULONG lFlags = 0L;
240
241 memset(&vFileDlg, '\0', sizeof(FILEDLG));
242 if (m_pParent)
243 hWnd = (HWND) m_pParent->GetHWND();
244 if (!hWnd && wxTheApp->GetTopWindow())
245 hWnd = (HWND) wxTheApp->GetTopWindow()->GetHWND();
246
247
248 *zFileNameBuffer = wxT('\0');
249 *zTitleBuffer = wxT('\0');
250
b93f4bb9
DW
251 if (m_lDialogStyle & wxSAVE)
252 lFlags = FDS_SAVEAS_DIALOG;
253 else
254 lFlags = FDS_OPEN_DIALOG;
255
4efd4259
DW
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;
260
261 vFileDlg.cbSize = sizeof(FILEDLG);
262 vFileDlg.fl = lFlags;
263 vFileDlg.pszTitle = zTitleBuffer;
264
265 //
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
269 //
270 sDir.reserve(nLen);
271 for ( i = 0; i < nLen; i++ )
272 {
273 wxChar ch = m_sDir[i];
274
275 switch (ch)
276 {
277 case _T('/'):
278 //
279 // Convert to backslash
280 //
281 ch = _T('\\');
282
283 //
284 // Fall through
285 //
286 case _T('\\'):
287 while (i < nLen - 1)
288 {
289 wxChar chNext = m_sDir[i + 1];
290
291 if (chNext != _T('\\') && chNext != _T('/'))
292 break;
293
294 //
295 // Ignore the next one, unless it is at the start of a UNC path
296 //
297 if (i > 0)
298 i++;
299 else
300 break;
301 }
302
303 //
304 // Fall through
305 //
306
307 default:
308 //
309 // Normal char
310 sDir += ch;
311 }
312 }
313 if ( wxStrlen(m_sWildCard) == 0 )
314 sTheFilter = "";
315 else
b93f4bb9 316 sTheFilter = m_sWildCard;
4efd4259 317
b93f4bb9
DW
318 pzFilterBuffer = strtok((char*)sTheFilter.c_str(), "|");
319 while(pzFilterBuffer != NULL)
4efd4259 320 {
b93f4bb9
DW
321 if (nCount > 0 && !(nCount % 2))
322 sDir += wxT(";");
323 if (nCount % 2)
4efd4259 324 {
b93f4bb9 325 sDir += pzFilterBuffer;
4efd4259 326 }
b93f4bb9
DW
327 pzFilterBuffer = strtok(NULL, "|");
328 nCount++;
4efd4259 329 }
b93f4bb9 330 if (nCount == 0)
4efd4259 331 sDir += m_sFileName;
b93f4bb9
DW
332 if (sDir.IsEmpty())
333 sDir = "*.*";
4efd4259 334 wxStrcpy(vFileDlg.szFullFile, sDir.c_str());
25fc812c 335 sFilterBuffer = sDir;
4efd4259 336
b93f4bb9 337 hWnd = ::WinFileDlg( HWND_DESKTOP
4efd4259
DW
338 ,GetHwndOf(m_pParent)
339 ,&vFileDlg
340 );
341 if (hWnd && vFileDlg.lReturn == DID_OK)
342 {
343 m_asFileNames.Empty();
344 if ((m_lDialogStyle & wxMULTIPLE ) && vFileDlg.ulFQFCount > 1)
345 {
346 for (int i = 0; i < vFileDlg.ulFQFCount; i++)
347 {
348 if (i == 0)
349 {
b93f4bb9
DW
350 m_sDir = wxPathOnly(wxString((const char*)*vFileDlg.papszFQFilename[0]));
351 m_sPath = (const char*)*vFileDlg.papszFQFilename[0];
4efd4259 352 }
b93f4bb9 353 m_sFileName = wxFileNameFromPath(wxString((const char*)*vFileDlg.papszFQFilename[i]));
4efd4259
DW
354 m_asFileNames.Add(m_sFileName);
355 }
b93f4bb9 356 ::WinFreeFileDlgList(vFileDlg.papszFQFilename);
4efd4259 357 }
b93f4bb9 358 else if (!(m_lDialogStyle & wxSAVE))
4efd4259
DW
359 {
360 m_sPath = vFileDlg.szFullFile;
361 m_sFileName = wxFileNameFromPath(vFileDlg.szFullFile);
362 m_sDir = wxPathOnly(vFileDlg.szFullFile);
363 }
364 else // save file
365 {
366 const wxChar* pzExtension = NULL;
367
368 wxStrcpy(zFileNameBuffer, vFileDlg.szFullFile);
369
370 int nIdx = wxStrlen(zFileNameBuffer) - 1;
25fc812c 371 wxString sExt;
4efd4259 372
25fc812c
DW
373 wxSplitPath( zFileNameBuffer
374 ,&m_sPath
375 ,&m_sFileName
376 ,&sExt
377 );
378 if (zFileNameBuffer[nIdx] == wxT('.') || sExt.IsEmpty())
4efd4259
DW
379 {
380 zFileNameBuffer[nIdx] = wxT('\0');
381
382 //
383 // User has typed a filename without an extension:
384 //
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
389 // "abc..ext")
390 //
391 pzExtension = sFilterBuffer.c_str();
392
393 for( int i = 0; i < sFilterBuffer.length(); i++ )
394 {
395 //
396 // Get extension
397 //
398 pzExtension = wxStrrchr(pzExtension, wxT('.'));
399 if ( pzExtension &&
400 !wxStrrchr(pzExtension, wxT('*')) &&
401 !wxStrrchr(pzExtension, wxT('?')) &&
402 pzExtension[1] &&
403 pzExtension[1] != wxT(' ')
404 ) // != "blabla. "
405 {
406 //
407 // Now concat extension to the fileName:
408 //
409 m_sPath = wxString(zFileNameBuffer) + pzExtension;
410 }
411 }
412 }
413 else
414 {
415 m_sPath = vFileDlg.szFullFile;
416 }
417 m_sFileName = wxFileNameFromPath(vFileDlg.szFullFile);
418 m_sDir = wxPathOnly(vFileDlg.szFullFile);
419
420 //
421 // === Simulating the wxOVERWRITE_PROMPT >>============================
422 //
423 if ((m_lDialogStyle & wxOVERWRITE_PROMPT) &&
424 (m_lDialogStyle & wxSAVE) &&
425 (wxFileExists(m_sPath.c_str())))
426 {
427 wxString sMessageText;
428
429 sMessageText.Printf( _("File '%s' already exists.\nDo you want to replace it?")
430 ,m_sPath.c_str()
431 );
432 if (wxMessageBox( sMessageText
433 ,wxT("Save File As")
434 ,wxYES_NO | wxICON_EXCLAMATION
435 ) != wxYES)
436 {
437 return wxID_CANCEL;
438 }
439 }
440 }
441 return wxID_OK;
442 }
0e320a79 443 return wxID_CANCEL;
4efd4259 444} // end of wxFileDialog::ShowModal
0e320a79 445
4efd4259 446//
0e320a79 447// Generic file load/save dialog
4efd4259
DW
448//
449static wxString wxDefaultFileSelector (
450 bool bLoad
451, const char* pzWhat
452, const char* pzExtension
453, const char* pzDefaultName
454, wxWindow* pParent
455)
0e320a79 456{
4efd4259
DW
457 char* pzExt = (char *)pzExtension;
458 char zPrompt[50];
459 wxString sStr;
460 char zWild[60];
0e320a79 461
4efd4259
DW
462 if (bLoad)
463 sStr = "Load %s file";
464 else
465 sStr = "Save %s file";
466 sprintf(zPrompt, wxGetTranslation(sStr), pzWhat);
0e320a79 467
4efd4259
DW
468 if (*pzExt == '.')
469 pzExt++;
470 sprintf(zWild, "*.%s", pzExt);
471 return wxFileSelector ( zPrompt
472 ,NULL
473 ,pzDefaultName
474 ,pzExt
475 ,zWild
476 ,0
477 ,pParent
478 );
479} // end of wxDefaultFileSelector
0e320a79 480
4efd4259 481//
0e320a79 482// Generic file load dialog
4efd4259
DW
483//
484wxString wxLoadFileSelector (
485 const char* pzWhat
486, const char* pzExtension
487, const char* pzDefaultName
488, wxWindow* pParent
489)
0e320a79 490{
4efd4259
DW
491 return wxDefaultFileSelector( TRUE
492 ,pzWhat
493 ,pzExtension
494 ,pzDefaultName
495 ,pParent
496 );
497} // end of wxLoadFileSelector
0e320a79
DW
498
499
4efd4259 500//
0e320a79 501// Generic file save dialog
4efd4259
DW
502//
503wxString wxSaveFileSelector (
504 const char* pzWhat
505, const char* pzExtension
506, const char* pzDefaultName
507, wxWindow* pParent
508)
0e320a79 509{
4efd4259
DW
510 return wxDefaultFileSelector( FALSE
511 ,pzWhat
512 ,pzExtension
513 ,pzDefaultName
514 ,pParent
515 );
516} // end of wxSaveFileSelector
0e320a79 517