~ubuntu-branches/ubuntu/breezy/gimp/breezy

« back to all changes in this revision

Viewing changes to app/dialogs/module-dialog.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2005-10-04 19:04:46 UTC
  • Revision ID: james.westby@ubuntu.com-20051004190446-ukh32kwk56s4sjhu
Tags: upstream-2.2.8
ImportĀ upstreamĀ versionĀ 2.2.8

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* The GIMP -- an image manipulation program
 
2
 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
 
3
 *
 
4
 * module-dialog.c
 
5
 * (C) 1999 Austin Donnelly <austin@gimp.org>
 
6
 *
 
7
 * This program is free software; you can redistribute it and/or modify
 
8
 * it under the terms of the GNU General Public License as published by
 
9
 * the Free Software Foundation; either version 2 of the License, or
 
10
 * (at your option) any later version.
 
11
 *
 
12
 * This program is distributed in the hope that it will be useful,
 
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
 * GNU General Public License for more details.
 
16
 *
 
17
 * You should have received a copy of the GNU General Public License
 
18
 * along with this program; if not, write to the Free Software
 
19
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
20
 */
 
21
 
 
22
#include "config.h"
 
23
 
 
24
#include <gtk/gtk.h>
 
25
 
 
26
#include "libgimpbase/gimpbase.h"
 
27
#include "libgimpmodule/gimpmodule.h"
 
28
#include "libgimpwidgets/gimpwidgets.h"
 
29
 
 
30
#include "dialogs-types.h"
 
31
 
 
32
#include "core/gimp.h"
 
33
#include "core/gimp-modules.h"
 
34
 
 
35
#include "widgets/gimphelp-ids.h"
 
36
#include "widgets/gimpviewabledialog.h"
 
37
 
 
38
#include "module-dialog.h"
 
39
 
 
40
#include "gimp-intl.h"
 
41
 
 
42
 
 
43
#define MODULES_RESPONSE_REFRESH 1
 
44
#define NUM_INFO_LINES           9
 
45
 
 
46
enum
 
47
{
 
48
  PATH_COLUMN,
 
49
  AUTO_COLUMN,
 
50
  MODULE_COLUMN,
 
51
  NUM_COLUMNS
 
52
};
 
53
 
 
54
typedef struct _ModuleDialog ModuleDialog;
 
55
 
 
56
struct _ModuleDialog
 
57
{
 
58
  Gimp         *gimp;
 
59
 
 
60
  GimpModule   *last_update;
 
61
  GtkListStore *list;
 
62
 
 
63
  GtkWidget    *table;
 
64
  GtkWidget    *label[NUM_INFO_LINES];
 
65
  GtkWidget    *button;
 
66
  GtkWidget    *button_label;
 
67
};
 
68
 
 
69
 
 
70
/*  local function prototypes  */
 
71
 
 
72
static void   dialog_response              (GtkWidget             *widget,
 
73
                                            gint                   response_id,
 
74
                                            ModuleDialog          *dialog);
 
75
static void   dialog_destroy_callback      (GtkWidget             *widget,
 
76
                                            ModuleDialog          *dialog);
 
77
static void   dialog_select_callback       (GtkTreeSelection      *sel,
 
78
                                            ModuleDialog          *dialog);
 
79
static void   dialog_autoload_toggled      (GtkCellRendererToggle *celltoggle,
 
80
                                            gchar                 *path_string,
 
81
                                            ModuleDialog          *dialog);
 
82
static void   dialog_load_unload_callback  (GtkWidget             *widget,
 
83
                                            ModuleDialog          *dialog);
 
84
static void   make_list_item               (gpointer               data,
 
85
                                            gpointer               user_data);
 
86
static void   dialog_info_add              (GimpModuleDB          *db,
 
87
                                            GimpModule            *module,
 
88
                                            ModuleDialog          *dialog);
 
89
static void   dialog_info_remove           (GimpModuleDB          *db,
 
90
                                            GimpModule            *module,
 
91
                                            ModuleDialog          *dialog);
 
92
static void   dialog_info_update           (GimpModuleDB          *db,
 
93
                                            GimpModule            *module,
 
94
                                            ModuleDialog          *dialog);
 
95
static void   dialog_info_init             (ModuleDialog          *dialog,
 
96
                                            GtkWidget             *table);
 
97
 
 
98
 
 
99
/*  public functions  */
 
100
 
 
101
GtkWidget *
 
102
module_dialog_new (Gimp *gimp)
 
