~ubuntu-branches/ubuntu/maverick/gimp/maverick-updates

« back to all changes in this revision

Viewing changes to plug-ins/dbbrowser/plugin-browser.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Holbach
  • Date: 2005-12-09 19:44:52 UTC
  • Revision ID: james.westby@ubuntu.com-20051209194452-yggpemjlofpjqyf4
Tags: upstream-2.2.9
ImportĀ upstreamĀ versionĀ 2.2.9

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
 
3
 *
 
4
 * This is a plug-in for the GIMP.
 
5
 *
 
6
 * Copyright (C) 1999 Andy Thomas  alt@picnic.demon.co.uk
 
7
 *
 
8
 * Note some portions of the UI comes from the dbbrowser plugin.
 
9
 * This program is free software; you can redistribute it and/or modify
 
10
 * it under the terms of the GNU General Public License as published by
 
11
 * the Free Software Foundation; either version 2 of the License, or
 
12
 * (at your option) any later version.
 
13
 *
 
14
 * This program is distributed in the hope that it will be useful,
 
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
17
 * GNU General Public License for more details.
 
18
 *
 
19
 * You should have received a copy of the GNU General Public License
 
20
 * along with this program; if not, write to the Free Software
 
21
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
22
 */
 
23
 
 
24
#include "config.h"
 
25
 
 
26
#include <stdlib.h>
 
27
#include <stdio.h>
 
28
#include <string.h>
 
29
#include <time.h>
 
30
 
 
31
#include <gtk/gtk.h>
 
32
 
 
33
#include <libgimp/gimp.h>
 
34
#include <libgimp/gimpui.h>
 
35
 
 
36
#include "gimpprocbox.h"
 
37
#include "gimpprocview.h"
 
38
 
 
39
#include "libgimp/stdplugins-intl.h"
 
40
 
 
41
 
 
42
enum
 
43
{
 
44
  LIST_NAME_COLUMN,
 
45
  LIST_DATE_COLUMN,
 
46
  LIST_PATH_COLUMN,
 
47
  LIST_IMAGE_TYPES_COLUMN,
 
48
  LIST_PINFO_COLUMN,
 
49
  LIST_N_COLUMNS
 
50
};
 
51
 
 
52
enum
 
53
{
 
54
  TREE_PATH_NAME_COLUMN,
 
55
  TREE_DATE_COLUMN,
 
56
  TREE_IMAGE_TYPES_COLUMN,
 
57
  TREE_MPATH_COLUMN,
 
58
  TREE_PINFO_COLUMN,
 
59
  TREE_N_COLUMNS
 
60
};
 
61
 
 
62
#define DBL_LIST_WIDTH  250
 
63
#define DBL_WIDTH       (DBL_LIST_WIDTH + 400)
 
64
#define DBL_HEIGHT      250
 
65
 
 
66
typedef struct
 
67
{
 
68
  GtkWidget   *dialog;
 
69
 
 
70
  GtkTreeView *list_view;
 
71
  GtkTreeView *tree_view;
 
72
 
 
73
  GtkWidget   *count_label;
 
74
  GtkWidget   *search_entry;
 
75
  GtkWidget   *proc_box;
 
76
 
 
77
  gint         num_plugins;
 
78
} PluginBrowser;
 
79
 
 
80
typedef struct
 
81
{
 
82
  gchar *menu;
 
83
  gchar *accel;
 
84
  gchar *prog;
 
85
  gchar *types;
 
86
  gchar *realname;
 
87
  gint  instime;
 
88
} PInfo;
 
89
 
 
90
 
 
91
/* Declare some local functions.
 
92
 */
 
93
static void   query      (void);
 
94
static void   run        (const gchar      *name,
 
95
                          gint              nparams,
 
96
                          const GimpParam  *param,
 
97
                          gint             *nreturn_vals,
 
98
                          GimpParam       **return_vals);
 
99
 
 
100
 
 
101
static GtkWidget * browser_dialog_new             (void);
 
102
static void        browser_dialog_response        (GtkWidget        *widget,
 
103
                                                   gint              response_id,
 
104
                                                   PluginBrowser    *browser);
 
105
static void        browser_list_selection_changed (GtkTreeSelection *selection,
 
106
                                                   PluginBrowser    *browser);
 
107
static void        browser_tree_selection_changed (GtkTreeSelection *selection,
 
108
                                                   PluginBrowser    *browser);
 
109
static void        browser_show_plugin            (PluginBrowser    *browser,
 
110
                                                   PInfo            *pinfo);
 
111
 
 
112
static gboolean    find_existing_mpath            (GtkTreeModel     *model,
 
113
                                                   gchar            *mpath,
 
114
                                                   GtkTreeIter      *return_iter);
 
115
 
 
116
 
 
117
 
 
118
static PluginBrowser *browser = NULL;
 
119
 
 
120
GimpPlugInInfo PLUG_IN_INFO =
 
121
{
 
122
  NULL,  /* init_proc  */
 
123
  NULL,  /* quit_proc  */
 
124
  query, /* query_proc */
 
125
  run,   /* run_proc   */
 
126
};
 
