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

1 by Daniel Holbach
Import upstream version 2.2.9
1
/* LIBGIMP - The GIMP Library
2
 * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
3
 *
4
 * gimppatheditor.c
5
 * Copyright (C) 1999-2004 Michael Natterer <mitch@gimp.org>
6
 *
7
 * This library is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10
 * version 2 of the License, or (at your option) any later version.
11
 *
12
 * This library 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 GNU
15
 * Library General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with this library; if not, write to the
19
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20
 * Boston, MA 02111-1307, USA.
21
 */
22
23
#include "config.h"
24
25
#include <string.h>
26
27
#include <gtk/gtk.h>
28
29
#include "libgimpbase/gimpbase.h"
30
31
#include "gimpwidgetstypes.h"
32
1.1.4 by Daniel Holbach
Import upstream version 2.3.16
33
#undef GIMP_DISABLE_DEPRECATED
34
#include "gimpfileentry.h"
35
1 by Daniel Holbach
Import upstream version 2.2.9
36
#include "gimppatheditor.h"
37
38
#include "libgimp/libgimp-intl.h"
39
40
41
enum
42
{
43
  PATH_CHANGED,
44
  WRITABLE_CHANGED,
45
  LAST_SIGNAL
46
};
47
48
enum
49
{
50
  COLUMN_UTF8,
51
  COLUMN_DIRECTORY,
52
  COLUMN_WRITABLE,
53
  NUM_COLUMNS
54
};
55
56
1.1.4 by Daniel Holbach
Import upstream version 2.3.16
57
static void   gimp_path_editor_new_clicked        (GtkWidget           *widget,
58
                                                   GimpPathEditor      *editor);
59
static void   gimp_path_editor_move_clicked       (GtkWidget           *widget,
60
                                                   GimpPathEditor      *editor);
61
static void   gimp_path_editor_delete_clicked     (GtkWidget           *widget,
62
                                                   GimpPathEditor      *editor);
63
static void   gimp_path_editor_file_entry_changed (GtkWidget           *widget,
64
                                                   GimpPathEditor      *editor);
65
static void   gimp_path_editor_selection_changed  (GtkTreeSelection    *sel,
66
                                                   GimpPathEditor      *editor);
67
static void   gimp_path_editor_writable_toggled   (GtkCellRendererToggle *toggle,
68
                                                   gchar               *path_str,
69
                                                   GimpPathEditor      *editor);
