1 /*
2 * Copyright (c) 2012-2013 Andrzej Radecki <andrzejr@xfce.org>
3 * Copyright (c) 2017 Viktor Odintsev <ninetls@xfce.org>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19
20
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25 #ifdef HAVE_STRING_H
26 #include <string.h>
27 #endif
28
29 #include <libxfce4ui/libxfce4ui.h>
30 #include <libxfce4util/libxfce4util.h>
31 #include <libxfce4panel/libxfce4panel.h>
32
33 #include "sn-dialog.h"
34 #include "sn-dialog-ui.h"
35
36
37
38 #define DEFAULT_ICON_SIZE 22
39
40
41
42 static gboolean sn_dialog_build (SnDialog *dialog);
43
44 static void sn_dialog_finalize (GObject *object);
45
46
47
48 struct _SnDialogClass
49 {
50 GObjectClass __parent__;
51 };
52
53 struct _SnDialog
54 {
55 GObject __parent__;
56
57 GtkBuilder *builder;
58 GtkWidget *dialog;
59 GtkWidget *auto_size;
60 GtkWidget *size_spinbutton;
61 GtkWidget *size_revealer;
62 GObject *store;
63 GObject *legacy_store;
64 SnConfig *config;
65 };
66
67 G_DEFINE_TYPE (SnDialog, sn_dialog, G_TYPE_OBJECT)
68
69
70
71 enum
72 {
73 COLUMN_PIXBUF,
74 COLUMN_TITLE,
75 COLUMN_HIDDEN,
76 COLUMN_TIP
77 };
78
79
80
81 /* known applications to improve the icon and name */
82 static const gchar *known_applications[][3] =
83 {
84 /* application name, icon-name, understandable name */
85 { "blueman", "blueman", "Blueman Applet" },
86 { "nm-applet", "network-workgroup", "Network Manager Applet" },
87 { "Skype1", "skypeforlinux", "Skype" },
88 { "chrome_status_icon_1", "google-chrome", "Google Chrome" },
89 { "Telegram Desktop", "telegram", "Telegram Desktop" },
90 { "redshift", "redshift", "Redshift" },
91 { "vlc", "vlc", "VLC Player" },
92 { "zoom", "Zoom", "Zoom" },
93 };
94
95 static const gchar *known_legacy_applications[][3] =
96 {
97 /* application name, icon-name, understandable name */
98 { "audacious2", "audacious", "Audacious" },
99 { "drop-down terminal", "utilities-terminal", "Xfce Dropdown Terminal" },
100 { "networkmanager applet", "network-workgroup", "Network Manager Applet" },
101 { "parole", "parole", "Parole Media Player" },
102 { "task manager", "org.xfce.taskmanager", "Xfce Taskmanager" },
103 { "thunar", "Thunar", "Thunar Progress Dialog" },
104 { "wicd-client.py", "wicd-gtk", "Wicd" },
105 { "workrave tray icon", NULL, "Workrave Applet" },
106 { "workrave", NULL, "Workrave" },
107 { "xfce terminal", "utilities-terminal", "Xfce Terminal" },
108 { "xfce4-power-manager", "xfpm-ac-adapter", "Xfce Power Manager" },
109 { "redshift-gtk", "redshift", "Redshift" },
110 { "skypeforlinux", "skypeforlinux", "Skype" },
111 { "blueman-applet", "blueman", "Blueman Applet" },
112 { "system-config-printer", "printer", "Printing Service" },
113 { "network", "network-workgroup", "Network Manager Applet" },
114 };
115
116
117
118 static void
sn_dialog_class_init(SnDialogClass * klass)119 sn_dialog_class_init (SnDialogClass *klass)
120 {
121 GObjectClass *object_class;
122
123 object_class = G_OBJECT_CLASS (klass);
124 object_class->finalize = sn_dialog_finalize;
125 }
126
127
128
129 static void
sn_dialog_init(SnDialog * dialog)130 sn_dialog_init (SnDialog *dialog)
131 {
132 dialog->builder = NULL;
133 dialog->dialog = NULL;
134 dialog->store = NULL;
135 dialog->legacy_store = NULL;
136 dialog->config = NULL;
137 }
138
139
140
141 static void
sn_dialog_add_item(SnDialog * dialog,GdkPixbuf * pixbuf,const gchar * name,const gchar * title,gboolean hidden)142 sn_dialog_add_item (SnDialog *dialog,
143 GdkPixbuf *pixbuf,
144 const gchar *name,
145 const gchar *title,
146 gboolean hidden)
147 {
148 GtkTreeIter iter;
149
150 g_return_if_fail (XFCE_IS_SN_DIALOG (dialog));
151 g_return_if_fail (GTK_IS_LIST_STORE (dialog->store));
152 g_return_if_fail (name == NULL || g_utf8_validate (name, -1, NULL));
153
154 /* insert in the store */
155 gtk_list_store_append (GTK_LIST_STORE (dialog->store), &iter);
156 gtk_list_store_set (GTK_LIST_STORE (dialog->store), &iter,
157 COLUMN_PIXBUF, pixbuf,
158 COLUMN_TITLE, title,
159 COLUMN_HIDDEN, hidden,
160 COLUMN_TIP, name,
161 -1);
162 }
163
164
165
166 static void
sn_dialog_add_legacy_item(SnDialog * dialog,GdkPixbuf * pixbuf,const gchar * name,const gchar * title,gboolean hidden)167 sn_dialog_add_legacy_item(SnDialog *dialog,
168 GdkPixbuf *pixbuf,
169 const gchar *name,
170 const gchar *title,
171 gboolean hidden)
172 {
173 GtkTreeIter iter;
174
175 g_return_if_fail(XFCE_IS_SN_DIALOG(dialog));
176 g_return_if_fail(GTK_IS_LIST_STORE(dialog->legacy_store));
177 g_return_if_fail(name == NULL || g_utf8_validate(name, -1, NULL));
178
179 /* insert in the store */
180 gtk_list_store_append(GTK_LIST_STORE(dialog->legacy_store), &iter);
181 gtk_list_store_set(GTK_LIST_STORE(dialog->legacy_store), &iter,
182 COLUMN_PIXBUF, pixbuf,
183 COLUMN_TITLE, title,
184 COLUMN_HIDDEN, hidden,
185 COLUMN_TIP, name,
186 -1);
187 }
188
189
190
191 static void
sn_dialog_update_names(SnDialog * dialog)192 sn_dialog_update_names (SnDialog *dialog)
193 {
194 GList *li;
195 const gchar *name;
196 const gchar *title;
197 const gchar *icon_name;
198 GdkPixbuf *pixbuf;
199 guint i;
200
201 g_return_if_fail (XFCE_IS_SN_DIALOG (dialog));
202 g_return_if_fail (XFCE_IS_SN_CONFIG (dialog->config));
203 g_return_if_fail (GTK_IS_LIST_STORE (dialog->store));
204
205 for (li = sn_config_get_known_items (dialog->config); li != NULL; li = li->next)
206 {
207 name = li->data;
208 title = name;
209 icon_name = name;
210
211 /* check if we have a better name for the application */
212 for (i = 0; i < G_N_ELEMENTS (known_applications); i++)
213 {
214 if (strcmp (name, known_applications[i][0]) == 0)
215 {
216 icon_name = known_applications[i][1];
217 title = known_applications[i][2];
218 break;
219 }
220 }
221
222 pixbuf = xfce_panel_pixbuf_from_source (icon_name, NULL, 22);
223
224 /* insert item in the store */
225 sn_dialog_add_item (dialog, pixbuf, name, title,
226 sn_config_is_hidden (dialog->config, name));
227
228 if (pixbuf != NULL)
229 g_object_unref (G_OBJECT (pixbuf));
230 }
231 }
232
233
234
235 static void
sn_dialog_update_legacy_names(SnDialog * dialog)236 sn_dialog_update_legacy_names(SnDialog *dialog)
237 {
238 GList *li;
239 const gchar *name;
240 const gchar *title;
241 const gchar *icon_name;
242 GdkPixbuf *pixbuf;
243 guint i;
244
245 g_return_if_fail(XFCE_IS_SN_DIALOG(dialog));
246 g_return_if_fail(XFCE_IS_SN_CONFIG(dialog->config));
247 g_return_if_fail(GTK_IS_LIST_STORE(dialog->legacy_store));
248
249 for (li = sn_config_get_known_legacy_items(dialog->config); li != NULL; li = li->next)
250 {
251 name = li->data;
252 title = name;
253 icon_name = name;
254
255 /* check if we have a better name for the application */
256 for (i = 0; i < G_N_ELEMENTS(known_legacy_applications); i++)
257 {
258 if (strcmp(name, known_legacy_applications[i][0]) == 0)
259 {
260 icon_name = known_legacy_applications[i][1];
261 title = known_legacy_applications[i][2];
262 break;
263 }
264 }
265
266 pixbuf = xfce_panel_pixbuf_from_source(icon_name, NULL, 22);
267
268 /* insert item in the store */
269 sn_dialog_add_legacy_item(dialog, pixbuf, name, title,
270 sn_config_is_legacy_hidden(dialog->config, name));
271
272 if (pixbuf != NULL)
273 g_object_unref(G_OBJECT(pixbuf));
274 }
275 }
276
277
278
279 static void
sn_dialog_selection_changed(GtkTreeSelection * selection,SnDialog * dialog)280 sn_dialog_selection_changed (GtkTreeSelection *selection,
281 SnDialog *dialog)
282 {
283 GtkTreeModel *model;
284 GtkTreeIter iter;
285 GtkTreePath *path;
286 gint *indices;
287 gint count = 0, position = -1, depth;
288 gboolean item_up_sensitive, item_down_sensitive;
289 GObject *object;
290
291 if (gtk_tree_selection_get_selected (selection, &model, &iter))
292 {
293 path = gtk_tree_model_get_path (model, &iter);
294 indices = gtk_tree_path_get_indices_with_depth (path, &depth);
295
296 if (indices != NULL && depth > 0)
297 position = indices[0];
298
299 count = gtk_tree_model_iter_n_children (model, NULL);
300
301 gtk_tree_path_free (path);
302 }
303
304 item_up_sensitive = position > 0;
305 item_down_sensitive = position + 1 < count;
306
307 object = gtk_builder_get_object (dialog->builder, "item-up");
308 if (GTK_IS_BUTTON (object))
309 gtk_widget_set_sensitive (GTK_WIDGET (object), item_up_sensitive);
310
311 object = gtk_builder_get_object (dialog->builder, "item-down");
312 if (GTK_IS_BUTTON (object))
313 gtk_widget_set_sensitive (GTK_WIDGET (object), item_down_sensitive);
314 }
315
316
317
318 static void
sn_dialog_legacy_selection_changed(GtkTreeSelection * selection,SnDialog * dialog)319 sn_dialog_legacy_selection_changed (GtkTreeSelection *selection,
320 SnDialog *dialog)
321 {
322 GtkTreeModel *model;
323 GtkTreeIter iter;
324 GtkTreePath *path;
325 gint *indices;
326 gint count = 0, position = -1, depth;
327 gboolean item_up_sensitive, item_down_sensitive;
328 GObject *object;
329
330 if (gtk_tree_selection_get_selected (selection, &model, &iter))
331 {
332 path = gtk_tree_model_get_path (model, &iter);
333 indices = gtk_tree_path_get_indices_with_depth (path, &depth);
334
335 if (indices != NULL && depth > 0)
336 position = indices[0];
337
338 count = gtk_tree_model_iter_n_children (model, NULL);
339
340 gtk_tree_path_free (path);
341 }
342
343 item_up_sensitive = position > 0;
344 item_down_sensitive = position + 1 < count;
345
346 object = gtk_builder_get_object (dialog->builder, "item-up");
347 if (GTK_IS_BUTTON (object))
348 gtk_widget_set_sensitive (GTK_WIDGET (object), item_up_sensitive);
349
350 object = gtk_builder_get_object (dialog->builder, "item-down");
351 if (GTK_IS_BUTTON (object))
352 gtk_widget_set_sensitive (GTK_WIDGET (object), item_down_sensitive);
353 }
354
355
356
357 static void
sn_dialog_hidden_toggled(GtkCellRendererToggle * renderer,const gchar * path_string,SnDialog * dialog)358 sn_dialog_hidden_toggled (GtkCellRendererToggle *renderer,
359 const gchar *path_string,
360 SnDialog *dialog)
361 {
362 GtkTreeIter iter;
363 gboolean hidden;
364 gchar *name;
365
366 g_return_if_fail (XFCE_IS_SN_DIALOG (dialog));
367 g_return_if_fail (XFCE_IS_SN_CONFIG (dialog->config));
368 g_return_if_fail (GTK_IS_LIST_STORE (dialog->store));
369
370 if (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (dialog->store), &iter, path_string))
371 {
372 gtk_tree_model_get (GTK_TREE_MODEL (dialog->store), &iter,
373 COLUMN_HIDDEN, &hidden,
374 COLUMN_TIP, &name, -1);
375
376 /* insert value (we need to update it) */
377 hidden = !hidden;
378
379 /* update box and store with new state */
380 sn_config_set_hidden (dialog->config, name, hidden);
381 gtk_list_store_set (GTK_LIST_STORE (dialog->store), &iter, COLUMN_HIDDEN, hidden, -1);
382
383 g_free (name);
384 }
385 }
386
387
388
389 static void
sn_dialog_legacy_hidden_toggled(GtkCellRendererToggle * renderer,const gchar * path_string,SnDialog * dialog)390 sn_dialog_legacy_hidden_toggled (GtkCellRendererToggle *renderer,
391 const gchar *path_string,
392 SnDialog *dialog)
393 {
394 GtkTreeIter iter;
395 gboolean hidden;
396 gchar *name;
397
398 g_return_if_fail (XFCE_IS_SN_DIALOG (dialog));
399 g_return_if_fail (XFCE_IS_SN_CONFIG (dialog->config));
400 g_return_if_fail (GTK_IS_LIST_STORE (dialog->store));
401
402 if (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (dialog->legacy_store), &iter, path_string))
403 {
404 gtk_tree_model_get (GTK_TREE_MODEL (dialog->legacy_store), &iter,
405 COLUMN_HIDDEN, &hidden,
406 COLUMN_TIP, &name, -1);
407
408 /* insert value (we need to update it) */
409 hidden = !hidden;
410
411 /* update box and store with new state */
412 sn_config_set_legacy_hidden (dialog->config, name, hidden);
413 gtk_list_store_set (GTK_LIST_STORE (dialog->legacy_store), &iter, COLUMN_HIDDEN, hidden, -1);
414
415 g_free (name);
416 }
417 }
418
419
420
421 static void
sn_dialog_swap_rows(SnDialog * dialog,GtkTreeIter * iter_prev,GtkTreeIter * iter)422 sn_dialog_swap_rows (SnDialog *dialog,
423 GtkTreeIter *iter_prev,
424 GtkTreeIter *iter)
425 {
426 GdkPixbuf *pixbuf1, *pixbuf2;
427 gchar *title1, *title2;
428 gboolean hidden1, hidden2;
429 gchar *tip1, *tip2;
430
431 g_return_if_fail (XFCE_IS_SN_DIALOG (dialog));
432 g_return_if_fail (XFCE_IS_SN_CONFIG (dialog->config));
433 g_return_if_fail (GTK_IS_LIST_STORE (dialog->store));
434
435 gtk_tree_model_get (GTK_TREE_MODEL (dialog->store), iter_prev,
436 COLUMN_PIXBUF, &pixbuf1,
437 COLUMN_TITLE, &title1,
438 COLUMN_HIDDEN, &hidden1,
439 COLUMN_TIP, &tip1, -1);
440 gtk_tree_model_get (GTK_TREE_MODEL (dialog->store), iter,
441 COLUMN_PIXBUF, &pixbuf2,
442 COLUMN_TITLE, &title2,
443 COLUMN_HIDDEN, &hidden2,
444 COLUMN_TIP, &tip2, -1);
445 gtk_list_store_set (GTK_LIST_STORE (dialog->store), iter_prev,
446 COLUMN_PIXBUF, pixbuf2,
447 COLUMN_TITLE, title2,
448 COLUMN_HIDDEN, hidden2,
449 COLUMN_TIP, tip2, -1);
450 gtk_list_store_set (GTK_LIST_STORE (dialog->store), iter,
451 COLUMN_PIXBUF, pixbuf1,
452 COLUMN_TITLE, title1,
453 COLUMN_HIDDEN, hidden1,
454 COLUMN_TIP, tip1, -1);
455
456 /* do a matching operation on SnConfig */
457 sn_config_swap_known_items (dialog->config, tip1, tip2);
458 }
459
460
461
462 static void
sn_dialog_legacy_swap_rows(SnDialog * dialog,GtkTreeIter * iter_prev,GtkTreeIter * iter)463 sn_dialog_legacy_swap_rows(SnDialog *dialog,
464 GtkTreeIter *iter_prev,
465 GtkTreeIter *iter)
466 {
467 GdkPixbuf *pixbuf1, *pixbuf2;
468 gchar *title1, *title2;
469 gboolean hidden1, hidden2;
470 gchar *tip1, *tip2;
471
472 g_return_if_fail(XFCE_IS_SN_DIALOG(dialog));
473 g_return_if_fail(XFCE_IS_SN_CONFIG(dialog->config));
474 g_return_if_fail(GTK_IS_LIST_STORE(dialog->legacy_store));
475
476 gtk_tree_model_get(GTK_TREE_MODEL(dialog->legacy_store), iter_prev,
477 COLUMN_PIXBUF, &pixbuf1,
478 COLUMN_TITLE, &title1,
479 COLUMN_HIDDEN, &hidden1,
480 COLUMN_TIP, &tip1, -1);
481 gtk_tree_model_get(GTK_TREE_MODEL(dialog->legacy_store), iter,
482 COLUMN_PIXBUF, &pixbuf2,
483 COLUMN_TITLE, &title2,
484 COLUMN_HIDDEN, &hidden2,
485 COLUMN_TIP, &tip2, -1);
486 gtk_list_store_set(GTK_LIST_STORE(dialog->legacy_store), iter_prev,
487 COLUMN_PIXBUF, pixbuf2,
488 COLUMN_TITLE, title2,
489 COLUMN_HIDDEN, hidden2,
490 COLUMN_TIP, tip2, -1);
491 gtk_list_store_set(GTK_LIST_STORE(dialog->legacy_store), iter,
492 COLUMN_PIXBUF, pixbuf1,
493 COLUMN_TITLE, title1,
494 COLUMN_HIDDEN, hidden1,
495 COLUMN_TIP, tip1, -1);
496
497 /* do a matching operation on SnConfig */
498 sn_config_swap_known_legacy_items(dialog->config, tip1, tip2);
499 }
500
501
502
503 static gboolean
sn_dialog_iter_equal(GtkTreeIter * iter1,GtkTreeIter * iter2)504 sn_dialog_iter_equal (GtkTreeIter *iter1,
505 GtkTreeIter *iter2)
506 {
507 return (iter1->user_data == iter2->user_data &&
508 iter1->user_data2 == iter2->user_data2 &&
509 iter1->user_data3 == iter2->user_data3);
510 }
511
512
513
514 static void
sn_dialog_item_up_clicked(GtkWidget * button,SnDialog * dialog)515 sn_dialog_item_up_clicked (GtkWidget *button,
516 SnDialog *dialog)
517 {
518 GObject *treeview;
519 GtkTreeSelection *selection;
520 GtkTreeIter iter, iter_prev, iter_tmp;
521
522 g_return_if_fail (XFCE_IS_SN_DIALOG (dialog));
523 g_return_if_fail (GTK_IS_LIST_STORE (dialog->store));
524
525 treeview = gtk_builder_get_object (dialog->builder, "items-treeview");
526 g_return_if_fail (GTK_IS_TREE_VIEW (treeview));
527
528 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
529 if (!gtk_tree_selection_get_selected (selection, NULL, &iter))
530 return;
531
532 /* gtk_tree_model_iter_previous available from Gtk3 */
533 /* so we have to search for it starting from the first iter */
534 if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (dialog->store), &iter_prev))
535 return;
536
537 iter_tmp = iter_prev;
538 while (!sn_dialog_iter_equal (&iter_tmp, &iter))
539 {
540 iter_prev = iter_tmp;
541 if (!gtk_tree_model_iter_next (GTK_TREE_MODEL (dialog->store), &iter_tmp))
542 return;
543 }
544
545 sn_dialog_swap_rows (dialog, &iter_prev, &iter);
546 gtk_tree_selection_select_iter (selection, &iter_prev);
547 }
548
549
550
551 static void
sn_dialog_legacy_item_up_clicked(GtkWidget * button,SnDialog * dialog)552 sn_dialog_legacy_item_up_clicked(GtkWidget *button,
553 SnDialog *dialog)
554 {
555 GObject *treeview;
556 GtkTreeSelection *selection;
557 GtkTreeIter iter, iter_prev, iter_tmp;
558
559 g_return_if_fail(XFCE_IS_SN_DIALOG(dialog));
560 g_return_if_fail(GTK_IS_LIST_STORE(dialog->legacy_store));
561
562 treeview = gtk_builder_get_object(dialog->builder, "legacy-items-treeview");
563 g_return_if_fail(GTK_IS_TREE_VIEW(treeview));
564
565 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));
566 if (!gtk_tree_selection_get_selected(selection, NULL, &iter))
567 return;
568
569 /* gtk_tree_model_iter_previous available from Gtk3 */
570 /* so we have to search for it starting from the first iter */
571 if (!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(dialog->legacy_store), &iter_prev))
572 return;
573
574 iter_tmp = iter_prev;
575 while (!sn_dialog_iter_equal(&iter_tmp, &iter))
576 {
577 iter_prev = iter_tmp;
578 if (!gtk_tree_model_iter_next(GTK_TREE_MODEL(dialog->legacy_store), &iter_tmp))
579 return;
580 }
581
582 sn_dialog_legacy_swap_rows(dialog, &iter_prev, &iter);
583 gtk_tree_selection_select_iter(selection, &iter_prev);
584 }
585
586
587
588 static void
sn_dialog_item_down_clicked(GtkWidget * button,SnDialog * dialog)589 sn_dialog_item_down_clicked (GtkWidget *button,
590 SnDialog *dialog)
591 {
592 GObject *treeview;
593 GtkTreeSelection *selection;
594 GtkTreeIter iter, iter_next;
595
596 g_return_if_fail (XFCE_IS_SN_DIALOG (dialog));
597
598 treeview = gtk_builder_get_object (dialog->builder, "items-treeview");
599 g_return_if_fail (GTK_IS_TREE_VIEW (treeview));
600
601 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
602 if (!gtk_tree_selection_get_selected (selection, NULL, &iter))
603 return;
604
605 iter_next = iter;
606 if (!gtk_tree_model_iter_next (GTK_TREE_MODEL (dialog->store), &iter_next))
607 return;
608
609 sn_dialog_swap_rows (dialog, &iter, &iter_next);
610 gtk_tree_selection_select_iter (selection, &iter_next);
611 }
612
613
614
615 static void
sn_dialog_legacy_item_down_clicked(GtkWidget * button,SnDialog * dialog)616 sn_dialog_legacy_item_down_clicked(GtkWidget *button,
617 SnDialog *dialog)
618 {
619 GObject *treeview;
620 GtkTreeSelection *selection;
621 GtkTreeIter iter, iter_next;
622
623 g_return_if_fail(XFCE_IS_SN_DIALOG(dialog));
624
625 treeview = gtk_builder_get_object(dialog->builder, "legacy-items-treeview");
626 g_return_if_fail(GTK_IS_TREE_VIEW(treeview));
627
628 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));
629 if (!gtk_tree_selection_get_selected(selection, NULL, &iter))
630 return;
631
632 iter_next = iter;
633 if (!gtk_tree_model_iter_next(GTK_TREE_MODEL(dialog->legacy_store), &iter_next))
634 return;
635
636 sn_dialog_legacy_swap_rows(dialog, &iter, &iter_next);
637 gtk_tree_selection_select_iter(selection, &iter_next);
638 }
639
640
641
642 static void
sn_dialog_clear_clicked(GtkWidget * button,SnDialog * dialog)643 sn_dialog_clear_clicked (GtkWidget *button,
644 SnDialog *dialog)
645 {
646 g_return_if_fail (XFCE_IS_SN_DIALOG (dialog));
647
648 if (xfce_dialog_confirm (GTK_WINDOW (gtk_widget_get_toplevel (button)),
649 "edit-clear", _("Clear"), NULL,
650 _("Are you sure you want to clear the list of "
651 "known items?")))
652 {
653 if (sn_config_items_clear (dialog->config))
654 {
655 gtk_list_store_clear (GTK_LIST_STORE (dialog->store));
656 sn_dialog_update_names (dialog);
657 }
658 if (sn_config_legacy_items_clear (dialog->config))
659 {
660 gtk_list_store_clear (GTK_LIST_STORE (dialog->legacy_store));
661 sn_dialog_update_legacy_names (dialog);
662 }
663 }
664 }
665
666
667
668 static void
sn_dialog_dialog_unref(gpointer data,GObject * where_the_object_was)669 sn_dialog_dialog_unref (gpointer data,
670 GObject *where_the_object_was)
671 {
672 SnDialog *dialog = data;
673
674 dialog->dialog = NULL;
675 g_object_unref (dialog);
676 }
677
678
679
680 static void
reveal_icon_size(GtkWidget * widget,GParamSpec * pspec,SnDialog * dialog)681 reveal_icon_size (GtkWidget *widget,
682 GParamSpec *pspec,
683 SnDialog *dialog)
684 {
685 gboolean active;
686 gint icon_size;
687
688 g_return_if_fail (XFCE_IS_SN_DIALOG (dialog));
689
690 active = gtk_switch_get_active (GTK_SWITCH (widget));
691
692 if (active)
693 icon_size = 0;
694 else
695 icon_size = DEFAULT_ICON_SIZE;
696
697 gtk_revealer_set_reveal_child (GTK_REVEALER (dialog->size_revealer), !active);
698 gtk_spin_button_set_value (GTK_SPIN_BUTTON (dialog->size_spinbutton), icon_size);
699 }
700
701
702
703 static gboolean
sn_dialog_build(SnDialog * dialog)704 sn_dialog_build (SnDialog *dialog)
705 {
706 GObject *object;
707 GError *error = NULL;
708 GtkTreeSelection *selection;
709
710 if (xfce_titled_dialog_get_type () == 0)
711 return FALSE;
712
713 dialog->builder = gtk_builder_new ();
714
715 /* load the builder data into the object */
716 if (gtk_builder_add_from_string (dialog->builder, sn_dialog_ui,
717 sn_dialog_ui_length, &error))
718 {
719 object = gtk_builder_get_object (dialog->builder, "dialog");
720 g_return_val_if_fail (XFCE_IS_TITLED_DIALOG (object), FALSE);
721 dialog->dialog = GTK_WIDGET (object);
722
723 object = gtk_builder_get_object (dialog->builder, "close-button");
724 g_return_val_if_fail (GTK_IS_BUTTON (object), FALSE);
725 g_signal_connect_swapped (G_OBJECT (object), "clicked",
726 G_CALLBACK (gtk_widget_destroy),
727 dialog->dialog);
728
729 object = gtk_builder_get_object (dialog->builder, "switch-auto-size");
730 g_return_val_if_fail (GTK_IS_WIDGET (object), FALSE);
731 dialog->auto_size = GTK_WIDGET (object);
732
733 object = gtk_builder_get_object (dialog->builder, "spinbutton-icon-size");
734 g_return_val_if_fail (GTK_IS_WIDGET (object), FALSE);
735 g_object_bind_property (G_OBJECT (dialog->config), "icon-size",
736 G_OBJECT (gtk_spin_button_get_adjustment
737 (GTK_SPIN_BUTTON (object))), "value",
738 G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
739 dialog->size_spinbutton = GTK_WIDGET (object);
740
741 object = gtk_builder_get_object (dialog->builder, "revealer-icon-size");
742 g_return_val_if_fail (GTK_IS_WIDGET (object), FALSE);
743 dialog->size_revealer = GTK_WIDGET (object);
744
745 if (sn_config_get_icon_size_is_automatic (dialog->config))
746 {
747 gtk_switch_set_active (GTK_SWITCH (dialog->auto_size), TRUE);
748 gtk_revealer_set_reveal_child (GTK_REVEALER (dialog->size_revealer), FALSE);
749 }
750
751 g_signal_connect (G_OBJECT (dialog->auto_size), "notify::active",
752 G_CALLBACK (reveal_icon_size), dialog);
753
754 object = gtk_builder_get_object (dialog->builder, "checkbutton-single-row");
755 g_return_val_if_fail (GTK_IS_WIDGET (object), FALSE);
756 g_object_bind_property (G_OBJECT (dialog->config), "single-row",
757 G_OBJECT (object), "active",
758 G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
759
760 object = gtk_builder_get_object (dialog->builder, "checkbutton-square-icons");
761 g_return_val_if_fail (GTK_IS_WIDGET (object), FALSE);
762 g_object_bind_property (G_OBJECT (dialog->config), "square-icons",
763 G_OBJECT (object), "active",
764 G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
765
766 object = gtk_builder_get_object (dialog->builder, "checkbutton-symbolic-icons");
767 g_return_val_if_fail (GTK_IS_WIDGET (object), FALSE);
768 g_object_bind_property (G_OBJECT (dialog->config), "symbolic-icons",
769 G_OBJECT (object), "active",
770 G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
771
772 object = gtk_builder_get_object (dialog->builder, "checkbutton-menu-is-primary");
773 g_return_val_if_fail (GTK_IS_WIDGET (object), FALSE);
774 g_object_bind_property (G_OBJECT (dialog->config), "menu-is-primary",
775 G_OBJECT (object), "active",
776 G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
777
778 object = gtk_builder_get_object (dialog->builder, "checkbutton-hide-new-items");
779 g_return_val_if_fail (GTK_IS_WIDGET (object), FALSE);
780 g_object_bind_property (G_OBJECT (dialog->config), "hide-new-items",
781 G_OBJECT (object), "active",
782 G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
783
784 dialog->store = gtk_builder_get_object (dialog->builder, "items-store");
785 g_return_val_if_fail (GTK_IS_LIST_STORE (dialog->store), FALSE);
786 sn_dialog_update_names (dialog);
787
788 object = gtk_builder_get_object (dialog->builder, "items-treeview");
789 g_return_val_if_fail (GTK_IS_TREE_VIEW (object), FALSE);
790 gtk_tree_view_set_tooltip_column (GTK_TREE_VIEW (object), COLUMN_TIP);
791
792 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (object));
793 g_signal_connect (G_OBJECT (selection), "changed",
794 G_CALLBACK (sn_dialog_selection_changed), dialog);
795 sn_dialog_selection_changed (selection, dialog);
796
797 object = gtk_builder_get_object (dialog->builder, "hidden-toggle");
798 g_return_val_if_fail (GTK_IS_CELL_RENDERER_TOGGLE (object), FALSE);
799 g_signal_connect (G_OBJECT (object), "toggled",
800 G_CALLBACK (sn_dialog_hidden_toggled), dialog);
801
802 object = gtk_builder_get_object (dialog->builder, "item-up");
803 g_return_val_if_fail (GTK_IS_BUTTON (object), FALSE);
804 g_signal_connect (G_OBJECT (object), "clicked",
805 G_CALLBACK (sn_dialog_item_up_clicked), dialog);
806
807 object = gtk_builder_get_object (dialog->builder, "item-down");
808 g_return_val_if_fail (GTK_IS_BUTTON (object), FALSE);
809 g_signal_connect (G_OBJECT (object), "clicked",
810 G_CALLBACK (sn_dialog_item_down_clicked), dialog);
811
812 dialog->legacy_store = gtk_builder_get_object (dialog->builder, "legacy-items-store");
813 g_return_val_if_fail (GTK_IS_LIST_STORE (dialog->legacy_store), FALSE);
814 sn_dialog_update_legacy_names (dialog);
815
816 object = gtk_builder_get_object (dialog->builder, "legacy-items-treeview");
817 g_return_val_if_fail (GTK_IS_TREE_VIEW (object), FALSE);
818 gtk_tree_view_set_tooltip_column (GTK_TREE_VIEW (object), COLUMN_TIP);
819
820 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (object));
821 g_signal_connect (G_OBJECT (selection), "changed",
822 G_CALLBACK (sn_dialog_legacy_selection_changed), dialog);
823 sn_dialog_selection_changed (selection, dialog);
824
825 object = gtk_builder_get_object (dialog->builder, "legacy-hidden-toggle");
826 g_return_val_if_fail (GTK_IS_CELL_RENDERER_TOGGLE (object), FALSE);
827 g_signal_connect (G_OBJECT (object), "toggled",
828 G_CALLBACK (sn_dialog_legacy_hidden_toggled), dialog);
829
830 object = gtk_builder_get_object (dialog->builder, "legacy-item-up");
831 g_return_val_if_fail (GTK_IS_BUTTON (object), FALSE);
832 g_signal_connect (G_OBJECT (object), "clicked",
833 G_CALLBACK (sn_dialog_legacy_item_up_clicked), dialog);
834
835 object = gtk_builder_get_object (dialog->builder, "legacy-item-down");
836 g_return_val_if_fail (GTK_IS_BUTTON (object), FALSE);
837 g_signal_connect (G_OBJECT (object), "clicked",
838 G_CALLBACK (sn_dialog_legacy_item_down_clicked), dialog);
839
840 object = gtk_builder_get_object (dialog->builder, "items-clear");
841 g_return_val_if_fail (GTK_IS_BUTTON (object), FALSE);
842 g_signal_connect (G_OBJECT (object), "clicked",
843 G_CALLBACK (sn_dialog_clear_clicked), dialog);
844
845 #ifndef HAVE_DBUSMENU
846 object = gtk_builder_get_object (dialog->builder, "sn_box");
847 gtk_widget_hide (GTK_WIDGET (object));
848 object = gtk_builder_get_object (dialog->builder, "items_stack_switcher");
849 gtk_widget_hide (GTK_WIDGET (object));
850 #endif
851
852 g_object_weak_ref (G_OBJECT (dialog->dialog), sn_dialog_dialog_unref, dialog);
853 return TRUE;
854 }
855 else
856 {
857 g_critical ("Failed to construct the builder: %s.",
858 error->message);
859 g_error_free (error);
860 return FALSE;
861 }
862 }
863
864
865
866 SnDialog *
sn_dialog_new(SnConfig * config,GdkScreen * screen)867 sn_dialog_new (SnConfig *config,
868 GdkScreen *screen)
869 {
870 SnDialog *dialog;
871
872 g_return_val_if_fail (XFCE_IS_SN_CONFIG (config), NULL);
873
874 dialog = g_object_new (XFCE_TYPE_SN_DIALOG, NULL);
875 dialog->config = config;
876
877 if (sn_dialog_build (dialog))
878 {
879 gtk_widget_show (dialog->dialog);
880 gtk_window_set_screen (GTK_WINDOW (dialog->dialog), screen);
881 return dialog;
882 }
883 else
884 {
885 g_object_unref (dialog);
886 return NULL;
887 }
888 }
889
890
891
892 static void
sn_dialog_finalize(GObject * object)893 sn_dialog_finalize (GObject *object)
894 {
895 SnDialog *dialog = XFCE_SN_DIALOG (object);
896
897 if (dialog->dialog != NULL)
898 gtk_widget_destroy (dialog->dialog);
899
900 if (dialog->builder != NULL)
901 g_object_unref (dialog->builder);
902
903 G_OBJECT_CLASS (sn_dialog_parent_class)->finalize (object);
904 }
905