127
 
 
128
 
 
129
MAIN ()
 
130
 
 
131
 
 
132
static void
 
133
query (void)
 
134
{
 
135
  static GimpParamDef args[] =
 
136
  {
 
137
    { GIMP_PDB_INT32, "run_mode", "Interactive, [non-interactive]" }
 
138
  };
 
139
 
 
140
  gimp_install_procedure ("plug_in_plug_in_details",
 
141
                          "Displays plug-in details",
 
142
                          "Allows to browse the plug-in menus system. You can "
 
143
                          "search for plug-in names, sort by name or menu "
 
144
                          "location and you can view a tree representation "
 
145
                          "of the plug-in menus. Can also be of help to find "
 
146
                          "where new plug-ins have installed themselves in "
 
147
                          "the menus.",
 
148
                          "Andy Thomas",
 
149
                          "Andy Thomas",
 
150
                          "1999",
 
151
                          N_("_Plug-In Browser"),
 
152
                          "",
 
153
                          GIMP_PLUGIN,
 
154
                          G_N_ELEMENTS (args), 0,
 
155
                          args, NULL);
 
156
 
 
157
  gimp_plugin_menu_register ("plug_in_plug_in_details",
 
158
                             "<Toolbox>/Xtns/Extensions");
 
159
  gimp_plugin_icon_register ("plug_in_plug_in_details",
 
160
                             GIMP_ICON_TYPE_STOCK_ID, GIMP_STOCK_PLUGIN);
 
161
}
 
162
 
 
163
static void
 
164
run (const gchar      *name,
 
165
     gint              nparams,
 
166
     const GimpParam  *param,
 
167
     gint             *nreturn_vals,
 
168
     GimpParam       **return_vals)
 
169
{
 
170
  static GimpParam  values[2];
 
171
  GimpRunMode       run_mode;
 
172
 
 
173
  run_mode = param[0].data.d_int32;
 
174
 
 
175
  *nreturn_vals = 1;
 
176
  *return_vals  = values;
 
177
 
 
178
  values[0].type          = GIMP_PDB_STATUS;
 
179
  values[0].data.d_status = GIMP_PDB_CALLING_ERROR;
 
180
 
 
181
  INIT_I18N ();
 
182
 
 
183
  if (strcmp (name, "plug_in_plug_in_details") == 0)
 
184
    {
 
185
      GtkWidget *plugin_dialog;
 
186
 
 
187
      *nreturn_vals = 1;
 
188
 
 
189
      values[0].data.d_status = GIMP_PDB_SUCCESS;
 
190
 
 
191
      plugin_dialog = browser_dialog_new ();
 
192
 
 
193
      gtk_main ();
 
194
    }
 
195
}
 
196
 
 
197
#if 0
 
198
static void
 
199
pinfo_free (gpointer p)
 
200
{
 
201
  PInfo *pinfo = p;
 
202
 
 
203
  g_free (pinfo->menu);
 
204
  g_free (pinfo->accel);
 
205
  g_free (pinfo->prog);
 
206
  g_free (pinfo->types);
 
207
  g_free (pinfo->realname);
 
208
  g_free (pinfo);
 
209
}
 
210
#endif
 
211
 
 
212
static gboolean
 
213
find_existing_mpath_helper (GtkTreeModel *model,
 
214
                            GtkTreeIter  *iter,
 
215
                            GtkTreePath  *path,
 
216
                            gchar        *mpath,
 
217
                            GtkTreeIter  *return_iter)
 
218
{
 
219
  do
 
220
    {
 
221
      GtkTreeIter  child;
 
222
      gchar       *picked_mpath;
 
223
 
 
224
      gtk_tree_model_get (model, iter,
 
225
                          TREE_MPATH_COLUMN, &picked_mpath,
 
226
                          -1);
 
227
 
 
228
      if (! strcmp (mpath, picked_mpath))
 
229
        {
 
230
          *return_iter = *iter;
 
231
          g_free (picked_mpath);
 
232
          return TRUE;
 
233
        }
 
234
 
 
235
      if (gtk_tree_model_iter_children (model, &child, iter))
 
236
        {
 
237
          gtk_tree_path_down (path);
 
238
 
 
239
          if (find_existing_mpath_helper (model, &child, path,
 
240
                                          mpath, return_iter))
 
241
            {
 
242
              g_free (picked_mpath);
 
243
              return TRUE;
 
244
            }
 
245
 
 
246
          gtk_tree_path_up (path);
 
247
        }
 
248
 
 
249
      gtk_tree_path_next (path);
 
250
      g_free (picked_mpath);
 
251
    }
 
252
  while (gtk_tree_model_iter_next (model, iter));
 
253
 
 
254
  return FALSE;
 
255
}
 
256
 
 
257
static gboolean
 
258
find_existing_mpath (GtkTreeModel *model,
 
259
                     gchar        *mpath,
 
260
                     GtkTreeIter  *return_iter)
 
