1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxFileDialog
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "filedlg.h"
17 #define XtDisplay XTDISPLAY
18 #define XtParent XTPARENT
19 #define XtWindow XTWINDOW
24 #include "wx/dialog.h"
25 #include "wx/filedlg.h"
28 #include "wx/settings.h"
29 #include "wx/tokenzr.h"
32 #pragma message disable nosimpint
35 #include <Xm/MwmUtil.h>
37 #include <Xm/BulletinB.h>
40 #include <Xm/DialogS.h>
41 #include <Xm/FileSB.h>
42 #include <Xm/RowColumn.h>
43 #include <Xm/LabelG.h>
45 #pragma message enable nosimpint
48 #include "wx/motif/private.h"
50 IMPLEMENT_CLASS(wxFileDialog
, wxDialog
)
52 #define DEFAULT_FILE_SELECTOR_SIZE 0
53 // Let Motif defines the size of File
54 // Selector Box (if 1), or fix it to
55 // wxFSB_WIDTH x wxFSB_HEIGHT (if 0)
56 #define wxFSB_WIDTH 600
57 #define wxFSB_HEIGHT 500
60 wxString
wxFileDialog::m_fileSelectorAnswer
= "";
61 bool wxFileDialog::m_fileSelectorReturned
= FALSE
;
63 static void wxFileSelClose(Widget
WXUNUSED(w
),
64 void* WXUNUSED(client_data
),
65 XmAnyCallbackStruct
*WXUNUSED(call_data
))
67 wxFileDialog::m_fileSelectorAnswer
= "";
68 wxFileDialog::m_fileSelectorReturned
= TRUE
;
71 void wxFileSelCancel( Widget
WXUNUSED(fs
), XtPointer
WXUNUSED(client_data
),
72 XmFileSelectionBoxCallbackStruct
*WXUNUSED(cbs
) )
74 wxFileDialog::m_fileSelectorAnswer
= "";
75 wxFileDialog::m_fileSelectorReturned
= TRUE
;
78 void wxFileSelOk(Widget
WXUNUSED(fs
), XtPointer
WXUNUSED(client_data
), XmFileSelectionBoxCallbackStruct
*cbs
)
80 char *filename
= NULL
;
81 if (!XmStringGetLtoR(cbs
->value
, XmSTRING_DEFAULT_CHARSET
, &filename
)) {
82 wxFileDialog::m_fileSelectorAnswer
= "";
83 wxFileDialog::m_fileSelectorReturned
= TRUE
;
86 wxFileDialog::m_fileSelectorAnswer
= filename
;
89 wxFileDialog::m_fileSelectorReturned
= TRUE
;
93 static wxString
ParseWildCard( const wxString
& wild
)
96 static const wxChar
* msg
=
97 _T("Motif file dialog does not understand this ")
98 _T("wildcard syntax");
101 wxStringTokenizer
tok( wild
, _T("|") );
103 wxCHECK_MSG( tok
.CountTokens() <= 2, _T("*.*"), msg
);
105 if( tok
.CountTokens() == 1 ) return wild
;
109 wxStringTokenizer
tok2( tok
.GetNextToken(), _T(";") );
111 wxCHECK_MSG( tok2
.CountTokens() == 1, tok2
.GetNextToken(), msg
);
112 return tok2
.GetNextToken();
115 wxFileDialog::wxFileDialog(wxWindow
*parent
, const wxString
& message
,
116 const wxString
& defaultDir
, const wxString
& defaultFileName
, const wxString
& wildCard
,
117 long style
, const wxPoint
& pos
)
120 m_dialogStyle
= style
;
123 m_fileName
= defaultFileName
;
125 m_wildCard
= wildCard
;
130 static void wxChangeListBoxColours(wxWindow
* WXUNUSED(win
), Widget widget
)
132 wxDoChangeBackgroundColour((WXWidget
) widget
, *wxWHITE
);
134 // Change colour of the scrolled areas of the listboxes
135 Widget listParent
= XtParent (widget
);
137 wxDoChangeBackgroundColour((WXWidget
) listParent
, *wxWHITE
, TRUE
);
140 Widget hsb
= (Widget
) 0;
141 Widget vsb
= (Widget
) 0;
142 XtVaGetValues (listParent
,
143 XmNhorizontalScrollBar
, &hsb
,
144 XmNverticalScrollBar
, &vsb
,
147 /* TODO: should scrollbars be affected? Should probably have separate
148 * function to change them (by default, taken from wxSystemSettings)
150 wxColour backgroundColour
= wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
);
151 wxDoChangeBackgroundColour((WXWidget
) hsb
, backgroundColour
, TRUE
);
152 wxDoChangeBackgroundColour((WXWidget
) vsb
, backgroundColour
, TRUE
);
156 XmNtroughColor
, backgroundColour
.AllocColour(XtDisplay(hsb
)),
160 XmNtroughColor
, backgroundColour
.AllocColour(XtDisplay(vsb
)),
164 int wxFileDialog::ShowModal()
168 // static char fileBuf[512];
169 Widget parentWidget
= (Widget
) 0;
171 parentWidget
= (Widget
) m_parent
->GetTopWidget();
173 parentWidget
= (Widget
) wxTheApp
->GetTopLevelWidget();
174 // prepare the arg list
178 wxComputeColours (XtDisplay(parentWidget
), & m_backgroundColour
,
181 XtSetArg(args
[ac
], XmNbackground
, g_itemColors
[wxBACK_INDEX
].pixel
); ac
++;
182 XtSetArg(args
[ac
], XmNtopShadowColor
, g_itemColors
[wxTOPS_INDEX
].pixel
); ac
++;
183 XtSetArg(args
[ac
], XmNbottomShadowColor
, g_itemColors
[wxBOTS_INDEX
].pixel
); ac
++;
184 XtSetArg(args
[ac
], XmNforeground
, g_itemColors
[wxFORE_INDEX
].pixel
); ac
++;
187 Widget fileSel
= XmCreateFileSelectionDialog(parentWidget
, "file_selector", args
, ac
);
188 XtUnmanageChild(XmFileSelectionBoxGetChild(fileSel
, XmDIALOG_HELP_BUTTON
));
190 Widget filterWidget
= XmFileSelectionBoxGetChild(fileSel
, XmDIALOG_FILTER_TEXT
);
191 Widget selectionWidget
= XmFileSelectionBoxGetChild(fileSel
, XmDIALOG_TEXT
);
192 Widget dirListWidget
= XmFileSelectionBoxGetChild(fileSel
, XmDIALOG_DIR_LIST
);
193 Widget fileListWidget
= XmFileSelectionBoxGetChild(fileSel
, XmDIALOG_LIST
);
195 // code using these vars disabled
197 Widget okWidget
= XmFileSelectionBoxGetChild(fileSel
, XmDIALOG_OK_BUTTON
);
198 Widget applyWidget
= XmFileSelectionBoxGetChild(fileSel
, XmDIALOG_APPLY_BUTTON
);
199 Widget cancelWidget
= XmFileSelectionBoxGetChild(fileSel
, XmDIALOG_CANCEL_BUTTON
);
203 Widget shell
= XtParent(fileSel
);
205 if (!m_message
.IsNull())
207 XmNtitle
, wxConstCast(m_message
.c_str(), char),
210 wxString
entirePath("");
212 if ((m_dir
!= "") && (m_fileName
!= ""))
214 entirePath
= m_dir
+ wxString("/") + m_fileName
;
216 else if ((m_dir
!= "") && (m_fileName
== ""))
218 entirePath
= m_dir
+ wxString("/");
220 else if ((m_dir
== "") && (m_fileName
!= ""))
222 entirePath
= m_fileName
;
225 if (m_wildCard
!= "")
227 // return something understandable by Motif
228 wxString wildCard
= ParseWildCard( m_wildCard
);
231 filter
= m_dir
+ wxString("/") + wildCard
;
235 XmTextSetString(filterWidget
, wxConstCast(filter
.c_str(), char));
236 XmFileSelectionDoSearch(fileSel
, NULL
);
239 // Suggested by Terry Gitnick, 16/9/97, because of change in Motif
240 // file selector on Solaris 1.5.1.
243 wxXmString
thePath( m_dir
);
245 XtVaSetValues (fileSel
,
246 XmNdirectory
, thePath(),
250 if (entirePath
!= "")
252 XmTextSetString(selectionWidget
,
253 wxConstCast(entirePath
.c_str(), char));
256 XtAddCallback(fileSel
, XmNcancelCallback
, (XtCallbackProc
)wxFileSelCancel
, (XtPointer
)NULL
);
257 XtAddCallback(fileSel
, XmNokCallback
, (XtCallbackProc
)wxFileSelOk
, (XtPointer
)NULL
);
258 XtAddCallback(fileSel
, XmNunmapCallback
,
259 (XtCallbackProc
)wxFileSelClose
, (XtPointer
)this);
261 //#if XmVersion > 1000
262 // I'm not sure about what you mean with XmVersion.
263 // If this is for Motif1.1/Motif1.2, then check XmVersion>=1200
264 // (Motif1.1.4 ==> XmVersion 1100 )
265 // Nevertheless, I put here a #define, so anyone can choose in (I)makefile...
267 #if !DEFAULT_FILE_SELECTOR_SIZE
268 int width
= wxFSB_WIDTH
;
269 int height
= wxFSB_HEIGHT
;
270 XtVaSetValues(fileSel
,
273 XmNresizePolicy
, XmRESIZE_NONE
,
276 // wxDoChangeBackgroundColour((WXWidget) fileSel, m_backgroundColour);
277 wxDoChangeBackgroundColour((WXWidget
) filterWidget
, *wxWHITE
);
278 wxDoChangeBackgroundColour((WXWidget
) selectionWidget
, *wxWHITE
);
280 wxChangeListBoxColours(this, dirListWidget
);
281 wxChangeListBoxColours(this, fileListWidget
);
283 XtManageChild(fileSel
);
285 m_fileSelectorAnswer
= "";
286 m_fileSelectorReturned
= FALSE
;
290 XtAddGrab(XtParent(fileSel
), TRUE
, FALSE
);
291 XtAppContext context
= (XtAppContext
) wxTheApp
->GetAppContext();
293 while (!m_fileSelectorReturned
)
295 XtAppNextEvent(context
, &event
);
296 XtDispatchEvent(&event
);
298 XtRemoveGrab(XtParent(fileSel
));
300 // XmUpdateDisplay((Widget) wxTheApp->GetTopLevelWidget()); // Experimental
302 Display
* display
= XtDisplay(fileSel
);
304 XtUnmapWidget(XtParent(fileSel
));
305 XtDestroyWidget(XtParent(fileSel
));
307 // Now process all events, because otherwise
308 // this might remain on the screen
309 wxFlushEvents(display
);
311 m_path
= m_fileSelectorAnswer
;
312 m_fileName
= wxFileNameFromPath(m_fileSelectorAnswer
);
313 m_dir
= wxPathOnly(m_path
);
315 if (m_fileName
== "")