70
71
72
G_DEFINE_TYPE (GimpPathEditor, gimp_path_editor, GTK_TYPE_VBOX)
73
74
#define parent_class gimp_path_editor_parent_class
1 by Daniel Holbach
Import upstream version 2.2.9
75
76
static guint gimp_path_editor_signals[LAST_SIGNAL] = { 0 };
77
78
79
static void
80
gimp_path_editor_class_init (GimpPathEditorClass *klass)
81
{
82
  /**
83
   * GimpPathEditor::path-changed:
84
   *
85
   * This signal is emitted whenever the user adds, deletes, modifies
86
   * or reorders an element of the search path.
87
   **/
88
  gimp_path_editor_signals[PATH_CHANGED] =
1.1.4 by Daniel Holbach
Import upstream version 2.3.16
89
    g_signal_new ("path-changed",
90
                  G_TYPE_FROM_CLASS (klass),
91
                  G_SIGNAL_RUN_FIRST,
92
                  G_STRUCT_OFFSET (GimpPathEditorClass, path_changed),
93
                  NULL, NULL,
94
                  g_cclosure_marshal_VOID__VOID,
95
                  G_TYPE_NONE, 0);
1 by Daniel Holbach
Import upstream version 2.2.9
96
97
  /**
98
   * GimpPathEditor::writable-changed:
99
   *
100
   * This signal is emitted whenever the "writable" column of a directory
101
   * is changed, either by the user clicking on it or by calling
102
   * gimp_path_editor_set_dir_writable().
103
   **/
104
  gimp_path_editor_signals[WRITABLE_CHANGED] =
1.1.4 by Daniel Holbach
Import upstream version 2.3.16
105
    g_signal_new ("writable-changed",
106
                  G_TYPE_FROM_CLASS (klass),
107
                  G_SIGNAL_RUN_FIRST,
108
                  G_STRUCT_OFFSET (GimpPathEditorClass, writable_changed),
109
                  NULL, NULL,
110
                  g_cclosure_marshal_VOID__VOID,
111
                  G_TYPE_NONE, 0);
1 by Daniel Holbach
Import upstream version 2.2.9
112
113
  klass->path_changed     = NULL;
114
  klass->writable_changed = NULL;
115
}
116
117
static void
118
gimp_path_editor_init (GimpPathEditor *editor)
119
{
120
  GtkWidget         *button_box;
121
  GtkWidget         *button;
122
  GtkWidget         *image;
123
  GtkWidget         *scrolled_window;
124
  GtkWidget         *tv;
125
  GtkTreeViewColumn *col;
126
  GtkCellRenderer   *renderer;
127
128
  editor->file_entry = NULL;
129
  editor->sel_path   = NULL;
130
  editor->num_items  = 0;
131
132
  editor->upper_hbox = gtk_hbox_new (FALSE, 2);
133
  gtk_box_pack_start (GTK_BOX (editor), editor->upper_hbox, FALSE, TRUE, 0);
134
  gtk_widget_show (editor->upper_hbox);
135
136
  button_box = gtk_hbox_new (TRUE, 0);
137
  gtk_box_pack_start (GTK_BOX (editor->upper_hbox), button_box, FALSE, TRUE, 0);
138
  gtk_widget_show (button_box);
139
140
  editor->new_button = button = gtk_button_new ();
141
  gtk_box_pack_start (GTK_BOX (button_box), button, TRUE, TRUE, 0);
142
  gtk_widget_show (button);
143
144
  image = gtk_image_new_from_stock (GTK_STOCK_NEW, GTK_ICON_SIZE_BUTTON);
145
  gtk_container_add (GTK_CONTAINER (button), image);
146
  gtk_widget_show (image);
147
148
  g_signal_connect (button, "clicked",
149
                    G_CALLBACK (gimp_path_editor_new_clicked),
1.1.4 by Daniel Holbach
Import upstream version 2.3.16
150
                    editor);
1 by Daniel Holbach
Import upstream version 2.2.9
151
152
  editor->up_button = button = gtk_button_new ();
153
  gtk_widget_set_sensitive (button, FALSE);
154
  gtk_box_pack_start (GTK_BOX (button_box), button, TRUE, TRUE, 0);
155
  gtk_widget_show (button);
156
157
  image = gtk_image_new_from_stock (GTK_STOCK_GO_UP, GTK_ICON_SIZE_BUTTON);
158
  gtk_container_add (GTK_CONTAINER (button), image);
159
  gtk_widget_show (image);
160
161
  g_signal_connect (button, "clicked",
162
                    G_CALLBACK (gimp_path_editor_move_clicked),
1.1.4 by Daniel Holbach
Import upstream version 2.3.16
163
                    editor);
1 by Daniel Holbach
Import upstream version 2.2.9
164
165
  editor->down_button = button = gtk_button_new ();
166
  gtk_widget_set_sensitive (button, FALSE);
167
  gtk_box_pack_start (GTK_BOX (button_box), button, TRUE, TRUE, 0);
168
  gtk_widget_show (button);
169
170
  image = gtk_image_new_from_stock (GTK_STOCK_GO_DOWN, GTK_ICON_SIZE_BUTTON);
171
  gtk_container_add (GTK_CONTAINER (button), image);
172
  gtk_widget_show (image);
173
174
  g_signal_connect (button, "clicked",
175
                    G_CALLBACK (gimp_path_editor_move_clicked),
1.1.4 by Daniel Holbach
Import upstream version 2.3.16
176
                    editor);
1 by Daniel Holbach
Import upstream version 2.2.9
177
178
  editor->delete_button = button = gtk_button_new ();
179
  gtk_widget_set_sensitive (button, FALSE);
180
  gtk_box_pack_start (GTK_BOX (button_box), button, TRUE, TRUE, 0);
181
  gtk_widget_show (button);
182
183
  image = gtk_image_new_from_stock (GTK_STOCK_DELETE, GTK_ICON_SIZE_BUTTON);
184
  gtk_container_add (GTK_CONTAINER (button), image);
185
  gtk_widget_show (image);
186
187
  g_signal_connect (button, "clicked",
188
                    G_CALLBACK (gimp_path_editor_delete_clicked),
1.1.4 by Daniel Holbach
Import upstream version 2.3.16
189
                    editor);
1 by Daniel Holbach
Import upstream version 2.2.9
190
191
  scrolled_window = gtk_scrolled_window_new (NULL, NULL);
192
  gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window),
