1 /* $XConsortium: ChangeDir.c /main/7 1996/10/30 11:09:35 drk $ */
2 /************************************<+>*************************************
3 ****************************************************************************
7 * COMPONENT_NAME: Desktop File Manager (dtfile)
9 * DESCRIPTION: Source file for the change directory dialog.
11 * FUNCTIONS: ChangeToNewDir
30 * (c) Copyright 1993, 1994, 1995 Hewlett-Packard Company
31 * (c) Copyright 1993, 1994, 1995 International Business Machines Corp.
32 * (c) Copyright 1993, 1994, 1995 Sun Microsystems, Inc.
33 * (c) Copyright 1993, 1994, 1995 Novell, Inc.
35 ****************************************************************************
36 ************************************<+>*************************************/
40 #include <sys/types.h>
44 #include <sys/inode.h>
52 #include <Xm/MessageB.h>
53 #include <Xm/SelectioB.h>
55 #include <Xm/VendorSEP.h>
57 #include <Xm/MwmUtil.h>
58 #include <Xm/Protocols.h>
60 #include <X11/ShellP.h>
61 #include <X11/Shell.h>
62 #include <X11/Xatom.h>
64 #include <Dt/Action.h>
65 #include <Dt/Connect.h>
66 #include <Dt/DtNlUtils.h>
70 #include <Xm/DragIcon.h>
75 #include "SharedProcs.h"
79 #include "ChangeDir.h"
81 #include "SharedMsgs.h"
86 static char * CHANGEDIRECTORY = "ChangeDirectory";
89 static DialogResource resources[] =
91 { "string_path", XmRXmString, sizeof(XmString),
92 XtOffset(ChangeDirDataPtr, string_path), NULL, _DtXmStringToString },
94 { "historyList", XmRXmStringTable, sizeof(XmStringTable),
95 XtOffset(ChangeDirDataPtr, history_list), NULL, _DtXmStringTableToString },
97 { "visibleCount", XmRInt, sizeof(int),
98 XtOffset(ChangeDirDataPtr, visible_count), (XtPointer) 8, _DtIntToString },
100 { "listCount", XmRInt, sizeof(int),
101 XtOffset(ChangeDirDataPtr, list_count), NULL, _DtIntToString },
105 /******** Static Function Declarations ********/
107 static void Create( Display *display,
111 static void InstallChange( ChangeDirRec *change_dir_rec,
112 XtCallbackProc callback,
113 XtPointer client_data) ;
114 static void InstallClose( ChangeDirRec *change_dir_rec,
115 XtCallbackProc callback,
116 XtPointer client_data) ;
117 static void Destroy( ChangeDirRec *change_dir_rec) ;
118 static XtPointer GetValues( ChangeDirRec *change_dir_rec) ;
119 static XtPointer GetDefaultValues( void ) ;
120 static XtPointer GetResourceValues( XrmDatabase data_base,
122 static void SetValues( ChangeDirRec *change_dir_rec,
123 ChangeDirData *change_dir_data) ;
124 static void WriteResourceValues( DialogData *values,
127 static void FreeValues( ChangeDirData *change_dir_data) ;
128 static Boolean TryToChangeDir( Boolean isFromDialog,
129 char * incoming_string,
130 FileMgrData * file_mgr_data,
131 FileMgrRec * file_mgr_rec,
132 ChangeDirData * change_dir_data,
133 Widget selection_box,
134 ChangeDirApply * apply_data,
135 XmSelectionBoxCallbackStruct * callback_data,
136 void (*callback)()) ;
137 static void OkCallback( Widget selection_box,
138 ChangeDirApply *apply_data,
139 XmSelectionBoxCallbackStruct *callback_data) ;
140 static int CheckRestrictedDir ( FileMgrRec * file_mgr_rec,
141 FileMgrData * file_mgr_data,
143 Boolean relative_name);
144 static void GoToNewDir ( FileMgrData * file_mgr_data,
146 static void SetFocus(
147 ChangeDirRec *change_dir_rec,
148 ChangeDirData *change_dir_data) ;
151 /******** End Static Function Declarations ********/
153 extern char *getwd(char *);
156 * The Dialog Class structure.
159 static DialogClass changeDirClassRec =
164 (DialogInstallChangeProc) InstallChange,
165 (DialogInstallCloseProc) InstallClose,
166 (DialogDestroyProc) Destroy,
167 (DialogGetValuesProc) GetValues,
170 (DialogSetValuesProc) SetValues,
172 (DialogFreeValuesProc) FreeValues,
173 (DialogMapWindowProc) _DtGenericMapWindow,
174 (DialogSetFocusProc) SetFocus,
177 DialogClass * changeDirClass = (DialogClass *) &changeDirClassRec;
182 /************************************************************************
186 ************************************************************************/
195 ChangeDirRec * change_dir_rec;
200 XtTranslations trans_table;
204 /* Allocate the change directory dialog instance record. */
206 change_dir_rec = (ChangeDirRec *) XtMalloc (sizeof (ChangeDirRec));
208 prompt = XmStringCreateLocalized (((char *)GETMESSAGE(2,14, "Destination Folder:")));
210 trans_table = XtParseTranslationTable(translations_space);
212 XtSetArg (args[n], XmNselectionLabelString, prompt); n++;
213 XtSetArg (args[n], XmNokLabelString, okXmString); n++;
214 XtSetArg (args[n], XmNcancelLabelString, cancelXmString); n++;
215 XtSetArg (args[n], XmNhelpLabelString, helpXmString); n++;
216 XtSetArg (args[n], XmNautoUnmanage, False); n++;
217 XtSetArg (args[n], XmNtextTranslations, trans_table); n++;
218 change_dir = change_dir_rec->change_dir =
219 XmCreateSelectionDialog (parent, "change_directory", args, n);
220 change_dir_rec->shell = XtParent(change_dir);
222 XmStringFree (prompt);
224 /* Add the help callback to each of the important sub-components */
225 XtAddCallback(change_dir, XmNhelpCallback, (XtCallbackProc)HelpRequestCB,
226 HELP_CHANGEDIR_DIALOG_STR);
227 w = XmSelectionBoxGetChild(change_dir, XmDIALOG_APPLY_BUTTON);
228 XtAddCallback(w, XmNhelpCallback, (XtCallbackProc)HelpRequestCB,
229 HELP_CHANGEDIR_DIALOG_STR);
230 w = XmSelectionBoxGetChild(change_dir, XmDIALOG_CANCEL_BUTTON);
231 XtAddCallback(w, XmNhelpCallback, (XtCallbackProc)HelpRequestCB,
232 HELP_CHANGEDIR_DIALOG_STR);
233 w = XmSelectionBoxGetChild(change_dir, XmDIALOG_HELP_BUTTON);
234 XtAddCallback(w, XmNhelpCallback, (XtCallbackProc)HelpRequestCB,
235 HELP_CHANGEDIR_DIALOG_STR);
236 XtAddCallback(w, XmNactivateCallback, (XtCallbackProc)HelpRequestCB,
237 HELP_CHANGEDIR_DIALOG_STR);
238 w = XmSelectionBoxGetChild(change_dir, XmDIALOG_OK_BUTTON);
239 XtAddCallback(w, XmNhelpCallback, (XtCallbackProc)HelpRequestCB,
240 HELP_CHANGEDIR_DIALOG_STR);
241 w = XmSelectionBoxGetChild(change_dir, XmDIALOG_LIST);
242 XtAddCallback(XtParent(w), XmNhelpCallback, (XtCallbackProc)HelpRequestCB,
243 HELP_CHANGEDIR_DIALOG_STR);
244 w = XmSelectionBoxGetChild(change_dir, XmDIALOG_LIST_LABEL);
245 XtAddCallback(w, XmNhelpCallback, (XtCallbackProc)HelpRequestCB,
246 HELP_CHANGEDIR_DIALOG_STR);
247 w = XmSelectionBoxGetChild(change_dir, XmDIALOG_SELECTION_LABEL);
248 XtAddCallback(w, XmNhelpCallback, (XtCallbackProc)HelpRequestCB,
249 HELP_CHANGEDIR_DIALOG_STR);
250 w = XmSelectionBoxGetChild(change_dir, XmDIALOG_TEXT);
251 XtAddCallback(w, XmNhelpCallback, (XtCallbackProc)HelpRequestCB,
252 HELP_CHANGEDIR_DIALOG_STR);
255 /* Adjust the margin widths and heights of each of the buttons */
257 XtSetArg (args[0], XmNmarginWidth, 6);
258 XtSetArg (args[1], XmNmarginHeight, 2);
260 w = XmSelectionBoxGetChild (change_dir_rec->change_dir, XmDIALOG_OK_BUTTON);
261 XtSetValues (w, args, 2);
263 w = XmSelectionBoxGetChild (change_dir_rec->change_dir,
264 XmDIALOG_HELP_BUTTON);
265 XtSetValues (w, args, 2);
267 w = XmSelectionBoxGetChild (change_dir_rec->change_dir,
268 XmDIALOG_CANCEL_BUTTON);
269 XtSetValues (w, args, 2);
271 XtUnmanageChild(XmSelectionBoxGetChild (change_dir_rec->change_dir,
272 XmDIALOG_APPLY_BUTTON));
275 /* Adjust the decorations for the dialog shell of the dialog */
277 XtSetArg(args[0], XmNmwmFunctions, MWM_FUNC_MOVE | MWM_FUNC_CLOSE);
278 XtSetArg(args[1], XmNmwmDecorations,
279 MWM_DECOR_BORDER | MWM_DECOR_TITLE);
280 XtSetValues (change_dir_rec->shell, args, 2);
282 XtSetArg(args[0], XmNcancelButton, w);
283 XtSetValues (change_dir_rec->change_dir, args, 1);
285 /* Set the return values for the dialog widget and dialog instance. */
287 *shell = change_dir_rec->change_dir;
288 *dialog = (XtPointer) change_dir_rec;
295 /************************************************************************
299 ************************************************************************/
303 ChangeDirRec *change_dir_rec,
304 XtCallbackProc callback,
305 XtPointer client_data )
307 Widget selection_box = change_dir_rec->change_dir;
308 ChangeDirApply * apply_data;
310 /* Setup the callback data to be sent to the Ok callback. */
311 /* This contains the encapsulation callback to invoke upon */
312 /* the data within the dialog being changed. */
314 apply_data = (ChangeDirApply *) XtMalloc (sizeof (ChangeDirApply));
315 apply_data->callback = callback;
316 apply_data->client_data = client_data;
317 apply_data->change_dir_rec = (XtPointer) change_dir_rec;
318 change_dir_rec->apply_data = apply_data;
320 /* Add the callbacks for list item insertion and help. */
322 XtAddCallback (selection_box, XmNokCallback, (XtCallbackProc) OkCallback,
323 (XtPointer) apply_data);
329 /************************************************************************
333 ************************************************************************/
337 ChangeDirRec *change_dir_rec,
338 XtCallbackProc callback,
339 XtPointer client_data )
342 Atom delete_window_atom;
345 XmSelectionBoxGetChild (change_dir_rec->change_dir,
346 XmDIALOG_CANCEL_BUTTON);
348 XtAddCallback (close_widget, XmNactivateCallback, callback, client_data);
350 delete_window_atom = XmInternAtom (XtDisplay(change_dir_rec->shell),
351 "WM_DELETE_WINDOW", True);
352 XmRemoveWMProtocols( change_dir_rec->shell, &delete_window_atom, 1 );
353 XmAddWMProtocolCallback( change_dir_rec->shell, delete_window_atom, callback,
354 (XtPointer)client_data );
360 /************************************************************************
364 ************************************************************************/
368 ChangeDirRec *change_dir_rec )
370 XtDestroyWidget (change_dir_rec->change_dir);
371 XtFree ((char *) change_dir_rec->apply_data);
372 XtFree ((char *) change_dir_rec);
378 /************************************************************************
382 ************************************************************************/
386 ChangeDirRec *change_dir_rec )
388 ChangeDirData * change_dir_data;
391 XmStringTable history_list;
392 XmString string_path;
395 /* Allocate and initialize the change dir dialog data. */
397 change_dir_data = (ChangeDirData *) XtMalloc (sizeof (ChangeDirData));
399 change_dir_data->displayed = True;
400 change_dir_data->host_name = NULL;
401 change_dir_data->file_mgr_rec = NULL;
404 XtSetArg (args[n], XmNx, &change_dir_data->x); n++;
405 XtSetArg (args[n], XmNy, &change_dir_data->y); n++;
406 XtSetArg (args[n], XmNwidth, &change_dir_data->width); n++;
407 XtSetArg (args[n], XmNheight, &change_dir_data->height); n++;
408 XtSetArg (args[n], XmNlistItemCount, &change_dir_data->list_count); n++;
409 XtSetArg (args[n], XmNlistVisibleItemCount, &change_dir_data->visible_count); n++;
410 XtSetArg (args[n], XmNtextString, &string_path); n++;
411 XtSetArg (args[n], XmNlistItems, &history_list); n++;
412 XtGetValues (change_dir_rec->change_dir, args, n);
415 /* Extract and make local copies of the XmString data. */
417 change_dir_data->history_list = (XmStringTable)
418 XtMalloc (sizeof(XmStringTable) * (change_dir_data->list_count + 1));
420 for (n = 0; n < change_dir_data->list_count; n++)
421 change_dir_data->history_list[n] = XmStringCopy (history_list[n]);
422 change_dir_data->history_list[n] = NULL;
424 if(change_dir_data->string_path)
425 XmStringFree (change_dir_data->string_path);
426 change_dir_data->string_path = XmStringCopy (string_path);
428 return ((XtPointer) change_dir_data);
434 /************************************************************************
438 ************************************************************************/
441 GetDefaultValues( void )
443 ChangeDirData * change_dir_data;
446 /* Allocate and initialize the default change dir dialog data. */
448 change_dir_data = (ChangeDirData *) XtMalloc (sizeof (ChangeDirData));
450 change_dir_data->displayed = False;
451 change_dir_data->x = 0;
452 change_dir_data->y = 0;
453 change_dir_data->height = 0;
454 change_dir_data->width = 0;
455 change_dir_data->string_path = NULL;
458 This will cause users_home_dir to be displayed in
459 Application Manager go to dialog.
462 change_dir_data->string_path =
463 XmStringCreateLocalized(users_home_dir, XmFONTLIST_DEFAULT_TAG);
465 change_dir_data->string_path = NULL;
467 change_dir_data->history_list = NULL;
468 change_dir_data->visible_count = 8;
469 change_dir_data->list_count = 0;
470 change_dir_data->host_name = NULL;
471 change_dir_data->file_mgr_rec = NULL;
474 return ((XtPointer) change_dir_data);
480 /************************************************************************
484 ************************************************************************/
488 XrmDatabase data_base,
491 ChangeDirData * change_dir_data;
492 XmStringTable new_table;
496 /* Allocate and get the resources for change dir dialog data. */
498 change_dir_data = (ChangeDirData *) XtMalloc (sizeof (ChangeDirData));
500 _DtDialogGetResources (data_base, name_list,
501 CHANGEDIRECTORY, (char *) change_dir_data,
502 resources, changeDirClass->resource_count);
504 change_dir_data->host_name = NULL;
507 /* If the history list is Non-Null, realloc the pointer array */
508 /* one element larger and NULL out the new last element */
510 if (change_dir_data->list_count != 0)
512 new_table = (XmStringTable) XtMalloc (sizeof (XmStringTable) *
513 (change_dir_data->list_count + 1));
515 for (i = 0; i < change_dir_data->list_count; i++)
516 new_table[i] = change_dir_data->history_list[i];
518 new_table[change_dir_data->list_count] = NULL;
521 THIS WILL BE A MEMORY HOLE WHEN MOTIF FIXES THE XMSTRINGTABLE
522 CONVERTER. EITHER REALLOC THE RETURNED TABLE OR COPY AND FREE IT.
524 change_dir_data->history_list = new_table;
527 return ((XtPointer) change_dir_data);
533 /************************************************************************
537 ************************************************************************/
541 ChangeDirRec *change_dir_rec,
542 ChangeDirData *change_dir_data )
545 char *tmp_str, *host_name;
546 XmString host_string;
547 DialogData * dialog_data;
548 FileMgrData * file_mgr_data;
550 dialog_data = _DtGetInstanceData (change_dir_data->file_mgr_rec);
551 file_mgr_data = (FileMgrData *) dialog_data->data;
553 if(change_dir_data->string_path)
554 XmStringFree (change_dir_data->string_path);
557 && file_mgr_data->toolbox == False )
558 change_dir_data->string_path =
559 XmStringCreateLocalized( users_home_dir);
560 else if( file_mgr_data->restricted_directory )
561 change_dir_data->string_path =
562 XmStringCreateLocalized( file_mgr_data->current_directory);
564 change_dir_data->string_path = NULL;
566 XtSetArg (args[0], XmNlistItemCount, change_dir_data->list_count);
567 XtSetArg (args[1], XmNlistVisibleItemCount, change_dir_data->visible_count);
568 XtSetArg (args[2], XmNtextString, change_dir_data->string_path);
569 XtSetArg (args[3], XmNlistItems, change_dir_data->history_list);
571 XtSetValues (change_dir_rec->change_dir, args, 4);
573 if( change_dir_data->string_path )
577 text = XmSelectionBoxGetChild(change_dir_rec->change_dir, XmDIALOG_TEXT);
578 XtAddCallback (text, XmNmodifyVerifyCallback,
579 (XtCallbackProc)TextChange, (XtPointer)file_mgr_data );
580 XtAddCallback (text, XmNmotionVerifyCallback,
581 (XtCallbackProc)TextChange, (XtPointer)file_mgr_data );
582 XtAddCallback (text, XmNvalueChangedCallback,
583 (XtCallbackProc)TextChange, (XtPointer)file_mgr_data );
586 tmp_str = GETMESSAGE(2, 16, "System Name: ");
587 host_name = XtMalloc(strlen(tmp_str) + strlen(change_dir_data->host_name)+1);
588 sprintf(host_name, "%s%s", tmp_str, change_dir_data->host_name);
589 host_string = XmStringCreateLocalized (host_name);
590 XtSetArg (args[0], XmNlabelString, host_string);
591 XtSetValues (XmSelectionBoxGetChild (change_dir_rec->change_dir,
592 XmDIALOG_LIST_LABEL), args, 1);
595 XmStringFree(host_string);
601 /************************************************************************
603 * WriteResourceValues
605 ************************************************************************/
613 ChangeDirData * change_dir_data = (ChangeDirData *) values->data;
614 ChangeDirRec * change_dir_rec;
616 /* If the dialog is currently displayed, update the geometry */
617 /* fields to their current values. */
619 if (change_dir_data->displayed == True)
621 _DtGenericUpdateWindowPosition(values);
622 change_dir_rec = (ChangeDirRec *) _DtGetDialogInstance (values);
625 _DtDialogPutResources (fd, name_list, CHANGEDIRECTORY, values->data,
626 resources, changeDirClass->resource_count);
632 /************************************************************************
636 ************************************************************************/
640 ChangeDirData *change_dir_data )
644 for (i = 0; i < change_dir_data->list_count; i++)
645 XmStringFree (change_dir_data->history_list[i]);
646 XtFree ((char *) change_dir_data->history_list);
648 XmStringFree (change_dir_data->string_path);
649 XtFree ((char *) change_dir_data->host_name);
651 XtFree ((char *) change_dir_data);
655 /************************************************************************
656 ************************************************************************
658 * Internal functions used by the ChangeDir dialog
660 ************************************************************************
661 ************************************************************************/
663 /*****************************************************************************
668 This function is used both by the ChangeDir dialog, and the FileMgr
669 dialog's text field; it attempts to verify the incoming string, and
670 then change to the indicated directory.
672 *****************************************************************************/
675 Boolean isFromDialog,
676 char * incoming_string,
677 FileMgrData * file_mgr_data,
678 FileMgrRec * file_mgr_rec,
679 ChangeDirData * change_dir_data,
680 Widget selection_box,
681 ChangeDirApply * apply_data,
682 XmSelectionBoxCallbackStruct * callback_data,
685 char * new_directory;
688 struct stat stat_buf;
690 XmString path_string;
691 XmString host_string;
698 char *restricted = NULL;
700 new_directory = XtNewString(incoming_string);
702 if ((new_directory) && (strcmp(new_directory, "") != 0))
704 _DtPathFromInput(new_directory, file_mgr_data->current_directory,
709 tmpStr = GetSharedMessage(CHANGE_DIR_ERROR_TITLE);
710 title = XtNewString(tmpStr);
711 tmpStr = GETMESSAGE(2,18, "Destination Folder name is missing.\nType in a folder name or select a folder from the list.");
712 msg = XtNewString(tmpStr);
715 _DtMessage(selection_box, title, msg, NULL, HelpRequestCB);
717 _DtMessage(file_mgr_rec->current_directory_text, title, msg, NULL,
726 /* Don't allow access to the desktop directory */
729 char *ttpath = (char *) GetTTPath(path);
730 char *dtpath = (char *) GetTTPath(desktop_dir);
731 if( ttpath && strcmp(ttpath, dtpath) == 0)
739 /* Stat the file and see if it is a valid directory. (If the current view
740 is restricted, make sure that the new directory doesn't violate the
741 directory restrictions. If so, refilter the displayed file set to show
742 the files in this directory.
745 &&(stat(path, &stat_buf) == 0)
746 &&((stat_buf.st_mode & S_IFMT) == S_IFDIR)
747 &&(CheckRestrictedDir(file_mgr_rec, file_mgr_data, &path, False) == 0))
749 /* Check for read/xcute permission */
750 if (CheckAccess(path, R_OK | X_OK))
752 tmpStr = GETMESSAGE(9, 6, "Action Error");
753 title = XtNewString(tmpStr);
754 msg = (char *)XtMalloc(strlen(GETMESSAGE(30, 1, "Cannot read from %s"))
755 + strlen(new_directory)
757 sprintf(msg, GETMESSAGE(30, 1, "Cannot read from %s"), new_directory);
760 _DtMessage(selection_box, title, msg, NULL, HelpRequestCB);
762 _DtMessage(file_mgr_rec->current_directory_text, title,
763 msg, NULL, HelpRequestCB);
773 /* Adjust the selection box elements to add the text item
776 list = XmSelectionBoxGetChild(selection_box, XmDIALOG_LIST);
778 path_string = XmStringCreateLocalized(path);
780 if (XmListItemExists(list, path_string))
781 XmListDeselectAllItems(list);
783 XmListAddItem(list, path_string, 0);
785 XmListSelectItem(list, path_string, False);
786 XmListSetBottomPos(list, 0);
788 XmStringFree(path_string);
791 /* Clear out the text string */
797 XmStringCreateLocalized(users_home_dir));
799 XtSetArg(args[0], XmNtextString, NULL);
800 XtSetValues(selection_box, args, 1);
804 if(!file_mgr_data || !file_mgr_data->restricted_directory)
805 XmTextFieldSetString(file_mgr_rec->current_directory_text,
811 /* Update the change directory host name field
812 and the host name indicator widget in the dialog.
814 XtFree((char *) change_dir_data->host_name);
815 change_dir_data->host_name = XtNewString(host);
819 tmpStr = GETMESSAGE(2, 16, "System Name: ");
820 message_buf = XtMalloc(strlen(tmpStr) +
821 strlen(change_dir_data->host_name) + 1);
822 sprintf(message_buf, "%s%s", tmpStr, change_dir_data->host_name);
824 XmStringCreateLocalized(message_buf);
825 XtSetArg(args[0], XmNlabelString, host_string);
826 XtSetValues(XmSelectionBoxGetChild(selection_box,XmDIALOG_LIST_LABEL),
829 XmStringFree(host_string);
831 XmUpdateDisplay (selection_box);
834 /* Call the encapsulation change data callback */
836 (*callback)(selection_box, apply_data->client_data, path);
838 (*callback)(file_mgr_data, path);
843 tmpStr = GetSharedMessage(CHANGE_DIR_ERROR_TITLE);
844 title = XtNewString(tmpStr);
847 tmpStr = GETMESSAGE(2,20,"You cannot switch to folder:\n\n%s\n\nYou are not allowed to view this folder\nbecause it is a restricted folder.");
851 tmpStr = GETMESSAGE(2,19,"The following folder name is invalid.\n\n%s");
854 message_buf = XtMalloc(strlen(tmpStr) + strlen(path) + 1);
855 sprintf(message_buf, tmpStr, path);
859 message_buf = XtMalloc(strlen(tmpStr) + strlen(new_directory) + 1);
860 sprintf(message_buf, tmpStr, new_directory);
864 _DtMessage(selection_box, title, message_buf, NULL, HelpRequestCB);
866 _DtMessage(file_mgr_rec->current_directory_text, title, message_buf,
867 NULL, HelpRequestCB);
875 XtFree((char *) path);
876 XtFree((char *) host);
877 XtFree((char *) new_directory);
884 /************************************************************************
887 * This is a callback function called when the Ok button (Apply)
888 * is pressed. It adds the string contained within the call data
889 * into the selection boxes list.
891 ************************************************************************/
895 Widget selection_box,
896 ChangeDirApply *apply_data,
897 XmSelectionBoxCallbackStruct *callback_data )
899 DialogData * dialog_data;
900 ChangeDirData * change_dir_data;
901 FileMgrRec * file_mgr_rec;
902 FileMgrData * file_mgr_data;
906 char message_buf[MAX_PATH + 100];
912 /* Get the change dir data record */
914 dialog_data = _DtGetInstanceData (apply_data->change_dir_rec);
915 change_dir_data = (ChangeDirData *) dialog_data->data;
917 file_mgr_rec = (FileMgrRec *) change_dir_data->file_mgr_rec;
918 dialog_data = _DtGetInstanceData ((XtPointer)file_mgr_rec);
919 file_mgr_data = (FileMgrData *) dialog_data->data;
921 value = (char *) _XmStringUngenerate((XmString)callback_data->value,
922 XmFONTLIST_DEFAULT_TAG,
923 XmCHARSET_TEXT, XmCHARSET_TEXT);
927 tmpStr = GetSharedMessage(CHANGE_DIR_ERROR_TITLE);
928 title = XtNewString(tmpStr);
929 tmpStr = (char *) GETMESSAGE(2, 11, "Cannot get the new folder name.");
930 msg = XtNewString(tmpStr);
932 _DtMessage(selection_box, title, message_buf, NULL, HelpRequestCB);
939 strValue = XtNewString(value);
940 if(file_mgr_data->toolbox && strValue[0] != '/')
941 result = CheckRestrictedDir(file_mgr_rec, file_mgr_data, &strValue, True);
943 result = CheckRestrictedDir(file_mgr_rec, file_mgr_data, &strValue,False);
945 /* Process the string representing a directory to verify */
946 /* that it is a valid path. */
949 TryToChangeDir(True, (char *)strValue, file_mgr_data,
950 file_mgr_rec, change_dir_data, selection_box, apply_data,
951 callback_data, apply_data->callback);
959 /************************************************************************
961 * CheckRestrictedDir:
962 * Make sure we stay inside a restricted directory
964 ************************************************************************/
968 FileMgrRec * file_mgr_rec,
969 FileMgrData * file_mgr_data,
971 Boolean relative_name)
973 char *tmpStr, directory[MAXPATHLEN];
975 char *tmpBuffer, *title, *msg;
977 /* If not in restricte mode, everything is ok. */
978 if (file_mgr_data->restricted_directory == NULL && !restrictMode)
981 /* get real file name */
984 tmpStr = (char *)XtMalloc(strlen(*value) +
985 strlen(file_mgr_data->restricted_directory) + 3);
986 strcpy(tmpStr, file_mgr_data->restricted_directory);
989 strcat(tmpStr, *value);
993 *value = (char *) DtEliminateDots (*value);
996 && file_mgr_data->toolbox == False )
998 if( strcmp( users_home_dir, "/" ) == 0 )
1000 strcpy( directory, users_home_dir );
1003 strcpy( directory, file_mgr_data->restricted_directory );
1005 len = strlen(directory);
1007 if( len > 1 && directory[len-1] == '/' )
1009 directory[len - 1] = 0x0;
1013 /* check if value is inside the restricted subdir */
1014 len = strlen(directory);
1015 if (strncmp(*value, directory, len) != 0 ||
1016 (*value)[len] != '/' && (*value)[len] != '\0')
1018 tmpBuffer = GetSharedMessage(CHANGE_DIR_ERROR_TITLE);
1019 title = XtNewString(tmpBuffer);
1021 tmpBuffer = GETMESSAGE(2,8, "You cannot switch to this folder. You are\nallowed to view only folders beneath your\ncurrent folder. You cannot specify an absolute\npath to the new folder.");
1023 tmpBuffer = GETMESSAGE(2,9, "This view is in restricted mode. You cannot go\nto the specified folder because it is not in the\nrelative path of the restricted folder.\n");
1024 msg = XtNewString(tmpBuffer);
1026 _DtMessage(file_mgr_rec->current_directory_text, title, msg,
1027 NULL, HelpRequestCB);
1038 /************************************************************************
1041 * This is the activate callback for the FileMgr text field provided
1042 * for quickly changing the current directory being viewed.
1044 ************************************************************************/
1049 XtPointer client_data,
1050 XmAnyCallbackStruct * callback_data )
1052 DialogData * dialog_data;
1053 ChangeDirData * change_dir_data;
1054 ChangeDirRec * change_dir_rec;
1055 FileMgrRec * file_mgr_rec;
1056 FileMgrData * file_mgr_data;
1058 Widget selection_box;
1063 /* Get the change dir data record */
1065 file_mgr_rec = (FileMgrRec *) client_data;
1066 dialog_data = _DtGetInstanceData ((XtPointer)file_mgr_rec);
1067 file_mgr_data = (FileMgrData *) dialog_data->data;
1068 change_dir_data = (ChangeDirData *) file_mgr_data->change_dir->data;
1069 change_dir_rec =(ChangeDirRec *)_DtGetDialogInstance(file_mgr_data->change_dir);
1072 selection_box = change_dir_rec->change_dir;
1074 selection_box = NULL;
1076 value = (char *)XmTextFieldGetString(text_field);
1078 /* check if user attempts to go outside restricted directory */
1079 rc = CheckRestrictedDir (file_mgr_rec, file_mgr_data, &value, True);
1082 This code will de-activate the text widget.
1083 HCI requests that if the switch is not successful, don't de-activate it
1084 so user has a change to go back and correct it without having to pop it
1087 XmProcessTraversal(file_mgr_rec->file_window, XmTRAVERSE_CURRENT);
1088 XtSetArg (args[0], XmNallowShellResize, False);
1089 XtSetValues (file_mgr_rec->shell, args, 1);
1090 XtUnmanageChild(file_mgr_rec->current_directory_text);
1091 XtSetArg (args[0], XmNallowShellResize, True);
1092 XtSetValues (file_mgr_rec->shell, args, 1);
1093 file_mgr_data->fast_cd_enabled = False;
1096 /* Process the string representing a directory to verify */
1097 /* that it is a valid path. */
1100 if( TryToChangeDir(False, value, file_mgr_data, file_mgr_rec,
1101 change_dir_data, selection_box, NULL, NULL,
1103 /* de-activate the text widget */
1104 UnpostTextPath( file_mgr_data );
1111 /************************************************************************
1114 * This is the drop callback for the change-view icon provided
1115 * for quickly changing the current directory being viewed.
1117 ************************************************************************/
1122 XtPointer client_data,
1123 XtPointer call_data)
1125 DtDndDropCallbackStruct *fileList = (DtDndDropCallbackStruct *)call_data;
1126 FileMgrRec *file_mgr_rec;
1127 DialogData * dialog_data;
1128 ChangeDirData * change_dir_data;
1129 ChangeDirRec * change_dir_rec;
1130 FileMgrData * file_mgr_data;
1131 Widget selection_box;
1132 char *full_path_name;
1135 numFiles = fileList->dropData->numItems;
1137 /* if multiple selection, ignore all but the last one */
1139 if (numFiles > 0 && fileList->reason == DtCR_DND_DROP_ANIMATE)
1141 file_mgr_rec = (FileMgrRec *) client_data;
1142 dialog_data = _DtGetInstanceData ((XtPointer)file_mgr_rec);
1143 file_mgr_data = (FileMgrData *) dialog_data->data;
1145 full_path_name = XtNewString(fileList->dropData->data.files[numFiles-1]);
1147 if (CheckRestrictedDir(file_mgr_rec, file_mgr_data,
1148 &full_path_name, False) == 0)
1150 change_dir_data = (ChangeDirData *) file_mgr_data->change_dir->data;
1152 (ChangeDirRec *)_DtGetDialogInstance(file_mgr_data->change_dir);
1154 selection_box = change_dir_rec->change_dir;
1156 selection_box = NULL;
1158 TryToChangeDir(False, full_path_name, file_mgr_data, file_mgr_rec,
1159 change_dir_data, selection_box, NULL, NULL,
1162 XtFree(full_path_name);
1165 fileList->status = DtDND_FAILURE;
1171 FileMgrData * file_mgr_data,
1174 ChangeDirData * change_dir_data;
1177 XmString xm_dir_name;
1179 /* Clear out any selected portion of the old CWD string */
1180 if (file_mgr_data->cd_select != NULL)
1182 XtFree(file_mgr_data->cd_select);
1183 file_mgr_data->cd_select = NULL;
1186 /* Update the internal copy of the dialog history list */
1187 if (file_mgr_data->change_dir)
1189 change_dir_data = (ChangeDirData *) file_mgr_data->change_dir->data;
1190 xm_dir_name = XmStringCreateLocalized(dir_name);
1192 /* Add the directory only if not already in the list */
1193 for (i = 0, found = False; i < change_dir_data->list_count; i++)
1195 if (XmStringCompare(xm_dir_name, change_dir_data->history_list[i]))
1198 XmStringFree(xm_dir_name);
1205 change_dir_data->list_count++;
1206 change_dir_data->history_list = (XmStringTable)
1207 XtRealloc((char *)change_dir_data->history_list,
1208 sizeof(XmStringTable) * (change_dir_data->list_count + 1));
1209 change_dir_data->history_list[change_dir_data->list_count - 1] =
1211 change_dir_data->history_list[change_dir_data->list_count] = NULL;
1214 /* Update view to display the new directory */
1215 ShowNewDirectory(file_mgr_data, change_dir_data->host_name, dir_name);
1221 * Class function for forcing the focus to the text field, each time
1222 * the Change Dir dialog is posted.
1227 ChangeDirRec *change_dir_rec,
1228 ChangeDirData *change_dir_data )
1232 /* Force the focus to the text field */
1233 text = XmSelectionBoxGetChild (change_dir_rec->change_dir, XmDIALOG_TEXT);
1234 XmProcessTraversal(text, XmTRAVERSE_CURRENT);
1238 /***************************************************************************
1240 * TextChange() - callback from editable text widgets when something is
1241 * typed in the text widget. Only used when in restricted mode.
1242 * Used to make sure the users are not going out of their
1243 * "restricted" space.
1245 ****************************************************************************/
1250 XtPointer client_data,
1251 XmTextVerifyCallbackStruct * callback_data )
1253 char *homeDir, *homeDirBackup;
1256 if (callback_data->reason == XmCR_MODIFYING_TEXT_VALUE ||
1257 callback_data->reason == XmCR_MOVING_INSERT_CURSOR )
1259 FileMgrData * file_mgr_data;
1261 file_mgr_data = (FileMgrData *) client_data;
1263 selection = XmTextFieldGetSelection(text);
1265 /* get whats in the text widget */
1266 homeDir = homeDirBackup = XmTextFieldGetString(text);
1268 if(selection != NULL)
1270 if(callback_data->event == NULL)
1271 XmTextFieldClearSelection(text, CurrentTime);
1273 XmTextFieldClearSelection(text, callback_data->event->xkey.time);
1274 callback_data->doit = False;
1276 else if(callback_data->reason == XmCR_MODIFYING_TEXT_VALUE)
1278 /* see if the user is trying to back over the 'restricted'
1279 * text, in this case users_home_dir
1281 if( strcmp( homeDir, "" ) != 0
1282 && strcmp( homeDir, file_mgr_data->restricted_directory ) <= 0 )
1284 if( callback_data->text->length != 0 )
1286 if( strncmp( file_mgr_data->restricted_directory,
1287 callback_data->text->ptr,
1288 strlen(file_mgr_data->restricted_directory)) != 0)
1290 callback_data->doit = True;
1295 callback_data->doit = False;
1303 maxlength = strlen( file_mgr_data->restricted_directory );
1305 if(callback_data->newInsert < maxlength)
1307 if(callback_data->event == NULL)
1308 _XmTextFieldSetDestination((Widget)text,
1309 (Position)callback_data->currInsert, CurrentTime);
1312 _XmTextFieldSetDestination((Widget)text,
1313 (Position)callback_data->currInsert,
1314 callback_data->event->xkey.time);
1315 callback_data->doit = False;
1320 XtFree(homeDirBackup);
1326 ChangeDirectoryToParent(
1327 FileMgrRec * file_mgr_rec,
1330 DialogData * dialog_data;
1331 ChangeDirData * change_dir_data;
1332 ChangeDirRec * change_dir_rec;
1333 FileMgrData * file_mgr_data;
1334 Widget selection_box;
1338 /* Get the change dir data record */
1340 dialog_data = _DtGetInstanceData ((XtPointer)file_mgr_rec);
1341 file_mgr_data = (FileMgrData *) dialog_data->data;
1342 change_dir_data = (ChangeDirData *) file_mgr_data->change_dir->data;
1343 change_dir_rec =(ChangeDirRec *)_DtGetDialogInstance(file_mgr_data->change_dir);
1346 selection_box = change_dir_rec->change_dir;
1348 selection_box = NULL;
1350 /* check if user attempts to go outside restricted directory */
1351 rc = CheckRestrictedDir (file_mgr_rec, file_mgr_data, &directory, True);
1353 /* Process the string representing a directory to verify */
1354 /* that it is a valid path. */
1357 TryToChangeDir(False, directory, file_mgr_data, file_mgr_rec,
1358 change_dir_data, selection_box, NULL, NULL,