1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/motif/filedlg.cpp
3 // Purpose: wxFileDialog
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
15 #include "wx/filedlg.h"
21 #include "wx/settings.h"
24 #include "wx/tokenzr.h"
25 #include "wx/stockitem.h"
26 #include "wx/testing.h"
29 #pragma message disable nosimpint
32 #include <Xm/MwmUtil.h>
34 #include <Xm/BulletinB.h>
37 #include <Xm/DialogS.h>
38 #include <Xm/FileSB.h>
39 #include <Xm/RowColumn.h>
40 #include <Xm/LabelG.h>
42 #pragma message enable nosimpint
45 #include "wx/motif/private.h"
47 IMPLEMENT_CLASS(wxFileDialog
, wxFileDialogBase
)
49 #define DEFAULT_FILE_SELECTOR_SIZE 0
50 // Let Motif defines the size of File
51 // Selector Box (if 1), or fix it to
52 // wxFSB_WIDTH x wxFSB_HEIGHT (if 0)
53 #define wxFSB_WIDTH 600
54 #define wxFSB_HEIGHT 500
57 wxString
wxFileDialog::m_fileSelectorAnswer
= wxEmptyString
;
58 bool wxFileDialog::m_fileSelectorReturned
= false;
60 static void wxFileSelClose(Widget
WXUNUSED(w
),
61 void* WXUNUSED(client_data
),
62 XmAnyCallbackStruct
*WXUNUSED(call_data
))
64 wxFileDialog::m_fileSelectorAnswer
= wxEmptyString
;
65 wxFileDialog::m_fileSelectorReturned
= true;
68 void wxFileSelCancel( Widget
WXUNUSED(fs
), XtPointer
WXUNUSED(client_data
),
69 XmFileSelectionBoxCallbackStruct
*WXUNUSED(cbs
) )
71 wxFileDialog::m_fileSelectorAnswer
= wxEmptyString
;
72 wxFileDialog::m_fileSelectorReturned
= true;
75 void wxFileSelOk(Widget
WXUNUSED(fs
), XtPointer
WXUNUSED(client_data
), XmFileSelectionBoxCallbackStruct
*cbs
)
77 char *filename
= NULL
;
78 if (!XmStringGetLtoR(cbs
->value
, XmSTRING_DEFAULT_CHARSET
, &filename
)) {
79 wxFileDialog::m_fileSelectorAnswer
= wxEmptyString
;
80 wxFileDialog::m_fileSelectorReturned
= true;
83 wxFileDialog::m_fileSelectorAnswer
= filename
;
86 wxFileDialog::m_fileSelectorReturned
= true;
90 static wxString
ParseWildCard( const wxString
& wild
)
93 static const char *msg
=
94 "Motif file dialog does not understand this wildcard syntax";
97 wxArrayString wildDescriptions
, wildFilters
;
98 const size_t count
= wxParseCommonDialogsFilter(wild
,
101 wxCHECK_MSG( count
, wxT("*.*"), wxT("wxFileDialog: bad wildcard string") );
102 wxCHECK_MSG( count
== 1, wxT("*.*"), msg
);
104 // check for *.txt;*.rtf
105 wxStringTokenizer
tok2( wildFilters
[0], wxT(";") );
106 wxString wildcard
= tok2
.GetNextToken();
108 wxCHECK_MSG( tok2
.CountTokens() <= 1, wildcard
, msg
);
112 wxFileDialog::wxFileDialog(wxWindow
*parent
, const wxString
& message
,
113 const wxString
& defaultDir
, const wxString
& defaultFileName
, const wxString
& wildCard
,
114 long style
, const wxPoint
& pos
, const wxSize
& sz
, const wxString
& name
)
115 :wxFileDialogBase(parent
, message
, defaultDir
, defaultFileName
, wildCard
, style
, pos
, sz
, name
)
119 static void wxChangeListBoxColours(wxWindow
* WXUNUSED(win
), Widget widget
)
121 wxDoChangeBackgroundColour((WXWidget
) widget
, *wxWHITE
);
123 // Change colour of the scrolled areas of the listboxes
124 Widget listParent
= XtParent (widget
);
126 wxDoChangeBackgroundColour((WXWidget
) listParent
, *wxWHITE
, true);
129 Widget hsb
= (Widget
) 0;
130 Widget vsb
= (Widget
) 0;
131 XtVaGetValues (listParent
,
132 XmNhorizontalScrollBar
, &hsb
,
133 XmNverticalScrollBar
, &vsb
,
136 /* TODO: should scrollbars be affected? Should probably have separate
137 * function to change them (by default, taken from wxSystemSettings)
139 wxColour backgroundColour
= wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
);
140 wxDoChangeBackgroundColour((WXWidget
) hsb
, backgroundColour
, true);
141 wxDoChangeBackgroundColour((WXWidget
) vsb
, backgroundColour
, true);
145 XmNtroughColor
, backgroundColour
.AllocColour(XtDisplay(hsb
)),
149 XmNtroughColor
, backgroundColour
.AllocColour(XtDisplay(vsb
)),
153 int wxFileDialog::ShowModal()
155 WX_TESTING_SHOW_MODAL_HOOK();
159 // static char fileBuf[512];
160 Widget parentWidget
= (Widget
) 0;
162 parentWidget
= (Widget
) m_parent
->GetTopWidget();
164 parentWidget
= (Widget
) wxTheApp
->GetTopLevelWidget();
165 // prepare the arg list
166 Display
* dpy
= XtDisplay(parentWidget
);
170 if (m_backgroundColour
.IsOk())
172 wxComputeColours (dpy
, & m_backgroundColour
, NULL
);
174 XtSetArg(args
[ac
], XmNbackground
, g_itemColors
[wxBACK_INDEX
].pixel
); ac
++;
175 XtSetArg(args
[ac
], XmNtopShadowColor
, g_itemColors
[wxTOPS_INDEX
].pixel
); ac
++;
176 XtSetArg(args
[ac
], XmNbottomShadowColor
, g_itemColors
[wxBOTS_INDEX
].pixel
); ac
++;
177 XtSetArg(args
[ac
], XmNforeground
, g_itemColors
[wxFORE_INDEX
].pixel
); ac
++;
180 wxFont font
= wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
);
182 #if __WXMOTIF20__ && !__WXLESSTIF__
183 XtSetArg(args
[ac
], XmNbuttonRenderTable
, font
.GetFontTypeC(dpy
)); ac
++;
184 XtSetArg(args
[ac
], XmNlabelRenderTable
, font
.GetFontTypeC(dpy
)); ac
++;
185 XtSetArg(args
[ac
], XmNtextRenderTable
, font
.GetFontTypeC(dpy
)); ac
++;
187 XtSetArg(args
[ac
], XmNbuttonFontList
, font
.GetFontTypeC(dpy
)); ac
++;
188 XtSetArg(args
[ac
], XmNlabelFontList
, font
.GetFontTypeC(dpy
)); ac
++;
189 XtSetArg(args
[ac
], XmNtextFontList
, font
.GetFontTypeC(dpy
)); ac
++;
192 Widget fileSel
= XmCreateFileSelectionDialog(parentWidget
,
193 wxMOTIF_STR("file_selector"),
195 #define wxFSChild( name ) \
196 XmFileSelectionBoxGetChild(fileSel, name)
198 XtUnmanageChild(wxFSChild(XmDIALOG_HELP_BUTTON
));
200 Widget filterWidget
= wxFSChild(XmDIALOG_FILTER_TEXT
);
201 Widget selectionWidget
= wxFSChild(XmDIALOG_TEXT
);
202 Widget dirListWidget
= wxFSChild(XmDIALOG_DIR_LIST
);
203 Widget fileListWidget
= wxFSChild(XmDIALOG_LIST
);
205 // for changing labels
206 Widget okWidget
= wxFSChild(XmDIALOG_OK_BUTTON
);
207 Widget applyWidget
= wxFSChild(XmDIALOG_APPLY_BUTTON
);
208 Widget cancelWidget
= wxFSChild(XmDIALOG_CANCEL_BUTTON
);
209 Widget dirlistLabel
= wxFSChild(XmDIALOG_DIR_LIST_LABEL
);
210 Widget filterLabel
= wxFSChild(XmDIALOG_FILTER_LABEL
);
211 Widget listLabel
= wxFSChild(XmDIALOG_LIST_LABEL
);
212 Widget selectionLabel
= wxFSChild(XmDIALOG_SELECTION_LABEL
);
217 wxXmString
btnOK( wxGetStockLabel( wxID_OK
, false ) ),
218 btnCancel( wxGetStockLabel( wxID_CANCEL
, false ) ),
219 btnFilter( _("Filter") ), lblFilter( _("Filter") ),
220 lblDirectories( _("Directories") ),
221 lblFiles( _("Files" ) ), lblSelection( _("Selection") );
223 XtVaSetValues( okWidget
, XmNlabelString
, btnOK(), NULL
);
224 XtVaSetValues( applyWidget
, XmNlabelString
, btnFilter(), NULL
);
225 XtVaSetValues( cancelWidget
, XmNlabelString
, btnCancel(), NULL
);
226 XtVaSetValues( dirlistLabel
, XmNlabelString
, lblDirectories(), NULL
);
227 XtVaSetValues( filterLabel
, XmNlabelString
, lblFilter(), NULL
);
228 XtVaSetValues( listLabel
, XmNlabelString
, lblFiles(), NULL
);
229 XtVaSetValues( selectionLabel
, XmNlabelString
, lblSelection(), NULL
);
231 Widget shell
= XtParent(fileSel
);
233 if ( !m_message
.empty() )
235 XmNtitle
, (const char*)m_message
.mb_str(),
238 if (!m_wildCard
.empty())
240 // return something understandable by Motif
241 wxString wildCard
= ParseWildCard( m_wildCard
);
244 filter
= m_dir
+ wxString("/") + wildCard
;
248 XmTextSetString(filterWidget
, filter
.char_str());
249 XmFileSelectionDoSearch(fileSel
, NULL
);
252 // Suggested by Terry Gitnick, 16/9/97, because of change in Motif
253 // file selector on Solaris 1.5.1.
254 if ( !m_dir
.empty() )
256 wxXmString
thePath( m_dir
);
258 XtVaSetValues (fileSel
,
259 XmNdirectory
, thePath(),
267 entirePath
= m_dir
+ wxString("/") + m_fileName
;
271 entirePath
= m_fileName
;
274 if (!entirePath
.empty())
276 XmTextSetString(selectionWidget
, entirePath
.char_str());
279 XtAddCallback(fileSel
, XmNcancelCallback
,
280 (XtCallbackProc
)wxFileSelCancel
, (XtPointer
)NULL
);
281 XtAddCallback(fileSel
, XmNokCallback
,
282 (XtCallbackProc
)wxFileSelOk
, (XtPointer
)NULL
);
283 XtAddCallback(fileSel
, XmNunmapCallback
,
284 (XtCallbackProc
)wxFileSelClose
, (XtPointer
)this);
286 //#if XmVersion > 1000
287 // I'm not sure about what you mean with XmVersion.
288 // If this is for Motif1.1/Motif1.2, then check XmVersion>=1200
289 // (Motif1.1.4 ==> XmVersion 1100 )
290 // Nevertheless, I put here a #define, so anyone can choose in (I)makefile.
292 #if !DEFAULT_FILE_SELECTOR_SIZE
293 int width
= wxFSB_WIDTH
;
294 int height
= wxFSB_HEIGHT
;
295 XtVaSetValues(fileSel
,
298 XmNresizePolicy
, XmRESIZE_NONE
,
301 wxDoChangeBackgroundColour((WXWidget
) filterWidget
, *wxWHITE
);
302 wxDoChangeBackgroundColour((WXWidget
) selectionWidget
, *wxWHITE
);
304 wxChangeListBoxColours(this, dirListWidget
);
305 wxChangeListBoxColours(this, fileListWidget
);
307 XtManageChild(fileSel
);
309 m_fileSelectorAnswer
= wxEmptyString
;
310 m_fileSelectorReturned
= false;
314 XtAddGrab(XtParent(fileSel
), True
, False
);
315 XtAppContext context
= (XtAppContext
) wxTheApp
->GetAppContext();
317 while (!m_fileSelectorReturned
)
319 XtAppNextEvent(context
, &event
);
320 XtDispatchEvent(&event
);
322 XtRemoveGrab(XtParent(fileSel
));
324 XtUnmapWidget(XtParent(fileSel
));
325 XtDestroyWidget(XtParent(fileSel
));
327 // Now process all events, because otherwise
328 // this might remain on the screen
329 wxFlushEvents(XtDisplay(fileSel
));
331 m_path
= m_fileSelectorAnswer
;
332 m_fileName
= wxFileNameFromPath(m_fileSelectorAnswer
);
333 m_dir
= wxPathOnly(m_path
);
335 if (m_fileName
.empty())