1.1.4 by Daniel Holbach
Import upstream version 2.3.16
193
                                       GTK_SHADOW_IN);
1 by Daniel Holbach
Import upstream version 2.2.9
194
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
195
                                  GTK_POLICY_AUTOMATIC,
196
                                  GTK_POLICY_ALWAYS);
197
  gtk_box_pack_start (GTK_BOX (editor), scrolled_window, TRUE, TRUE, 2);
198
  gtk_widget_show (scrolled_window);
199
200
  editor->dir_list = gtk_list_store_new (NUM_COLUMNS,
201
                                         G_TYPE_STRING,
202
                                         G_TYPE_STRING,
203
                                         G_TYPE_BOOLEAN);
204
  tv = gtk_tree_view_new_with_model (GTK_TREE_MODEL (editor->dir_list));
205
  g_object_unref (editor->dir_list);
206
207
  renderer = gtk_cell_renderer_toggle_new ();
208
209
  g_signal_connect (renderer, "toggled",
210
                    G_CALLBACK (gimp_path_editor_writable_toggled),
211
                    editor);
212
213
  editor->writable_column = col = gtk_tree_view_column_new ();
214
  gtk_tree_view_column_set_title (col, _("Writable"));
215
  gtk_tree_view_column_pack_start (col, renderer, FALSE);
216
  gtk_tree_view_column_add_attribute (col, renderer, "active", COLUMN_WRITABLE);
217
218
  gtk_tree_view_append_column (GTK_TREE_VIEW (tv), col);
219
220
  gtk_tree_view_column_set_visible (col, FALSE);
221
222
  gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (tv),
1.1.4 by Daniel Holbach
Import upstream version 2.3.16
223
                                               -1, _("Folder"),
224
                                               gtk_cell_renderer_text_new (),
225
                                               "text", COLUMN_UTF8,
226
                                               NULL);
1 by Daniel Holbach
Import upstream version 2.2.9
227
228
  gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (tv), TRUE);
229
230
  gtk_container_add (GTK_CONTAINER (scrolled_window), tv);
231
  gtk_widget_show (tv);
232
233
  editor->sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (tv));
234
  g_signal_connect (editor->sel, "changed",
1.1.4 by Daniel Holbach
Import upstream version 2.3.16
235
                    G_CALLBACK (gimp_path_editor_selection_changed),
236
                    editor);
1 by Daniel Holbach
Import upstream version 2.2.9
237
}
238
239
/**
240
 * gimp_path_editor_new:
1.1.4 by Daniel Holbach
Import upstream version 2.3.16
241
 * @title: The title of the #GtkFileChooser dialog which can be popped up.
242
 * @path:  The initial search path.
1 by Daniel Holbach
Import upstream version 2.2.9
243
 *
244
 * Creates a new #GimpPathEditor widget.
245
 *
246
 * The elements of the initial search path must be separated with the
247
 * #G_SEARCHPATH_SEPARATOR character.
248
 *
249
 * Returns: A pointer to the new #GimpPathEditor widget.
250
 **/
251
GtkWidget *
1.1.4 by Daniel Holbach
Import upstream version 2.3.16
252
gimp_path_editor_new (const gchar *title,
253
                      const gchar *path)