261
{
 
262
  GtkTreePath *path;
 
263
  GtkTreeIter  parent;
 
264
 
 
265
  path = gtk_tree_path_new_first ();
 
266
 
 
267
  if (gtk_tree_model_get_iter (model, &parent, path) == FALSE)
 
268
    {
 
269
      gtk_tree_path_free (path);
 
270
      return FALSE;
 
271
    }
 
272
 
 
273
  return find_existing_mpath_helper (model, &parent, path,
 
274
                                     mpath, return_iter);
 
275
  gtk_tree_path_free (path);
 
276
}
 
277
 
 
278
static void
 
279
get_parent (PluginBrowser *browser,
 
280
            gchar         *mpath,
 
281
            GtkTreeIter   *parent)
 
282
{
 
283
  GtkTreeIter   last_parent;
 
284
  gchar        *tmp_ptr;
 
285
  gchar        *str_ptr;
 
286
  gchar        *leaf_ptr;
 
287
  GtkTreeStore *tree_store;
 
288
 
 
289
  if (mpath == NULL)
 
290
    return;
 
291
 
 
292
  tree_store = GTK_TREE_STORE (gtk_tree_view_get_model (browser->tree_view));
 
293
 
 
294
  /* Lookup for existing mpath */
 
295
  if (find_existing_mpath (GTK_TREE_MODEL (tree_store), mpath, parent))
 
296
    return;
 
297
 
 
298
  /* Next one up */
 
299
  tmp_ptr = g_strdup (mpath);
 
300
 
 
301
  str_ptr = strrchr (tmp_ptr,'/');
 
302
 
 
303
  if (str_ptr == NULL)
 
304
    {
 
305
      leaf_ptr = mpath;
 
306
      gtk_tree_store_append (tree_store, parent, NULL);
 
307
      gtk_tree_store_set (tree_store, parent,
 
308
                          TREE_MPATH_COLUMN, mpath,
 
309
                          TREE_PATH_NAME_COLUMN, mpath,
 
310
                          -1);
 
311
    }
 
312
  else
 
313
    {
 
314
      leaf_ptr = g_strdup(str_ptr+1);
 
315
 
 
316
      *str_ptr = '\000';
 
317
 
 
318
      get_parent (browser, tmp_ptr, &last_parent);
 
319
      gtk_tree_store_append (tree_store, parent, &last_parent);
 
320
      gtk_tree_store_set (tree_store, parent,
 
321
                          TREE_MPATH_COLUMN, mpath,
 
322
                          TREE_PATH_NAME_COLUMN, leaf_ptr,
 
323
                          -1);
 
324
    }
 
325
}
 
326
 
 
327
static void
 
328
insert_into_tree_view (PluginBrowser *browser,
 
329
                       gchar         *name,
 
330
                       gchar         *xtimestr,
 
331
                       gchar         *menu_str,
 
332
                       gchar         *types_str,
 
333
                       PInfo         *pinfo)
 
334
{
 
335
  gchar        *labels[3];
 
336
  gchar        *str_ptr;
 
337
  gchar        *tmp_ptr;
 
338
  gchar        *leaf_ptr;
 
339
  GtkTreeIter   parent, iter;
 
340
  GtkTreeStore *tree_store;
 
341
 
 
342
  /* Find all nodes */
 
343
  /* Last one is the leaf part */
 
344
 
 
345
  tmp_ptr = g_strdup (menu_str);
 
346
 
 
347
  str_ptr = strrchr (tmp_ptr, '/');
 
348
 
 
349
  if (str_ptr == NULL)
 
350
    return; /* No node */
 
351
 
 
352
  leaf_ptr = g_strdup (str_ptr + 1);
 
353
 
 
354
  *str_ptr = '\000';
 
355
 
 
356
  /*   printf("inserting %s...\n",menu_str); */
 
357
 
 
358
  get_parent (browser, tmp_ptr, &parent);
 
359
 
 
360
  /* Last was a leaf */
 
361
  /*   printf("found leaf %s parent = %p\n",leaf_ptr,parent); */
 
362
  labels[0] = g_strdup (name);
 
363
  labels[1] = g_strdup (xtimestr);
 
364
  labels[2] = g_strdup (types_str);
 
365
 
 
366
  tree_store = GTK_TREE_STORE (gtk_tree_view_get_model (browser->tree_view));
 
367
  gtk_tree_store_append (tree_store, &iter, &parent);
 
368
  gtk_tree_store_set (tree_store, &iter,
 
369
                      TREE_MPATH_COLUMN,       menu_str,
 
370
                      TREE_PATH_NAME_COLUMN,   name,
 
371
                      TREE_IMAGE_TYPES_COLUMN, types_str,
 
372
                      TREE_DATE_COLUMN,        xtimestr,
 
373
                      TREE_PINFO_COLUMN,       pinfo,
 
374
                      -1);
 
375
}
 
376
 
 
377
static void
 
378
get_plugin_info (PluginBrowser *browser,
 
379
                 const gchar   *search_text)
 
