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" 
  28 #pragma message disable nosimpint 
  31 #include <Xm/MwmUtil.h> 
  33 #include <Xm/BulletinB.h> 
  36 #include <Xm/DialogS.h> 
  37 #include <Xm/FileSB.h> 
  38 #include <Xm/RowColumn.h> 
  39 #include <Xm/LabelG.h> 
  41 #pragma message enable nosimpint 
  44 #include "wx/motif/private.h" 
  46 IMPLEMENT_CLASS(wxFileDialog
, wxFileDialogBase
) 
  48 #define DEFAULT_FILE_SELECTOR_SIZE 0 
  49 // Let Motif defines the size of File 
  50 // Selector Box (if 1), or fix it to 
  51 // wxFSB_WIDTH x wxFSB_HEIGHT (if 0) 
  52 #define wxFSB_WIDTH                600 
  53 #define wxFSB_HEIGHT               500 
  56 wxString 
wxFileDialog::m_fileSelectorAnswer 
= wxEmptyString
; 
  57 bool wxFileDialog::m_fileSelectorReturned 
= false; 
  59 static void wxFileSelClose(Widget 
WXUNUSED(w
), 
  60                            void* WXUNUSED(client_data
), 
  61                            XmAnyCallbackStruct 
*WXUNUSED(call_data
)) 
  63     wxFileDialog::m_fileSelectorAnswer 
= wxEmptyString
; 
  64     wxFileDialog::m_fileSelectorReturned 
= true; 
  67 void wxFileSelCancel( Widget 
WXUNUSED(fs
), XtPointer 
WXUNUSED(client_data
), 
  68                      XmFileSelectionBoxCallbackStruct 
*WXUNUSED(cbs
) ) 
  70     wxFileDialog::m_fileSelectorAnswer 
= wxEmptyString
; 
  71     wxFileDialog::m_fileSelectorReturned 
= true; 
  74 void wxFileSelOk(Widget 
WXUNUSED(fs
), XtPointer 
WXUNUSED(client_data
), XmFileSelectionBoxCallbackStruct 
*cbs
) 
  76     char *filename 
