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"
34 #pragma message disable nosimpint
37 #include <Xm/MwmUtil.h>
39 #include <Xm/BulletinB.h>
42 #include <Xm/DialogS.h>
43 #include <Xm/FileSB.h>
44 #include <Xm/RowColumn.h>
45 #include <Xm/LabelG.h>
47 #pragma message enable nosimpint
50 #include "wx/motif/private.h"
52 IMPLEMENT_CLASS(wxFileDialog
, wxFileDialogBase
)
54 #define DEFAULT_FILE_SELECTOR_SIZE 0
55 // Let Motif defines the size of File
56 // Selector Box (if 1), or fix it to
57 // wxFSB_WIDTH x wxFSB_HEIGHT (if 0)
58 #define wxFSB_WIDTH 600
59 #define wxFSB_HEIGHT 500
62 wxString
wxFileDialog::m_fileSelectorAnswer
= "";
63 bool wxFileDialog::m_fileSelectorReturned
= false;
65 static void wxFileSelClose(Widget
WXUNUSED(w
),
66 void* WXUNUSED(client_data
),
67 XmAnyCallbackStruct
*WXUNUSED(call_data
))
69 wxFileDialog::m_fileSelectorAnswer
= "";
70 wxFileDialog::m_fileSelectorReturned
= true;
73 void wxFileSelCancel( Widget
WXUNUSED(fs
), XtPointer
WXUNUSED(client_data
),
74 XmFileSelectionBoxCallbackStruct
*WXUNUSED(cbs
) )
76 wxFileDialog::m_fileSelectorAnswer
= "";
77 wxFileDialog::m_fileSelectorReturned
= true;
80 void wxFileSelOk(Widget
WXUNUSED(fs
), XtPointer
WXUNUSED(client_data
), XmFileSelectionBoxCallbackStruct
*cbs
)
82 char *filename
= NULL
;
83 if (!XmStringGetLtoR(cbs
->value
, XmSTRING_DEFAULT_CHARSET
, &filename
)) {
84 wxFileDialog::m_fileSelectorAnswer
= "";
85 wxFileDialog::m_fileSelectorReturned
= true;
88 wxFileDialog::m_fileSelectorAnswer
= filename
;
91 wxFileDialog::m_fileSelectorReturned
= true;
95 static wxString
ParseWildCard( const wxString
& wild
)
98 static const wxChar
* msg
=
99 _T("Motif file dialog does not understand this ")
100 _T("wildcard syntax");
103 wxArrayString wildDescriptions
, wildFilters
;
104 const size_t count
= wxParseCommonDialogsFilter(wild
,
107 wxCHECK_MSG( count
, _T("*.*"), wxT("wxFileDialog: bad wildcard string") );
108 wxCHECK_MSG( count
== 1, _T("*.*"), msg
);
110 // check for *.txt;*.rtf
111 wxStringTokenizer
tok2( wildFilters
[0], _T(";") );
112 wxString wildcard
= tok2
.GetNextToken();
114 wxCHECK_MSG( tok2
.CountTokens() <= 1, wildcard
, msg
);
118 wxFileDialog::wxFileDialog(wxWindow
*parent
, const wxString
& message
,
119 const wxString
& defaultDir
, const wxString
& defaultFileName
, const wxString
& wildCard
,
120 long style
, const wxPoint
& pos
)
121 :wxFileDialogBase(parent
, message
, defaultDir
, defaultFileName
, wildCard
, style
, pos
)
126 static void wxChangeListBoxColours(wxWindow
* WXUNUSED(win
), Widget widget
)
128 wxDoChangeBackgroundColour((WXWidget
) widget
, *wxWHITE
);
130 // Change colour of the scrolled areas of the listboxes
131 Widget listParent
= XtParent (widget
);
133 wxDoChangeBackgroundColour((WXWidget
) listParent
, *wxWHITE
, true);
136 Widget hsb
= (Widget
) 0;
137 Widget vsb
= (Widget
) 0;
138 XtVaGetValues (listParent
,
139 XmNhorizontalScrollBar
, &hsb
,
140 XmNverticalScrollBar
, &vsb
,
143 /* TODO: should scrollbars be affected? Should probably have separate
144 * function to change them (by default, taken from wxSystemSettings)
146 wxColour backgroundColour
= wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
);
147 wxDoChangeBackgroundColour((WXWidget
) hsb
, backgroundColour
, true);
148 wxDoChangeBackgroundColour((WXWidget
) vsb
, backgroundColour
, true);
152 XmNtroughColor
, backgroundColour
.AllocColour(XtDisplay(hsb
)),
156 XmNtroughColor
, backgroundColour
.AllocColour(XtDisplay(vsb
)),
160 int wxFileDialog::ShowModal()
164 // static char fileBuf[512];
165 Widget parentWidget
= (Widget
) 0;
167 parentWidget
= (Widget
) m_parent
->GetTopWidget();
169 parentWidget
= (Widget
) wxTheApp
->GetTopLevelWidget();
170 // prepare the arg list
174 wxComputeColours (XtDisplay(parentWidget
), & m_backgroundColour
,
177 XtSetArg(args
[ac
], XmNbackground
, g_itemColors
[wxBACK_INDEX
].pixel
); ac
++;
178 XtSetArg(args
[ac
], XmNtopShadowColor
, g_itemColors
[wxTOPS_INDEX
].pixel
); ac
++;
179 XtSetArg(args
[ac
], XmNbottomShadowColor
, g_itemColors
[wxBOTS_INDEX
].pixel
); ac
++;
180 XtSetArg(args
[ac
], XmNforeground
, g_itemColors
[wxFORE_INDEX
].pixel
); ac
++;
183 Widget fileSel
= XmCreateFileSelectionDialog(parentWidget
, "file_selector", args
, ac
);
184 XtUnmanageChild(XmFileSelectionBoxGetChild(fileSel
, XmDIALOG_HELP_BUTTON
));
186 Widget filterWidget
= XmFileSelectionBoxGetChild(fileSel
, XmDIALOG_FILTER_TEXT
);
187 Widget selectionWidget
= XmFileSelectionBoxGetChild(fileSel
, XmDIALOG_TEXT
);
188 Widget dirListWidget
= XmFileSelectionBoxGetChild(fileSel
, XmDIALOG_DIR_LIST
);
189 Widget fileListWidget
= XmFileSelectionBoxGetChild(fileSel
, XmDIALOG_LIST
);
191 // code using these vars disabled
193 Widget okWidget
= XmFileSelectionBoxGetChild(fileSel
, XmDIALOG_OK_BUTTON
);
194 Widget applyWidget
= XmFileSelectionBoxGetChild(fileSel
, XmDIALOG_APPLY_BUTTON
);
195 Widget cancelWidget
= XmFileSelectionBoxGetChild(fileSel
, XmDIALOG_CANCEL_BUTTON
);
199 Widget shell
= XtParent(fileSel
);
201 if (!m_message
.IsNull())
203 XmNtitle
, wxConstCast(m_message
.c_str(), char),
206 wxString
entirePath("");
208 if ((m_dir
!= "") && (m_fileName
!= ""))
210 entirePath
= m_dir
+ wxString("/") + m_fileName
;
212 else if ((m_dir
!= "") && (m_fileName
== ""))
214 entirePath
= m_dir
+ wxString("/");
216 else if ((m_dir
== "") && (m_fileName
!= ""))
218 entirePath
= m_fileName
;
221 if (m_wildCard
!= "")
223 // return something understandable by Motif
224 wxString wildCard
= ParseWildCard( m_wildCard
);
227 filter
= m_dir
+ wxString("/") + wildCard
;
231 XmTextSetString(filterWidget
, wxConstCast(filter
.c_str(), char));
232 XmFileSelectionDoSearch(fileSel
, NULL
);
235 // Suggested by Terry Gitnick, 16/9/97, because of change in Motif
236 // file selector on Solaris 1.5.1.
239 wxXmString
thePath( m_dir
);
241 XtVaSetValues (fileSel
,
242 XmNdirectory
, thePath(),
246 if (entirePath
!= "")
248 XmTextSetString(selectionWidget
,
249 wxConstCast(entirePath
.c_str(), char));
252 XtAddCallback(fileSel
, XmNcancelCallback
, (XtCallbackProc
)wxFileSelCancel
, (XtPointer
)NULL
);
253 XtAddCallback(fileSel
, XmNokCallback
, (XtCallbackProc
)wxFileSelOk
, (XtPointer
)NULL
);
254 XtAddCallback(fileSel
, XmNunmapCallback
,
255 (XtCallbackProc
)wxFileSelClose
, (XtPointer
)this);
257 //#if XmVersion > 1000
258 // I'm not sure about what you mean with XmVersion.
259 // If this is for Motif1.1/Motif1.2, then check XmVersion>=1200
260 // (Motif1.1.4 ==> XmVersion 1100 )
261 // Nevertheless, I put here a #define, so anyone can choose in (I)makefile...
263 #if !DEFAULT_FILE_SELECTOR_SIZE
264 int width
= wxFSB_WIDTH
;
265 int height
= wxFSB_HEIGHT
;
266 XtVaSetValues(fileSel
,
269 XmNresizePolicy
, XmRESIZE_NONE
,
272 // wxDoChangeBackgroundColour((WXWidget) fileSel, m_backgroundColour);
273 wxDoChangeBackgroundColour((WXWidget
) filterWidget
, *wxWHITE
);
274 wxDoChangeBackgroundColour((WXWidget
) selectionWidget
, *wxWHITE
);
276 wxChangeListBoxColours(this, dirListWidget
);
277 wxChangeListBoxColours(this, fileListWidget
);
279 XtManageChild(fileSel
);
281 m_fileSelectorAnswer
= "";
282 m_fileSelectorReturned
= false;
286 XtAddGrab(XtParent(fileSel
), True
, False
);
287 XtAppContext context
= (XtAppContext
) wxTheApp
->GetAppContext();
289 while (!m_fileSelectorReturned
)
291 XtAppNextEvent(context
, &event
);
292 XtDispatchEvent(&event
);
294 XtRemoveGrab(XtParent(fileSel
));
296 // XmUpdateDisplay((Widget) wxTheApp->GetTopLevelWidget()); // Experimental
298 Display
* display
= XtDisplay(fileSel
);
300 XtUnmapWidget(XtParent(fileSel
));
301 XtDestroyWidget(XtParent(fileSel
));
303 // Now process all events, because otherwise
304 // this might remain on the screen
305 wxFlushEvents(display
);
307 m_path
= m_fileSelectorAnswer
;
308 m_fileName
= wxFileNameFromPath(m_fileSelectorAnswer
);
309 m_dir
= wxPathOnly(m_path
);
311 if (m_fileName
== "")