103
{
 
104
  GtkWidget         *shell;
 
105
  GtkWidget         *hbox;
 
106
  GtkWidget         *vbox;
 
107
  GtkWidget         *listbox;
 
108
  GtkWidget         *tv;
 
109
  ModuleDialog      *dialog;
 
110
  GtkTreeSelection  *sel;
 
111
  GtkTreeIter        iter;
 
112
  GtkTreeViewColumn *col;
 
113
  GtkCellRenderer   *rend;
 
114
 
 
115
  g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
 
116
 
 
117
  dialog = g_new0 (ModuleDialog, 1);
 
118
 
 
119
  dialog->gimp = gimp;
 
120
 
 
121
  shell = gimp_viewable_dialog_new (NULL,
 
122
                                    _("Module Manager"), "gimp-modules",
 
123
                                    GTK_STOCK_EXECUTE,
 
124
                                    _("Manage Loadable Modules"),
 
125
                                    NULL,
 
126
                                    gimp_standard_help_func,
 
127
                                    GIMP_HELP_MODULE_DIALOG,
 
128
 
 
129
                                    GTK_STOCK_REFRESH, MODULES_RESPONSE_REFRESH,
 
130
                                    GTK_STOCK_CLOSE,   GTK_STOCK_CLOSE,
 
131
 
 
132
                                    NULL);
 
133
 
 
134
  g_signal_connect (shell, "response",
 
135
                    G_CALLBACK (dialog_response),
 
136
                    dialog);
 
137
 
 
138
  vbox = gtk_vbox_new (FALSE, 12);
 
139
  gtk_container_set_border_width (GTK_CONTAINER (vbox), 12);
 
140
  gtk_container_add (GTK_CONTAINER (GTK_DIALOG (shell)->vbox), vbox);
 
141
  gtk_widget_show (vbox);
 
142
 
 
143
  listbox = gtk_scrolled_window_new (NULL, NULL);
 
144
  gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (listbox),
 
145
                                       GTK_SHADOW_IN);
 
146
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (listbox),
 
147
                                  GTK_POLICY_AUTOMATIC,
 
148
                                  GTK_POLICY_AUTOMATIC);
 
149
  gtk_box_pack_start (GTK_BOX (vbox), listbox, TRUE, TRUE, 0);
 
150
  gtk_widget_set_size_request (listbox, 125, 100);
 
151
  gtk_widget_show (listbox);
 
152
 
 
153
  dialog->list = gtk_list_store_new (NUM_COLUMNS,
 
154
                                     G_TYPE_STRING, G_TYPE_BOOLEAN,
 
155
                                     G_TYPE_POINTER);
 
156
  tv = gtk_tree_view_new_with_model (GTK_TREE_MODEL (dialog->list));
 
157
  g_object_unref (dialog->list);
 
158
 
 
159
  g_list_foreach (gimp->module_db->modules, make_list_item, dialog);
 
160
 
 
161
  rend = gtk_cell_renderer_toggle_new ();
 
162
 
 
163
  g_signal_connect (rend, "toggled",
 
164
                    G_CALLBACK (dialog_autoload_toggled),
 
165
                    dialog);
 
166
 
 
167
  col = gtk_tree_view_column_new ();
 
168
  gtk_tree_view_column_set_title (col, _("Autoload"));
 
169
  gtk_tree_view_column_pack_start (col, rend, FALSE);
 
170
  gtk_tree_view_column_add_attribute (col, rend, "active", AUTO_COLUMN);
 
171
 
 
172
  gtk_tree_view_append_column (GTK_TREE_VIEW (tv), col);
 
173
 
 
174
  gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (tv), 1,
 
175
                                               _("Module path"),
 
176
                                               gtk_cell_renderer_text_new (),
 
177
                                               "text", PATH_COLUMN,
 
178
                                               NULL);
 
179
 
 
180
  gtk_container_add (GTK_CONTAINER (listbox), tv);
 
181
  gtk_widget_show (tv);
 
182
 
 
183
  dialog->table = gtk_table_new (2, NUM_INFO_LINES, FALSE);
 
184
  gtk_table_set_col_spacings (GTK_TABLE (dialog->table), 4);
 
185
  gtk_box_pack_start (GTK_BOX (vbox), dialog->table, FALSE, FALSE, 0);
 
186
  gtk_widget_show (dialog->table);
 
187
 
 
188
  hbox = gtk_hbutton_box_new ();
 
189
  gtk_button_box_set_layout (GTK_BUTTON_BOX (hbox), GTK_BUTTONBOX_SPREAD);
 
190
  gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
 
191
  gtk_widget_show (hbox);
 
192
 
 
193
 
 
194
  dialog->button = gtk_button_new_with_label ("");
 
