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 <stdio.h>
21 #include <stdlib.h> //for system();
22 #include <gtk/gtk.h>
23 #ifndef NO_GIO
24 #include <gio/gio.h>
25 #endif
26 #include <sys/types.h> //Diese hier auch f�r die Verzeichnisfunktionen und Attribute / and fork()
27 #include <sys/stat.h> //Diese hier auch f�r die Verzeichnisfunktionen und Attribute
28 #include <dirent.h> //Verzeichnis Zeiger und DIR - Struktur
29 #include <string.h>
30 #include <time.h>
31 #include <unistd.h> //e.g. chdir, usleep
32 #include <errno.h>
33 #include <glib.h>
34
35 #include "Lists.h"
36 #include "listitems.h"
37 #include "mytrace.h"
38 #include "helpers.h"
39 #include "globalDefinitions.h"
40 #include "userdata.h"
41 #include "myfm.h"
42
43 #include "allInclude.h"
44
45 extern GtkWindow *win;
46
makeDirectory(char * Directory,int iShowErrorMessage,GString * gstrErrorStorage)47 int makeDirectory(char *Directory, int iShowErrorMessage, GString *gstrErrorStorage){
48 //if iShowErrorMessage == 1 then a message widget may pop up, showing some error, otherwise no message widget pops up
49 //if gstrErrorStorage is != NULL the error message is written to it.
50 //return: -1 internal error
51 //return: 0 OK
52 //return: 1 Error Message
53 TRACEIT(10,"makeDirectory start");
54
55 int ret=-1;
56 if (Directory == NULL){
57 TRACEIT(2,"makeDirectory ends, Parameter NULL");
58 return -1;
59 }
60 GError *Error = NULL;
61 GFile *Sourcefile = g_file_new_for_path(Directory);
62 GString *gstrText=g_string_sized_new(20);
63 if (FALSE == g_file_make_directory (Sourcefile, NULL, &Error) ){
64 if (gstrErrorStorage){
65 g_string_append(gstrErrorStorage, Error->message);
66 }
67 MyMessageWidget(win, "Error while creating Directory", Error->message);
68 g_string_printf(gstrText, "error created Directory: \"%s\":%s",Directory, Error->message);
69 textbuffer_commandHistory_addText(gstrText->str,"error");
70 ret = 1;
71 }
72 else{
73 g_string_printf(gstrText, "created Directory: %s",Directory);
74 textbuffer_commandHistory_addText(gstrText->str,NULL);
75 ret = 0;
76 }
77
78 if (Error)
79 g_error_free(Error);
80 if (Sourcefile)
81 g_object_unref(Sourcefile);
82 if (gstrText)
83 g_string_free(gstrText, TRUE);
84 Sourcefile = NULL;
85
86 TRACEIT(10,"makeDirectory ends");
87 return ret;
88 }
89
90 #define UPDATETIMESINGLEITEM 100000
91 #define UPDATETIMETOTALBYTES 500000
92
copyItemRecursive_Callback(goffset current_num_bytes,goffset total_num_bytes,gpointer data)93 void copyItemRecursive_Callback (goffset current_num_bytes, goffset total_num_bytes, gpointer data){
94 TRACEIT(11,"copyItemRecursive_Callback start");
95 if (data == NULL){
96 TRACEIT(2,"copyItemRecursive_Callback end, userdate NULL");
97 return;
98 }
99 //we have to use list, NOT commstru->currentItem, as the currentItem is set in another thread and may
100 //not be the same as the listitem aimed by this function!!
101 struct CopyReMoveList *list = (struct CopyReMoveList *)data;
102 GString *gstrBuf=g_string_sized_new(10);
103 GString *gstrSpeed=g_string_sized_new(10);
104 GString *gstrBuf2=g_string_sized_new(10);
105 double percentage=0.0;
106 double totalPercentage=0.0;
107 double myTime;
108 int iUpdateView = 0;
109 int iUpdateViewSingleItem = 0;
110
111 GTimeVal *startTime;
112 GTimeVal nextTime;
113
114
115 //when finished we come up here twice, this leads to an percentage of 200%
116 //when you dont understand how this works, please mind, that copying a directory
117 //may consist of many files, for them we have to the leading if structure.
118 //every time one item finished, we add the total amount to our list variable
119 //list->ui64pTotalBytesCopied
120
121 //Calc Percentage of the Item and write it to the list
122 startTime = list->timepStartTimeForBytesCopiedSingleItem;
123
124 if (list->iBytesCopied == -1){
125 list->iBytesCopied = 0;
126 g_get_current_time (startTime);
127 g_time_val_add(startTime, UPDATETIMESINGLEITEM);
128 iUpdateViewSingleItem = 1;
129 }
130
131 if (current_num_bytes == total_num_bytes){
132 if (list->lastfinishedTotalBytes != total_num_bytes){
133 list->iBytesCopied += total_num_bytes;
134 list->lastfinishedTotalBytes = total_num_bytes;
135
136 *(list->ui64pTotalBytesCopied) += total_num_bytes;
137 }
138 else{
139 list->lastfinishedTotalBytes = -1;
140 }
141 current_num_bytes = 0;
142 iUpdateViewSingleItem = 1;
143 }
144 if (iUpdateViewSingleItem == 0){
145 g_get_current_time (&nextTime);
146 myTime = GetTimeMine(*startTime) - GetTimeMine(nextTime);
147 if ( myTime <= 0){
148 g_get_current_time (startTime);
149 g_time_val_add(startTime, UPDATETIMESINGLEITEM);
150 iUpdateViewSingleItem = 1;
151 }
152 }
153
154 if (iUpdateViewSingleItem == 1){
155 if (list->iBytesToCopyIsValid == 1){
156 percentage = 100*(double)(list->iBytesCopied+current_num_bytes)/(double)list->iBytesToCopy;
157 g_string_printf(gstrBuf, "%0.2f", percentage);
158 }
159 else{
160 g_string_assign(gstrBuf, "na");
161 }
162
163 myWrap_gdk_threads_enter("copyItemRecursive_Callback 1");
164 gtk_list_store_set (list->listStore, &(list->iter), 1, gstrBuf->str,-1);
165 myWrap_gdk_threads_leave("copyItemRecursive_Callback 1");
166 }
167
168 //TotalPercentag and bytes/Sec
169 startTime = list->timepStartTimeForBytesCopied;
170
171 //totalPercentage = (double)(*(list->ui64pTotalBytesCopied)+current_num_bytes) / *(list->ui64TotalBytes);
172 //totalPercentage = (totalPercentage>1.0)?1.0:totalPercentage;
173 if (*(list->i64pStartTotalBytesCopied)<0){ //start messuring
174 *(list->i64pStartTotalBytesCopied) = *(list->ui64pTotalBytesCopied)+current_num_bytes;
175 g_get_current_time (startTime);
176 g_time_val_add(startTime, UPDATETIMETOTALBYTES);
177 }
178 g_get_current_time (&nextTime);
179 myTime = GetTimeMine(*startTime) - GetTimeMine(nextTime);
180 if ( myTime <= 0){
181 *(list->i64pStartTotalBytesCopied) = *(list->ui64pTotalBytesCopied)+current_num_bytes - *(list->i64pStartTotalBytesCopied);
182 myTime = 0.5 - myTime;
183 *(list->dpCopySpeed) = *(list->i64pStartTotalBytesCopied) / myTime;
184
185 *(list->i64pStartTotalBytesCopied)=-1.0;
186 iUpdateView = 1;
187 }
188 if (*(list->iTotalBytesValid)==1){
189 BytesToHumanityString ((guint64)*(list->dpCopySpeed), gstrSpeed, 1);
190 g_string_append(gstrSpeed, "/s");
191
192 if (totalPercentage>1.0)
193 totalPercentage = 1.0;
194 else if (totalPercentage<0.0)
195 totalPercentage = 0.0;
196 }
197 else{
198 g_string_assign(gstrBuf, "in progress ...");
199 }
200
201
202 if (iUpdateView == 1){
203 totalPercentage = (double)(*(list->ui64pTotalBytesCopied)+current_num_bytes) / *(list->ui64TotalBytes);
204 totalPercentage = (totalPercentage>1.0)?1.0:totalPercentage;
205
206
207 BytesToHumanityString ((guint64)*(list->ui64TotalBytes), gstrBuf2, 1);
208
209 g_string_printf(gstrBuf, "total: %0.0f%%, at %s (%s)", totalPercentage*100, gstrSpeed->str, gstrBuf2->str);
210
211 myWrap_gdk_threads_enter("copyItemRecursive_Callback 2");
212 gtk_progress_bar_set_fraction (list->progressBar, totalPercentage);
213 gtk_progress_bar_set_text(list->progressBar, gstrBuf->str);
214 myWrap_gdk_threads_leave("copyItemRecursive_Callback 2");
215 }
216
217 g_string_free(gstrBuf, TRUE);
218 g_string_free(gstrSpeed, TRUE);
219 g_string_free(gstrBuf2, TRUE);
220 TRACEIT(11,"copyItemRecursive_Callback end");
221 return;
222 }
223
224
copyReMoveItemRecursive(const char * cpSource,const char * cpDest,struct ListWidgetCommunicationStruct * commstru)225 int copyReMoveItemRecursive(const char *cpSource, const char *cpDest, struct ListWidgetCommunicationStruct *commstru){
226 //return: -1:error, 1=success, 0=copy returned false or any other error, copying failed
227 //cpDest is supposed to be a path
228 //while cpSource may be a path or filename
229 //cpDest may be NULL (for deleting)
230 TRACEIT(10,"copyReMoveItemRecursive start");
231 if ( commstru==NULL || cpSource==NULL || (cpDest==NULL && commstru->currentItem->CopyMoveOrRemove != 3) ){
232 TRACEIT(2,"copyReMoveItemRecursive end, Parameter NULL");
233 return -1;
234 }
235
236 /*
237 #ifdef NO_GIO
238 int iRetErrorCode=0; //0=error, 1=0k, -1 internal error, thsi is the value returned by this function
239 GString *gstrCommandString = g_string_sized_new(20);
240 GString *gstrSource = g_string_sized_new(20);
241 GString *gstrDest = g_string_sized_new(20);
242 gchar *error=NULL;
243 int iExitStatus;
244 if (commstru->currentItem->CopyMoveOrRemove == 1){ //copy
245 g_string_printf(gstrCommandString, "%s \"%s\" \"%s\"", g_gstrCommandCopy->str, cpSource, cpDest);
246 }
247 else if (commstru->currentItem->CopyMoveOrRemove == 2){ //move
248 g_string_printf(gstrCommandString, "%s \"%s\" \"%s\"", g_gstrCommandMove->str, cpSource, cpDest);
249 }
250 else if (commstru->currentItem->CopyMoveOrRemove == 3){ //remove
251 g_string_printf(gstrCommandString, "%s \"%s\"", g_gstrCommandRemove->str, cpSource);
252 }
253
254 myWrapOf__g_spawn_command_line_sync (gstrCommandString->str, NULL, &error, &iExitStatus, NULL, TRUE);
255
256 if (iExitStatus != 0){
257 if (error != NULL){
258 g_string_assign(commstru->currentItem->ErrorMessage, error);
259 g_free(error);
260 error=NULL;
261 }
262 iRetErrorCode=0; //error
263 }
264 else{
265 iRetErrorCode=1; //OK
266 }
267
268 myWrap_gdk_threads_enter("copyReMoveItemRecursive 1");
269 if (commstru->currentItem->CopyMoveOrRemove == 1){ //copy
270 g_string_assign(gstrDest, cpDest);
271 updateObjectsViewingFolder(gstrDest->str, TRUE);
272 }
273 else if (commstru->currentItem->CopyMoveOrRemove == 2){ //move
274 g_string_assign(gstrSource, cpSource);
275 GetPathFromPathWithName(gstrSource, 1);
276 updateObjectsViewingFolder(gstrSource->str, TRUE);
277 g_string_assign(gstrDest, cpDest);
278 updateObjectsViewingFolder(gstrDest->str, TRUE);
279 }
280 else if (commstru->currentItem->CopyMoveOrRemove == 3){ //remove
281 g_string_assign(gstrSource, cpSource);
282 GetPathFromPathWithName(gstrSource, 1);
283 updateObjectsViewingFolder(gstrSource->str, TRUE);
284 }
285 myWrap_gdk_threads_leave("copyReMoveItemRecursive 1");
286 g_string_free(gstrCommandString, TRUE);
287 g_string_free(gstrSource, TRUE);
288 g_string_free(gstrDest, TRUE);
289 TRACEIT(10,"copyReMoveItemRecursive end");
290 return iRetErrorCode;
291 #endif //#ifdef NO_GIO
292 */
293 #ifndef NO_GIO
294
295 gboolean iDoWeDelete = (commstru->currentItem->CopyMoveOrRemove == 3)?TRUE:FALSE;
296 struct CopyReMoveList *currentItem = commstru->currentItem;
297
298 GString *gstrSource=g_string_sized_new(20);
299 if (!iDoWeDelete)
300 g_string_assign(gstrSource,cpDest);
301
302 //GString *gstrDest=g_string_new(cpSource);
303 GString *gstrDest=g_string_sized_new(20);
304 g_string_assign(gstrDest, cpSource);
305 GString *gstrNames=g_string_sized_new(10);
306 gboolean bRet=FALSE;
307
308 GFile *Sourcefile = NULL;
309 GFile *Destfile = NULL;
310
311 struct myLocationStruct locationStru;
312
313 int iRetRecursivItem=0;
314 int iRetFolder=0;
315 int iRetErrorCode=0; //0=error, 1=0k, -1 internal error, thsi is the value returned by this function
316 int iRecItemCount=0;
317 int iOverwriteRet=0;
318 gboolean bCanceled = FALSE;
319
320 bCanceled = g_cancellable_is_cancelled (commstru->cancellable);
321
322 //build the complete Name of the destination:
323 //get the name of the file:
324 if (bCanceled == FALSE && currentItem->status==0){
325 if (!iDoWeDelete){
326 getLastStringInPath(gstrDest);
327 checkPathForLastChar(gstrSource); //gstrSource is filled with cpDest
328 g_string_prepend(gstrDest,gstrSource->str); //now we have the complete destination
329 }
330 g_string_assign(gstrSource, cpSource); //now the source is valid too.
331 //printf("comming in: Source=%s\n",gstrSource->str);
332
333 //check existance of sourceitem, and ask for permission for overwrite
334 if (!iDoWeDelete && TRUE == g_file_test( gstrDest->str, G_FILE_TEST_EXISTS)){ //Ask for permission to overwirte existing file
335 if (commstru->bOverWriteAllExisting==-1 && currentItem->bOverWriteExisting==FALSE){
336 myWrap_gdk_threads_enter("copyReMoveItemRecursive 2");
337 iOverwriteRet = MyEasyInputWidget_Two ((GtkWindow *)commstru->mainListWidget, "overwrite", "There is allready an item with the\nsame name in the destination directory.\nDo you want to overwrite it?\n", NULL, NULL, NULL, "Overwrite", "Overwrite all", "No to all", "No");
338 myWrap_gdk_threads_leave("copyReMoveItemRecursive 2");
339 if (iOverwriteRet == 0){ //Overwrite this item
340 //printf("overwrite item\n");
341 currentItem->bOverWriteExisting = TRUE;
342 }
343 else if (iOverwriteRet == 1){ //Overwirte all items
344 //printf("overwrite ALL item\n");
345 currentItem->bOverWriteExisting = TRUE;
346 commstru->bOverWriteAllExisting = 1;
347 }
348 else if (iOverwriteRet == 2){ //No to all, this means we may cancel the whole list.
349 //printf("NO to ALL item\n");
350 commstru->bOverWriteAllExisting = 0;
351 currentItem->status=-10;
352 //commstru->CancelListFunction(commstru);
353 }
354 else if (iOverwriteRet == 3){ //No to this item, we cancel this item
355 //printf("No to this item\n");
356 currentItem->status=-10; //mark it as cancelled
357 }
358 }
359 else if (commstru->bOverWriteAllExisting==0){//-1:not asked, 1=user said yes to all, 0=user said no to all
360 currentItem->status=-10; //mark it as cancelled
361 }
362 }
363
364 if (currentItem->status == 0){ //item in process, this means this function
365 //do not follow links, event if they are pointing to a directory
366 if (TRUE == checkStringIsPath( gstrSource->str ) && FALSE == g_file_test( gstrSource->str, G_FILE_TEST_IS_SYMLINK)){ //open directory and give one item after each other recursive to this function
367 //printf("Identified as path\n");
368 //printf("found dir:%s\n",gstrSource->str);
369 if (!iDoWeDelete){
370 if (TRUE == g_file_test( gstrDest->str, G_FILE_TEST_EXISTS)){
371 if (TRUE == checkStringIsPath( gstrDest->str )){ //check if the directory allready exists
372 iRetFolder = 0; //folder exists, we do not need to build it.
373 }
374 else{
375 iRetFolder = -1; //it seems there is all ready a file with this name, prefents us creating the directory
376 }
377 }
378 else{ //we buld the directory
379 //printf("create Dir: %s\n",gstrDest->str);
380 //gdk_threads_enter();
381 //iRetFolder = makeDirectory(gstrDest->str,0,gstrNames); //create the other directory, stores error message in gstrNames
382 //return 0=ok, 1=error , -1=internal error
383 //myWrap_gdk_threads_leave();
384 Sourcefile = g_file_new_for_path(gstrDest->str);
385 if (FALSE == g_file_make_directory (Sourcefile, commstru->cancellable, &(commstru->gerror)) ){
386 g_string_append(currentItem->ErrorMessage, commstru->gerror->message);
387 iRetFolder = -1;
388 }
389 else{
390 iRetFolder = 0;
391 }
392 if (Sourcefile)
393 g_object_unref(Sourcefile);
394 Sourcefile = NULL;
395 }
396 }
397 else{
398 iRetFolder = 0;
399 }
400 if (0 == iRetFolder){ //directory exists lets get in there
401 iRetErrorCode=1; //so far so good
402 //printf("created Drectory:%s\n",gstrDest->str);
403 //printf("going to open Dir:%s\n", gstrSource->str);
404 if (0 == openLocation(gstrSource->str, &locationStru, FALSE, TRUE)){ //read directories entries and process them
405 iRetErrorCode=1; //so far so good
406 iRecItemCount = 0;
407 iRetRecursivItem = 0;
408 while ( 1==getNextItemInLocation(&locationStru, gstrNames, FALSE, TRUE)){
409 if (strcmp(gstrNames->str,".")!=0 && strcmp(gstrNames->str,"..")!=0){
410 g_string_assign(gstrSource, cpSource);
411 checkPathForLastChar(gstrSource);
412 g_string_append(gstrSource, gstrNames->str);
413
414 //printf("new source is:%s\nnew dest is:%s\n",gstrSource->str, gstrDest->str);
415 if (currentItem->CopyMoveOrRemove == 1){ //copy
416 iRetRecursivItem += copyReMoveItemRecursive(gstrSource->str, gstrDest->str, commstru);
417 }
418 else if (currentItem->CopyMoveOrRemove == 2){ //move
419 //printf("moving %s\n",gstrSource->str);
420 iRetRecursivItem += copyReMoveItemRecursive(gstrSource->str, gstrDest->str, commstru);
421 }
422 else if (currentItem->CopyMoveOrRemove == 3){ //remove
423 //printf("deleting %s\n",gstrSource->str);
424 iRetRecursivItem += copyReMoveItemRecursive(gstrSource->str, NULL, commstru);
425 }
426 iRecItemCount++;
427 }
428 }
429 //closeDirectory(&Directory);
430 closeLocation(&locationStru);
431 if (iRetRecursivItem != iRecItemCount){ //error on one item in the current Directory
432 iRetErrorCode=0;
433 }
434 if (currentItem->CopyMoveOrRemove == 3 || currentItem->CopyMoveOrRemove == 2){ //delete directory when ReMoved
435 if (iRetRecursivItem == iRecItemCount){ //Dont know this makes sence
436 Sourcefile = g_file_new_for_path(cpSource);
437 //printf("try to delete directory %s\n",cpSource);
438 if (commstru->gerror){
439 g_error_free(commstru->gerror);
440 commstru->gerror = NULL;
441 }
442 if (FALSE == g_file_delete (Sourcefile, commstru->cancellable, &(commstru->gerror))){
443 //error deleting source directory
444 g_string_assign ( currentItem->ErrorMessage, "Error: Failed to delete source directory code 1" );
445 if (commstru->gerror){
446 g_string_append(currentItem->ErrorMessage, " Message: ");
447 g_string_append(currentItem->ErrorMessage, commstru->gerror->message);
448 }
449 //printf("error deleting directory 1\n");
450 //printf("Message: %s\n",commstru->gerror->message);
451 iRetErrorCode=0;
452 }
453 else{
454 iRetErrorCode=1;
455 }
456 //printf("going to delete directory:%s\n",cpSource);
457 if (Sourcefile){
458 g_object_unref(Sourcefile);
459 Sourcefile=NULL;
460 }
461 }
462 else{ //error deleting source directory, not empty
463 g_string_assign ( currentItem->ErrorMessage, "Error: Failed to delete source directory code 2" );
464 //printf("error deleting directory 2\n");
465 iRetErrorCode=0;
466 }
467 }
468 }
469 else{
470 g_string_assign ( currentItem->ErrorMessage, "Error: Failed to open source directory" );
471 //printf("error opening source directory\n");
472 iRetErrorCode=0;
473 //failed to open source directory
474 }
475 }
476 else if (iRetFolder == 1){
477 //g_string_assign (currentItem->ErrorMessage, gstrNames->str);
478 iRetErrorCode=0;
479 }
480 else{
481 g_string_assign (currentItem->ErrorMessage, "Error: Failed to create destination directory");
482 //printf("error create destination directory\n");
483 //failed to create destination directory
484 }
485 }
486 else{ //copy a file
487 //printf("Identified as file\n");
488 //prepare listitems member
489 Sourcefile = getCorrectGFileTypeFromLocation(gstrSource->str, NULL);
490 //Sourcefile = g_file_new_for_path(gstrSource->str);
491 if (Sourcefile != NULL){
492 if (!iDoWeDelete)
493 Destfile = g_file_new_for_path(gstrDest->str);
494 if (commstru->gerror != NULL){
495 g_error_free (commstru->gerror);
496 commstru->gerror = NULL;
497 TRACEIT(5,"copyReMoveItemRecursive ErrorStruct was not NULL, checkpoint 1");
498 }
499 if (currentItem->CopyMoveOrRemove == 1){ //copy
500 bRet = g_file_copy ( Sourcefile, Destfile, G_FILE_COPY_OVERWRITE | G_FILE_COPY_NOFOLLOW_SYMLINKS, commstru->cancellable, copyItemRecursive_Callback, (void *)currentItem, &(commstru->gerror));
501 }
502 else if (currentItem->CopyMoveOrRemove == 2){ //move
503 bRet = g_file_move ( Sourcefile, Destfile, G_FILE_COPY_OVERWRITE | G_FILE_COPY_NOFOLLOW_SYMLINKS, commstru->cancellable, copyItemRecursive_Callback, (void *)currentItem, &(commstru->gerror));
504 }
505 else if (currentItem->CopyMoveOrRemove == 3){ //remove
506 bRet = g_file_delete (Sourcefile, commstru->cancellable, &(commstru->gerror));
507 }
508
509 //sprintf("copied: _%s_ TO _%s_\n",gstrSource->str, gstrDest->str);
510 if (bRet)
511 iRetErrorCode = 1;
512 else
513 iRetErrorCode = 0;
514 }
515 else{
516 iRetErrorCode = 0;
517 g_string_assign (currentItem->ErrorMessage, "Error acquiring pointer for source object");
518 }
519 }
520 }
521 else{ //list->status!=-0
522 iRetErrorCode = 0;
523 g_string_assign (currentItem->ErrorMessage, "Cancelled for overwriting");
524 }
525 }
526 //else{
527 // printf("copyReMoveItemRecursive got some bad news for you\n");
528 //}
529
530 if (Sourcefile)
531 g_object_unref(Sourcefile);
532 if (Destfile)
533 g_object_unref(Destfile);
534
535 g_string_free(gstrSource, TRUE);
536 g_string_free(gstrDest, TRUE);
537 g_string_free(gstrNames, TRUE);
538
539 TRACEIT(10,"copyReMoveItemRecursive end");
540 return iRetErrorCode;
541
542 #endif //#ifndef NO_GIO
543 }
544
545
CalcSizeForCopyDialog(struct CopyReMoveList * list)546 void CalcSizeForCopyDialog(struct CopyReMoveList *list){
547 TRACEIT(10,"CalcSizeForCopyDialog start");
548 if (list == NULL ){
549 TRACEIT(2,"CalcSizeForCopyDialog end, Parameter NULL");
550 g_thread_exit(0);
551 }
552 if (list->string1 == NULL){
553 TRACEIT(2,"CalcSizeForCopyDialog end, Parameter2 NULL");
554 g_thread_exit(0);
555 }
556 list->iBytesToCopyIsValid=0;
557 list->iBytesToCopy=0;
558
559 if (0==getDirectorySize(&(list->iBytesToCopy), list->string1, &(list->ibreak), FALSE )){
560 list->iBytesToCopyIsValid=1;
561 }
562 else{
563 list->iBytesToCopyIsValid=2; //in CopyReMoveItemsViaList, in the case we want to move, we have to wait for
564 //the the size thread to finish. �n CopyReMoveItemsViaList we check this variable for 1 or 2 to continue
565 }
566
567 TRACEIT(10,"CalcSizeForCopyDialog end");
568 g_thread_exit(0);
569 }
570
571
CopyReMoveItemsViaList_SizeCalc(void * data)572 void CopyReMoveItemsViaList_SizeCalc (void *data){
573 TRACEIT(10,"CopyReMoveItemsViaList_SizeCalc start");
574 if (data == NULL){
575 TRACEIT(2,"CopyReMoveItemsViaList_SizeCalc ends, parameter NULL" );
576 g_thread_exit(0);
577 }
578 struct ListWidgetCommunicationStruct *commStru=(struct ListWidgetCommunicationStruct *)data;
579 struct CopyReMoveList *list = commStru->firstItem;
580
581 commStru->ui64TotalBytes=0;
582 commStru->iTotalBytesValid=0;
583 while (list){
584 list->threadCalcSize = g_thread_create((GThreadFunc)CalcSizeForCopyDialog, list , TRUE, NULL);
585 if (list->threadCalcSize != NULL){
586 //printf("Joining thread at CopyReMoveItemsViaList_SizeCalc\n");
587 g_thread_join (list->threadCalcSize);
588 list->threadCalcSize = NULL; //do not join again!
589 //printf("Leaving thread join at CopyReMoveItemsViaList_SizeCalc\n");
590 commStru->ui64TotalBytes += list->iBytesToCopy;
591 }
592 list=list->NextItem;
593 }
594 commStru->iTotalBytesValid=1;
595 TRACEIT(10,"CopyReMoveItemsViaList_SizeCalc end");
596 g_thread_exit(0);
597 }
598
599
CopyReMoveItemsViaList(void * data)600 void CopyReMoveItemsViaList(void *data){
601 TRACEIT(10,"CopyReMoveItemsViaList start");
602 if (data == NULL){
603 TRACEIT(2,"CopyReMoveItemsViaList ends, parameter NULL" );
604 g_thread_exit(0);
605 }
606 struct ListWidgetCommunicationStruct *commStru=(struct ListWidgetCommunicationStruct *)data;
607 struct CopyReMoveList *list = NULL;
608 GString *gstrError = g_string_sized_new(20);
609 GString *gstrForTextBuffer = g_string_sized_new(20);
610 GtkTreePath *pTreePath;
611 GtkTreeSelection *selection;
612 int iRet=0;
613 int iBreak=0;
614 myWrap_gdk_threads_enter("CopyReMoveItemsViaList 1");
615 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(commStru->listView));
616 myWrap_gdk_threads_leave("CopyReMoveItemsViaList 1");
617 //int iSomeError=0;
618 int iStillValid=1;
619 GThread *threadCalcSource=NULL;
620
621 /*
622 this function will process only one item: commStru->currentItem and nor more!
623 after this function anther thread (actully the same function) is called to continue the list in commStru->currentItem.
624
625 The threads have to be created as joinable, therefore we have to join the last thread before continuing!
626 */
627
628 commStru->SecondThreadRunning = 1;
629
630 if (NULL != commStru->gthrdCopyReMoveThread_2){
631 //this means that this is NOT the first CopyReMove Thread, as this thread will create the second thread to continue the list
632 if (NULL != commStru->gthrdCopyReMoveThread_1){
633 g_thread_join (commStru->gthrdCopyReMoveThread_1); //make sure, that only one CopyReMove Thread is running at a time and the last threads memory gets freed
634 }
635 commStru->gthrdCopyReMoveThread_1 = commStru->gthrdCopyReMoveThread_2; //forget the old thread and store this thread at the 1st position;
636 commStru->gthrdCopyReMoveThread_2 = NULL;
637 }
638
639
640 list = commStru->currentItem; //for faster writing. and shorter sentences
641 if (NULL == list){
642 //because this function will set the next currentItem for the following thread, the currentItem can be NULL, as the list ends.
643 //So we reached the end of the list and we only have to clear everything as usual
644 iBreak = 2;
645 }
646
647
648 if (iBreak==0 && (list->string1==NULL || ( (list->CopyMoveOrRemove == 1 || list->CopyMoveOrRemove == 2) && list->string2==NULL) )){
649 list->ibreak=1;
650 iBreak = 1;
651 }
652 if (iBreak==0 && (list->status == -10 || commStru->iCancelled==1)){
653 list->ibreak=1;
654 iBreak = 1;
655 }
656
657
658
659
660 if (iBreak==0 && NULL!=commStru->currentItem && commStru->iCancelled==0){
661
662 //list->ibreak=0; //done in ProcessItemsViaList, the previouse function
663 myWrap_gdk_threads_enter("CopyReMoveItemsViaList 2");
664 gtk_tree_selection_select_iter(selection, &(list->iter));
665
666 //make the scrolling follow the marked Item
667 pTreePath = gtk_tree_model_get_path (gtk_tree_view_get_model ((GtkTreeView *)commStru->listView),&(list->iter));
668 gtk_tree_view_scroll_to_cell ((GtkTreeView *)commStru->listView,pTreePath,NULL,TRUE,0.0,0.0);
669 gtk_tree_path_free(pTreePath);
670 myWrap_gdk_threads_leave("CopyReMoveItemsViaList 2");
671
672
673 if (list->ErrorMessage)
674 g_string_free(list->ErrorMessage,TRUE);
675 list->ErrorMessage = g_string_sized_new(10); //make clear this pointer is valid //TODO FREE IT AND FILL IT WITH 0 on list creation
676
677 if (commStru->gerror){
678 g_error_free(commStru->gerror);
679 commStru->gerror=NULL;
680 TRACEIT(10,"copyItemRecursive error struct was not NULL, checkpoint 2");
681 }
682
683 if (list->status == -1){
684 list->status = 0;
685
686 //calc size //the size is calculated in a nother thread now
687 //list->iBytesToCopy = 0;
688 //list->iBytesToCopyIsValid = 0;
689 list->iBytesCopied = -1; //initialize with -1, so we now when to start messuring the time
690 if (list->CopyMoveOrRemove != 3){ //do not calculate this when deleting
691 //threadCalcSource = g_thread_create((GThreadFunc)CalcSizeForCopyDialog, list , TRUE, NULL);
692 threadCalcSource = list->threadCalcSize;
693 }
694 //tell the textBuffer what we are giong to do:
695 if (list->CopyMoveOrRemove == 1){
696 g_string_printf(gstrForTextBuffer, "copying \"%s\" TO \"%s\"",list->string1->str,list->string2->str);
697 }
698 else if (list->CopyMoveOrRemove == 2){
699 while (list->iBytesToCopyIsValid == 0){
700 usleep(10000);
701 //if (list->iBytesToCopyIsValid==0 && threadCalcSource ){
702 // g_thread_join (threadCalcSource); //we should wait for the calcthread before moving.
703 }
704 g_string_printf(gstrForTextBuffer, "moving \"%s\" TO \"%s\"",list->string1->str,list->string2->str);
705 }
706 else if (list->CopyMoveOrRemove == 3){
707 g_string_printf(gstrForTextBuffer, "deleting \"%s\"",list->string1->str);
708 // Set the row for percentage to some text, its better to view something than nothing, because nothing means not processed yet
709 myWrap_gdk_threads_enter("CopyReMoveItemsViaList 3");
710 gtk_list_store_set (commStru->listStore, &(list->iter), 1, "deleting",-1);
711 myWrap_gdk_threads_leave("CopyReMoveItemsViaList 3");
712 }
713 myWrap_gdk_threads_enter("CopyReMoveItemsViaList 4");
714 textbuffer_commandHistory_addText(gstrForTextBuffer->str, NULL);
715 myWrap_gdk_threads_leave("CopyReMoveItemsViaList 4");
716
717 //start copying, this call is synchron
718 iRet = copyReMoveItemRecursive(list->string1->str, (list->string2)?list->string2->str:NULL, commStru);
719
720 if (iRet==1){ //iRet == 1 : Ok
721 list->ibreak=0;
722 myWrap_gdk_threads_enter("CopyReMoveItemsViaList 5");
723 gtk_list_store_set (list->listStore, &(list->iter), 1, "100.00",-1); //when no error occured we assume that we copied 100%
724 myWrap_gdk_threads_leave("CopyReMoveItemsViaList 5");
725 //if (list->CopyMoveOrRemove != 3){
726 //list->threadCalcSizeAfterProcessing = g_thread_create((GThreadFunc)CalcSizeAfterCopyMove, list , TRUE, NULL);
727 //}
728 }
729 else{
730 list->ibreak=1;
731 }
732 }
733
734 if (iRet == 0 ){ //Error copying look GError for information
735 g_string_erase(gstrError,0,-1);
736 if (commStru->gerror){
737 if (G_IO_ERROR_CANCELLED != commStru->gerror->code){
738 g_string_printf(gstrError, "Error: code: %d, message:%s",commStru->gerror->code, commStru->gerror->message);
739 textbuffer_commandHistory_addText(gstrError->str, "error");
740 g_error_free(commStru->gerror);
741 commStru->gerror=NULL;
742 commStru->iSomeError = 1;
743 }
744 else
745 commStru->iSomeError = 2; //do not show the hint that there was an error
746 }
747 else if (strlen (list->ErrorMessage->str) != 0){
748 g_string_assign (gstrError, list->ErrorMessage->str);
749 textbuffer_commandHistory_addText(gstrError->str, "error");
750 commStru->iSomeError = 1;
751 }
752 else{
753 g_string_assign(gstrError, "Unknown error");
754 textbuffer_commandHistory_addText(gstrError->str, "error");
755 commStru->iSomeError = 1;
756 }
757 if (strlen(gstrError->str)>0){
758 myWrap_gdk_threads_enter("CopyReMoveItemsViaList 6");
759 gtk_list_store_set (commStru->listStore, &(list->iter), 3, gstrError->str,-1);
760 myWrap_gdk_threads_leave("CopyReMoveItemsViaList 6");
761 commStru->iSomeError=1;
762 }
763 }
764 else if(iRet == -1){ //internal Error
765 g_string_assign(gstrError, "BAD INTERNAL ERROR, INFORM THE PROGRAMMER");
766 textbuffer_commandHistory_addText(gstrError->str, "error");
767 myWrap_gdk_threads_enter("CopyReMoveItemsViaList 7");
768 gtk_list_store_set (commStru->listStore, &(list->iter), 3, gstrError->str,-1);
769 myWrap_gdk_threads_leave("CopyReMoveItemsViaList 7");
770 commStru->iSomeError=1;
771 }
772 //if (commStru->iCancelled==1){
773 // list->ibreak=1;
774 // break;
775 //}
776 //commStru->currentItem = commStru->currentItem->NextItem;
777 }
778
779 //list->ibreak=1; //for security reason, this cancels the size calculation thread
780 //we can come up here when there was
781 //some error, in this case we may have a cancel
782 //just a cancel
783 //we finished, no error, no cancel
784 //only in the last case we going to close the widget from here
785
786 g_mutex_lock (commStru->mtxContinue);
787 iStillValid = 1;
788 //printf("after thread 2 loop\n");
789 if (iBreak == 2){ //iBreak=2 was set if the currentItem was NULL, in this case, this thread is the last one and we have finished the list
790 //printf("last item in list\n");
791 if (commStru->iCancelled==1 || commStru->iSomeError!=0){ //error or cancel, its not our turn to close the widget, but to update some things
792 //printf("Error or cancel\n");
793 myWrap_gdk_threads_enter("CopyReMoveItemsViaList 8");
794 if (commStru->iSomeError == 1){
795 MyMessageWidget((GtkWindow *)commStru->mainListWidget, "ERROR", "There was at least one Error \nwhile processing the list.\nLook at the column errors and scroll up\ntill you find the error message.");
796 g_string_append(commStru->WindowName," ERROR");
797 }
798 else if (commStru->iCancelled == 1){
799 g_string_append(commStru->WindowName," Cancelled");
800 }
801 gtk_window_set_title((GtkWindow *)commStru->mainListWidget,commStru->WindowName->str);
802
803 gtk_widget_show(GTK_WIDGET(commStru->closeButton));
804 gtk_widget_hide(GTK_WIDGET(commStru->cancelButton));
805
806 gtk_widget_queue_draw ((GtkWidget *)commStru->mainListWidget);
807 myWrap_gdk_threads_leave("CopyReMoveItemsViaList 8");
808
809 }
810 else if (commStru->iCancelDialogRuns==0){
811 //printf("check 2\n");
812 commStru->SecondThreadRunning = 0;
813 g_mutex_unlock (commStru->mtxContinue);
814 iStillValid = 0;
815 myWrap_gdk_threads_enter("CopyReMoveItemsViaList 9");
816 (commStru->FreeMemoryAndDeleteWidgetFunction)( commStru); //here Notify MUST BE 2 other wise this call will lead to a deadlock becuase of SecondThreadRunning
817 myWrap_gdk_threads_leave("CopyReMoveItemsViaList 9");
818 }
819 else{ //the cancel dialog is open
820 //printf("check 3\n");
821 commStru->iDestroyFlag = 1;
822 }
823
824 }
825 else if (0 == commStru->iListPaused){
826 //we will start the next thread, in the case that the next item is NULL, the thread is created without the option to join it:
827 commStru->iNextThreadStarted = 1;
828
829 commStru->currentItem = commStru->currentItem->NextItem;
830
831 if (NULL != commStru->currentItem){
832 commStru->gthrdCopyReMoveThread_2 = g_thread_create((GThreadFunc)CopyReMoveItemsViaList, (void *)commStru , TRUE, NULL);
833 }
834 else {
835 g_thread_create((GThreadFunc)CopyReMoveItemsViaList, (void *)commStru , FALSE, NULL);
836 }
837 }
838 else{
839 commStru->iNextThreadStarted = 0;
840 }
841
842
843 if (1 == iStillValid){
844 commStru->SecondThreadRunning = 0;
845 g_mutex_unlock (commStru->mtxContinue);
846 }
847
848
849
850 //free things
851 g_string_free(gstrError, TRUE);
852 g_string_free(gstrForTextBuffer, TRUE);
853 //commStru->SecondThreadRunning = 0; NOT HERE, because of the last else if
854
855 TRACEIT(10,"CopyReMoveItemsViaList ends");
856 g_thread_exit(0);
857 }
858
859
fileAttributesGet(struct FileAttributs * attribs,char * path,char * name)860 int fileAttributesGet(struct FileAttributs *attribs,char *path, char *name){
861 //DO NOT FORGETT: FREE MEMORY (GSTRING IF IT IS A LINK)
862 //example:
863 // if (attribs->gstrLinkTarget)
864 // g_string_free(attribs->gstrLinkTarget, TRUE);
865 //
866 //name can be NULL, in this case path is expected to be the whole name with path
867 TRACEIT(11,"fileAttributesGet start");
868 int i;
869 if (attribs == NULL || path == NULL){
870 TRACEIT(10,"fileAttributesGet ends");
871 return -1;
872 }
873
874 GString *gstrFullName = g_string_new(path);
875 GString *gstrBuf = g_string_sized_new(10);
876 GString *gstrName = g_string_sized_new(10);
877 struct stat fileattributes;
878
879 attribs->size = 0;
880 attribs->owner = 0;
881 attribs->group = 0;
882 sprintf(attribs->permission,"-");
883 strcat(attribs->permission,"-");
884 strcat(attribs->permission,"-");
885 strcat(attribs->permission,"-");
886 strcat(attribs->permission,"-");
887 strcat(attribs->permission,"-");
888 strcat(attribs->permission,"-");
889 strcat(attribs->permission,"-");
890 strcat(attribs->permission,"-");
891 sprintf(attribs->accessed,"na"); //keep in mind, that the accessed array is 30 bytes in size (defined in listitems.h)
892 sprintf(attribs->changed,"na");
893 attribs->gstrLinkTarget=NULL;
894
895 if ( name!=NULL ){
896 checkPathForLastChar(gstrFullName);
897 g_string_append(gstrFullName, name);
898 }
899
900 if (FALSE == g_file_test(gstrFullName->str,G_FILE_TEST_EXISTS)){
901 g_string_free(gstrFullName,TRUE);
902 g_string_free(gstrBuf,TRUE);
903 g_string_free(gstrName, TRUE);
904 TRACEIT(11,"fileAttributesGet end, File not found");
905 return -1;
906 }
907
908 if (stat(gstrFullName->str, &fileattributes) == -1){
909 sprintf(attribs->accessed,"fstab: errno=%d", errno); //keep in mind, that the accessed array is 30 bytes in size (defined in listitems.h)
910 }
911 else{
912 //size
913 attribs->size = (guint64)fileattributes.st_size;
914
915 //owner
916 attribs->owner = fileattributes.st_uid;
917
918 //group
919 attribs->group = fileattributes.st_gid;
920
921 //permission
922 sprintf(attribs->permission,(S_IRUSR & fileattributes.st_mode)?"r":"-");
923 strcat(attribs->permission,(S_IWUSR & fileattributes.st_mode)?"w":"-");
924 strcat(attribs->permission,(S_IXUSR & fileattributes.st_mode)?"x":"-");
925 strcat(attribs->permission,(S_IRGRP & fileattributes.st_mode)?"r":"-");
926 strcat(attribs->permission,(S_IWGRP & fileattributes.st_mode)?"w":"-");
927 strcat(attribs->permission,(S_IXGRP & fileattributes.st_mode)?"x":"-");
928 strcat(attribs->permission,(S_IROTH & fileattributes.st_mode)?"r":"-");
929 strcat(attribs->permission,(S_IWOTH & fileattributes.st_mode)?"w":"-");
930 strcat(attribs->permission,(S_IXOTH & fileattributes.st_mode)?"x":"-");
931
932 attribs->type_d = (S_IFDIR & fileattributes.st_mode)?4:0;
933 //accessed
934 attribs->utaccessed=fileattributes.st_atime;
935 sprintf(attribs->accessed,"%s", ctime(&fileattributes.st_atime));
936 attribs->accessed[strlen(attribs->accessed)-1]='\0';
937
938 //changed
939 attribs->utchanged=fileattributes.st_mtime;
940 sprintf(attribs->changed,"%s", ctime(&fileattributes.st_mtime));
941 attribs->changed[strlen(attribs->changed)-1]='\0';
942
943 //hiddenfile
944 if (name == NULL){
945 g_string_assign(gstrBuf, gstrFullName->str);
946 getLastStringInPath(gstrBuf);
947 name = gstrBuf->str;
948 }
949 if (name[0] == '.' && strcmp(name,".") != 0 && strcmp(name,"..") != 0)
950 attribs->hiddenfile = TRUE;
951 else
952 attribs->hiddenfile = FALSE;
953 }
954 //check if we have a Link and set the appropriate variables
955 #ifndef NO_GIO
956 attribs->gstrLinkTarget=NULL;
957 GFileInfo *SymlinkInfo=NULL;
958 GFile *Symfile=NULL;
959 const char *cpTarget=NULL;
960 int iItsASymlink=0; //1 if it is a symlink, but its no garantee the links exists!!
961 if (TRUE == g_file_test( gstrFullName->str, G_FILE_TEST_IS_SYMLINK)){
962 //printf("found symlink: %s\n", gstrFullName->str);
963 iItsASymlink=1;
964 attribs->type_d = 10;
965 Symfile = g_file_new_for_path(gstrFullName->str);
966 SymlinkInfo = g_file_query_info (Symfile, G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET,
967 G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
968 NULL,
969 NULL);
970 cpTarget = g_file_info_get_attribute_byte_string (SymlinkInfo,G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET);
971 if (cpTarget){
972 //printf("target: %s\n", cpTarget);
973 attribs->gstrLinkTarget = g_string_new(cpTarget);
974 if (g_file_test( attribs->gstrLinkTarget->str, G_FILE_TEST_EXISTS)){
975 if (checkStringIsPath(attribs->gstrLinkTarget->str)){
976 attribs->type_d=4; //handle as path
977 }
978 else{
979 attribs->type_d=0; //handle as ordinary file
980 }
981 }
982 }
983 else{
984 // printf("No target found\n");
985 }
986
987 if (Symfile)
988 g_object_unref(Symfile);
989 if (SymlinkInfo)
990 g_object_unref(SymlinkInfo);
991 }
992 #endif
993
994 //type
995
996 #ifndef NO_GIO
997 if (iItsASymlink==1 && attribs->gstrLinkTarget !=NULL){
998 g_string_assign (gstrName, attribs->gstrLinkTarget->str);
999 getLastStringInPath(gstrName);
1000 }
1001 else{
1002 g_string_assign(gstrName, name);
1003 }
1004 #endif //#ifndef NO_GIO
1005 #ifdef NO_GIO
1006 g_string_assign(gstrName, name);
1007 #endif //#ifdef NO_GIO
1008 int len = strlen(gstrName->str);
1009 int foundit=0;
1010 for (i=1; i<=MAXTYPELENGTH; i++){
1011 //was len-i<=1 , but then e.g. 1.jpg was not recognized
1012 //if (len - i < 1 || dirzeiger->d_type == 4 || dirzeiger->d_type == 10){ //removed because we need this function for the fileshelf too, and do not have an directory opened
1013 if (len - i < 1 || attribs->type_d == 4 || attribs->type_d == 10){
1014 if (attribs->type_d == 10) //without this, short files will be marked with "-", and than could not be distinguished from directories. important, when marking all items of the same type
1015 foundit = 10;
1016 else if (attribs->type_d == 4)
1017 foundit = 4;
1018 break;
1019 }
1020 if (gstrName->str[len-i] == '.'){
1021 foundit = 1;
1022 strncpy (attribs->type,&(gstrName->str[len-i+1]),FIELDSIZE);
1023 break;
1024 }
1025 }
1026 if (foundit==0)
1027 strncpy(attribs->type,"-",FIELDSIZE); //this things are used to distinguish between types, used when marking all items of the same type
1028 else if(foundit==10)
1029 strncpy(attribs->type,"---",FIELDSIZE);
1030 else if(foundit==4)
1031 strncpy(attribs->type,"--",FIELDSIZE);
1032
1033 g_string_free(gstrName,TRUE);
1034 g_string_free(gstrFullName,TRUE);
1035 g_string_free(gstrBuf,TRUE);
1036
1037 TRACEIT(11,"fileAttributesGet ends");
1038 return 0;
1039 }
1040
1041
openLocation(char * cpLocation,struct myLocationStruct * struLocation,gboolean bUseMessageWidgets,gboolean bMakeThreadSave)1042 int openLocation (char *cpLocation, struct myLocationStruct *struLocation, gboolean bUseMessageWidgets, gboolean bMakeThreadSave){
1043 //this is NOT THREAD SAVE if bUseMessageWidgets == TRUE
1044 //bUseMassageWidget=True: show error messages
1045 //bMakeThreadSave=True: use gdk_threads_enter/leave
1046 //return: 0: success opening directory, -1: error
1047 //the struLocation must be a pointer to a valid structure, it is not created inside here, nor it is freed!!
1048 //however the things which are going to be filled into this structure are freed in closeLocation
1049 //errors on opneing a location are shown as messageboxes from within this function,so the calling function does not have to interprete errors
1050 //EVEN ON AN ERROR YOU HAVE TO CALL closeLocation to free the structure struLocation
1051 TRACEIT(10,"openLocation start");
1052 GString *gstrBuf = g_string_sized_new(10);
1053 if (cpLocation==NULL || struLocation==NULL){
1054 g_string_free(gstrBuf, TRUE);
1055 TRACEIT(2,"openLocation end, Parameter NULL");
1056 return -1;
1057 }
1058
1059 //first step is to initialize the structure (not the structure itself but its member)
1060 struLocation->gfileLocation=NULL;
1061 struLocation->error=NULL;
1062 struLocation->gstrLocation=NULL;
1063 struLocation->enumerator=NULL;
1064 struLocation->gfileInfo=NULL;
1065
1066 int iItsPath = -1; //-1 unknown, 0=uri, 1=path
1067 //first we have to decide if we have a path, or a uri:
1068 //when the first character is a '/' its supposed to be a path.
1069 if (strlen(cpLocation) >= 2){
1070 if (cpLocation[0]=='/')
1071 iItsPath = 1;
1072 else
1073 iItsPath = 0;
1074 }
1075 else{//its a path
1076 iItsPath = 1;
1077 }
1078
1079 if (iItsPath == 1 && checkStringIsPath(cpLocation) == FALSE){
1080 g_string_free(gstrBuf, TRUE);
1081 TRACEIT(7,"openLocation end, directory not found:");
1082 TRACEIT(7,cpLocation);
1083 return -1;
1084 }
1085
1086 struLocation->gstrLocation = g_string_new(cpLocation);
1087
1088 //Now lets create the GFile Object
1089 if (iItsPath == 0){ //uri
1090 struLocation->gfileLocation = g_file_new_for_uri (cpLocation);
1091 }
1092 else if (iItsPath == 1){ //path
1093 struLocation->gfileLocation = g_file_new_for_path (cpLocation);
1094 }
1095 else{
1096 g_string_free(gstrBuf, TRUE);
1097 if (bUseMessageWidgets){
1098 if (bMakeThreadSave)
1099 myWrap_gdk_threads_enter("openLocation 1");
1100 MyMessageWidget(win, "Error", "The type of the location could not be recognized.\nError opening new location");
1101 if (bMakeThreadSave)
1102 myWrap_gdk_threads_leave("openLocation 1");
1103 }
1104 TRACEIT(5,"openLocation end, type not recognized:");
1105 TRACEIT(5,cpLocation);
1106 return -1;
1107 }
1108
1109 struLocation->enumerator = g_file_enumerate_children (struLocation->gfileLocation, "standard::name", G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, &(struLocation->error));
1110 if (struLocation->error != NULL){
1111 if (bUseMessageWidgets){
1112 g_string_printf(gstrBuf, "Unable to open location:\n%s\nError:%d:%s",cpLocation, struLocation->error->code, struLocation->error->message);
1113 if (bMakeThreadSave)
1114 myWrap_gdk_threads_enter("openLocation 2");
1115 MyMessageWidget(NULL,"Error",gstrBuf->str);
1116 if (bMakeThreadSave)
1117 myWrap_gdk_threads_leave("openLocation 2");
1118 }
1119 g_error_free(struLocation->error);
1120 struLocation->error=NULL;
1121 g_string_free(gstrBuf, TRUE);
1122 TRACEIT(5,"openLocation end, location not supported:");
1123 TRACEIT(5,cpLocation);
1124 return -1;
1125 }
1126
1127 g_string_free(gstrBuf, TRUE);
1128 TRACEIT(10,"openLocation end");
1129 return 0; //success, directory opened
1130 }
1131
1132
getNextItemInLocation(struct myLocationStruct * struLocation,GString * gstrName,gboolean bUseMessageWidgets,gboolean bMakeThreadSave)1133 int getNextItemInLocation(struct myLocationStruct *struLocation, GString *gstrName, gboolean bUseMessageWidgets, gboolean bMakeThreadSave){
1134 //return: -1=error, 1=success, 0=no item left
1135 TRACEIT(10,"getNextItemInLocation start");
1136 const char *cpName=NULL;
1137 if (struLocation==NULL || gstrName==NULL){
1138 TRACEIT(2,"getNextItemInLocation end, parameter NULL");
1139 return -1;
1140 }
1141
1142 if (struLocation->gfileLocation==NULL || struLocation->enumerator==NULL){
1143 g_string_erase(gstrName, 0, -1);
1144 TRACEIT(4,"getNextItemInLocation end, struLoction not initialized properly");
1145 return -1;
1146 }
1147
1148 if (struLocation->gfileInfo!=NULL){
1149 g_object_unref(struLocation->gfileInfo);
1150 struLocation->gfileInfo=NULL;
1151 }
1152
1153 struLocation->gfileInfo = g_file_enumerator_next_file (struLocation->enumerator, NULL, &(struLocation->error));
1154
1155 if (struLocation->error != NULL){
1156 if (bUseMessageWidgets){
1157 if (bMakeThreadSave)
1158 myWrap_gdk_threads_enter("getNextItemInLocation 1");
1159 MyMessageWidget(NULL,"Error",struLocation->error->message);
1160 if (bMakeThreadSave)
1161 myWrap_gdk_threads_enter("getNextItemInLocation 1");
1162 }
1163 g_error_free(struLocation->error);
1164 struLocation->error=NULL;
1165 }
1166
1167 if (struLocation->gfileInfo == NULL){ //no item left at location
1168 g_string_erase(gstrName, 0, -1);
1169 TRACEIT(10,"getNextItemInLocation end, location finished");
1170 return 0; //no more items to come
1171 }
1172
1173 //G_FILE_ATTRIBUTE_STANDARD_COPY_NAME , G_FILE_ATTRIBUTE_STANDARD_NAME, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME
1174 //cpName = g_file_info_get_attribute_as_string (struLocation->gfileInfo, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME);
1175 cpName = g_file_info_get_name(struLocation->gfileInfo);
1176 if (cpName==NULL){
1177 //MyMessageWidget(NULL,"Error","Error retreiving name of item at location, aborting.");
1178 TRACEIT(4,"getNextItemInLocation end, Error retreiving name of item at location");
1179 }
1180 else{
1181 g_string_assign(gstrName, cpName);
1182 }
1183
1184 if (struLocation->gfileInfo!=NULL){
1185 g_object_unref(struLocation->gfileInfo);
1186 struLocation->gfileInfo=NULL;
1187 }
1188
1189 TRACEIT(10,"getNextItemInLocation end");
1190 return 1; //more items to come
1191 }
1192
1193
closeLocation(struct myLocationStruct * struLocation)1194 int closeLocation (struct myLocationStruct *struLocation){
1195 //frees all the things created and stored in struLocation.
1196 //make sure you call this function even if one of the leading functions (openLocation ...) fails!
1197 //return: 0=ok, -1=internal error;
1198 TRACEIT(10,"closeLocation start");
1199 if (struLocation == NULL){
1200 TRACEIT(2,"closeLocation end, Parameter NULL");
1201 }
1202
1203 if (struLocation->gstrLocation!=NULL){
1204 g_string_free(struLocation->gstrLocation, TRUE);
1205 struLocation->gstrLocation=NULL;
1206 }
1207
1208 if (struLocation->error!=NULL){
1209 g_error_free(struLocation->error);
1210 struLocation->error=NULL;
1211 }
1212 if (struLocation->gfileInfo!=NULL){
1213 g_object_unref(struLocation->gfileInfo);
1214 struLocation->gfileInfo=NULL;
1215 }
1216
1217 if (struLocation->enumerator!=NULL){
1218 g_file_enumerator_close (struLocation->enumerator,NULL,NULL);
1219 g_object_unref(struLocation->enumerator);
1220 struLocation->enumerator=NULL;
1221 }
1222
1223 if (struLocation->gfileLocation!=NULL){
1224 g_object_unref(struLocation->gfileLocation);
1225 struLocation->gfileLocation=NULL;
1226 }
1227
1228 TRACEIT(10,"closeLocation end");
1229 return 0;
1230 }
1231
1232
getSizeOfSelectedItemsRecursive(struct RecursiveSizeStructure * stru)1233 static void getSizeOfSelectedItemsRecursive(struct RecursiveSizeStructure *stru){
1234 TRACEIT(10,"getSizeOfSelectedItemsRecursive start");
1235
1236 GString *gstrItem=g_string_sized_new(20);
1237 int i;
1238
1239 for (i=0; i<stru->ItemCounter; i++){
1240 if (*(stru->ibreak) != 0){
1241 break;
1242 }
1243 if (stru->intPTypes[i] == 4 /*|| stru->intPTypes[i] == 10*/){
1244 if (stru->SideObjectOrFileshelfItem==SOURCE_SIDEOBJECT){
1245 g_string_assign(gstrItem, stru->gstrPath->str);
1246 checkPathForLastChar(gstrItem);
1247 g_string_append(gstrItem, (stru->gstrDPItems)[i]->str);
1248 }
1249 else{
1250 g_string_assign(gstrItem, (stru->gstrDPItems)[i]->str);
1251 }
1252 if (0 != getDirectorySize(&(stru->guint64_size), gstrItem, stru->ibreak, FALSE)){ //Error opening directory
1253 stru->ErrorOccured=1;
1254 }
1255 }
1256 else{
1257 stru->guint64_size+=stru->intPSizes[i];
1258 }
1259 if (*(stru->ibreak) != 0){
1260 break;
1261 }
1262 }
1263
1264 //clean up
1265 g_string_free(gstrItem,TRUE);
1266
1267 //We are ready for clean up the structure, tell this the other thread:
1268 stru->iReadyForCleanUp = 1;
1269
1270 TRACEIT(10,"getSizeOfSelectedItemsRecursive ends");
1271 g_thread_exit(0);
1272 }
1273
1274
getSizeOfSelectedItemsRecursive_dialog(void * data)1275 void getSizeOfSelectedItemsRecursive_dialog(void *data){
1276 TRACEIT(10,"getSizeOfSelectedItemsRecursive_dialog start");
1277 GtkWidget *dialog, *label;
1278 int i;
1279 int len;
1280 struct RecursiveSizeStructure *stru = (struct RecursiveSizeStructure *) data;
1281 GString *gstrBuf = g_string_sized_new(10);
1282 GString *gstrBuf2 = g_string_sized_new(10);
1283 char buf[320]; //just needed to hold the size (only the number), g_printf does not know how to handle 64bit numbers
1284 GtkButton *CancelButton;
1285 GtkVBox *VBox;
1286 GError *error = NULL;
1287 //GThread *thread = NULL;
1288
1289 myWrap_gdk_threads_enter("getSizeOfSelectedItemsRecursive_dialog 1");
1290
1291 stru->ibreak = malloc (sizeof(int));
1292 *(stru->ibreak) = 0;
1293 stru->theLabel = gtk_label_new("sdf");
1294 stru->iReadyForCleanUp=1;
1295 stru->guint64_size=0;
1296 stru->ErrorOccured=0;
1297
1298 int iNotify=0;
1299
1300 //simple dialog
1301 dialog = CreateMyWindow("Size of selected items",stru->mainWin,400,250,FALSE, TRUE, TRUE, &iNotify, FALSE, FALSE);
1302 //dialog = CreateMyWindow("Size of selected items",NULL,400,250,FALSE, FALSE);
1303 AddMyIconsToWindow((GtkWindow *)dialog);
1304
1305 CancelButton = (GtkButton *)gtk_button_new_with_label("Ok");
1306 g_signal_connect (CancelButton,"clicked",G_CALLBACK(CancelButtonFunctionForIBreak),stru->ibreak);
1307
1308 VBox = g_object_new(GTK_TYPE_VBOX, "spacing", 5, "homogeneous", FALSE, NULL);
1309
1310 g_string_printf(gstrBuf,"\tCalculates the size of the selected items.\t\n\tDirectories are searched recursively.\t\n\n\tItems selected: %d\n",stru->ItemCounter);
1311
1312 label = gtk_label_new(gstrBuf->str);
1313
1314 gtk_box_pack_start(GTK_BOX(VBox),label,TRUE,TRUE,1);
1315 gtk_box_pack_start(GTK_BOX(VBox),stru->theLabel,TRUE,TRUE,1);
1316 gtk_box_pack_start(GTK_BOX(VBox),GTK_WIDGET(CancelButton),FALSE,FALSE,1);
1317 gtk_container_add((GtkContainer *)dialog,(GtkWidget *)VBox);
1318
1319 gtk_widget_show_all(dialog);
1320 myWrap_gdk_threads_leave("getSizeOfSelectedItemsRecursive_dialog 1");
1321
1322 if (stru->ItemStringCounter != stru->ItemCounter){ //Error allocation memory for storing ItemInformation
1323 gtk_label_set_text ((GtkLabel *)stru->theLabel, "Sorry, an error occured while memory allocation.\nUnable to calculate size.");
1324 *(stru->ibreak) = 1;
1325 stru->iReadyForCleanUp = 1;
1326 }
1327 else{
1328 stru->iReadyForCleanUp=0;
1329 //thread = g_thread_create((GThreadFunc)getSizeOfSelectedItemsRecursive, (void *)stru , TRUE, &error);
1330 g_thread_create((GThreadFunc)getSizeOfSelectedItemsRecursive, (void *)stru , FALSE, &error);
1331 if (error != NULL){
1332 TRACEIT (3 ,"getSizeOfSelectedItemsRecursive_dialog error creating thread:");
1333 TRACEIT (3 ,error->message);
1334 g_error_free (error);
1335 error = NULL;
1336 }
1337 //do not make this thread joinable and join in here, because in this case the little widget showing the size
1338 //will not be updated anymore.
1339 //g_thread_join (thread);
1340 }
1341
1342 do{
1343 BytesToHumanityString (stru->guint64_size, gstrBuf2, 0);
1344 snprintf(buf,99,"%lld",stru->guint64_size);
1345 g_string_assign(gstrBuf,buf);
1346 len = strlen(gstrBuf->str)-3;
1347 while (len>0){
1348 g_string_insert_c(gstrBuf,len,'.');
1349 len -=3;
1350 }
1351 strcpy(buf,gstrBuf->str);
1352 if (stru->ErrorOccured == 1){
1353 g_string_sprintf(gstrBuf,"\tSelected need %s (%s bytes)\t\nBut there was at least one directory\nthat could not be opened.",gstrBuf2->str, buf);
1354 }
1355 else{
1356 g_string_sprintf(gstrBuf,"\tSelected need %s (%s bytes)\t",gstrBuf2->str, buf);
1357 }
1358 myWrap_gdk_threads_enter("getSizeOfSelectedItemsRecursive_dialog 2" );
1359 if (iNotify==1){ //as long this is 1 the dialog is valid and was not destroyed
1360 gtk_label_set_text ((GtkLabel *)stru->theLabel, gstrBuf->str);
1361 }
1362 else{
1363 *(stru->ibreak)=1;
1364 }
1365 myWrap_gdk_threads_leave("getSizeOfSelectedItemsRecursive_dialog 2");
1366 usleep(100000);
1367 }while(*(stru->ibreak) == 0);
1368
1369 while (stru->iReadyForCleanUp != 1){
1370 //The other thread has not finished yet, we should wait for him.
1371 usleep(100000);
1372 }
1373
1374 myWrap_gdk_threads_enter("getSizeOfSelectedItemsRecursive_dialog 3");
1375 if (iNotify==1){ //then, the window was closed by our ok-button and not by upper-right-corner-X, so we have to destroy the window by ourself
1376 gtk_widget_destroy(dialog);
1377 }
1378 myWrap_gdk_threads_leave("getSizeOfSelectedItemsRecursive_dialog3 ");
1379
1380 //free everything in the struct and the struct itself
1381 free(stru->ibreak);
1382 if (stru->gstrPath != NULL){
1383 g_string_free(stru->gstrPath,TRUE);
1384 }
1385 for (i=0; i<stru->ItemStringCounter; i++){
1386 g_string_free(stru->gstrDPItems[i], TRUE);
1387 }
1388 free(stru->gstrDPItems);
1389 free(stru->intPSizes);
1390 free(stru->intPTypes);
1391 free(stru);
1392 stru = NULL;
1393 g_string_free(gstrBuf,TRUE);
1394 g_string_free(gstrBuf2, TRUE);
1395
1396 TRACEIT(10,"getSizeOfSelectedItemsRecursive_dialog ends");
1397 g_thread_exit(0);
1398 }
1399
1400
getDirectorySize(guint64 * size,GString * gstrDirectory,int * ibreak,gboolean bFollowLinks)1401 int getDirectorySize(guint64 *size, GString *gstrDirectory, int *ibreak, gboolean bFollowLinks){
1402 //calls openLocation which is thread save in here, because this function is called
1403 //only from other threads
1404 //stops when ibreak == 1
1405 TRACEIT(10,"getDirectorySize start");
1406 if (size == NULL || gstrDirectory == NULL || ibreak == NULL){
1407 TRACEIT(2,"getDirectorySize end, Parameter NULL");
1408 return -1;
1409 }
1410 if (FALSE == g_file_test( gstrDirectory->str, G_FILE_TEST_EXISTS)){
1411 TRACEIT(2,"getDirectorySize end, error opening item:");
1412 return -1;
1413 }
1414 GString *gstrNames = g_string_new(gstrDirectory->str);
1415 GString *Path= g_string_new(gstrDirectory->str);
1416 struct FileAttributs attribs;
1417 struct myLocationStruct locationStru;
1418 int iFoundLink = 0;
1419
1420 //check if we have an Directory
1421 if (FALSE == checkStringIsPath( gstrDirectory->str )){ //then we have no directory
1422 checkPathForLastCharOtherwise(gstrNames);
1423 getLastStringInPath(gstrNames);
1424 GetPathFromPathWithName(Path, 1);
1425 if (strcmp(gstrNames->str,".")!=0 && strcmp(gstrNames->str,"..")!=0){
1426 fileAttributesGet( &attribs, Path->str, gstrNames->str);
1427 if (attribs.gstrLinkTarget){
1428 g_string_free(attribs.gstrLinkTarget, TRUE);
1429 }
1430 *size+=attribs.size;
1431 }
1432 g_string_free(gstrNames,TRUE);
1433 g_string_free(Path,TRUE);
1434 TRACEIT(10,"getDirectorySize end");
1435 return 0;
1436 }
1437
1438 if (0 != openLocation(gstrDirectory->str, &locationStru, FALSE, TRUE)){
1439 closeLocation(&locationStru);
1440 g_string_free(gstrNames,TRUE);
1441 g_string_free(Path,TRUE);
1442 TRACEIT(2,"getDirectorySize end, could not open directory");
1443 return -1;
1444 }
1445
1446 while ( 1 == getNextItemInLocation(&locationStru, gstrNames, FALSE, TRUE) && *ibreak == 0){
1447
1448 //fileAttributesGet(dirzeiger, DirectoryOpened, &attribs, gstrDirectory->str, gstrNames->str);
1449 fileAttributesGet(&attribs, gstrDirectory->str, gstrNames->str);
1450 if (attribs.gstrLinkTarget){
1451 iFoundLink = 1;
1452 g_string_free(attribs.gstrLinkTarget, TRUE);
1453 }
1454 if (strcmp(gstrNames->str,".")!=0 && strcmp(gstrNames->str,"..")!=0 && ( attribs.type_d==4 && (iFoundLink!=1 || bFollowLinks==TRUE ) ) ){
1455 g_string_assign(Path,gstrDirectory->str);
1456 checkPathForLastChar(Path);
1457 g_string_append(Path,gstrNames->str);
1458 getDirectorySize(size, Path, ibreak, bFollowLinks);
1459 }
1460 else if (strcmp(gstrNames->str,".")!=0 && strcmp(gstrNames->str,"..")!=0){
1461 *size+=attribs.size;
1462 }
1463 }
1464
1465 //S�ubern:
1466 closeLocation(&locationStru);
1467 g_string_free(gstrNames,TRUE);
1468 g_string_free(Path,TRUE);
1469
1470 TRACEIT(10,"getDirectorySize end");
1471 if (*ibreak == 0){
1472 return 0;
1473 }
1474 else{
1475 return -1;
1476 }
1477 }
1478
1479
markedNamesToClipboard_Helper(GtkTreeModel * model,GtkTreePath * path,GtkTreeIter * iter,gpointer data)1480 static void markedNamesToClipboard_Helper(GtkTreeModel *model,GtkTreePath *path,GtkTreeIter *iter,gpointer data){
1481 TRACEIT(11,"markedNamesToClipboard_Helper start");
1482 if (data == NULL){
1483 TRACEIT(2,"markedNamesToClipboard_Helper end, PARAMETER NULL");
1484 return;
1485 }
1486 struct AllInformationAllUseStruct *stru = (struct AllInformationAllUseStruct *)data;
1487 gchar *Name=NULL;
1488 gchar *Path=NULL;
1489
1490 GString *gstrNames = (GString *)stru->Info_1;
1491 int iColumnName = *(int *)stru->Info_2;
1492 gboolean bWithPath = *(gboolean *)stru->Info_3;
1493 int iColumnPath = *(int *)stru->Info_4;
1494 char *cpPath = (char *)stru->Info_5;
1495
1496 gtk_tree_model_get(model, iter, iColumnName, &Name, -1);
1497
1498 if (gstrNames->len != 0){
1499 g_string_append(gstrNames, " ");
1500 }
1501
1502 if (bWithPath == TRUE){
1503 if (cpPath != NULL){
1504 g_string_append(gstrNames, cpPath);
1505 }
1506 else if (iColumnPath > -1){
1507 gtk_tree_model_get(model, iter, iColumnPath, &Path, -1);
1508 g_string_append(gstrNames, Path);
1509 }
1510 else{
1511 TRACEIT(2,"markedNamesToClipboard_Helper parameter validation error");
1512 }
1513 checkPathForLastChar(gstrNames);
1514 }
1515
1516 g_string_append(gstrNames, Name);
1517
1518 if (Name)
1519 g_free(Name);
1520 if (Path)
1521 g_free(Path);
1522
1523 TRACEIT(11,"markedNamesToClipboard_Helper end");
1524 }
1525
1526
markedNamesToClipboard(GtkTreeView * TreeView,gboolean bWithPath,int iColumnName,int iColumnPath,char * cpPath)1527 void markedNamesToClipboard(GtkTreeView *TreeView, gboolean bWithPath, int iColumnName, int iColumnPath, char *cpPath){
1528 //copies the names marked in the TreeView to the real clipboard, if more than one item is marked, all names are copied to one single line
1529 //if bWithPath is TRUE, the pathes are added to the names.
1530 //if bWithPath is FALSE, only the names are copied
1531 //the names are searched in the column iColumnName
1532 //when bWithPath is TRUE, iColumnPath or cpPath must be valid. cpPath is checked for NULL, iColumnPath is checked for < 0
1533 TRACEIT(10,"markedNamesToClipboard start");
1534 GtkTreeSelection *selection;
1535 struct AllInformationAllUseStruct stru;
1536 GString *gstrNames=NULL;
1537 GtkClipboard *ClipBoard=NULL;
1538
1539 if (TreeView == NULL){
1540 TRACEIT(2,"markedNamesToClipboard end, PARAMETER NULL");
1541 return;
1542 }
1543
1544 //validate:
1545 if (bWithPath == TRUE && cpPath==NULL && iColumnPath<0){
1546 TRACEIT(2,"markedNamesToClipboard end, parameter validation error");
1547 return;
1548 }
1549
1550 gstrNames = g_string_sized_new(10);
1551 stru.Info_1 = (void *)gstrNames;
1552 stru.Info_2 = (void *)&iColumnName;
1553 stru.Info_3 = (void *)&bWithPath;
1554 stru.Info_4 = (void *)&iColumnPath;
1555 stru.Info_5 = (void *)cpPath;
1556
1557 selection = gtk_tree_view_get_selection(TreeView);
1558 gtk_tree_selection_selected_foreach(selection, markedNamesToClipboard_Helper, (void *)&stru);
1559
1560 //printf("gstrNames = %s\nlen=%d\n",gstrNames->str, gstrNames->len);
1561
1562 ClipBoard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
1563 if (ClipBoard != NULL){
1564 gtk_clipboard_set_text (ClipBoard, gstrNames->str, gstrNames->len);
1565 }
1566 else{
1567 TRACEIT(2,"markedNamesToClipboard end, could not achive clipboard object");
1568 }
1569
1570 if (gstrNames)
1571 g_string_free(gstrNames, TRUE);
1572
1573 TRACEIT(10,"markedNamesToClipboard end");
1574 }
1575
1576
mySelectAllFunction_Helper(GtkTreeModel * model,GtkTreePath * path,GtkTreeIter * iter,gpointer data)1577 static void mySelectAllFunction_Helper(GtkTreeModel *model,GtkTreePath *path,GtkTreeIter *iter,gpointer data){
1578 //if (gtk_tree_model_get_iter(model, iter, path)){
1579 TRACEIT(10,"mySelectAllFunction_Helper start");
1580
1581 // 1'st POSSIBILITY
1582 struct AllInformationAllUseStruct *stru = (struct AllInformationAllUseStruct *)data;
1583 GtkTreeSelection **selection = (GtkTreeSelection **)stru->Info_2;
1584 int *found = (int *)stru->Info_1;
1585 if (*found >= 2){
1586 TRACEIT(10,"mySelectAllFunction_Helper end, . and .. already found");
1587 return;
1588 }
1589 gchar *Name=NULL;
1590 gtk_tree_model_get(model, iter, COL_NAME, &Name, -1);
1591
1592 if ((strcmp(Name, "..")==0 || strcmp(Name,".")==0)){
1593 (*found)+=1;
1594 gtk_tree_selection_unselect_iter(*selection, iter);
1595 }
1596
1597 if (Name)
1598 g_free(Name);
1599 // END 1'st POSSIBILITY
1600
1601 /*
1602
1603 // 2'st POSSIBILITY
1604 gchar *Name=NULL;
1605 GtkTreeSelection **selection = (GtkTreeSelection **)data;
1606 gtk_tree_model_get(model, iter, COL_NAME, &Name, -1);
1607 //gtk_tree_model_get(model, iter, COL_NAME, &Name, -1);
1608 if (Name != NULL && !(strcmp(Name, "..")==0 || strcmp(Name,".")==0)){
1609 gtk_tree_selection_select_iter(*selection, iter);
1610 }
1611 if (Name)
1612 g_free(Name);
1613 // END 2'st POSSIBILITY
1614 */
1615 TRACEIT(10,"mySelectAllFunction_Helper end");
1616 }
1617
1618
mySelectAllFunction(GtkTreeView * treeview,gpointer user_data)1619 gboolean mySelectAllFunction( GtkTreeView *treeview, gpointer user_data){
1620 //catches the signel select-all from within the listviews (side views only)
1621 TRACEIT(10,"mySelectAllFunction start");
1622
1623 // 1'st POSSIBILITY
1624 GtkTreeSelection *selection;
1625 struct AllInformationAllUseStruct stru;
1626 int found=0;
1627 stru.Info_1 = (void *)&found;
1628 stru.Info_2 = (void *)&selection;
1629 stru.Info_3 = NULL;
1630 stru.Info_4 = NULL;
1631 stru.Info_5 = NULL;
1632
1633 selection = gtk_tree_view_get_selection(treeview);
1634 gtk_tree_selection_select_all ( selection );
1635 gtk_tree_selection_selected_foreach(selection, mySelectAllFunction_Helper, (void *)&stru);
1636 // END 1'st POSSIBILITY
1637
1638
1639 /*
1640 // 2'st POSSIBILITY
1641 GtkTreeSelection *selection; // Tested within the library directory with more than 200 entries: this solution is realy slow!!
1642 selection = gtk_tree_view_get_selection(treeview);
1643 struct SideObjectList *Object = (struct SideObjectList *)user_data;
1644 gtk_tree_model_foreach(GTK_TREE_MODEL(Object->listStore),(GtkTreeModelForeachFunc) mySelectAllFunction_Helper,(void *)&selection);
1645 // END 2'st POSSIBILITY
1646 */
1647 TRACEIT(10,"mySelectAllFunction end");
1648 return TRUE;
1649 }
1650
1651
markItemsWithSameType_Helper_1(GtkTreeModel * model,GtkTreePath * path,GtkTreeIter * iter,gpointer data)1652 static void markItemsWithSameType_Helper_1(GtkTreeModel *model,GtkTreePath *path,GtkTreeIter *iter,gpointer data){
1653 TRACEIT(11,"markItemsWithSameType_Helper_1 start");
1654
1655 struct AllInformationAllUseStruct *stru = (struct AllInformationAllUseStruct *)data;
1656 struct updateList **typeList=(struct updateList **)stru->Info_1;
1657 int *ColType = stru->Info_2;
1658
1659 gchar *type=NULL;
1660 gchar *typebuf=NULL;
1661
1662 gtk_tree_model_get(model, iter, *ColType,&type, -1);
1663
1664 typebuf = g_utf8_strdown(type,-1);
1665 if (*typeList != NULL){
1666 if (0==updateList_checkForItem_NoRef(typeList, typebuf)){
1667 updateList_addItem(typeList, typebuf, NULL, NULL, 0);
1668 }
1669 }
1670 else{
1671 updateList_addItem(typeList, typebuf, NULL, NULL, 0);
1672 }
1673
1674 if (type)
1675 g_free(type);
1676 if (typebuf)
1677 g_free(typebuf);
1678 TRACEIT(11,"markItemsWithSameType_Helper_1 end");
1679 }
1680
1681
markItemsWithSameType_Helper_2(GtkTreeModel * model,GtkTreePath * path,GtkTreeIter * iter,gpointer data)1682 static void markItemsWithSameType_Helper_2(GtkTreeModel *model,GtkTreePath *path,GtkTreeIter *iter,gpointer data){
1683 TRACEIT(11,"markItemsWithSameType_Helper_2 start");
1684
1685 struct AllInformationAllUseStruct *stru = (struct AllInformationAllUseStruct *)data;
1686 struct updateList **typeList=(struct updateList **)stru->Info_1;
1687 int *ColType = stru->Info_2;
1688 GtkTreeSelection *selection = (GtkTreeSelection *)stru->Info_3;
1689
1690 gchar *type=NULL;
1691 gchar *typebuf=NULL;
1692
1693 gtk_tree_model_get(model, iter, *ColType,&type, -1);
1694
1695 typebuf = g_utf8_strdown(type,-1);
1696 struct updateList *bufList = *typeList;
1697 updateList_getFirstItem(&bufList);
1698
1699 if (0==updateList_checkForItem_NoRef(&bufList, typebuf)){
1700 gtk_tree_selection_unselect_iter(selection, iter);
1701 }
1702
1703 if (type)
1704 g_free(type);
1705 if (typebuf)
1706 g_free(typebuf);
1707 TRACEIT(11,"markItemsWithSameType_Helper_2 end");
1708 }
1709
1710
markItemsWithSameType(GtkTreeView * treeview,int ColType)1711 void markItemsWithSameType(GtkTreeView *treeview, int ColType){
1712 //selects all items in treeview wich are from the same type as the already marked one.
1713 //ColType holds the ID of the coloumn with the type information
1714
1715
1716 //get the types of all marked items and put them to in a list
1717 struct AllInformationAllUseStruct stru;
1718 struct updateList *typeList=NULL;
1719
1720 stru.Info_1 = (void *)&typeList;
1721 stru.Info_2 = (void *)&ColType;
1722
1723 GtkTreeSelection *selection;
1724 selection = gtk_tree_view_get_selection(treeview);
1725 gtk_tree_selection_selected_foreach(selection, markItemsWithSameType_Helper_1, (void *)&stru);
1726
1727 //The list is ready, now mark all items and walk throught the view and unmark the right ones.
1728 stru.Info_3 = (void *)selection;
1729 gtk_tree_selection_select_all(selection);
1730
1731 gtk_tree_selection_selected_foreach(selection, markItemsWithSameType_Helper_2, (void *)&stru);
1732
1733
1734 //now the . and .. may be marked: check this
1735 int found=0;
1736 stru.Info_1 = (void *)&found;
1737 stru.Info_2 = (void *)&selection;
1738 gtk_tree_selection_selected_foreach(selection, mySelectAllFunction_Helper, (void *)&stru);
1739
1740 updateList_deleteList(&typeList);
1741
1742 }
1743
1744