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