1 /*
2  *
3  *   File: interface.c
4  *
5  *   Copyright (C) 2009-2013 Darran Kartaschew
6  *
7  *   This file is part of the gMTP package.
8  *
9  *   gMTP is free software; you can redistribute it and/or modify
10  *   it under the terms of the BSD License as included within the
11  *   file 'COPYING' located in the root directory
12  *
13  */
14 
15 #include "interface.h"
16 
17 #include <string.h>
18 #include <strings.h>
19 #include <unistd.h>
20 
21 #include <libgen.h>
22 #include <gdk/gdkkeysyms.h>
23 #if HAVE_GTK3 == 0
24 #include <gconf/gconf.h>
25 #include <gconf/gconf-client.h>
26 #else
27 #include <gio/gio.h>
28 #include <gdk/gdkkeysyms-compat.h>
29 #endif
30 
31 #include "main.h"
32 #include "mtp.h"
33 #include "callbacks.h"
34 #include "preferences.h"
35 #include "dnd.h"
36 #include "prefs.h"
37 #include "properties.h"
38 #include "playlist.h"
39 #include "albumart.h"
40 #include "formatdevice.h"
41 #include "progress.h"
42 
43 void setupFileList();
44 GtkTreeViewColumn *setupFolderList();
45 void __fileRemove(GtkTreeRowReference *Row);
46 void __fileDownload(GtkTreeRowReference *Row);
47 void __folderRemove(GtkTreeRowReference *Row);
48 
49 GtkWidget *windowMain;
50 GtkWidget *scrolledwindowMain;
51 GtkWidget *toolbuttonAddFile;
52 GtkWidget *toolbuttonRetrieve;
53 GtkWidget *toolbuttonRemoveFile;
54 GtkWidget *toolbuttonRescan;
55 GtkWidget *toolbuttonAlbumArt;
56 GtkWidget *toolbuttonPlaylist;
57 GtkWidget *toolbuttonProperties;
58 GtkWidget *properties1;
59 GtkWidget *fileConnect;
60 GtkWidget *fileAdd;
61 GtkWidget *fileDownload;
62 GtkWidget *fileRemove;
63 GtkWidget *fileRename;
64 GtkWidget *fileMove;
65 GtkWidget *fileNewFolder;
66 GtkWidget *fileRemoveFolder;
67 GtkWidget *fileRescan;
68 GtkWidget *editDeviceName;
69 GtkWidget *editFormatDevice;
70 GtkWidget *editAddAlbumArt;
71 GtkWidget *editPlaylist;
72 GtkWidget *editFind;
73 GtkWidget *editSelectAll;
74 
75 GtkWidget *contextMenu;
76 GtkWidget *contextMenuColumn;
77 GtkWidget *contextMenuFolder;
78 GtkWidget* cfileAdd;
79 GtkWidget* cfileNewFolder;
80 
81 // Main toolbar parent container.
82 GtkWidget *handlebox1;
83 GtkWidget *toolbarMain; // The actual toolbar.
84 
85 GtkWidget *findToolbar;
86 
87 GtkWidget *scrolledwindowFolders;
88 
89 #if HAVE_GTK3 == 0
90 GtkTooltips *tooltipsToolbar;
91 #endif
92 
93 GtkListStore *fileList;
94 GtkTreeModel *fileListModel;
95 GtkTreeSelection *fileSelection;
96 GtkTreeStore *folderList;
97 GtkTreeModel *folderListModel;
98 GtkTreeViewColumn *folderColumn;
99 GtkTreeSelection *folderSelection;
100 GList *fileSelection_RowReferences = NULL;
101 
102 gulong folderSelectHandler = 0;
103 gulong fileSelectHandler = 0;
104 
105 // Columns in main file view;
106 GtkTreeViewColumn *column_Size;
107 GtkTreeViewColumn *column_Type;
108 GtkTreeViewColumn *column_Track_Number;
109 GtkTreeViewColumn *column_Title;
110 GtkTreeViewColumn *column_Artist;
111 GtkTreeViewColumn *column_Album;
112 GtkTreeViewColumn *column_Year;
113 GtkTreeViewColumn *column_Genre;
114 GtkTreeViewColumn *column_Duration;
115 GtkTreeViewColumn *column_Location;
116 
117 GtkWidget *menu_view_filesize;
118 GtkWidget *menu_view_filetype;
119 GtkWidget *menu_view_track_number;
120 GtkWidget *menu_view_title;
121 GtkWidget *menu_view_artist;
122 GtkWidget *menu_view_album;
123 GtkWidget *menu_view_year;
124 GtkWidget *menu_view_genre;
125 GtkWidget *menu_view_duration;
126 GtkWidget *menu_view_folders;
127 GtkWidget *menu_view_toolbar;
128 
129 GtkWidget* cViewSize;
130 GtkWidget* cViewType;
131 GtkWidget* cViewTrackName;
132 GtkWidget* cViewTrackNumber;
133 GtkWidget* cViewArtist;
134 GtkWidget* cViewAlbum;
135 GtkWidget* cViewYear;
136 GtkWidget* cViewGenre;
137 GtkWidget* cViewDuration;
138 
139 GtkWidget* cfFolderAdd;
140 GtkWidget* cfFolderDelete;
141 GtkWidget* cfFolderRename;
142 GtkWidget* cfFolderMove;
143 GtkWidget* cfFolderRefresh;
144 
145 // Flags for overwriting files of host PC and device.
146 gint fileoverwriteop = MTP_ASK;
147 // Flag to allow overwrite of files on device.
148 gint deviceoverwriteop = MTP_ASK;
149 
150 // Find options and variables.
151 gboolean inFindMode = FALSE;
152 GSList *searchList = NULL;
153 GtkWidget *FindToolbar_entry_FindText;
154 GtkWidget *FindToolbar_checkbutton_FindFiles;
155 GtkWidget *FindToolbar_checkbutton_TrackInformation;
156 
157 // Combobox used in AddTrackPlaylist feature.
158 GtkWidget *combobox_AddTrackPlaylist;
159 
160 // File/Folder Move operations.
161 int64_t fileMoveTargetFolder = 0;
162 
163 // ************************************************************************************************
164 
create_windowMain(void)165 GtkWidget* create_windowMain(void) {
166     GtkWidget *vbox1;
167     GtkWidget *menubarMain;
168     GtkWidget *menuitem1;
169     GtkWidget *menuitem1_menu;
170     GtkWidget *menuseparator1;
171     GtkWidget *menuseparator2;
172     GtkWidget *menuseparator3;
173     GtkWidget *menuseparator4;
174     GtkWidget *menuseparator5;
175     GtkWidget *menuseparator6;
176     GtkWidget *menuseparator7;
177     GtkWidget *menuseparator8;
178     GtkWidget *menuseparator9;
179     GtkWidget *menuseparator10;
180     GtkWidget *quit1;
181     GtkWidget *menuitem2;
182     GtkWidget *menuitem2_menu;
183     GtkWidget *preferences1;
184     GtkWidget *menuView;
185     GtkWidget *menuView_menu;
186 
187     GtkWidget *menuitem4;
188     GtkWidget *menuitem4_menu;
189     GtkWidget *about1;
190 
191     gint tmp_toolbar_icon_size;
192     GtkWidget *tmp_image;
193     GtkWidget *toolbuttonPreferences;
194     GtkWidget *hpanel;
195 
196     GtkWidget *toolbarSeparator;
197     GtkWidget *toolbarSeparator2;
198     //GtkWidget *toolbuttonQuit;
199 
200     GtkWidget *FindToolbar_hbox_FindToolbar;
201     GtkWidget *FindToolbar_label_FindLabel;
202     GtkWidget *FindToolbar_FindButton;
203     GtkWidget *FindToolbar_CloseButton;
204 
205     GtkAccelGroup *accel_group;
206 
207     accel_group = gtk_accel_group_new();
208 
209     windowMain = gtk_window_new(GTK_WINDOW_TOPLEVEL);
210     setWindowTitle(NULL);
211     gtk_window_set_default_size(GTK_WINDOW(windowMain), 880, 400);
212     gtk_window_set_icon_from_file(GTK_WINDOW(windowMain), file_icon48_png, NULL);
213 #if HAVE_GTK3 == 0
214     vbox1 = gtk_vbox_new(FALSE, 0);
215 #else
216     vbox1 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
217 #endif
218     gtk_widget_show(vbox1);
219     gtk_container_add(GTK_CONTAINER(windowMain), vbox1);
220 
221     menubarMain = gtk_menu_bar_new();
222     gtk_widget_show(menubarMain);
223     gtk_box_pack_start(GTK_BOX(vbox1), menubarMain, FALSE, FALSE, 0);
224 
225     menuitem1 = gtk_menu_item_new_with_mnemonic(_("_File"));
226     gtk_widget_show(menuitem1);
227     gtk_container_add(GTK_CONTAINER(menubarMain), menuitem1);
228 
229     menuitem1_menu = gtk_menu_new();
230     gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem1), menuitem1_menu);
231 
232     fileConnect = gtk_menu_item_new_with_mnemonic(_("_Connect Device"));
233     gtk_widget_show(fileConnect);
234     gtk_container_add(GTK_CONTAINER(menuitem1_menu), fileConnect);
235 
236     menuseparator4 = gtk_separator_menu_item_new();
237     gtk_widget_show(menuseparator4);
238     gtk_container_add(GTK_CONTAINER(menuitem1_menu), menuseparator4);
239 
240     fileAdd = gtk_menu_item_new_with_label(_("Add Files"));
241     gtk_widget_show(fileAdd);
242     gtk_container_add(GTK_CONTAINER(menuitem1_menu), fileAdd);
243 
244     fileRemove = gtk_menu_item_new_with_label(_("Delete Files"));
245     gtk_widget_show(fileRemove);
246     gtk_container_add(GTK_CONTAINER(menuitem1_menu), fileRemove);
247 
248     fileRename = gtk_menu_item_new_with_label(_("Rename Files"));
249     gtk_widget_show(fileRename);
250     gtk_container_add(GTK_CONTAINER(menuitem1_menu), fileRename);
251 
252     fileMove = gtk_menu_item_new_with_label(_("Move To..."));
253     gtk_widget_show(fileMove);
254     gtk_container_add(GTK_CONTAINER(menuitem1_menu), fileMove);
255 
256     fileDownload = gtk_menu_item_new_with_label(_("Download Files"));
257     gtk_widget_show(fileDownload);
258     gtk_container_add(GTK_CONTAINER(menuitem1_menu), fileDownload);
259 
260     menuseparator1 = gtk_separator_menu_item_new();
261     gtk_widget_show(menuseparator1);
262     gtk_container_add(GTK_CONTAINER(menuitem1_menu), menuseparator1);
263 
264     fileNewFolder = gtk_menu_item_new_with_label(_("Create Folder"));
265     gtk_widget_show(fileNewFolder);
266     gtk_container_add(GTK_CONTAINER(menuitem1_menu), fileNewFolder);
267 
268     fileRemoveFolder = gtk_menu_item_new_with_label(_("Delete Folder"));
269     gtk_widget_show(fileRemoveFolder);
270     gtk_container_add(GTK_CONTAINER(menuitem1_menu), fileRemoveFolder);
271 
272     menuseparator2 = gtk_separator_menu_item_new();
273     gtk_widget_show(menuseparator2);
274     gtk_container_add(GTK_CONTAINER(menuitem1_menu), menuseparator2);
275 
276     fileRescan = gtk_menu_item_new_with_label(_("Refresh Folder"));
277     //menuText = gtk_bin_get_child(GTK_BIN(fileRescan));
278     //gtk_label_set_text(GTK_LABEL(menuText), _("Refresh Device"));
279     gtk_widget_show(fileRescan);
280     gtk_container_add(GTK_CONTAINER(menuitem1_menu), fileRescan);
281 
282     properties1 = gtk_menu_item_new_with_label(_("Device Properties"));
283     //menuText = gtk_bin_get_child(GTK_BIN(properties1));
284     //gtk_label_set_text(GTK_LABEL(menuText), _("Device Properties"));
285     gtk_widget_show(properties1);
286     gtk_container_add(GTK_CONTAINER(menuitem1_menu), properties1);
287 
288     menuseparator3 = gtk_separator_menu_item_new();
289     gtk_widget_show(menuseparator3);
290     gtk_container_add(GTK_CONTAINER(menuitem1_menu), menuseparator3);
291 
292     quit1 = gtk_menu_item_new_with_mnemonic(_("_Quit"));
293     gtk_widget_show(quit1);
294     gtk_container_add(GTK_CONTAINER(menuitem1_menu), quit1);
295 
296     menuitem2 = gtk_menu_item_new_with_mnemonic(_("_Edit"));
297     gtk_widget_show(menuitem2);
298     gtk_container_add(GTK_CONTAINER(menubarMain), menuitem2);
299 
300     menuitem2_menu = gtk_menu_new();
301     gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem2), menuitem2_menu);
302 
303     editSelectAll = gtk_menu_item_new_with_label(_("Select All"));
304     gtk_widget_show(editSelectAll);
305     gtk_container_add(GTK_CONTAINER(menuitem2_menu), editSelectAll);
306 
307     menuseparator6 = gtk_separator_menu_item_new();
308     gtk_widget_show(menuseparator6);
309     gtk_container_add(GTK_CONTAINER(menuitem2_menu), menuseparator6);
310 
311     editFind = gtk_menu_item_new_with_label(_("Find"));
312     gtk_widget_show(editFind);
313     gtk_container_add(GTK_CONTAINER(menuitem2_menu), editFind);
314 
315     menuseparator9 = gtk_separator_menu_item_new();
316     gtk_widget_show(menuseparator9);
317     gtk_container_add(GTK_CONTAINER(menuitem2_menu), menuseparator9);
318 
319     editDeviceName = gtk_menu_item_new_with_label(_("Change Device Name"));
320     gtk_widget_show(editDeviceName);
321     gtk_container_add(GTK_CONTAINER(menuitem2_menu), editDeviceName);
322 
323     editFormatDevice = gtk_menu_item_new_with_label(_("Format Device"));
324     gtk_widget_show(editFormatDevice);
325     gtk_container_add(GTK_CONTAINER(menuitem2_menu), editFormatDevice);
326 
327     menuseparator7 = gtk_separator_menu_item_new();
328     gtk_widget_show(menuseparator7);
329     gtk_container_add(GTK_CONTAINER(menuitem2_menu), menuseparator7);
330 
331     editAddAlbumArt = gtk_menu_item_new_with_label(_("Album Art"));
332     gtk_widget_show(editAddAlbumArt);
333     gtk_container_add(GTK_CONTAINER(menuitem2_menu), editAddAlbumArt);
334 
335     editPlaylist = gtk_menu_item_new_with_label(_("Edit Playlist(s)"));
336     gtk_widget_show(editPlaylist);
337     gtk_container_add(GTK_CONTAINER(menuitem2_menu), editPlaylist);
338 
339     menuseparator5 = gtk_separator_menu_item_new();
340     gtk_widget_show(menuseparator5);
341     gtk_container_add(GTK_CONTAINER(menuitem2_menu), menuseparator5);
342 
343     preferences1 = gtk_menu_item_new_with_mnemonic(_("_Preferences"));
344     gtk_widget_show(preferences1);
345     gtk_container_add(GTK_CONTAINER(menuitem2_menu), preferences1);
346 
347     menuView = gtk_menu_item_new_with_mnemonic(_("_View"));
348     gtk_widget_show(menuView);
349     gtk_container_add(GTK_CONTAINER(menubarMain), menuView);
350 
351 
352     menuView_menu = gtk_menu_new();
353     gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuView), menuView_menu);
354 
355     menu_view_toolbar = gtk_check_menu_item_new_with_label(_("Toolbar"));
356     gtk_widget_show(menu_view_toolbar);
357     gtk_container_add(GTK_CONTAINER(menuView_menu), menu_view_toolbar);
358 
359     menuseparator10 = gtk_separator_menu_item_new();
360     gtk_widget_show(menuseparator10);
361     gtk_container_add(GTK_CONTAINER(menuView_menu), menuseparator10);
362 
363     menu_view_folders = gtk_check_menu_item_new_with_label(_("Folders"));
364     gtk_widget_show(menu_view_folders);
365     gtk_container_add(GTK_CONTAINER(menuView_menu), menu_view_folders);
366 
367     menuseparator8 = gtk_separator_menu_item_new();
368     gtk_widget_show(menuseparator8);
369     gtk_container_add(GTK_CONTAINER(menuView_menu), menuseparator8);
370 
371     menu_view_filesize = gtk_check_menu_item_new_with_label(_("File Size"));
372     gtk_widget_show(menu_view_filesize);
373     gtk_container_add(GTK_CONTAINER(menuView_menu), menu_view_filesize);
374 
375     menu_view_filetype = gtk_check_menu_item_new_with_label(_("File Type"));
376     gtk_widget_show(menu_view_filetype);
377     gtk_container_add(GTK_CONTAINER(menuView_menu), menu_view_filetype);
378 
379     menu_view_track_number = gtk_check_menu_item_new_with_label(_("Track Number"));
380     gtk_widget_show(menu_view_track_number);
381     gtk_container_add(GTK_CONTAINER(menuView_menu), menu_view_track_number);
382 
383     menu_view_title = gtk_check_menu_item_new_with_label(_("Track Name"));
384     gtk_widget_show(menu_view_title);
385     gtk_container_add(GTK_CONTAINER(menuView_menu), menu_view_title);
386 
387     menu_view_artist = gtk_check_menu_item_new_with_label(_("Artist"));
388     gtk_widget_show(menu_view_artist);
389     gtk_container_add(GTK_CONTAINER(menuView_menu), menu_view_artist);
390 
391     menu_view_album = gtk_check_menu_item_new_with_label(_("Album"));
392     gtk_widget_show(menu_view_album);
393     gtk_container_add(GTK_CONTAINER(menuView_menu), menu_view_album);
394 
395     menu_view_year = gtk_check_menu_item_new_with_label(_("Year"));
396     gtk_widget_show(menu_view_year);
397     gtk_container_add(GTK_CONTAINER(menuView_menu), menu_view_year);
398 
399     menu_view_genre = gtk_check_menu_item_new_with_label(_("Genre"));
400     gtk_widget_show(menu_view_genre);
401     gtk_container_add(GTK_CONTAINER(menuView_menu), menu_view_genre);
402 
403     menu_view_duration = gtk_check_menu_item_new_with_label(_("Duration"));
404     gtk_widget_show(menu_view_duration);
405     gtk_container_add(GTK_CONTAINER(menuView_menu), menu_view_duration);
406 
407     menuitem4 = gtk_menu_item_new_with_mnemonic(_("_Help"));
408     gtk_widget_show(menuitem4);
409     gtk_container_add(GTK_CONTAINER(menubarMain), menuitem4);
410 
411     menuitem4_menu = gtk_menu_new();
412     gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem4), menuitem4_menu);
413 
414     about1 = gtk_menu_item_new_with_mnemonic(_("_About"));
415     gtk_widget_show(about1);
416     gtk_container_add(GTK_CONTAINER(menuitem4_menu), about1);
417 
418 #if HAVE_GTK3 == 0
419     handlebox1 = gtk_handle_box_new();
420     gtk_handle_box_set_shadow_type(GTK_HANDLE_BOX(handlebox1), GTK_SHADOW_ETCHED_OUT);
421 #else
422     handlebox1 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
423 #endif
424     gtk_widget_show(handlebox1);
425     gtk_box_pack_start(GTK_BOX(vbox1), handlebox1, FALSE, FALSE, 0);
426 
427 #if HAVE_GTK3 == 0
428     tooltipsToolbar = gtk_tooltips_new();
429 #endif
430 
431     toolbarMain = gtk_toolbar_new();
432     gtk_widget_show(toolbarMain);
433 #if HAVE_GTK3 == 0
434     gtk_container_add(GTK_CONTAINER(handlebox1), toolbarMain);
435 #else
436     gtk_box_pack_start(GTK_BOX(handlebox1), toolbarMain, TRUE, TRUE, 0);
437 #endif
438     if (Preferences.toolbarStyle != NULL) {
439         if (g_ascii_strcasecmp(Preferences.toolbarStyle->str, "icon") == 0) {
440             gtk_toolbar_set_style(GTK_TOOLBAR(toolbarMain), GTK_TOOLBAR_ICONS);
441         } else if (g_ascii_strcasecmp(Preferences.toolbarStyle->str, "text") == 0) {
442             gtk_toolbar_set_style(GTK_TOOLBAR(toolbarMain), GTK_TOOLBAR_TEXT);
443         } else if (g_ascii_strcasecmp(Preferences.toolbarStyle->str, "both") == 0) {
444             gtk_toolbar_set_style(GTK_TOOLBAR(toolbarMain), GTK_TOOLBAR_BOTH);
445         }
446     } else {
447         gtk_toolbar_set_style(GTK_TOOLBAR(toolbarMain), GTK_TOOLBAR_BOTH);
448     }
449     tmp_toolbar_icon_size = gtk_toolbar_get_icon_size(GTK_TOOLBAR(toolbarMain));
450 
451 #if HAVE_GTK3 == 0
452     gtk_toolbar_set_tooltips(GTK_TOOLBAR(toolbarMain), TRUE);
453 #else
454     g_object_set(gtk_settings_get_default(), "gtk-enable-tooltips", TRUE, NULL);
455 #endif
456 
457 #if HAVE_GTK3 == 0
458     tmp_image = gtk_image_new_from_stock(GTK_STOCK_NETWORK, tmp_toolbar_icon_size);
459 #else
460     tmp_image = gtk_image_new_from_icon_name("network-workgroup", tmp_toolbar_icon_size);
461 #endif
462     gtk_widget_show(tmp_image);
463     toolbuttonConnect = (GtkWidget*) gtk_tool_button_new(tmp_image, _("Connect"));
464     gtk_widget_show(toolbuttonConnect);
465     gtk_container_add(GTK_CONTAINER(toolbarMain), toolbuttonConnect);
466 #if HAVE_GTK3 == 0
467     gtk_tool_item_set_tooltip(GTK_TOOL_ITEM(toolbuttonConnect), GTK_TOOLTIPS(tooltipsToolbar), _("Connect/Disconnect to your device."), _("Connect/Disconnect to your device."));
468 #else
469     gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(toolbuttonConnect), _("Connect/Disconnect to your device."));
470 #endif
471 
472     toolbarSeparator = (GtkWidget*) gtk_separator_tool_item_new();
473     gtk_separator_tool_item_set_draw(GTK_SEPARATOR_TOOL_ITEM(toolbarSeparator), TRUE);
474     gtk_widget_show(toolbarSeparator);
475     gtk_container_add(GTK_CONTAINER(toolbarMain), toolbarSeparator);
476 
477 #if HAVE_GTK3 == 0
478     tmp_image = gtk_image_new_from_stock(GTK_STOCK_ADD, tmp_toolbar_icon_size);
479 #else
480     tmp_image = gtk_image_new_from_icon_name("list-add", tmp_toolbar_icon_size);
481 #endif
482     gtk_widget_show(tmp_image);
483     toolbuttonAddFile = (GtkWidget*) gtk_tool_button_new(tmp_image, _("Add"));
484     gtk_widget_show(toolbuttonAddFile);
485     gtk_container_add(GTK_CONTAINER(toolbarMain), toolbuttonAddFile);
486 #if HAVE_GTK3 == 0
487     gtk_tool_item_set_tooltip(GTK_TOOL_ITEM(toolbuttonAddFile), GTK_TOOLTIPS(tooltipsToolbar), _("Add Files to your device."), _("Add a varity of Files to your device in the current folder."));
488 #else
489     gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(toolbuttonAddFile), _("Add Files to your device."));
490 #endif
491 #if HAVE_GTK3 == 0
492     tmp_image = gtk_image_new_from_stock(GTK_STOCK_REMOVE, tmp_toolbar_icon_size);
493 #else
494     tmp_image = gtk_image_new_from_icon_name("list-remove", tmp_toolbar_icon_size);
495 #endif
496     gtk_widget_show(tmp_image);
497     toolbuttonRemoveFile = (GtkWidget*) gtk_tool_button_new(tmp_image, _("Delete"));
498     gtk_widget_show(toolbuttonRemoveFile);
499     gtk_container_add(GTK_CONTAINER(toolbarMain), toolbuttonRemoveFile);
500 #if HAVE_GTK3 == 0
501     gtk_tool_item_set_tooltip(GTK_TOOL_ITEM(toolbuttonRemoveFile), GTK_TOOLTIPS(tooltipsToolbar), _("Delete Files/Folders from your device."), _("Permanently remove files/folders from your device. Note: Albums are stored as *.alb files."));
502 #else
503     gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(toolbuttonRemoveFile), _("Delete Files/Folders from your device."));
504 #endif
505 #if HAVE_GTK3 == 0
506     tmp_image = gtk_image_new_from_stock(GTK_STOCK_GOTO_BOTTOM, tmp_toolbar_icon_size);
507 #else
508     tmp_image = gtk_image_new_from_icon_name("go-bottom", tmp_toolbar_icon_size);
509 #endif
510     gtk_widget_show(tmp_image);
511     toolbuttonRetrieve = (GtkWidget*) gtk_tool_button_new(tmp_image, _("Download"));
512     gtk_widget_show(toolbuttonRetrieve);
513     gtk_container_add(GTK_CONTAINER(toolbarMain), toolbuttonRetrieve);
514 #if HAVE_GTK3 == 0
515     gtk_tool_item_set_tooltip(GTK_TOOL_ITEM(toolbuttonRetrieve), GTK_TOOLTIPS(tooltipsToolbar), _("Download Files from your device to your Host PC."), _("Download files from your device to your PC. Default Download path is set in the preferences dialog."));
516 #else
517     gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(toolbuttonRetrieve), _("Download Files from your device to your Host PC."));
518 #endif
519 
520     toolbarSeparator2 = (GtkWidget*) gtk_separator_tool_item_new();
521     gtk_separator_tool_item_set_draw(GTK_SEPARATOR_TOOL_ITEM(toolbarSeparator2), TRUE);
522     gtk_widget_show(toolbarSeparator2);
523     gtk_container_add(GTK_CONTAINER(toolbarMain), toolbarSeparator2);
524 
525 #if HAVE_GTK3 == 0
526     tmp_image = gtk_image_new_from_stock(GTK_STOCK_CDROM, tmp_toolbar_icon_size);
527 #else
528     tmp_image = gtk_image_new_from_icon_name("media-optical", tmp_toolbar_icon_size);
529 #endif
530     gtk_widget_show(tmp_image);
531     toolbuttonAlbumArt = (GtkWidget*) gtk_tool_button_new(tmp_image, _("Album Art"));
532     gtk_widget_show(toolbuttonAlbumArt);
533     gtk_container_add(GTK_CONTAINER(toolbarMain), toolbuttonAlbumArt);
534 #if HAVE_GTK3 == 0
535     gtk_tool_item_set_tooltip(GTK_TOOL_ITEM(toolbuttonAlbumArt), GTK_TOOLTIPS(tooltipsToolbar), _("Upload an image file as Album Art."), _("Upload a JPG file and assign it as Album Art."));
536 #else
537     gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(toolbuttonAlbumArt), _("Upload an image file as Album Art."));
538 #endif
539 #if HAVE_GTK3 == 0
540     tmp_image = gtk_image_new_from_stock(GTK_STOCK_DND_MULTIPLE, tmp_toolbar_icon_size);
541 #else
542     tmp_image = gtk_image_new_from_icon_name("emblem-documents", tmp_toolbar_icon_size);
543 #endif
544     gtk_widget_show(tmp_image);
545     toolbuttonPlaylist = (GtkWidget*) gtk_tool_button_new(tmp_image, _("Playlists"));
546     gtk_widget_show(toolbuttonPlaylist);
547     gtk_container_add(GTK_CONTAINER(toolbarMain), toolbuttonPlaylist);
548 #if HAVE_GTK3 == 0
549     gtk_tool_item_set_tooltip(GTK_TOOL_ITEM(toolbuttonPlaylist), GTK_TOOLTIPS(tooltipsToolbar), _("Add and Modify Playlists."), _("Add and Modify Playlists."));
550 #else
551     gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(toolbuttonPlaylist), _("Add and Modify Playlists."));
552 #endif
553 #if HAVE_GTK3 == 0
554     tmp_image = gtk_image_new_from_stock(GTK_STOCK_REFRESH, tmp_toolbar_icon_size);
555 #else
556     tmp_image = gtk_image_new_from_icon_name("view-refresh", tmp_toolbar_icon_size);
557 #endif
558     gtk_widget_show(tmp_image);
559     toolbuttonRescan = (GtkWidget*) gtk_tool_button_new(tmp_image, _("Refresh"));
560     gtk_widget_show(toolbuttonRescan);
561     gtk_container_add(GTK_CONTAINER(toolbarMain), toolbuttonRescan);
562 #if HAVE_GTK3 == 0
563     gtk_tool_item_set_tooltip(GTK_TOOL_ITEM(toolbuttonRescan), GTK_TOOLTIPS(tooltipsToolbar), _("Refresh File/Folder listing."), _("Refresh File/Folder listing."));
564 #else
565     gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(toolbuttonRescan), _("Refresh File/Folder listing."));
566 #endif
567 
568     toolbarSeparator = (GtkWidget*) gtk_separator_tool_item_new();
569     gtk_separator_tool_item_set_draw(GTK_SEPARATOR_TOOL_ITEM(toolbarSeparator), TRUE);
570     gtk_widget_show(toolbarSeparator);
571     gtk_container_add(GTK_CONTAINER(toolbarMain), toolbarSeparator);
572 
573 #if HAVE_GTK3 == 0
574     tmp_image = gtk_image_new_from_stock(GTK_STOCK_PROPERTIES, tmp_toolbar_icon_size);
575 #else
576     tmp_image = gtk_image_new_from_icon_name("document-properties", tmp_toolbar_icon_size);
577 #endif
578     gtk_widget_show(tmp_image);
579     toolbuttonProperties = (GtkWidget*) gtk_tool_button_new(tmp_image, _("Properties"));
580     gtk_widget_show(toolbuttonProperties);
581     gtk_container_add(GTK_CONTAINER(toolbarMain), toolbuttonProperties);
582 #if HAVE_GTK3 == 0
583     gtk_tool_item_set_tooltip(GTK_TOOL_ITEM(toolbuttonProperties), GTK_TOOLTIPS(tooltipsToolbar), _("View Device Properties."), _("View Device Properties."));
584 #else
585     gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(toolbuttonProperties), _("View Device Properties."));
586 #endif
587 #if HAVE_GTK3 == 0
588     tmp_image = gtk_image_new_from_stock(GTK_STOCK_PREFERENCES, tmp_toolbar_icon_size);
589 #else
590     tmp_image = gtk_image_new_from_icon_name("preferences-system", tmp_toolbar_icon_size);
591 #endif
592     gtk_widget_show(tmp_image);
593     toolbuttonPreferences = (GtkWidget*) gtk_tool_button_new(tmp_image, _("Preferences"));
594     gtk_widget_show(toolbuttonPreferences);
595     gtk_container_add(GTK_CONTAINER(toolbarMain), toolbuttonPreferences);
596 #if HAVE_GTK3 == 0
597     gtk_tool_item_set_tooltip(GTK_TOOL_ITEM(toolbuttonPreferences), GTK_TOOLTIPS(tooltipsToolbar), _("View/Change gMTP Preferences."), _("View/Change gMTP Preferences."));
598 #else
599     gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(toolbuttonPreferences), _("View/Change gMTP Preferences."));
600 #endif
601 
602     /*    toolbarSeparator = (GtkWidget*) gtk_separator_tool_item_new();
603         gtk_separator_tool_item_set_draw(GTK_SEPARATOR_TOOL_ITEM(toolbarSeparator), TRUE);
604         gtk_widget_show(toolbarSeparator);
605         gtk_container_add(GTK_CONTAINER(toolbarMain), toolbarSeparator);
606     #if HAVE_GTK3 == 0
607         tmp_image = gtk_image_new_from_stock(GTK_STOCK_QUIT, tmp_toolbar_icon_size);
608     #else
609         tmp_image = gtk_image_new_from_icon_name("application-exit", tmp_toolbar_icon_size);
610     #endif
611         gtk_widget_show(tmp_image);
612         toolbuttonQuit = (GtkWidget*) gtk_tool_button_new(tmp_image, _("Quit"));
613         gtk_widget_show(toolbuttonQuit);
614         gtk_container_add(GTK_CONTAINER(toolbarMain), toolbuttonQuit);
615     #if HAVE_GTK3 == 0
616         gtk_tool_item_set_tooltip(GTK_TOOL_ITEM(toolbuttonQuit), GTK_TOOLTIPS(tooltipsToolbar), _("Quit gMTP."), _("Quit"));
617     #else
618         gtk_tool_item_set_tooltip_text(GTK_TOOL_ITEM(toolbuttonQuit), _("Quit gMTP."));
619     #endif
620      */
621 #if HAVE_GTK3 == 0
622     gtk_tooltips_enable(tooltipsToolbar);
623 #endif
624 
625     // Find toolbar;
626 #if HAVE_GTK3 == 0
627     findToolbar = gtk_handle_box_new();
628     //gtk_widget_show(findToolbar); // Only show when the user selects the menu option.
629     gtk_handle_box_set_shadow_type(GTK_HANDLE_BOX(findToolbar), GTK_SHADOW_ETCHED_OUT);
630 #else
631     findToolbar = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
632 #endif
633     gtk_box_pack_start(GTK_BOX(vbox1), findToolbar, FALSE, FALSE, 0);
634 
635 #if HAVE_GTK3 == 0
636     FindToolbar_hbox_FindToolbar = gtk_hbox_new(FALSE, 5);
637 #else
638     FindToolbar_hbox_FindToolbar = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
639 #endif
640     gtk_widget_show(FindToolbar_hbox_FindToolbar);
641     gtk_container_add(GTK_CONTAINER(findToolbar), FindToolbar_hbox_FindToolbar);
642     gtk_container_set_border_width(GTK_CONTAINER(FindToolbar_hbox_FindToolbar), 2);
643 
644     FindToolbar_label_FindLabel = gtk_label_new(_("Find:"));
645     gtk_widget_show(FindToolbar_label_FindLabel);
646     gtk_box_pack_start(GTK_BOX(FindToolbar_hbox_FindToolbar), FindToolbar_label_FindLabel, FALSE, FALSE, 0);
647     gtk_label_set_justify(GTK_LABEL(FindToolbar_label_FindLabel), GTK_JUSTIFY_RIGHT);
648 
649     FindToolbar_entry_FindText = gtk_entry_new();
650     gtk_widget_show(FindToolbar_entry_FindText);
651     gtk_box_pack_start(GTK_BOX(FindToolbar_hbox_FindToolbar), FindToolbar_entry_FindText, TRUE, TRUE, 0);
652     gtk_entry_set_max_length(GTK_ENTRY(FindToolbar_entry_FindText), 256);
653 #if HAVE_GTK3 == 0
654     FindToolbar_FindButton = gtk_button_new_from_stock(GTK_STOCK_FIND);
655 #else
656 #if GTK_CHECK_VERSION(3,10,0)
657     FindToolbar_FindButton = gtk_button_new_from_icon_name("edit-find", tmp_toolbar_icon_size);
658 #else
659     FindToolbar_FindButton = gtk_button_new_from_stock(GTK_STOCK_FIND);
660 #endif
661 #endif
662     gtk_widget_show(FindToolbar_FindButton);
663     gtk_box_pack_start(GTK_BOX(FindToolbar_hbox_FindToolbar), FindToolbar_FindButton, FALSE, FALSE, 5);
664     //gtk_container_set_border_width(GTK_CONTAINER(FindToolbar_FindButton), 5);
665 
666     FindToolbar_checkbutton_FindFiles = gtk_check_button_new_with_mnemonic(_("Filenames"));
667     gtk_widget_show(FindToolbar_checkbutton_FindFiles);
668     gtk_box_pack_start(GTK_BOX(FindToolbar_hbox_FindToolbar), FindToolbar_checkbutton_FindFiles, FALSE, FALSE, 0);
669     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(FindToolbar_checkbutton_FindFiles), TRUE);
670 
671     FindToolbar_checkbutton_TrackInformation = gtk_check_button_new_with_mnemonic(_("Track Information"));
672     gtk_widget_show(FindToolbar_checkbutton_TrackInformation);
673     gtk_box_pack_start(GTK_BOX(FindToolbar_hbox_FindToolbar), FindToolbar_checkbutton_TrackInformation, FALSE, FALSE, 0);
674 #if HAVE_GTK3 == 0
675     tmp_image = gtk_image_new_from_stock(GTK_STOCK_CLOSE, tmp_toolbar_icon_size);
676 #else
677     tmp_image = gtk_image_new_from_icon_name("window-close", tmp_toolbar_icon_size);
678 #endif
679 
680     gtk_widget_show(tmp_image);
681     FindToolbar_CloseButton = (GtkWidget*) gtk_button_new();
682     gtk_container_add(GTK_CONTAINER(FindToolbar_CloseButton), tmp_image);
683     gtk_widget_show(FindToolbar_CloseButton);
684     gtk_box_pack_start(GTK_BOX(FindToolbar_hbox_FindToolbar), FindToolbar_CloseButton, FALSE, FALSE, 5);
685     gtk_button_set_relief(GTK_BUTTON(FindToolbar_CloseButton), GTK_RELIEF_NONE);
686 
687     // Main Window.
688 
689     // Hpane for showing both folders and main window.
690 
691 #if HAVE_GTK3 == 0
692     hpanel = gtk_hpaned_new();
693 #else
694     hpanel = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
695 #endif
696     gtk_widget_show(hpanel);
697     gtk_box_pack_start(GTK_BOX(vbox1), hpanel, TRUE, TRUE, 0);
698     gtk_paned_set_position(GTK_PANED(hpanel), 150);
699 
700 
701     // Folder Window
702 
703     scrolledwindowFolders = gtk_scrolled_window_new(NULL, NULL);
704     gtk_widget_hide(scrolledwindowFolders);
705     gtk_paned_pack1(GTK_PANED(hpanel), scrolledwindowFolders, TRUE, TRUE);
706     gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwindowFolders), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
707 
708     treeviewFolders = gtk_tree_view_new();
709     gtk_widget_show(treeviewFolders);
710     gtk_container_add(GTK_CONTAINER(scrolledwindowFolders), treeviewFolders);
711     gtk_container_set_border_width(GTK_CONTAINER(treeviewFolders), 5);
712     folderSelection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviewFolders));
713     gtk_tree_selection_set_mode(folderSelection, GTK_SELECTION_SINGLE);
714 
715     folderList = gtk_tree_store_new(NUM_FOL_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_UINT, GDK_TYPE_PIXBUF);
716     folderColumn = setupFolderList(treeviewFolders);
717 
718     folderListModel = gtk_tree_model_sort_new_with_model(GTK_TREE_MODEL(folderList));
719     gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(folderListModel),
720             COL_FOL_NAME_HIDDEN, GTK_SORT_ASCENDING);
721 
722     gtk_tree_view_set_model(GTK_TREE_VIEW(treeviewFolders), GTK_TREE_MODEL(folderListModel));
723     gtk_tree_view_expand_all(GTK_TREE_VIEW(treeviewFolders));
724     g_object_unref(folderList);
725 
726     // Main file window
727 
728     scrolledwindowMain = gtk_scrolled_window_new(NULL, NULL);
729     gtk_widget_show(scrolledwindowMain);
730     gtk_paned_pack2(GTK_PANED(hpanel), scrolledwindowMain, TRUE, TRUE);
731     gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwindowMain), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
732 
733     treeviewFiles = gtk_tree_view_new();
734     gtk_widget_show(treeviewFiles);
735     gtk_container_add(GTK_CONTAINER(scrolledwindowMain), treeviewFiles);
736     gtk_container_set_border_width(GTK_CONTAINER(treeviewFiles), 5);
737     fileSelection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviewFiles));
738     gtk_tree_selection_set_mode(fileSelection, GTK_SELECTION_MULTIPLE);
739 
740     fileList = gtk_list_store_new(NUM_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
741             G_TYPE_UINT, G_TYPE_BOOLEAN, G_TYPE_UINT64, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_STRING,
742             G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_UINT, GDK_TYPE_PIXBUF,
743             G_TYPE_STRING);
744     setupFileList(treeviewFiles);
745 
746     fileListModel = gtk_tree_model_sort_new_with_model(GTK_TREE_MODEL(fileList));
747     gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(fileListModel),
748             COL_FILENAME_HIDDEN, GTK_SORT_ASCENDING);
749 
750     gtk_tree_view_set_model(GTK_TREE_VIEW(treeviewFiles), GTK_TREE_MODEL(fileListModel));
751     g_object_unref(fileList);
752 
753     windowStatusBar = gtk_statusbar_new();
754     gtk_widget_show(windowStatusBar);
755     gtk_box_pack_start(GTK_BOX(vbox1), windowStatusBar, FALSE, FALSE, 0);
756 
757     // Build our right-click context menu;
758     contextMenu = create_windowMainContextMenu();
759     contextMenuColumn = create_windowMainColumnContextMenu();
760     contextMenuFolder = create_windowFolderContextMenu();
761 
762     // DnD functions
763 
764     g_signal_connect((gpointer) scrolledwindowMain, "drag-data-received",
765             G_CALLBACK(gmtp_drag_data_received), NULL);
766 
767     g_signal_connect((gpointer) treeviewFolders, "drag-data-received",
768             G_CALLBACK(gmtpfolders_drag_data_received), NULL);
769 
770     g_signal_connect((gpointer) treeviewFolders, "drag-motion",
771             G_CALLBACK(gmtpfolders_drag_motion_received), NULL);
772 
773     // End Dnd functions
774 
775     g_signal_connect((gpointer) windowMain, "destroy",
776             G_CALLBACK(on_quit1_activate),
777             NULL);
778 
779     g_signal_connect((gpointer) properties1, "activate",
780             G_CALLBACK(on_deviceProperties_activate),
781             NULL);
782     g_signal_connect((gpointer) toolbuttonProperties, "clicked",
783             G_CALLBACK(on_deviceProperties_activate),
784             NULL);
785 
786     g_signal_connect((gpointer) quit1, "activate",
787             G_CALLBACK(on_quit1_activate),
788             NULL);
789 
790     g_signal_connect((gpointer) preferences1, "activate",
791             G_CALLBACK(on_preferences1_activate),
792             NULL);
793 
794     g_signal_connect((gpointer) editFind, "activate",
795             G_CALLBACK(on_editFind_activate),
796             NULL);
797 
798     g_signal_connect((gpointer) editSelectAll, "activate",
799             G_CALLBACK(on_editSelectAll_activate),
800             NULL);
801 
802     g_signal_connect((gpointer) editDeviceName, "activate",
803             G_CALLBACK(on_editDeviceName_activate),
804             NULL);
805 
806     g_signal_connect((gpointer) editFormatDevice, "activate",
807             G_CALLBACK(on_editFormatDevice_activate),
808             NULL);
809 
810     g_signal_connect((gpointer) editAddAlbumArt, "activate",
811             G_CALLBACK(on_editAddAlbumArt_activate),
812             NULL);
813 
814     g_signal_connect((gpointer) editPlaylist, "activate",
815             G_CALLBACK(on_editPlaylist_activate),
816             NULL);
817 
818     g_signal_connect((gpointer) fileAdd, "activate",
819             G_CALLBACK(on_filesAdd_activate),
820             NULL);
821 
822     g_signal_connect((gpointer) fileDownload, "activate",
823             G_CALLBACK(on_filesDownload_activate),
824             NULL);
825 
826     g_signal_connect((gpointer) fileRemove, "activate",
827             G_CALLBACK(on_filesDelete_activate),
828             NULL);
829 
830     g_signal_connect((gpointer) fileRename, "activate",
831             G_CALLBACK(on_fileRenameFile_activate),
832             NULL);
833 
834     g_signal_connect((gpointer) fileMove, "activate",
835             G_CALLBACK(on_fileMoveFile_activate),
836             NULL);
837 
838     g_signal_connect((gpointer) fileConnect, "activate",
839             G_CALLBACK(on_deviceConnect_activate),
840             NULL);
841 
842     g_signal_connect((gpointer) fileNewFolder, "activate",
843             G_CALLBACK(on_fileNewFolder_activate),
844             NULL);
845 
846     g_signal_connect((gpointer) fileRemoveFolder, "activate",
847             G_CALLBACK(on_fileRemoveFolder_activate),
848             NULL);
849 
850     g_signal_connect((gpointer) fileRescan, "activate",
851             G_CALLBACK(on_deviceRescan_activate),
852             NULL);
853 
854     g_signal_connect((gpointer) about1, "activate",
855             G_CALLBACK(on_about1_activate),
856             NULL);
857 
858     /*    g_signal_connect((gpointer) toolbuttonQuit, "clicked",
859                 G_CALLBACK(on_quit1_activate),
860                 NULL);*/
861 
862     g_signal_connect((gpointer) toolbuttonRescan, "clicked",
863             G_CALLBACK(on_deviceRescan_activate),
864             NULL);
865 
866     g_signal_connect((gpointer) toolbuttonAddFile, "clicked",
867             G_CALLBACK(on_filesAdd_activate),
868             NULL);
869 
870     g_signal_connect((gpointer) toolbuttonRemoveFile, "clicked",
871             G_CALLBACK(on_filesDelete_activate),
872             NULL);
873 
874     g_signal_connect((gpointer) toolbuttonRetrieve, "clicked",
875             G_CALLBACK(on_filesDownload_activate),
876             NULL);
877 
878     g_signal_connect((gpointer) toolbuttonAlbumArt, "clicked",
879             G_CALLBACK(on_editAddAlbumArt_activate),
880             NULL);
881 
882     g_signal_connect((gpointer) toolbuttonPlaylist, "clicked",
883             G_CALLBACK(on_editPlaylist_activate),
884             NULL);
885 
886     g_signal_connect((gpointer) toolbuttonConnect, "clicked",
887             G_CALLBACK(on_deviceConnect_activate),
888             NULL);
889     g_signal_connect((gpointer) toolbuttonPreferences, "clicked",
890             G_CALLBACK(on_preferences1_activate),
891             NULL);
892 
893     g_signal_connect((gpointer) treeviewFiles, "row-activated",
894             G_CALLBACK(fileListRowActivated),
895             NULL);
896 
897     g_signal_connect((gpointer) treeviewFolders, "row-activated",
898             G_CALLBACK(folderListRowActivated),
899             NULL);
900 
901     g_signal_connect_swapped(treeviewFiles, "button_press_event",
902             G_CALLBACK(on_windowMainContextMenu_activate), contextMenu);
903 
904     g_signal_connect_swapped(treeviewFolders, "button_press_event",
905             G_CALLBACK(on_windowMainContextMenu_activate), contextMenuFolder);
906 
907     g_signal_connect((gpointer) menu_view_filesize, "toggled",
908             G_CALLBACK(on_view_activate),
909             NULL);
910 
911     g_signal_connect((gpointer) menu_view_filetype, "toggled",
912             G_CALLBACK(on_view_activate),
913             NULL);
914 
915     g_signal_connect((gpointer) menu_view_track_number, "toggled",
916             G_CALLBACK(on_view_activate),
917             NULL);
918 
919     g_signal_connect((gpointer) menu_view_title, "toggled",
920             G_CALLBACK(on_view_activate),
921             NULL);
922 
923     g_signal_connect((gpointer) menu_view_artist, "toggled",
924             G_CALLBACK(on_view_activate),
925             NULL);
926 
927     g_signal_connect((gpointer) menu_view_album, "toggled",
928             G_CALLBACK(on_view_activate),
929             NULL);
930 
931     g_signal_connect((gpointer) menu_view_year, "toggled",
932             G_CALLBACK(on_view_activate),
933             NULL);
934 
935     g_signal_connect((gpointer) menu_view_genre, "toggled",
936             G_CALLBACK(on_view_activate),
937             NULL);
938 
939     g_signal_connect((gpointer) menu_view_duration, "toggled",
940             G_CALLBACK(on_view_activate),
941             NULL);
942 
943     g_signal_connect((gpointer) menu_view_folders, "toggled",
944             G_CALLBACK(on_view_activate),
945             NULL);
946 
947     g_signal_connect((gpointer) menu_view_toolbar, "toggled",
948             G_CALLBACK(on_view_activate),
949             NULL);
950 
951     g_signal_connect((gpointer) FindToolbar_CloseButton, "clicked",
952             G_CALLBACK(on_editFindClose_activate),
953             NULL);
954 
955     g_signal_connect((gpointer) FindToolbar_FindButton, "clicked",
956             G_CALLBACK(on_editFindSearch_activate),
957             NULL);
958 
959     g_signal_connect((gpointer) FindToolbar_entry_FindText, "activate",
960             G_CALLBACK(on_editFindSearch_activate),
961             NULL);
962 
963     folderSelectHandler = g_signal_connect_after((gpointer) folderSelection, "changed",
964             G_CALLBACK(on_treeviewFolders_rowactivated),
965             NULL);
966 
967     fileSelectHandler = g_signal_connect_after((gpointer) fileSelection, "changed",
968             G_CALLBACK(on_treeviewFolders_rowactivated),
969             NULL);
970 
971     gtk_window_add_accel_group(GTK_WINDOW(windowMain), accel_group);
972     gtk_menu_set_accel_group(GTK_MENU(menuitem1_menu), accel_group);
973     gtk_widget_add_accelerator(fileRemove, "activate", accel_group, GDK_Delete, 0, GTK_ACCEL_VISIBLE);
974     gtk_widget_add_accelerator(fileRename, "activate", accel_group, GDK_F2, 0, GTK_ACCEL_VISIBLE);
975     gtk_widget_add_accelerator(fileConnect, "activate", accel_group, GDK_F3, 0, GTK_ACCEL_VISIBLE);
976     gtk_widget_add_accelerator(fileRescan, "activate", accel_group, GDK_F5, 0, GTK_ACCEL_VISIBLE);
977     gtk_widget_add_accelerator(fileNewFolder, "activate", accel_group, GDK_N, GDK_CONTROL_MASK + GDK_SHIFT_MASK, GTK_ACCEL_VISIBLE);
978     gtk_widget_add_accelerator(fileAdd, "activate", accel_group, GDK_O, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
979     gtk_widget_add_accelerator(fileDownload, "activate", accel_group, GDK_D, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
980     gtk_widget_add_accelerator(editPlaylist, "activate", accel_group, GDK_P, GDK_CONTROL_MASK + GDK_SHIFT_MASK, GTK_ACCEL_VISIBLE);
981     gtk_widget_add_accelerator(editAddAlbumArt, "activate", accel_group, GDK_A, GDK_CONTROL_MASK + GDK_SHIFT_MASK, GTK_ACCEL_VISIBLE);
982     gtk_widget_add_accelerator(editSelectAll, "activate", accel_group, GDK_A, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
983     gtk_widget_add_accelerator(editFind, "activate", accel_group, GDK_F, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
984     return windowMain;
985 }
986 
987 // ************************************************************************************************
988 
statusBarSet(gchar * text)989 void statusBarSet(gchar *text) {
990     statusBarClear();
991     guint c_id1 = gtk_statusbar_get_context_id(GTK_STATUSBAR(windowStatusBar), "");
992     gtk_statusbar_push(GTK_STATUSBAR(windowStatusBar), c_id1, text);
993 }
994 
995 // ************************************************************************************************
996 
statusBarClear()997 void statusBarClear() {
998     guint c_id1 = gtk_statusbar_get_context_id(GTK_STATUSBAR(windowStatusBar), "");
999     gtk_statusbar_pop(GTK_STATUSBAR(windowStatusBar), c_id1);
1000 }
1001 
1002 // ************************************************************************************************
1003 
SetToolbarButtonState(gboolean state)1004 void SetToolbarButtonState(gboolean state) {
1005     gtk_widget_set_sensitive(GTK_WIDGET(toolbuttonAddFile), state);
1006     gtk_widget_set_sensitive(GTK_WIDGET(toolbuttonRemoveFile), state);
1007     gtk_widget_set_sensitive(GTK_WIDGET(toolbuttonRetrieve), state);
1008     gtk_widget_set_sensitive(GTK_WIDGET(toolbuttonRescan), state);
1009     gtk_widget_set_sensitive(GTK_WIDGET(toolbuttonAlbumArt), state);
1010     gtk_widget_set_sensitive(GTK_WIDGET(toolbuttonPlaylist), state);
1011     gtk_widget_set_sensitive(GTK_WIDGET(toolbuttonProperties), state);
1012     gtk_widget_set_sensitive(GTK_WIDGET(properties1), state);
1013     gtk_widget_set_sensitive(GTK_WIDGET(fileAdd), state);
1014     gtk_widget_set_sensitive(GTK_WIDGET(fileDownload), state);
1015     gtk_widget_set_sensitive(GTK_WIDGET(fileRemove), state);
1016     gtk_widget_set_sensitive(GTK_WIDGET(fileRename), state);
1017     gtk_widget_set_sensitive(GTK_WIDGET(fileMove), state);
1018     gtk_widget_set_sensitive(GTK_WIDGET(fileNewFolder), state);
1019     gtk_widget_set_sensitive(GTK_WIDGET(fileRemoveFolder), state);
1020     gtk_widget_set_sensitive(GTK_WIDGET(fileRescan), state);
1021     gtk_widget_set_sensitive(GTK_WIDGET(editDeviceName), state);
1022     gtk_widget_set_sensitive(GTK_WIDGET(editFormatDevice), state);
1023     gtk_widget_set_sensitive(GTK_WIDGET(editAddAlbumArt), state);
1024     gtk_widget_set_sensitive(GTK_WIDGET(editFind), state);
1025     gtk_widget_set_sensitive(GTK_WIDGET(editSelectAll), state);
1026     gtk_widget_set_sensitive(GTK_WIDGET(editPlaylist), state);
1027     gtk_widget_set_sensitive(GTK_WIDGET(treeviewFiles), state);
1028     // Only set this if we are using the normal connection method.
1029     if (!Preferences.use_alt_access_method) {
1030         gtk_widget_set_sensitive(GTK_WIDGET(treeviewFolders), state);
1031     }
1032 }
1033 
1034 // ************************************************************************************************
1035 
1036 /**
1037  * Construct the main file view within the main application window.
1038  * @param treeviewFiles
1039  */
setupFileList(GtkTreeView * treeviewFiles)1040 void setupFileList(GtkTreeView *treeviewFiles) {
1041     GtkCellRenderer *renderer;
1042     GtkTreeViewColumn *column;
1043     GtkWidget *header;
1044     GtkWidget *parent;
1045 
1046     // Filename column
1047     //renderer = gtk_cell_renderer_text_new();
1048     //column = gtk_tree_view_column_new_with_attributes(_("Filename"), renderer,
1049     //    "text", COL_FILENAME,
1050     //    NULL);
1051 
1052     column = gtk_tree_view_column_new();
1053     gtk_tree_view_column_set_title(column, _("Filename"));
1054     renderer = gtk_cell_renderer_pixbuf_new();
1055 
1056     gtk_tree_view_column_pack_start(column, renderer, FALSE);
1057     gtk_tree_view_column_set_attributes(column, renderer, "pixbuf", COL_ICON, NULL);
1058 
1059     renderer = gtk_cell_renderer_text_new();
1060     gtk_tree_view_column_pack_start(column, renderer, TRUE);
1061     gtk_tree_view_column_set_attributes(column, renderer, "text", COL_FILENAME_ACTUAL, NULL);
1062 
1063     gtk_tree_view_append_column(GTK_TREE_VIEW(treeviewFiles), column);
1064     gtk_tree_view_column_set_sort_column_id(column, COL_FILENAME_HIDDEN);
1065     gtk_tree_view_column_set_resizable(column, TRUE);
1066     gtk_tree_view_column_set_spacing(column, 5);
1067 
1068     header = gtk_label_new(_("Filename"));
1069     gtk_widget_show(header);
1070     gtk_tree_view_column_set_widget(column, header);
1071     parent = gtk_widget_get_ancestor(gtk_tree_view_column_get_widget(column), GTK_TYPE_BUTTON);
1072 
1073     g_signal_connect_swapped(parent, "button_press_event",
1074             G_CALLBACK(on_windowViewContextMenu_activate), contextMenuColumn);
1075 
1076     // Filename column for sorting.
1077     renderer = gtk_cell_renderer_text_new();
1078     column = gtk_tree_view_column_new_with_attributes("Filename Hidden", renderer,
1079             "text", COL_FILENAME_HIDDEN,
1080             NULL);
1081     gtk_tree_view_append_column(GTK_TREE_VIEW(treeviewFiles), column);
1082     gtk_tree_view_column_set_visible(column, FALSE);
1083 
1084     // File name actual - used for renaming operations.
1085     renderer = gtk_cell_renderer_text_new();
1086     column = gtk_tree_view_column_new_with_attributes("Filename Actual", renderer,
1087             "text", COL_FILENAME_ACTUAL,
1088             NULL);
1089     gtk_tree_view_append_column(GTK_TREE_VIEW(treeviewFiles), column);
1090     gtk_tree_view_column_set_visible(column, FALSE);
1091 
1092     // File Size column
1093     renderer = gtk_cell_renderer_text_new();
1094     column_Size = gtk_tree_view_column_new_with_attributes(_("Size"), renderer,
1095             "text", COL_FILESIZE,
1096             NULL);
1097     gtk_tree_view_append_column(GTK_TREE_VIEW(treeviewFiles), column_Size);
1098     gtk_tree_view_column_set_sort_column_id(column_Size, COL_FILESIZE_HID);
1099     gtk_tree_view_column_set_resizable(column_Size, TRUE);
1100     gtk_tree_view_column_set_spacing(column_Size, 5);
1101     gtk_tree_view_column_set_visible(column_Size, Preferences.view_size);
1102 
1103     header = gtk_label_new(_("Size"));
1104     gtk_widget_show(header);
1105     gtk_tree_view_column_set_widget(column_Size, header);
1106     parent = gtk_widget_get_ancestor(gtk_tree_view_column_get_widget(column_Size), GTK_TYPE_BUTTON);
1107 
1108     g_signal_connect_swapped(parent, "button_press_event",
1109             G_CALLBACK(on_windowViewContextMenu_activate), contextMenuColumn);
1110 
1111 
1112     // Folder/FileID column
1113     renderer = gtk_cell_renderer_text_new();
1114     column = gtk_tree_view_column_new_with_attributes("Object ID", renderer,
1115             "text", COL_FILEID,
1116             NULL);
1117     gtk_tree_view_append_column(GTK_TREE_VIEW(treeviewFiles), column);
1118     gtk_tree_view_column_set_visible(column, FALSE);
1119 
1120     // isFolder column
1121     renderer = gtk_cell_renderer_text_new();
1122     column = gtk_tree_view_column_new_with_attributes("isFolder", renderer,
1123             "text", COL_ISFOLDER,
1124             NULL);
1125     gtk_tree_view_append_column(GTK_TREE_VIEW(treeviewFiles), column);
1126     gtk_tree_view_column_set_visible(column, FALSE);
1127 
1128     // File size column - hidden used for sorting the visible file size column
1129     renderer = gtk_cell_renderer_text_new();
1130     column = gtk_tree_view_column_new_with_attributes("FileSize Hidden", renderer,
1131             "text", COL_FILESIZE_HID,
1132             NULL);
1133     gtk_tree_view_append_column(GTK_TREE_VIEW(treeviewFiles), column);
1134     gtk_tree_view_column_set_visible(column, FALSE);
1135 
1136     // File Type column
1137     renderer = gtk_cell_renderer_text_new();
1138     column_Type = gtk_tree_view_column_new_with_attributes(_("File Type"), renderer,
1139             "text", COL_TYPE,
1140             NULL);
1141     gtk_tree_view_append_column(GTK_TREE_VIEW(treeviewFiles), column_Type);
1142     gtk_tree_view_column_set_sort_column_id(column_Type, COL_TYPE);
1143     gtk_tree_view_column_set_resizable(column_Type, TRUE);
1144     gtk_tree_view_column_set_spacing(column_Type, 5);
1145     gtk_tree_view_column_set_visible(column_Type, Preferences.view_type);
1146 
1147     header = gtk_label_new(_("File Type"));
1148     gtk_widget_show(header);
1149     gtk_tree_view_column_set_widget(column_Type, header);
1150     parent = gtk_widget_get_ancestor(gtk_tree_view_column_get_widget(column_Type), GTK_TYPE_BUTTON);
1151 
1152     g_signal_connect_swapped(parent, "button_press_event",
1153             G_CALLBACK(on_windowViewContextMenu_activate), contextMenuColumn);
1154 
1155     // Track Number column
1156     renderer = gtk_cell_renderer_text_new();
1157     column_Track_Number = gtk_tree_view_column_new_with_attributes(_("Track"), renderer,
1158             "text", COL_TRACK_NUMBER,
1159             NULL);
1160     gtk_tree_view_append_column(GTK_TREE_VIEW(treeviewFiles), column_Track_Number);
1161     gtk_tree_view_column_set_sort_column_id(column_Track_Number, COL_TRACK_NUMBER_HIDDEN);
1162     gtk_tree_view_column_set_resizable(column_Track_Number, TRUE);
1163     gtk_tree_view_column_set_spacing(column_Track_Number, 5);
1164     gtk_tree_view_column_set_visible(column_Track_Number, Preferences.view_track_number);
1165 
1166     header = gtk_label_new(_("Track"));
1167     gtk_widget_show(header);
1168     gtk_tree_view_column_set_widget(column_Track_Number, header);
1169     parent = gtk_widget_get_ancestor(gtk_tree_view_column_get_widget(column_Track_Number), GTK_TYPE_BUTTON);
1170 
1171     g_signal_connect_swapped(parent, "button_press_event",
1172             G_CALLBACK(on_windowViewContextMenu_activate), contextMenuColumn);
1173 
1174     renderer = gtk_cell_renderer_text_new();
1175     column = gtk_tree_view_column_new_with_attributes("Track Num Hidden", renderer,
1176             "text", COL_TRACK_NUMBER_HIDDEN,
1177             NULL);
1178     gtk_tree_view_append_column(GTK_TREE_VIEW(treeviewFiles), column);
1179     gtk_tree_view_column_set_visible(column, FALSE);
1180 
1181     // Track Title column
1182     renderer = gtk_cell_renderer_text_new();
1183     column_Title = gtk_tree_view_column_new_with_attributes(_("Track Name"), renderer,
1184             "text", COL_TITLE,
1185             NULL);
1186     gtk_tree_view_append_column(GTK_TREE_VIEW(treeviewFiles), column_Title);
1187     gtk_tree_view_column_set_sort_column_id(column_Title, COL_TITLE);
1188     gtk_tree_view_column_set_resizable(column_Title, TRUE);
1189     gtk_tree_view_column_set_spacing(column_Title, 5);
1190     gtk_tree_view_column_set_visible(column_Title, Preferences.view_track_number);
1191 
1192     header = gtk_label_new(_("Track Name"));
1193     gtk_widget_show(header);
1194     gtk_tree_view_column_set_widget(column_Title, header);
1195     parent = gtk_widget_get_ancestor(gtk_tree_view_column_get_widget(column_Title), GTK_TYPE_BUTTON);
1196 
1197     g_signal_connect_swapped(parent, "button_press_event",
1198             G_CALLBACK(on_windowViewContextMenu_activate), contextMenuColumn);
1199 
1200     // Artist column
1201     renderer = gtk_cell_renderer_text_new();
1202     column_Artist = gtk_tree_view_column_new_with_attributes(_("Artist"), renderer,
1203             "text", COL_FL_ARTIST,
1204             NULL);
1205     gtk_tree_view_append_column(GTK_TREE_VIEW(treeviewFiles), column_Artist);
1206     gtk_tree_view_column_set_sort_column_id(column_Artist, COL_FL_ARTIST);
1207     gtk_tree_view_column_set_resizable(column_Artist, TRUE);
1208     gtk_tree_view_column_set_spacing(column_Artist, 5);
1209     gtk_tree_view_column_set_visible(column_Artist, Preferences.view_artist);
1210 
1211     header = gtk_label_new(_("Artist"));
1212     gtk_widget_show(header);
1213     gtk_tree_view_column_set_widget(column_Artist, header);
1214     parent = gtk_widget_get_ancestor(gtk_tree_view_column_get_widget(column_Artist), GTK_TYPE_BUTTON);
1215 
1216     g_signal_connect_swapped(parent, "button_press_event",
1217             G_CALLBACK(on_windowViewContextMenu_activate), contextMenuColumn);
1218 
1219     // Album column
1220     renderer = gtk_cell_renderer_text_new();
1221     column_Album = gtk_tree_view_column_new_with_attributes(_("Album"), renderer,
1222             "text", COL_FL_ALBUM,
1223             NULL);
1224     gtk_tree_view_append_column(GTK_TREE_VIEW(treeviewFiles), column_Album);
1225     gtk_tree_view_column_set_sort_column_id(column_Album, COL_FL_ALBUM);
1226     gtk_tree_view_column_set_resizable(column_Album, TRUE);
1227     gtk_tree_view_column_set_spacing(column_Album, 5);
1228     gtk_tree_view_column_set_visible(column_Album, Preferences.view_album);
1229 
1230     header = gtk_label_new(_("Album"));
1231     gtk_widget_show(header);
1232     gtk_tree_view_column_set_widget(column_Album, header);
1233     parent = gtk_widget_get_ancestor(gtk_tree_view_column_get_widget(column_Album), GTK_TYPE_BUTTON);
1234 
1235     g_signal_connect_swapped(parent, "button_press_event",
1236             G_CALLBACK(on_windowViewContextMenu_activate), contextMenuColumn);
1237 
1238     // Year column
1239     renderer = gtk_cell_renderer_text_new();
1240     column_Year = gtk_tree_view_column_new_with_attributes(_("Year"), renderer,
1241             "text", COL_YEAR,
1242             NULL);
1243     gtk_tree_view_append_column(GTK_TREE_VIEW(treeviewFiles), column_Year);
1244     gtk_tree_view_column_set_sort_column_id(column_Year, COL_YEAR);
1245     gtk_tree_view_column_set_resizable(column_Year, TRUE);
1246     gtk_tree_view_column_set_spacing(column_Year, 5);
1247     gtk_tree_view_column_set_visible(column_Year, Preferences.view_year);
1248 
1249     header = gtk_label_new(_("Year"));
1250     gtk_widget_show(header);
1251     gtk_tree_view_column_set_widget(column_Year, header);
1252     parent = gtk_widget_get_ancestor(gtk_tree_view_column_get_widget(column_Year), GTK_TYPE_BUTTON);
1253 
1254     g_signal_connect_swapped(parent, "button_press_event",
1255             G_CALLBACK(on_windowViewContextMenu_activate), contextMenuColumn);
1256 
1257     // Genre column
1258     renderer = gtk_cell_renderer_text_new();
1259     column_Genre = gtk_tree_view_column_new_with_attributes(_("Genre"), renderer,
1260             "text", COL_GENRE,
1261             NULL);
1262     gtk_tree_view_append_column(GTK_TREE_VIEW(treeviewFiles), column_Genre);
1263     gtk_tree_view_column_set_sort_column_id(column_Genre, COL_GENRE);
1264     gtk_tree_view_column_set_resizable(column_Genre, TRUE);
1265     gtk_tree_view_column_set_spacing(column_Genre, 5);
1266     gtk_tree_view_column_set_visible(column_Genre, Preferences.view_genre);
1267 
1268     header = gtk_label_new(_("Genre"));
1269     gtk_widget_show(header);
1270     gtk_tree_view_column_set_widget(column_Genre, header);
1271     parent = gtk_widget_get_ancestor(gtk_tree_view_column_get_widget(column_Genre), GTK_TYPE_BUTTON);
1272 
1273     g_signal_connect_swapped(parent, "button_press_event",
1274             G_CALLBACK(on_windowViewContextMenu_activate), contextMenuColumn);
1275 
1276     // Duration Visible column
1277     renderer = gtk_cell_renderer_text_new();
1278     column_Duration = gtk_tree_view_column_new_with_attributes(_("Duration"), renderer,
1279             "text", COL_DURATION,
1280             NULL);
1281     gtk_tree_view_append_column(GTK_TREE_VIEW(treeviewFiles), column_Duration);
1282     gtk_tree_view_column_set_sort_column_id(column_Duration, COL_DURATION_HIDDEN);
1283     gtk_tree_view_column_set_resizable(column_Duration, TRUE);
1284     gtk_tree_view_column_set_spacing(column_Duration, 5);
1285     gtk_tree_view_column_set_visible(column_Duration, Preferences.view_duration);
1286 
1287     header = gtk_label_new(_("Duration"));
1288     gtk_widget_show(header);
1289     gtk_tree_view_column_set_widget(column_Duration, header);
1290     parent = gtk_widget_get_ancestor(gtk_tree_view_column_get_widget(column_Duration), GTK_TYPE_BUTTON);
1291 
1292     g_signal_connect_swapped(parent, "button_press_event",
1293             G_CALLBACK(on_windowViewContextMenu_activate), contextMenuColumn);
1294 
1295     // Duration Hidden column
1296     renderer = gtk_cell_renderer_text_new();
1297     column = gtk_tree_view_column_new_with_attributes("Duration Hidden", renderer,
1298             "text", COL_DURATION_HIDDEN,
1299             NULL);
1300     gtk_tree_view_append_column(GTK_TREE_VIEW(treeviewFiles), column);
1301     gtk_tree_view_column_set_visible(column, FALSE);
1302 
1303     // Location column - only used in search mode.
1304     renderer = gtk_cell_renderer_text_new();
1305     column_Location = gtk_tree_view_column_new_with_attributes(_("Location"), renderer,
1306             "text", COL_LOCATION,
1307             NULL);
1308     gtk_tree_view_append_column(GTK_TREE_VIEW(treeviewFiles), column_Location);
1309     gtk_tree_view_column_set_sort_column_id(column_Location, COL_LOCATION);
1310     gtk_tree_view_column_set_resizable(column_Location, TRUE);
1311     gtk_tree_view_column_set_spacing(column_Location, 5);
1312     gtk_tree_view_column_set_visible(column_Location, FALSE);
1313 
1314     header = gtk_label_new(_("Location"));
1315     gtk_widget_show(header);
1316     gtk_tree_view_column_set_widget(column_Location, header);
1317     parent = gtk_widget_get_ancestor(gtk_tree_view_column_get_widget(column_Location), GTK_TYPE_BUTTON);
1318 
1319     g_signal_connect_swapped(parent, "button_press_event",
1320             G_CALLBACK(on_windowViewContextMenu_activate), contextMenuColumn);
1321 }
1322 
1323 // ************************************************************************************************
1324 
setupFolderList(GtkTreeView * treeviewFolders)1325 GtkTreeViewColumn *setupFolderList(GtkTreeView *treeviewFolders) {
1326     GtkCellRenderer *renderer;
1327     GtkTreeViewColumn *column;
1328     GtkTreeViewColumn *folderColumnInt;
1329 
1330     folderColumnInt = gtk_tree_view_column_new();
1331     gtk_tree_view_column_set_title(folderColumnInt, _("Folder"));
1332 
1333     renderer = gtk_cell_renderer_pixbuf_new();
1334     gtk_tree_view_column_pack_start(folderColumnInt, renderer, FALSE);
1335     gtk_tree_view_column_set_attributes(folderColumnInt, renderer, "pixbuf", COL_FOL_ICON, NULL);
1336 
1337     renderer = gtk_cell_renderer_text_new();
1338     g_object_set(renderer, "weight", PANGO_WEIGHT_BOLD, NULL);
1339     gtk_tree_view_column_pack_start(folderColumnInt, renderer, TRUE);
1340     gtk_tree_view_column_set_attributes(folderColumnInt, renderer, "text", COL_FOL_NAME_HIDDEN, NULL);
1341 
1342     gtk_tree_view_append_column(GTK_TREE_VIEW(treeviewFolders), folderColumnInt);
1343     gtk_tree_view_column_set_sort_column_id(folderColumnInt, COL_FOL_NAME_HIDDEN);
1344     gtk_tree_view_column_set_resizable(folderColumnInt, TRUE);
1345     gtk_tree_view_column_set_spacing(folderColumnInt, 5);
1346 
1347     // Folder column for sorting.
1348     renderer = gtk_cell_renderer_text_new();
1349     column = gtk_tree_view_column_new_with_attributes("Folder name Hidden", renderer,
1350             "text", COL_FOL_NAME_HIDDEN,
1351             NULL);
1352     gtk_tree_view_append_column(GTK_TREE_VIEW(treeviewFolders), column);
1353     gtk_tree_view_column_set_visible(column, FALSE);
1354 
1355     return folderColumnInt;
1356 }
1357 
1358 // ************************************************************************************************
1359 
fileListClear()1360 gboolean fileListClear() {
1361     gtk_list_store_clear(GTK_LIST_STORE(fileList));
1362     return TRUE;
1363 }
1364 
1365 // ************************************************************************************************
1366 
folderListClear()1367 gboolean folderListClear() {
1368     gtk_tree_store_clear(GTK_TREE_STORE(folderList));
1369     return TRUE;
1370 }
1371 
1372 // ************************************************************************************************
1373 
getFileGetList2Add()1374 GSList* getFileGetList2Add() {
1375     GSList* files = NULL;
1376     GtkWidget *FileDialog;
1377 
1378     FileDialog = gtk_file_chooser_dialog_new(_("Select Files to Add"),
1379             GTK_WINDOW(windowMain), GTK_FILE_CHOOSER_ACTION_OPEN,
1380             _("_Cancel"), GTK_RESPONSE_CANCEL,
1381             _("_Open"), GTK_RESPONSE_ACCEPT,
1382             NULL);
1383 
1384     gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(FileDialog), TRUE);
1385     gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(FileDialog), Preferences.fileSystemUploadPath->str);
1386     if (gtk_dialog_run(GTK_DIALOG(FileDialog)) == GTK_RESPONSE_ACCEPT) {
1387         gchar *savepath = gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(FileDialog));
1388         // Save our upload path.
1389         Preferences.fileSystemUploadPath = g_string_assign(Preferences.fileSystemUploadPath, savepath);
1390         files = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(FileDialog));
1391         g_free(savepath);
1392     }
1393 
1394     gtk_widget_hide(FileDialog);
1395     gtk_widget_destroy(FileDialog);
1396     return files;
1397 }
1398 
1399 // ************************************************************************************************
1400 
fileListAdd()1401 gboolean fileListAdd() {
1402     GtkTreeIter rowIter;
1403     //gchar *filename = NULL;
1404     gchar *filename_hid = NULL;
1405     gchar *filesize = NULL;
1406     gchar *filetype = NULL;
1407     gchar *trackduration = NULL;
1408     gchar *tracknumber = NULL;
1409     gchar *fileext = NULL;
1410     LIBMTP_folder_t *tmpfolder;
1411     LIBMTP_file_t *tmpfile;
1412     guint parentID;
1413     GdkPixbuf *image = NULL;
1414 
1415     // Confirm our currentFolder exists otherwise goto the root folder.
1416     if (!Preferences.use_alt_access_method) {
1417         tmpfolder = getCurrentFolderPtr(deviceFolders, currentFolderID);
1418         if (tmpfolder == NULL)
1419             currentFolderID = 0;
1420     } else {
1421         // deviceFolders is NULL or has garbage. So assume that we actually do exist!
1422         filesUpateFileList();
1423     }
1424     // This ensure that if the current folder or a parent of is deleted in the find mode,
1425     // the current folder is reset to something sane.
1426 
1427     // Start our file listing.
1428     if (inFindMode == FALSE) {
1429         // Since we are in normal mode, hide the location Column.
1430         gtk_tree_view_column_set_visible(column_Location, FALSE);
1431         // We start with the folder list...
1432         if (currentFolderID != 0) {
1433             // If we are not folderID = 0; then...
1434             image = gdk_pixbuf_new_from_file(file_folder_png, NULL);
1435             // Scan the folder list for the current folderID, and set the parent ID,
1436             if (!Preferences.use_alt_access_method) {
1437                 tmpfolder = deviceFolders;
1438                 parentID = getParentFolderID(tmpfolder, currentFolderID);
1439             } else {
1440                 parentID = *((guint*) g_queue_peek_tail(stackFolderIDs));
1441             }
1442             // Now add in the row information.
1443             gtk_list_store_append(GTK_LIST_STORE(fileList), &rowIter);
1444             gtk_list_store_set(GTK_LIST_STORE(fileList), &rowIter,
1445                     //COL_FILENAME, "< .. >",
1446                     COL_FILENAME_HIDDEN, "     < .. >",
1447                     COL_FILENAME_ACTUAL, "..",
1448                     COL_FILESIZE, "",
1449                     COL_FILEID, parentID,
1450                     COL_ISFOLDER, TRUE,
1451                     COL_FILESIZE_HID, (guint64) 0,
1452                     COL_ICON, image,
1453                     -1);
1454 
1455             // Indicate we are done with this image.
1456             g_object_unref(image);
1457         }
1458 
1459         // Only use device folders if using normal display mode.
1460         if (!Preferences.use_alt_access_method) {
1461             // What we scan for is the folder's details where 'parent_id' == currentFolderID and display those.
1462             tmpfolder = getParentFolderPtr(deviceFolders, currentFolderID);
1463             while (tmpfolder != NULL) {
1464                 if ((tmpfolder->parent_id == currentFolderID) && (tmpfolder->storage_id == DeviceMgr.devicestorage->id)) {
1465                     image = gdk_pixbuf_new_from_file(file_folder_png, NULL);
1466                     gtk_list_store_append(GTK_LIST_STORE(fileList), &rowIter);
1467                     //filename = g_strdup_printf("< %s >", tmpfolder->name);
1468                     filename_hid = g_strdup_printf("     < %s >", tmpfolder->name);
1469                     gtk_list_store_set(GTK_LIST_STORE(fileList), &rowIter,
1470                             //COL_FILENAME, filename,
1471                             COL_FILENAME_HIDDEN, filename_hid,
1472                             COL_FILENAME_ACTUAL, tmpfolder->name,
1473                             COL_FILESIZE, "",
1474                             COL_FILEID, tmpfolder->folder_id,
1475                             COL_ISFOLDER, TRUE,
1476                             COL_FILESIZE_HID, (guint64) 0,
1477                             COL_ICON, image,
1478                             -1);
1479                     //g_free(filename);
1480                     g_free(filename_hid);
1481                     // Indicate we are done with this image.
1482                     g_object_unref(image);
1483                 }
1484                 tmpfolder = tmpfolder->sibling;
1485             }
1486         }
1487         // We don't destroy the structure, only on a rescan operation.
1488 
1489         // We scan for files in the file details we 'parent_id' == currentFolderID and display those.
1490         tmpfile = deviceFiles;
1491         while (tmpfile != NULL) {
1492 
1493             if ((tmpfile->parent_id == currentFolderID) && (tmpfile->storage_id == DeviceMgr.devicestorage->id)) {
1494                 gtk_list_store_append(GTK_LIST_STORE(fileList), &rowIter);
1495                 filesize = calculateFriendlySize(tmpfile->filesize);
1496                 fileext = strrchr(tmpfile->filename, '.');
1497                 // This accounts for the case with a filename without any "." (period).
1498                 if (!fileext) {
1499                     gchar* tmpStr = g_ascii_strup(tmpfile->filename, -1);
1500                     filetype = g_strconcat(tmpStr, " File", NULL);
1501                     g_free(tmpStr);
1502                 } else {
1503                     gchar* tmpStr = g_ascii_strup(++fileext, -1);
1504                     filetype = g_strconcat(tmpStr, " File", NULL);
1505                     g_free(tmpStr);
1506                 }
1507 
1508                 // Get the type, and if it's one of the supported types, get the metadata for it.
1509                 gboolean useTrack = (tmpfile->filetype == LIBMTP_FILETYPE_MP3) ||
1510                         (tmpfile->filetype == LIBMTP_FILETYPE_OGG) ||
1511                         (tmpfile->filetype == LIBMTP_FILETYPE_FLAC) ||
1512                         (tmpfile->filetype == LIBMTP_FILETYPE_WMA);
1513                 // Ignore track metadata if we are treating all media as regular files.
1514                 if (Preferences.allmediaasfiles) {
1515                     useTrack = FALSE;
1516                 }
1517 
1518                 // Now if it's a track type file, eg OGG, WMA, MP3 or FLAC, get it's metadata.
1519                 if (useTrack) {
1520                     LIBMTP_track_t *trackinfo;
1521                     trackinfo = LIBMTP_Get_Trackmetadata(DeviceMgr.device, tmpfile->item_id);
1522                     if (trackinfo != NULL) {
1523                         trackduration = g_strdup_printf("%d:%.2d", (int) ((trackinfo->duration / 1000) / 60),
1524                                 (int) ((trackinfo->duration / 1000) % 60));
1525                         if (trackinfo->tracknumber != 0) {
1526                             tracknumber = g_strdup_printf("%d", trackinfo->tracknumber);
1527                         } else {
1528                             tracknumber = g_strdup(" ");
1529                         }
1530                         // Some basic sanitisation.
1531                         if (trackinfo->title == NULL) trackinfo->title = g_strdup("");
1532                         if (trackinfo->artist == NULL) trackinfo->artist = g_strdup("");
1533                         if (trackinfo->album == NULL) trackinfo->album = g_strdup("");
1534                         if (trackinfo->date == NULL) {
1535                             trackinfo->date = g_strdup("");
1536                         } else {
1537                             if (strlen(trackinfo->date) > 4)
1538                                 trackinfo->date[4] = '\0'; // Shorten the string to year only, yes this is nasty...
1539                         }
1540                         if (trackinfo->genre == NULL) trackinfo->genre = g_strdup("");
1541 
1542                         // Icon
1543                         image = gdk_pixbuf_new_from_file(file_audio_png, NULL);
1544 
1545                         gtk_list_store_set(GTK_LIST_STORE(fileList), &rowIter,
1546                                 //COL_FILENAME, tmpfile->filename,
1547                                 COL_FILENAME_HIDDEN, tmpfile->filename,
1548                                 COL_FILENAME_ACTUAL, tmpfile->filename,
1549                                 COL_FILESIZE, filesize,
1550                                 COL_FILEID, tmpfile->item_id,
1551                                 COL_ISFOLDER, FALSE,
1552                                 COL_FILESIZE_HID, tmpfile->filesize,
1553                                 COL_TYPE, filetype,
1554                                 COL_TRACK_NUMBER, tracknumber,
1555                                 COL_TRACK_NUMBER_HIDDEN, trackinfo->tracknumber,
1556                                 COL_TITLE, trackinfo->title,
1557                                 COL_FL_ARTIST, trackinfo->artist,
1558                                 COL_FL_ALBUM, trackinfo->album,
1559                                 COL_YEAR, trackinfo->date,
1560                                 COL_GENRE, trackinfo->genre,
1561                                 COL_DURATION, trackduration,
1562                                 COL_DURATION_HIDDEN, trackinfo->duration,
1563                                 COL_ICON, image,
1564                                 -1);
1565                         g_free(trackduration);
1566                         g_free(tracknumber);
1567                         trackduration = NULL;
1568                         tracknumber = NULL;
1569                         // Indicate we are done with this image.
1570                         g_object_unref(image);
1571                         LIBMTP_destroy_track_t(trackinfo);
1572                     } else {
1573                         LIBMTP_Dump_Errorstack(DeviceMgr.device);
1574                         LIBMTP_Clear_Errorstack(DeviceMgr.device);
1575                     }
1576                 } else {
1577                     // Determine the file type.
1578                     if (LIBMTP_FILETYPE_IS_AUDIO(tmpfile->filetype)) {
1579                         image = gdk_pixbuf_new_from_file(file_audio_png, NULL);
1580                     } else if (LIBMTP_FILETYPE_IS_AUDIOVIDEO(tmpfile->filetype)) {
1581                         image = gdk_pixbuf_new_from_file(file_video_png, NULL);
1582                     } else if (LIBMTP_FILETYPE_IS_VIDEO(tmpfile->filetype)) {
1583                         image = gdk_pixbuf_new_from_file(file_video_png, NULL);
1584                     } else if (LIBMTP_FILETYPE_IS_IMAGE(tmpfile->filetype)) {
1585                         image = gdk_pixbuf_new_from_file(file_image_png, NULL);
1586                     } else if (tmpfile->filetype == LIBMTP_FILETYPE_ALBUM) {
1587                         image = gdk_pixbuf_new_from_file(file_album_png, NULL);
1588                     } else if (tmpfile->filetype == LIBMTP_FILETYPE_PLAYLIST) {
1589                         image = gdk_pixbuf_new_from_file(file_playlist_png, NULL);
1590                     } else if (tmpfile->filetype == LIBMTP_FILETYPE_TEXT) {
1591                         image = gdk_pixbuf_new_from_file(file_textfile_png, NULL);
1592                     } else if (tmpfile->filetype == LIBMTP_FILETYPE_FOLDER) {
1593                         image = gdk_pixbuf_new_from_file(file_folder_png, NULL);
1594                     } else {
1595                         image = gdk_pixbuf_new_from_file(file_generic_png, NULL);
1596                     }
1597 
1598                     // let folders through IFF we are in alt connection mode.
1599                     if (!Preferences.use_alt_access_method && tmpfile->filetype == LIBMTP_FILETYPE_FOLDER) {
1600                         goto skipAdd;
1601                     }
1602 
1603                     // Set folder type.
1604                     int isFolder = FALSE;
1605                     if (tmpfile->filetype == LIBMTP_FILETYPE_FOLDER) {
1606                         isFolder = TRUE;
1607                         if (filesize != NULL)
1608                             g_free(filesize);
1609                         if (filetype != NULL)
1610                             g_free(filetype);
1611                         filesize = g_strdup("");
1612                         filetype = g_strdup("");
1613                         filename_hid = g_strdup_printf("     < %s >", tmpfile->filename);
1614                     } else {
1615                         filename_hid = g_strdup(tmpfile->filename);
1616                     }
1617 
1618                     // Otherwise just show the file information
1619                     gtk_list_store_set(GTK_LIST_STORE(fileList), &rowIter,
1620                             //COL_FILENAME, tmpfile->filename,
1621                             COL_FILENAME_HIDDEN, filename_hid,
1622                             COL_FILENAME_ACTUAL, tmpfile->filename,
1623                             COL_FILESIZE, filesize,
1624                             COL_FILEID, tmpfile->item_id,
1625                             COL_ISFOLDER, isFolder,
1626                             COL_FILESIZE_HID, tmpfile->filesize,
1627                             COL_TYPE, filetype,
1628                             COL_ICON, image,
1629                             -1);
1630                     g_free(filename_hid);
1631 skipAdd:
1632 
1633                     // Indicate we are done with this image.
1634                     g_object_unref(image);
1635                 }
1636 
1637                 if (filetype != NULL)
1638                     g_free(filetype);
1639                 filetype = NULL;
1640 
1641                 if (filesize != NULL)
1642                     g_free(filesize);
1643                 filesize = NULL;
1644             }
1645             tmpfile = tmpfile->next;
1646         }
1647 
1648         // Now update the title bar with our folder name.
1649         if (!Preferences.use_alt_access_method) {
1650             setWindowTitle(getFullFolderPath(currentFolderID));
1651         } else {
1652             // Construct the place string based on the contents of the stackFolderNameQueue.
1653             gchar* fullfilename = g_strdup("");
1654             gchar* tmpfilename = NULL;
1655             guint stringlength = 0;
1656             int items = g_queue_get_length(stackFolderNames);
1657 
1658             // Add in our names;
1659             while (items-- > 0) {
1660                 tmpfilename = g_strdup_printf("%s/%s", (gchar *) g_queue_peek_nth(stackFolderNames, items), fullfilename);
1661                 g_free(fullfilename);
1662                 fullfilename = tmpfilename;
1663             }
1664             // Add in leading slash if needed
1665             if (*fullfilename != '/') {
1666                 tmpfilename = g_strdup_printf("/%s", fullfilename);
1667                 g_free(fullfilename);
1668                 fullfilename = tmpfilename;
1669             }
1670             // Remove trailing slash if needed.
1671             stringlength = strlen(fullfilename);
1672             if (stringlength > 1) {
1673                 fullfilename[stringlength - 1] = '\0';
1674             }
1675             setWindowTitle(fullfilename);
1676             g_free(fullfilename);
1677         }
1678     } else {
1679         // We are in search mode, so use the searchList instead as our source!
1680         gint item_count = 0;
1681         GSList *tmpsearchList = searchList;
1682         FileListStruc *itemdata = NULL;
1683         while (tmpsearchList != NULL) {
1684             // Add our files/folders.
1685             itemdata = tmpsearchList->data;
1686             item_count++;
1687             // If a folder...
1688             if (itemdata->isFolder == TRUE) {
1689                 image = gdk_pixbuf_new_from_file(file_folder_png, NULL);
1690                 gtk_list_store_append(GTK_LIST_STORE(fileList), &rowIter);
1691                 //filename = g_strdup_printf("< %s >", tmpfolder->name);
1692                 filename_hid = g_strdup_printf("     < %s >", itemdata->filename);
1693                 gtk_list_store_set(GTK_LIST_STORE(fileList), &rowIter,
1694                         //COL_FILENAME, filename,
1695                         COL_FILENAME_HIDDEN, filename_hid,
1696                         COL_FILENAME_ACTUAL, itemdata->filename,
1697                         COL_FILESIZE, "",
1698                         COL_FILEID, itemdata->itemid,
1699                         COL_ISFOLDER, TRUE,
1700                         COL_FILESIZE_HID, (guint64) 0,
1701                         COL_ICON, image,
1702                         COL_LOCATION, itemdata->location,
1703                         -1);
1704                 //g_free(filename);
1705                 g_free(filename_hid);
1706                 // Indicate we are done with this image.
1707                 g_object_unref(image);
1708 
1709             } else {
1710                 // else if a file...
1711                 gtk_list_store_append(GTK_LIST_STORE(fileList), &rowIter);
1712                 filesize = calculateFriendlySize(itemdata->filesize);
1713                 fileext = strrchr(itemdata->filename, '.');
1714                 // This accounts for the case with a filename without any "." (period).
1715                 if (!fileext) {
1716                     filetype = g_strconcat(g_ascii_strup(itemdata->filename, -1), " File", NULL);
1717                 } else {
1718                     filetype = g_strconcat(g_ascii_strup(++fileext, -1), " File", NULL);
1719                 }
1720                 // Get the type, and if it's one of the supported types, get the metadata for it.
1721                 gboolean useTrack = (itemdata->filetype == LIBMTP_FILETYPE_MP3) ||
1722                         (itemdata->filetype == LIBMTP_FILETYPE_OGG) ||
1723                         (itemdata->filetype == LIBMTP_FILETYPE_FLAC) ||
1724                         (itemdata->filetype == LIBMTP_FILETYPE_WMA);
1725                 // Ignore track metadata if we are treating all media as regular files.
1726                 if (Preferences.allmediaasfiles) {
1727                     useTrack = FALSE;
1728                 }
1729 
1730                 // Now if it's a track type file, eg OGG, WMA, MP3 or FLAC, get it's metadata.
1731                 if (useTrack) {
1732                     LIBMTP_track_t *trackinfo;
1733                     trackinfo = LIBMTP_Get_Trackmetadata(DeviceMgr.device, itemdata->itemid);
1734                     if (trackinfo != NULL) {
1735                         trackduration = g_strdup_printf("%d:%.2d", (int) ((trackinfo->duration / 1000) / 60),
1736                                 (int) ((trackinfo->duration / 1000) % 60));
1737                         if (trackinfo->tracknumber != 0) {
1738                             tracknumber = g_strdup_printf("%d", trackinfo->tracknumber);
1739                         } else {
1740                             tracknumber = g_strdup(" ");
1741                         }
1742                         // Some basic sanitisation.
1743                         if (trackinfo->title == NULL) trackinfo->title = g_strdup("");
1744                         if (trackinfo->artist == NULL) trackinfo->artist = g_strdup("");
1745                         if (trackinfo->album == NULL) trackinfo->album = g_strdup("");
1746                         if (trackinfo->date == NULL) trackinfo->date = g_strdup("");
1747                         if (trackinfo->genre == NULL) trackinfo->genre = g_strdup("");
1748 
1749                         // Icon
1750                         image = gdk_pixbuf_new_from_file(file_audio_png, NULL);
1751 
1752                         gtk_list_store_set(GTK_LIST_STORE(fileList), &rowIter,
1753                                 //COL_FILENAME, tmpfile->filename,
1754                                 COL_FILENAME_HIDDEN, itemdata->filename,
1755                                 COL_FILENAME_ACTUAL, itemdata->filename,
1756                                 COL_FILESIZE, filesize,
1757                                 COL_FILEID, itemdata->itemid,
1758                                 COL_ISFOLDER, FALSE,
1759                                 COL_FILESIZE_HID, itemdata->filesize,
1760                                 COL_TYPE, filetype,
1761                                 COL_TRACK_NUMBER, tracknumber,
1762                                 COL_TRACK_NUMBER_HIDDEN, trackinfo->tracknumber,
1763                                 COL_TITLE, trackinfo->title,
1764                                 COL_FL_ARTIST, trackinfo->artist,
1765                                 COL_FL_ALBUM, trackinfo->album,
1766                                 COL_YEAR, trackinfo->date,
1767                                 COL_GENRE, trackinfo->genre,
1768                                 COL_DURATION, trackduration,
1769                                 COL_DURATION_HIDDEN, trackinfo->duration,
1770                                 COL_ICON, image,
1771                                 COL_LOCATION, itemdata->location,
1772                                 -1);
1773                         g_free(trackduration);
1774                         g_free(tracknumber);
1775                         trackduration = NULL;
1776                         tracknumber = NULL;
1777                         // Indicate we are done with this image.
1778                         g_object_unref(image);
1779                         LIBMTP_destroy_track_t(trackinfo);
1780                     } else {
1781                         LIBMTP_Dump_Errorstack(DeviceMgr.device);
1782                         LIBMTP_Clear_Errorstack(DeviceMgr.device);
1783                     }
1784                 } else {
1785                     // Determine the file type.
1786                     if (LIBMTP_FILETYPE_IS_AUDIO(itemdata->filetype)) {
1787                         image = gdk_pixbuf_new_from_file(file_audio_png, NULL);
1788                     } else if (LIBMTP_FILETYPE_IS_AUDIOVIDEO(itemdata->filetype)) {
1789                         image = gdk_pixbuf_new_from_file(file_video_png, NULL);
1790                     } else if (LIBMTP_FILETYPE_IS_VIDEO(itemdata->filetype)) {
1791                         image = gdk_pixbuf_new_from_file(file_video_png, NULL);
1792                     } else if (LIBMTP_FILETYPE_IS_IMAGE(itemdata->filetype)) {
1793                         image = gdk_pixbuf_new_from_file(file_image_png, NULL);
1794                     } else if (itemdata->filetype == LIBMTP_FILETYPE_ALBUM) {
1795                         image = gdk_pixbuf_new_from_file(file_album_png, NULL);
1796                     } else if (itemdata->filetype == LIBMTP_FILETYPE_PLAYLIST) {
1797                         image = gdk_pixbuf_new_from_file(file_playlist_png, NULL);
1798                     } else if (itemdata->filetype == LIBMTP_FILETYPE_TEXT) {
1799                         image = gdk_pixbuf_new_from_file(file_textfile_png, NULL);
1800                     } else if (itemdata->filetype == LIBMTP_FILETYPE_FOLDER) {
1801                         image = gdk_pixbuf_new_from_file(file_folder_png, NULL);
1802                     } else {
1803                         image = gdk_pixbuf_new_from_file(file_generic_png, NULL);
1804                     }
1805 
1806                     // let folders through IFF we are in alt connection mode.
1807                     if (!Preferences.use_alt_access_method && itemdata->filetype == LIBMTP_FILETYPE_FOLDER) {
1808                         goto skipAdd2;
1809                     }
1810 
1811                     // Set folder type.
1812                     //int isFolder = FALSE;
1813                     if (itemdata->filetype == LIBMTP_FILETYPE_FOLDER) {
1814                         //isFolder = TRUE;
1815                         if (filesize != NULL)
1816                             g_free(filesize);
1817                         if (filetype != NULL)
1818                             g_free(filetype);
1819                         filesize = g_strdup("");
1820                         filetype = g_strdup("");
1821                         filename_hid = g_strdup_printf("     < %s >", itemdata->filename);
1822                     } else {
1823                         filename_hid = g_strdup(itemdata->filename);
1824                     }
1825 
1826                     // Otherwise just show the file information
1827                     gtk_list_store_set(GTK_LIST_STORE(fileList), &rowIter,
1828                             //COL_FILENAME, tmpfile->filename,
1829                             COL_FILENAME_HIDDEN, itemdata->filename,
1830                             COL_FILENAME_ACTUAL, itemdata->filename,
1831                             COL_FILESIZE, filesize,
1832                             COL_FILEID, itemdata->itemid,
1833                             COL_ISFOLDER, FALSE,
1834                             COL_FILESIZE_HID, itemdata->filesize,
1835                             COL_TYPE, filetype,
1836                             COL_ICON, image,
1837                             COL_LOCATION, itemdata->location,
1838                             -1);
1839                     // Indicate we are done with this image.
1840                     g_free(filename_hid);
1841 skipAdd2:
1842                     g_object_unref(image);
1843                 }
1844 
1845                 if (filetype != NULL)
1846                     g_free(filetype);
1847                 filetype = NULL;
1848 
1849                 if (filesize != NULL)
1850                     g_free(filesize);
1851                 filesize = NULL;
1852             }
1853             tmpsearchList = tmpsearchList->next;
1854         }
1855         gchar *tmp_string;
1856         if (item_count != 1) {
1857             tmp_string = g_strdup_printf(_("Found %d items"), item_count);
1858         } else {
1859             tmp_string = g_strdup_printf(_("Found %d item"), item_count);
1860         }
1861         statusBarSet(tmp_string);
1862         g_free(tmp_string);
1863     }
1864     return TRUE;
1865 }
1866 
1867 // ************************************************************************************************
1868 
folderListAdd(LIBMTP_folder_t * folders,GtkTreeIter * parent)1869 gboolean folderListAdd(LIBMTP_folder_t *folders, GtkTreeIter *parent) {
1870     GtkTreeIter rowIter;
1871     GdkPixbuf *image = NULL;
1872 
1873     if (parent == NULL) {
1874         // Add in the root node.
1875         image = gdk_pixbuf_new_from_file(file_folder_png, NULL);
1876         // Now add in the row information.
1877         gtk_tree_store_append(GTK_TREE_STORE(folderList), &rowIter, parent);
1878         gtk_tree_store_set(GTK_TREE_STORE(folderList), &rowIter,
1879                 //COL_FOL_NAME, folders->name,
1880                 COL_FOL_NAME_HIDDEN, "/",
1881                 COL_FOL_ID, 0,
1882                 COL_FOL_ICON, image,
1883                 -1);
1884 
1885         // Indicate we are done with this image.
1886         g_object_unref(image);
1887         folderListAdd(folders, &rowIter);
1888         return TRUE;
1889     }
1890 
1891     while (folders != NULL) {
1892         // Only add in folder if it's in the current storage device.
1893         if (folders->storage_id == DeviceMgr.devicestorage->id) {
1894 
1895             image = gdk_pixbuf_new_from_file(file_folder_png, NULL);
1896             // Now add in the row information.
1897             gtk_tree_store_append(GTK_TREE_STORE(folderList), &rowIter, parent);
1898             gtk_tree_store_set(GTK_TREE_STORE(folderList), &rowIter,
1899                     //COL_FOL_NAME, folders->name,
1900                     COL_FOL_NAME_HIDDEN, folders->name,
1901                     COL_FOL_ID, folders->folder_id,
1902                     COL_FOL_ICON, image,
1903                     -1);
1904 
1905             // Indicate we are done with this image.
1906             g_object_unref(image);
1907             if (folders->child != NULL) {
1908                 // Call our child.
1909                 folderListAdd(folders->child, &rowIter);
1910             }
1911         }
1912         folders = folders->sibling;
1913     }
1914     gtk_tree_view_expand_all(GTK_TREE_VIEW(treeviewFolders));
1915     gtk_tree_view_column_set_sort_order(folderColumn, GTK_SORT_ASCENDING);
1916     return TRUE;
1917 }
1918 
1919 // ************************************************************************************************
1920 
fileListDownload(GList * List)1921 gboolean fileListDownload(GList *List) {
1922     gchar *savepath = NULL;
1923 
1924     // Let's confirm our download path.
1925     if (Preferences.ask_download_path == TRUE) {
1926         GtkWidget *FileDialog = gtk_file_chooser_dialog_new(_("Select Path to Download"),
1927                 GTK_WINDOW(windowMain), GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
1928                 _("_Cancel"), GTK_RESPONSE_CANCEL,
1929                 _("_Open"), GTK_RESPONSE_ACCEPT,
1930                 NULL);
1931 
1932         gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(FileDialog), Preferences.fileSystemDownloadPath->str);
1933         if (gtk_dialog_run(GTK_DIALOG(FileDialog)) == GTK_RESPONSE_ACCEPT) {
1934             gtk_widget_hide(FileDialog);
1935             savepath = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(FileDialog));
1936             // Save our download path.
1937             Preferences.fileSystemDownloadPath = g_string_assign(Preferences.fileSystemDownloadPath, savepath);
1938             // We do the deed.
1939             g_list_foreach(List, (GFunc) __fileDownload, NULL);
1940             fileoverwriteop = MTP_ASK;
1941         }
1942         gtk_widget_destroy(FileDialog);
1943     } else {
1944         // We do the deed.
1945         g_list_foreach(List, (GFunc) __fileDownload, NULL);
1946         fileoverwriteop = MTP_ASK;
1947     }
1948     if (savepath != NULL)
1949         g_free(savepath);
1950     return TRUE;
1951 }
1952 
1953 // ************************************************************************************************
1954 
folderListDownload(gchar * foldername,uint32_t folderid)1955 gboolean folderListDownload(gchar *foldername, uint32_t folderid) {
1956     gchar *savepath = NULL;
1957     // Let's confirm our download path.
1958     if (Preferences.ask_download_path == TRUE) {
1959         GtkWidget *FileDialog = gtk_file_chooser_dialog_new(_("Select Path to Download"),
1960                 GTK_WINDOW(windowMain), GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
1961                 _("_Cancel"), GTK_RESPONSE_CANCEL,
1962                 _("_Open"), GTK_RESPONSE_ACCEPT,
1963                 NULL);
1964 
1965         gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(FileDialog), Preferences.fileSystemDownloadPath->str);
1966         if (gtk_dialog_run(GTK_DIALOG(FileDialog)) == GTK_RESPONSE_ACCEPT) {
1967             gtk_widget_hide(FileDialog);
1968             savepath = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(FileDialog));
1969             // Save our download path.
1970             Preferences.fileSystemDownloadPath = g_string_assign(Preferences.fileSystemDownloadPath, savepath);
1971             // We do the deed.
1972             displayProgressBar(_("File download"));
1973             folderDownload(foldername, folderid, TRUE);
1974             destroyProgressBar();
1975             fileoverwriteop = MTP_ASK;
1976         }
1977         gtk_widget_destroy(FileDialog);
1978     } else {
1979         // We do the deed.
1980         displayProgressBar(_("File download"));
1981         folderDownload(foldername, folderid, TRUE);
1982         destroyProgressBar();
1983         fileoverwriteop = MTP_ASK;
1984     }
1985     if (savepath != NULL)
1986         g_free(savepath);
1987     return TRUE;
1988 }
1989 
1990 // ************************************************************************************************
1991 
1992 /**
1993  * Perform each file individually.
1994  * @param Row
1995  */
__fileDownload(GtkTreeRowReference * Row)1996 void __fileDownload(GtkTreeRowReference *Row) {
1997     GtkTreePath *path;
1998     GtkTreeIter iter;
1999     gchar *filename = NULL;
2000     gchar* fullfilename = NULL;
2001 
2002     gboolean isFolder;
2003     uint32_t objectID;
2004 
2005 
2006     fullfilename = g_malloc0(8192);
2007     // First of all, lets set the download path.
2008 
2009     // convert the referenece to a path and retrieve the iterator;
2010     path = gtk_tree_row_reference_get_path(Row);
2011     gtk_tree_model_get_iter(GTK_TREE_MODEL(fileList), &iter, path);
2012     // We have our Iter now.
2013     // Before we download, is it a folder ?
2014     gtk_tree_model_get(GTK_TREE_MODEL(fileList), &iter, COL_ISFOLDER, &isFolder, COL_FILENAME_ACTUAL, &filename, COL_FILEID, &objectID, -1);
2015     if (isFolder == FALSE) {
2016         // Our strings are not equal, so we get to download the file.
2017         g_sprintf(fullfilename, "%s/%s", Preferences.fileSystemDownloadPath->str, filename);
2018         // Now download the actual file from the MTP device.
2019         // Check if file exists?
2020         if (access(fullfilename, F_OK) != -1) {
2021             // We have that file already?
2022             if (Preferences.prompt_overwrite_file_op == TRUE) {
2023                 if (fileoverwriteop == MTP_ASK) {
2024                     fileoverwriteop = displayFileOverwriteDialog(filename);
2025                 }
2026                 switch (fileoverwriteop) {
2027                     case MTP_ASK:
2028                         break;
2029                     case MTP_SKIP:
2030                         fileoverwriteop = MTP_ASK;
2031                         break;
2032                     case MTP_SKIP_ALL:
2033                         break;
2034                     case MTP_OVERWRITE:
2035                         filesDownload(filename, objectID);
2036                         fileoverwriteop = MTP_ASK;
2037                         break;
2038                     case MTP_OVERWRITE_ALL:
2039                         filesDownload(filename, objectID);
2040                         break;
2041                 }
2042             } else {
2043                 filesDownload(filename, objectID);
2044             }
2045         } else {
2046             filesDownload(filename, objectID);
2047         }
2048     } else {
2049         // Overwrite critera performed within this call...
2050         if (g_ascii_strcasecmp(filename, "..") != 0) {
2051             folderDownload(filename, objectID, TRUE);
2052         } else {
2053             g_fprintf(stderr, _("I don't know how to download a parent folder reference?\n"));
2054             displayError(_("I don't know how to download a parent folder reference?\n"));
2055         }
2056     }
2057     gtk_tree_path_free(path);
2058     g_free(filename);
2059     g_free(fullfilename);
2060 }
2061 
2062 // ************************************************************************************************
2063 
__fileMove(GtkTreeRowReference * Row)2064 void __fileMove(GtkTreeRowReference *Row) {
2065     GtkTreePath *path;
2066     GtkTreeIter iter;
2067 
2068     gboolean isFolder;
2069     uint32_t objectID;
2070     int error;
2071 
2072     // convert the referenece to a path and retrieve the iterator;
2073     path = gtk_tree_row_reference_get_path(Row);
2074     gtk_tree_model_get_iter(GTK_TREE_MODEL(fileList), &iter, path);
2075     // We have our Iter now.
2076     // Before we move, is it a folder ?
2077     gtk_tree_model_get(GTK_TREE_MODEL(fileList), &iter, COL_ISFOLDER, &isFolder, COL_FILEID, &objectID, -1);
2078     if (isFolder == FALSE) {
2079         if ((error = setNewParentFolderID(objectID, fileMoveTargetFolder)) != 0) {
2080             displayError(_("Unable to move the selected file?\n"));
2081             g_fprintf(stderr, "File Move Error: %d\n", error);
2082             LIBMTP_Dump_Errorstack(DeviceMgr.device);
2083             LIBMTP_Clear_Errorstack(DeviceMgr.device);
2084         }
2085     } else {
2086         // Make sure we don't want to move the folder into itself?
2087         if (objectID == fileMoveTargetFolder) {
2088             displayError(_("Unable to move the selected folder into itself?\n"));
2089             g_fprintf(stderr, _("Unable to move the selected folder into itself?\n"));
2090             return;
2091         }
2092         // We have the target folder, so let's check to ensure that we will not create a circular
2093         // reference by moving a folder underneath it self.
2094         LIBMTP_folder_t *currentFolder = getCurrentFolderPtr(deviceFolders, objectID);
2095         if (currentFolder == NULL) {
2096             // WTF?
2097             g_fprintf(stderr, "File Move Error: Can't get current folder pointer\n");
2098             return;
2099         }
2100         // Use currentFolder as the starting point, and simply attempt to get the ptr to the new
2101         // folder based on this point.
2102         LIBMTP_folder_t *newFolder = getCurrentFolderPtr(currentFolder->child, fileMoveTargetFolder);
2103         if (newFolder == NULL) {
2104             // We are alright to proceed.
2105             if ((error = setNewParentFolderID(objectID, fileMoveTargetFolder)) != 0) {
2106                 displayError(_("Unable to move the selected folder?\n"));
2107                 g_fprintf(stderr, "File Move Error: %d\n", error);
2108                 LIBMTP_Dump_Errorstack(DeviceMgr.device);
2109                 LIBMTP_Clear_Errorstack(DeviceMgr.device);
2110             }
2111         } else {
2112             displayError(_("Unable to move the selected folder underneath itself?\n"));
2113             g_fprintf(stderr, _("Unable to move the selected folder underneath itself?\n"));
2114         }
2115     }
2116 }
2117 
2118 // ************************************************************************************************
2119 
fileListRemove(GList * List)2120 gboolean fileListRemove(GList *List) {
2121     // Clear any selection that is present.
2122     fileListClearSelection();
2123     // List is a list of Iter's to be removed
2124     g_list_foreach(List, (GFunc) __fileRemove, NULL);
2125     // We have 2 options, manually scan the file structure for that file and manually fix up...
2126     // or do a rescan...
2127     // I'll be cheap, and do a full rescan of the device.
2128     deviceRescan();
2129     return TRUE;
2130 }
2131 
2132 // ************************************************************************************************
2133 
2134 /**
2135  * Remove each selected file from the device.
2136  * @param Row
2137  */
__fileRemove(GtkTreeRowReference * Row)2138 void __fileRemove(GtkTreeRowReference *Row) {
2139     GtkTreePath *path;
2140     GtkTreeIter iter;
2141     gchar* filename = NULL;
2142     uint32_t objectID;
2143     gboolean isFolder;
2144     // convert the referenece to a path and retrieve the iterator;
2145     path = gtk_tree_row_reference_get_path(Row);
2146     gtk_tree_model_get_iter(GTK_TREE_MODEL(fileList), &iter, path);
2147     // We have our Iter now.
2148     gtk_tree_model_get(GTK_TREE_MODEL(fileList), &iter, COL_ISFOLDER, &isFolder, COL_FILENAME_ACTUAL, &filename,
2149             COL_FILEID, &objectID, -1);
2150     if (isFolder == FALSE) {
2151         gtk_tree_model_get_iter(GTK_TREE_MODEL(fileList), &iter, path);
2152         gtk_list_store_remove(GTK_LIST_STORE(fileList), &iter);
2153         // Now get rid of the actual file from the MTP device.
2154         filesDelete(filename, objectID);
2155     } else {
2156         // Our file is really a folder, so perform a folder remove operation.
2157         __folderRemove(Row);
2158     }
2159     gtk_tree_path_free(path);
2160     g_free(filename);
2161 }
2162 
2163 // ************************************************************************************************
2164 
folderListRemove(GList * List)2165 gboolean folderListRemove(GList *List) {
2166     // Clear any selection that is present.
2167     fileListClearSelection();
2168     // List is a list of Iter's to be removed
2169     g_list_foreach(List, (GFunc) __folderRemove, NULL);
2170     // We have 2 options, manually scan the file structure for that file and manually fix up...
2171     // or do a rescan...
2172     // I'll be cheap, and do a full rescan of the device.
2173     deviceRescan();
2174     return TRUE;
2175 }
2176 
2177 // ************************************************************************************************
2178 
2179 /**
2180  * Remove the indivual folder from the device.
2181  * @param Row
2182  */
__folderRemove(GtkTreeRowReference * Row)2183 void __folderRemove(GtkTreeRowReference *Row) {
2184     GtkTreePath *path;
2185     GtkTreeIter iter;
2186     gchar* filename = NULL;
2187     uint32_t objectID;
2188     gboolean isFolder;
2189 
2190     // convert the referenece to a path and retrieve the iterator;
2191     path = gtk_tree_row_reference_get_path(Row);
2192     gtk_tree_model_get_iter(GTK_TREE_MODEL(fileList), &iter, path);
2193     // We have our Iter now.
2194     gtk_tree_model_get(GTK_TREE_MODEL(fileList), &iter, COL_ISFOLDER, &isFolder, COL_FILENAME_ACTUAL, &filename,
2195             COL_FILEID, &objectID, -1);
2196     if (isFolder == TRUE) {
2197         if (g_ascii_strcasecmp(filename, "..") != 0) {
2198             gtk_tree_model_get_iter(GTK_TREE_MODEL(fileList), &iter, path);
2199             gtk_list_store_remove(GTK_LIST_STORE(fileList), &iter);
2200             // Now get rid of the actual file from the MTP device.
2201             folderDelete(getCurrentFolderPtr(deviceFolders, objectID), 0);
2202         } else {
2203             g_fprintf(stderr, _("I don't know how to delete a parent folder reference?\n"));
2204             displayError(_("I don't know how to delete a parent folder reference?\n"));
2205         }
2206     } else {
2207         // Our folder is really a file, so delete the file instead.
2208         __fileRemove(Row);
2209     }
2210     gtk_tree_path_free(path);
2211     g_free(filename);
2212 }
2213 
2214 // ************************************************************************************************
2215 
__filesAdd(gchar * filename)2216 void __filesAdd(gchar* filename) {
2217     gchar* filename_stripped = NULL;
2218 
2219     filename_stripped = basename(filename);
2220     if (Preferences.prompt_overwrite_file_op == FALSE) {
2221         if (fileExists(filename_stripped) == TRUE) {
2222             filesDelete(filename_stripped, getFile(filename_stripped, currentFolderID));
2223         }
2224         filesAdd(filename);
2225         return;
2226     }
2227     // I guess we want to know if we should replace the file, but first
2228     if (deviceoverwriteop == MTP_ASK) {
2229         if (fileExists(filename_stripped) == TRUE) {
2230             deviceoverwriteop = displayFileOverwriteDialog(filename_stripped);
2231             switch (deviceoverwriteop) {
2232                 case MTP_ASK:
2233                     break;
2234                 case MTP_SKIP:
2235                     deviceoverwriteop = MTP_ASK;
2236                     break;
2237                 case MTP_SKIP_ALL:
2238                     break;
2239                 case MTP_OVERWRITE:
2240                     if (fileExists(filename_stripped) == TRUE) {
2241                         filesDelete(filename_stripped, getFile(filename_stripped, currentFolderID));
2242                     }
2243                     filesAdd(filename);
2244                     deviceoverwriteop = MTP_ASK;
2245                     break;
2246                 case MTP_OVERWRITE_ALL:
2247                     if (fileExists(filename_stripped) == TRUE) {
2248                         filesDelete(filename_stripped, getFile(filename_stripped, currentFolderID));
2249                     }
2250                     filesAdd(filename);
2251                     break;
2252             }
2253         } else {
2254             if (fileExists(filename_stripped) == TRUE) {
2255                 filesDelete(filename_stripped, getFile(filename_stripped, currentFolderID));
2256             }
2257             filesAdd(filename);
2258         }
2259     } else {
2260         if (deviceoverwriteop == MTP_OVERWRITE_ALL) {
2261             if (fileExists(filename_stripped) == TRUE) {
2262                 filesDelete(filename_stripped, getFile(filename_stripped, currentFolderID));
2263             }
2264             filesAdd(filename);
2265         } else if (deviceoverwriteop == MTP_SKIP_ALL) {
2266             // Ensure we add files that don't exist.
2267             if (fileExists(filename_stripped) != TRUE) {
2268                 filesAdd(filename);
2269             }
2270         }
2271     }
2272 }
2273 
2274 // ************************************************************************************************
2275 
fileListGetSelection()2276 GList* fileListGetSelection() {
2277     GList *selectedFiles, *ptr;
2278     GtkTreeModel *sortmodel;
2279     // Lets clear up the old list.
2280     g_list_free(fileSelection_RowReferences);
2281     fileSelection_RowReferences = NULL;
2282 
2283     if (gtk_tree_selection_count_selected_rows(fileSelection) == 0) {
2284         // We have no rows.
2285         return NULL;
2286     }
2287     // So now we must convert each selection to a row reference and store it in a new GList variable
2288     // which we will return below.
2289     sortmodel = gtk_tree_view_get_model(GTK_TREE_VIEW(treeviewFiles));
2290     selectedFiles = gtk_tree_selection_get_selected_rows(fileSelection, &sortmodel);
2291     ptr = selectedFiles;
2292     while (ptr != NULL) {
2293         // Add our row into the GSList so it can be parsed by the respective operations, including
2294         // handling changing from the sort model to the real underlying model.
2295         GtkTreeRowReference *ref = gtk_tree_row_reference_new(GTK_TREE_MODEL(fileList),
2296                 gtk_tree_model_sort_convert_path_to_child_path(GTK_TREE_MODEL_SORT(sortmodel), (GtkTreePath*) ptr->data));
2297         fileSelection_RowReferences = g_list_prepend(fileSelection_RowReferences, gtk_tree_row_reference_copy(ref));
2298         gtk_tree_row_reference_free(ref);
2299         ptr = ptr->next;
2300     }
2301     g_list_foreach(selectedFiles, (GFunc) gtk_tree_path_free, NULL);
2302     g_list_free(selectedFiles);
2303     return fileSelection_RowReferences;
2304 }
2305 
2306 // ************************************************************************************************
2307 
folderListGetSelection(void)2308 int64_t folderListGetSelection(void) {
2309     GtkTreeModel *sortmodel;
2310     GtkTreeIter iter;
2311     GtkTreeIter childiter;
2312     uint32_t objectID;
2313 
2314     if (gtk_tree_selection_count_selected_rows(folderSelection) == 0) {
2315         // We have no rows.
2316         return -1;
2317     }
2318     sortmodel = gtk_tree_view_get_model(GTK_TREE_VIEW(treeviewFolders));
2319     gtk_tree_selection_get_selected(folderSelection, &sortmodel, &iter);
2320     gtk_tree_model_sort_convert_iter_to_child_iter(GTK_TREE_MODEL_SORT(sortmodel), &childiter, &iter);
2321     gtk_tree_model_get(GTK_TREE_MODEL(folderList), &childiter, COL_FOL_ID, &objectID, -1);
2322     return objectID;
2323 }
2324 
2325 // ************************************************************************************************
2326 
folderListGetSelectionName(void)2327 gchar *folderListGetSelectionName(void) {
2328     GtkTreeModel *sortmodel;
2329     GtkTreeIter iter;
2330     GtkTreeIter childiter;
2331     gchar *objectName;
2332 
2333     if (gtk_tree_selection_count_selected_rows(folderSelection) == 0) {
2334         // We have no rows.
2335         return NULL;
2336     }
2337     sortmodel = gtk_tree_view_get_model(GTK_TREE_VIEW(treeviewFolders));
2338     gtk_tree_selection_get_selected(folderSelection, &sortmodel, &iter);
2339     gtk_tree_model_sort_convert_iter_to_child_iter(GTK_TREE_MODEL_SORT(sortmodel), &childiter, &iter);
2340     gtk_tree_model_get(GTK_TREE_MODEL(folderList), &childiter, COL_FOL_NAME_HIDDEN, &objectName, -1);
2341     return objectName;
2342 
2343 }
2344 
2345 // ************************************************************************************************
2346 
fileListClearSelection()2347 gboolean fileListClearSelection() {
2348     if (fileSelection != NULL)
2349         gtk_tree_selection_unselect_all(fileSelection);
2350     return TRUE;
2351 }
2352 
2353 // ************************************************************************************************
2354 
fileListSelectAll(void)2355 gboolean fileListSelectAll(void) {
2356     if (fileSelection != NULL)
2357         gtk_tree_selection_select_all(fileSelection);
2358     return TRUE;
2359 }
2360 
2361 // ************************************************************************************************
2362 
displayError(gchar * msg)2363 void displayError(gchar* msg) {
2364     GtkWidget *dialog;
2365     dialog = gtk_message_dialog_new(GTK_WINDOW(windowMain),
2366             GTK_DIALOG_DESTROY_WITH_PARENT,
2367             GTK_MESSAGE_ERROR,
2368             GTK_BUTTONS_OK,
2369             "%s",
2370             msg);
2371     gtk_window_set_title(GTK_WINDOW(dialog), _("Error"));
2372     gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE);
2373     gtk_dialog_run(GTK_DIALOG(dialog));
2374     gtk_widget_destroy(dialog);
2375 }
2376 
2377 // ************************************************************************************************
2378 
displayInformation(gchar * msg)2379 void displayInformation(gchar* msg) {
2380     GtkWidget *dialog;
2381     dialog = gtk_message_dialog_new(GTK_WINDOW(windowMain),
2382             GTK_DIALOG_DESTROY_WITH_PARENT,
2383             GTK_MESSAGE_INFO,
2384             GTK_BUTTONS_OK,
2385             "%s",
2386             msg);
2387     gtk_window_set_title(GTK_WINDOW(dialog), _("Information"));
2388     gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE);
2389     gtk_dialog_run(GTK_DIALOG(dialog));
2390     gtk_widget_destroy(dialog);
2391 }
2392 
2393 // ************************************************************************************************
2394 
displayFolderNewDialog(void)2395 gchar* displayFolderNewDialog(void) {
2396     GtkWidget *dialog, *hbox, *label, *textbox;
2397 
2398     dialog = gtk_dialog_new_with_buttons(_("New Folder"), GTK_WINDOW(windowMain),
2399             (GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT),
2400             _("_OK"), GTK_RESPONSE_OK,
2401             _("_Cancel"), GTK_RESPONSE_CANCEL,
2402             NULL);
2403 
2404     gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK);
2405     gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE);
2406     gtk_container_set_border_width(GTK_CONTAINER(dialog), 5);
2407 #if HAVE_GTK3 == 0
2408     hbox = gtk_hbox_new(FALSE, 5);
2409 #else
2410     hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
2411 #endif
2412     gtk_widget_show(hbox);
2413 
2414 #if HAVE_GTK3 == 0
2415     gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox);
2416 #else
2417     gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), hbox);
2418 #endif
2419 
2420     label = gtk_label_new(_("Folder Name:"));
2421     gtk_widget_show(label);
2422     gtk_container_add(GTK_CONTAINER(hbox), label);
2423 
2424     textbox = gtk_entry_new();
2425     gtk_widget_show(textbox);
2426     gtk_entry_set_max_length(GTK_ENTRY(textbox), 64);
2427     gtk_entry_set_has_frame(GTK_ENTRY(textbox), TRUE);
2428     gtk_entry_set_activates_default(GTK_ENTRY(textbox), TRUE);
2429     gtk_container_add(GTK_CONTAINER(hbox), textbox);
2430 
2431     gint result = gtk_dialog_run(GTK_DIALOG(dialog));
2432     if (result == GTK_RESPONSE_OK) {
2433         gchar* textfield = g_strdup(gtk_entry_get_text(GTK_ENTRY(textbox)));
2434         if (strlen(textfield) == 0) {
2435             // We have an emtpy string.
2436             gtk_widget_destroy(dialog);
2437             return NULL;
2438         } else {
2439             gtk_widget_destroy(dialog);
2440             return textfield;
2441         }
2442     } else {
2443         gtk_widget_destroy(dialog);
2444         return NULL;
2445     }
2446 }
2447 
2448 // ************************************************************************************************
2449 
displayChangeDeviceNameDialog(gchar * devicename)2450 gchar* displayChangeDeviceNameDialog(gchar* devicename) {
2451     GtkWidget *dialog, *hbox, *label, *textbox;
2452 
2453     dialog = gtk_dialog_new_with_buttons(_("Change Device Name"), GTK_WINDOW(windowMain),
2454             (GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT),
2455             _("_OK"), GTK_RESPONSE_OK,
2456             _("_Cancel"), GTK_RESPONSE_CANCEL,
2457             NULL);
2458 
2459     gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK);
2460     gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE);
2461     gtk_container_set_border_width(GTK_CONTAINER(dialog), 5);
2462 #if HAVE_GTK3 == 0
2463     hbox = gtk_hbox_new(FALSE, 5);
2464 #else
2465     hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
2466 #endif
2467     gtk_widget_show(hbox);
2468     gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
2469 #if HAVE_GTK3 == 0
2470     gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox);
2471 #else
2472     gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), hbox);
2473 #endif
2474 
2475     label = gtk_label_new(_("Device Name:"));
2476     gtk_widget_show(label);
2477     gtk_container_add(GTK_CONTAINER(hbox), label);
2478 
2479     textbox = gtk_entry_new();
2480     gtk_widget_show(textbox);
2481     if (devicename != NULL) {
2482         gtk_entry_set_text(GTK_ENTRY(textbox), devicename);
2483     }
2484     gtk_entry_set_max_length(GTK_ENTRY(textbox), 64);
2485     gtk_entry_set_has_frame(GTK_ENTRY(textbox), TRUE);
2486     gtk_entry_set_activates_default(GTK_ENTRY(textbox), TRUE);
2487     gtk_container_add(GTK_CONTAINER(hbox), textbox);
2488 
2489     gint result = gtk_dialog_run(GTK_DIALOG(dialog));
2490     if (result == GTK_RESPONSE_OK) {
2491         gchar* textfield = g_strdup(gtk_entry_get_text(GTK_ENTRY(textbox)));
2492         if (strlen(textfield) == 0) {
2493             // We have an emtpy string.
2494             gtk_widget_destroy(dialog);
2495             return NULL;
2496         } else {
2497             gtk_widget_destroy(dialog);
2498             return textfield;
2499         }
2500     } else {
2501         gtk_widget_destroy(dialog);
2502         return NULL;
2503     }
2504 }
2505 
2506 // ************************************************************************************************
2507 
displayRenameFileDialog(gchar * currentfilename)2508 gchar* displayRenameFileDialog(gchar* currentfilename) {
2509     GtkWidget *dialog, *hbox, *label, *textbox;
2510 
2511     dialog = gtk_dialog_new_with_buttons(_("Rename File/Folder"), GTK_WINDOW(windowMain),
2512             (GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT),
2513             _("_OK"), GTK_RESPONSE_OK,
2514             _("_Cancel"), GTK_RESPONSE_CANCEL,
2515             NULL);
2516 
2517     gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK);
2518     gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE);
2519     gtk_container_set_border_width(GTK_CONTAINER(dialog), 5);
2520 #if HAVE_GTK3 == 0
2521     hbox = gtk_hbox_new(FALSE, 5);
2522 #else
2523     hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
2524 #endif
2525     gtk_widget_show(hbox);
2526 
2527 #if HAVE_GTK3 == 0
2528     gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox);
2529 #else
2530     gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), hbox);
2531 #endif
2532 
2533     label = gtk_label_new(_("File Name:"));
2534     gtk_widget_show(label);
2535     gtk_container_add(GTK_CONTAINER(hbox), label);
2536 
2537     textbox = gtk_entry_new();
2538     gtk_widget_show(textbox);
2539     if (currentfilename != NULL) {
2540         gtk_entry_set_text(GTK_ENTRY(textbox), currentfilename);
2541     }
2542     gtk_entry_set_max_length(GTK_ENTRY(textbox), 64);
2543     gtk_entry_set_has_frame(GTK_ENTRY(textbox), TRUE);
2544     gtk_entry_set_activates_default(GTK_ENTRY(textbox), TRUE);
2545     gtk_container_add(GTK_CONTAINER(hbox), textbox);
2546 
2547     gint result = gtk_dialog_run(GTK_DIALOG(dialog));
2548     if (result == GTK_RESPONSE_OK) {
2549         gchar* textfield = g_strdup(gtk_entry_get_text(GTK_ENTRY(textbox)));
2550         if (strlen(textfield) == 0) {
2551             // We have an emtpy string.
2552             gtk_widget_destroy(dialog);
2553             return NULL;
2554         } else {
2555             gtk_widget_destroy(dialog);
2556             return textfield;
2557         }
2558     } else {
2559         gtk_widget_destroy(dialog);
2560         return NULL;
2561     }
2562 }
2563 
2564 // ************************************************************************************************
2565 
displayMultiDeviceDialog(void)2566 gint displayMultiDeviceDialog(void) {
2567     GtkWidget *dialog, *hbox, *label, *textbox;
2568     gchar *tmp_string = NULL;
2569     gint dialog_selection = -1;
2570 
2571     dialog = gtk_dialog_new_with_buttons(_("Connect to which device?"), GTK_WINDOW(windowMain),
2572             (GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT),
2573             _("_OK"), GTK_RESPONSE_OK,
2574             NULL);
2575 
2576     gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK);
2577     gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE);
2578     gtk_container_set_border_width(GTK_CONTAINER(dialog), 5);
2579 #if HAVE_GTK3 == 0
2580     hbox = gtk_hbox_new(FALSE, 5);
2581 #else
2582     hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
2583 #endif
2584     gtk_widget_show(hbox);
2585     gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
2586 #if HAVE_GTK3 == 0
2587     gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox);
2588 #else
2589     gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), hbox);
2590 #endif
2591 
2592     label = gtk_label_new(_("Device:"));
2593     gtk_widget_show(label);
2594     gtk_container_add(GTK_CONTAINER(hbox), label);
2595 
2596     // Now create the combo box.
2597 #if HAVE_GTK3 == 0
2598     textbox = gtk_combo_box_new_text();
2599 #else
2600     textbox = gtk_combo_box_text_new();
2601 #endif
2602     gtk_widget_show(textbox);
2603     gtk_container_add(GTK_CONTAINER(hbox), textbox);
2604     // Now add in our selection strings.
2605     // We should just take straight strings here, but this is quicker/easier.
2606     gint i = 0;
2607     for (i = 0; i < DeviceMgr.numrawdevices; i++) {
2608         if (DeviceMgr.rawdevices[i].device_entry.vendor != NULL ||
2609                 DeviceMgr.rawdevices[i].device_entry.product != NULL) {
2610             tmp_string = g_strdup_printf("   %s %s : (%04x:%04x) @ bus %d, dev %d",
2611                     DeviceMgr.rawdevices[i].device_entry.vendor,
2612                     DeviceMgr.rawdevices[i].device_entry.product,
2613                     DeviceMgr.rawdevices[i].device_entry.vendor_id,
2614                     DeviceMgr.rawdevices[i].device_entry.product_id,
2615                     DeviceMgr.rawdevices[i].bus_location,
2616                     DeviceMgr.rawdevices[i].devnum);
2617         } else {
2618             tmp_string = g_strdup_printf(_("Unknown : %04x:%04x @ bus %d, dev %d"),
2619                     DeviceMgr.rawdevices[i].device_entry.vendor_id,
2620                     DeviceMgr.rawdevices[i].device_entry.product_id,
2621                     DeviceMgr.rawdevices[i].bus_location,
2622                     DeviceMgr.rawdevices[i].devnum);
2623         }
2624 #if HAVE_GTK3 == 0
2625         gtk_combo_box_append_text(GTK_COMBO_BOX(textbox), tmp_string);
2626 #else
2627         gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(textbox), tmp_string);
2628 #endif
2629     }
2630     gtk_combo_box_set_active(GTK_COMBO_BOX(textbox), 0);
2631 
2632     gint result = gtk_dialog_run(GTK_DIALOG(dialog));
2633     if (result == GTK_RESPONSE_OK) {
2634         dialog_selection = gtk_combo_box_get_active(GTK_COMBO_BOX(textbox));
2635     }
2636     gtk_widget_destroy(dialog);
2637     g_free(tmp_string);
2638     return dialog_selection;
2639 }
2640 
2641 // ************************************************************************************************
2642 
displayDeviceStorageDialog(void)2643 gint displayDeviceStorageDialog(void) {
2644     GtkWidget *dialog, *hbox, *label, *textbox;
2645     LIBMTP_devicestorage_t *devicestorage;
2646     gchar *tmp_string = NULL;
2647     gint dialog_selection = -1;
2648 
2649     devicestorage = DeviceMgr.device->storage;
2650 
2651     dialog = gtk_dialog_new_with_buttons(_("Connect to which storage device?"), GTK_WINDOW(windowMain),
2652             (GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT),
2653             _("_OK"), GTK_RESPONSE_OK,
2654             NULL);
2655 
2656     gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK);
2657     gtk_window_set_default_size(GTK_WINDOW(dialog), 400, -1);
2658     gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE);
2659     gtk_container_set_border_width(GTK_CONTAINER(dialog), 5);
2660 #if HAVE_GTK3 == 0
2661     hbox = gtk_hbox_new(FALSE, 5);
2662 #else
2663     hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
2664 #endif
2665     gtk_widget_show(hbox);
2666     gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
2667 #if HAVE_GTK3 == 0
2668     gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox);
2669 #else
2670     gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), hbox);
2671 #endif
2672 
2673     label = gtk_label_new(_("Storage Device:"));
2674     gtk_widget_show(label);
2675     gtk_container_add(GTK_CONTAINER(hbox), label);
2676 
2677     // Now create the combo box.
2678 #if HAVE_GTK3 == 0
2679     textbox = gtk_combo_box_new_text();
2680 #else
2681     textbox = gtk_combo_box_text_new();
2682 #endif
2683     gtk_widget_show(textbox);
2684     gtk_container_add(GTK_CONTAINER(hbox), textbox);
2685     // Now add in our selection strings.
2686     while (devicestorage != NULL) {
2687         if (devicestorage->StorageDescription != NULL) {
2688 #if HAVE_GTK3 == 0
2689             gtk_combo_box_append_text(GTK_COMBO_BOX(textbox), devicestorage->StorageDescription);
2690 #else
2691             gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(textbox), devicestorage->StorageDescription);
2692 #endif
2693         } else {
2694             tmp_string = g_strdup_printf(_("Unknown id: %d, %s"), devicestorage->id, calculateFriendlySize((devicestorage->MaxCapacity)));
2695 #if HAVE_GTK3 == 0
2696             gtk_combo_box_append_text(GTK_COMBO_BOX(textbox), tmp_string);
2697 #else
2698             gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(textbox), tmp_string);
2699 #endif
2700         }
2701         devicestorage = devicestorage->next;
2702     }
2703 
2704     gtk_combo_box_set_active(GTK_COMBO_BOX(textbox), 0);
2705 
2706     gint result = gtk_dialog_run(GTK_DIALOG(dialog));
2707     if (result == GTK_RESPONSE_OK) {
2708         dialog_selection = gtk_combo_box_get_active(GTK_COMBO_BOX(textbox));
2709     }
2710     gtk_widget_destroy(dialog);
2711     g_free(tmp_string);
2712     return dialog_selection;
2713 
2714 }
2715 
2716 // ************************************************************************************************
2717 
displayFileOverwriteDialog(gchar * filename)2718 gint displayFileOverwriteDialog(gchar *filename) {
2719     GtkWidget *dialog;
2720     dialog = gtk_message_dialog_new_with_markup(GTK_WINDOW(windowMain),
2721             (GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT),
2722             GTK_MESSAGE_WARNING,
2723             GTK_BUTTONS_NONE,
2724             _("File <b>%s</b> already exists in target folder.\nDo you want to:"), filename);
2725     gtk_dialog_add_buttons(GTK_DIALOG(dialog),
2726             _("Skip"), MTP_SKIP,
2727             _("Skip All"), MTP_SKIP_ALL,
2728             _("Overwrite"), MTP_OVERWRITE,
2729             _("Overwrite All"), MTP_OVERWRITE_ALL,
2730             NULL);
2731     gtk_window_set_title(GTK_WINDOW(dialog), _("Question: Confirm Overwrite of Existing File?"));
2732     gtk_dialog_set_default_response(GTK_DIALOG(dialog), MTP_OVERWRITE);
2733     gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE);
2734     gint result = gtk_dialog_run(GTK_DIALOG(dialog));
2735     gtk_widget_destroy(dialog);
2736     return result;
2737 }
2738 
2739 // ************************************************************************************************
2740 
create_windowMainContextMenu(void)2741 GtkWidget* create_windowMainContextMenu(void) {
2742     GtkWidget* menu;
2743     //GtkWidget* cfileAdd;
2744     GtkWidget* cfileRename;
2745     GtkWidget* cfileRemove;
2746     GtkWidget* cfileDownload;
2747     GtkWidget* cfileMove;
2748     //GtkWidget* cfileNewFolder;
2749     GtkWidget* cfileRemoveFolder;
2750     GtkWidget* cfileRescan;
2751     GtkWidget* cfileAddToPlaylist;
2752     GtkWidget* cfileRemoveFromPlaylist;
2753     GtkWidget* menuseparator1;
2754     GtkWidget* menuseparator2;
2755     GtkWidget* menuseparator3;
2756 
2757     menu = gtk_menu_new();
2758 
2759     cfileAdd = gtk_menu_item_new_with_label(_("Add Files"));
2760     gtk_widget_show(cfileAdd);
2761     gtk_container_add(GTK_CONTAINER(menu), cfileAdd);
2762 
2763     cfileRemove = gtk_menu_item_new_with_label(_("Delete Files"));
2764     gtk_widget_show(cfileRemove);
2765     gtk_container_add(GTK_CONTAINER(menu), cfileRemove);
2766 
2767     cfileDownload = gtk_menu_item_new_with_label(_("Download Files"));
2768     gtk_widget_show(cfileDownload);
2769     gtk_container_add(GTK_CONTAINER(menu), cfileDownload);
2770 
2771     cfileRename = gtk_menu_item_new_with_label(_("Rename File"));
2772     gtk_widget_show(cfileRename);
2773     gtk_container_add(GTK_CONTAINER(menu), cfileRename);
2774 
2775     cfileMove = gtk_menu_item_new_with_label(_("Move To..."));
2776     gtk_widget_show(cfileMove);
2777     gtk_container_add(GTK_CONTAINER(menu), cfileMove);
2778 
2779     menuseparator3 = gtk_separator_menu_item_new();
2780     gtk_widget_show(menuseparator3);
2781     gtk_container_add(GTK_CONTAINER(menu), menuseparator3);
2782 
2783     cfileAddToPlaylist = gtk_menu_item_new_with_label(_("Add To Playlist"));
2784     gtk_widget_show(cfileAddToPlaylist);
2785     gtk_container_add(GTK_CONTAINER(menu), cfileAddToPlaylist);
2786 
2787     cfileRemoveFromPlaylist = gtk_menu_item_new_with_label(_("Remove From Playlist"));
2788     gtk_widget_show(cfileRemoveFromPlaylist);
2789     gtk_container_add(GTK_CONTAINER(menu), cfileRemoveFromPlaylist);
2790 
2791     menuseparator1 = gtk_separator_menu_item_new();
2792     gtk_widget_show(menuseparator1);
2793     gtk_container_add(GTK_CONTAINER(menu), menuseparator1);
2794 
2795     cfileNewFolder = gtk_menu_item_new_with_label(_("Create Folder"));
2796     gtk_widget_show(cfileNewFolder);
2797     gtk_container_add(GTK_CONTAINER(menu), cfileNewFolder);
2798 
2799     cfileRemoveFolder = gtk_menu_item_new_with_label(_("Delete Folder"));
2800     gtk_widget_show(cfileRemoveFolder);
2801     gtk_container_add(GTK_CONTAINER(menu), cfileRemoveFolder);
2802 
2803     menuseparator2 = gtk_separator_menu_item_new();
2804     gtk_widget_show(menuseparator2);
2805     gtk_container_add(GTK_CONTAINER(menu), menuseparator2);
2806 
2807     cfileRescan = gtk_menu_item_new_with_label(_("Refresh Device"));
2808     gtk_widget_show(cfileRescan);
2809     gtk_container_add(GTK_CONTAINER(menu), cfileRescan);
2810 
2811     // Now our call backs.
2812     g_signal_connect((gpointer) cfileAdd, "activate",
2813             G_CALLBACK(on_filesAdd_activate),
2814             NULL);
2815 
2816     g_signal_connect((gpointer) cfileDownload, "activate",
2817             G_CALLBACK(on_filesDownload_activate),
2818             NULL);
2819 
2820     g_signal_connect((gpointer) cfileRename, "activate",
2821             G_CALLBACK(on_fileRenameFile_activate),
2822             NULL);
2823 
2824     g_signal_connect((gpointer) cfileMove, "activate",
2825             G_CALLBACK(on_fileMoveFile_activate),
2826             NULL);
2827 
2828     g_signal_connect((gpointer) cfileRemove, "activate",
2829             G_CALLBACK(on_filesDelete_activate),
2830             NULL);
2831 
2832     g_signal_connect((gpointer) cfileNewFolder, "activate",
2833             G_CALLBACK(on_fileNewFolder_activate),
2834             NULL);
2835 
2836     g_signal_connect((gpointer) cfileRemoveFolder, "activate",
2837             G_CALLBACK(on_fileRemoveFolder_activate),
2838             NULL);
2839 
2840     g_signal_connect((gpointer) cfileRescan, "activate",
2841             G_CALLBACK(on_deviceRescan_activate),
2842             NULL);
2843 
2844     g_signal_connect((gpointer) cfileAddToPlaylist, "activate",
2845             G_CALLBACK(on_fileAddToPlaylist_activate),
2846             NULL);
2847 
2848     g_signal_connect((gpointer) cfileRemoveFromPlaylist, "activate",
2849             G_CALLBACK(on_fileRemoveFromPlaylist_activate),
2850             NULL);
2851 
2852     return menu;
2853 
2854 }
2855 
2856 // ************************************************************************************************
2857 
create_windowMainColumnContextMenu(void)2858 GtkWidget* create_windowMainColumnContextMenu(void) {
2859     GtkWidget* menu;
2860     menu = gtk_menu_new();
2861 
2862     cViewSize = gtk_check_menu_item_new_with_label(_("File Size"));
2863     gtk_widget_show(cViewSize);
2864     gtk_container_add(GTK_CONTAINER(menu), cViewSize);
2865 
2866     cViewType = gtk_check_menu_item_new_with_label(_("File Type"));
2867     gtk_widget_show(cViewType);
2868     gtk_container_add(GTK_CONTAINER(menu), cViewType);
2869 
2870     cViewTrackNumber = gtk_check_menu_item_new_with_label(_("Track Number"));
2871     gtk_widget_show(cViewTrackNumber);
2872     gtk_container_add(GTK_CONTAINER(menu), cViewTrackNumber);
2873 
2874     cViewTrackName = gtk_check_menu_item_new_with_label(_("Track Name"));
2875     gtk_widget_show(cViewTrackName);
2876     gtk_container_add(GTK_CONTAINER(menu), cViewTrackName);
2877 
2878     cViewArtist = gtk_check_menu_item_new_with_label(_("Artist"));
2879     gtk_widget_show(cViewArtist);
2880     gtk_container_add(GTK_CONTAINER(menu), cViewArtist);
2881 
2882     cViewAlbum = gtk_check_menu_item_new_with_label(_("Album"));
2883     gtk_widget_show(cViewAlbum);
2884     gtk_container_add(GTK_CONTAINER(menu), cViewAlbum);
2885 
2886     cViewYear = gtk_check_menu_item_new_with_label(_("Year"));
2887     gtk_widget_show(cViewYear);
2888     gtk_container_add(GTK_CONTAINER(menu), cViewYear);
2889 
2890     cViewGenre = gtk_check_menu_item_new_with_label(_("Genre"));
2891     gtk_widget_show(cViewGenre);
2892     gtk_container_add(GTK_CONTAINER(menu), cViewGenre);
2893 
2894     cViewDuration = gtk_check_menu_item_new_with_label(_("Duration"));
2895     gtk_widget_show(cViewDuration);
2896     gtk_container_add(GTK_CONTAINER(menu), cViewDuration);
2897 
2898 
2899     // Now our call backs.
2900     g_signal_connect((gpointer) cViewSize, "toggled",
2901             G_CALLBACK(on_view_activate),
2902             NULL);
2903 
2904     g_signal_connect((gpointer) cViewTrackNumber, "toggled",
2905             G_CALLBACK(on_view_activate),
2906             NULL);
2907 
2908     g_signal_connect((gpointer) cViewTrackName, "toggled",
2909             G_CALLBACK(on_view_activate),
2910             NULL);
2911 
2912     g_signal_connect((gpointer) cViewType, "toggled",
2913             G_CALLBACK(on_view_activate),
2914             NULL);
2915 
2916     g_signal_connect((gpointer) cViewArtist, "toggled",
2917             G_CALLBACK(on_view_activate),
2918             NULL);
2919 
2920     g_signal_connect((gpointer) cViewAlbum, "toggled",
2921             G_CALLBACK(on_view_activate),
2922             NULL);
2923 
2924     g_signal_connect((gpointer) cViewYear, "toggled",
2925             G_CALLBACK(on_view_activate),
2926             NULL);
2927 
2928     g_signal_connect((gpointer) cViewGenre, "toggled",
2929             G_CALLBACK(on_view_activate),
2930             NULL);
2931 
2932     g_signal_connect((gpointer) cViewDuration, "toggled",
2933             G_CALLBACK(on_view_activate),
2934             NULL);
2935 
2936     return menu;
2937 }
2938 
2939 // ************************************************************************************************
2940 
2941 /**
2942  * Create the Context Menu widget.
2943  * @return
2944  */
create_windowFolderContextMenu(void)2945 GtkWidget* create_windowFolderContextMenu(void) {
2946     GtkWidget* menu;
2947     GtkWidget* menuseparator1;
2948     menu = gtk_menu_new();
2949 
2950     cfFolderAdd = gtk_menu_item_new_with_label(_("Create Folder"));
2951     gtk_widget_show(cfFolderAdd);
2952     gtk_container_add(GTK_CONTAINER(menu), cfFolderAdd);
2953 
2954     cfFolderRename = gtk_menu_item_new_with_label(_("Rename Folder"));
2955     gtk_widget_show(cfFolderRename);
2956     gtk_container_add(GTK_CONTAINER(menu), cfFolderRename);
2957 
2958     cfFolderDelete = gtk_menu_item_new_with_label(_("Delete Folder"));
2959     gtk_widget_show(cfFolderDelete);
2960     gtk_container_add(GTK_CONTAINER(menu), cfFolderDelete);
2961 
2962     cfFolderMove = gtk_menu_item_new_with_label(_("Move To..."));
2963     gtk_widget_show(cfFolderMove);
2964     gtk_container_add(GTK_CONTAINER(menu), cfFolderMove);
2965 
2966     menuseparator1 = gtk_separator_menu_item_new();
2967     gtk_widget_show(menuseparator1);
2968     gtk_container_add(GTK_CONTAINER(menu), menuseparator1);
2969 
2970     cfFolderRefresh = gtk_menu_item_new_with_label(_("Refresh Device"));
2971     gtk_widget_show(cfFolderRefresh);
2972     gtk_container_add(GTK_CONTAINER(menu), cfFolderRefresh);
2973 
2974 
2975     // Now our call backs.
2976     g_signal_connect((gpointer) cfFolderRefresh, "activate",
2977             G_CALLBACK(on_deviceRescan_activate),
2978             NULL);
2979 
2980     g_signal_connect((gpointer) cfFolderRename, "activate",
2981             G_CALLBACK(on_folderRenameFolder_activate),
2982             NULL);
2983 
2984     g_signal_connect((gpointer) cfFolderDelete, "activate",
2985             G_CALLBACK(on_folderRemoveFolder_activate),
2986             NULL);
2987 
2988     g_signal_connect((gpointer) cfFolderMove, "activate",
2989             G_CALLBACK(on_folderMoveFolder_activate),
2990             NULL);
2991 
2992     g_signal_connect((gpointer) cfFolderAdd, "activate",
2993             G_CALLBACK(on_folderNewFolder_activate),
2994             NULL);
2995 
2996     return menu;
2997 }
2998 
2999 // ************************************************************************************************
3000 
displayAddTrackPlaylistDialog(gboolean showNew)3001 int32_t displayAddTrackPlaylistDialog(gboolean showNew /* = TRUE */) {
3002     GtkWidget *dialog, *hbox, *label, *buttonNewPlaylist;
3003     LIBMTP_playlist_t* tmpplaylist = NULL;
3004     gint selectedPlaylist = 0;
3005 
3006 #if HAVE_GTK3 == 0
3007     GtkTooltips *tooltips;
3008     tooltips = gtk_tooltips_new();
3009 #endif
3010 
3011     dialog = gtk_dialog_new_with_buttons(_("Playlists"), GTK_WINDOW(windowMain),
3012             (GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT),
3013             _("_OK"), GTK_RESPONSE_OK,
3014             _("_Cancel"), GTK_RESPONSE_CANCEL,
3015             NULL);
3016 
3017     gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK);
3018     gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE);
3019     gtk_container_set_border_width(GTK_CONTAINER(dialog), 5);
3020 #if HAVE_GTK3 == 0
3021     hbox = gtk_hbox_new(FALSE, 5);
3022 #else
3023     hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
3024 #endif
3025 
3026     gtk_widget_show(hbox);
3027 
3028 #if HAVE_GTK3 == 0
3029     gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox);
3030 #else
3031     gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), hbox);
3032 #endif
3033 
3034     // Add in the label
3035     label = gtk_label_new(_("Playlist Name:"));
3036     gtk_widget_show(label);
3037     gtk_container_add(GTK_CONTAINER(hbox), label);
3038 #if HAVE_GTK3 == 0
3039     gtk_misc_set_padding(GTK_MISC(label), 5, 0);
3040 #else
3041 #if GTK_CHECK_VERSION(3,12,0)
3042     gtk_widget_set_margin_start(label, 5);
3043     gtk_widget_set_margin_end(label, 5);
3044 #else
3045     gtk_widget_set_margin_left(label, 5);
3046     gtk_widget_set_margin_right(label, 5);
3047 #endif
3048 
3049 #endif
3050 
3051 
3052     // Add in the combobox
3053 #if HAVE_GTK3 == 0
3054     combobox_AddTrackPlaylist = gtk_combo_box_new_text();
3055 #else
3056     combobox_AddTrackPlaylist = gtk_combo_box_text_new();
3057 #endif
3058     gtk_widget_show(combobox_AddTrackPlaylist);
3059     gtk_box_pack_start(GTK_BOX(hbox), combobox_AddTrackPlaylist, TRUE, TRUE, 0);
3060     gtk_container_set_border_width(GTK_CONTAINER(combobox_AddTrackPlaylist), 5);
3061 
3062     // Add in the new playlist button.
3063 #if HAVE_GTK3 == 0
3064     buttonNewPlaylist = gtk_button_new_from_stock(GTK_STOCK_ADD);
3065 #else
3066     buttonNewPlaylist = gtk_button_new_with_label(_("Add"));
3067 #endif
3068     if (showNew == TRUE) {
3069         gtk_widget_show(buttonNewPlaylist);
3070         gtk_container_add(GTK_CONTAINER(hbox), buttonNewPlaylist);
3071         gtk_container_set_border_width(GTK_CONTAINER(buttonNewPlaylist), 5);
3072     }
3073 
3074 #if HAVE_GTK3 == 0
3075     gtk_tooltips_set_tip(tooltips, buttonNewPlaylist, _("Add New Playlist"), NULL);
3076 #else
3077     gtk_widget_set_tooltip_text(buttonNewPlaylist, _("Add New Playlist"));
3078 #endif
3079 
3080     // Assign the callback for the new playlist button.
3081     g_signal_connect((gpointer) buttonNewPlaylist, "clicked",
3082             G_CALLBACK(on_TrackPlaylist_NewPlaylistButton_activate),
3083             NULL);
3084 
3085     // Populate the combobox with the current playlists.
3086 
3087     // We need to remove all entries in the combo box before starting.
3088     // This is a little bit of a hack - but does work.
3089     gtk_list_store_clear(GTK_LIST_STORE(gtk_combo_box_get_model(GTK_COMBO_BOX(combobox_AddTrackPlaylist))));
3090 
3091     if (devicePlayLists != NULL) {
3092         // Populate the playlist dropdown box;
3093         //comboboxentry_playlist;
3094         tmpplaylist = devicePlayLists;
3095         while (tmpplaylist != NULL) {
3096             if (tmpplaylist->storage_id == DeviceMgr.devicestorage->id) {
3097 #if HAVE_GTK3 == 0
3098                 gtk_combo_box_append_text(GTK_COMBO_BOX(combobox_AddTrackPlaylist), (tmpplaylist->name));
3099 #else
3100                 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combobox_AddTrackPlaylist), (tmpplaylist->name));
3101 #endif
3102             }
3103             tmpplaylist = tmpplaylist->next;
3104         }
3105     }
3106     if (devicePlayLists != NULL) {
3107         // Set our playlist to the first one.
3108         gtk_combo_box_set_active(GTK_COMBO_BOX(combobox_AddTrackPlaylist), 0);
3109     }
3110 
3111     gint result = gtk_dialog_run(GTK_DIALOG(dialog));
3112     if (result == GTK_RESPONSE_OK) {
3113         // Get our playlist ID.
3114         selectedPlaylist = gtk_combo_box_get_active(GTK_COMBO_BOX(combobox_AddTrackPlaylist));
3115         // Now cycle through the playlists to get the correct one.
3116         tmpplaylist = devicePlayLists;
3117 
3118         if (selectedPlaylist > 0) {
3119             while (selectedPlaylist--)
3120                 if (tmpplaylist->next != NULL)
3121                     tmpplaylist = tmpplaylist->next;
3122         }
3123         gtk_widget_destroy(dialog);
3124         return tmpplaylist->playlist_id;
3125     } else {
3126         gtk_widget_destroy(dialog);
3127         return GMTP_NO_PLAYLIST;
3128     }
3129 }
3130 
3131 // ************************************************************************************************
3132 
setWindowTitle(gchar * foldername)3133 void setWindowTitle(gchar *foldername) {
3134     gchar *winTitle;
3135 
3136     if (foldername == NULL) {
3137         winTitle = g_strconcat(PACKAGE_NAME, NULL);
3138     } else {
3139         winTitle = g_strconcat(foldername, " - ", PACKAGE_NAME, NULL);
3140     }
3141     gtk_window_set_title(GTK_WINDOW(windowMain), (winTitle));
3142     g_free(winTitle);
3143 }
3144 
3145 // ************************************************************************************************
3146 
g_free_search(FileListStruc * file)3147 void g_free_search(FileListStruc *file) {
3148     if (file != NULL) {
3149         if (file->filename != NULL) {
3150             g_free(file->filename);
3151         }
3152         if (file->location != NULL) {
3153             g_free(file->location);
3154         }
3155     }
3156     g_free(file);
3157 }
3158 
3159 // ************************************************************************************************
3160 
fileListAddToPlaylist(GList * List,uint32_t PlaylistID)3161 gboolean fileListAddToPlaylist(GList *List, uint32_t PlaylistID) {
3162     LIBMTP_playlist_t *playlist = NULL;
3163     LIBMTP_playlist_t *node = NULL;
3164 
3165     node = devicePlayLists;
3166     while (node != NULL) {
3167         if (node->playlist_id == PlaylistID) {
3168             playlist = node;
3169             node = NULL;
3170         } else {
3171             node = node->next;
3172         }
3173     }
3174     if (playlist != NULL) {
3175         g_list_foreach(List, (GFunc) __fileAddToPlaylist, (gpointer) & playlist);
3176     }
3177     return TRUE;
3178 }
3179 
3180 // ************************************************************************************************
3181 
getTargetFolderLocation(void)3182 int64_t getTargetFolderLocation(void) {
3183     GtkWidget *dialog;
3184     GtkWidget *treeviewFoldersDialog;
3185     GtkTreeStore *folderListDialog;
3186     GtkTreeSelection *folderSelectionDialog;
3187     GtkWidget *scrolledwindowFoldersDialog;
3188     GtkTreeModel *folderListModelDialog;
3189 
3190     GtkTreeModel *sortmodel;
3191     GtkTreeIter iter;
3192     GtkTreeIter childiter;
3193     uint32_t objectID = 0;
3194 
3195     dialog = gtk_dialog_new_with_buttons(_("Move To..."), GTK_WINDOW(windowMain),
3196             (GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT),
3197             _("_OK"), GTK_RESPONSE_OK,
3198             _("_Cancel"), GTK_RESPONSE_CANCEL,
3199             NULL);
3200 
3201     gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK);
3202     gtk_window_set_resizable(GTK_WINDOW(dialog), TRUE);
3203     gtk_window_set_default_size(GTK_WINDOW(dialog), 240, 400);
3204     gtk_container_set_border_width(GTK_CONTAINER(dialog), 5);
3205 
3206     // Actual folder list.
3207     scrolledwindowFoldersDialog = gtk_scrolled_window_new(NULL, NULL);
3208     gtk_widget_show(scrolledwindowFoldersDialog);
3209 #if HAVE_GTK3 == 0
3210     gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), scrolledwindowFoldersDialog);
3211 #else
3212     gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), scrolledwindowFoldersDialog);
3213     gtk_widget_set_vexpand(scrolledwindowFoldersDialog, TRUE);
3214 #endif
3215 
3216     gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwindowFoldersDialog), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
3217 
3218     treeviewFoldersDialog = gtk_tree_view_new();
3219     gtk_widget_show(treeviewFoldersDialog);
3220     gtk_container_add(GTK_CONTAINER(scrolledwindowFoldersDialog), treeviewFoldersDialog);
3221     gtk_container_set_border_width(GTK_CONTAINER(treeviewFoldersDialog), 5);
3222     folderSelectionDialog = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeviewFoldersDialog));
3223     gtk_tree_selection_set_mode(folderSelectionDialog, GTK_SELECTION_SINGLE);
3224 
3225     folderListDialog = gtk_tree_store_new(NUM_FOL_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_UINT, GDK_TYPE_PIXBUF);
3226     setupFolderList(GTK_TREE_VIEW(treeviewFoldersDialog));
3227 
3228     folderListModelDialog = gtk_tree_model_sort_new_with_model(GTK_TREE_MODEL(folderListDialog));
3229     gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(folderListModelDialog),
3230             COL_FOL_NAME_HIDDEN, GTK_SORT_ASCENDING);
3231 
3232     gtk_tree_view_set_model(GTK_TREE_VIEW(treeviewFoldersDialog), GTK_TREE_MODEL(folderListModelDialog));
3233 
3234     folderListAddDialog(deviceFolders, NULL, folderListDialog);
3235 
3236     gtk_tree_view_expand_all(GTK_TREE_VIEW(treeviewFoldersDialog));
3237     g_object_unref(folderListDialog);
3238 
3239     gint result = gtk_dialog_run(GTK_DIALOG(dialog));
3240     if (result == GTK_RESPONSE_OK) {
3241 
3242         // Get our selected row.
3243         sortmodel = gtk_tree_view_get_model(GTK_TREE_VIEW(treeviewFoldersDialog));
3244 
3245         if (gtk_tree_selection_get_selected(folderSelectionDialog, &sortmodel, &iter)) {
3246             gtk_tree_model_sort_convert_iter_to_child_iter(GTK_TREE_MODEL_SORT(sortmodel), &childiter, &iter);
3247             gtk_tree_model_get(GTK_TREE_MODEL(folderListDialog), &childiter, COL_FOL_ID, &objectID, -1);
3248             gtk_widget_destroy(dialog);
3249             return objectID;
3250         }
3251     }
3252     gtk_widget_destroy(dialog);
3253     return -1;
3254 }
3255 
3256 // ************************************************************************************************
3257 
folderListAddDialog(LIBMTP_folder_t * folders,GtkTreeIter * parent,GtkTreeStore * fl)3258 gboolean folderListAddDialog(LIBMTP_folder_t *folders, GtkTreeIter *parent, GtkTreeStore *fl) {
3259     GtkTreeIter rowIter;
3260     GdkPixbuf *image = NULL;
3261 
3262     if (parent == NULL) {
3263         // Add in the root node.
3264         image = gdk_pixbuf_new_from_file(file_folder_png, NULL);
3265         // Now add in the row information.
3266         gtk_tree_store_append(GTK_TREE_STORE(fl), &rowIter, parent);
3267         gtk_tree_store_set(GTK_TREE_STORE(fl), &rowIter,
3268                 //COL_FOL_NAME, folders->name,
3269                 COL_FOL_NAME_HIDDEN, "/",
3270                 COL_FOL_ID, 0,
3271                 COL_FOL_ICON, image,
3272                 -1);
3273 
3274         // Indicate we are done with this image.
3275         g_object_unref(image);
3276         folderListAddDialog(folders, &rowIter, fl);
3277         return TRUE;
3278     }
3279 
3280     while (folders != NULL) {
3281 
3282         // Only add in folder if it's in the current storage device.
3283         if (folders->storage_id == DeviceMgr.devicestorage->id) {
3284 
3285             image = gdk_pixbuf_new_from_file(file_folder_png, NULL);
3286             // Now add in the row information.
3287             gtk_tree_store_append(GTK_TREE_STORE(fl), &rowIter, parent);
3288             gtk_tree_store_set(GTK_TREE_STORE(fl), &rowIter,
3289                     //COL_FOL_NAME, folders->name,
3290                     COL_FOL_NAME_HIDDEN, folders->name,
3291                     COL_FOL_ID, folders->folder_id,
3292                     COL_FOL_ICON, image,
3293                     -1);
3294 
3295             // Indicate we are done with this image.
3296             g_object_unref(image);
3297             if (folders->child != NULL) {
3298                 // Call our child.
3299                 folderListAddDialog(folders->child, &rowIter, fl);
3300             }
3301         }
3302         folders = folders->sibling;
3303     }
3304     return TRUE;
3305 }
3306 
3307 // ************************************************************************************************
3308 
calculateFriendlySize(const uint64_t value)3309 gchar *calculateFriendlySize(const uint64_t value) {
3310     if (value < KILOBYTE) {
3311         return g_strdup_printf("%lu B", (long unsigned) value);
3312     };
3313     if (value < MEGABYTE) {
3314         return g_strdup_printf("%.1f KB", value / 1024.00);
3315     }
3316     if (value < GIGABYTE) {
3317         return g_strdup_printf("%.1f MB", value / (1024.00 * 1024.00));
3318     };
3319     return g_strdup_printf("%.1f GB", value / (1024.00 * 1024.00 * 1024.00));
3320 }
3321