2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 /* $XConsortium: Command.c /main/9 1996/10/30 11:09:42 drk $ */
24 /************************************<+>*************************************
25 ****************************************************************************
29 * COMPONENT_NAME: Desktop File Manager (dtfile)
31 * Description: Command processing functions used by the File Browser.
33 * FUNCTIONS: ActionCallback
34 * InvalidTrashDragDrop
36 * ProcessBufferDropOnFolder
41 * UpdateActionMenuPane
43 * (c) Copyright 1993, 1994, 1995 Hewlett-Packard Company
44 * (c) Copyright 1993, 1994, 1995 International Business Machines Corp.
45 * (c) Copyright 1993, 1994, 1995 Sun Microsystems, Inc.
46 * (c) Copyright 1993, 1994, 1995 Novell, Inc.
48 ****************************************************************************
49 ************************************<+>*************************************/
52 #include <sys/types.h>
54 #include <Xm/PushBG.h>
55 #include <Xm/RowColumn.h>
56 #include <Xm/SeparatoG.h>
58 #include <X11/Shell.h>
59 #include <X11/Intrinsic.h>
61 #include <Dt/Action.h>
62 #include <Dt/ActionP.h>
63 #include <Dt/Connect.h>
64 #include <Dt/DtNlUtils.h>
65 #include <Dt/HourGlass.h>
69 #include "SharedProcs.h"
74 #include "SharedMsgs.h"
77 /******** Static Function Declarations ********/
79 static void ActionCallback( Widget w,
80 XtPointer client_data,
81 XtPointer call_data) ;
82 static void TimerEvent(
85 void ProcessBufferDropOnFolder (
87 FileMgrData *file_mgr_data,
88 FileViewData *file_view_data,
89 DtDndDropCallbackStruct *drop_parameters,
93 /******** End Static Function Declarations ********/
95 extern int G_dropx,G_dropy;
97 /************************************************************************
99 * UpdateActionMenuPane
100 * Build up a set of menu panes for the provided file manager rec
101 * that contains as items each of the commands for each file type.
103 ************************************************************************/
106 UpdateActionMenuPane(
107 XtPointer client_data,
108 FileMgrRec *file_mgr_rec,
113 unsigned char physical_type)
115 XmManagerWidget action_pane;
116 FileMgrData *file_mgr_data = NULL;
117 DialogData * dialog_data;
118 FileViewData *file_view_data;
119 DesktopRec *desktopWindow;
121 register int i, menu_offset;
122 register int action_count;
123 int count, del_count;
125 char ** command_list;
133 desktopWindow = (DesktopRec *)client_data;
134 else if(type == FM_POPUP)
135 file_view_data = (FileViewData *)client_data;
139 dialog_data = _DtGetInstanceData ((XtPointer)file_mgr_rec);
140 file_mgr_data = (FileMgrData *) dialog_data->data;
143 /* Count the number of actions defined for the the file type */
146 command_list = _DtCompileActionVector(file_type);
148 if(command_list != NULL)
149 while (command_list[action_count] != NULL &&
150 strlen (command_list[action_count]) != 0)
153 if (physical_type == DtDIRECTORY && type == DESKTOP)
157 /* If the menu pane is already set up for the file type then return. */
159 if(type == NOT_DESKTOP)
161 XtFree(file_mgr_rec->action_pane_file_type);
162 file_mgr_rec->action_pane_file_type = XtNewString(file_type);
164 action_pane = (XmManagerWidget) file_mgr_rec->action_pane;
165 menu_offset = number + SELECTED_MENU_MAX;
169 action_pane = (XmManagerWidget) widget;
170 menu_offset = number;
173 num_children = action_pane->composite.num_children;
176 * This is so that we can determine which icon was responsible for
177 * posting the menu, or requesting help.
179 if (type == FM_POPUP)
180 file_mgr_data->popup_menu_icon = file_view_data;
182 else if (file_mgr_data)
183 file_mgr_data->popup_menu_icon = NULL;
186 if (action_count + menu_offset > num_children)
189 for (i = number; i < num_children; i++)
190 XtManageChild (action_pane->composite.children[i]);
191 for (i = num_children; i < action_count + menu_offset; i++)
193 child = XmCreatePushButtonGadget ((Widget)action_pane,
194 "action_button", args, 0);
197 XtAddCallback (child, XmNactivateCallback, DTActionCallback,
198 (XtPointer)desktopWindow);
199 XtAddCallback(child, XmNhelpCallback,
200 (XtCallbackProc)DTHelpRequestCB, NULL);
202 else if(type == FM_POPUP)
204 XtAddCallback (child, XmNactivateCallback, ActionCallback, NULL);
205 XtAddCallback(child, XmNhelpCallback,
206 (XtCallbackProc)HelpRequestCB, NULL);
210 XtAddCallback (child, XmNactivateCallback, ActionCallback,
211 (XtPointer)file_mgr_rec);
212 XtAddCallback(child, XmNhelpCallback,
213 (XtCallbackProc)HelpRequestCB, NULL);
215 XtManageChild (child);
220 for (i = menu_offset; i < num_children; i++)
222 if (i < action_count + menu_offset)
224 XtRemoveAllCallbacks(action_pane->composite.children[i],
225 XmNactivateCallback);
227 XtAddCallback (action_pane->composite.children[i],
228 XmNactivateCallback, DTActionCallback,
229 (XtPointer)desktopWindow);
230 else if(type == FM_POPUP)
231 XtAddCallback (action_pane->composite.children[i],
232 XmNactivateCallback, ActionCallback, NULL);
234 XtAddCallback (action_pane->composite.children[i],
235 XmNactivateCallback, ActionCallback,
236 (XtPointer)file_mgr_rec);
237 XtManageChild (action_pane->composite.children[i]);
240 XtUnmanageChild (action_pane->composite.children[i]);
244 /* For each action, set the label of the menu button */
245 /* and the user data. */
247 num_children = menu_offset + action_count;
249 for (i = 0; i < action_count; i++)
258 strp = XtNewString(command_list[i]);
259 XtSetArg (args[1], XmNuserData, strp);
261 action_label = DtActionLabel(command_list[i]);
263 if(action_label != NULL)
264 string = XmStringCreateLocalized(action_label);
266 string = XmStringCreateLocalized(command_list[i]);
268 count = i + menu_offset;
272 if (physical_type == DtDIRECTORY && i == 0)
274 if((action_label = DtActionLabel(openNewView)) != NULL)
275 string = XmStringCreateLocalized(action_label);
277 string = XmStringCreateLocalized(openNewView);
278 XtSetArg (args[1], XmNuserData, openNewView);
283 if (physical_type == DtDIRECTORY)
285 if(strcmp(command_list[i - 1], openNewView) == 0 ||
286 strcmp(command_list[i - 1], openInPlace) == 0)
289 XtUnmanageChild (action_pane->composite.children[
290 num_children - del_count]);
293 action_label = DtActionLabel(command_list[i - 1]);
295 if(action_label != NULL)
296 string = XmStringCreateLocalized(action_label);
298 string = XmStringCreateLocalized(command_list[i-1]);
300 XtSetArg (args[1], XmNuserData, XtNewString
301 (command_list[i - 1]));
302 count = i + number - del_count;
306 action_label = DtActionLabel(command_list[i]);
308 if(action_label != NULL)
309 string = XmStringCreateLocalized(action_label);
311 string = XmStringCreateLocalized(command_list[i]);
313 XtSetArg (args[1], XmNuserData, XtNewString(command_list[i]));
319 /* first we need to get the userData from the push button and
321 XtSetArg (argsTmp[0], XmNuserData, &oldCommand);
322 XtGetValues (action_pane->composite.children[count], argsTmp, 1);
324 if(oldCommand != NULL && strcmp(oldCommand, openNewView) != 0)
328 XtSetArg (args[0], XmNlabelString, string);
329 XtSetValues (action_pane->composite.children[count], args, 2);
330 if(type != NOT_DESKTOP)
332 XtRemoveAllCallbacks(action_pane->composite.children[count],
333 XmNactivateCallback);
337 XtAddCallback (action_pane->composite.children[count],
338 XmNactivateCallback, DTActionCallback,
339 (XtPointer)desktopWindow);
342 XtAddCallback (action_pane->composite.children[count],
343 XmNactivateCallback, ActionCallback,
346 XmStringFree (string);
347 XtFree(action_label);
350 _DtFreeStringVector(command_list);
356 /************************************************************************
359 * Callback function invoked upon the an actions menu button
362 ************************************************************************/
367 XtPointer client_data,
368 XtPointer call_data )
370 FileMgrRec * file_mgr_rec;
371 DialogData * dialog_data;
372 FileMgrData * file_mgr_data;
373 FileViewData * file_view_data;
377 Boolean popup = False;
378 XmAnyCallbackStruct * callback;
384 callback = (XmAnyCallbackStruct *) call_data;
385 if(client_data == NULL)
388 XtSetArg(args[0], XmNuserData, &file_mgr_rec);
389 XtGetValues(mbar, args, 1);
390 dialog_data = _DtGetInstanceData ((XtPointer)file_mgr_rec);
391 file_mgr_data = (FileMgrData *) dialog_data->data;
392 file_view_data = file_mgr_data->popup_menu_icon;
393 if(!file_view_data) /* The object would have probably been delete */
395 file_mgr_data->popup_menu_icon = NULL; /* Just to make it unuseful */
399 file_mgr_rec = (FileMgrRec *) client_data;
400 dialog_data = _DtGetInstanceData ((XtPointer)file_mgr_rec);
401 file_mgr_data = (FileMgrData *) dialog_data->data;
406 /* Find the file data for the file that is selected */
408 XtSetArg (args[0], XmNuserData, (XtPointer) &command);
409 XtGetValues (w, args, 1);
411 if(strcmp(command, openNewView) == 0)
413 XButtonEvent *event = (XButtonEvent *)callback->event;
414 unsigned int modifiers;
416 modifiers = event->state;
418 RunCommand (command, file_mgr_data, file_view_data, NULL, NULL, NULL);
420 RunCommand (command, file_mgr_data, file_mgr_data->selection_list[0],
423 if((modifiers != 0) && ((modifiers & ControlMask) != 0))
425 DialogData *dialog_data;
427 dialog_data = _DtGetInstanceData(file_mgr_data->file_mgr_rec);
428 CloseView(dialog_data);
434 RunCommand (command, file_mgr_data, file_view_data, NULL, NULL, NULL);
436 RunCommand (command, file_mgr_data, file_mgr_data->selection_list[0],
442 /************************************************************************
446 * WARNING: when desktop links are passed in, this function will NOT
447 * expect the links to have already been mapped to their
450 ************************************************************************/
455 FileMgrData *file_mgr_data,
456 FileViewData *file_view_data,
457 WindowPosition *position,
458 DtDndDropCallbackStruct *drop_parameters,
462 if ((strcmp (command, openInPlace) == 0) ||
463 (strcmp (command, openNewView) == 0))
465 /* If the folder is locked, don't allow user to go into it */
466 if( strcmp( file_view_data->file_data->logical_type, LT_FOLDER_LOCK ) == 0 )
468 char *tmpStr, *title, *msg;
470 tmpStr = GETMESSAGE(9, 6, "Action Error");
471 title = XtNewString(tmpStr);
472 msg = (char *)XtMalloc(
473 strlen( GETMESSAGE(30, 1, "Cannot read from %s") )
474 + strlen( file_view_data->file_data->file_name )
476 sprintf( msg, GETMESSAGE(30, 1, "Cannot read from %s"),
477 file_view_data->file_data->file_name );
478 _DtMessage(((FileMgrRec*)file_mgr_data->file_mgr_rec)->file_window,
479 title, msg, NULL, HelpRequestCB );
485 /* this statement applies to the case where a user traverses down the *
486 * part of the directory tree containing the application manager *
487 * directories or the trash directory */
488 if( ((strcmp(file_view_data->file_data->logical_type, LT_AGROUP) == 0) &&
489 (!(file_mgr_data->toolbox)))
491 (strcmp(file_view_data->file_data->logical_type, LT_TRASH) == 0) )
493 ProcessAction(command,
497 file_mgr_data->current_directory,
498 file_mgr_data->restricted_directory,
499 ((FileMgrRec *) file_mgr_data->file_mgr_rec)->shell);
503 ProcessNewView(command, file_mgr_data, file_view_data, position);
507 else if ((strcmp (command, "FILESYSTEM_MOVE") == 0) ||
508 (strcmp (command, "FILESYSTEM_COPY") == 0) ||
509 (strcmp (command, "FILESYSTEM_LINK") == 0))
511 /* Check to see what was dropped (files or buffers) */
512 /* Call the appropriate routine to handle the drop */
513 if (drop_parameters->dropData->protocol == DtDND_FILENAME_TRANSFER)
514 ProcessMoveCopyLink(command,
520 if (drop_parameters->dropData->protocol == DtDND_BUFFER_TRANSFER)
521 ProcessBufferDropOnFolder(command,
531 ProcessAction(command,
535 file_mgr_data->current_directory,
536 file_mgr_data->restricted_directory,
537 ((FileMgrRec *) file_mgr_data->file_mgr_rec)->shell);
542 /************************************************************************
546 ************************************************************************/
551 FileMgrData *file_mgr_data,
552 FileViewData *file_view_data,
553 WindowPosition *position)
555 DirectorySet * directory_set;
556 char host_name[MAX_PATH];
557 char directory_name[MAX_PATH];
558 char *tmpStr, *title, *msg;
560 /* we don't want to execute the default action if in trash ... */
561 if( trashFileMgrData != NULL
562 && file_mgr_data == trashFileMgrData)
564 tmpStr = GETMESSAGE(27, 3, "Trash Can Error");
565 title = XtNewString(tmpStr);
566 tmpStr = GETMESSAGE(27, 87, "Object in the Trash cannot be opened.\n\nTo open an object use 'Put Back' to return it to the\nFile Manager then open it there.");
567 msg = XtNewString(tmpStr);
569 _DtMessage( ((FileMgrRec *)file_mgr_data->file_mgr_rec)->file_window,
570 title, msg, NULL, HelpRequestCB);
576 strcpy (host_name, file_mgr_data->host);
578 directory_set = (DirectorySet *) (file_view_data->directory_set);
579 strcpy (directory_name, directory_set->name);
581 if (strcmp (directory_name, "/") != 0)
582 strcat (directory_name, "/");
584 strcat (directory_name, file_view_data->file_data->file_name);
585 DtEliminateDots (directory_name);
587 if (strcmp (directory_name, "/..") == 0)
588 strcpy (directory_name, "/");
590 if (strcmp (command, openInPlace) == 0)
592 FileMgrRec *file_mgr_rec;
595 int value, size, increment, page;
597 file_mgr_rec = (FileMgrRec *)file_mgr_data->file_mgr_rec;
598 ShowNewDirectory (file_mgr_data, host_name, directory_name);
600 XtSetArg (args[0], XmNverticalScrollBar, &vb);
601 XtGetValues (file_mgr_rec->scroll_window, args, 1);
603 /* get scroll bar values */
604 (void)XmScrollBarGetValues(vb, &value, &size, &increment, &page);
606 /* set scroll bar values changing its position */
608 (void)XmScrollBarSetValues(vb, (int)0, size, increment, page, True);
610 if(strcmp(file_mgr_data->current_directory,
611 file_mgr_data->restricted_directory) == 0)
613 XtSetSensitive(*upBarBtn, False);
614 currentMenuStates &= ~(MOVE_UP);
615 file_mgr_rec->menuStates &= ~(MOVE_UP);
619 file_mgr_rec->menuStates |= MOVE_UP;
620 XtSetSensitive(*upBarBtn, True);
621 currentMenuStates &= ~(MOVE_UP);
626 initiating_view = (XtPointer) file_mgr_data;
627 if(file_mgr_data->restricted_directory == NULL)
629 GetNewView (host_name, directory_name, NULL, position, 0);
634 special_treeType = file_mgr_data->show_type;
635 special_viewType = file_mgr_data->view;
636 special_orderType = file_mgr_data->order;
637 special_directionType = file_mgr_data->direction;
638 special_randomType = file_mgr_data->positionEnabled;
640 XtNewString(file_mgr_data->restricted_directory);
641 if(file_mgr_data->title == NULL)
642 special_title = NULL;
644 special_title = XtNewString(file_mgr_data->title);
645 special_helpVol = XtNewString(file_mgr_data->helpVol);
646 if(file_mgr_data->toolbox)
647 GetNewView (file_mgr_data->host, directory_name,
648 file_mgr_data->restricted_directory, position, 0);
650 GetNewView (file_mgr_data->host, directory_name, NULL, position, 0);
653 initiating_view = (XtPointer) NULL;
658 /************************************************************************
660 * ProcessMoveCopyLink
662 ************************************************************************/
665 ProcessMoveCopyLink (
667 FileMgrData *file_mgr_data,
668 FileViewData *file_view_data,
669 DtDndDropCallbackStruct *drop_parameters,
673 unsigned int modifiers = NULL;
675 char ** file_set = NULL;
676 char ** host_set = NULL;
680 /***************************************************/
681 /* if no drop_parameters, there is nothing to move */
682 /***************************************************/
683 if (!drop_parameters)
687 /**************************/
688 /* are these trash files? */
689 /**************************/
690 trashFile = FileFromTrash(drop_parameters->dropData->data.files[0]);
693 /***********************************************/
694 /* if trying to copy or link from trash return */
695 /***********************************************/
698 if (file_mgr_data != trashFileMgrData)
699 if (InvalidTrashDragDrop(drop_parameters->operation,
701 ((FileMgrRec *)file_mgr_data->file_mgr_rec)->file_window))
706 /***************************************************/
707 /* extract file and host sets from drop parameters */
708 /***************************************************/
709 numFiles = drop_parameters->dropData->numItems;
710 _DtSetDroppedFileInfo(drop_parameters, &file_set, &host_set);
713 /******************************/
714 /* set movement modifier mask */
715 /******************************/
716 if( (initiating_view != NULL) &&
717 (((FileMgrData *)initiating_view)->toolbox) )
719 /* if initiating_view is a toolbox, the transfer must be */
721 modifiers = ControlMask;
725 if (strcmp(command, "FILESYSTEM_COPY") == 0)
726 modifiers = ControlMask;
727 else if (strcmp(command, "FILESYSTEM_LINK") == 0)
728 modifiers = ShiftMask;
734 /*****************************/
735 /* Files dropped on a window */
736 /*****************************/
739 /****************************************************************/
740 /* Files dropped in the trash -- move files to trash directory */
741 /****************************************************************/
742 if(file_mgr_data == trashFileMgrData && !trashFile)
744 DPRINTF(("DropOnFileWindow:Dragging File(s) to Trash Can from NonTrash Window\n"));
746 DropOnTrashCan(numFiles, host_set, file_set, drop_parameters);
749 /****************************************************************/
750 /* Files dragged in the trash -- do nothing */
751 /****************************************************************/
752 else if(file_mgr_data == trashFileMgrData && trashFile)
754 DPRINTF(("DropOnFileWindow: Drag from Within Trash Can\n"));
757 /****************************************************************/
758 /* Files dragged from the trash -- move the files to their new */
760 /****************************************************************/
761 else if(trashFile && file_mgr_data != trashFileMgrData)
763 DPRINTF(("DropOnFileWindow: Dragging from Trash to Folder Window\n"));
765 MoveOutOfTrashCan(file_mgr_data,
766 (FileMgrRec *)file_mgr_data->file_mgr_rec,
767 XtWindow(drop_window), numFiles, host_set,
768 file_set, drop_parameters->x, drop_parameters->y);
772 /****************************************************************/
773 /* Files dropped on a non-trash window -- move files to new */
776 /* Droppable windows must be handled like the desktop; i.e. */
777 /* positioning is supported. */
778 /****************************************************************/
781 FileMgrRec *file_mgr_rec = (FileMgrRec *)file_mgr_data->file_mgr_rec;
784 if ((file_mgr_data->show_type == SINGLE_DIRECTORY) &&
785 (file_mgr_data->view != BY_ATTRIBUTES))
788 if (file_mgr_data == (FileMgrData *) initiating_view)
790 DPRINTF(("DropOnFileWindow: Dragging and Dropping File within same window\n"));
792 /* Simple reposition in the same window */
793 XmDropSiteStartUpdate(file_mgr_rec->file_window);
794 RepositionIcons(file_mgr_data,
797 drop_parameters->x, drop_parameters->y,
799 LayoutFileIcons(file_mgr_rec, file_mgr_data, False, True);
800 XmDropSiteEndUpdate(file_mgr_rec->file_window);
804 DPRINTF (("DropOnFileWindow: Dragging file(s) and dropping from other folders\n"));
806 CheckMoveType(file_mgr_data, (FileViewData *)NULL,
807 (DirectorySet *)NULL, (DesktopRec *)NULL,
808 file_set, host_set, modifiers,
810 drop_parameters->x, drop_parameters->y,
817 DPRINTF(("DropOnFileWindow: Not Single Directory View\n"));
819 if (FileMoveCopy (file_mgr_data,
820 NULL, file_mgr_data->current_directory, file_mgr_data->host,
821 host_set, file_set, numFiles,
822 modifiers, NULL, NULL))
824 DirectorySet * directory_data;
825 char * directory_name;
826 FileViewData * file_view_data;
829 DeselectAllFiles (file_mgr_data);
831 directory_data = file_mgr_data->directory_set[0];
832 for (i = 0; i < numFiles; i++)
834 directory_name = DName (file_set[i]);
835 for (j = 0; j < directory_data->file_count; j++)
837 file_view_data = directory_data->file_view_data[j];
838 if ( (file_view_data->filtered != True) &&
839 (strcmp(directory_name,
840 file_view_data->file_data->file_name) == 0) )
842 SelectFile (file_mgr_data, file_view_data);
848 PositionFileView(file_view_data, file_mgr_data);
853 if (file_mgr_data->selected_file_count == 0)
854 ActivateNoSelect (file_mgr_rec);
855 else if (file_mgr_data->selected_file_count == 1)
858 file_mgr_data->selection_list[0]->file_data->logical_type);
860 ActivateMultipleSelect (file_mgr_rec);
864 /*****************************/
865 /* Files dropped on an icon */
866 /*****************************/
869 CheckMoveType(file_mgr_data, file_view_data,
870 (DirectorySet *) file_view_data->directory_set,
872 file_set, host_set, modifiers,
873 numFiles, drop_parameters->x, drop_parameters->y,
877 /***************************/
878 /* free file and host sets */
879 /***************************/
880 _DtFreeDroppedFileInfo(numFiles, file_set, host_set);
884 /************************************************************************
886 * ProcessBufferDropOnFolder
888 ************************************************************************/
891 ProcessBufferDropOnFolder (
893 FileMgrData *file_mgr_data,
894 FileViewData *file_view_data,
895 DtDndDropCallbackStruct *drop_parameters,
899 unsigned int modifiers = NULL;
900 int num_of_buffers, i;
901 char ** file_set = NULL;
902 char ** host_set = NULL;
903 BufferInfo *buffer_set = NULL;
904 char directory[MAX_PATH];
909 /***************************************************/
910 /* if no drop_parameters, or invalid params */
911 /* then disallow the drop */
912 /***************************************************/
913 if (!drop_parameters)
916 /* if dropped on file window and file_mgr_data is null */
917 if (drop_window && (file_mgr_data == NULL))
920 /* if dropped on a folder icon and file_view_data */
921 /* is NULL, disallow the drop */
922 if (!drop_window && (file_view_data == NULL))
929 /****************************************************/
930 /* extract file and host sets from drop parameters */
931 /* @@@...need to check with Linda about how host_set*/
932 /* is being handled */
933 /****************************************************/
935 num_of_buffers = drop_parameters->dropData->numItems;
937 /* Allocate memory for file and buffer structures */
938 file_set = (char **)XtMalloc(sizeof(char **) * num_of_buffers );
939 host_set = (char **)XtMalloc(sizeof(char **) * num_of_buffers);
940 buffer_set = (BufferInfo * )XtMalloc (sizeof (BufferInfo) * num_of_buffers);
943 _DtSetDroppedBufferInfo(file_set, buffer_set, host_set, drop_parameters);
948 /*****************************************************/
949 /* If buffers were dropped on the window, determine */
950 /* which MODE (AS PLACED, GRID, TREE VIEW) and call */
951 /* the appropriate routines to handle the creation */
952 /* of the buffers into files. Assuming dropping */
953 /* on non-trash windows. */
954 /*****************************************************/
959 /* Single directory view */
960 if ((file_mgr_data->show_type == SINGLE_DIRECTORY ) &&
961 (file_mgr_data->view != BY_ATTRIBUTES))
965 DPRINTF (("ProcessDropOnBufferFolder: Dropping buffers on single directory view: %s\n", file_mgr_data->current_directory));
967 G_dropx = drop_parameters->x;
968 G_dropy = drop_parameters->y;
970 /* Reposition Icons if in in "AS PLACED" Mode */
971 if (file_mgr_data -> positionEnabled == RANDOM_ON)
974 RepositionIcons (file_mgr_data,
977 drop_parameters->x, drop_parameters->y,
982 /* Call MakeFileFromBuffer */
983 MakeFilesFromBuffers(file_mgr_data, file_mgr_data->current_directory,
984 file_mgr_data->host, file_set,
985 host_set, buffer_set, num_of_buffers,
991 DPRINTF (("ProcessDropOnBufferFolder: Dropping buffers in Tree View\n"));
993 MakeFilesFromBuffers(file_mgr_data, file_mgr_data->current_directory,
994 file_mgr_data->host, file_set,
995 host_set, buffer_set, num_of_buffers,
998 /* Do Tree View Stuff */
1000 DirectorySet * directory_data;
1001 char * directory_name;
1002 FileViewData * file_view_data;
1005 DeselectAllFiles (file_mgr_data);
1007 directory_data = file_mgr_data->directory_set[0];
1008 for (i = 0; i < num_of_buffers; i++)
1010 directory_name = DName (file_set[i]);
1011 for (j = 0; j < directory_data->file_count; j++)
1013 file_view_data = directory_data->file_view_data[j];
1014 if ( (file_view_data->filtered != True) &&
1015 (strcmp(directory_name,
1016 file_view_data->file_data->file_name) == 0) )
1018 SelectFile (file_mgr_data, file_view_data);
1023 PositionFileView(file_view_data, file_mgr_data);
1025 } /* endif for Tree View */
1027 } /* endif drop buffers on window */
1030 /* Buffers were dropped on a Folder icon */
1031 /* Call MakeFileFromBuffer */
1034 DPRINTF(("ProcessBufferDropOnFolder...Buffers dropped on Folder icon %s\n",
1035 file_view_data ->file_data -> file_name));
1037 if (file_mgr_data->show_type != SINGLE_DIRECTORY &&
1038 file_mgr_data->tree_root == file_view_data)
1040 /* dropped on the top level folder in the tree view */
1041 sprintf (directory,"%s",file_mgr_data->current_directory);
1044 sprintf (directory,"%s/%s",file_mgr_data->current_directory,
1045 file_view_data->file_data->file_name);
1046 DtEliminateDots(directory);
1048 DPRINTF (("Copying buffer to %s\n", directory));
1049 MakeFilesFromBuffers(file_mgr_data, directory,
1050 file_mgr_data->host, file_set,
1051 host_set, buffer_set, num_of_buffers,
1057 /***********************************/
1058 /* free file_set + buffer_set */
1059 /***********************************/
1060 _DtFreeDroppedBufferInfo (file_set, buffer_set, host_set, num_of_buffers);
1066 /************************************************************************
1068 * InvalidTrashDragDrop
1070 ************************************************************************/
1073 InvalidTrashDragDrop (
1080 if ( (drag_op == XmDROP_COPY) ||
1081 (drag_op == XmDROP_LINK) )
1083 char *tmpStr, *title, *msg;
1085 tmpStr = GETMESSAGE(18, 22, "Drag Error");
1086 title = XtNewString(tmpStr);
1088 switch(trash_context)
1092 tmpStr = (GETMESSAGE(18,36, "You can't copy or link a file or folder out of the Trash Can.\nMove the object out of the Trash and put it into the File Manager.\nYou can then copy or link it from there."));
1095 tmpStr = (GETMESSAGE(18,37, "You can't copy or link a file or folder out of the Trash Can.\nMove the object out of the Trash and put it into the File Manager.\nYou can then copy or link it from there."));
1104 msg = XtNewString(tmpStr);
1105 _DtMessage (w, title, msg, NULL, HelpRequestCB);
1118 /************************************************************************
1122 ************************************************************************/
1127 FileViewData *file_view_data,
1128 DtDndDropCallbackStruct *drop_parameters,
1131 char *restricted_dir,
1135 FileViewData *first_arg = NULL;
1136 DtActionArg * action_args = NULL;
1138 char * pwd_host = NULL;
1139 char * pwd_dir = NULL;
1140 DirectorySet *directory_set;
1141 FileMgrData *file_mgr_data;
1143 /* We don't want to execute the default action if in trash ... */
1144 directory_set = (DirectorySet *) file_view_data->directory_set;
1145 file_mgr_data = (FileMgrData *) directory_set->file_mgr_data;
1146 if( trashFileMgrData != NULL
1147 && file_mgr_data == trashFileMgrData)
1149 char *tmpStr, *title, *msg;
1151 /* we don't want to execute the default action if in trash ... */
1152 tmpStr = GETMESSAGE(27, 3, "Trash Can Error");
1153 title = XtNewString(tmpStr);
1154 tmpStr = GETMESSAGE(27, 105, "Default action of a trash object will not be executed.\n\nTo execute the default action of this object\n use 'Put Back' to return it to the File Manager\nthen execute it there.");
1155 msg = XtNewString(tmpStr);
1157 _DtMessage(((FileMgrRec *)file_mgr_data->file_mgr_rec)->file_window,
1158 title, msg, NULL, HelpRequestCB);
1164 /* Build action arguments:
1165 * First, test for redundant action information --
1166 * file_view_data contains information for the object that the user
1167 * a) dropped files on
1168 * b) activated a popup menu over (note that the Actions piece
1169 * of both the Selected and popup menus is only active when
1170 * a single file is selected; therefore, this function doesn't
1171 * deal with cases where multiple files are selected and a
1172 * popup menu is activated
1173 * c) doubled-clicked
1175 * If file_view_data contains information for the action that we
1176 * are processing, then this information is not included as an
1177 * argument to DtActionInvoke; otherwise, the information is
1178 * included as the first argument to DtActionInvoke.
1180 if ( !DtDtsDataTypeIsAction(file_view_data->file_data->logical_type) ||
1181 (strcmp(action, file_view_data->file_data->logical_type) != 0) ||
1182 (strcmp(action, file_view_data->file_data->file_name) != 0) )
1183 first_arg = file_view_data;
1185 if (drop_parameters)
1187 if (drop_parameters->dropData->protocol == DtDND_FILENAME_TRANSFER)
1188 _DtBuildActionArgsWithDroppedFiles(first_arg, drop_parameters,
1189 &action_args, &arg_count);
1191 _DtBuildActionArgsWithDroppedBuffers(first_arg, drop_parameters,
1192 &action_args, &arg_count);
1197 _DtBuildActionArgsWithSelectedFiles(&first_arg, 1,
1198 &action_args, &arg_count);
1202 /* Retrieve context dir for action -- in the case of toolboxes, the
1204 SetPWD(cur_host, cur_dir, &pwd_host, &pwd_dir, restricted_dir);
1207 /* Turn on hour glass */
1208 _DtTurnOnHourGlass(w);
1212 DtActionInvoke(w, action, action_args, arg_count,
1213 NULL, NULL, pwd_dir, True, NULL, NULL);
1216 /* Add timer event to turn off hour glass */
1217 XtAppAddTimeOut(XtWidgetToApplicationContext(w), 1500,
1218 (XtTimerCallbackProc) TimerEvent, (XtPointer) w);
1223 _DtFreeActionArgs(action_args, arg_count);
1227 /************************************************************************
1230 * This function is called when dtfile does an _DtActionInvoke. All
1231 * it does is turn off the Hourglass cursor.
1233 ************************************************************************/
1240 _DtTurnOffHourGlass (widget);
1243 /************************************************************************
1245 * This Handle's the FILESYSTEM_MOVE, FILESYSTEM_COPY, or FILESYSTEM_LINK
1246 * ToolTalk messages. The operation type is passed in via opType. It is
1247 * either MOVE_FILE, COPY_FILE, or LINK_FILE. Arg 0 of the ToolTalk message
1248 * contains the folder the operation is taking place TO and arg 1 contains
1249 * the files that the operation is happening to.
1251 ************************************************************************/
1254 MoveCopyLinkHandler(
1258 struct stat fileInfo;
1261 char *ptr, *toName, *fileNames = NULL, *type = NULL, *fileList;
1263 char ** file_set = NULL;
1264 char ** host_set = NULL;
1265 unsigned int modifiers = NULL;
1267 int file_set_size = 0;
1270 toName = tt_message_file( ttMsg );
1271 fileNames = fileList = tt_message_arg_val( ttMsg, 1 );
1273 if( tt_is_err( tt_ptr_error( toName ) ) )
1274 { /* No file name */
1275 tt_message_reply( ttMsg );
1276 tttk_message_destroy( ttMsg );
1280 /* let's loop through the fileName passed to get the files which the
1281 * operation is to happen on. The file's are separated by spaces. What
1282 * happens if a file has a space in it: We parse on the spaces and if the
1283 * next char after a space is a '/' then we assume that is the end of the
1284 * file name. What this implies is that this won't work for files with
1285 * spaces at the end of the name
1289 /* build the arrary of char pointer's */
1290 if (file_count == file_set_size)
1292 file_set_size += 10;
1294 (char **) XtRealloc ((char *)file_set,
1295 sizeof (char **) * file_set_size);
1298 /* find the next space */
1299 ptr = DtStrchr(fileList, ' ');
1301 /* if ptr is NULL, we have our last file name (no spaces found) */
1304 file_set[file_count] = XtNewString(fileList);
1310 /* Let's check if the next char is a '/'. If it is then we know it's
1311 * the next file name, else the space found is part of a filename.
1316 file_set[file_count] = XtNewString(fileList);
1324 /* go clean up all the '.' and '..' */
1325 for(i = 0; i < file_count; i++)
1326 DtEliminateDots( file_set[i] );
1327 DtEliminateDots( toName );
1329 /* Set up the modifier key's */
1330 if( opType == MOVE_FILE)
1332 else if ( opType == COPY_FILE)
1333 modifiers = ControlMask;
1335 modifiers = ShiftMask;
1339 * Let's check make sure the Folder the operation is happening to exists.
1341 if( stat( toName, &fileInfo ) != 0
1342 && lstat( toName, &fileInfo ) != 0 )
1343 { /* to directory does not exist */
1346 if(opType == MOVE_FILE)
1348 dialogTitle = XtNewString(GETMESSAGE(33, 3, "Move Object Error"));
1349 sprintf(title, GETMESSAGE(33, 6, "The location you are trying to Move to:\n\n %s\n\ndoes not exist in the file system."), toName);
1351 else if(opType == COPY_FILE)
1353 dialogTitle = XtNewString(GETMESSAGE(33, 4, "Copy Object Error"));
1354 sprintf(title, GETMESSAGE(33, 7, "The location you are trying to Copy to:\n\n %s\n\ndoes not exist in the file system."), toName);
1358 dialogTitle = XtNewString(GETMESSAGE(33, 5, "Link Object Error"));
1359 sprintf(title, GETMESSAGE(33, 8, "The location you are trying to Link to:\n\n %s\n\ndoes not exist in the file system."), toName);
1361 _DtMessage( toplevel, dialogTitle, title, NULL, HelpRequestCB );
1364 tt_message_reply( ttMsg );
1365 tttk_message_destroy( ttMsg );
1371 * Let's check make sure the object the operation is happening to is a
1374 if ((fileInfo.st_mode & S_IFMT) != S_IFDIR) /* target not directory */
1375 { /* File that the user is doing the operation to is not a directory */
1378 if(opType == MOVE_FILE)
1380 dialogTitle = XtNewString(GETMESSAGE(33, 3, "Move Object Error"));
1381 sprintf(title, GETMESSAGE(33, 9, "The location you are trying to Move to:\n\n %s\n\nis not a folder."), toName);
1383 else if(opType == COPY_FILE)
1385 dialogTitle = XtNewString(GETMESSAGE(33, 4, "Copy Object Error"));
1386 sprintf(title, GETMESSAGE(33, 10, "The location you are trying to Copy to:\n\n %s\n\nis not a folder."), toName);
1390 dialogTitle = XtNewString(GETMESSAGE(33, 5, "Link Object Error"));
1391 sprintf(title, GETMESSAGE(33, 11,"The location you are trying to Link to:\n\n %s\n\nis not a folder."), toName);
1393 _DtMessage( toplevel, dialogTitle, title, NULL, HelpRequestCB );
1396 tt_message_reply( ttMsg );
1397 tttk_message_destroy( ttMsg );
1405 for(i = 0; i < file_count; i++)
1407 if( stat( file_set[i], &fileInfo ) != 0
1408 && lstat( file_set[i], &fileInfo ) != 0 )
1409 { /* File does not exist */
1412 if(opType == MOVE_FILE)
1414 dialogTitle = XtNewString(GETMESSAGE(33, 3, "Move Object Error"));
1416 sprintf(title, GETMESSAGE(33, 12, "The object you are trying to Move:\n\n %s\n\ndoes not exist in the file system."), file_set[i]);
1418 sprintf(title, GETMESSAGE(33, 13, "One of the objects you are trying to Move:\n\n %s\n\ndoes not exist in the file system.\nNot Moving any of them."), file_set[i]);
1420 else if(opType == COPY_FILE)
1422 dialogTitle = XtNewString(GETMESSAGE(33, 4, "Copy Object Error"));
1424 sprintf(title, GETMESSAGE(33, 14, "The object you are trying to Copy:\n\n %s\n\ndoes not exist in the file system."), file_set[i]);
1426 sprintf(title, GETMESSAGE(33, 15, "One of the objects you are trying to Copy:\n\n %s\n\ndoes not exist in the file system.\nNot Copying any of them."), file_set[i]);
1430 dialogTitle = XtNewString(GETMESSAGE(33, 5, "Link Object Error"));
1432 sprintf(title, GETMESSAGE(33, 16, "The object you are trying to Link:\n\n %s\n\ndoes not exist in the file system."), file_set[i]);
1434 sprintf(title, GETMESSAGE(33, 17, "One of the objects you are trying to Link:\n\n %s\n\ndoes not exist in the file system.\nNot Linking any of them."), file_set[i]);
1436 _DtMessage( toplevel, dialogTitle, title, NULL, HelpRequestCB );
1439 tt_message_reply( ttMsg );
1440 tttk_message_destroy( ttMsg );
1446 /* set all the hosts to the home host name since ToolTalk messages pass
1447 * the filenames in host relative paths (Is this correct?)
1449 host_set = (char **)XtMalloc(sizeof(char *) * file_count);
1450 for(i = 0; i < file_count; i++)
1451 host_set[i] = home_host_name;
1453 /* Go do the Move/Copy/Link... this function will do proper error checking */
1454 FileMoveCopy(NULL, NULL, toName, home_host_name,
1455 host_set, file_set, file_count,
1456 modifiers, NULL, NULL);
1459 tt_message_reply( ttMsg );
1460 tttk_message_destroy( ttMsg );