380
{
 
381
  GimpParam    *return_vals;
 
382
  gint          nreturn_vals;
 
383
  gchar       **menu_strs;
 
384
  gchar       **accel_strs;
 
385
  gchar       **prog_strs;
 
386
  gchar       **types_strs;
 
387
  gchar       **realname_strs;
 
388
  gint         *time_ints;
 
389
  GtkListStore *list_store;
 
390
  GtkTreeStore *tree_store;
 
391
  GtkTreeIter   iter;
 
392
 
 
393
  if (! search_text)
 
394
    search_text = "";
 
395
 
 
396
  gimp_proc_box_show_message (browser->proc_box,
 
397
                              _("Searching by name - please wait"));
 
398
 
 
399
  return_vals = gimp_run_procedure ("gimp_plugins_query",
 
400
                                    &nreturn_vals,
 
401
                                    GIMP_PDB_STRING, search_text,
 
402
                                    GIMP_PDB_END);
 
403
 
 
404
  if (return_vals[0].data.d_status == GIMP_PDB_SUCCESS)
 
405
    {
 
406
      gchar *str;
 
407
      gint   loop;
 
408
 
 
409
      browser->num_plugins = return_vals[1].data.d_int32;
 
410
      menu_strs            = return_vals[2].data.d_stringarray;
 
411
      accel_strs           = return_vals[4].data.d_stringarray;
 
412
      prog_strs            = return_vals[6].data.d_stringarray;
 
413
      types_strs           = return_vals[8].data.d_stringarray;
 
414
      time_ints            = return_vals[10].data.d_int32array;
 
415
      realname_strs        = return_vals[12].data.d_stringarray;
 
416
 
 
417
      if (browser->num_plugins == 1)
 
418
        str = g_strdup (_("1 Plug-In Interface"));
 
419
      else
 
420
        str = g_strdup_printf (_("%d Plug-In Interfaces"),
 
421
                               browser->num_plugins);
 
422
 
 
423
      gtk_label_set_text (GTK_LABEL (browser->count_label), str);
 
424
      g_free (str);
 
425
 
 
426
      list_store = GTK_LIST_STORE (gtk_tree_view_get_model (browser->list_view));
 
427
      gtk_list_store_clear (list_store);
 
428
 
 
429
      tree_store = GTK_TREE_STORE (gtk_tree_view_get_model (browser->tree_view));
 
430
      gtk_tree_store_clear (tree_store);
 
431
 
 
432
      for (loop = 0; loop < return_vals[1].data.d_int32; loop++)
 
433
        {
 
434
          PInfo     *pinfo;
 
435
          gchar     *name;
 
436
          gchar      xtimestr[50];
 
437
          struct tm *x;
 
438
          time_t     tx;
 
439
          int        ret;
 
440
 
 
441
          name = strrchr (menu_strs[loop], '/');
 
442
 
 
443
          if (name)
 
444
            name = name + 1;
 
445
          else
 
446
            name = menu_strs[loop];
 
447
 
 
448
          pinfo = g_new0 (PInfo, 1);
 
449
 
 
450
          tx = time_ints[loop];
 
451
          if (tx)
 
452
            {
 
453
              const gchar *format = "%c";  /* gcc workaround to avoid warning */
 
454
              gchar       *utf8;
 
455
 
 
456
              x = localtime (&tx);
 
457
              ret = strftime (xtimestr, sizeof (xtimestr), format, x);
 
458
              xtimestr[ret] = 0;
 
459
 
 
460
              if ((utf8 = g_locale_to_utf8 (xtimestr, -1, NULL, NULL, NULL)))
 
461
                {
 
462
                  strncpy (xtimestr, utf8, sizeof (xtimestr));
 
463
                  xtimestr[sizeof (xtimestr) - 1] = 0;
 
464
                  g_free (utf8);
 
465
                }
 
466
            }
 
467
          else
 
468
            strcpy (xtimestr,"");
 
469
 
 
470
          pinfo->menu     = g_strdup (menu_strs[loop]);
 
471
          pinfo->accel    = g_strdup (accel_strs[loop]);
 
472
          pinfo->prog     = g_strdup (prog_strs[loop]);
 
473
          pinfo->types    = g_strdup (types_strs[loop]);
 
474
          pinfo->instime  = time_ints[loop];
 
475
          pinfo->realname = g_strdup (realname_strs[loop]);
 
476
 
 
477
          gtk_list_store_append (list_store, &iter);
 
478
          gtk_list_store_set (list_store, &iter,
 
479
                              LIST_NAME_COLUMN,        name,
 
480
                              LIST_DATE_COLUMN,        xtimestr,
 
481
                              LIST_PATH_COLUMN,        menu_strs[loop],
 
482
                              LIST_IMAGE_TYPES_COLUMN, types_strs[loop],
 
483
                              LIST_PINFO_COLUMN,       pinfo,
 
484
                              -1);
 
485
 
 
486
          /* Now do the tree view.... */
 
487
          insert_into_tree_view (browser,
 
488
                                 name,
 
489
                                 xtimestr,
 
490
                                 menu_strs[loop],
 
491
                                 types_strs[loop],
 
492
                                 pinfo);
 
493
        }
 
494
 
 
495
      gtk_tree_view_columns_autosize (GTK_TREE_VIEW (browser->list_view));
 
496
      gtk_tree_view_columns_autosize (GTK_TREE_VIEW (browser->tree_view));
 
497
 
 
498
      gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (list_store),
 
499
                                            LIST_NAME_COLUMN,
 
500
                                            GTK_SORT_ASCENDING);
 
501
      gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (tree_store),
 
502
                                            TREE_PATH_NAME_COLUMN,
 
503
                                            GTK_SORT_ASCENDING);
 
