1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxFileDialog
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
13 #pragma implementation "filedlg.h"
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
20 #define XtDisplay XTDISPLAY
21 #define XtParent XTPARENT
22 #define XtWindow XTWINDOW
27 #include "wx/filedlg.h"
30 #include "wx/settings.h"
31 #include "wx/tokenzr.h"
32 #include "wx/stockitem.h"
35 #pragma message disable nosimpint
38 #include <Xm/MwmUtil.h>
40 #include <Xm/BulletinB.h>
43 #include <Xm/DialogS.h>
44 #include <Xm/FileSB.h>
45 #include <Xm/RowColumn.h>
46 #include <Xm/LabelG.h>
48 #pragma message enable nosimpint
51 #include "wx/motif/private.h"
53 IMPLEMENT_CLASS(wxFileDialog
, wxFileDialogBase
)
55 #define DEFAULT_FILE_SELECTOR_SIZE 0
56 // Let Motif defines the size of File
57 // Selector Box (if 1), or fix it to
58 // wxFSB_WIDTH x wxFSB_HEIGHT (if 0)
59 #define wxFSB_WIDTH 600
60 #define wxFSB_HEIGHT 500
63 wxString
wxFileDialog::m_fileSelectorAnswer
= "";
64 bool wxFileDialog::m_fileSelectorReturned
= false;
66 static void wxFileSelClose(Widget
WXUNUSED(w
),
67 void* WXUNUSED(client_data
),
68 XmAnyCallbackStruct
*WXUNUSED(call_data
))
70 wxFileDialog::m_fileSelectorAnswer
= "";
71 wxFileDialog::m_fileSelectorReturned
= true;
74 void wxFileSelCancel( Widget
WXUNUSED(fs
), XtPointer
WXUNUSED(client_data
),
75 XmFileSelectionBoxCallbackStruct
*WXUNUSED(cbs
) )
77 wxFileDialog::m_fileSelectorAnswer
= "";
78 wxFileDialog::m_fileSelectorReturned
= true;
81 void wxFileSelOk(Widget
WXUNUSED(fs
), XtPointer
WXUNUSED(client_data
), XmFileSelectionBoxCallbackStruct
*cbs
)
83 char *filename
= NULL
;
84 if (!XmStringGetLtoR(cbs
->value
, XmSTRING_DEFAULT_CHARSET
, &filename
)) {
85 wxFileDialog::m_fileSelectorAnswer
= "";
86 wxFileDialog::m_fileSelectorReturned
= true;
89 wxFileDialog::m_fileSelectorAnswer
= filename
;
92 wxFileDialog::m_fileSelectorReturned
= true;
96 static wxString
ParseWildCard( const wxString
& wild
)
99 static const wxChar
* msg
=
100 _T("Motif file dialog does not understand this ")
101 _T("wildcard syntax");
104 wxArrayString wildDescriptions
, wildFilters
;
105 const size_t count
= wxParseCommonDialogsFilter(wild
,
108 wxCHECK_MSG( count
, _T("*.*"), wxT("wxFileDialog: bad wildcard string") );
109 wxCHECK_MSG( count
== 1, _T("*.*"), msg
);
111 // check for *.txt;*.rtf
112 wxStringTokenizer
tok2( wildFilters
[0], _T(";") );
113 wxString wildcard
= tok2
.GetNextToken();
115 wxCHECK_MSG( tok2
.CountTokens() <= 1, wildcard
, msg
);
119 wxFileDialog::wxFileDialog(wxWindow
*parent
, const wxString
& message
,
120 const wxString
& defaultDir
, const wxString
& defaultFileName
, const wxString
& wildCard
,
121 long style
, const wxPoint
& pos
)
122 :wxFileDialogBase(parent
, message
, defaultDir
, defaultFileName
, wildCard
, style
, pos
)
127 static void wxChangeListBoxColours(wxWindow
* WXUNUSED(win
), Widget widget
)
129 wxDoChangeBackgroundColour((WXWidget
) widget
, *wxWHITE
);
131 // Change colour of the scrolled areas of the listboxes
132 Widget listParent
= XtParent (widget
);
134 wxDoChangeBackgroundColour((WXWidget
) listParent
, *wxWHITE
, true);
137 Widget hsb
= (Widget
) 0;
138 Widget vsb
= (Widget
) 0;
139 XtVaGetValues (listParent
,
140 XmNhorizontalScrollBar
, &hsb
,
141 XmNverticalScrollBar
, &vsb
,
144 /* TODO: should scrollbars be affected? Should probably have separate
145 * function to change them (by default, taken from wxSystemSettings)
147 wxColour backgroundColour
= wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
);
148 wxDoChangeBackgroundColour((WXWidget
) hsb
, backgroundColour
, true);
149 wxDoChangeBackgroundColour((WXWidget
) vsb
, backgroundColour
, true);
153 XmNtroughColor
, backgroundColour
.AllocColour(XtDisplay(hsb
)),
157 XmNtroughColor
, backgroundColour
.AllocColour(XtDisplay(vsb
)),
161 int wxFileDialog::ShowModal()
165 // static char fileBuf[512];
166 Widget parentWidget
= (Widget
) 0;
168 parentWidget
= (Widget
) m_parent
->GetTopWidget();
170 parentWidget
= (Widget
) wxTheApp
->GetTopLevelWidget();
171 // prepare the arg list
172 Display
* dpy
= XtDisplay(parentWidget
);
176 wxComputeColours (dpy
, & m_backgroundColour
, (wxColour
*) NULL
);
178 XtSetArg(args
[ac
], XmNbackground
, g_itemColors
[wxBACK_INDEX
].pixel
); ac
++;
179 XtSetArg(args
[ac
], XmNtopShadowColor
, g_itemColors
[wxTOPS_INDEX
].pixel
); ac
++;
180 XtSetArg(args
[ac
], XmNbottomShadowColor
, g_itemColors
[wxBOTS_INDEX
].pixel
); ac
++;
181 XtSetArg(args
[ac
], XmNforeground
, g_itemColors
[wxFORE_INDEX
].pixel
); ac
++;
183 wxFont font
= wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
);
185 if ( wxFont::GetFontTag() == (WXString
) XmNfontList
)
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
++;
193 XtSetArg(args
[ac
], XmNbuttonRenderTable
, font
.GetFontTypeC(dpy
)); ac
++;
194 XtSetArg(args
[ac
], XmNlabelRenderTable
, font
.GetFontTypeC(dpy
)); ac
++;
195 XtSetArg(args
[ac
], XmNtextRenderTable
, font
.GetFontTypeC(dpy
)); ac
++;
198 Widget fileSel
= XmCreateFileSelectionDialog(parentWidget
,
199 "file_selector", args
, ac
);
200 #define wxFSChild( name ) \
201 XmFileSelectionBoxGetChild(fileSel, name)
203 XtUnmanageChild(wxFSChild(XmDIALOG_HELP_BUTTON
));
205 Widget filterWidget
= wxFSChild(XmDIALOG_FILTER_TEXT
);
206 Widget selectionWidget
= wxFSChild(XmDIALOG_TEXT
);
207 Widget dirListWidget
= wxFSChild(XmDIALOG_DIR_LIST
);
208 Widget fileListWidget
= wxFSChild(XmDIALOG_LIST
);
210 // for changing labels
211 Widget okWidget
= wxFSChild(XmDIALOG_OK_BUTTON
);
212 Widget applyWidget
= wxFSChild(XmDIALOG_APPLY_BUTTON
);
213 Widget cancelWidget
= wxFSChild(XmDIALOG_CANCEL_BUTTON
);
214 Widget dirlistLabel
= wxFSChild(XmDIALOG_DIR_LIST_LABEL
);
215 Widget filterLabel
= wxFSChild(XmDIALOG_FILTER_LABEL
);
216 Widget listLabel
= wxFSChild(XmDIALOG_LIST_LABEL
);
217 Widget selectionLabel
= wxFSChild(XmDIALOG_SELECTION_LABEL
);
222 wxXmString
btnOK( wxGetStockLabel( wxID_OK
, false ) ),
223 btnCancel( wxGetStockLabel( wxID_CANCEL
, false ) ),
224 btnFilter( _("Filter") ), lblFilter( _("Filter") ),
225 lblDirectories( _("Directories") ),
226 lblFiles( _("Files" ) ), lblSelection( _("Selection") );
228 XtVaSetValues( okWidget
, XmNlabelString
, btnOK(), NULL
);
229 XtVaSetValues( applyWidget
, XmNlabelString
, btnFilter(), NULL
);
230 XtVaSetValues( cancelWidget
, XmNlabelString
, btnCancel(), NULL
);
231 XtVaSetValues( dirlistLabel
, XmNlabelString
, lblDirectories(), NULL
);
232 XtVaSetValues( filterLabel
, XmNlabelString
, lblFilter(), NULL
);
233 XtVaSetValues( listLabel
, XmNlabelString
, lblFiles(), NULL
);
234 XtVaSetValues( selectionLabel
, XmNlabelString
, lblSelection(), NULL
);
236 Widget shell
= XtParent(fileSel
);
238 if (!m_message
.IsNull())
240 XmNtitle
, wxConstCast(m_message
.c_str(), char),
243 if (m_wildCard
!= "")
245 // return something understandable by Motif
246 wxString wildCard
= ParseWildCard( m_wildCard
);
249 filter
= m_dir
+ wxString("/") + wildCard
;
253 XmTextSetString(filterWidget
, wxConstCast(filter
.c_str(), char));
254 XmFileSelectionDoSearch(fileSel
, NULL
);
257 // Suggested by Terry Gitnick, 16/9/97, because of change in Motif
258 // file selector on Solaris 1.5.1.
261 wxXmString
thePath( m_dir
);
263 XtVaSetValues (fileSel
,
264 XmNdirectory
, thePath(),
268 wxString
entirePath("");
272 entirePath
= m_dir
+ wxString("/") + m_fileName
;
276 entirePath
= m_fileName
;
279 if (entirePath
!= "")
281 XmTextSetString(selectionWidget
,
282 wxConstCast(entirePath
.c_str(), char));
285 XtAddCallback(fileSel
, XmNcancelCallback
,
286 (XtCallbackProc
)wxFileSelCancel
, (XtPointer
)NULL
);
287 XtAddCallback(fileSel
, XmNokCallback
,
288 (XtCallbackProc
)wxFileSelOk
, (XtPointer
)NULL
);
289 XtAddCallback(fileSel
, XmNunmapCallback
,
290 (XtCallbackProc
)wxFileSelClose
, (XtPointer
)this);
292 //#if XmVersion > 1000
293 // I'm not sure about what you mean with XmVersion.
294 // If this is for Motif1.1/Motif1.2, then check XmVersion>=1200
295 // (Motif1.1.4 ==> XmVersion 1100 )
296 // Nevertheless, I put here a #define, so anyone can choose in (I)makefile.
298 #if !DEFAULT_FILE_SELECTOR_SIZE
299 int width
= wxFSB_WIDTH
;
300 int height
= wxFSB_HEIGHT
;
301 XtVaSetValues(fileSel
,
304 XmNresizePolicy
, XmRESIZE_NONE
,
307 wxDoChangeBackgroundColour((WXWidget
) filterWidget
, *wxWHITE
);
308 wxDoChangeBackgroundColour((WXWidget
) selectionWidget
, *wxWHITE
);
310 wxChangeListBoxColours(this, dirListWidget
);
311 wxChangeListBoxColours(this, fileListWidget
);
313 XtManageChild(fileSel
);
315 m_fileSelectorAnswer
= "";
316 m_fileSelectorReturned
= false;
320 XtAddGrab(XtParent(fileSel
), True
, False
);
321 XtAppContext context
= (XtAppContext
) wxTheApp
->GetAppContext();
323 while (!m_fileSelectorReturned
)
325 XtAppNextEvent(context
, &event
);
326 XtDispatchEvent(&event
);
328 XtRemoveGrab(XtParent(fileSel
));
330 XtUnmapWidget(XtParent(fileSel
));
331 XtDestroyWidget(XtParent(fileSel
));
333 // Now process all events, because otherwise
334 // this might remain on the screen
335 wxFlushEvents(XtDisplay(fileSel
));
337 m_path
= m_fileSelectorAnswer
;
338 m_fileName
= wxFileNameFromPath(m_fileSelectorAnswer
);
339 m_dir
= wxPathOnly(m_path
);
341 if (m_fileName
== "")