1 by Daniel Holbach
Import upstream version 2.2.9
254
{
255
  GimpPathEditor *editor;
256
1.1.4 by Daniel Holbach
Import upstream version 2.3.16
257
  g_return_val_if_fail (title != NULL, NULL);
1 by Daniel Holbach
Import upstream version 2.2.9
258
259
  editor = g_object_new (GIMP_TYPE_PATH_EDITOR, NULL);
260
1.1.4 by Daniel Holbach
Import upstream version 2.3.16
261
  editor->file_entry = gimp_file_entry_new (title, "", TRUE, TRUE);
1 by Daniel Holbach
Import upstream version 2.2.9
262
  gtk_widget_set_sensitive (editor->file_entry, FALSE);
263
  gtk_box_pack_start (GTK_BOX (editor->upper_hbox), editor->file_entry,
264
                      TRUE, TRUE, 0);
265
  gtk_widget_show (editor->file_entry);
266
1.1.4 by Daniel Holbach
Import upstream version 2.3.16
267
  g_signal_connect (editor->file_entry, "filename-changed",
1 by Daniel Holbach
Import upstream version 2.2.9
268
                    G_CALLBACK (gimp_path_editor_file_entry_changed),
1.1.4 by Daniel Holbach
Import upstream version 2.3.16
269
                    editor);
1 by Daniel Holbach
Import upstream version 2.2.9
270
271
  if (path)
272
    gimp_path_editor_set_path (editor, path);
273
274
  return GTK_WIDGET (editor);
275
}
276
277
/**
278
 * gimp_path_editor_get_path:
279
 * @editor: The path editor you want to get the search path from.
280
 *
281
 * The elements of the returned search path string are separated with the
282
 * #G_SEARCHPATH_SEPARATOR character.
283
 *
284
 * Note that you have to g_free() the returned string.
285
 *
286
 * Returns: The search path the user has selected in the path editor.
287
 **/
288
gchar *
289
gimp_path_editor_get_path (GimpPathEditor *editor)
290
{
291
  GtkTreeModel *model;
292
  GString      *path;
293
  GtkTreeIter   iter;
294
  gboolean      iter_valid;
295
296
  g_return_val_if_fail (GIMP_IS_PATH_EDITOR (editor), g_strdup (""));
297
298
  model = GTK_TREE_MODEL (editor->dir_list);
299
300
  path = g_string_new ("");
301
302
  for (iter_valid = gtk_tree_model_get_iter_first (model, &iter);
303
       iter_valid;
304
       iter_valid = gtk_tree_model_iter_next (model, &iter))
305
    {
306
      gchar *dir;
307
308
      gtk_tree_model_get (model, &iter,
309
                          COLUMN_DIRECTORY, &dir,
310
                          -1);
311
312
      if (path->len > 0)
313
        g_string_append_c (path, G_SEARCHPATH_SEPARATOR);
314
315
      g_string_append (path, dir);
316
317
      g_free (dir);
318
    }
319
320
  return g_string_free (path, FALSE);
321
}
322
323
/**
324
 * gimp_path_editor_set_path:
325
 * @editor: The path editor you want to set the search path from.
326
 * @path:   The new path to set.
327
 *
328
 * The elements of the initial search path must be separated with the
329
 * #G_SEARCHPATH_SEPARATOR character.
330
 **/
331
void
332
gimp_path_editor_set_path (GimpPathEditor *editor,
333
                           const gchar    *path)
334
{
335
  gchar *old_path;
336
  GList *path_list;
337
  GList *list;
338
339
  g_return_if_fail (GIMP_IS_PATH_EDITOR (editor));
340
341
  old_path = gimp_path_editor_get_path (editor);
342
1.1.4 by Daniel Holbach
Import upstream version 2.3.16
343
  if (old_path && path && strcmp (old_path, path) == 0)
1 by Daniel Holbach
Import upstream version 2.2.9
344
    {
345
      g_free (old_path);
346
      return;
347
    }
348
1.1.4 by Daniel Holbach
Import upstream version 2.3.16
349
  g_free (old_path);
350
1 by Daniel Holbach
Import upstream version 2.2.9
351
  path_list = gimp_path_parse (path, 16, TRUE, NULL);
352
353
  gtk_list_store_clear (editor->dir_list);
354
355
  for (list = path_list; list; list = g_list_next (list))
356
    {
357
      gchar       *directory = list->data;
358
      gchar       *utf8;
359
      GtkTreeIter  iter;
360
361
      utf8 = g_filename_to_utf8 (directory, -1, NULL, NULL, NULL);
362
363
      gtk_list_store_append (editor->dir_list, &iter);
364
      gtk_list_store_set (editor->dir_list, &iter,
365
                          COLUMN_UTF8,      utf8,
366
                          COLUMN_DIRECTORY, directory,
367
                          COLUMN_WRITABLE,  FALSE,
368
                          -1);
369
370
      g_free (utf8);
371
372
      editor->num_items++;
373
    }
374
375
  gimp_path_free (path_list);
376
377
  g_signal_emit (editor, gimp_path_editor_signals[PATH_CHANGED], 0);
378
}
379
380
gchar *
381
gimp_path_editor_get_writable_path (GimpPathEditor *editor)
382
{
383
  GtkTreeModel *model;
384
  GString      *path;
385
  GtkTreeIter   iter;
386
  gboolean      iter_valid;
387
388
  g_return_val_if_fail (GIMP_IS_PATH_EDITOR (editor), g_strdup (""));
389
390
  model = GTK_TREE_MODEL (editor->dir_list);
391
392
  path = g_string_new ("");
393
394
  for (iter_valid = gtk_tree_model_get_iter_first (model, &iter);
395
       iter_valid;
396
       iter_valid = gtk_tree_model_iter_next (model, &iter))
397
    {
398
      gchar    *dir;
399
      gboolean  dir_writable;
400
401
      gtk_tree_model_get (model, &iter,
402
                          COLUMN_DIRECTORY, &dir,
403
                          COLUMN_WRITABLE,  &dir_writable,
404
                          -1);
405
406
      if (dir_writable)
407
        {
408
          if (path->len > 0)
409
            g_string_append_c (path, G_SEARCHPATH_SEPARATOR);
410
411
          g_string_append (path, dir);
412
        }
413
414
      g_free (dir);
415
    }
416
417
  return g_string_free (path, FALSE);
418
}
419
420
void
421
gimp_path_editor_set_writable_path (GimpPathEditor *editor,
422
                                    const gchar    *path)