504
 
 
505
      if (browser->num_plugins)
 
506
        {
 
507
          GtkTreeSelection *sel =
 
508
            gtk_tree_view_get_selection (GTK_TREE_VIEW (browser->list_view));
 
509
 
 
510
          gtk_tree_model_get_iter_first (GTK_TREE_MODEL (list_store),
 
511
                                         &iter);
 
512
          gtk_tree_selection_select_iter (sel, &iter);
 
513
        }
 
514
      else
 
515
        {
 
516
          gimp_proc_box_show_message (browser->proc_box, _("No matches"));
 
517
        }
 
518
    }
 
519
 
 
520
  gimp_destroy_params (return_vals, nreturn_vals);
 
521
}
 
522
 
 
523
static GtkWidget *
 
524
browser_dialog_new (void)
 
525
{
 
526
  GtkWidget         *paned;
 
527
  GtkWidget         *hbox, *vbox;
 
528
  GtkWidget         *label, *notebook, *swindow;
 
529
  GtkListStore      *list_store;
 
530
  GtkTreeStore      *tree_store;
 
531
  GtkWidget         *list_view;
 
532
  GtkWidget         *tree_view;
 
533
  GtkTreeViewColumn *column;
 
534
  GtkCellRenderer   *renderer;
 
535
  GtkTreeSelection  *selection;
 
536
  GtkTreeIter        iter;
 
537
 
 
538
  gimp_ui_init ("plugindetails", FALSE);
 
539
 
 
540
  browser = g_new0 (PluginBrowser, 1);
 
541
 
 
542
  /* the dialog box */
 
543
  browser->dialog =
 
544
    gimp_dialog_new (_("Plug-In Browser"), "plugindetails",
 
545
                     NULL, 0,
 
546
                     gimp_standard_help_func, "plug-in-plug-in-details",
 
547
 
 
548
                     _("Search by _Name"), GTK_RESPONSE_OK,
 
549
                     GTK_STOCK_CLOSE,      GTK_RESPONSE_CLOSE,
 
550
 
 
551
                     NULL);
 
552
 
 
553
  g_signal_connect (browser->dialog, "response",
 
554
                    G_CALLBACK (browser_dialog_response),
 
555
                    browser);
 
556
 
 
557
  /* paned : left=notebook ; right=description */
 
558
 
 
559
  paned = gtk_hpaned_new ();
 
560
  gtk_container_set_border_width (GTK_CONTAINER (paned), 12);
 
561
  gtk_container_add (GTK_CONTAINER (GTK_DIALOG (browser->dialog)->vbox),
 
562
                     paned);
 
563
  gtk_widget_show (paned);
 
564
 
 
565
  /* left = vbox : the list and the search entry */
 
566
 
 
567
  vbox = gtk_vbox_new (FALSE, 6);
 
568
  gtk_paned_pack1 (GTK_PANED (paned), vbox, FALSE, TRUE);
 
569
  gtk_widget_show (vbox);
 
570
 
 
571
  browser->count_label = gtk_label_new ("0 Plug-In Interfaces");
 
572
  gtk_misc_set_alignment (GTK_MISC (browser->count_label), 0.0, 0.5);
 
573
  gtk_box_pack_start (GTK_BOX (vbox), browser->count_label, FALSE, FALSE, 0);
 
574
  gtk_widget_show (browser->count_label);
 
575
 
 
576
  /* left = notebook */
 
577
 
 
578
  notebook = gtk_notebook_new ();
 
579
  gtk_box_pack_start (GTK_BOX (vbox), notebook, TRUE, TRUE, 0);
 
580
 
 
581
  /* list : list in a scrolled_win */
 
582
  list_store = gtk_list_store_new (LIST_N_COLUMNS,
 
583
                                   G_TYPE_STRING,
 
584
                                   G_TYPE_STRING,
 
585
                                   G_TYPE_STRING,
 
586
                                   G_TYPE_STRING,
 
587
                                   G_TYPE_POINTER);
 
588
 
 
589
  list_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (list_store));
 
590
  g_object_unref (list_store);
 
591
 
 
592
  browser->list_view = GTK_TREE_VIEW (list_view);
 
593
 
 
594
  renderer = gtk_cell_renderer_text_new ();
 
595
  column = gtk_tree_view_column_new_with_attributes (_("Name"),
 
596
                                                     renderer,
 
597
                                                     "text", LIST_NAME_COLUMN,
 
598
                                                     NULL);
 
599
  gtk_tree_view_column_set_sort_column_id  (column, LIST_NAME_COLUMN);
 
600
  gtk_tree_view_append_column (GTK_TREE_VIEW (list_view), column);
 
601
 
 
602
  renderer = gtk_cell_renderer_text_new ();
 
