1 /*
2 Copyright 2007, 2008, 2009, 2010 Geyer Klaus
3
4 This file is part of Cat'sEyE.
5
6 Cat'sEyE is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 Cat'sEyE is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with Cat'sEyE. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include <gtk/gtk.h>
21 #ifndef NO_GIO
22 #include <gio/gio.h>
23 #endif
24 #include <string.h>
25
26 #include "helpers.h"
27 #include "globalDefinitions.h"
28 #include "Lists.h"
29 #include "listitems.h"
30 #include "userdata.h"
31 #include "myfm.h"
32 #include "fileshelf.h"
33 #include "threads.h"
34
35 #include "mytrace.h"
36
37 #include "allInclude.h"
38
39 void DNDSignal_dragdataget (GtkWidget *widget, GdkDragContext *drag_context, GtkSelectionData *selection_data, guint info, guint time, gpointer user_data);
40 void DNDSignal_dragdatereceive (GtkWidget *widget, GdkDragContext *drag_context, gint x, gint y, GtkSelectionData *data, guint info, guint time, gpointer user_data);
41 gboolean DNDSignal_dragdrop (GtkWidget *widget, GdkDragContext *drag_context, gint x, gint y, guint time, gpointer user_data);
42
43 extern GtkWidget *Notebooks[SIDE_BOTH];
44 extern GtkNotebook *g_FileShelfNotebook;
45 extern GtkWindow *win;
46
47 enum {
48 TARGET_LISTVIEW, //treeview, basic DnD for sideviews and fileshelfs
49 TARGET_MARKEDITEMSASTEXT
50 //TARGET_FROMNOTEBOOK //for getting tabs from notebooks, we have this target
51 };
52
53 // text/uri-list text/plain application/x-moz-file
54 static GtkTargetEntry targets[] = {
55 /* { "widget(listview)", GTK_TARGET_SAME_APP, TARGET_LISTVIEW },*/
56 { "STRING", GTK_TARGET_SAME_APP, TARGET_MARKEDITEMSASTEXT },
57 { "STRING", GTK_TARGET_OTHER_APP, TARGET_MARKEDITEMSASTEXT },
58 { "text/plain", GTK_TARGET_OTHER_APP, TARGET_MARKEDITEMSASTEXT },
59 { "text/uri-list", GTK_TARGET_OTHER_APP, TARGET_MARKEDITEMSASTEXT }/*,
60 { "application/x-moz-file", GTK_TARGET_OTHER_APP, TARGET_MARKEDITEMSASTEXT },
61 { "GTK_NOTEBOOK_TAB", GTK_TARGET_SAME_APP, TARGET_LISTVIEW } */ //look at 'http://library.gnome.org/devel/gtk/unstable/GtkNotebook.html', search for 'gtk_notebook_set_tab_detachable'
62 };
63
64
65
66 /*
67 static GtkTargetEntry NoteBookTargets[] = {
68 { "GTK_NOTEBOOK_TAB", GTK_TARGET_SAME_APP, TARGET_LISTVIEW } //look at 'http://library.gnome.org/devel/gtk/unstable/GtkNotebook.html', search for 'gtk_notebook_set_tab_detachable'
69 };
70 */
71 /*
72 int prepareWidgetForDragnDrop (GtkWidget *widget, int enableNoteBookDest){ //enables dragndrop for the widget and connects signals
73 //this is our standard dragndrop for copying items from/to view/Shelf
74 //enableNoteBookDest: 0:no, 1:yes, the widget can be achieve a ntebook-tab
75 TRACEIT(10,"prepareWidgetForDragnDrop start");
76 if (widget == NULL){
77 TRACEIT(2,"prepareWidgetForDragnDrop end, widget NULL");
78 return -1;
79 }
80 if (enableNoteBookDest==1){
81 gtk_drag_dest_set (widget, GTK_DEST_DEFAULT_ALL, NoteBookTargets, 1, GDK_ACTION_COPY|GDK_ACTION_MOVE);
82 }
83 else{
84 gtk_drag_dest_set (widget, GTK_DEST_DEFAULT_ALL, targets, 1, GDK_ACTION_COPY);
85 }
86 gtk_drag_source_set (widget, GDK_BUTTON1_MASK, targets, 1, GDK_ACTION_COPY); //Mind that only destinations who can handle Notebooktabs are allowd to get the target for notebooks
87
88 //g_signal_connect(widget,"drag-drop",G_CALLBACK(DNDSignal_dragdrop),NULL); //Do you remember the problem that we end up in the drag-data-get and receive signal handler twice
89 //after comment this out we did not have this Problem again
90 g_signal_connect(widget,"drag-data-get",G_CALLBACK(DNDSignal_dragdataget),NULL);
91 g_signal_connect(widget,"drag-data-received",G_CALLBACK(DNDSignal_dragdatereceive),NULL);
92
93 TRACEIT(10,"prepareWidgetForDragnDrop end");
94 return 0;
95 }
96 */
prepareWidgetForDrag(GtkWidget * widget)97 int prepareWidgetForDrag (GtkWidget *widget){ //enables the Drag in dragndrop for the widget and connects signals
98 //this is our standard dragndrop for copying items from/to view/Shelf
99
100 TRACEIT(10,"prepareWidgetForDrag start");
101 if (widget == NULL){
102 TRACEIT(2,"prepareWidgetForDrag end, widget NULL");
103 return -1;
104 }
105 gtk_drag_source_set (widget, GDK_BUTTON1_MASK, targets, sizeof(targets) / sizeof(targets[0]), GDK_ACTION_COPY); //Mind that only destinations who can handle Notebooktabs are allowd to get the target for notebooks
106
107 //g_signal_connect(widget,"drag-drop",G_CALLBACK(DNDSignal_dragdrop),NULL); //Do you remember the problem that we end up in the drag-data-get and receive signal handler twice
108 //after comment this out we did not have this Problem again
109 g_signal_connect(widget,"drag-data-get",G_CALLBACK(DNDSignal_dragdataget),NULL);
110
111
112 TRACEIT(10,"prepareWidgetForDrag end");
113 return 0;
114 }
115
116
prepareWidgetForDrop(GtkWidget * widget,int enableNoteBookDest,void (* functionStartNotification)(),void * UserData)117 int prepareWidgetForDrop (GtkWidget *widget, int enableNoteBookDest, void (*functionStartNotification)(), void *UserData){ //enables Drop for dragndrop for the widget and connects signals
118 //this is our standard dragndrop for copying items from/to view/Shelf
119 //enableNoteBookDest: 0:no, 1:yes, the widget can be achieve a ntebook-tab
120 //functionStartNotification: the function to connect to the receiv-signal
121 TRACEIT(10,"prepareWidgetForDrop start");
122 if (widget == NULL){
123 TRACEIT(2,"prepareWidgetForDrop end, widget NULL");
124 return -1;
125 }
126 if (enableNoteBookDest==1){
127 gtk_drag_dest_set (widget, GTK_DEST_DEFAULT_ALL, targets, sizeof(targets)/sizeof(targets[0]), GDK_ACTION_COPY);// GDK_ACTION_COPY|GDK_ACTION_MOVE
128 }
129 else{
130 gtk_drag_dest_set (widget, GTK_DEST_DEFAULT_ALL, targets, sizeof(targets)/sizeof(targets[0]), GDK_ACTION_COPY);
131 }
132
133 //g_signal_connect(widget,"drag-drop",G_CALLBACK(DNDSignal_dragdrop),NULL); //Do you remember the problem that we end up in the drag-data-get and receive signal handler twice
134 //after comment this out we did not have this Problem again
135
136
137 g_signal_connect(widget,"drag-data-received",G_CALLBACK(functionStartNotification), UserData);
138
139 TRACEIT(10,"prepareWidgetForDrop end");
140 return 0;
141 }
142 ////////////////// signal handler ////////////////////
143
144 /*
145 gboolean DNDSignal_dragdrop (GtkWidget *widget, GdkDragContext *drag_context, gint x, gint y, guint time, gpointer user_data){
146 printf ("DID NOT THINK WE CAN COME UP HERE\n");
147
148 return FALSE;
149 }
150 */
151
152 //"drag-data-get" signal (source side)
153 //the source sets the data
DNDSignal_dragdataget(GtkWidget * widget,GdkDragContext * drag_context,GtkSelectionData * selection_data,guint info,guint time,gpointer user_data)154 void DNDSignal_dragdataget (GtkWidget *widget, GdkDragContext *drag_context, GtkSelectionData *selection_data, guint info, guint time, gpointer user_data){
155 TRACEIT(10,"DNDSignal_dragdataget start");
156 //GtkTreeSelection *selection=NULL;
157 if (info == TARGET_MARKEDITEMSASTEXT){
158 GString *gstrDataToSend = g_string_sized_new (10);
159 GString *gstrBuf = g_string_sized_new (10);
160 struct CopyReMoveList *FirstItem = NULL;
161 struct CopyReMoveList *BufItem = NULL;
162 //The only widgets connected to this functions are the listviews from the sideObjects and the fileshelfs
163
164 GtkTreeSelection *selection;
165 struct SideObjectList *me_sideObject=NULL;
166 struct FileShelfObjectList *me_fileshelfObject=NULL;
167 int side;
168 int iWeAre=0; //1=sideObject, 2=fileshelf
169 char *cpConvertedString = NULL;
170 GError *error=NULL;
171 SideObjectList_GetObjectByChildListView(&me_sideObject, (GtkTreeView *)widget, &side);
172 if (me_sideObject == NULL){ //maybe we are a FileshelfObject
173 //FileShelfObjectList_GetActiveObject(&me_fileshelfObject);
174 FileShelfObjectList_GetObjectByChildListView(&me_fileshelfObject, (GtkTreeView *)widget);
175 //if (me_fileshelfObject!=NULL && me_fileshelfObject->listView == widget){
176 if (me_fileshelfObject!=NULL){
177 iWeAre=2;
178 }
179 }
180 else{
181 iWeAre=1;
182 }
183 if (iWeAre == 1){
184 iWeAre = SOURCE_SIDEOBJECT;
185 }
186 else if (iWeAre == 2){
187 iWeAre = SOURCE_FILESHELF;
188 }
189 else{
190 TRACEIT (4, "DNDSignal_dragdataget unable to determine the source widget, isnt it a listview?");
191 return;
192 }
193
194 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget));
195 g_string_assign (gstrDataToSend, "/NoPathHere"); //we will never use this, so it doesn't matter
196 g_string_assign (gstrBuf, "/JustAnotherPath");
197 if (0 == MakeList (iWeAre, &FirstItem, selection, (iWeAre==SOURCE_SIDEOBJECT)?me_sideObject->gstrPath:gstrDataToSend, gstrBuf)){ // all is good
198 BufItem = FirstItem;
199 g_string_erase (gstrDataToSend, 0, -1);
200 while (BufItem){
201 cutCharFromGString (BufItem->string1, '\"', 0);
202 cpConvertedString = g_locale_to_utf8 (BufItem->string1->str, strlen (BufItem->string1->str), NULL, NULL, &error);
203 if (error != NULL){
204 TRACEIT (3, "DNDSignal_dragdataget error:");
205 TRACEIT (3, error->message);
206 g_error_free (error);
207 error=NULL;
208 //BufItem = BufItem->NextItem; //do not cancel on that error
209 //continue;
210 }
211
212 //g_string_append (gstrDataToSend, "file://"); //we only have this type in our views
213 if (cpConvertedString != NULL){
214 g_string_assign (gstrBuf, cpConvertedString);
215 g_free (cpConvertedString);
216 }
217 else{ //a fall back if the encoding failed
218 g_string_assign (gstrBuf, BufItem->string1->str);
219 }
220 cpConvertedString = g_filename_to_uri (gstrBuf->str, NULL, &error);
221 if (error != NULL){
222 TRACEIT (3, "DNDSignal_dragdataget error:");
223 TRACEIT (3, error->message);
224 g_error_free (error);
225 error = NULL;
226 }
227 if (cpConvertedString != NULL){
228 g_string_append (gstrDataToSend, cpConvertedString);
229 g_string_append_c (gstrDataToSend, '\r'); //Carriage return, Ctrl-m, ASCII code 13, 0xD
230 g_string_append_c (gstrDataToSend, '\n');
231 g_free (cpConvertedString);
232 }
233 else{
234 g_string_erase (gstrDataToSend, 0, -1);
235 }
236
237 BufItem = BufItem->NextItem;
238 }
239
240 if (0 < strlen (gstrDataToSend->str)){
241 //data will be copied from gtk_selection_data_set.
242 gtk_selection_data_set (selection_data, selection_data->target, 8, (guchar *)gstrDataToSend->str, strlen (gstrDataToSend->str));
243 }
244 }
245 g_string_free (gstrDataToSend, TRUE);
246 g_string_free (gstrBuf, TRUE);
247 if (FirstItem != NULL){
248 CopyReMoveList_DeleteList (FirstItem);
249 FirstItem = NULL;
250 }
251 }
252
253 if (info == TARGET_LISTVIEW){
254 int *testpointer = (int *)widget;
255
256 //selection = gtk_tree_view_get_selection((GtkTreeView *)widget /*ListView*/);
257
258 //gtk_selection_data_set (selection_data, selection_data->target, 8,(guchar *)&widget, sizeof(GtkWidget*));
259 gtk_selection_data_set (selection_data, selection_data->target, 1,(guchar *)&testpointer, sizeof(int*));
260
261 }
262 TRACEIT(10,"DNDSignal_dragdataget end");
263 }
264
265
266 //"drag-data-received" signal (drop side) for SideObjects and FileShelfs
DNDSignal_dragdatereceive_forSideObjectAndFileShelf(GtkWidget * widget,GdkDragContext * drag_context,gint x,gint y,GtkSelectionData * selection_data,guint info,guint time,gpointer user_data)267 void DNDSignal_dragdatereceive_forSideObjectAndFileShelf (GtkWidget *widget, GdkDragContext *drag_context, gint x, gint y, GtkSelectionData *selection_data, guint info, guint time, gpointer user_data){
268 TRACEIT(10,"DNDSignal_dragdatereceive_forSideObjectAndFileShelf start");
269 //GtkTreeSelection *selection;
270 struct SideObjectList *me_sideObject=NULL;
271 struct FileShelfObjectList *me_fileshelfObject=NULL;
272 //struct SideObjectList *source_sideObject=NULL;
273 //struct FileShelfObjectList *source_fileshelfObject=NULL;
274 int side;
275 int iWeAre=0; //1=sideObject, 2=fileshelf, 3=ViewNotebook, 4=FSNotebook
276 //int iSourceIs=0;//1=sideObject, 2=fileshelf, 3=ViewNotebook
277 //GtkWidget *sourceWidget=NULL;
278 gboolean DND_Done = FALSE;
279 //GtkWidget **NotebookChild=NULL;
280 GString *gstrPath=NULL;
281 GString *gstrName=NULL;
282 GError *error = NULL;
283 gchar *cpConvertedString=NULL;
284 gchar *cpConvertedString2=NULL;
285 gchar *cpHostName=NULL;
286
287 if((selection_data != NULL) && (selection_data->length >= 0)){
288 //determine own type (the widget is from sideObject or Fileshelf)
289 if (widget == Notebooks[SIDE_LEFT] || widget == Notebooks[SIDE_RIGHT]){ //find viewNotebooks
290 SideObjectList_GetActiveObject((GtkNotebook *)widget, &me_sideObject);
291 if (me_sideObject){
292 iWeAre=3; //3=ViewNotebook
293 }
294 if (widget == Notebooks[SIDE_LEFT]){
295 side=SIDE_LEFT;
296 }
297 else if (widget == Notebooks[SIDE_RIGHT]){
298 side=SIDE_RIGHT;
299 }
300 }
301 else if (widget == (GtkWidget *)g_FileShelfNotebook){
302 FileShelfObjectList_GetActiveObject(&me_fileshelfObject);
303 if (me_fileshelfObject!=NULL){
304 iWeAre=4;
305 }
306 }
307 else{
308 SideObjectList_GetObjectByChildListView(&me_sideObject, (GtkTreeView *)widget, &side);
309 if (me_sideObject == NULL){ //maybe we are a FileshelfObject
310 FileShelfObjectList_GetActiveObject(&me_fileshelfObject);
311 if (me_fileshelfObject!=NULL && me_fileshelfObject->listView == widget){
312 iWeAre=2;
313 }
314 }
315 else{
316 iWeAre=1;
317 }
318 }
319 if (iWeAre==0){
320 TRACEIT(2,"DNDSignal_dragdatereceive_forSideObjectAndFileShelf end, could not determine own type.");
321 DND_Done = FALSE;
322 gtk_drag_finish (drag_context, DND_Done, FALSE, time);
323 return;
324 }
325 if (me_sideObject!=NULL && me_sideObject->bReadOnly == TRUE){
326 MyMessageWidget(win, "Read only Tab", "The tab is marked as read only.\nPlease remove this flag to\nperform this action.\n(tab context menu)");
327 TRACEIT(2,"DNDSignal_dragdatereceive_forSideObjectAndFileShelf end, could not determine own type.");
328 DND_Done = FALSE;
329 gtk_drag_finish (drag_context, DND_Done, FALSE, time);
330 return;
331 }
332
333 if (info == TARGET_MARKEDITEMSASTEXT){
334 //we only handle "file://<PATHWITHFILE>" objects in here, this is a filebrowser.
335 char *cpBuf = (char *)selection_data->data;
336 gstrPath = g_string_sized_new (10);
337 gstrName = g_string_sized_new (10);
338 int iCopyToSideObject = 0;
339 struct CopyReMoveList *FirstItem = NULL;
340 for (cpBuf = strtok (cpBuf, "\r\n"); cpBuf!=NULL; cpBuf = strtok (NULL, "\r\n") ){
341
342 cpConvertedString = g_locale_from_utf8 (cpBuf, strlen (cpBuf), NULL, NULL, &error);
343 if (error != NULL){
344 TRACEIT (2, "DNDSignal_dragdatereceive_forSideObjectAndFileShelf error from locale_from_utf8:");
345 TRACEIT (2, error->message);
346 g_error_free (error);
347 error = NULL;
348 }
349 if (cpConvertedString == NULL){
350 //do not stop here, we will have a fall back for this case
351 cpConvertedString2 = g_filename_from_uri (cpBuf, &cpHostName, &error);
352 }
353 else{
354 cpConvertedString2 = g_filename_from_uri (cpConvertedString, &cpHostName, &error);
355 g_free (cpConvertedString);
356 cpConvertedString=NULL;
357 }
358 if (error != NULL){
359 TRACEIT (2, "DNDSignal_dragdatereceive_forSideObjectAndFileShelf error from g_filename_from_uri:");
360 TRACEIT (2, error->message);
361 g_error_free (error);
362 error = NULL;
363 }
364 if (cpConvertedString2 == NULL){
365 continue;
366 }
367
368 if (cpHostName != NULL && strcmp (cpHostName, "file://")!=0){
369 g_free(cpConvertedString2);
370 cpConvertedString2=NULL;
371 continue;
372 }
373 else if (cpHostName != NULL){
374 g_free (cpHostName);
375 }
376
377 if (iWeAre==1 || iWeAre==3){ //sideobject copy
378 //we create a CopyReMoveList and let others do the work
379 g_string_assign (gstrPath, cpConvertedString2);
380 GetPathFromPathWithName(gstrPath, 1);
381 if (0 == strcmp (gstrPath->str, me_sideObject->gstrPath->str)){
382 g_free(cpConvertedString2);
383 cpConvertedString2=NULL;
384 continue;
385 }
386 CopyReMoveList_AddItem ( &FirstItem, cpConvertedString2, me_sideObject->gstrPath->str, NULL, me_sideObject, NULL);
387
388 iCopyToSideObject = 1;
389 }
390 else if (iWeAre==2 || iWeAre==4){ //fileshelf add
391 g_string_assign (gstrPath, cpConvertedString2);
392 g_string_assign (gstrName, cpConvertedString2);
393
394 getLastStringInPath(gstrName);
395 GetPathFromPathWithName(gstrPath, 1);
396
397 AddItemToFileshelf (me_fileshelfObject, gstrName->str, gstrPath->str, TRUE, 1);
398 DND_Done = TRUE;
399 }
400 if (cpConvertedString2!=NULL){
401 g_free(cpConvertedString2);
402 cpConvertedString2=NULL;
403 }
404 }
405 if (iCopyToSideObject == 1){ //sideobject copy
406 ProcessItemsViaListWrap(FirstItem, 1);
407 DND_Done = TRUE;
408 }
409
410 g_string_free (gstrPath, TRUE);
411 g_string_free (gstrName, TRUE);
412 DND_Done = FALSE;
413 }
414 /*else if (info == TARGET_LISTVIEW){
415 sourceWidget = gtk_drag_get_source_widget (drag_context);
416
417 //find source type
418 if (sourceWidget == Notebooks[0] || sourceWidget == Notebooks[1]){ //find viewNotebooks
419 NotebookChild = (void *)selection_data->data;
420 SideObjectList_GetObjectByChildVBox(&source_sideObject, (GtkWidget *)*NotebookChild, &side);
421 if (source_sideObject){
422 iSourceIs=3; //3=Notebook
423 }
424 }
425 else{
426 SideObjectList_GetObjectByChildListView(&source_sideObject, (GtkTreeView *)sourceWidget, &side);
427 if (source_sideObject == NULL){ //maybe we are a FileshelfObject
428 FileShelfObjectList_GetObjectByChildListView(&source_fileshelfObject, (GtkTreeView *)sourceWidget);
429 if (source_fileshelfObject){
430 iSourceIs=2;
431 }
432 }
433 else{
434 iSourceIs=1;
435 }
436 }
437 if (iSourceIs==0){
438 TRACEIT(2,"DNDSignal_dragdatereceive end, could not determine source type.");
439 gtk_drag_finish (drag_context, DND_Done, FALSE, time);
440 return;
441 }
442
443 //printf("found iWeAre=%d\tiSourceIs=%d\n",iWeAre,iSourceIs);
444
445 if ( (iWeAre==1||iWeAre==3) && iSourceIs == 1){ //From sideObject to sideObject
446 //printf("View2View\n");
447 if (source_sideObject != me_sideObject){
448 copyToAnOtherPannel( source_sideObject, me_sideObject);
449 DND_Done=TRUE;
450 }
451 }
452 else if ( (iWeAre==2||iWeAre==4) && iSourceIs==1){ //From sideObject to FileShelf
453 //printf("View2FS\n");
454 MenuAddItemToFileshelf(NULL, (void *) source_sideObject);
455 DND_Done=TRUE;
456 }
457 else if ( (iWeAre==1||iWeAre==3) && iSourceIs == 2){ //From fileshelf to sideObject
458 //printf("FS2View\n");
459 if (side == SIDE_RIGHT){
460 copyFileShelfToRightPannel(NULL, source_fileshelfObject);
461 DND_Done=TRUE;
462 }
463 else if (side == SIDE_LEFT){
464 copyFileShelfToLeftPannel(NULL, source_fileshelfObject);
465 DND_Done=TRUE;
466 }
467 }
468 else if ( (iWeAre==2||iWeAre==4) && iSourceIs == 2){ //From Fileshelf to FileShelf
469 //printf("FS2FS\n");
470 if (source_fileshelfObject != me_fileshelfObject){
471 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(source_fileshelfObject->listView));
472 gtk_tree_selection_selected_foreach(selection, addItemsFromFileshelfToFileshelf_Helper, source_fileshelfObject);
473 DND_Done=TRUE;
474 }
475 }
476 else if ( (iWeAre==2||iWeAre==4) && iSourceIs == 3){ //notbook tab to Fileshelf (we put the directory viewed from the notebook to the shelf as item)
477 //printf("ViewTab2FS\n");
478 gstrPath = g_string_new (source_sideObject->gstrPath->str);
479 gstrName = g_string_new (source_sideObject->gstrPath->str);
480
481 getLastStringInPath(gstrName);
482 GetPathFromPathWithName(gstrPath, 1);
483
484 AddItemToFileshelf (me_fileshelfObject, gstrName->str, gstrPath->str, 0, 1);
485
486 g_string_free(gstrPath, TRUE);
487 g_string_free(gstrName, TRUE);
488 DND_Done=TRUE;
489 }
490 }*/
491 }
492
493 gtk_drag_finish (drag_context, DND_Done, FALSE, time);
494 //gtk_drag_finish (drag_context, TRUE, TRUE, time);
495
496 TRACEIT(10,"DNDSignal_dragdatereceive_forSideObjectAndFileShelf end");
497 }
498
499
500
DNDSignal_dragdatereceive_forCopyReMoveWidget(GtkWidget * widget,GdkDragContext * drag_context,gint x,gint y,GtkSelectionData * selection_data,guint info,guint time,void * user_data)501 void DNDSignal_dragdatereceive_forCopyReMoveWidget (GtkWidget *widget, GdkDragContext *drag_context, gint x, gint y, GtkSelectionData *selection_data, guint info, guint time, void *user_data){
502 TRACEIT(10,"DNDSignal_dragdatereceive_forCopyReMoveWidget start");
503 // user_data is of type struct ListWidgetCommunicationStruct
504 GString *gstrPath = g_string_sized_new (10);
505 GString *gstrName = g_string_sized_new (10);
506 //int iCopyToSideObject = 0;
507 char *cpBuf = NULL;
508 struct CopyReMoveList *FirstItem = NULL;
509 struct CopyReMoveList *AllreadyExistingList = NULL;
510 struct ListWidgetCommunicationStruct *CommStru = NULL;
511 GError *error = NULL;
512 gchar *cpConvertedString=NULL;
513 gchar *cpConvertedString2=NULL;
514 gboolean DND_Done = FALSE;
515 gchar *cpHostName=NULL;
516 GtkTreeIter iter;
517 int iListCreated=0;
518 int iItemColumn=0;
519
520 CommStru = (struct ListWidgetCommunicationStruct *)user_data;
521 AllreadyExistingList = CommStru->firstItem;
522 if (NULL == CommStru){
523 gtk_drag_finish (drag_context, DND_Done, FALSE, time);
524 TRACEIT(2, "DNDSignal_dragdatereceive_forCopyReMoveWidget PARAMETER NULL (1)");
525 return;
526 }
527
528 AllreadyExistingList = CommStru->firstItem;
529 if (NULL == AllreadyExistingList){
530 gtk_drag_finish (drag_context, DND_Done, FALSE, time);
531 TRACEIT(2, "DNDSignal_dragdatereceive_forCopyReMoveWidget PARAMETER NULL");
532 return;
533 }
534
535 if((selection_data != NULL) && (selection_data->length >= 0)){
536 //determine own type (the widget is from sideObject or Fileshelf)
537
538 if (info == TARGET_MARKEDITEMSASTEXT){
539 //we only handle "file://<PATHWITHFILE>" objects in here, this is a filebrowser.
540 cpBuf = (char *)selection_data->data;
541
542 for (cpBuf = strtok (cpBuf, "\r\n"); cpBuf!=NULL; cpBuf = strtok (NULL, "\r\n") ){
543
544 cpConvertedString = g_locale_from_utf8 (cpBuf, strlen (cpBuf), NULL, NULL, &error);
545 if (error != NULL){
546 TRACEIT (2, "DNDSignal_dragdatereceive_forSideObjectAndFileShelf error from locale_from_utf8:");
547 TRACEIT (2, error->message);
548 g_error_free (error);
549 error = NULL;
550 }
551 if (cpConvertedString == NULL){
552 //do not stop here, we will have a fall back for this case
553 cpConvertedString2 = g_filename_from_uri (cpBuf, &cpHostName, &error);
554 }
555 else{
556 cpConvertedString2 = g_filename_from_uri (cpConvertedString, &cpHostName, &error);
557 g_free (cpConvertedString);
558 cpConvertedString=NULL;
559 }
560 if (error != NULL){
561 TRACEIT (2, "DNDSignal_dragdatereceive_forSideObjectAndFileShelf error from g_filename_from_uri:");
562 TRACEIT (2, error->message);
563 g_error_free (error);
564 error = NULL;
565 }
566 if (cpConvertedString2 == NULL){
567 continue;
568 }
569
570 if (cpHostName != NULL && strcmp (cpHostName, "file://")!=0){
571 g_free(cpConvertedString2);
572 cpConvertedString2=NULL;
573 continue;
574 }
575 else if (cpHostName != NULL){
576 g_free (cpHostName);
577 }
578
579 //we create a CopyReMoveList and let others do the work
580 g_string_assign (gstrPath, cpConvertedString2);
581 GetPathFromPathWithName(gstrPath, 1);
582 if (NULL!=AllreadyExistingList->DestObject && 0 == strcmp (gstrPath->str, AllreadyExistingList->DestObject->gstrPath->str)){
583 g_free(cpConvertedString2);
584 cpConvertedString2=NULL;
585 continue;
586 }
587
588 //copy unknown parameter from the 'old' list
589 CopyReMoveList_AddItem ( &FirstItem, cpConvertedString2,
590 (AllreadyExistingList->DestObject==NULL)?NULL:AllreadyExistingList->DestObject->gstrPath->str,
591 AllreadyExistingList->SrcObject,
592 AllreadyExistingList->DestObject,
593 AllreadyExistingList->FileShelfObject);
594 iListCreated = 1;
595
596 if (cpConvertedString2!=NULL){
597 g_free(cpConvertedString2);
598 cpConvertedString2=NULL;
599 }
600 }
601
602 //now we want to connect the old list in AllreadyExistingList with the new one in FirstItem
603 struct CopyReMoveList *listbuf = NULL;
604 //int iListCounter = 0;
605
606 /*
607 listbuf = AllreadyExistingList;
608 iListCounter = 0;
609 do{
610 iListCounter++;
611 listbuf = listbuf->NextItem;
612 }while(listbuf!= NULL);
613
614 listbuf = FirstItem;
615 do{
616 iListCounter++;
617 listbuf = listbuf->NextItem;
618 }while(listbuf!= NULL);
619 */
620
621 if (CommStru->ThreadStartStruct != NULL){
622 iItemColumn = 1;
623 }
624 else{
625 iItemColumn = 2;
626 }
627
628 if (iListCreated == 1){
629 listbuf = FirstItem;
630 do{
631 gtk_list_store_append( CommStru->listStore, &iter);
632 gtk_list_store_set ( CommStru->listStore, &iter, iItemColumn, listbuf->string1->str,-1);
633
634 CopyReMoveList_initializeMemberTo (listbuf, CommStru->listStore, iter, &(CommStru->ui64TotalBytesProcessed), &(CommStru->i64StartTotalBytesCopied), &(CommStru->timeStartTimeForBytesCopied), &(CommStru->timeStartTimeForBytesCopiedSingleItem), &(CommStru->ui64TotalBytes), &(CommStru->iTotalBytesValid), (GtkProgressBar *)CommStru->progressBar, AllreadyExistingList->CopyMoveOrRemove, &(CommStru->dCopySpeed) );
635
636
637
638 if (CommStru->ThreadStartStruct != NULL){
639 //We are in the usercommand via list widget
640 //we have to add the new items to some more lists for the usercommand:
641 g_string_assign (gstrPath, listbuf->string1->str);
642 g_string_assign (gstrName, listbuf->string1->str);
643
644 getLastStringInPath(gstrName);
645 //GetPathFromPathWithName(gstrPath, 1);
646
647 CommStru->ThreadStartStruct->glistItemsWithPath = g_list_append (CommStru->ThreadStartStruct->glistItemsWithPath, g_string_new (gstrPath->str));
648 CommStru->ThreadStartStruct->glistItemsWithoutPath = g_list_append (CommStru->ThreadStartStruct->glistItemsWithoutPath, g_string_new(gstrName->str));
649 CommStru->ThreadStartStruct->uiSizeOfLists = g_list_length (CommStru->ThreadStartStruct->glistItemsWithPath);
650 }
651
652
653 listbuf = listbuf->NextItem;
654 }while(listbuf!= NULL);
655
656 //find the last item in the list
657 for (listbuf=AllreadyExistingList; listbuf->NextItem; listbuf=listbuf->NextItem);
658
659 //connect the two lists
660 listbuf->NextItem = FirstItem;
661 FirstItem->PrevItem = listbuf;
662
663
664 copyReMoveWidget_updateItemCounterColumn(FirstItem);
665
666 if (CommStru->ThreadStartStruct == NULL){
667 //means, that we are in the CopyReMoveWidget
668 if (CommStru->iTotalBytesValid==1){
669 if (FirstItem->CopyMoveOrRemove != 3){ //do not calculate this when deleting
670 g_thread_create((GThreadFunc)CopyReMoveItemsViaList_SizeCalc, (void *)CommStru , FALSE, NULL);
671 }
672 }
673 }
674 }
675
676 DND_Done=TRUE;
677 }
678 }
679
680 g_string_free (gstrPath, TRUE);
681 g_string_free (gstrName, TRUE);
682
683 gtk_drag_finish (drag_context, DND_Done, FALSE, time);
684
685 //fired automaticly via signal drag-leave
686 //gtk_button_clicked (CommStru->continueButton);
687
688 TRACEIT(10,"DNDSignal_dragdatereceive_forCopyReMoveWidget end");
689 }
690
691
692
693
694 ////////////////////////////////////////////////////////////////////////////////////////////
695 /*
696 void gtk_drag_dest_set (GtkWidget *widget,
697 GtkDestDefaults flags,
698 const GtkTargetEntry *targets,
699 gint n_targets,
700 GdkDragAction actions);
701
702 typedef struct {
703 gchar *target;
704 guint flags; //GTK_TARGET_SAME_APP
705 guint info;
706 } GtkTargetEntry;
707
708 typedef enum
709 {
710 GDK_ACTION_DEFAULT = 1 << 0,
711 GDK_ACTION_COPY = 1 << 1,
712 GDK_ACTION_MOVE = 1 << 2,
713 GDK_ACTION_LINK = 1 << 3,
714 GDK_ACTION_PRIVATE = 1 << 4,
715 GDK_ACTION_ASK = 1 << 5
716 } GdkDragAction;
717
718
719 //some signals
720 "drag-begin" : Run Last
721 "drag-data-delete" : Run Last
722 "drag-data-get" : Run Last
723 "drag-data-received" : Run Last
724 "drag-drop" : Run Last
725 "drag-end" : Run Last
726 "drag-failed" : Run Last
727 "drag-leave" : Run Last
728 "drag-motion"
729 */
730
731