423
{
424
  GtkTreeModel *model;
425
  GtkTreeIter   iter;
426
  gboolean      iter_valid;
427
  GList        *path_list;
428
  gboolean      writable_changed = FALSE;
429
430
  g_return_if_fail (GIMP_IS_PATH_EDITOR (editor));
431
432
  gtk_tree_view_column_set_visible (editor->writable_column, TRUE);
433
434
  path_list = gimp_path_parse (path, 16, TRUE, NULL);
435
436
  model = GTK_TREE_MODEL (editor->dir_list);
437
438
  for (iter_valid = gtk_tree_model_get_iter_first (model, &iter);
439
       iter_valid;
440
       iter_valid = gtk_tree_model_iter_next (model, &iter))
441
    {
442
      gchar    *dir;
443
      gboolean  dir_writable;
444
      gboolean  new_writable = FALSE;
445
446
      gtk_tree_model_get (model, &iter,
447
                          COLUMN_DIRECTORY, &dir,
448
                          COLUMN_WRITABLE,  &dir_writable,
449
                          -1);
450
451
      if (g_list_find_custom (path_list, dir, (GCompareFunc) strcmp))
452
        new_writable = TRUE;
453
454
      g_free (dir);
455
456
      if (dir_writable != new_writable)
457
        {
458
          gtk_list_store_set (editor->dir_list, &iter,
459
                              COLUMN_WRITABLE, new_writable,
460
                              -1);
461
462
          writable_changed = TRUE;
463
        }
464
    }
465
466
  gimp_path_free (path_list);
467
468
  if (writable_changed)
469
    g_signal_emit (editor, gimp_path_editor_signals[WRITABLE_CHANGED], 0);
470
}
471
472
gboolean
473
gimp_path_editor_get_dir_writable (GimpPathEditor *editor,
474
                                   const gchar    *directory)
475
{
476
  GtkTreeModel *model;
477
  GtkTreeIter   iter;
478
  gboolean      iter_valid;
479
480
  g_return_val_if_fail (GIMP_IS_PATH_EDITOR (editor), FALSE);
481
  g_return_val_if_fail (directory != NULL, FALSE);
482
483
  model = GTK_TREE_MODEL (editor->dir_list);
484
485
  for (iter_valid = gtk_tree_model_get_iter_first (model, &iter);
486
       iter_valid;
487
       iter_valid = gtk_tree_model_iter_next (model, &iter))
488
    {
489
      gchar    *dir;
490
      gboolean  dir_writable;
491
492
      gtk_tree_model_get (model, &iter,
493
                          COLUMN_DIRECTORY, &dir,
494
                          COLUMN_WRITABLE,  &dir_writable,
495
                          -1);
496
497
      if (! strcmp (dir, directory))
498
        {
499
          g_free (dir);
500
501
          return dir_writable;
502
        }
503
504
      g_free (dir);
505
    }
506
507
  return FALSE;
508
}
509
510
void
511
gimp_path_editor_set_dir_writable (GimpPathEditor *editor,
512
                                   const gchar    *directory,
513
                                   gboolean        writable)