603
  column = gtk_tree_view_column_new_with_attributes (_("Insertion Date"),
 
604
                                                     renderer,
 
605
                                                     "text", LIST_DATE_COLUMN,
 
606
                                                     NULL);
 
607
  gtk_tree_view_column_set_sort_column_id  (column, LIST_DATE_COLUMN);
 
608
  gtk_tree_view_append_column (GTK_TREE_VIEW (list_view), column);
 
609
 
 
610
  renderer = gtk_cell_renderer_text_new ();
 
611
  column = gtk_tree_view_column_new_with_attributes (_("Menu Path"),
 
612
                                                     renderer,
 
613
                                                     "text", LIST_PATH_COLUMN,
 
614
                                                     NULL);
 
615
  gtk_tree_view_column_set_sort_column_id  (column, LIST_PATH_COLUMN);
 
616
  gtk_tree_view_append_column (GTK_TREE_VIEW (list_view), column);
 
617
 
 
618
  renderer = gtk_cell_renderer_text_new ();
 
619
  column = gtk_tree_view_column_new_with_attributes (_("Image Types"),
 
620
                                                     renderer,
 
621
                                                     "text",
 
622
                                                     LIST_IMAGE_TYPES_COLUMN,
 
623
                                                     NULL);
 
624
  gtk_tree_view_column_set_sort_column_id  (column, LIST_IMAGE_TYPES_COLUMN);
 
625
  gtk_tree_view_append_column (GTK_TREE_VIEW (list_view), column);
 
626
 
 
627
  swindow = gtk_scrolled_window_new (NULL, NULL);
 
628
  gtk_container_set_border_width (GTK_CONTAINER (swindow), 2);
 
629
  gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (swindow),
 
630
                                       GTK_SHADOW_IN);
 
631
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swindow),
 
632
                                  GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
 
633
 
 
634
  gtk_widget_set_size_request (list_view, DBL_LIST_WIDTH, DBL_HEIGHT);
 
635
 
 
636
  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (list_view));
 
637
  gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE);
 
638
 
 
639
  g_signal_connect (selection, "changed",
 
640
                    G_CALLBACK (browser_list_selection_changed),
 
641
                    browser);
 
642
 
 
643
  label = gtk_label_new (_("List View"));
 
644
  gtk_notebook_append_page (GTK_NOTEBOOK (notebook), swindow, label);
 
645
  gtk_container_add (GTK_CONTAINER (swindow), list_view);
 
646
  gtk_widget_show (list_view);
 
647
  gtk_widget_show (swindow);
 
648
 
 
649
  /* notebook->ctree */
 
650
  tree_store = gtk_tree_store_new (LIST_N_COLUMNS,
 
651
                                   G_TYPE_STRING,
 
652
                                   G_TYPE_STRING,
 
653
                                   G_TYPE_STRING,
 
654
                                   G_TYPE_STRING,
 
655
                                   G_TYPE_POINTER);
 
656
 
 
657
  tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (tree_store));
 
658
  g_object_unref (tree_store);
 
659
 
 
660
  browser->tree_view = GTK_TREE_VIEW (tree_view);
 
661
 
 
662
  renderer = gtk_cell_renderer_text_new ();
 
663
  column = gtk_tree_view_column_new_with_attributes (_("Menu Path/Name"),
 
664
                                                     renderer,
 
665
                                                     "text",
 
666
                                                     TREE_PATH_NAME_COLUMN,
 
667
                                                     NULL);
 
668
  gtk_tree_view_column_set_sort_column_id  (column, TREE_PATH_NAME_COLUMN);
 
669
  gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column);
 
670
 
 
671
  renderer = gtk_cell_renderer_text_new ();
 
672
  column = gtk_tree_view_column_new_with_attributes (_("Insertion Date"),
 
673
                                                     renderer,
 
674
                                                     "text",
 
675
                                                     TREE_DATE_COLUMN,
 
676
                                                     NULL);
 
677
  gtk_tree_view_column_set_sort_column_id  (column, TREE_DATE_COLUMN);
 
678
  gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column);
 
679
 
 
680
  renderer = gtk_cell_renderer_text_new ();
 
681
  column = gtk_tree_view_column_new_with_attributes (_("Image Types"),
 
682
                                                     renderer,
 
683
                                                     "text",
 
684
                                                     TREE_IMAGE_TYPES_COLUMN,
 
685
                                                     NULL);
 
686
  gtk_tree_view_column_set_sort_column_id  (column, TREE_IMAGE_TYPES_COLUMN);
 
687
  gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column);
 
688
 
 
689
  swindow = gtk_scrolled_window_new (NULL, NULL);
 
690
  gtk_container_set_border_width (GTK_CONTAINER (swindow), 2);
 
691
  gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (swindow),
 
692
                                       GTK_SHADOW_IN);
 
693
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swindow),
 
694
                                  GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
 
695
  gtk_widget_set_size_request (tree_view, DBL_LIST_WIDTH, DBL_HEIGHT);
 
696
 
 
697
  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view));
 
698
  gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE);
 
699
 
 
700
  g_signal_connect (selection, "changed",
 
701
                    G_CALLBACK (browser_tree_selection_changed),
 
702
                    browser);
 
