Initial import of the CDE 2.1.30 sources from the Open Group.
[oweals/cde.git] / cde / programs / dtmail / MotifApp / SelectFileCmd.C
1 /* $TOG: SelectFileCmd.C /main/9 1998/10/26 17:57:37 mgreess $ */
2 /*
3  *+SNOTICE
4  *
5  *      RESTRICTED CONFIDENTIAL INFORMATION:
6  *      
7  *      The information in this document is subject to special
8  *      restrictions in a confidential disclosure agreement bertween
9  *      HP, IBM, Sun, USL, SCO and Univel.  Do not distribute this
10  *      document outside HP, IBM, Sun, USL, SCO, or Univel wihtout
11  *      Sun's specific written approval.  This documment and all copies
12  *      and derivative works thereof must be returned or destroyed at
13  *      Sun's request.
14  *
15  *      Copyright 1993, 1994, 1995 Sun Microsystems, Inc.  All rights reserved.
16  *
17  *+ENOTICE
18  */
19
20 ///////////////////////////////////////////////////////////////////////////////
21 //////////////////////////////////////////////////////////////////////////////
22 //         This example code is from the book:
23 //
24 //           Object-Oriented Programming with C++ and OSF/Motif
25 //         by
26 //           Douglas Young
27 //           Prentice Hall, 1992
28 //           ISBN 0-13-630252-1 
29 //
30 //         Copyright 1991 by Prentice Hall
31 //         All Rights Reserved
32 //
33 //  Permission to use, copy, modify, and distribute this software for 
34 //  any purpose except publication and without fee is hereby granted, provided 
35 //  that the above copyright notice appear in all copies of the software.
36 ///////////////////////////////////////////////////////////////////////////////
37 //////////////////////////////////////////////////////////////////////////////
38
39
40 //////////////////////////////////////////////////////////
41 // SelectFileCmd.C: 
42 //////////////////////////////////////////////////////////
43 #include <unistd.h>
44 #include <stdlib.h>
45 #include "SelectFileCmd.h"
46 #include "Application.h"
47 #include <Xm/FileSB.h>
48 #include <X11/Intrinsic.h>
49 #include "Help.hh"
50
51 #include <nl_types.h>
52 extern nl_catd catd;
53
54 #include "NLS.hh"
55
56 extern "C" {
57 #include <Dt/HourGlass.h>
58 }
59
60 extern "C" {
61 extern XtPointer _XmStringUngenerate (
62                                 XmString string,
63                                 XmStringTag tag,
64                                 XmTextType tag_type,
65                                 XmTextType output_type);
66 }
67
68
69 extern forceUpdate( Widget );
70
71 SelectFileCmd::SelectFileCmd (const char * name, 
72                               const char * label,
73                               const char * title,
74                               const char * ok_label,
75                               int          active,
76                               FileCallback ok_callback,
77                               void        *ok_clientData,
78                               Widget       parent) :
79                               NoUndoCmd ((char *)name, (char *)label, active )
80 {
81     _ok_label = (ok_label ? strdup(ok_label) : strdup("OK"));
82     _title = (title ? strdup(title) : strdup(name));
83     _ok_callback       = ok_callback;
84     _ok_clientData     = ok_clientData;
85     _cancel_callback   = NULL;
86     _cancel_clientData = NULL;
87     _fileBrowser       = NULL;
88     _parentWidget      = parent;
89 }
90
91 SelectFileCmd::SelectFileCmd (const char * name, 
92                               const char * label,
93                               const char * title,
94                               const char * ok_label,
95                               int          active,
96                               FileCallback ok_callback,
97                               void        *ok_clientData,
98                               FileCallback cancel_callback,
99                               void        *cancel_clientData,
100                               Widget       parent) :
101                               NoUndoCmd ((char *)name, (char *)label, active )
102 {
103     _ok_label = (ok_label ? strdup(ok_label) : strdup("OK"));
104     _title = (title ? strdup(title) : strdup(name));
105     _ok_callback       = ok_callback;
106     _ok_clientData     = ok_clientData;
107     _cancel_callback   = cancel_callback;
108     _cancel_clientData = cancel_clientData;
109     _fileBrowser       = NULL;
110     _parentWidget      = parent;
111 }
112
113 SelectFileCmd::~SelectFileCmd()
114 {
115     free(_ok_label);
116     free(_title);
117 }
118
119
120 void SelectFileCmd::doit()
121 {
122     // Create a FileSelectionBox widget
123     
124     Arg args[1];
125     Cardinal n = 0;
126     XmString title;
127
128     // If the FSB already exists and is managed, raise it.
129
130     if (_fileBrowser) {
131         XtManageChild ( _fileBrowser );
132         XtPopup (XtParent(_fileBrowser), XtGrabNone );
133         XRaiseWindow(XtDisplay(_fileBrowser), XtWindow(XtParent(_fileBrowser)));
134         forceUpdate(_fileBrowser);
135         return;
136     }
137
138     // If there is no FSB, create it and manage it.
139     // If there is one, just manage it.
140
141     // Creating one is different from the book. cast required.
142     // Also, its the "new CDE" FSB!
143
144     if (!_fileBrowser) {
145         _DtTurnOnHourGlass(_parentWidget);
146
147         _fileBrowser =
148             XmCreateFileSelectionDialog (_parentWidget,
149                                          (char *) name(), 
150                                          args, n );       
151         // Set the title right...
152         title = XmStringCreateLocalized(_title);
153         XmString ok_str = XmStringCreateLocalized(_ok_label);
154         XtVaSetValues(_fileBrowser,
155                       XmNdialogTitle, title,
156                       XmNokLabelString, ok_str,
157                       NULL);
158         XmStringFree(title);
159         XmStringFree(ok_str);
160         XmString hidden_str = XmStringCreateLocalized(
161                         GETMSG(catd, 1, 11, "Show hidden folders and files"));
162         _hidden_button = XtVaCreateManagedWidget(
163                                 "hidden", xmToggleButtonWidgetClass,
164                                  _fileBrowser,
165                                  XmNlabelString, hidden_str,
166                                  XmNalignment, XmALIGNMENT_BEGINNING,
167                                  XmNnavigationType, XmSTICKY_TAB_GROUP,
168                                  XmNsensitive, TRUE,
169                                  NULL);
170         XmStringFree(hidden_str);
171
172         printHelpId("_fileBrowser", _fileBrowser);
173         /* add help callback */
174         // XtAddCallback(_fileBrowser, XmNhelpCallback, HelpCB, helpId);
175         
176         // Set up the callback to be called when the user chooses a file
177             
178         XtAddCallback ( _fileBrowser, 
179             XmNokCallback,
180             &SelectFileCmd::fileSelectedCB, 
181             (XtPointer) this );
182         XtAddCallback ( _fileBrowser,
183             XmNcancelCallback,
184             &SelectFileCmd::fileCanceledCB,
185             (XtPointer) this );
186         XtAddCallback(_hidden_button,
187                       XmNvalueChangedCallback,
188                       &SelectFileCmd::hiddenCB,
189                       this);
190
191         XtSetSensitive(
192             XmFileSelectionBoxGetChild(_fileBrowser, XmDIALOG_HELP_BUTTON),
193             False);
194
195         _DtTurnOffHourGlass(_parentWidget);
196     }
197     
198     // Display the dialog
199     
200     XtManageChild ( _fileBrowser );
201
202     // Raise it, because it might be buried.
203     //
204     XRaiseWindow(XtDisplay(_fileBrowser), XtWindow(XtParent(_fileBrowser)));
205 }
206
207 void SelectFileCmd::fileSelectedCB(
208                                 Widget w,
209                                 XtPointer clientData,
210                                 XtPointer callData)
211 {
212     SelectFileCmd * obj = (SelectFileCmd *) clientData;
213     XmFileSelectionBoxCallbackStruct *cb = 
214         (XmFileSelectionBoxCallbackStruct *) callData;
215     char     *name   = NULL;
216
217     // XtUnmanageChild ( w );   // Bring the file selection dialog down.
218     
219     if (cb->value)
220     {
221         // Extract the first character string matching the default
222         // character set from the compound string
223         name = (char *) _XmStringUngenerate(
224                                         cb->value, NULL,
225                                         XmMULTIBYTE_TEXT, XmMULTIBYTE_TEXT);
226          // if the name is a null string ( no file is selected)
227          // we should pop up an error dialog to let user know
228          // that he/she did not specify file name. But because
229          // the message cat file is frozen, we can not add any
230          // new msg. Just free the name and return.
231          // see aix defect 176761.
232          if(NULL == name) return;
233          if (strlen(name)<1)
234          {
235            free(name);
236            return;
237          }
238
239         // If a string was succesfully extracted, call
240         // fileSelected to handle the file.
241
242         XtUnmanageChild ( w );   // Bring the file selection dialog down.
243         obj->fileSelected ( name );
244     }
245 }
246
247 void SelectFileCmd::fileCanceledCB ( Widget w,
248                                      XtPointer clientData,
249                                      XtPointer )
250 {
251     SelectFileCmd * obj = (SelectFileCmd *) clientData;
252
253     XtUnmanageChild(w);   // Bring the file selection dialog down.
254     obj->fileCanceled();
255 }
256
257 void SelectFileCmd::fileSelected ( char *filename )
258 {
259     if ( _ok_callback )
260         _ok_callback ( _ok_clientData, filename );
261 }
262
263 void SelectFileCmd::fileCanceled ()
264 {
265     if ( _cancel_callback )
266         _cancel_callback ( _cancel_clientData, NULL );
267 }
268
269 void
270 SelectFileCmd::hiddenCB(Widget,
271                         XtPointer client_data,
272                         XtPointer cb_data)
273 {
274     SelectFileCmd * self = (SelectFileCmd *)client_data;
275     XmToggleButtonCallbackStruct *cbs = (XmToggleButtonCallbackStruct*) cb_data;
276
277     self->doHidden(cbs->set);
278 }
279
280 void
281 SelectFileCmd::doHidden(int on)
282 {
283     XtEnum              style;
284     style = (on) ? XmFILTER_NONE : XmFILTER_HIDDEN_FILES;
285     XtVaSetValues(_fileBrowser, XmNfileFilterStyle, style, NULL);
286     XmFileSelectionDoSearch(_fileBrowser, NULL);
287 }
288
289 char *
290 SelectFileCmd::getDirectory()
291 {
292     XmString    directory;
293     char        *path;
294
295     if (NULL == _fileBrowser)
296       return NULL;
297
298     // Get the default selection.
299     XtVaGetValues(_fileBrowser, XmNdirectory, &directory, NULL);
300     path = (char *)
301       _XmStringUngenerate(directory, NULL, XmMULTIBYTE_TEXT, XmMULTIBYTE_TEXT);
302     XmStringFree(directory);
303
304     return path;
305 }
306
307 char *
308 SelectFileCmd::getSelected()
309 {
310     Widget      text;
311     char        *path = NULL;
312
313     if (NULL == _fileBrowser)
314       return NULL;
315
316     // Set the default selection.
317     text = XtNameToWidget(_fileBrowser, "Text");
318     if (NULL != text)
319       XtVaGetValues(text, XmNvalue, &path, NULL);
320
321     return path;
322 }
323
324 int
325 SelectFileCmd::getHidden()
326 {
327     int                 val;
328     unsigned char       current_state;
329
330     if (NULL == _fileBrowser || NULL == _hidden_button)
331       return 0;
332     
333     XtVaGetValues(_hidden_button, XmNset, &current_state, NULL);
334     val = (current_state == XmSET) ? 1 : 0;
335     return val;
336 }
337
338 void
339 SelectFileCmd::setDirectory(char *path)
340 {
341     XmString    directory;
342
343     if (NULL == _fileBrowser)
344       return;
345
346     // Set the default directory where the file selection box points.
347     directory = XmStringCreateLocalized(path);
348     XtVaSetValues(_fileBrowser, XmNdirectory, directory, NULL);
349     XmStringFree(directory);
350 }
351
352 void
353 SelectFileCmd::setSelected(char *path)
354 {
355     Widget      text;
356
357     if (NULL == _fileBrowser)
358       return;
359
360     // Set the default selection.
361     text = XtNameToWidget(_fileBrowser, "Text");
362     if (NULL != text)
363       XtVaSetValues(text, XmNvalue, path, NULL);
364 }
365
366 void
367 SelectFileCmd::setHidden(int on)
368 {
369     unsigned char       current_state;
370     unsigned char       desired_state;
371
372     if (NULL == _fileBrowser || NULL == _hidden_button)
373       return;
374     
375     desired_state = (on) ? XmSET : XmUNSET;
376     XtVaGetValues(_hidden_button, XmNset, &current_state, NULL);
377     if (current_state == desired_state)
378       return;
379
380     XtVaSetValues(_hidden_button, XmNset, desired_state, NULL);
381     doHidden(on);
382 }