514
{
515
  GtkTreeModel *model;
516
  GtkTreeIter   iter;
517
  gboolean      iter_valid;
518
519
  g_return_if_fail (GIMP_IS_PATH_EDITOR (editor));
520
  g_return_if_fail (directory != NULL);
521
522
  model = GTK_TREE_MODEL (editor->dir_list);
523
524
  for (iter_valid = gtk_tree_model_get_iter_first (model, &iter);
525
       iter_valid;
526
       iter_valid = gtk_tree_model_iter_next (model, &iter))
527
    {
528
      gchar    *dir;
529
      gboolean  dir_writable;
530
531
      gtk_tree_model_get (model, &iter,
532
                          COLUMN_DIRECTORY, &dir,
533
                          COLUMN_WRITABLE,  &dir_writable,
534
                          -1);
535
536
      if (! strcmp (dir, directory) && dir_writable != writable)
537
        {
538
          gtk_list_store_set (editor->dir_list, &iter,
539
                              COLUMN_WRITABLE, writable ? TRUE : FALSE,
540
                              -1);
541
542
          g_signal_emit (editor, gimp_path_editor_signals[WRITABLE_CHANGED], 0);
543
544
          g_free (dir);
545
          break;
546
        }
547
548
      g_free (dir);
549
    }
550
}
551
552
553
/*  private functions  */
554
555
static void
556
gimp_path_editor_new_clicked (GtkWidget      *widget,
557
                              GimpPathEditor *editor)
558
{
559
  if (editor->sel_path)
560
    {
561
      g_signal_handlers_block_by_func (editor->sel,
1.1.4 by Daniel Holbach
Import upstream version 2.3.16
562
                                       gimp_path_editor_selection_changed,
1 by Daniel Holbach
Import upstream version 2.2.9
563
                                       editor);
564
565
      gtk_tree_selection_unselect_path (editor->sel, editor->sel_path);
566
567
      g_signal_handlers_unblock_by_func (editor->sel,
1.1.4 by Daniel Holbach
Import upstream version 2.3.16
568
                                         gimp_path_editor_selection_changed,
1 by Daniel Holbach
Import upstream version 2.2.9
569
                                         editor);
570
571
      gtk_tree_path_free (editor->sel_path);
572
      editor->sel_path = NULL;
573
    }
574
575
  gtk_widget_set_sensitive (editor->delete_button, FALSE);
576
  gtk_widget_set_sensitive (editor->up_button, FALSE);
577
  gtk_widget_set_sensitive (editor->down_button, FALSE);
578
  gtk_widget_set_sensitive (editor->file_entry, TRUE);
579
580
  gtk_editable_set_position
581
    (GTK_EDITABLE (GIMP_FILE_ENTRY (editor->file_entry)->entry), -1);
582
  gtk_widget_grab_focus
583
    (GTK_WIDGET (GIMP_FILE_ENTRY (editor->file_entry)->entry));
584
}
585
586
static void
587
gimp_path_editor_move_clicked (GtkWidget      *widget,
588
                               GimpPathEditor *editor)