195
  dialog->button_label = gtk_bin_get_child (GTK_BIN (dialog->button));
 
196
  gtk_box_pack_start (GTK_BOX (hbox), dialog->button, TRUE, TRUE, 0);
 
197
  gtk_widget_show (dialog->button);
 
198
 
 
199
  g_signal_connect (dialog->button, "clicked",
 
200
                    G_CALLBACK (dialog_load_unload_callback),
 
201
                    dialog);
 
202
 
 
203
  dialog_info_init (dialog, dialog->table);
 
204
 
 
205
  dialog_info_update (gimp->module_db, dialog->last_update, dialog);
 
206
 
 
207
  sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (tv));
 
208
 
 
209
  g_signal_connect (sel, "changed",
 
210
                    G_CALLBACK (dialog_select_callback),
 
211
                    dialog);
 
212
 
 
213
  if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (dialog->list), &iter))
 
214
    gtk_tree_selection_select_iter (sel, &iter);
 
215
 
 
216
  /* hook the GimpModuleDB signals so we can refresh the display
 
217
   * appropriately.
 
218
   */
 
219
  g_signal_connect (gimp->module_db, "add",
 
220
                    G_CALLBACK (dialog_info_add),
 
221
                    dialog);
 
222
  g_signal_connect (gimp->module_db, "remove",
 
223
                    G_CALLBACK (dialog_info_remove),
 
224
                    dialog);
 
225
  g_signal_connect (gimp->module_db, "module_modified",
 
226
                    G_CALLBACK (dialog_info_update),
 
227
                    dialog);
 
228
 
 
229
  g_signal_connect (shell, "destroy",
 
230
                    G_CALLBACK (dialog_destroy_callback),
 
231
                    dialog);
 
232
 
 
233
  return shell;
 
234
}
 
235
 
 
236
 
 
237
/*  private functions  */
 
238
 
 
239
static void
 
240
dialog_response (GtkWidget    *widget,
 
241
                 gint          response_id,
 
242
                 ModuleDialog *dialog)
 
243
{
 
244
  if (response_id == MODULES_RESPONSE_REFRESH)
 
245
    gimp_modules_refresh (dialog->gimp);
 
246
  else
 
247
    gtk_widget_destroy (widget);
 
248
}
 
249
 
 
250
static void
 
251
dialog_destroy_callback (GtkWidget    *widget,
 
252
                         ModuleDialog *dialog)
 
253
{
 
254
  g_signal_handlers_disconnect_by_func (dialog->gimp->module_db,
 
255
                                        dialog_info_add,
 
256
                                        dialog);
 
257
  g_signal_handlers_disconnect_by_func (dialog->gimp->module_db,
 
258
                                        dialog_info_remove,
 
259
                                        dialog);
 
260
  g_signal_handlers_disconnect_by_func (dialog->gimp->module_db,
 
261
                                        dialog_info_update,
 
262
                                        dialog);
 
263
 
 
264
  g_free (dialog);
 
265
}
 
266
 
 
267
static void
 
268
dialog_select_callback (GtkTreeSelection *sel,
 
269
                        ModuleDialog     *dialog)
 
270
{
 
271
  GimpModule  *module;
 
272
  GtkTreeIter  iter;
 
273
 
 
274
  gtk_tree_selection_get_selected (sel, NULL, &iter);
 
275
  gtk_tree_model_get (GTK_TREE_MODEL (dialog->list), &iter,
 
276
                      MODULE_COLUMN, &module, -1);
 
277
 
 
278
  if (dialog->last_update == module)
 
279
    return;
 
280
 
 
281
  dialog->last_update = module;
 
282
 
 
283
  dialog_info_update (dialog->gimp->module_db, dialog->last_update, dialog);
 
284
}
 
285
 
 
286
static void
 
287
dialog_autoload_toggled (GtkCellRendererToggle *celltoggle,
 
288
                         gchar                 *path_string,
 
289
                         ModuleDialog          *dialog)
 
