]> git.saurik.com Git - wxWidgets.git/blob - src/motif/filedlg.cpp
Applied patch for multiple file selection, documented.
[wxWidgets.git] / src / motif / filedlg.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: filedlg.cpp
3 // Purpose: wxFileDialog
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 17/09/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation "filedlg.h"
14 #endif
15
16 #include "wx/defs.h"
17 #include "wx/utils.h"
18 #include "wx/dialog.h"
19 #include "wx/filedlg.h"
20 #include "wx/intl.h"
21 #include "wx/app.h"
22 #include "wx/settings.h"
23
24 #ifdef __VMS__
25 #pragma message disable nosimpint
26 #endif
27 #include <Xm/Xm.h>
28 #include <Xm/MwmUtil.h>
29 #include <Xm/Label.h>
30 #include <Xm/BulletinB.h>
31 #include <Xm/Frame.h>
32 #include <Xm/Text.h>
33 #include <Xm/DialogS.h>
34 #include <Xm/FileSB.h>
35 #include <Xm/RowColumn.h>
36 #include <Xm/LabelG.h>
37 #ifdef __VMS__
38 #pragma message enable nosimpint
39 #endif
40
41 #include "wx/motif/private.h"
42
43 #if !USE_SHARED_LIBRARY
44 IMPLEMENT_CLASS(wxFileDialog, wxDialog)
45 #endif
46
47 #define DEFAULT_FILE_SELECTOR_SIZE 0
48 // Let Motif defines the size of File
49 // Selector Box (if 1), or fix it to
50 // wxFSB_WIDTH x wxFSB_HEIGHT (if 0)
51 #define wxFSB_WIDTH 600
52 #define wxFSB_HEIGHT 500
53
54
55 wxString wxFileSelector(const char *title,
56 const char *defaultDir, const char *defaultFileName,
57 const char *defaultExtension, const char *filter, int flags,
58 wxWindow *parent, int x, int y)
59 {
60 // If there's a default extension specified but no filter, we create a suitable
61 // filter.
62
63 wxString filter2("");
64 if ( defaultExtension && !filter )
65 filter2 = wxString("*.") + wxString(defaultExtension) ;
66 else if ( filter )
67 filter2 = filter;
68
69 wxString defaultDirString;
70 if (defaultDir)
71 defaultDirString = defaultDir;
72 else
73 defaultDirString = "";
74
75 wxString defaultFilenameString;
76 if (defaultFileName)
77 defaultFilenameString = defaultFileName;
78 else
79 defaultFilenameString = "";
80
81 wxFileDialog fileDialog(parent, title, defaultDirString, defaultFilenameString, filter2, flags, wxPoint(x, y));
82
83 if ( fileDialog.ShowModal() == wxID_OK )
84 {
85 return fileDialog.GetPath();
86 }
87 else
88 return wxEmptyString;
89 }
90
91 wxString wxFileSelectorEx(const char *title,
92 const char *defaultDir,
93 const char *defaultFileName,
94 int* defaultFilterIndex,
95 const char *filter,
96 int flags,
97 wxWindow* parent,
98 int x,
99 int y)
100
101 {
102 wxFileDialog fileDialog(parent, title ? title : "", defaultDir ? defaultDir : "",
103 defaultFileName ? defaultFileName : "", filter ? filter : "", flags, wxPoint(x, y));
104
105 if ( fileDialog.ShowModal() == wxID_OK )
106 {
107 *defaultFilterIndex = fileDialog.GetFilterIndex();
108 return fileDialog.GetPath();
109 }
110 else
111 return wxEmptyString;
112 }
113
114 wxString wxFileDialog::m_fileSelectorAnswer = "";
115 bool wxFileDialog::m_fileSelectorReturned = FALSE;
116
117 void wxFileSelCancel( Widget WXUNUSED(fs), XtPointer WXUNUSED(client_data),
118 XmFileSelectionBoxCallbackStruct *WXUNUSED(cbs) )
119 {
120 wxFileDialog::m_fileSelectorAnswer = "";
121 wxFileDialog::m_fileSelectorReturned = TRUE;
122 }
123
124 void wxFileSelOk(Widget WXUNUSED(fs), XtPointer WXUNUSED(client_data), XmFileSelectionBoxCallbackStruct *cbs)
125 {
126 char *filename = NULL;
127 if (!XmStringGetLtoR(cbs->value, XmSTRING_DEFAULT_CHARSET, &filename)) {
128 wxFileDialog::m_fileSelectorAnswer = "";
129 wxFileDialog::m_fileSelectorReturned = TRUE;
130 } else {
131 if (filename) {
132 wxFileDialog::m_fileSelectorAnswer = filename;
133 XtFree(filename);
134 }
135 wxFileDialog::m_fileSelectorReturned = TRUE;
136 }
137 }
138
139 wxFileDialog::wxFileDialog(wxWindow *parent, const wxString& message,
140 const wxString& defaultDir, const wxString& defaultFileName, const wxString& wildCard,
141 long style, const wxPoint& pos)
142 {
143 m_message = message;
144 m_dialogStyle = style;
145 m_parent = parent;
146 m_path = "";
147 m_fileName = defaultFileName;
148 m_dir = defaultDir;
149 m_wildCard = wildCard;
150 m_filterIndex = 1;
151 m_pos = pos;
152 }
153
154 static void wxChangeListBoxColours(wxWindow* WXUNUSED(win), Widget widget)
155 {
156 wxWindow::DoChangeBackgroundColour((WXWidget) widget, *wxWHITE);
157
158 // Change colour of the scrolled areas of the listboxes
159 Widget listParent = XtParent (widget);
160 wxWindow::DoChangeBackgroundColour((WXWidget) listParent, *wxWHITE, TRUE);
161
162 Widget hsb = (Widget) 0;
163 Widget vsb = (Widget) 0;
164 XtVaGetValues (listParent,
165 XmNhorizontalScrollBar, &hsb,
166 XmNverticalScrollBar, &vsb,
167 NULL);
168
169 /* TODO: should scrollbars be affected? Should probably have separate
170 * function to change them (by default, taken from wxSystemSettings)
171 */
172 wxColour backgroundColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE);
173 wxWindow::DoChangeBackgroundColour((WXWidget) hsb, backgroundColour, TRUE);
174 wxWindow::DoChangeBackgroundColour((WXWidget) vsb, backgroundColour, TRUE);
175
176 if (hsb)
177 XtVaSetValues (hsb,
178 XmNtroughColor, backgroundColour.AllocColour(XtDisplay(hsb)),
179 NULL);
180 if (vsb)
181 XtVaSetValues (vsb,
182 XmNtroughColor, backgroundColour.AllocColour(XtDisplay(vsb)),
183 NULL);
184 }
185
186 int wxFileDialog::ShowModal()
187 {
188 wxBeginBusyCursor();
189
190 // static char fileBuf[512];
191 Widget parentWidget = (Widget) 0;
192 if (m_parent)
193 {
194 parentWidget = (Widget) m_parent->GetTopWidget();
195 }
196 else
197 parentWidget = (Widget) wxTheApp->GetTopLevelWidget();
198 // prepare the arg list
199 Arg args[10];
200 int ac = 0;
201
202 wxComputeColours (XtDisplay(parentWidget), & m_backgroundColour,
203 (wxColour*) NULL);
204
205 XtSetArg(args[ac], XmNbackground, g_itemColors[wxBACK_INDEX].pixel); ac++;
206 XtSetArg(args[ac], XmNtopShadowColor, g_itemColors[wxTOPS_INDEX].pixel); ac++;
207 XtSetArg(args[ac], XmNbottomShadowColor, g_itemColors[wxBOTS_INDEX].pixel); ac++;
208 XtSetArg(args[ac], XmNforeground, g_itemColors[wxFORE_INDEX].pixel); ac++;
209
210
211 Widget fileSel = XmCreateFileSelectionDialog(parentWidget, "file_selector", args, ac);
212 XtUnmanageChild(XmFileSelectionBoxGetChild(fileSel, XmDIALOG_HELP_BUTTON));
213
214 Widget filterWidget = XmFileSelectionBoxGetChild(fileSel, XmDIALOG_FILTER_TEXT);
215 Widget selectionWidget = XmFileSelectionBoxGetChild(fileSel, XmDIALOG_TEXT);
216 Widget dirListWidget = XmFileSelectionBoxGetChild(fileSel, XmDIALOG_DIR_LIST);
217 Widget fileListWidget = XmFileSelectionBoxGetChild(fileSel, XmDIALOG_LIST);
218
219 // code using these vars disabled
220 #if 0
221 Widget okWidget = XmFileSelectionBoxGetChild(fileSel, XmDIALOG_OK_BUTTON);
222 Widget applyWidget = XmFileSelectionBoxGetChild(fileSel, XmDIALOG_APPLY_BUTTON);
223 Widget cancelWidget = XmFileSelectionBoxGetChild(fileSel, XmDIALOG_CANCEL_BUTTON);
224 #endif
225
226
227 Widget shell = XtParent(fileSel);
228
229 if (!m_message.IsNull())
230 XtVaSetValues(shell, XmNtitle, (char*) (const char*) m_message, NULL);
231
232 wxString entirePath("");
233
234 if ((m_dir != "") && (m_fileName != ""))
235 {
236 entirePath = m_dir + wxString("/") + m_fileName;
237 }
238 else if ((m_dir != "") && (m_fileName == ""))
239 {
240 entirePath = m_dir + wxString("/");
241 }
242 else if ((m_dir == "") && (m_fileName != ""))
243 {
244 entirePath = m_fileName;
245 }
246
247 if (entirePath != "")
248 {
249 XmTextSetString(selectionWidget, (char*) (const char*) entirePath);
250 }
251
252 if (m_wildCard != "")
253 {
254 wxString filter("");
255 if (m_dir != "")
256 filter = m_dir + wxString("/") + m_wildCard;
257 else
258 filter = m_wildCard;
259
260 XmTextSetString(filterWidget, (char*) (const char*) filter);
261 XmFileSelectionDoSearch(fileSel, NULL);
262 }
263
264 // Suggested by Terry Gitnick, 16/9/97, because of change in Motif
265 // file selector on Solaris 1.5.1.
266 if ( m_dir != "" )
267 {
268 XmString thePath = XmStringCreateLtoR ((char*) (const char*) m_dir,
269 XmSTRING_DEFAULT_CHARSET);
270
271 XtVaSetValues (fileSel,
272 XmNdirectory, thePath,
273 NULL);
274
275 XmStringFree(thePath);
276 }
277
278 XtAddCallback(fileSel, XmNcancelCallback, (XtCallbackProc)wxFileSelCancel, (XtPointer)NULL);
279 XtAddCallback(fileSel, XmNokCallback, (XtCallbackProc)wxFileSelOk, (XtPointer)NULL);
280
281 //#if XmVersion > 1000
282 // I'm not sure about what you mean with XmVersion.
283 // If this is for Motif1.1/Motif1.2, then check XmVersion>=1200
284 // (Motif1.1.4 ==> XmVersion 1100 )
285 // Nevertheless, I put here a #define, so anyone can choose in (I)makefile...
286 //
287 #if !DEFAULT_FILE_SELECTOR_SIZE
288 int width = wxFSB_WIDTH;
289 int height = wxFSB_HEIGHT;
290 XtVaSetValues(fileSel,
291 XmNwidth, width,
292 XmNheight, height,
293 XmNresizePolicy, XmRESIZE_NONE,
294 NULL);
295 #endif
296 // DoChangeBackgroundColour((WXWidget) fileSel, m_backgroundColour);
297 DoChangeBackgroundColour((WXWidget) filterWidget, *wxWHITE);
298 DoChangeBackgroundColour((WXWidget) selectionWidget, *wxWHITE);
299
300 wxChangeListBoxColours(this, dirListWidget);
301 wxChangeListBoxColours(this, fileListWidget);
302
303 XtManageChild(fileSel);
304
305 m_fileSelectorAnswer = "";
306 m_fileSelectorReturned = FALSE;
307
308 wxEndBusyCursor();
309
310 XtAddGrab(XtParent(fileSel), TRUE, FALSE);
311 XEvent event;
312 while (!m_fileSelectorReturned)
313 {
314 XtAppProcessEvent((XtAppContext) wxTheApp->GetAppContext(), XtIMAll);
315 }
316 XtRemoveGrab(XtParent(fileSel));
317
318 XmUpdateDisplay((Widget) wxTheApp->GetTopLevelWidget()); // Experimental
319
320 // XtDestroyWidget(fileSel);
321 XtUnmapWidget(XtParent(fileSel));
322 XtDestroyWidget(XtParent(fileSel));
323
324 // Now process all events, because otherwise
325 // this might remain on the screen
326 XSync(XtDisplay((Widget) wxTheApp->GetTopLevelWidget()), FALSE);
327 while (XtAppPending((XtAppContext) wxTheApp->GetAppContext()))
328 {
329 XFlush(XtDisplay((Widget) wxTheApp->GetTopLevelWidget()));
330 XtAppNextEvent((XtAppContext) wxTheApp->GetAppContext(), &event);
331 XtDispatchEvent(&event);
332 }
333
334 m_path = m_fileSelectorAnswer;
335 m_fileName = wxFileNameFromPath(m_fileSelectorAnswer);
336 m_dir = wxPathOnly(m_path);
337
338 if (m_fileName == "")
339 return wxID_CANCEL;
340 else
341 return wxID_OK;
342 }
343
344 // Generic file load/save dialog
345 static wxString
346 wxDefaultFileSelector(bool load, const char *what, const char *extension, const char *default_name, wxWindow *parent)
347 {
348 char *ext = (char *)extension;
349
350 wxString prompt;
351 wxString str;
352 if (load)
353 str = _("Load %s file");
354 else
355 str = _("Save %s file");
356 prompt.Printf(str, what);
357
358 if (*ext == '.')
359 ext++;
360 wxString wild;
361 wild.Printf("*.%s", ext);
362
363 return wxFileSelector (prompt, NULL, default_name, ext, wild, 0, parent);
364 }
365
366 // Generic file load dialog
367 wxString wxLoadFileSelector(const char *what, const char *extension, const char *default_name, wxWindow *parent)
368 {
369 return wxDefaultFileSelector(TRUE, what, extension, default_name, parent);
370 }
371
372
373 // Generic file save dialog
374 wxString wxSaveFileSelector(const char *what, const char *extension, const char *default_name, wxWindow *parent)
375 {
376 return wxDefaultFileSelector(FALSE, what, extension, default_name, parent);
377 }
378
379