703
 
 
704
  label = gtk_label_new (_("Tree View"));
 
705
  gtk_notebook_append_page (GTK_NOTEBOOK (notebook), swindow, label);
 
706
  gtk_container_add (GTK_CONTAINER (swindow), tree_view);
 
707
 
 
708
  gtk_widget_show (tree_view);
 
709
  gtk_widget_show (swindow);
 
710
  gtk_widget_show (notebook);
 
711
 
 
712
  /* search entry & details button */
 
713
 
 
714
  hbox = gtk_hbox_new (FALSE, 6);
 
715
  gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
 
716
  gtk_widget_show (hbox);
 
717
 
 
718
  label = gtk_label_new_with_mnemonic (_("_Search:"));
 
719
  gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
 
720
  gtk_widget_show (label);
 
721
 
 
722
  browser->search_entry = gtk_entry_new ();
 
723
  gtk_entry_set_activates_default (GTK_ENTRY (browser->search_entry), TRUE);
 
724
  gtk_box_pack_start (GTK_BOX (hbox), browser->search_entry, TRUE, TRUE, 0);
 
725
  gtk_widget_show (browser->search_entry);
 
726
 
 
727
  gtk_label_set_mnemonic_widget (GTK_LABEL (label), browser->search_entry);
 
728
 
 
729
  /* right = description */
 
730
 
 
731
  browser->proc_box = gimp_proc_box_new ();
 
732
  gtk_widget_set_size_request (browser->proc_box,
 
733
                               DBL_WIDTH - DBL_LIST_WIDTH, -1);
 
734
  gtk_paned_pack2 (GTK_PANED (paned), browser->proc_box, TRUE, TRUE);
 
735
  gtk_widget_show (browser->proc_box);
 
736
 
 
737
  /* now build the list */
 
738
  browser_dialog_response (NULL, GTK_RESPONSE_OK, browser);
 
739
 
 
740
  gtk_widget_show (browser->dialog);
 
741
 
 
742
  if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (list_store), &iter))
 
743
    gtk_tree_selection_select_iter (gtk_tree_view_get_selection (GTK_TREE_VIEW (list_view)),
 
744
                                    &iter);
 
745
 
 
746
  gtk_widget_grab_focus (browser->search_entry);
 
747
 
 
748
  return browser->dialog;
 
749
}
 
750
 
 
751
static void
 
752
browser_dialog_response (GtkWidget     *widget,
 
753
                         gint           response_id,
 
754
                         PluginBrowser *browser)
 
755
{
 
756
  const gchar *search_text = NULL;
 
757
 
 
758
  switch (response_id)
 
759
    {
 
760
    case GTK_RESPONSE_OK:
 
761
      search_text = gtk_entry_get_text (GTK_ENTRY (browser->search_entry));
 
762
      get_plugin_info (browser, search_text);
 
763
      break;
 
764
 
 
765
    default:
 
766
      gtk_widget_destroy (browser->dialog);
 
767
      gtk_main_quit ();
 
768
      break;
 
769
    }
 
770
}
 
771
 
 
772
static void
 
773
browser_list_selection_changed (GtkTreeSelection *selection,
 
774
                                PluginBrowser    *browser)
 
775
{
 
776
  PInfo        *pinfo = NULL;
 
777
  GtkTreeIter   iter;
 
778
  GtkTreeModel *model;
 
779
  gchar        *mpath = NULL;
 
780
 
 
781
  g_return_if_fail (browser != NULL);
 
782
 
 
783
  if (gtk_tree_selection_get_selected (selection, &model, &iter))
 
784
    {
 
785
      gtk_tree_model_get (model, &iter,
 
786
                          LIST_PINFO_COLUMN, &pinfo,
 
787
                          LIST_PATH_COLUMN,  &mpath,
 
788
                          -1);
 
789
    }
 
790
 
 
791
  if (!pinfo || !mpath)
 
792
    return;
 
793
 
 
794
  model = gtk_tree_view_get_model (browser->tree_view);
 
795
 
 
796
  if (find_existing_mpath (model, mpath, &iter))
 
797
    {
 
798
      GtkTreeSelection *tree_selection;
 
799
      GtkTreePath      *tree_path;
 
800
 
 
801
      tree_path = gtk_tree_model_get_path (model, &iter);
 
802
      gtk_tree_view_expand_to_path (browser->tree_view, tree_path);
 
803
      tree_selection = gtk_tree_view_get_selection (browser->tree_view);
 
804
 
 
805
      g_signal_handlers_block_by_func (tree_selection,
 
806
                                       browser_tree_selection_changed,
 
807
                                       browser);
 
808
      gtk_tree_selection_select_iter (tree_selection, &iter);
 
809
      g_signal_handlers_unblock_by_func (tree_selection,
 
810
                                         browser_tree_selection_changed,
 
811
                                         browser);
 
812
 
 
813
      gtk_tree_view_scroll_to_cell (browser->tree_view,
 
814
                                    tree_path, NULL,
 
815
                                    TRUE, 0.5, 0.0);
 
816
    }
 
817
  else
 
818
    {
 
819
      g_warning ("Failed to find node in tree");
 
820
    }
 
821
 
 
822
  g_free (mpath);
 
823
 
 
824
  browser_show_plugin (browser, pinfo);
 
825
}
 