290
{
 
291
  GtkTreePath *path;
 
292
  GtkTreeIter  iter;
 
293
  gboolean     active = FALSE;
 
294
  GimpModule  *module = NULL;
 
295
 
 
296
  path = gtk_tree_path_new_from_string (path_string);
 
297
  if (! gtk_tree_model_get_iter (GTK_TREE_MODEL (dialog->list), &iter, path))
 
298
    {
 
299
      g_warning ("%s: bad tree path?", G_STRFUNC);
 
300
      return;
 
301
    }
 
302
  gtk_tree_path_free (path);
 
303
 
 
304
  gtk_tree_model_get (GTK_TREE_MODEL (dialog->list), &iter,
 
305
                      AUTO_COLUMN,   &active,
 
306
                      MODULE_COLUMN, &module,
 
307
                      -1);
 
308
 
 
309
  if (module)
 
310
    {
 
311
      gimp_module_set_load_inhibit (module, active);
 
312
 
 
313
      dialog->gimp->write_modulerc = TRUE;
 
314
 
 
315
      gtk_list_store_set (GTK_LIST_STORE (dialog->list), &iter,
 
316
                          AUTO_COLUMN, ! active,
 
317
                          -1);
 
318
    }
 
319
}
 
320
 
 
321
static void
 
322
dialog_load_unload_callback (GtkWidget    *widget,
 
323
                             ModuleDialog *dialog)
 
324
{
 
325
  if (dialog->last_update->state != GIMP_MODULE_STATE_LOADED)
 
326
    {
 
327
      if (dialog->last_update->info)
 
328
        {
 
329
          if (g_type_module_use (G_TYPE_MODULE (dialog->last_update)))
 
330
            g_type_module_unuse (G_TYPE_MODULE (dialog->last_update));
 
331
        }
 
332
      else
 
333
        {
 
334
          gimp_module_query_module (dialog->last_update);
 
335
        }
 
336
    }
 
337
 
 
338
  gimp_module_modified (dialog->last_update);
 
339
}
 
340
 
 
341
static void
 
342
make_list_item (gpointer data,
 
343
                gpointer user_data)
 
344
{
 
345
  GimpModule   *module  = data;
 
346
  ModuleDialog *dialog = user_data;
 
347
  GtkTreeIter   iter;
 
348
 
 
349
  if (! dialog->last_update)
 
350
    dialog->last_update = module;
 
351
 
 
352
  gtk_list_store_append (dialog->list, &iter);
 
353
  gtk_list_store_set (dialog->list, &iter,
 
354
                      PATH_COLUMN, module->filename,
 
355
                      AUTO_COLUMN, ! module->load_inhibit,
 
356
                      MODULE_COLUMN, module,
 
357
                      -1);
 
358
}
 
359
 
 
360
static void
 
361
dialog_info_add (GimpModuleDB *db,
 
362
                 GimpModule   *module,
 
363
                 ModuleDialog *dialog)
 
364
{
 
365
  make_list_item (module, dialog);
 
366
}
 
367
 
 
368
static void
 
369
dialog_info_remove (GimpModuleDB *db,
 
370
                    GimpModule   *mod,
 
371
                    ModuleDialog *dialog)
 
372
{
 
373
  GtkTreeIter  iter;
 
374
  GimpModule  *module;
 
375
 
 
376
  /* FIXME: Use gtk_list_store_foreach_remove when it becomes available */
 
377
 
 
378
  if (! gtk_tree_model_get_iter_first (GTK_TREE_MODEL (dialog->list), &iter))
 
379
    return;
 
380
 
 
381
  do
 
382
    {
 
383
      gtk_tree_model_get (GTK_TREE_MODEL (dialog->list), &iter,
 
384
                          MODULE_COLUMN, &module,
 
385
                          -1);
 
386
 
 
387
      if (module == mod)
 
388
        {
 
389
          gtk_list_store_remove (dialog->list, &iter);
 
390
          return;
 
391
        }
 
392
    }
 
393
  while (gtk_tree_model_iter_next (GTK_TREE_MODEL (dialog->list), &iter));
 
394
 
 
395
  g_warning ("%s: Tried to remove a module not in the dialog's list.",
 
396
             G_STRFUNC);
 
397
}
 
398
 
 
399
static void
 
400
dialog_info_update (GimpModuleDB *db,
 
401
                    GimpModule   *module,
 
402
                    ModuleDialog *dialog)
 
