1 /*
2 * Copyright (C) 2008-2010 Nick Schermer <nick@xfce.org>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19 #ifdef HAVE_CONFIG_H
20 #include <config.h>
21 #endif
22
23 #ifdef HAVE_STDLIB_H
24 #include <stdlib.h>
25 #endif
26
27 #include <libxfce4util/libxfce4util.h>
28 #include <libxfce4ui/libxfce4ui.h>
29
30 #include <common/panel-private.h>
31 #include <common/panel-utils.h>
32
33 #include <libxfce4panel/libxfce4panel.h>
34 #include <libxfce4panel/xfce-panel-plugin-provider.h>
35
36 #include <panel/panel-window.h>
37 #include <panel/panel-application.h>
38 #include <panel/panel-dialogs.h>
39 #include <panel/panel-module.h>
40 #include <panel/panel-itembar.h>
41 #include <panel/panel-item-dialog.h>
42 #include <panel/panel-preferences-dialog.h>
43 #include <panel/panel-preferences-dialog-ui.h>
44 #include <panel/panel-plugin-external.h>
45
46 #define PREFERENCES_HELP_URL "http://www.xfce.org"
47
48
49
50 static void panel_preferences_dialog_finalize (GObject *object);
51 static void panel_preferences_dialog_response (GtkWidget *window,
52 gint response_id,
53 PanelPreferencesDialog *dialog);
54 static void panel_preferences_dialog_bindings_unbind (PanelPreferencesDialog *dialog);
55 static void panel_preferences_dialog_bindings_add (PanelPreferencesDialog *dialog,
56 const gchar *property1,
57 const gchar *property2,
58 GBindingFlags flags);
59 static void panel_preferences_dialog_bindings_update (PanelPreferencesDialog *dialog);
60 static void panel_preferences_dialog_output_changed (GtkComboBox *combobox,
61 PanelPreferencesDialog *dialog);
62 static void panel_preferences_dialog_autohide_changed (GtkComboBox *combobox,
63 PanelPreferencesDialog *dialog);
64 static void panel_preferences_dialog_bg_style_changed (PanelPreferencesDialog *dialog);
65 static void panel_preferences_dialog_bg_image_file_set (GtkFileChooserButton *button,
66 PanelPreferencesDialog *dialog);
67 static void panel_preferences_dialog_bg_image_notified (PanelPreferencesDialog *dialog);
68 static void panel_preferences_dialog_panel_combobox_changed (GtkComboBox *combobox,
69 PanelPreferencesDialog *dialog);
70 static gboolean panel_preferences_dialog_panel_combobox_rebuild (PanelPreferencesDialog *dialog,
71 gint panel_id);
72 static void panel_preferences_dialog_panel_add (GtkWidget *widget,
73 PanelPreferencesDialog *dialog);
74 static void panel_preferences_dialog_panel_remove (GtkWidget *widget,
75 PanelPreferencesDialog *dialog);
76 static gboolean panel_preferences_dialog_icon_size_state_set (GtkSwitch *widget,
77 gboolean state,
78 PanelPreferencesDialog *dialog);
79 static void panel_preferences_dialog_icon_size_changed (GtkSpinButton *button,
80 PanelPreferencesDialog *dialog);
81 static void panel_preferences_dialog_compositing_clicked (GtkButton *button,
82 gpointer user_data);
83 static void panel_preferences_dialog_panel_switch (GtkWidget *widget,
84 PanelPreferencesDialog *dialog);
85 static XfcePanelPluginProvider *panel_preferences_dialog_item_get_selected (PanelPreferencesDialog *dialog,
86 GtkTreeIter *return_iter);
87 static void panel_preferences_dialog_item_store_rebuild (GtkWidget *itembar,
88 PanelPreferencesDialog *dialog);
89 static void panel_preferences_dialog_item_move (GtkWidget *button,
90 PanelPreferencesDialog *dialog);
91 static void panel_preferences_dialog_item_remove (GtkWidget *button,
92 PanelPreferencesDialog *dialog);
93 static void panel_preferences_dialog_item_add (GtkWidget *button,
94 PanelPreferencesDialog *dialog);
95 static void panel_preferences_dialog_item_properties (GtkWidget *button,
96 PanelPreferencesDialog *dialog);
97 static void panel_preferences_dialog_item_about (GtkWidget *button,
98 PanelPreferencesDialog *dialog);
99 static gboolean panel_preferences_dialog_treeview_clicked (GtkTreeView *treeview,
100 GdkEventButton *event,
101 PanelPreferencesDialog *dialog);
102 static void panel_preferences_dialog_item_row_changed (GtkTreeModel *model,
103 GtkTreePath *path,
104 GtkTreeIter *iter,
105 PanelPreferencesDialog *dialog);
106 static void panel_preferences_dialog_item_selection_changed (GtkTreeSelection *selection,
107 PanelPreferencesDialog *dialog);
108
109
110
111 enum
112 {
113 ITEM_COLUMN_ICON_NAME,
114 ITEM_COLUMN_DISPLAY_NAME,
115 ITEM_COLUMN_TOOLTIP,
116 ITEM_COLUMN_PROVIDER,
117 N_ITEM_COLUMNS
118 };
119
120 enum
121 {
122 OUTPUT_NAME,
123 OUTPUT_TITLE
124 };
125
126 struct _PanelPreferencesDialogClass
127 {
128 GtkBuilderClass __parent__;
129 };
130
131 struct _PanelPreferencesDialog
132 {
133 GtkBuilder __parent__;
134
135 PanelApplication *application;
136
137 /* currently selected window in the selector */
138 PanelWindow *active;
139
140 /* GBinding's between dialog <-> window */
141 GSList *bindings;
142
143 /* store for the items list */
144 GtkListStore *store;
145
146 /* changed signal for the active panel's itembar */
147 gulong items_changed_handler_id;
148
149 /* background image watch */
150 gulong bg_image_notify_handler_id;
151
152 /* changed signal for the output selector */
153 gulong output_changed_handler_id;
154
155 /* plug in which the dialog is embedded */
156 GtkWidget *socket_plug;
157 };
158
159
160
161 G_DEFINE_TYPE (PanelPreferencesDialog, panel_preferences_dialog, GTK_TYPE_BUILDER)
162
163
164
165 static PanelPreferencesDialog *dialog_singleton = NULL;
166
167
168
169 static void
panel_preferences_dialog_class_init(PanelPreferencesDialogClass * klass)170 panel_preferences_dialog_class_init (PanelPreferencesDialogClass *klass)
171 {
172 GObjectClass *gobject_class;
173
174 gobject_class = G_OBJECT_CLASS (klass);
175 gobject_class->finalize = panel_preferences_dialog_finalize;
176 }
177
178
179
180 static void
panel_preferences_dialog_init(PanelPreferencesDialog * dialog)181 panel_preferences_dialog_init (PanelPreferencesDialog *dialog)
182 {
183 GObject *window;
184 GObject *object;
185 GObject *info;
186 GObject *treeview;
187 GtkTreeViewColumn *column;
188 GtkCellRenderer *renderer;
189 GtkTreeSelection *selection;
190 gchar *path_old;
191 gchar *path_new;
192 gchar *xfwm4_tweaks;
193
194 dialog->bindings = NULL;
195 dialog->application = panel_application_get ();
196
197 /* block autohide */
198 panel_application_windows_blocked (dialog->application, TRUE);
199
200 /* load the builder data into the object */
201 gtk_builder_add_from_string (GTK_BUILDER (dialog), panel_preferences_dialog_ui,
202 panel_preferences_dialog_ui_length, NULL);
203
204 /* get the dialog */
205 window = gtk_builder_get_object (GTK_BUILDER (dialog), "dialog");
206 panel_return_if_fail (GTK_IS_WIDGET (window));
207 g_signal_connect (G_OBJECT (window), "response",
208 G_CALLBACK (panel_preferences_dialog_response), dialog);
209
210 #define connect_signal(name,detail_signal,c_handler) \
211 object = gtk_builder_get_object (GTK_BUILDER (dialog), name); \
212 panel_return_if_fail (G_IS_OBJECT (object)); \
213 g_signal_connect (G_OBJECT (object), detail_signal, G_CALLBACK (c_handler), dialog);
214
215 /* panel selector buttons and combobox */
216 connect_signal ("panel-add", "clicked", panel_preferences_dialog_panel_add);
217 connect_signal ("panel-remove", "clicked", panel_preferences_dialog_panel_remove);
218 connect_signal ("panel-combobox", "changed", panel_preferences_dialog_panel_combobox_changed);
219
220 /* check if xfce4-panel-profiles or panel-switch are installed and if either is show the button */
221 object = gtk_builder_get_object (GTK_BUILDER (dialog), "panel-profiles");
222 path_old = g_find_program_in_path ("xfpanel-switch");
223 path_new = g_find_program_in_path ("xfce4-panel-profiles");
224 if (path_new == NULL && path_old == NULL)
225 gtk_widget_hide (GTK_WIDGET (object));
226 g_free (path_old);
227 g_free (path_new);
228 connect_signal ("panel-switch", "clicked", panel_preferences_dialog_panel_switch);
229
230 /* appearance tab */
231 object = gtk_builder_get_object (GTK_BUILDER (dialog), "background-style");
232 panel_return_if_fail (G_IS_OBJECT (object));
233 g_signal_connect_swapped (G_OBJECT (object), "changed",
234 G_CALLBACK (panel_preferences_dialog_bg_style_changed), dialog);
235
236 /* icon size switch, handling enabling/disabling of custom icon sizes */
237 object = gtk_builder_get_object (GTK_BUILDER (dialog), "icon-size-spinbutton");
238 panel_return_if_fail (G_IS_OBJECT (object));
239 g_signal_connect (G_OBJECT (object), "value-changed",
240 G_CALLBACK (panel_preferences_dialog_icon_size_changed), dialog);
241 object = gtk_builder_get_object (GTK_BUILDER (dialog), "icon-size-switch");
242 panel_return_if_fail (G_IS_OBJECT (object));
243 g_signal_connect (G_OBJECT (object), "state-set",
244 G_CALLBACK (panel_preferences_dialog_icon_size_state_set), dialog);
245
246 object = gtk_builder_get_object (GTK_BUILDER (dialog), "composited");
247 panel_return_if_fail (G_IS_OBJECT (object));
248 g_signal_connect_swapped (G_OBJECT (object), "notify::visible",
249 G_CALLBACK (panel_preferences_dialog_bg_style_changed), dialog);
250
251 info = gtk_builder_get_object (GTK_BUILDER (dialog), "composited-info");
252 panel_return_if_fail (G_IS_OBJECT (info));
253 g_object_bind_property (G_OBJECT (object), "sensitive",
254 G_OBJECT (info), "visible",
255 G_BINDING_SYNC_CREATE | G_BINDING_INVERT_BOOLEAN);
256
257 object = gtk_builder_get_object (GTK_BUILDER (dialog), "xfwm4-settings");
258 panel_return_if_fail (G_IS_OBJECT (object));
259 xfwm4_tweaks = g_find_program_in_path ("xfwm4-tweaks-settings");
260 gtk_widget_set_visible (GTK_WIDGET (object), xfwm4_tweaks != NULL);
261 g_free (xfwm4_tweaks);
262 g_signal_connect (G_OBJECT (object), "clicked",
263 G_CALLBACK (panel_preferences_dialog_compositing_clicked), NULL);
264
265 object = gtk_builder_get_object (GTK_BUILDER (dialog), "background-image");
266 panel_return_if_fail (GTK_IS_FILE_CHOOSER_BUTTON (object));
267 g_signal_connect (G_OBJECT (object), "file-set",
268 G_CALLBACK (panel_preferences_dialog_bg_image_file_set), dialog);
269
270 /* items treeview and buttons */
271 connect_signal ("item-up", "clicked", panel_preferences_dialog_item_move);
272 connect_signal ("item-down", "clicked", panel_preferences_dialog_item_move);
273 connect_signal ("item-remove", "clicked", panel_preferences_dialog_item_remove);
274 connect_signal ("item-add", "clicked", panel_preferences_dialog_item_add);
275 connect_signal ("item-properties", "clicked", panel_preferences_dialog_item_properties);
276 connect_signal ("item-about", "clicked", panel_preferences_dialog_item_about);
277
278 /* create store for panel items */
279 dialog->store = gtk_list_store_new (N_ITEM_COLUMNS,
280 G_TYPE_STRING, /* ITEM_COLUMN_ICON_NAME */
281 G_TYPE_STRING, /* ITEM_COLUMN_DISPLAY_NAME */
282 G_TYPE_STRING, /* ITEM_COLUMN_TOOLTIP */
283 G_TYPE_OBJECT); /* ITEM_COLUMN_PROVIDER */
284
285 /* build tree for panel items */
286 treeview = gtk_builder_get_object (GTK_BUILDER (dialog), "item-treeview");
287 panel_return_if_fail (GTK_IS_WIDGET (treeview));
288 gtk_tree_view_set_model (GTK_TREE_VIEW (treeview), GTK_TREE_MODEL (dialog->store));
289 gtk_tree_view_set_tooltip_column (GTK_TREE_VIEW (treeview), ITEM_COLUMN_TOOLTIP);
290 g_signal_connect (G_OBJECT (treeview), "button-press-event",
291 G_CALLBACK (panel_preferences_dialog_treeview_clicked), dialog);
292
293 gtk_tree_view_set_reorderable (GTK_TREE_VIEW (treeview), TRUE);
294 g_signal_connect (G_OBJECT (dialog->store), "row-changed",
295 G_CALLBACK (panel_preferences_dialog_item_row_changed), dialog);
296
297 /* setup tree selection */
298 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
299 gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE);
300 g_signal_connect (G_OBJECT (selection), "changed",
301 G_CALLBACK (panel_preferences_dialog_item_selection_changed), dialog);
302
303 /* icon renderer */
304 renderer = gtk_cell_renderer_pixbuf_new ();
305 column = gtk_tree_view_column_new_with_attributes ("", renderer, "icon-name",
306 ITEM_COLUMN_ICON_NAME, NULL);
307 g_object_set (G_OBJECT (renderer), "stock-size", GTK_ICON_SIZE_LARGE_TOOLBAR, NULL);
308 gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
309
310 /* text renderer */
311 renderer = gtk_cell_renderer_text_new ();
312 column = gtk_tree_view_column_new ();
313 gtk_tree_view_column_pack_start (column, renderer, TRUE);
314 gtk_tree_view_column_set_attributes (column, renderer, "markup",
315 ITEM_COLUMN_DISPLAY_NAME, NULL);
316 gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
317
318 /* connect the output changed signal */
319 object = gtk_builder_get_object (GTK_BUILDER (dialog), "output-name");
320 panel_return_if_fail (GTK_IS_COMBO_BOX (object));
321 dialog->output_changed_handler_id =
322 g_signal_connect (G_OBJECT (object), "changed",
323 G_CALLBACK (panel_preferences_dialog_output_changed),
324 dialog);
325
326 /* connect the autohide behavior changed signal */
327 object = gtk_builder_get_object (GTK_BUILDER (dialog), "autohide-behavior");
328 panel_return_if_fail (GTK_IS_COMBO_BOX (object));
329 g_signal_connect (G_OBJECT (object), "changed",
330 G_CALLBACK (panel_preferences_dialog_autohide_changed), dialog);
331 }
332
333
334
335 static void
panel_preferences_dialog_finalize(GObject * object)336 panel_preferences_dialog_finalize (GObject *object)
337 {
338 PanelPreferencesDialog *dialog = PANEL_PREFERENCES_DIALOG (object);
339 GtkWidget *itembar;
340
341 /* unblock autohide */
342 panel_application_windows_blocked (dialog->application, FALSE);
343
344 /* free bindings list */
345 g_slist_free (dialog->bindings);
346
347 /* destroy possible pluggable dialog */
348 if (dialog->socket_plug != NULL)
349 gtk_widget_destroy (dialog->socket_plug);
350
351 if (dialog->active != NULL)
352 {
353 if (dialog->items_changed_handler_id != 0)
354 {
355 /* disconnect changed signal */
356 itembar = gtk_bin_get_child (GTK_BIN (dialog->active));
357 g_signal_handler_disconnect (G_OBJECT (itembar),
358 dialog->items_changed_handler_id);
359 }
360
361 if (dialog->bg_image_notify_handler_id != 0)
362 {
363 g_signal_handler_disconnect (G_OBJECT (dialog->active),
364 dialog->bg_image_notify_handler_id);
365 }
366 }
367
368 /* deselect all windows */
369 if (!panel_item_dialog_visible ())
370 panel_application_window_select (dialog->application, NULL);
371
372 g_object_unref (G_OBJECT (dialog->application));
373 g_object_unref (G_OBJECT (dialog->store));
374
375 (*G_OBJECT_CLASS (panel_preferences_dialog_parent_class)->finalize) (object);
376 }
377
378
379
380 static void
panel_preferences_dialog_response(GtkWidget * window,gint response_id,PanelPreferencesDialog * dialog)381 panel_preferences_dialog_response (GtkWidget *window,
382 gint response_id,
383 PanelPreferencesDialog *dialog)
384 {
385 panel_return_if_fail (GTK_IS_DIALOG (window));
386 panel_return_if_fail (PANEL_IS_PREFERENCES_DIALOG (dialog));
387
388 if (G_UNLIKELY (response_id == 1))
389 {
390 panel_utils_show_help (GTK_WINDOW (window), "preferences", NULL);
391 }
392 else
393 {
394 gtk_widget_destroy (window);
395 g_object_unref (G_OBJECT (dialog));
396 }
397 }
398
399
400
401 static void
panel_preferences_dialog_bindings_unbind(PanelPreferencesDialog * dialog)402 panel_preferences_dialog_bindings_unbind (PanelPreferencesDialog *dialog)
403 {
404 GSList *li;
405
406 if (dialog->bindings != NULL)
407 {
408 /* remove all bindings */
409 for (li = dialog->bindings; li != NULL; li = li->next)
410 g_object_unref (G_OBJECT (li->data));
411
412 g_slist_free (dialog->bindings);
413 dialog->bindings = NULL;
414 }
415
416 /* disconnect image watch */
417 if (dialog->bg_image_notify_handler_id != 0)
418 {
419 if (dialog->active != NULL)
420 {
421 g_signal_handler_disconnect (G_OBJECT (dialog->active),
422 dialog->bg_image_notify_handler_id);
423 }
424
425 dialog->bg_image_notify_handler_id = 0;
426 }
427 }
428
429
430
431 static void
panel_preferences_dialog_bindings_add(PanelPreferencesDialog * dialog,const gchar * property1,const gchar * property2,GBindingFlags flags)432 panel_preferences_dialog_bindings_add (PanelPreferencesDialog *dialog,
433 const gchar *property1,
434 const gchar *property2,
435 GBindingFlags flags)
436 {
437 GBinding *binding;
438 GObject *object;
439
440 /* get the object from the builder */
441 object = gtk_builder_get_object (GTK_BUILDER (dialog), property1);
442 panel_return_if_fail (G_IS_OBJECT (object));
443
444 /* create the binding and prepend to the list */
445 binding = g_object_bind_property (G_OBJECT (dialog->active), property1, object, property2,
446 flags ? flags : G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
447 dialog->bindings = g_slist_prepend (dialog->bindings, binding);
448 }
449
450
451
452 static void
panel_preferences_dialog_bindings_update(PanelPreferencesDialog * dialog)453 panel_preferences_dialog_bindings_update (PanelPreferencesDialog *dialog)
454 {
455 GdkDisplay *display;
456 GdkMonitor *monitor;
457 gint n_monitors = 1;
458 GObject *object;
459 GObject *store;
460 gchar *output_name = NULL;
461 gboolean selector_visible = TRUE;
462 GtkTreeIter iter;
463 gboolean output_selected = FALSE;
464 gint n = 0, i;
465 gchar *name, *title;
466 gboolean span_monitors_sensitive = FALSE;
467 gboolean icon_size_set;
468
469 /* leave when there is no active panel */
470 panel_return_if_fail (G_IS_OBJECT (dialog->active));
471 if (dialog->active == NULL)
472 return;
473
474 /* hook up the bindings */
475 panel_preferences_dialog_bindings_add (dialog, "mode", "active", 0);
476 panel_preferences_dialog_bindings_add (dialog, "span-monitors", "active", 0);
477 panel_preferences_dialog_bindings_add (dialog, "position-locked", "active", 0);
478 panel_preferences_dialog_bindings_add (dialog, "autohide-behavior", "active", 0);
479 panel_preferences_dialog_bindings_add (dialog, "disable-struts", "active", 0);
480 panel_preferences_dialog_bindings_add (dialog, "size", "value", 0);
481 panel_preferences_dialog_bindings_add (dialog, "nrows", "value", 0);
482 panel_preferences_dialog_bindings_add (dialog, "length", "value", 0);
483 panel_preferences_dialog_bindings_add (dialog, "length-adjust", "active", 0);
484 panel_preferences_dialog_bindings_add (dialog, "enter-opacity", "value", 0);
485 panel_preferences_dialog_bindings_add (dialog, "leave-opacity", "value", 0);
486 panel_preferences_dialog_bindings_add (dialog, "composited", "sensitive", G_BINDING_SYNC_CREATE);
487 panel_preferences_dialog_bindings_add (dialog, "background-style", "active", 0);
488 panel_preferences_dialog_bindings_add (dialog, "background-rgba", "rgba", 0);
489 panel_preferences_dialog_bindings_add (dialog, "icon-size", "value", 0);
490 panel_preferences_dialog_bindings_add (dialog, "dark-mode", "active", 0);
491
492 /* watch image changes from the panel */
493 dialog->bg_image_notify_handler_id = g_signal_connect_swapped (G_OBJECT (dialog->active),
494 "notify::background-image", G_CALLBACK (panel_preferences_dialog_bg_image_notified), dialog);
495 panel_preferences_dialog_bg_image_notified (dialog);
496
497
498 /* get run mode of the driver (multiple monitors or randr) */
499 display = gtk_widget_get_display (GTK_WIDGET (dialog->active));
500 n_monitors = gdk_display_get_n_monitors (display);
501
502 /* update the output selector */
503 object = gtk_builder_get_object (GTK_BUILDER (dialog), "output-name");
504 panel_return_if_fail (GTK_IS_COMBO_BOX (object));
505
506 g_signal_handler_block (G_OBJECT (object), dialog->output_changed_handler_id);
507
508 store = gtk_builder_get_object (GTK_BUILDER (dialog), "output-store");
509 panel_return_if_fail (GTK_IS_LIST_STORE (store));
510 gtk_list_store_clear (GTK_LIST_STORE (store));
511
512 g_object_get (G_OBJECT (dialog->active), "output-name", &output_name, NULL);
513
514 if (n_monitors > 1 || !panel_str_is_empty (output_name))
515 {
516 gtk_list_store_insert_with_values (GTK_LIST_STORE (store), &iter, n++,
517 OUTPUT_NAME, "Automatic",
518 OUTPUT_TITLE, _("Automatic"), -1);
519 if (panel_str_is_empty (output_name) ||
520 g_strcmp0 (output_name, "Automatic") == 0)
521 {
522 gtk_combo_box_set_active_iter (GTK_COMBO_BOX (object), &iter);
523 output_selected = TRUE;
524 span_monitors_sensitive = TRUE;
525 }
526 gtk_list_store_insert_with_values (GTK_LIST_STORE (store), &iter, n++,
527 OUTPUT_NAME, "Primary",
528 OUTPUT_TITLE, _("Primary"), -1);
529 if (g_strcmp0 (output_name, "Primary") == 0)
530 {
531 gtk_combo_box_set_active_iter (GTK_COMBO_BOX (object), &iter);
532 output_selected = TRUE;
533 span_monitors_sensitive = FALSE;
534 }
535
536 if (n_monitors >= 1)
537 {
538 for (i = 0; i < n_monitors; i++)
539 {
540 monitor = gdk_display_get_monitor(display, i);
541 name = g_strdup(gdk_monitor_get_model (monitor));
542 if (panel_str_is_empty (name))
543 {
544 g_free (name);
545
546 /* I18N: monitor name in the output selector */
547 title = g_strdup_printf (_("Monitor %d"), i + 1);
548 name = g_strdup_printf ("monitor-%d", i);
549 }
550 else
551 {
552 /* use the randr name for the title */
553 title = g_strdup (name);
554 }
555
556 gtk_list_store_insert_with_values (GTK_LIST_STORE (store), &iter, n++,
557 OUTPUT_NAME, name,
558 OUTPUT_TITLE, title, -1);
559 if (!output_selected
560 && g_strcmp0 (name, output_name) == 0)
561 {
562 gtk_combo_box_set_active_iter (GTK_COMBO_BOX (object), &iter);
563 output_selected = TRUE;
564 }
565
566 g_free (name);
567 g_free (title);
568 }
569 }
570
571 /* add the output from the config if still nothing has been selected */
572 if (!output_selected && !panel_str_is_empty (output_name))
573 {
574 gtk_list_store_insert_with_values (GTK_LIST_STORE (store), &iter, n++,
575 OUTPUT_NAME, output_name,
576 OUTPUT_TITLE, output_name, -1);
577 gtk_combo_box_set_active_iter (GTK_COMBO_BOX (object), &iter);
578 }
579 }
580 else
581 {
582 /* hide the selector */
583 selector_visible = FALSE;
584 span_monitors_sensitive = TRUE;
585 }
586
587 g_signal_handler_unblock (G_OBJECT (object), dialog->output_changed_handler_id);
588
589 /* update visibility of the output selector */
590 object = gtk_builder_get_object (GTK_BUILDER (dialog), "output-label");
591 panel_return_if_fail (GTK_IS_WIDGET (object));
592 g_object_set (G_OBJECT (object), "visible", selector_visible, NULL);
593
594 object = gtk_builder_get_object (GTK_BUILDER (dialog), "output-name");
595 panel_return_if_fail (GTK_IS_WIDGET (object));
596 g_object_set (G_OBJECT (object), "visible", selector_visible, NULL);
597
598 /* monitor spanning is only active when no output is selected */
599 object = gtk_builder_get_object (GTK_BUILDER (dialog), "span-monitors");
600 panel_return_if_fail (GTK_IS_WIDGET (object));
601 gtk_widget_set_sensitive (GTK_WIDGET (object), span_monitors_sensitive);
602 g_object_set (G_OBJECT (object), "visible", n_monitors > 1, NULL);
603
604 g_free (output_name);
605
606 /* update sensitivity of "don't reserve space on borders" option */
607 object = gtk_builder_get_object (GTK_BUILDER (dialog), "autohide-behavior");
608 panel_return_if_fail (GTK_IS_COMBO_BOX (object));
609 panel_preferences_dialog_autohide_changed (GTK_COMBO_BOX (object), dialog);
610
611 /* update visibility of the "icon-size" widgets */
612 object = gtk_builder_get_object (GTK_BUILDER (dialog), "icon-size-spinbutton");
613 panel_return_if_fail (G_IS_OBJECT (object));
614
615 if (gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (object)) == 0)
616 icon_size_set = FALSE;
617 else
618 icon_size_set = TRUE;
619
620 object = gtk_builder_get_object (GTK_BUILDER (dialog), "icon-size-revealer");
621 panel_return_if_fail (G_IS_OBJECT (object));
622 gtk_revealer_set_reveal_child (GTK_REVEALER (object), icon_size_set);
623
624 object = gtk_builder_get_object (GTK_BUILDER (dialog), "icon-size-switch");
625 panel_return_if_fail (G_IS_OBJECT (object));
626 gtk_switch_set_state (GTK_SWITCH (object), !icon_size_set);
627 }
628
629
630
631 static void
panel_preferences_dialog_output_changed(GtkComboBox * combobox,PanelPreferencesDialog * dialog)632 panel_preferences_dialog_output_changed (GtkComboBox *combobox,
633 PanelPreferencesDialog *dialog)
634 {
635 GtkTreeIter iter;
636 GtkTreeModel *model;
637 gchar *output_name = NULL;
638 GObject *object;
639
640 panel_return_if_fail (GTK_IS_COMBO_BOX (combobox));
641 panel_return_if_fail (PANEL_IS_PREFERENCES_DIALOG (dialog));
642 panel_return_if_fail (PANEL_WINDOW (dialog->active));
643
644 if (gtk_combo_box_get_active_iter (combobox, &iter))
645 {
646 model = gtk_combo_box_get_model (combobox);
647 gtk_tree_model_get (model, &iter, OUTPUT_NAME, &output_name, -1);
648 g_object_set (G_OBJECT (dialog->active), "output-name", output_name, NULL);
649
650 /* monitor spanning does not work when an output is selected */
651 object = gtk_builder_get_object (GTK_BUILDER (dialog), "span-monitors");
652 panel_return_if_fail (GTK_IS_WIDGET (object));
653 if (output_name == NULL ||
654 g_strcmp0 ("Automatic", output_name) == 0)
655 gtk_widget_set_sensitive (GTK_WIDGET (object), TRUE);
656 else
657 gtk_widget_set_sensitive (GTK_WIDGET (object), FALSE);
658
659 g_free (output_name);
660 }
661 }
662
663
664
665 static void
panel_preferences_dialog_autohide_changed(GtkComboBox * combobox,PanelPreferencesDialog * dialog)666 panel_preferences_dialog_autohide_changed (GtkComboBox *combobox,
667 PanelPreferencesDialog *dialog)
668 {
669 GObject *object;
670
671 panel_return_if_fail (GTK_IS_COMBO_BOX (combobox));
672 panel_return_if_fail (PANEL_IS_PREFERENCES_DIALOG (dialog));
673 panel_return_if_fail (PANEL_WINDOW (dialog->active));
674
675 object = gtk_builder_get_object (GTK_BUILDER (dialog), "disable-struts");
676 panel_return_if_fail (GTK_IS_WIDGET (object));
677
678 /* make "don't reserve space on borders" sensitive only when autohide is disabled */
679 if (gtk_combo_box_get_active (combobox) == 0)
680 gtk_widget_set_sensitive (GTK_WIDGET (object), TRUE);
681 else
682 gtk_widget_set_sensitive (GTK_WIDGET (object), FALSE);
683 }
684
685
686
687 static void
panel_preferences_dialog_bg_style_changed(PanelPreferencesDialog * dialog)688 panel_preferences_dialog_bg_style_changed (PanelPreferencesDialog *dialog)
689 {
690 gint active;
691 GObject *object;
692 gboolean composited;
693
694 panel_return_if_fail (PANEL_IS_PREFERENCES_DIALOG (dialog));
695 panel_return_if_fail (PANEL_WINDOW (dialog->active));
696
697 object = gtk_builder_get_object (GTK_BUILDER (dialog), "background-style");
698 panel_return_if_fail (GTK_IS_COMBO_BOX (object));
699 active = gtk_combo_box_get_active (GTK_COMBO_BOX (object));
700
701 object = gtk_builder_get_object (GTK_BUILDER (dialog), "background-rgba");
702 panel_return_if_fail (GTK_IS_WIDGET (object));
703 g_object_get (G_OBJECT (dialog->active), "composited", &composited, NULL);
704 gtk_color_chooser_set_use_alpha (GTK_COLOR_CHOOSER (object), composited);
705
706 object = gtk_builder_get_object (GTK_BUILDER (dialog), "background-rgba-label");
707 panel_return_if_fail (GTK_IS_WIDGET (object));
708 g_object_set (G_OBJECT (object), "visible", active == 1, NULL);
709
710 object = gtk_builder_get_object (GTK_BUILDER (dialog), "background-rgba");
711 panel_return_if_fail (GTK_IS_WIDGET (object));
712 g_object_set (G_OBJECT (object), "visible", active == 1, NULL);
713
714 object = gtk_builder_get_object (GTK_BUILDER (dialog), "background-image-label");
715 panel_return_if_fail (GTK_IS_WIDGET (object));
716 g_object_set (G_OBJECT (object), "visible", active == 2, NULL);
717
718 object = gtk_builder_get_object (GTK_BUILDER (dialog), "background-image");
719 panel_return_if_fail (GTK_IS_WIDGET (object));
720 g_object_set (G_OBJECT (object), "visible", active == 2, NULL);
721 }
722
723
724
725 static void
panel_preferences_dialog_bg_image_file_set(GtkFileChooserButton * button,PanelPreferencesDialog * dialog)726 panel_preferences_dialog_bg_image_file_set (GtkFileChooserButton *button,
727 PanelPreferencesDialog *dialog)
728 {
729 gchar *filename;
730
731 panel_return_if_fail (GTK_IS_FILE_CHOOSER_BUTTON (button));
732 panel_return_if_fail (PANEL_IS_PREFERENCES_DIALOG (dialog));
733 panel_return_if_fail (PANEL_IS_WINDOW (dialog->active));
734
735 g_signal_handler_block (G_OBJECT (dialog->active),
736 dialog->bg_image_notify_handler_id);
737
738 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (button));
739 g_object_set (G_OBJECT (dialog->active), "background-image", filename, NULL);
740 g_free (filename);
741
742 g_signal_handler_unblock (G_OBJECT (dialog->active),
743 dialog->bg_image_notify_handler_id);
744 }
745
746
747
748 static void
panel_preferences_dialog_bg_image_notified(PanelPreferencesDialog * dialog)749 panel_preferences_dialog_bg_image_notified (PanelPreferencesDialog *dialog)
750 {
751 gchar *filename;
752 GObject *button;
753
754 panel_return_if_fail (PANEL_IS_PREFERENCES_DIALOG (dialog));
755 panel_return_if_fail (PANEL_IS_WINDOW (dialog->active));
756
757 button = gtk_builder_get_object (GTK_BUILDER (dialog), "background-image");
758 panel_return_if_fail (GTK_IS_FILE_CHOOSER_BUTTON (button));
759
760 g_signal_handlers_block_by_func (G_OBJECT (button),
761 G_CALLBACK (panel_preferences_dialog_bg_image_file_set), dialog);
762
763 g_object_get (G_OBJECT (dialog->active), "background-image", &filename, NULL);
764 gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (button), filename != NULL ? filename : "");
765 g_free (filename);
766
767 g_signal_handlers_unblock_by_func (G_OBJECT (button),
768 G_CALLBACK (panel_preferences_dialog_bg_image_file_set), dialog);
769 }
770
771
772
773 static void
panel_preferences_dialog_panel_sensitive(PanelPreferencesDialog * dialog)774 panel_preferences_dialog_panel_sensitive (PanelPreferencesDialog *dialog)
775 {
776
777 GObject *object;
778 gboolean locked = TRUE;
779 GSList *windows;
780
781 panel_return_if_fail (PANEL_IS_PREFERENCES_DIALOG (dialog));
782
783 if (G_LIKELY (dialog->active != NULL))
784 locked = panel_window_get_locked (dialog->active);
785
786 object = gtk_builder_get_object (GTK_BUILDER (dialog), "panel-remove");
787 panel_return_if_fail (GTK_IS_WIDGET (object));
788 windows = panel_application_get_windows (dialog->application);
789 gtk_widget_set_sensitive (GTK_WIDGET (object),
790 !locked && g_slist_length (windows) > 1);
791
792 object = gtk_builder_get_object (GTK_BUILDER (dialog), "panel-add");
793 panel_return_if_fail (GTK_IS_WIDGET (object));
794 gtk_widget_set_sensitive (GTK_WIDGET (object),
795 !panel_application_get_locked (dialog->application));
796
797 object = gtk_builder_get_object (GTK_BUILDER (dialog), "notebook");
798 panel_return_if_fail (GTK_IS_WIDGET (object));
799 gtk_widget_set_sensitive (GTK_WIDGET (object), !locked);
800
801 object = gtk_builder_get_object (GTK_BUILDER (dialog), "item-add");
802 panel_return_if_fail (GTK_IS_WIDGET (object));
803 gtk_widget_set_sensitive (GTK_WIDGET (object), !locked);
804 }
805
806
807
808 static void
panel_preferences_dialog_panel_combobox_changed(GtkComboBox * combobox,PanelPreferencesDialog * dialog)809 panel_preferences_dialog_panel_combobox_changed (GtkComboBox *combobox,
810 PanelPreferencesDialog *dialog)
811 {
812 gint panel_id;
813 GtkWidget *itembar;
814 GtkTreeModel *model;
815 GtkTreeIter iter;
816
817 panel_return_if_fail (GTK_IS_COMBO_BOX (combobox));
818 panel_return_if_fail (PANEL_IS_PREFERENCES_DIALOG (dialog));
819
820 /* disconnect signal we used to monitor changes in the itembar */
821 if (dialog->active != NULL && dialog->items_changed_handler_id != 0)
822 {
823 itembar = gtk_bin_get_child (GTK_BIN (dialog->active));
824 g_signal_handler_disconnect (G_OBJECT (itembar), dialog->items_changed_handler_id);
825 }
826
827 /* remove all the active bindings */
828 panel_preferences_dialog_bindings_unbind (dialog);
829
830 /* set the selected window */
831 if (gtk_combo_box_get_active_iter (combobox, &iter))
832 {
833 model = gtk_combo_box_get_model (combobox);
834 gtk_tree_model_get (model, &iter, 0, &panel_id, -1);
835
836 dialog->active = panel_application_get_window (dialog->application, panel_id);
837 }
838 else
839 {
840 dialog->active = NULL;
841 }
842
843 panel_application_window_select (dialog->application, dialog->active);
844
845 if (G_LIKELY (dialog->active != NULL))
846 {
847 itembar = gtk_bin_get_child (GTK_BIN (dialog->active));
848 dialog->items_changed_handler_id =
849 g_signal_connect (G_OBJECT (itembar), "changed",
850 G_CALLBACK (panel_preferences_dialog_item_store_rebuild),
851 dialog);
852
853 /* rebind the dialog bindings */
854 panel_preferences_dialog_bindings_update (dialog);
855
856 /* update the items treeview */
857 panel_preferences_dialog_item_store_rebuild (itembar, dialog);
858 }
859
860 panel_preferences_dialog_panel_sensitive (dialog);
861 }
862
863
864
865 static gboolean
panel_preferences_dialog_panel_combobox_rebuild(PanelPreferencesDialog * dialog,gint panel_id)866 panel_preferences_dialog_panel_combobox_rebuild (PanelPreferencesDialog *dialog,
867 gint panel_id)
868 {
869 GObject *store, *combo;
870 gint i;
871 GSList *windows, *li;
872 gchar *name;
873 gint id;
874 GtkTreeIter iter;
875 gboolean selected = FALSE;
876
877 /* get the combo box and model */
878 store = gtk_builder_get_object (GTK_BUILDER (dialog), "panel-store");
879 panel_return_val_if_fail (GTK_IS_LIST_STORE (store), FALSE);
880 combo = gtk_builder_get_object (GTK_BUILDER (dialog), "panel-combobox");
881 panel_return_val_if_fail (GTK_IS_COMBO_BOX (combo), FALSE);
882
883 /* block signal */
884 g_signal_handlers_block_by_func (combo,
885 panel_preferences_dialog_panel_combobox_changed, dialog);
886
887 /* empty the combo box */
888 gtk_list_store_clear (GTK_LIST_STORE (store));
889
890 /* add new names */
891 windows = panel_application_get_windows (dialog->application);
892 for (li = windows, i = 0; li != NULL; li = li->next, i++)
893 {
894 /* I18N: panel combo box in the preferences dialog */
895 id = panel_window_get_id (li->data);
896 name = g_strdup_printf (_("Panel %d"), id);
897 gtk_list_store_insert_with_values (GTK_LIST_STORE (store), &iter, i,
898 0, id, 1, name, -1);
899 g_free (name);
900
901 if (id == panel_id)
902 {
903 /* select panel id */
904 gtk_combo_box_set_active_iter (GTK_COMBO_BOX (combo), &iter);
905 selected = TRUE;
906 }
907 }
908
909 /* unblock signal */
910 g_signal_handlers_unblock_by_func (combo,
911 panel_preferences_dialog_panel_combobox_changed, dialog);
912
913 if (selected)
914 panel_preferences_dialog_panel_combobox_changed (GTK_COMBO_BOX (combo), dialog);
915
916 panel_preferences_dialog_panel_sensitive (dialog);
917
918 return selected;
919 }
920
921
922
923 static void
panel_preferences_dialog_panel_add(GtkWidget * widget,PanelPreferencesDialog * dialog)924 panel_preferences_dialog_panel_add (GtkWidget *widget,
925 PanelPreferencesDialog *dialog)
926 {
927 PanelWindow *window;
928 gint panel_id;
929
930 /* create new window */
931 window = panel_application_new_window (dialog->application,
932 gtk_widget_get_screen (widget), -1, TRUE);
933
934 /* block autohide */
935 panel_window_freeze_autohide (window);
936
937 /* show window */
938 gtk_widget_show (GTK_WIDGET (window));
939
940 /* rebuild the selector */
941 panel_id = panel_window_get_id (window);
942 panel_preferences_dialog_panel_combobox_rebuild (dialog, panel_id);
943 }
944
945
946
947 static void
panel_preferences_dialog_panel_remove(GtkWidget * widget,PanelPreferencesDialog * dialog)948 panel_preferences_dialog_panel_remove (GtkWidget *widget,
949 PanelPreferencesDialog *dialog)
950 {
951 gint idx;
952 GtkWidget *toplevel;
953 GSList *windows;
954 gint n_windows;
955
956 /* leave if the window is locked */
957 if (panel_window_get_locked (dialog->active))
958 return;
959
960 toplevel = gtk_widget_get_toplevel (widget);
961 if (xfce_dialog_confirm (GTK_WINDOW (toplevel), "list-remove", _("_Remove"),
962 _("The panel and plugin configurations will be permanently removed"),
963 _("Are you sure you want to remove panel %d?"),
964 panel_window_get_id (dialog->active)))
965 {
966 /* release the bindings */
967 panel_preferences_dialog_bindings_unbind (dialog);
968
969 /* get position of the panel */
970 windows = panel_application_get_windows (dialog->application);
971 idx = g_slist_index (windows, dialog->active);
972 n_windows = g_slist_length (windows) - 2;
973
974 /* remove the panel, plugins and configuration */
975 panel_application_remove_window (dialog->application,
976 dialog->active);
977 dialog->active = NULL;
978
979 /* rebuild the selector */
980 panel_preferences_dialog_panel_combobox_rebuild (dialog, CLAMP (idx, 0, n_windows));
981 }
982 }
983
984
985
986 static gboolean
panel_preferences_dialog_icon_size_state_set(GtkSwitch * widget,gboolean state,PanelPreferencesDialog * dialog)987 panel_preferences_dialog_icon_size_state_set (GtkSwitch *widget,
988 gboolean state,
989 PanelPreferencesDialog *dialog)
990 {
991 GObject *spinbutton, *revealer;
992
993 panel_return_val_if_fail (PANEL_IS_PREFERENCES_DIALOG (dialog), FALSE);
994 spinbutton = gtk_builder_get_object (GTK_BUILDER (dialog), "icon-size-spinbutton");
995 panel_return_val_if_fail (G_IS_OBJECT (spinbutton), FALSE);
996 revealer = gtk_builder_get_object (GTK_BUILDER (dialog), "icon-size-revealer");
997 panel_return_val_if_fail (G_IS_OBJECT (revealer), FALSE);
998
999 /* we set the icon-size to 0 for auto-handling */
1000 if (state)
1001 {
1002 gtk_spin_button_set_value (GTK_SPIN_BUTTON (spinbutton), 0.0);
1003 }
1004 else
1005 {
1006 /* if the setting is initially enabled we start at the low default of 16px */
1007 if (gtk_spin_button_get_value (GTK_SPIN_BUTTON (spinbutton)) == 0)
1008 gtk_spin_button_set_value (GTK_SPIN_BUTTON (spinbutton), 16.0);
1009 }
1010
1011 gtk_revealer_set_reveal_child (GTK_REVEALER (revealer), !state);
1012 gtk_switch_set_state (GTK_SWITCH (widget), state);
1013
1014 return TRUE;
1015 }
1016
1017
1018
1019 static void
panel_preferences_dialog_icon_size_changed(GtkSpinButton * button,PanelPreferencesDialog * dialog)1020 panel_preferences_dialog_icon_size_changed (GtkSpinButton *button,
1021 PanelPreferencesDialog *dialog)
1022 {
1023 GObject *object;
1024
1025 panel_return_if_fail (PANEL_IS_PREFERENCES_DIALOG (dialog));
1026 object = gtk_builder_get_object (GTK_BUILDER (dialog), "icon-size-switch");
1027 panel_return_if_fail (G_IS_OBJECT (object));
1028
1029 /* 0 means the setting is disabled (icon-size-switch's state == true) so the lower value
1030 of the spinbutton has to be 0. however, we want to set 16px as the reasonable lower limit for icons. */
1031 if (gtk_spin_button_get_value_as_int (button) < 16
1032 && gtk_switch_get_state (GTK_SWITCH (object)))
1033 gtk_spin_button_set_value (button, 16.0);
1034 }
1035
1036
1037
1038 static void
panel_preferences_dialog_compositing_clicked(GtkButton * button,gpointer user_data)1039 panel_preferences_dialog_compositing_clicked (GtkButton *button, gpointer user_data)
1040 {
1041 gchar *command;
1042 GAppInfo *app_info = NULL;
1043 GError *error = NULL;
1044
1045 command = g_find_program_in_path ("xfwm4-tweaks-settings");
1046 if (command != NULL)
1047 app_info = g_app_info_create_from_commandline (command, "Window Manager Tweaks", G_APP_INFO_CREATE_NONE, &error);
1048 g_free (command);
1049
1050 if (error != NULL)
1051 {
1052 g_warning ("Could not find application %s", error->message);
1053 g_error_free (error);
1054 return;
1055 }
1056
1057 if (app_info != NULL && !g_app_info_launch (app_info, NULL, NULL, &error))
1058 {
1059 g_warning ("Could not launch the application %s", error->message);
1060 g_error_free (error);
1061 }
1062 }
1063
1064
1065
1066 static void
panel_preferences_dialog_panel_switch(GtkWidget * widget,PanelPreferencesDialog * dialog)1067 panel_preferences_dialog_panel_switch (GtkWidget *widget, PanelPreferencesDialog *dialog)
1068 {
1069 GtkWidget *toplevel;
1070 gchar *path_old;
1071 gchar *path_new;
1072
1073 path_old = g_find_program_in_path ("xfpanel-switch");
1074 path_new = g_find_program_in_path ("xfce4-panel-profiles");
1075 if (path_old == NULL && path_new == NULL)
1076 return;
1077
1078 /* close the preferences dialog */
1079 toplevel = gtk_widget_get_toplevel (widget);
1080 panel_preferences_dialog_response (toplevel, 0, dialog);
1081
1082 /* first try the new name of the executable, then the old */
1083 if (path_new)
1084 g_spawn_command_line_async (path_new, NULL);
1085 else if (path_old)
1086 g_spawn_command_line_async (path_old, NULL);
1087
1088 g_free (path_old);
1089 g_free (path_new);
1090 }
1091
1092
1093
1094 static XfcePanelPluginProvider *
panel_preferences_dialog_item_get_selected(PanelPreferencesDialog * dialog,GtkTreeIter * return_iter)1095 panel_preferences_dialog_item_get_selected (PanelPreferencesDialog *dialog,
1096 GtkTreeIter *return_iter)
1097 {
1098 GObject *treeview;
1099 XfcePanelPluginProvider *provider = NULL;
1100 GtkTreeModel *model;
1101 GtkTreeIter iter;
1102 GtkTreeSelection *selection;
1103
1104 panel_return_val_if_fail (PANEL_IS_PREFERENCES_DIALOG (dialog), NULL);
1105
1106 /* get the treeview selection */
1107 treeview = gtk_builder_get_object (GTK_BUILDER (dialog), "item-treeview");
1108 panel_return_val_if_fail (GTK_IS_WIDGET (treeview), NULL);
1109 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
1110
1111 /* get the selection item */
1112 if (gtk_tree_selection_get_selected (selection, &model, &iter))
1113 {
1114 /* get the selected provider */
1115 gtk_tree_model_get (model, &iter, ITEM_COLUMN_PROVIDER, &provider, -1);
1116 panel_return_val_if_fail (XFCE_IS_PANEL_PLUGIN_PROVIDER (provider), NULL);
1117
1118 if (return_iter)
1119 *return_iter = iter;
1120 }
1121
1122 return provider;
1123 }
1124
1125
1126
1127 static void
panel_preferences_dialog_item_store_rebuild(GtkWidget * itembar,PanelPreferencesDialog * dialog)1128 panel_preferences_dialog_item_store_rebuild (GtkWidget *itembar,
1129 PanelPreferencesDialog *dialog)
1130 {
1131 GList *items, *li;
1132 guint i;
1133 PanelModule *module;
1134 gchar *tooltip, *display_name;
1135 XfcePanelPluginProvider *selected_provider;
1136 GtkTreeIter iter;
1137 GtkTreePath *path;
1138 GObject *treeview;
1139
1140 panel_return_if_fail (PANEL_IS_PREFERENCES_DIALOG (dialog));
1141 panel_return_if_fail (GTK_IS_LIST_STORE (dialog->store));
1142 panel_return_if_fail (PANEL_IS_ITEMBAR (itembar));
1143
1144 /* memorize selected item */
1145 selected_provider = panel_preferences_dialog_item_get_selected (dialog, NULL);
1146
1147 gtk_list_store_clear (dialog->store);
1148
1149 g_signal_handlers_block_by_func (G_OBJECT (dialog->store),
1150 G_CALLBACK (panel_preferences_dialog_item_row_changed), dialog);
1151
1152 /* add items to the store */
1153 items = gtk_container_get_children (GTK_CONTAINER (itembar));
1154 for (li = items, i = 0; li != NULL; li = li->next, i++)
1155 {
1156 /* get the panel module from the plugin */
1157 module = panel_module_get_from_plugin_provider (li->data);
1158
1159 if (PANEL_IS_PLUGIN_EXTERNAL (li->data))
1160 {
1161 /* I18N: append (external) in the preferences dialog if the plugin
1162 * runs external */
1163 display_name = g_strdup_printf (_("%s <span color=\"grey\" size=\"small\">(external)</span>"),
1164 panel_module_get_display_name (module));
1165
1166 /* I18N: tooltip in preferences dialog when hovering an item in the list
1167 * for external plugins */
1168 tooltip = g_strdup_printf (_("Internal name: %s-%d\n"
1169 "PID: %d"),
1170 xfce_panel_plugin_provider_get_name (li->data),
1171 xfce_panel_plugin_provider_get_unique_id (li->data),
1172 panel_plugin_external_get_pid (PANEL_PLUGIN_EXTERNAL (li->data)));
1173 }
1174 else
1175 {
1176 display_name = g_strdup (panel_module_get_display_name (module));
1177
1178 /* I18N: tooltip in preferences dialog when hovering an item in the list
1179 * for internal plugins */
1180 tooltip = g_strdup_printf (_("Internal name: %s-%d"),
1181 xfce_panel_plugin_provider_get_name (li->data),
1182 xfce_panel_plugin_provider_get_unique_id (li->data));
1183 }
1184
1185 gtk_list_store_insert_with_values (dialog->store, &iter, i,
1186 ITEM_COLUMN_ICON_NAME,
1187 panel_module_get_icon_name (module),
1188 ITEM_COLUMN_DISPLAY_NAME,
1189 display_name,
1190 ITEM_COLUMN_TOOLTIP,
1191 tooltip,
1192 ITEM_COLUMN_PROVIDER, li->data, -1);
1193
1194 /* reconstruct selection */
1195 if (selected_provider == li->data)
1196 {
1197 path = gtk_tree_model_get_path (GTK_TREE_MODEL (dialog->store), &iter);
1198 treeview = gtk_builder_get_object (GTK_BUILDER (dialog), "item-treeview");
1199 if (GTK_IS_WIDGET (treeview))
1200 gtk_tree_view_set_cursor (GTK_TREE_VIEW (treeview), path, NULL, FALSE);
1201 gtk_tree_path_free (path);
1202 }
1203
1204 g_free (tooltip);
1205 g_free (display_name);
1206 }
1207
1208 g_list_free (items);
1209
1210 g_signal_handlers_unblock_by_func (G_OBJECT (dialog->store),
1211 G_CALLBACK (panel_preferences_dialog_item_row_changed), dialog);
1212 }
1213
1214
1215
1216 static void
panel_preferences_dialog_item_move(GtkWidget * button,PanelPreferencesDialog * dialog)1217 panel_preferences_dialog_item_move (GtkWidget *button,
1218 PanelPreferencesDialog *dialog)
1219 {
1220 GObject *treeview, *object;
1221 GtkTreeSelection *selection;
1222 GtkTreeIter iter_a, iter_b;
1223 XfcePanelPluginProvider *provider;
1224 GtkWidget *itembar;
1225 gint position;
1226 gint direction;
1227 GtkTreePath *path;
1228
1229 panel_return_if_fail (PANEL_IS_PREFERENCES_DIALOG (dialog));
1230
1231 /* direction */
1232 object = gtk_builder_get_object (GTK_BUILDER (dialog), "item-up");
1233 panel_return_if_fail (GTK_IS_WIDGET (object));
1234 direction = G_OBJECT (button) == object ? -1 : 1;
1235
1236 provider = panel_preferences_dialog_item_get_selected (dialog, &iter_a);
1237 if (G_LIKELY (provider != NULL))
1238 {
1239 /* get the provider position on the panel */
1240 itembar = gtk_bin_get_child (GTK_BIN (dialog->active));
1241 position = panel_itembar_get_child_index (PANEL_ITEMBAR (itembar),
1242 GTK_WIDGET (provider));
1243 path = gtk_tree_model_get_path (GTK_TREE_MODEL (dialog->store), &iter_a);
1244
1245 if (G_LIKELY (position != -1))
1246 {
1247 /* block the changed signal */
1248 g_signal_handler_block (G_OBJECT (itembar), dialog->items_changed_handler_id);
1249
1250 /* move the item on the panel */
1251 panel_itembar_reorder_child (PANEL_ITEMBAR (itembar),
1252 GTK_WIDGET (provider),
1253 position + direction);
1254
1255 /* save the new ids */
1256 panel_application_save_window (dialog->application,
1257 dialog->active,
1258 SAVE_PLUGIN_IDS);
1259
1260 /* unblock the changed signal */
1261 g_signal_handler_unblock (G_OBJECT (itembar), dialog->items_changed_handler_id);
1262
1263 /* move the item up or down in the list */
1264 if (direction == 1)
1265 {
1266 /* swap the items in the list */
1267 iter_b = iter_a;
1268 if (gtk_tree_model_iter_next (GTK_TREE_MODEL (dialog->store), &iter_b))
1269 {
1270 gtk_list_store_swap (dialog->store, &iter_a, &iter_b);
1271 gtk_tree_path_next (path);
1272 }
1273 }
1274 else
1275 {
1276 /* get the previous item in the list */
1277 if (gtk_tree_path_prev (path))
1278 {
1279 /* swap the items in the list */
1280 gtk_tree_model_get_iter (GTK_TREE_MODEL (dialog->store), &iter_b, path);
1281 gtk_list_store_swap (dialog->store, &iter_a, &iter_b);
1282 }
1283 }
1284
1285 /* fake update the selection */
1286 treeview = gtk_builder_get_object (GTK_BUILDER (dialog), "item-treeview");
1287 panel_return_if_fail (GTK_IS_WIDGET (treeview));
1288 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
1289 panel_preferences_dialog_item_selection_changed (selection, dialog);
1290
1291 /* make the new selected position visible if moved out of area */
1292 gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (treeview), path, NULL, FALSE, 0, 0);
1293 gtk_tree_view_set_cursor (GTK_TREE_VIEW (treeview), path, NULL, FALSE);
1294
1295 }
1296 gtk_tree_path_free (path);
1297 }
1298 }
1299
1300
1301
1302 static void
panel_preferences_dialog_item_remove(GtkWidget * button,PanelPreferencesDialog * dialog)1303 panel_preferences_dialog_item_remove (GtkWidget *button,
1304 PanelPreferencesDialog *dialog)
1305 {
1306 XfcePanelPluginProvider *provider;
1307 GtkWidget *widget, *toplevel;
1308 PanelModule *module;
1309
1310 panel_return_if_fail (PANEL_IS_PREFERENCES_DIALOG (dialog));
1311
1312 provider = panel_preferences_dialog_item_get_selected (dialog, NULL);
1313 if (G_LIKELY (provider != NULL))
1314 {
1315 module = panel_module_get_from_plugin_provider (provider);
1316
1317 /* create question dialog (same code is also in xfce-panel-plugin.c) */
1318 toplevel = gtk_widget_get_toplevel (button);
1319 widget = gtk_message_dialog_new (GTK_WINDOW (toplevel), GTK_DIALOG_MODAL,
1320 GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE,
1321 _("Are you sure that you want to remove \"%s\"?"),
1322 panel_module_get_display_name (module));
1323 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (widget),
1324 _("If you remove the item from the panel, "
1325 "it is permanently lost."));
1326 gtk_dialog_add_buttons (GTK_DIALOG (widget), _("_Cancel"), GTK_RESPONSE_NO,
1327 _("_Remove"), GTK_RESPONSE_YES, NULL);
1328 gtk_dialog_set_default_response (GTK_DIALOG (widget), GTK_RESPONSE_NO);
1329
1330 /* run the dialog */
1331 if (gtk_dialog_run (GTK_DIALOG (widget)) == GTK_RESPONSE_YES)
1332 {
1333 gtk_widget_hide (widget);
1334 xfce_panel_plugin_provider_emit_signal (provider, PROVIDER_SIGNAL_REMOVE_PLUGIN);
1335 }
1336
1337 gtk_widget_destroy (widget);
1338 }
1339 }
1340
1341
1342
1343 static void
panel_preferences_dialog_item_add(GtkWidget * button,PanelPreferencesDialog * dialog)1344 panel_preferences_dialog_item_add (GtkWidget *button,
1345 PanelPreferencesDialog *dialog)
1346 {
1347 panel_return_if_fail (PANEL_IS_PREFERENCES_DIALOG (dialog));
1348
1349 panel_item_dialog_show (dialog->active);
1350 }
1351
1352
1353
1354 static void
panel_preferences_dialog_item_properties(GtkWidget * button,PanelPreferencesDialog * dialog)1355 panel_preferences_dialog_item_properties (GtkWidget *button,
1356 PanelPreferencesDialog *dialog)
1357 {
1358 XfcePanelPluginProvider *provider;
1359
1360 panel_return_if_fail (PANEL_IS_PREFERENCES_DIALOG (dialog));
1361
1362 provider = panel_preferences_dialog_item_get_selected (dialog, NULL);
1363 if (G_LIKELY (provider != NULL))
1364 xfce_panel_plugin_provider_show_configure (provider);
1365 }
1366
1367
1368
1369 static void
panel_preferences_dialog_item_about(GtkWidget * button,PanelPreferencesDialog * dialog)1370 panel_preferences_dialog_item_about (GtkWidget *button,
1371 PanelPreferencesDialog *dialog)
1372 {
1373 XfcePanelPluginProvider *provider;
1374
1375 panel_return_if_fail (PANEL_IS_PREFERENCES_DIALOG (dialog));
1376
1377 provider = panel_preferences_dialog_item_get_selected (dialog, NULL);
1378 if (G_LIKELY (provider != NULL))
1379 xfce_panel_plugin_provider_show_about (provider);
1380 }
1381
1382
1383
1384 static gboolean
panel_preferences_dialog_treeview_clicked(GtkTreeView * treeview,GdkEventButton * event,PanelPreferencesDialog * dialog)1385 panel_preferences_dialog_treeview_clicked (GtkTreeView *treeview,
1386 GdkEventButton *event,
1387 PanelPreferencesDialog *dialog)
1388 {
1389 gint x, y;
1390
1391 panel_return_val_if_fail (PANEL_IS_PREFERENCES_DIALOG (dialog), FALSE);
1392 panel_return_val_if_fail (GTK_IS_TREE_VIEW (treeview), FALSE);
1393
1394 gtk_tree_view_convert_widget_to_bin_window_coords (treeview,
1395 event->x, event->y,
1396 &x, &y);
1397
1398 /* open preferences on double-click on a row */
1399 if (event->type == GDK_2BUTTON_PRESS
1400 && event->button == 1
1401 && gtk_tree_view_get_path_at_pos (treeview, x, y, NULL, NULL, NULL, NULL))
1402 {
1403 panel_preferences_dialog_item_properties (NULL, dialog);
1404 return TRUE;
1405 }
1406
1407 return FALSE;
1408 }
1409
1410
1411
1412 static void
panel_preferences_dialog_item_row_changed(GtkTreeModel * model,GtkTreePath * path,GtkTreeIter * iter,PanelPreferencesDialog * dialog)1413 panel_preferences_dialog_item_row_changed (GtkTreeModel *model,
1414 GtkTreePath *path,
1415 GtkTreeIter *iter,
1416 PanelPreferencesDialog *dialog)
1417 {
1418 XfcePanelPluginProvider *provider = NULL;
1419 gint position;
1420 GtkWidget *itembar;
1421 gint store_position;
1422
1423 panel_return_if_fail (PANEL_IS_PREFERENCES_DIALOG (dialog));
1424 panel_return_if_fail (GTK_TREE_MODEL (dialog->store) == model);
1425 panel_return_if_fail (PANEL_IS_WINDOW (dialog->active));
1426
1427 /* get the changed row */
1428 gtk_tree_model_get (model, iter, ITEM_COLUMN_PROVIDER, &provider, -1);
1429 panel_return_if_fail (XFCE_IS_PANEL_PLUGIN_PROVIDER (provider));
1430 store_position = gtk_tree_path_get_indices (path)[0];
1431
1432 /* actual position on the panel */
1433 itembar = gtk_bin_get_child (GTK_BIN (dialog->active));
1434 position = panel_itembar_get_child_index (PANEL_ITEMBAR (itembar),
1435 GTK_WIDGET (provider));
1436
1437 /* correct position in the list */
1438 if (position < store_position)
1439 store_position--;
1440
1441 /* move the item on the panel */
1442 if (position != store_position)
1443 {
1444 panel_itembar_reorder_child (PANEL_ITEMBAR (itembar),
1445 GTK_WIDGET (provider),
1446 store_position);
1447
1448 panel_application_save_window (dialog->application,
1449 dialog->active,
1450 SAVE_PLUGIN_IDS);
1451 }
1452 }
1453
1454
1455
1456 static void
panel_preferences_dialog_item_selection_changed(GtkTreeSelection * selection,PanelPreferencesDialog * dialog)1457 panel_preferences_dialog_item_selection_changed (GtkTreeSelection *selection,
1458 PanelPreferencesDialog *dialog)
1459 {
1460 XfcePanelPluginProvider *provider;
1461 GtkWidget *itembar;
1462 gint position;
1463 gint items;
1464 gboolean active;
1465 GObject *object;
1466 guint i;
1467 const gchar *button_names[] = { "item-remove", "item-up",
1468 "item-down", "item-about",
1469 "item-properties" };
1470
1471 panel_return_if_fail (PANEL_IS_PREFERENCES_DIALOG (dialog));
1472
1473 provider = panel_preferences_dialog_item_get_selected (dialog, NULL);
1474 if (G_LIKELY (provider != NULL))
1475 {
1476 /* get the current position and the items on the bar */
1477 itembar = gtk_bin_get_child (GTK_BIN (dialog->active));
1478 position = panel_itembar_get_child_index (PANEL_ITEMBAR (itembar), GTK_WIDGET (provider));
1479 items = panel_itembar_get_n_children (PANEL_ITEMBAR (itembar)) - 1;
1480
1481 /* update sensitivity of buttons */
1482 object = gtk_builder_get_object (GTK_BUILDER (dialog), "item-up");
1483 panel_return_if_fail (GTK_IS_WIDGET (object));
1484 gtk_widget_set_sensitive (GTK_WIDGET (object), !!(position > 0 && position <= items));
1485
1486 object = gtk_builder_get_object (GTK_BUILDER (dialog), "item-down");
1487 panel_return_if_fail (GTK_IS_WIDGET (object));
1488 gtk_widget_set_sensitive (GTK_WIDGET (object), !!(position >= 0 && position < items));
1489
1490 object = gtk_builder_get_object (GTK_BUILDER (dialog), "item-remove");
1491 panel_return_if_fail (GTK_IS_WIDGET (object));
1492 gtk_widget_set_sensitive (GTK_WIDGET (object), TRUE);
1493
1494 object = gtk_builder_get_object (GTK_BUILDER (dialog), "item-properties");
1495 panel_return_if_fail (GTK_IS_WIDGET (object));
1496 active = xfce_panel_plugin_provider_get_show_configure (provider);
1497 gtk_widget_set_sensitive (GTK_WIDGET (object), active);
1498
1499 object = gtk_builder_get_object (GTK_BUILDER (dialog), "item-about");
1500 panel_return_if_fail (GTK_IS_WIDGET (object));
1501 active = xfce_panel_plugin_provider_get_show_about (provider);
1502 gtk_widget_set_sensitive (GTK_WIDGET (object), active);
1503 }
1504 else
1505 {
1506 /* make all items insensitive, except for the add button */
1507 for (i = 0; i < G_N_ELEMENTS (button_names); i++)
1508 {
1509 object = gtk_builder_get_object (GTK_BUILDER (dialog), button_names[i]);
1510 panel_return_if_fail (GTK_IS_WIDGET (object));
1511 gtk_widget_set_sensitive (GTK_WIDGET (object), FALSE);
1512 }
1513 }
1514 }
1515
1516
1517
1518 static void
panel_preferences_dialog_plug_deleted(GtkWidget * plug)1519 panel_preferences_dialog_plug_deleted (GtkWidget *plug)
1520 {
1521 g_signal_handlers_disconnect_by_func (G_OBJECT (plug),
1522 G_CALLBACK (panel_preferences_dialog_plug_deleted), NULL);
1523
1524 g_object_unref (G_OBJECT (dialog_singleton));
1525 }
1526
1527
1528
1529 static void
panel_preferences_dialog_show_internal(PanelWindow * active,Window socket_window)1530 panel_preferences_dialog_show_internal (PanelWindow *active,
1531 Window socket_window)
1532 {
1533 gint panel_id = 0;
1534 GObject *window, *combo;
1535 GdkScreen *screen;
1536 GSList *windows;
1537 GtkWidget *plug;
1538 GObject *plug_child;
1539 GtkWidget *content_area;
1540
1541 panel_return_if_fail (active == NULL || PANEL_IS_WINDOW (active));
1542
1543 /* check if not the entire application is locked */
1544 if (panel_dialogs_kiosk_warning ())
1545 return;
1546
1547 if (dialog_singleton == NULL)
1548 {
1549 /* create new dialog singleton */
1550 dialog_singleton = g_object_new (PANEL_TYPE_PREFERENCES_DIALOG, NULL);
1551 g_object_add_weak_pointer (G_OBJECT (dialog_singleton), (gpointer) &dialog_singleton);
1552 }
1553
1554 if (active == NULL)
1555 {
1556 /* select first window */
1557 windows = panel_application_get_windows (dialog_singleton->application);
1558 if (windows != NULL)
1559 active = g_slist_nth_data (windows, 0);
1560 }
1561
1562 /* select the active window in the dialog */
1563 combo = gtk_builder_get_object (GTK_BUILDER (dialog_singleton), "panel-combobox");
1564 panel_return_if_fail (GTK_IS_WIDGET (combo));
1565 panel_id = panel_window_get_id (active);
1566 if (!panel_preferences_dialog_panel_combobox_rebuild (dialog_singleton, panel_id))
1567 gtk_combo_box_set_active (GTK_COMBO_BOX (combo), 0);
1568
1569 window = gtk_builder_get_object (GTK_BUILDER (dialog_singleton), "dialog");
1570 panel_return_if_fail (GTK_IS_WIDGET (window));
1571 plug_child = gtk_builder_get_object (GTK_BUILDER (dialog_singleton), "plug-child");
1572 panel_return_if_fail (GTK_IS_WIDGET (plug_child));
1573
1574 /* check if we need to remove the window from the plug */
1575 if (dialog_singleton->socket_plug != NULL)
1576 {
1577 panel_return_if_fail (GTK_IS_PLUG (dialog_singleton->socket_plug));
1578
1579 /* move the vbox to the dialog */
1580 content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
1581 xfce_widget_reparent (GTK_WIDGET (plug_child), content_area);
1582 gtk_widget_show (GTK_WIDGET (plug_child));
1583
1584 /* destroy the plug */
1585 plug = dialog_singleton->socket_plug;
1586 dialog_singleton->socket_plug = NULL;
1587
1588 g_signal_handlers_disconnect_by_func (G_OBJECT (plug),
1589 G_CALLBACK (panel_preferences_dialog_plug_deleted), NULL);
1590 gtk_widget_destroy (plug);
1591 }
1592
1593 if (socket_window == 0)
1594 {
1595 /* show the dialog on the same screen as the panel */
1596 if (G_LIKELY (active != NULL))
1597 screen = gtk_widget_get_screen (GTK_WIDGET (active));
1598 else
1599 screen = gdk_screen_get_default ();
1600 gtk_window_set_screen (GTK_WINDOW (window), screen);
1601
1602 gtk_window_present (GTK_WINDOW (window));
1603 panel_application_take_dialog (dialog_singleton->application, GTK_WINDOW (window));
1604 }
1605 else
1606 {
1607 /* hide window */
1608 gtk_widget_hide (GTK_WIDGET (window));
1609
1610 /* create a new plug */
1611 plug = gtk_plug_new (socket_window);
1612 g_signal_connect (G_OBJECT (plug), "delete-event",
1613 G_CALLBACK (panel_preferences_dialog_plug_deleted), NULL);
1614 dialog_singleton->socket_plug = plug;
1615 gtk_widget_show (plug);
1616
1617 /* move the vbox in the plug */
1618 xfce_widget_reparent (GTK_WIDGET (plug_child), plug);
1619 gtk_widget_show (GTK_WIDGET (plug_child));
1620 }
1621 }
1622
1623
1624
1625 void
panel_preferences_dialog_show(PanelWindow * active)1626 panel_preferences_dialog_show (PanelWindow *active)
1627 {
1628 panel_return_if_fail (active == NULL || PANEL_IS_WINDOW (active));
1629 panel_preferences_dialog_show_internal (active, 0);
1630 }
1631
1632
1633
1634 void
panel_preferences_dialog_show_from_id(gint panel_id,Window socket_window)1635 panel_preferences_dialog_show_from_id (gint panel_id,
1636 Window socket_window)
1637 {
1638 PanelApplication *application;
1639 PanelWindow *window;
1640
1641 application = panel_application_get ();
1642 window = panel_application_get_window (application, panel_id);
1643 panel_preferences_dialog_show_internal (window, socket_window);
1644 g_object_unref (G_OBJECT (application));
1645 }
1646
1647
1648
1649 gboolean
panel_preferences_dialog_visible(void)1650 panel_preferences_dialog_visible (void)
1651 {
1652 return !!(dialog_singleton != NULL);
1653 }
1654