= NULL
; 
  77     if (!XmStringGetLtoR(cbs
->value
, XmSTRING_DEFAULT_CHARSET
, &filename
)) { 
  78         wxFileDialog::m_fileSelectorAnswer 
= wxEmptyString
; 
  79         wxFileDialog::m_fileSelectorReturned 
= true; 
  82             wxFileDialog::m_fileSelectorAnswer 
= filename
; 
  85         wxFileDialog::m_fileSelectorReturned 
= true; 
  89 static wxString 
ParseWildCard( const wxString
& wild 
) 
  92     static const wxChar
* msg 
= 
  93         _T("Motif file dialog does not understand this ") 
  94         _T("wildcard syntax"); 
  97     wxArrayString wildDescriptions
, wildFilters
; 
  98     const size_t count 
= wxParseCommonDialogsFilter(wild
, 
 101     wxCHECK_MSG( count
, _T("*.*"), wxT("wxFileDialog: bad wildcard string") ); 
 102     wxCHECK_MSG( count 
== 1, _T("*.*"), msg 
); 
 104     // check for *.txt;*.rtf 
 105     wxStringTokenizer 
tok2( wildFilters
[0], _T(";") ); 
 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
) 
 120 static void wxChangeListBoxColours(wxWindow
* WXUNUSED(win
), Widget widget
) 
 122     wxDoChangeBackgroundColour((WXWidget
) widget
, *wxWHITE
); 
 124     // Change colour of the scrolled areas of the listboxes 
 125     Widget listParent 
= XtParent (widget
); 
 127     wxDoChangeBackgroundColour((WXWidget
) listParent
, *wxWHITE
, true); 
 130     Widget hsb 
= (Widget
) 0; 
 131     Widget vsb 
= (Widget
) 0; 
 132     XtVaGetValues (listParent
, 
 133         XmNhorizontalScrollBar
, &hsb
, 
 134         XmNverticalScrollBar
, &vsb
, 
 137    /* TODO: should scrollbars be affected? Should probably have separate 
 138     * function to change them (by default, taken from wxSystemSettings) 
 140     wxColour backgroundColour 
= wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
); 
 141     wxDoChangeBackgroundColour((WXWidget
) hsb
, backgroundColour
, true); 
 142     wxDoChangeBackgroundColour((WXWidget
) vsb
, backgroundColour
, true); 
 146         XmNtroughColor
, backgroundColour
.AllocColour(XtDisplay(hsb
)), 
 150         XmNtroughColor
, backgroundColour
.AllocColour(XtDisplay(vsb
)), 
 154 int wxFileDialog::ShowModal() 
 158     //  static char fileBuf[512]; 
 159     Widget parentWidget 
= (Widget
) 0; 
 161         parentWidget 
= (Widget
) m_parent
->GetTopWidget(); 
 163         parentWidget 
= (Widget
) wxTheApp
->GetTopLevelWidget(); 
 164     // prepare the arg list 
 165     Display
* dpy 
= XtDisplay(parentWidget
); 
 169     if (m_backgroundColour
.Ok()) 
 171         wxComputeColours (dpy
, & m_backgroundColour
, (wxColour
*) NULL
); 
 173         XtSetArg(args
[ac
], XmNbackground
, g_itemColors
[wxBACK_INDEX
].pixel
); ac
++; 
 174         XtSetArg(args
[ac
], XmNtopShadowColor
, g_itemColors
[wxTOPS_INDEX
].pixel
); ac
++; 
 175         XtSetArg(args
[ac
], XmNbottomShadowColor
, g_itemColors
[wxBOTS_INDEX
].pixel
); ac
++; 
 176         XtSetArg(args
[ac
], XmNforeground
, g_itemColors
[wxFORE_INDEX
].pixel
); ac
++; 
 179     wxFont font 
= wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
); 
 181 #if __WXMOTIF20__ && !__WXLESSTIF__ 
 182     XtSetArg(args
[ac
], XmNbuttonRenderTable
, font
.GetFontTypeC(dpy
)); ac
++; 
 183     XtSetArg(args
[ac
], XmNlabelRenderTable
, font
.GetFontTypeC(dpy
)); ac
++; 
 184     XtSetArg(args
[ac
], XmNtextRenderTable
, font
.GetFontTypeC(dpy
)); ac
++; 
 186     XtSetArg(args
[ac
], XmNbuttonFontList
, font
.GetFontTypeC(dpy
)); ac
++; 
 187     XtSetArg(args
[ac
], XmNlabelFontList
, font
.GetFontTypeC(dpy
)); ac
++; 
 188     XtSetArg(args
[ac
], XmNtextFontList
, font
.GetFontTypeC(dpy
)); ac
++; 
 191     Widget fileSel 
= XmCreateFileSelectionDialog(parentWidget
, 
 192                                                  wxMOTIF_STR("file_selector"), 
 194 #define wxFSChild( name ) \ 
 195     XmFileSelectionBoxGetChild(fileSel, name) 
 197     XtUnmanageChild(wxFSChild(XmDIALOG_HELP_BUTTON
)); 
 199     Widget filterWidget 
= wxFSChild(XmDIALOG_FILTER_TEXT
); 
 200     Widget selectionWidget 
= wxFSChild(XmDIALOG_TEXT
); 
 201     Widget dirListWidget 
= wxFSChild(XmDIALOG_DIR_LIST
); 
 202     Widget fileListWidget 
= wxFSChild(XmDIALOG_LIST
); 
 204     // for changing labels 
 205     Widget okWidget 
= wxFSChild(XmDIALOG_OK_BUTTON
); 
 206     Widget applyWidget 
= wxFSChild(XmDIALOG_APPLY_BUTTON
); 
 207     Widget cancelWidget 
= wxFSChild(XmDIALOG_CANCEL_BUTTON
); 
 208     Widget dirlistLabel 
= wxFSChild(XmDIALOG_DIR_LIST_LABEL
); 
 209     Widget filterLabel 
= wxFSChild(XmDIALOG_FILTER_LABEL
); 
 210     Widget listLabel 
= wxFSChild(XmDIALOG_LIST_LABEL
); 
 211     Widget selectionLabel 
= wxFSChild(XmDIALOG_SELECTION_LABEL
); 
 216     wxXmString 
btnOK( wxGetStockLabel( wxID_OK
, false ) ), 
 217                btnCancel( wxGetStockLabel( wxID_CANCEL
, false ) ), 
 218                btnFilter( _("Filter") ), lblFilter( _("Filter") ), 
 219                lblDirectories( _("Directories") ), 
 220                lblFiles( _("Files" ) ), lblSelection( _("Selection") ); 
 222     XtVaSetValues( okWidget
, XmNlabelString
, btnOK(), NULL 
); 
 223     XtVaSetValues( applyWidget
, XmNlabelString
, btnFilter(), NULL 
); 
 224     XtVaSetValues( cancelWidget
, XmNlabelString
, btnCancel(), NULL 
); 
 225     XtVaSetValues( dirlistLabel
, XmNlabelString
, lblDirectories(), NULL 
); 
 226     XtVaSetValues( filterLabel
, XmNlabelString
, lblFilter(), NULL 
); 
 227     XtVaSetValues( listLabel
, XmNlabelString
, lblFiles(), NULL 
); 
 228     XtVaSetValues( selectionLabel
, XmNlabelString
, lblSelection(), NULL 
); 
 230     Widget shell 
= XtParent(fileSel
); 
 232     if (!m_message
.IsNull()) 
 234                       XmNtitle
, (const char*)m_message
.mb_str(), 
 237     if (!m_wildCard
.empty()) 
 239         // return something understandable by Motif 
 240         wxString wildCard 
= ParseWildCard( m_wildCard 
); 
 243             filter 
= m_dir 
+ wxString("/") + wildCard
; 
 247         XmTextSetString(filterWidget
, filter
.char_str()); 
 248         XmFileSelectionDoSearch(fileSel
, NULL
); 
 251     // Suggested by Terry Gitnick, 16/9/97, because of change in Motif 
 252     // file selector on Solaris 1.5.1. 
 253     if ( !m_dir
.empty() ) 
 255         wxXmString 
thePath( m_dir 
); 
 257         XtVaSetValues (fileSel
, 
 258             XmNdirectory
, thePath(), 
 266         entirePath 
= m_dir 
+ wxString("/") + m_fileName
; 
 270         entirePath 
= m_fileName
; 
 273     if (!entirePath
.empty()) 
 275         XmTextSetString(selectionWidget
, entirePath
.char_str()); 
 278     XtAddCallback(fileSel
, XmNcancelCallback
, 
 279                   (XtCallbackProc
)wxFileSelCancel
, (XtPointer
)NULL
); 
 280     XtAddCallback(fileSel
, XmNokCallback
, 
 281                   (XtCallbackProc
)wxFileSelOk
, (XtPointer
)NULL
); 
 282     XtAddCallback(fileSel
, XmNunmapCallback
, 
 283                   (XtCallbackProc
)wxFileSelClose
, (XtPointer
)this); 
 285     //#if XmVersion > 1000 
 286     // I'm not sure about what you mean with XmVersion. 
 287     // If this is for Motif1.1/Motif1.2, then check XmVersion>=1200 
 288     // (Motif1.1.4 ==> XmVersion 1100 ) 
 289     // Nevertheless, I put here a #define, so anyone can choose in (I)makefile. 
 291 #if !DEFAULT_FILE_SELECTOR_SIZE 
 292     int width 
= wxFSB_WIDTH
; 
 293     int height 
= wxFSB_HEIGHT
; 
 294     XtVaSetValues(fileSel
, 
 297         XmNresizePolicy
, XmRESIZE_NONE
, 
 300     wxDoChangeBackgroundColour((WXWidget
) filterWidget
, *wxWHITE
); 
 301     wxDoChangeBackgroundColour((WXWidget
) selectionWidget
, *wxWHITE
); 
 303     wxChangeListBoxColours(this, dirListWidget
); 
 304     wxChangeListBoxColours(this, fileListWidget
); 
 306     XtManageChild(fileSel
); 
 308     m_fileSelectorAnswer 
= wxEmptyString
; 
 309     m_fileSelectorReturned 
= false; 
 313     XtAddGrab(XtParent(fileSel
), True
, False
); 
 314     XtAppContext context 
= (XtAppContext
) wxTheApp
->GetAppContext(); 
 316     while (!m_fileSelectorReturned
) 
 318         XtAppNextEvent(context
, &event
); 
 319         XtDispatchEvent(&event
); 
 321     XtRemoveGrab(XtParent(fileSel
)); 
 323     XtUnmapWidget(XtParent(fileSel
)); 
 324     XtDestroyWidget(XtParent(fileSel
)); 
 326     // Now process all events, because otherwise 
 327     // this might remain on the screen 
 328     wxFlushEvents(XtDisplay(fileSel
)); 
 330     m_path 
= m_fileSelectorAnswer
; 
 331     m_fileName 
= wxFileNameFromPath(m_fileSelectorAnswer
); 
 332     m_dir 
= wxPathOnly(m_path
); 
 334     if (m_fileName
.empty())