826
 
 
827
static void
 
828
browser_tree_selection_changed (GtkTreeSelection *selection,
 
829
                                PluginBrowser    *browser)
 
830
{
 
831
  PInfo        *pinfo = NULL;
 
832
  GtkTreeIter   iter;
 
833
  GtkTreeModel *model;
 
834
  gchar        *mpath = NULL;
 
835
  gboolean      valid, found;
 
836
 
 
837
  g_return_if_fail (browser != NULL);
 
838
 
 
839
  if (gtk_tree_selection_get_selected (selection, &model, &iter))
 
840
    {
 
841
      gtk_tree_model_get (model, &iter,
 
842
                          TREE_PINFO_COLUMN, &pinfo,
 
843
                          TREE_MPATH_COLUMN, &mpath,
 
844
                          -1);
 
845
    }
 
846
 
 
847
  if (!pinfo || !mpath)
 
848
    return;
 
849
 
 
850
  /* Get the first iter in the list */
 
851
  model = gtk_tree_view_get_model (browser->list_view);
 
852
  valid = gtk_tree_model_get_iter_first (model, &iter);
 
853
  found = FALSE;
 
854
 
 
855
  while (valid)
 
856
    {
 
857
      /* Walk through the list, reading each row */
 
858
      gchar *picked_mpath;
 
859
 
 
860
      gtk_tree_model_get (model, &iter,
 
861
                          LIST_PATH_COLUMN, &picked_mpath,
 
862
                          -1);
 
863
      if (picked_mpath && !strcmp (mpath, picked_mpath))
 
864
        {
 
865
          found = TRUE;
 
866
          break;
 
867
        }
 
868
      g_free (picked_mpath);
 
869
      valid = gtk_tree_model_iter_next (model, &iter);
 
870
    }
 
871
  g_free (mpath);
 
872
 
 
873
  if (found)
 
874
    {
 
875
      GtkTreeSelection *list_selection;
 
876
      GtkTreePath      *tree_path;
 
877
 
 
878
      tree_path = gtk_tree_model_get_path (model, &iter);
 
879
      list_selection = gtk_tree_view_get_selection (browser->list_view);
 
880
 
 
881
      g_signal_handlers_block_by_func (list_selection,
 
882
                                       browser_list_selection_changed,
 
883
                                       browser);
 
884
      gtk_tree_selection_select_iter (list_selection, &iter);
 
885
      g_signal_handlers_unblock_by_func (list_selection,
 
886
                                         browser_list_selection_changed,
 
887
                                         browser);
 
888
 
 
889
      gtk_tree_view_scroll_to_cell (browser->list_view,
 
890
                                    tree_path, NULL,
 
891
                                    TRUE, 0.5, 0.0);
 
892
    }
 
893
  else
 
894
    {
 
895
      g_warning ("Failed to find node in list");
 
896
    }
 
897
 
 
898
  browser_show_plugin (browser, pinfo);
 
899
}
 
900
 
 
901
static void
 
902
browser_show_plugin (PluginBrowser *browser,
 
903
                     PInfo         *pinfo)
 
904
{
 
905
  gchar           *blurb         = NULL;
 
906
  gchar           *help          = NULL;
 
907
  gchar           *author        = NULL;
 
908
  gchar           *copyright     = NULL;
 
909
  gchar           *date          = NULL;
 
910
  GimpPDBProcType  type          = 0;
 
911
  gint             n_params      = 0;
 
912
  gint             n_return_vals = 0;
 
913
  GimpParamDef    *params        = NULL;
 
914
  GimpParamDef    *return_vals   = NULL;
 
915
 
 
916
  g_return_if_fail (browser != NULL);
 
917
  g_return_if_fail (pinfo != NULL);
 
918
 
 
919
  gimp_procedural_db_proc_info (pinfo->realname,
 
920
                                &blurb,
 
921
                                &help,
 
922
                                &author,
 
923
                                &copyright,
 
924
                                &date,
 
925
                                &type,
 
926
                                &n_params,
 
927
                                &n_return_vals,
 
928
                                &params,
 
929
                                &return_vals);
 
930
 
 
931
  gimp_proc_box_set_widget (browser->proc_box,
 
932
                            gimp_proc_view_new (pinfo->realname,
 
933
                                                pinfo->menu,
 
934
                                                blurb,
 
935
                                                help,
 
936
                                                author,
 
937
                                                copyright,
 
938
                                                date,
 
939
                                                type,
 
940
                                                n_params,
 
941
                                                n_return_vals,
 
942
                                                params,
 
943
                                                return_vals));
 
944
 
 
945
  g_free (blurb);
 
946
  g_free (help);
 
947
  g_free (author);
 
948
  g_free (copyright);
 
949
  g_free (date);
 
950
 
 
951
  gimp_destroy_paramdefs (params,      n_params);
 
952
  gimp_destroy_paramdefs (return_vals, n_return_vals);
 
953
}