589
{
590
  GtkTreePath  *path;
591
  GtkTreeModel *model;
592
  GtkTreeIter   iter1, iter2;
593
  gchar        *utf81, *utf82;
594
  gchar        *dir1, *dir2;
595
  gboolean      writable1, writable2;
596
597
  if (editor->sel_path == NULL)
598
    return;
599
600
  path = gtk_tree_path_copy (editor->sel_path);
601
602
  if (widget == editor->up_button)
603
    gtk_tree_path_prev (path);
604
  else
605
    gtk_tree_path_next (path);
606
607
  model = GTK_TREE_MODEL (editor->dir_list);
608
609
  gtk_tree_model_get_iter (model, &iter1, editor->sel_path);
610
  gtk_tree_model_get_iter (model, &iter2, path);
611
612
  gtk_tree_model_get (model, &iter1,
613
                      COLUMN_UTF8,      &utf81,
614
                      COLUMN_DIRECTORY, &dir1,
615
                      COLUMN_WRITABLE,  &writable1,
616
                      -1);
617
  gtk_tree_model_get (model, &iter2,
618
                      COLUMN_UTF8,      &utf82,
619
                      COLUMN_DIRECTORY, &dir2,
620
                      COLUMN_WRITABLE,  &writable2,
621
                      -1);
622
623
  gtk_list_store_set (editor->dir_list, &iter1,
624
                      COLUMN_UTF8,      utf82,
625
                      COLUMN_DIRECTORY, dir2,
626
                      COLUMN_WRITABLE,  writable2,
627
                      -1);
628
  gtk_list_store_set (editor->dir_list, &iter2,
629
                      COLUMN_UTF8,      utf81,
630
                      COLUMN_DIRECTORY, dir1,
631
                      COLUMN_WRITABLE,  writable1,
632
                      -1);
633
634
  g_free (utf81);
635
  g_free (utf82);
636
637
  g_free (dir2);
638
  g_free (dir1);
639
640
  gtk_tree_selection_select_iter (editor->sel, &iter2);
641
642
  g_signal_emit (editor, gimp_path_editor_signals[PATH_CHANGED], 0);
643
}
644
645
static void
646
gimp_path_editor_delete_clicked (GtkWidget      *widget,
647
                                 GimpPathEditor *editor)
648
{
649
  GtkTreeIter iter;
650
  gboolean    dir_writable;
651
652
  if (editor->sel_path == NULL)
653
    return;
654
655
  gtk_tree_model_get_iter (GTK_TREE_MODEL (editor->dir_list), &iter,
1.1.4 by Daniel Holbach
Import upstream version 2.3.16
656
                           editor->sel_path);
1 by Daniel Holbach
Import upstream version 2.2.9
657
658
  gtk_tree_model_get (GTK_TREE_MODEL (editor->dir_list), &iter,
659
                      COLUMN_WRITABLE, &dir_writable,
660
                      -1);
661
662
  gtk_list_store_remove (editor->dir_list, &iter);
663
664
  editor->num_items--;
665
666
  if (editor->num_items == 0)
667
    {
668
      gtk_tree_path_free (editor->sel_path);
669
      editor->sel_path = NULL;
670
671
      g_signal_handlers_block_by_func (editor->file_entry,
672
                                       gimp_path_editor_file_entry_changed,
673
                                       editor);
674
675
      gimp_file_entry_set_filename (GIMP_FILE_ENTRY (editor->file_entry), "");
676
677
      g_signal_handlers_unblock_by_func (editor->file_entry,
678
                                         gimp_path_editor_file_entry_changed,
679
                                         editor);
680
681
      gtk_widget_set_sensitive (editor->delete_button, FALSE);
682
      gtk_widget_set_sensitive (editor->up_button,     FALSE);
683
      gtk_widget_set_sensitive (editor->down_button,   FALSE);
684
      gtk_widget_set_sensitive (editor->file_entry,    FALSE);
685
    }
686
  else
687
    {
688
      gint *indices;
689
690
      indices = gtk_tree_path_get_indices (editor->sel_path);
691
      if ((indices[0] == editor->num_items) && (indices[0] > 0))
692
        gtk_tree_path_prev (editor->sel_path);
693
694
      gtk_tree_selection_select_path (editor->sel, editor->sel_path);
695
    }
696
697
  g_signal_emit (editor, gimp_path_editor_signals[PATH_CHANGED], 0);
698
699
  if (dir_writable)
700
    g_signal_emit (editor, gimp_path_editor_signals[WRITABLE_CHANGED], 0);
701
}
702
703
static void
704
gimp_path_editor_file_entry_changed (GtkWidget      *widget,
705
                                     GimpPathEditor *editor)
