~ubuntu-branches/ubuntu/wily/xfce4-panel/wily

« back to all changes in this revision

Viewing changes to .pc/xubuntu_xfpanel-switch-integration.patch/panel/panel-preferences-dialog.c

  • Committer: Package Import Robot
  • Author(s): Sean Davis
  • Date: 2015-08-31 06:43:04 UTC
  • Revision ID: package-import@ubuntu.com-20150831064304-l4c4ezngm8vbwdl1
Tags: 4.12.0-3ubuntu2
* debian/patches/xubuntu_xfpanel-switch-integration.patch:
  - Include patch to add integration with xfpanel-switch

Show diffs side-by-side

added added

removed removed

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