403
{
 
404
  GTypeModule *g_type_module;
 
405
  const gchar *text[NUM_INFO_LINES];
 
406
  gint         i;
 
407
 
 
408
  g_type_module = G_TYPE_MODULE (module);
 
409
 
 
410
  /* only update the info if we're actually showing it */
 
411
  if (module != dialog->last_update)
 
412
    return;
 
413
 
 
414
  if (! module)
 
415
    {
 
416
      for (i = 0; i < NUM_INFO_LINES; i++)
 
417
        gtk_label_set_text (GTK_LABEL (dialog->label[i]), "");
 
418
      gtk_label_set_text (GTK_LABEL (dialog->button_label), _("<No modules>"));
 
419
      gtk_widget_set_sensitive (GTK_WIDGET (dialog->button), FALSE);
 
420
      return;
 
421
    }
 
422
 
 
423
  if (module->info)
 
424
    {
 
425
      text[0] = module->info->purpose;
 
426
      text[1] = module->info->author;
 
427
      text[2] = module->info->version;
 
428
      text[3] = module->info->copyright;
 
429
      text[4] = module->info->date;
 
430
      text[5] = module->on_disk ? _("On disk") : _("Only in memory");
 
431
    }
 
432
  else
 
433
    {
 
434
      text[0] = "--";
 
435
      text[1] = "--";
 
436
      text[2] = "--";
 
437
      text[3] = "--";
 
438
      text[4] = "--";
 
439
      text[5] = module->on_disk ? _("On disk") : _("No longer available");
 
440
    }
 
441
 
 
442
  text[6] = gimp_module_state_name (module->state);
 
443
 
 
444
  if (module->state == GIMP_MODULE_STATE_ERROR && module->last_module_error)
 
445
    text[7] = module->last_module_error;
 
446
  else
 
447
    text[7] = "--";
 
448
 
 
449
  if (g_type_module->type_infos || g_type_module->interface_infos)
 
450
    {
 
451
      gchar *str;
 
452
 
 
453
      str = g_strdup_printf ("%d Types, %d Interfaces",
 
454
                             g_slist_length (g_type_module->type_infos),
 
455
                             g_slist_length (g_type_module->interface_infos));
 
456
      gtk_label_set_text (GTK_LABEL (dialog->label[NUM_INFO_LINES - 1]), str);
 
457
      g_free (str);
 
458
    }
 
459
  else
 
460
    {
 
461
      gtk_label_set_text (GTK_LABEL (dialog->label[NUM_INFO_LINES - 1]),
 
462
                          "---");
 
463
    }
 
464
 
 
465
  for (i = 0; i < NUM_INFO_LINES - 1; i++)
 
466
    gtk_label_set_text (GTK_LABEL (dialog->label[i]), gettext (text[i]));
 
467
 
 
468
  /* work out what the button should do (if anything) */
 
469
  switch (module->state)
 
470
    {
 
471
    case GIMP_MODULE_STATE_ERROR:
 
472
    case GIMP_MODULE_STATE_LOAD_FAILED:
 
473
    case GIMP_MODULE_STATE_NOT_LOADED:
 
474
      if (module->info)
 
475
        gtk_label_set_text (GTK_LABEL (dialog->button_label), _("Load"));
 
476
      else
 
477
        gtk_label_set_text (GTK_LABEL (dialog->button_label), _("Query"));
 
478
 
 
479
      gtk_widget_set_sensitive (GTK_WIDGET (dialog->button),
 
480
                                module->on_disk);
 
481
      break;
 
482
 
 
483
    case GIMP_MODULE_STATE_LOADED:
 
484
      gtk_label_set_text (GTK_LABEL (dialog->button_label), _("Unload"));
 
485
      gtk_widget_set_sensitive (GTK_WIDGET (dialog->button), FALSE);
 
486
      break;
 
487
    }
 
488
}
 
489
 
 
490
static void
 
491
dialog_info_init (ModuleDialog *dialog,
 
492
                  GtkWidget    *table)
 
493
{
 
494
  GtkWidget *label;
 
495
  gint       i;
 
496
 
 
497
  static const gchar * const text[] =
 
498
  {
 
499
    N_("Purpose:"),
 
500
    N_("Author:"),
 
501
    N_("Version:"),
 
502
    N_("Copyright:"),
 
503
    N_("Date:"),
 
504
    N_("Location:"),
 
505
    N_("State:"),
 
506
    N_("Last Error:"),
 
507
    N_("Available Types:")
 
508
  };
 
509
 
 
510
  for (i = 0; i < G_N_ELEMENTS (text); i++)
 
511
    {
 
512
      label = gtk_label_new (gettext (text[i]));
 
513
      gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
 
514
      gtk_table_attach (GTK_TABLE (table), label, 0, 1, i, i + 1,
 
515
                        GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 2);
 
516
      gtk_widget_show (label);
 
517
 
 
518
      dialog->label[i] = gtk_label_new ("");
 
519
      gtk_misc_set_alignment (GTK_MISC (dialog->label[i]), 0.0, 0.5);
 
520
      gtk_table_attach (GTK_TABLE (dialog->table), dialog->label[i],
 
521
                        1, 2, i, i + 1,
 
522
                        GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 2);
 
523
      gtk_widget_show (dialog->label[i]);
 
524
    }
 
525
}