706
{
707
  gchar       *dir;
708
  gchar       *utf8;
709
  GtkTreeIter  iter;
710
711
  dir = gimp_file_entry_get_filename (GIMP_FILE_ENTRY (widget));
712
  if (strcmp (dir, "") == 0)
713
    {
714
      g_free (dir);
715
      return;
716
    }
717
1.1.4 by Daniel Holbach
Import upstream version 2.3.16
718
  utf8 = g_filename_display_name (dir);
1 by Daniel Holbach
Import upstream version 2.2.9
719
720
  if (editor->sel_path == NULL)
721
    {
722
      gtk_list_store_append (editor->dir_list, &iter);
723
      gtk_list_store_set (editor->dir_list, &iter,
724
                          COLUMN_UTF8,      utf8,
725
                          COLUMN_DIRECTORY, dir,
726
                          COLUMN_WRITABLE,  FALSE,
727
                          -1);
728
      editor->num_items++;
729
730
      gtk_tree_selection_select_iter (editor->sel, &iter);
731
    }
732
  else
733
    {
734
      gtk_tree_model_get_iter (GTK_TREE_MODEL (editor->dir_list), &iter,
1.1.4 by Daniel Holbach
Import upstream version 2.3.16
735
                               editor->sel_path);
1 by Daniel Holbach
Import upstream version 2.2.9
736
      gtk_list_store_set (editor->dir_list, &iter,
737
                          COLUMN_UTF8,      utf8,
738
                          COLUMN_DIRECTORY, dir,
739
                          -1);
740
    }
741
742
  g_free (dir);
743
  g_free (utf8);
744
745
  g_signal_emit (editor, gimp_path_editor_signals[PATH_CHANGED], 0);
746
}
747
748
static void
749
gimp_path_editor_selection_changed (GtkTreeSelection *sel,
750
                                    GimpPathEditor   *editor)
751
{
752
  GtkTreeIter  iter;
753
  gchar       *directory;
754
  gint        *indices;
755
756
  if (gtk_tree_selection_get_selected (sel, NULL, &iter))
757
    {
758
      gtk_tree_model_get (GTK_TREE_MODEL (editor->dir_list), &iter,
759
                          0, &directory,
760
                          -1);
761
762
      g_signal_handlers_block_by_func (editor->file_entry,
763
                                       gimp_path_editor_file_entry_changed,
764
                                       editor);
765
766
      gimp_file_entry_set_filename (GIMP_FILE_ENTRY (editor->file_entry),
767
                                    directory);
768
769
      g_signal_handlers_unblock_by_func (editor->file_entry,
770
                                         gimp_path_editor_file_entry_changed,
771
                                         editor);
772
773
      g_free (directory);
774
775
      if (editor->sel_path)
1.1.4 by Daniel Holbach
Import upstream version 2.3.16
776
        gtk_tree_path_free (editor->sel_path);
1 by Daniel Holbach
Import upstream version 2.2.9
777
778
      editor->sel_path =
779
        gtk_tree_model_get_path (GTK_TREE_MODEL (editor->dir_list), &iter);
780
781
      indices = gtk_tree_path_get_indices (editor->sel_path);
782
783
      gtk_widget_set_sensitive (editor->delete_button, TRUE);
784
      gtk_widget_set_sensitive (editor->up_button, (indices[0] > 0));
785
      gtk_widget_set_sensitive (editor->down_button,
786
                                (indices[0] < (editor->num_items - 1)));
787
      gtk_widget_set_sensitive (editor->file_entry, TRUE);
788
    }
789
  else
790
    {
791
      g_signal_handlers_block_by_func (sel,
792
                                       gimp_path_editor_selection_changed,
793
                                       editor);
794
795
      gtk_tree_selection_select_path (editor->sel, editor->sel_path);
796
797
      g_signal_handlers_unblock_by_func (sel,
798
                                         gimp_path_editor_selection_changed,
799
                                         editor);
800
    }
801
}
802
803
static void
804
gimp_path_editor_writable_toggled (GtkCellRendererToggle *toggle,
805
                                   gchar                 *path_str,
806
                                   GimpPathEditor        *editor)
807
{
808
  GtkTreePath *path;
809
  GtkTreeIter  iter;
810
811
  path = gtk_tree_path_new_from_string (path_str);
812
813
  if (gtk_tree_model_get_iter (GTK_TREE_MODEL (editor->dir_list), &iter, path))
814
    {
815
      gboolean dir_writable;
816
817
      gtk_tree_model_get (GTK_TREE_MODEL (editor->dir_list), &iter,
818
                          COLUMN_WRITABLE,  &dir_writable,
819
                          -1);
820
821
      gtk_list_store_set (editor->dir_list, &iter,
822
                          COLUMN_WRITABLE, ! dir_writable,
823
                          -1);
824
825
      g_signal_emit (editor, gimp_path_editor_signals[WRITABLE_CHANGED], 0);
826
    }
827
828
  gtk_tree_path_free (path);
829
}