~ubuntu-branches/ubuntu/utopic/thunar/utopic-proposed

« back to all changes in this revision

Viewing changes to thunar/thunar-properties-dialog.c

  • Committer: Package Import Robot
  • Author(s): Lionel Le Folgoc
  • Date: 2012-12-03 13:13:58 UTC
  • mfrom: (1.3.4)
  • Revision ID: package-import@ubuntu.com-20121203131358-zk6tkel37d732wh6
Tags: 1.6.0-0ubuntu1
* Upload to raring.
* Remaining Ubuntu change:
  - debian/control: recommend udisks2 for mounting devices. lp: #1014632
* Drop obsolete Ubuntu changes:
  - debian/patches/02_guard-for-no-supported-vfs-schemas.patch,
    debian/patches/xubuntu_fix-duplicate-volumes.patch: included upstream.
* Bugs fixed:
  - "Thunar: sendto_printer broken" lp: #1061846
  - "segfault when a specific html file is selected" lp: #751739
  - "can't book mark remote shares" lp: #778268
  - "Thunar crashed with SIGSEGV in thunarx_menu_provider_get_file_actions()
    thinking a directory was a file" lp: #852410
  - "Left or right-clicking on 3MB or bigger svg file is unresponsive"
    lp: #893330
  - "Thunar crashed with SIGSEGV in fast_validate()" lp: #913041
  - "Thunar crashed with SIGSEGV in thunar_file_get_display_name()"
    lp: #931101
  - "Thunar crashed with SIGSEGV in sort_by_mime_type()" lp: #931842
  - "Thunar crashed with SIGSEGV in thunar_util_parse_parent()" lp: #969222
  - "thunar crashed with SIGSEGV in thunar_standard_view_cancel_thumbnailing()"
    lp: #1059397
  - "Does not unmount USB drive when you try first time" lp: #1059997
  - "regression: thunar no longer shows all unmounted, but mountable, volumes
    in sidepane" lp: #1068947
  - "Thunar shows folder sizes wrong" lp: #59235
  - "Right-click "Open With" list not refreshing" lp: #107392
  - "no thunar contextmenu with GTK setting "gtk-menu-popup-delay = 0""
    lp: #127372
  - "rename folder, still active but answers not on 'Enter'" lp: #479975
  - "Thunar hangs on first launch of each session" lp: #775117
  - "emblems disappear on rename" lp: #877755
  - "Remote Deleted file in Thunar remains visible until resfresh" lp: #999824
  - "Incorrect alphabetical sort order in thunar with non-latin (eg. cyrillic)
    file names" lp: #684317
  - "Thunar does not display current folder name" lp: #875193
  - "Thunar crashed with SIGSEGV in g_file_equal()" lp: #900306
  - "Hard to see, if volume is mounted or not" lp: #838917

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
/*-
3
3
 * Copyright (c) 2005-2007 Benedikt Meurer <benny@xfce.org>
4
4
 * Copyright (c) 2009-2011 Jannis Pohlmann <jannis@xfce.org>
 
5
 * Copyright (c) 2012      Nick Schermer <nick@xfce.org>
5
6
 *
6
 
 * This program is free software; you can redistribute it and/or 
 
7
 * This program is free software; you can redistribute it and/or
7
8
 * modify it under the terms of the GNU General Public License as
8
 
 * published by the Free Software Foundation; either version 2 of 
 
9
 * published by the Free Software Foundation; either version 2 of
9
10
 * the License, or (at your option) any later version.
10
11
 *
11
12
 * This program is distributed in the hope that it will be useful,
12
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
15
 * GNU General Public License for more details.
15
16
 *
16
 
 * You should have received a copy of the GNU General Public 
17
 
 * License along with this program; if not, write to the Free 
 
17
 * You should have received a copy of the GNU General Public
 
18
 * License along with this program; if not, write to the Free
18
19
 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19
20
 * Boston, MA 02110-1301, USA.
20
21
 */
62
63
enum
63
64
{
64
65
  PROP_0,
65
 
  PROP_FILE,
 
66
  PROP_FILES,
66
67
};
67
68
 
68
69
/* Signal identifiers */
87
88
static void     thunar_properties_dialog_response             (GtkDialog                   *dialog,
88
89
                                                               gint                         response);
89
90
static gboolean thunar_properties_dialog_reload               (ThunarPropertiesDialog      *dialog);
90
 
static void     thunar_properties_dialog_activate             (GtkWidget                   *entry,
 
91
static void     thunar_properties_dialog_name_activate        (GtkWidget                   *entry,
91
92
                                                               ThunarPropertiesDialog      *dialog);
92
 
static gboolean thunar_properties_dialog_focus_out_event      (GtkWidget                   *entry,
 
93
static gboolean thunar_properties_dialog_name_focus_out_event (GtkWidget                   *entry,
93
94
                                                               GdkEventFocus               *event,
94
95
                                                               ThunarPropertiesDialog      *dialog);
95
96
static void     thunar_properties_dialog_icon_button_clicked  (GtkWidget                   *button,
96
97
                                                               ThunarPropertiesDialog      *dialog);
97
98
static void     thunar_properties_dialog_update               (ThunarPropertiesDialog      *dialog);
98
99
static void     thunar_properties_dialog_update_providers     (ThunarPropertiesDialog      *dialog);
99
 
 
 
100
static GList   *thunar_properties_dialog_get_files            (ThunarPropertiesDialog      *dialog);
100
101
 
101
102
 
102
103
struct _ThunarPropertiesDialogClass
116
117
 
117
118
  ThunarPreferences      *preferences;
118
119
 
119
 
  ThunarFile             *file;
 
120
  GList                  *files;
120
121
 
121
122
  ThunarThumbnailer      *thumbnailer;
122
123
  guint                   thumbnail_request;
125
126
  GtkWidget              *icon_button;
126
127
  GtkWidget              *icon_image;
127
128
  GtkWidget              *name_entry;
 
129
  GtkWidget              *names_label;
 
130
  GtkWidget              *single_box;
128
131
  GtkWidget              *kind_ebox;
129
132
  GtkWidget              *kind_label;
130
133
  GtkWidget              *openwith_chooser;
131
134
  GtkWidget              *link_label;
 
135
  GtkWidget              *location_label;
132
136
  GtkWidget              *origin_label;
133
137
  GtkWidget              *deleted_label;
134
138
  GtkWidget              *modified_label;
164
168
  klass->reload = thunar_properties_dialog_reload;
165
169
 
166
170
  /**
167
 
   * ThunarPropertiesDialog:file:
 
171
   * ThunarPropertiesDialog:files:
168
172
   *
169
 
   * The #ThunarFile whose properties are currently displayed by
 
173
   * The list of currently selected files whose properties are displayed by
170
174
   * this #ThunarPropertiesDialog. This property may also be %NULL
171
175
   * in which case nothing is displayed.
172
176
   **/
173
177
  g_object_class_install_property (gobject_class,
174
 
                                   PROP_FILE,
175
 
                                   g_param_spec_object ("file", "file", "file",
176
 
                                                        THUNAR_TYPE_FILE,
 
178
                                   PROP_FILES,
 
179
                                   g_param_spec_boxed ("files", "files", "files",
 
180
                                                        THUNARX_TYPE_FILE_INFO_LIST,
177
181
                                                        EXO_PARAM_READWRITE));
178
182
 
179
183
  /**
208
212
  GtkWidget *label;
209
213
  GtkWidget *box;
210
214
  GtkWidget *spacer;
211
 
  gint       row = 0;
 
215
  guint      row = 0;
 
216
  GtkWidget *image;
212
217
 
213
218
  /* acquire a reference on the preferences and monitor the "misc-date-style" setting */
214
219
  dialog->preferences = thunar_preferences_get ();
216
221
                            G_CALLBACK (thunar_properties_dialog_reload), dialog);
217
222
 
218
223
  /* create a new thumbnailer */
219
 
  dialog->thumbnailer = thunar_thumbnailer_new ();
 
224
  dialog->thumbnailer = thunar_thumbnailer_get ();
220
225
  dialog->thumbnail_request = 0;
221
226
 
222
227
  dialog->provider_factory = thunarx_provider_factory_get_default ();
225
230
                          GTK_STOCK_HELP, GTK_RESPONSE_HELP,
226
231
                          GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
227
232
                          NULL);
228
 
  gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
229
233
  gtk_window_set_default_size (GTK_WINDOW (dialog), 400, 430);
230
234
 
231
235
  dialog->notebook = gtk_notebook_new ();
233
237
  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), dialog->notebook, TRUE, TRUE, 0);
234
238
  gtk_widget_show (dialog->notebook);
235
239
 
236
 
  table = gtk_table_new (2, 2, FALSE);
 
240
  table = gtk_table_new (16, 2, FALSE);
237
241
  label = gtk_label_new (_("General"));
238
242
  gtk_table_set_col_spacings (GTK_TABLE (table), 12);
239
243
  gtk_container_set_border_width (GTK_CONTAINER (table), 6);
243
247
 
244
248
 
245
249
  /*
246
 
     First box (icon, name)
 
250
     First box (icon, name) for 1 file
247
251
   */
248
 
  box = gtk_hbox_new (FALSE, 6);
249
 
  gtk_table_attach (GTK_TABLE (table), box, 0, 1, row, row + 1, GTK_FILL, GTK_FILL, 0, 3);
250
 
  gtk_widget_show (box);
 
252
  dialog->single_box = gtk_hbox_new (FALSE, 6);
 
253
  gtk_table_attach (GTK_TABLE (table), dialog->single_box, 0, 1, row, row + 1, GTK_FILL, GTK_FILL, 0, 3);
251
254
 
252
255
  dialog->icon_button = gtk_button_new ();
253
256
  g_signal_connect (G_OBJECT (dialog->icon_button), "clicked", G_CALLBACK (thunar_properties_dialog_icon_button_clicked), dialog);
254
 
  gtk_box_pack_start (GTK_BOX (box), dialog->icon_button, FALSE, TRUE, 0);
 
257
  gtk_box_pack_start (GTK_BOX (dialog->single_box), dialog->icon_button, FALSE, TRUE, 0);
255
258
  gtk_widget_show (dialog->icon_button);
256
259
 
257
260
  dialog->icon_image = thunar_image_new ();
258
 
  gtk_box_pack_start (GTK_BOX (box), dialog->icon_image, FALSE, TRUE, 0);
 
261
  gtk_box_pack_start (GTK_BOX (dialog->single_box), dialog->icon_image, FALSE, TRUE, 0);
259
262
  gtk_widget_show (dialog->icon_image);
260
263
 
261
 
  label = gtk_label_new (_("Name:"));
 
264
  label = gtk_label_new_with_mnemonic (_("_Name:"));
262
265
  gtk_label_set_attributes (GTK_LABEL (label), thunar_pango_attr_list_bold ());
263
266
  gtk_misc_set_alignment (GTK_MISC (label), 1.0f, 0.5f);
264
 
  gtk_box_pack_end (GTK_BOX (box), label, TRUE, TRUE, 0);
 
267
  gtk_box_pack_end (GTK_BOX (dialog->single_box), label, TRUE, TRUE, 0);
265
268
  gtk_widget_show (label);
266
269
 
267
270
  dialog->name_entry = g_object_new (GTK_TYPE_ENTRY, "editable", FALSE, NULL);
268
 
  g_signal_connect (G_OBJECT (dialog->name_entry), "activate", G_CALLBACK (thunar_properties_dialog_activate), dialog);
269
 
  g_signal_connect (G_OBJECT (dialog->name_entry), "focus-out-event", G_CALLBACK (thunar_properties_dialog_focus_out_event), dialog);
 
271
  gtk_label_set_mnemonic_widget (GTK_LABEL (label), dialog->name_entry);
 
272
  g_signal_connect (G_OBJECT (dialog->name_entry), "activate", G_CALLBACK (thunar_properties_dialog_name_activate), dialog);
 
273
  g_signal_connect (G_OBJECT (dialog->name_entry), "focus-out-event", G_CALLBACK (thunar_properties_dialog_name_focus_out_event), dialog);
270
274
  gtk_table_attach (GTK_TABLE (table), dialog->name_entry, 1, 2, row, row + 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 3);
271
 
  gtk_widget_show (dialog->name_entry);
 
275
  exo_binding_new (G_OBJECT (dialog->single_box), "visible", G_OBJECT (dialog->name_entry), "visible");
272
276
 
273
277
  ++row;
274
278
 
275
279
 
276
 
  spacer = g_object_new (GTK_TYPE_ALIGNMENT, "height-request", 12, NULL);
277
 
  gtk_table_attach (GTK_TABLE (table), spacer, 0, 2, row, row + 1, GTK_FILL, GTK_FILL, 0, 3);
278
 
  gtk_widget_show (spacer);
 
280
  /*
 
281
     First box (icon, name) for multiple files
 
282
   */
 
283
  box = gtk_hbox_new (FALSE, 6);
 
284
  gtk_table_attach (GTK_TABLE (table), box, 0, 1, row, row + 1, GTK_FILL, GTK_FILL, 0, 3);
 
285
  exo_binding_new_with_negation (G_OBJECT (dialog->single_box), "visible", G_OBJECT (box), "visible");
 
286
 
 
287
  image = gtk_image_new_from_icon_name ("text-x-generic", GTK_ICON_SIZE_DIALOG);
 
288
  gtk_box_pack_start (GTK_BOX (box), image, FALSE, TRUE, 0);
 
289
  gtk_widget_show (image);
 
290
 
 
291
  label = gtk_label_new (_("Names:"));
 
292
  gtk_label_set_attributes (GTK_LABEL (label), thunar_pango_attr_list_bold ());
 
293
  gtk_misc_set_alignment (GTK_MISC (label), 1.0f, 0.5f);
 
294
  gtk_box_pack_end (GTK_BOX (box), label, TRUE, TRUE, 0);
 
295
  gtk_widget_show (label);
 
296
 
 
297
  dialog->names_label = gtk_label_new ("");
 
298
  gtk_misc_set_alignment (GTK_MISC (dialog->names_label), 0.0f, 0.5f);
 
299
  gtk_table_attach (GTK_TABLE (table), dialog->names_label, 1, 2, row, row + 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 3);
 
300
  gtk_label_set_ellipsize (GTK_LABEL (dialog->names_label), PANGO_ELLIPSIZE_END);
 
301
  gtk_label_set_selectable (GTK_LABEL (dialog->names_label), TRUE);
 
302
  exo_binding_new (G_OBJECT (box), "visible", G_OBJECT (dialog->names_label), "visible");
 
303
 
279
304
 
280
305
  ++row;
281
306
 
286
311
  label = gtk_label_new (_("Kind:"));
287
312
  gtk_label_set_attributes (GTK_LABEL (label), thunar_pango_attr_list_bold ());
288
313
  gtk_misc_set_alignment (GTK_MISC (label), 1.0f, 0.5f);
289
 
  exo_binding_new (G_OBJECT (label), "visible", G_OBJECT (spacer), "visible");
290
314
  gtk_table_attach (GTK_TABLE (table), label, 0, 1, row, row + 1, GTK_FILL, GTK_FILL, 0, 3);
291
315
  gtk_widget_show (label);
292
316
 
305
329
 
306
330
  ++row;
307
331
 
308
 
  label = gtk_label_new (_("Open With:"));
 
332
  label = gtk_label_new_with_mnemonic (_("_Open With:"));
309
333
  gtk_label_set_attributes (GTK_LABEL (label), thunar_pango_attr_list_bold ());
310
334
  gtk_misc_set_alignment (GTK_MISC (label), 1.0f, 0.5f);
311
335
  gtk_table_attach (GTK_TABLE (table), label, 0, 1, row, row + 1, GTK_FILL, GTK_FILL, 0, 3);
312
336
  gtk_widget_show (label);
313
337
 
314
338
  dialog->openwith_chooser = thunar_chooser_button_new ();
315
 
  exo_binding_new (G_OBJECT (dialog), "file", G_OBJECT (dialog->openwith_chooser), "file");
 
339
  gtk_label_set_mnemonic_widget (GTK_LABEL (label), dialog->openwith_chooser);
316
340
  exo_binding_new (G_OBJECT (dialog->openwith_chooser), "visible", G_OBJECT (label), "visible");
317
341
  gtk_table_attach (GTK_TABLE (table), dialog->openwith_chooser, 1, 2, row, row + 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 3);
318
342
  gtk_widget_show (dialog->openwith_chooser);
351
375
 
352
376
  ++row;
353
377
 
 
378
  label = gtk_label_new (_("Location:"));
 
379
  gtk_label_set_attributes (GTK_LABEL (label), thunar_pango_attr_list_bold ());
 
380
  gtk_misc_set_alignment (GTK_MISC (label), 1.0f, 0.5f);
 
381
  gtk_table_attach (GTK_TABLE (table), label, 0, 1, row, row + 1, GTK_FILL, GTK_FILL, 0, 3);
 
382
  gtk_widget_show (label);
 
383
 
 
384
  dialog->location_label = g_object_new (GTK_TYPE_LABEL, "ellipsize", PANGO_ELLIPSIZE_START, "xalign", 0.0f, NULL);
 
385
  gtk_label_set_selectable (GTK_LABEL (dialog->location_label), TRUE);
 
386
  exo_binding_new (G_OBJECT (dialog->location_label), "visible", G_OBJECT (label), "visible");
 
387
  gtk_table_attach (GTK_TABLE (table), dialog->location_label, 1, 2, row, row + 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 3);
 
388
  gtk_widget_show (dialog->location_label);
 
389
 
 
390
  ++row;
 
391
 
354
392
 
355
393
  spacer = g_object_new (GTK_TYPE_ALIGNMENT, "height-request", 12, NULL);
356
394
  gtk_table_attach (GTK_TABLE (table), spacer, 0, 2, row, row + 1, GTK_FILL, GTK_FILL, 0, 3);
407
445
 
408
446
  spacer = g_object_new (GTK_TYPE_ALIGNMENT, "height-request", 12, NULL);
409
447
  gtk_table_attach (GTK_TABLE (table), spacer, 0, 2, row, row + 1, GTK_FILL, GTK_FILL, 0, 3);
410
 
  gtk_widget_show (spacer);
 
448
  exo_binding_new (G_OBJECT (dialog->accessed_label), "visible", G_OBJECT (spacer), "visible");
411
449
 
412
450
  ++row;
413
451
 
422
460
  gtk_widget_show (label);
423
461
 
424
462
  label = thunar_size_label_new ();
425
 
  exo_binding_new (G_OBJECT (dialog), "file", G_OBJECT (label), "file");
 
463
  exo_binding_new (G_OBJECT (dialog), "files", G_OBJECT (label), "files");
426
464
  gtk_table_attach (GTK_TABLE (table), label, 1, 2, row, row + 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 3);
427
465
  gtk_widget_show (label);
428
466
 
479
517
   */
480
518
  label = gtk_label_new (_("Emblems"));
481
519
  chooser = thunar_emblem_chooser_new ();
482
 
  exo_binding_new (G_OBJECT (dialog), "file", G_OBJECT (chooser), "file");
 
520
  exo_binding_new (G_OBJECT (dialog), "files", G_OBJECT (chooser), "files");
483
521
  gtk_notebook_append_page (GTK_NOTEBOOK (dialog->notebook), chooser, label);
484
522
  gtk_widget_show (chooser);
485
523
  gtk_widget_show (label);
486
524
 
487
 
 
488
525
  /*
489
526
     Permissions chooser
490
527
   */
491
528
  label = gtk_label_new (_("Permissions"));
492
529
  dialog->permissions_chooser = thunar_permissions_chooser_new ();
493
 
  exo_binding_new (G_OBJECT (dialog), "file", G_OBJECT (dialog->permissions_chooser), "file");
 
530
  exo_binding_new (G_OBJECT (dialog), "files", G_OBJECT (dialog->permissions_chooser), "files");
494
531
  gtk_notebook_append_page (GTK_NOTEBOOK (dialog->notebook), dialog->permissions_chooser, label);
495
532
  gtk_widget_show (dialog->permissions_chooser);
496
533
  gtk_widget_show (label);
497
 
 
498
 
 
499
 
  /* place the initial focus on the name entry widget */
500
 
  gtk_widget_grab_focus (dialog->name_entry);
501
534
}
502
535
 
503
536
 
508
541
  ThunarPropertiesDialog *dialog = THUNAR_PROPERTIES_DIALOG (object);
509
542
 
510
543
  /* reset the file displayed by the dialog */
511
 
  thunar_properties_dialog_set_file (dialog, NULL);
 
544
  thunar_properties_dialog_set_files (dialog, NULL);
512
545
 
513
546
  (*G_OBJECT_CLASS (thunar_properties_dialog_parent_class)->dispose) (object);
514
547
}
520
553
{
521
554
  ThunarPropertiesDialog *dialog = THUNAR_PROPERTIES_DIALOG (object);
522
555
 
 
556
  _thunar_return_if_fail (dialog->files == NULL);
 
557
 
523
558
  /* disconnect from the preferences */
524
559
  g_signal_handlers_disconnect_by_func (dialog->preferences, thunar_properties_dialog_reload, dialog);
525
560
  g_object_unref (dialog->preferences);
535
570
  g_object_unref (dialog->thumbnailer);
536
571
 
537
572
  /* release the provider property pages */
538
 
  g_list_foreach (dialog->provider_pages, (GFunc) g_object_unref, NULL);
539
 
  g_list_free (dialog->provider_pages);
 
573
  g_list_free_full (dialog->provider_pages, g_object_unref);
540
574
 
541
575
  /* drop the reference on the provider factory */
542
576
  g_object_unref (dialog->provider_factory);
556
590
 
557
591
  switch (prop_id)
558
592
    {
559
 
    case PROP_FILE:
560
 
      g_value_set_object (value, thunar_properties_dialog_get_file (dialog));
 
593
    case PROP_FILES:
 
594
      g_value_set_boxed (value, thunar_properties_dialog_get_files (dialog));
561
595
      break;
562
596
 
563
597
    default:
578
612
 
579
613
  switch (prop_id)
580
614
    {
581
 
    case PROP_FILE:
582
 
      thunar_properties_dialog_set_file (dialog, g_value_get_object (value));
 
615
    case PROP_FILES:
 
616
      thunar_properties_dialog_set_files (dialog, g_value_get_boxed (value));
583
617
      break;
584
618
 
585
619
    default:
615
649
static gboolean
616
650
thunar_properties_dialog_reload (ThunarPropertiesDialog *dialog)
617
651
{
618
 
  /* verify that we still have a file */
619
 
  if (G_LIKELY (dialog->file != NULL))
620
 
    {
621
 
      /* reload the file status */
622
 
      thunar_file_reload (dialog->file);
 
652
  /* reload the active files */
 
653
  g_list_foreach (dialog->files, (GFunc) thunar_file_reload, NULL);
623
654
 
624
 
      /* we handled the event */
625
 
      return TRUE;
626
 
    }
627
 
  else
628
 
    {
629
 
      /* did not handle the event */
630
 
      return FALSE;
631
 
    }
 
655
  return dialog->files != NULL;
632
656
}
633
657
 
634
658
 
641
665
  _thunar_return_if_fail (EXO_IS_JOB (job));
642
666
  _thunar_return_if_fail (error != NULL);
643
667
  _thunar_return_if_fail (THUNAR_IS_PROPERTIES_DIALOG (dialog));
 
668
  _thunar_return_if_fail (g_list_length (dialog->files) == 1);
644
669
 
645
670
  /* display an error message */
646
671
  thunar_dialogs_show_error (GTK_WIDGET (dialog), error, _("Failed to rename \"%s\""),
647
 
                             thunar_file_get_display_name (dialog->file));
 
672
                             thunar_file_get_display_name (THUNAR_FILE (dialog->files->data)));
648
673
}
649
674
 
650
675
 
653
678
thunar_properties_dialog_rename_finished (ExoJob                 *job,
654
679
                                          ThunarPropertiesDialog *dialog)
655
680
{
656
 
  const gchar *new_name;
657
 
 
658
681
  _thunar_return_if_fail (EXO_IS_JOB (job));
659
682
  _thunar_return_if_fail (THUNAR_IS_PROPERTIES_DIALOG (dialog));
660
 
 
661
 
  /* determine the new display name */
662
 
  new_name = thunar_file_get_display_name (dialog->file);
663
 
 
664
 
  /* reset the entry widget to the new name */
665
 
  gtk_entry_set_text (GTK_ENTRY (dialog->name_entry), new_name);
 
683
  _thunar_return_if_fail (g_list_length (dialog->files) == 1);
666
684
 
667
685
  g_signal_handlers_disconnect_matched (job, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, dialog);
668
686
  g_object_unref (job);
671
689
 
672
690
 
673
691
static void
674
 
thunar_properties_dialog_activate (GtkWidget              *entry,
675
 
                                   ThunarPropertiesDialog *dialog)
 
692
thunar_properties_dialog_name_activate (GtkWidget              *entry,
 
693
                                        ThunarPropertiesDialog *dialog)
676
694
{
677
695
  const gchar *old_name;
678
696
  ThunarJob   *job;
679
697
  gchar       *new_name;
 
698
  ThunarFile  *file;
 
699
 
 
700
  _thunar_return_if_fail (THUNAR_IS_PROPERTIES_DIALOG (dialog));
680
701
 
681
702
  /* check if we still have a valid file and if the user is allowed to rename */
682
 
  if (G_UNLIKELY (dialog->file == NULL || !GTK_WIDGET_SENSITIVE (dialog->name_entry)))
 
703
  if (G_UNLIKELY (!gtk_widget_get_sensitive (dialog->name_entry)
 
704
      || g_list_length (dialog->files) != 1))
683
705
    return;
684
706
 
685
707
  /* determine new and old name */
 
708
  file = THUNAR_FILE (dialog->files->data);
686
709
  new_name = gtk_editable_get_chars (GTK_EDITABLE (dialog->name_entry), 0, -1);
687
 
  old_name = thunar_file_get_display_name (dialog->file);
 
710
  old_name = thunar_file_get_display_name (file);
688
711
  if (g_utf8_collate (new_name, old_name) != 0)
689
712
    {
690
 
      job = thunar_io_jobs_rename_file (dialog->file, new_name);
 
713
      job = thunar_io_jobs_rename_file (file, new_name);
691
714
      if (job != NULL)
692
715
        {
693
716
          g_signal_connect (job, "error", G_CALLBACK (thunar_properties_dialog_rename_error), dialog);
699
722
 
700
723
 
701
724
static gboolean
702
 
thunar_properties_dialog_focus_out_event (GtkWidget              *entry,
703
 
                                          GdkEventFocus          *event,
704
 
                                          ThunarPropertiesDialog *dialog)
 
725
thunar_properties_dialog_name_focus_out_event (GtkWidget              *entry,
 
726
                                               GdkEventFocus          *event,
 
727
                                               ThunarPropertiesDialog *dialog)
705
728
{
706
 
  thunar_properties_dialog_activate (entry, dialog);
 
729
  thunar_properties_dialog_name_activate (entry, dialog);
707
730
  return FALSE;
708
731
}
709
732
 
713
736
thunar_properties_dialog_icon_button_clicked (GtkWidget              *button,
714
737
                                              ThunarPropertiesDialog *dialog)
715
738
{
716
 
  GtkWidget *chooser;
717
 
  GError    *err = NULL;
718
 
  gchar     *custom_icon;
719
 
  gchar     *title;
720
 
  gchar     *icon;
 
739
  GtkWidget   *chooser;
 
740
  GError      *err = NULL;
 
741
  const gchar *custom_icon;
 
742
  gchar       *title;
 
743
  gchar       *icon;
 
744
  ThunarFile  *file;
721
745
 
722
746
  _thunar_return_if_fail (THUNAR_IS_PROPERTIES_DIALOG (dialog));
723
747
  _thunar_return_if_fail (GTK_IS_BUTTON (button));
 
748
  _thunar_return_if_fail (g_list_length (dialog->files) == 1);
724
749
 
725
750
  /* make sure we still have a file */
726
 
  if (G_UNLIKELY (dialog->file == NULL))
 
751
  if (G_UNLIKELY (dialog->files == NULL))
727
752
    return;
728
753
 
 
754
  file = THUNAR_FILE (dialog->files->data);
 
755
 
729
756
  /* allocate the icon chooser */
730
 
  title = g_strdup_printf (_("Select an Icon for \"%s\""), thunar_file_get_display_name (dialog->file));
 
757
  title = g_strdup_printf (_("Select an Icon for \"%s\""), thunar_file_get_display_name (file));
731
758
  chooser = exo_icon_chooser_dialog_new (title, GTK_WINDOW (dialog),
732
759
                                         GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
733
760
                                         GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
737
764
  g_free (title);
738
765
 
739
766
  /* use the custom_icon of the file as default */
740
 
  custom_icon = thunar_file_get_custom_icon (dialog->file);
 
767
  custom_icon = thunar_file_get_custom_icon (file);
741
768
  if (G_LIKELY (custom_icon != NULL && *custom_icon != '\0'))
742
769
    exo_icon_chooser_dialog_set_icon (EXO_ICON_CHOOSER_DIALOG (chooser), custom_icon);
743
 
  g_free (custom_icon);
744
770
 
745
771
  /* run the icon chooser dialog and make sure the dialog still has a file */
746
 
  if (gtk_dialog_run (GTK_DIALOG (chooser)) == GTK_RESPONSE_ACCEPT && dialog->file != NULL)
 
772
  if (gtk_dialog_run (GTK_DIALOG (chooser)) == GTK_RESPONSE_ACCEPT && file != NULL)
747
773
    {
748
774
      /* determine the selected icon and use it for the file */
749
775
      icon = exo_icon_chooser_dialog_get_icon (EXO_ICON_CHOOSER_DIALOG (chooser));
750
 
      if (!thunar_file_set_custom_icon (dialog->file, icon, &err))
 
776
      if (!thunar_file_set_custom_icon (file, icon, &err))
751
777
        {
752
778
          /* hide the icon chooser dialog first */
753
779
          gtk_widget_hide (chooser);
754
780
 
755
781
          /* tell the user that we failed to change the icon of the .desktop file */
756
 
          thunar_dialogs_show_error (GTK_WIDGET (dialog), err, _("Failed to change icon of \"%s\""), thunar_file_get_display_name (dialog->file));
 
782
          thunar_dialogs_show_error (GTK_WIDGET (dialog), err,
 
783
                                     _("Failed to change icon of \"%s\""),
 
784
                                     thunar_file_get_display_name (file));
757
785
          g_error_free (err);
758
786
        }
759
787
      g_free (icon);
771
799
  GtkWidget *label_widget;
772
800
  GList     *providers;
773
801
  GList     *pages = NULL;
774
 
  GList      files;
775
802
  GList     *tmp;
776
803
  GList     *lp;
777
804
 
779
806
  providers = thunarx_provider_factory_list_providers (dialog->provider_factory, THUNARX_TYPE_PROPERTY_PAGE_PROVIDER);
780
807
  if (G_LIKELY (providers != NULL))
781
808
    {
782
 
      /* determine the (one-element) file list */
783
 
      files.data = dialog->file; files.next = files.prev = NULL;
784
 
 
785
809
      /* load the pages offered by the menu providers */
786
810
      for (lp = providers; lp != NULL; lp = lp->next)
787
811
        {
788
 
          tmp = thunarx_property_page_provider_get_pages (lp->data, &files);
 
812
          tmp = thunarx_property_page_provider_get_pages (lp->data, dialog->files);
789
813
          pages = g_list_concat (pages, tmp);
790
814
          g_object_unref (G_OBJECT (lp->data));
791
815
        }
814
838
 
815
839
 
816
840
static void
817
 
thunar_properties_dialog_update (ThunarPropertiesDialog *dialog)
 
841
thunar_properties_dialog_update_single (ThunarPropertiesDialog *dialog)
818
842
{
819
843
  ThunarIconFactory *icon_factory;
820
844
  ThunarDateStyle    date_style;
823
847
  const gchar       *name;
824
848
  const gchar       *path;
825
849
  GVolume           *volume;
826
 
  guint64            size;
827
850
  GIcon             *gicon;
828
851
  glong              offset;
829
852
  gchar             *date;
830
853
  gchar             *display_name;
831
 
  gchar             *size_string;
 
854
  gchar             *fs_string;
832
855
  gchar             *str;
833
856
  gchar             *volume_name;
 
857
  ThunarFile        *file;
 
858
  ThunarFile        *parent_file;
 
859
  gboolean           show_chooser;
834
860
 
835
861
  _thunar_return_if_fail (THUNAR_IS_PROPERTIES_DIALOG (dialog));
836
 
  _thunar_return_if_fail (THUNAR_IS_FILE (dialog->file));
837
 
 
838
 
  /* cancel any pending thumbnail requests */
839
 
  if (dialog->thumbnail_request > 0)
840
 
    {
841
 
      thunar_thumbnailer_dequeue (dialog->thumbnailer, dialog->thumbnail_request);
842
 
      dialog->thumbnail_request = 0;
843
 
    }
844
 
 
845
 
  if (dialog->file != NULL)
846
 
    {
847
 
      /* queue a new thumbnail request */
848
 
      thunar_thumbnailer_queue_file (dialog->thumbnailer, dialog->file, 
849
 
                                     &dialog->thumbnail_request);
850
 
    }
 
862
  _thunar_return_if_fail (g_list_length (dialog->files) == 1);
 
863
  _thunar_return_if_fail (THUNAR_IS_FILE (dialog->files->data));
 
864
 
 
865
  /* whether the dialog shows a single file or a group of files */
 
866
  file = THUNAR_FILE (dialog->files->data);
 
867
 
 
868
  /* hide the permissions chooser for trashed files */
 
869
  gtk_widget_set_visible (dialog->permissions_chooser, !thunar_file_is_trashed (file));
 
870
 
 
871
  /* queue a new thumbnail request */
 
872
  thunar_thumbnailer_queue_file (dialog->thumbnailer, file,
 
873
                                 &dialog->thumbnail_request);
851
874
 
852
875
  icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (dialog)));
853
876
  icon_factory = thunar_icon_factory_get_for_icon_theme (icon_theme);
856
879
  g_object_get (G_OBJECT (dialog->preferences), "misc-date-style", &date_style, NULL);
857
880
 
858
881
  /* update the properties dialog title */
859
 
  str = g_strdup_printf (_("%s - Properties"), thunar_file_get_display_name (dialog->file));
 
882
  str = g_strdup_printf (_("%s - Properties"), thunar_file_get_display_name (file));
860
883
  gtk_window_set_title (GTK_WINDOW (dialog), str);
861
884
  g_free (str);
862
885
 
863
886
  /* update the preview image */
864
 
  thunar_image_set_file (THUNAR_IMAGE (dialog->icon_image), dialog->file);
 
887
  thunar_image_set_file (THUNAR_IMAGE (dialog->icon_image), file);
865
888
 
866
889
  /* check if the icon may be changed (only for writable .desktop files) */
867
890
  g_object_ref (G_OBJECT (dialog->icon_image));
868
891
  gtk_container_remove (GTK_CONTAINER (gtk_widget_get_parent (dialog->icon_image)), dialog->icon_image);
869
 
  if (thunar_file_is_writable (dialog->file) && thunar_file_is_desktop_file (dialog->file))
 
892
  if (thunar_file_is_writable (file)
 
893
      && thunar_file_is_desktop_file (file, NULL))
870
894
    {
871
895
      gtk_container_add (GTK_CONTAINER (dialog->icon_button), dialog->icon_image);
872
896
      gtk_widget_show (dialog->icon_button);
879
903
  g_object_unref (G_OBJECT (dialog->icon_image));
880
904
 
881
905
  /* update the name (if it differs) */
882
 
  gtk_editable_set_editable (GTK_EDITABLE (dialog->name_entry), thunar_file_is_renameable (dialog->file));
883
 
  name = thunar_file_get_display_name (dialog->file);
 
906
  gtk_editable_set_editable (GTK_EDITABLE (dialog->name_entry), thunar_file_is_renameable (file));
 
907
  name = thunar_file_get_display_name (file);
884
908
  if (G_LIKELY (strcmp (name, gtk_entry_get_text (GTK_ENTRY (dialog->name_entry))) != 0))
885
909
    {
886
910
      gtk_entry_set_text (GTK_ENTRY (dialog->name_entry), name);
902
926
    }
903
927
 
904
928
  /* update the content type */
905
 
  content_type = thunar_file_get_content_type (dialog->file);
 
929
  content_type = thunar_file_get_content_type (file);
906
930
  if (content_type != NULL)
907
931
    {
908
932
      if (G_UNLIKELY (g_content_type_equals (content_type, "inode/symlink")))
909
933
        str = g_strdup (_("broken link"));
910
 
      else if (G_UNLIKELY (thunar_file_is_symlink (dialog->file)))
911
 
        str = g_strdup_printf (_("link to %s"), thunar_file_get_symlink_target (dialog->file));
 
934
      else if (G_UNLIKELY (thunar_file_is_symlink (file)))
 
935
        str = g_strdup_printf (_("link to %s"), thunar_file_get_symlink_target (file));
912
936
      else
913
937
        str = g_content_type_get_description (content_type);
914
938
      gtk_widget_set_tooltip_text (dialog->kind_ebox, content_type);
921
945
    }
922
946
 
923
947
  /* update the application chooser (shown only for non-executable regular files!) */
924
 
  g_object_set (G_OBJECT (dialog->openwith_chooser),
925
 
                "visible", (thunar_file_is_regular (dialog->file) && !thunar_file_is_executable (dialog->file)),
926
 
                NULL);
 
948
  show_chooser = thunar_file_is_regular (file) && !thunar_file_is_executable (file);
 
949
  gtk_widget_set_visible (dialog->openwith_chooser, show_chooser);
 
950
  if (show_chooser)
 
951
    thunar_chooser_button_set_file (THUNAR_CHOOSER_BUTTON (dialog->openwith_chooser), file);
927
952
 
928
953
  /* update the link target */
929
 
  path = thunar_file_is_symlink (dialog->file) ? thunar_file_get_symlink_target (dialog->file) : NULL;
 
954
  path = thunar_file_is_symlink (file) ? thunar_file_get_symlink_target (file) : NULL;
930
955
  if (G_UNLIKELY (path != NULL))
931
956
    {
932
957
      display_name = g_filename_display_name (path);
940
965
    }
941
966
 
942
967
  /* update the original path */
943
 
  path = thunar_file_get_original_path (dialog->file);
 
968
  path = thunar_file_get_original_path (file);
944
969
  if (G_UNLIKELY (path != NULL))
945
970
    {
946
971
      display_name = g_filename_display_name (path);
953
978
      gtk_widget_hide (dialog->origin_label);
954
979
    }
955
980
 
 
981
  /* update the file or folder location (parent) */
 
982
  parent_file = thunar_file_get_parent (file, NULL);
 
983
  if (G_UNLIKELY (parent_file != NULL))
 
984
    {
 
985
      display_name = g_file_get_parse_name (thunar_file_get_file (parent_file));
 
986
      gtk_label_set_text (GTK_LABEL (dialog->location_label), display_name);
 
987
      gtk_widget_show (dialog->location_label);
 
988
      g_object_unref (G_OBJECT (parent_file));
 
989
      g_free (display_name);
 
990
    }
 
991
  else
 
992
    {
 
993
      gtk_widget_hide (dialog->location_label);
 
994
    }
 
995
 
956
996
  /* update the deleted time */
957
 
  date = thunar_file_get_deletion_date (dialog->file, date_style);
 
997
  date = thunar_file_get_deletion_date (file, date_style);
958
998
  if (G_LIKELY (date != NULL))
959
999
    {
960
1000
      gtk_label_set_text (GTK_LABEL (dialog->deleted_label), date);
967
1007
    }
968
1008
 
969
1009
  /* update the modified time */
970
 
  date = thunar_file_get_date_string (dialog->file, THUNAR_FILE_DATE_MODIFIED, date_style);
 
1010
  date = thunar_file_get_date_string (file, THUNAR_FILE_DATE_MODIFIED, date_style);
971
1011
  if (G_LIKELY (date != NULL))
972
1012
    {
973
1013
      gtk_label_set_text (GTK_LABEL (dialog->modified_label), date);
980
1020
    }
981
1021
 
982
1022
  /* update the accessed time */
983
 
  date = thunar_file_get_date_string (dialog->file, THUNAR_FILE_DATE_ACCESSED, date_style);
 
1023
  date = thunar_file_get_date_string (file, THUNAR_FILE_DATE_ACCESSED, date_style);
984
1024
  if (G_LIKELY (date != NULL))
985
1025
    {
986
1026
      gtk_label_set_text (GTK_LABEL (dialog->accessed_label), date);
993
1033
    }
994
1034
 
995
1035
  /* update the free space (only for folders) */
996
 
  if (thunar_file_is_directory (dialog->file) 
997
 
      && thunar_file_get_free_space (dialog->file, &size))
 
1036
  if (thunar_file_is_directory (file))
998
1037
    {
999
 
#if GLIB_CHECK_VERSION (2, 30, 0)
1000
 
      size_string = g_format_size (size);
1001
 
#else
1002
 
      size_string = g_format_size_for_display (size);
1003
 
#endif
1004
 
      gtk_label_set_text (GTK_LABEL (dialog->freespace_label), size_string);
1005
 
      gtk_widget_show (dialog->freespace_label);
1006
 
      g_free (size_string);
 
1038
      fs_string = thunar_g_file_get_free_space_string (thunar_file_get_file (file));
 
1039
      if (fs_string != NULL)
 
1040
        {
 
1041
          gtk_label_set_text (GTK_LABEL (dialog->freespace_label), fs_string);
 
1042
          gtk_widget_show (dialog->freespace_label);
 
1043
          g_free (fs_string);
 
1044
        }
 
1045
      else
 
1046
        {
 
1047
          gtk_widget_hide (dialog->freespace_label);
 
1048
        }
1007
1049
    }
1008
1050
  else
1009
1051
    {
1011
1053
    }
1012
1054
 
1013
1055
  /* update the volume */
1014
 
  volume = thunar_file_get_volume (dialog->file);
 
1056
  volume = thunar_file_get_volume (file);
1015
1057
  if (G_LIKELY (volume != NULL))
1016
1058
    {
1017
1059
      gicon = g_volume_get_icon (volume);
1035
1077
 
1036
1078
 
1037
1079
 
 
1080
static void
 
1081
thunar_properties_dialog_update_multiple (ThunarPropertiesDialog *dialog)
 
1082
{
 
1083
  ThunarFile  *file;
 
1084
  GString     *names_string;
 
1085
  gboolean     first_file = TRUE;
 
1086
  GList       *lp;
 
1087
  const gchar *content_type = NULL;
 
1088
  const gchar *tmp;
 
1089
  gchar       *str;
 
1090
  GVolume     *volume = NULL;
 
1091
  GVolume     *tmp_volume;
 
1092
  GIcon       *gicon;
 
1093
  gchar       *volume_name;
 
1094
  gchar       *display_name;
 
1095
  ThunarFile  *parent_file = NULL;
 
1096
  ThunarFile  *tmp_parent;
 
1097
  gboolean     has_trashed_files = FALSE;
 
1098
 
 
1099
  _thunar_return_if_fail (THUNAR_IS_PROPERTIES_DIALOG (dialog));
 
1100
  _thunar_return_if_fail (g_list_length (dialog->files) > 1);
 
1101
 
 
1102
  /* update the properties dialog title */
 
1103
  gtk_window_set_title (GTK_WINDOW (dialog), _("Properties"));
 
1104
 
 
1105
  /* widgets not used with > 1 file selected */
 
1106
  gtk_widget_hide (dialog->deleted_label);
 
1107
  gtk_widget_hide (dialog->modified_label);
 
1108
  gtk_widget_hide (dialog->accessed_label);
 
1109
  gtk_widget_hide (dialog->freespace_label);
 
1110
  gtk_widget_hide (dialog->origin_label);
 
1111
  gtk_widget_hide (dialog->openwith_chooser);
 
1112
  gtk_widget_hide (dialog->link_label);
 
1113
 
 
1114
  names_string = g_string_new (NULL);
 
1115
 
 
1116
  /* collect data of the selected files */
 
1117
  for (lp = dialog->files; lp != NULL; lp = lp->next)
 
1118
    {
 
1119
      _thunar_assert (THUNAR_IS_FILE (lp->data));
 
1120
      file = THUNAR_FILE (lp->data);
 
1121
 
 
1122
      /* append the name */
 
1123
      if (!first_file)
 
1124
        g_string_append (names_string, ", ");
 
1125
      g_string_append (names_string, thunar_file_get_display_name (file));
 
1126
 
 
1127
      /* update the content type */
 
1128
      if (first_file)
 
1129
        {
 
1130
          content_type = thunar_file_get_content_type (file);
 
1131
        }
 
1132
      else if (content_type != NULL)
 
1133
        {
 
1134
          /* check the types match */
 
1135
          tmp = thunar_file_get_content_type (file);
 
1136
          if (tmp == NULL || !g_content_type_equals (content_type, tmp))
 
1137
            content_type = NULL;
 
1138
        }
 
1139
 
 
1140
      /* check if all selected files are on the same volume */
 
1141
      tmp_volume = thunar_file_get_volume (file);
 
1142
      if (first_file)
 
1143
        {
 
1144
          volume = tmp_volume;
 
1145
        }
 
1146
      else if (tmp_volume != NULL)
 
1147
        {
 
1148
          /* we only display information if the files are on the same volume */
 
1149
          if (tmp_volume != volume)
 
1150
            {
 
1151
              if (volume != NULL)
 
1152
                g_object_unref (G_OBJECT (volume));
 
1153
              volume = NULL;
 
1154
            }
 
1155
 
 
1156
          g_object_unref (G_OBJECT (tmp_volume));
 
1157
        }
 
1158
 
 
1159
      /* check if all files have the same parent */
 
1160
      tmp_parent = thunar_file_get_parent (file, NULL);
 
1161
      if (first_file)
 
1162
        {
 
1163
          parent_file = tmp_parent;
 
1164
        }
 
1165
      else if (tmp_parent != NULL)
 
1166
        {
 
1167
          /* we only display the location if they are all equal */
 
1168
          if (!g_file_equal (thunar_file_get_file (parent_file), thunar_file_get_file (tmp_parent)))
 
1169
            {
 
1170
              if (parent_file != NULL)
 
1171
                g_object_unref (G_OBJECT (parent_file));
 
1172
              parent_file = NULL;
 
1173
            }
 
1174
 
 
1175
          g_object_unref (G_OBJECT (tmp_parent));
 
1176
        }
 
1177
 
 
1178
      if (thunar_file_is_trashed (file))
 
1179
        has_trashed_files = TRUE;
 
1180
 
 
1181
      first_file = FALSE;
 
1182
    }
 
1183
 
 
1184
  /* set the labels string */
 
1185
  gtk_label_set_text (GTK_LABEL (dialog->names_label), names_string->str);
 
1186
  gtk_widget_set_tooltip_text (dialog->names_label, names_string->str);
 
1187
  g_string_free (names_string, TRUE);
 
1188
 
 
1189
  /* hide the permissions chooser for trashed files */
 
1190
  gtk_widget_set_visible (dialog->permissions_chooser, !has_trashed_files);
 
1191
 
 
1192
  /* update the content type */
 
1193
  if (content_type != NULL
 
1194
      && !g_content_type_equals (content_type, "inode/symlink"))
 
1195
    {
 
1196
      str = g_content_type_get_description (content_type);
 
1197
      gtk_widget_set_tooltip_text (dialog->kind_ebox, content_type);
 
1198
      gtk_label_set_text (GTK_LABEL (dialog->kind_label), str);
 
1199
      g_free (str);
 
1200
    }
 
1201
  else
 
1202
    {
 
1203
      gtk_label_set_text (GTK_LABEL (dialog->kind_label), _("mixed"));
 
1204
    }
 
1205
 
 
1206
  /* update the file or folder location (parent) */
 
1207
  if (G_UNLIKELY (parent_file != NULL))
 
1208
    {
 
1209
      display_name = g_file_get_parse_name (thunar_file_get_file (parent_file));
 
1210
      gtk_label_set_text (GTK_LABEL (dialog->location_label), display_name);
 
1211
      gtk_widget_show (dialog->location_label);
 
1212
      g_object_unref (G_OBJECT (parent_file));
 
1213
      g_free (display_name);
 
1214
    }
 
1215
  else
 
1216
    {
 
1217
      gtk_widget_hide (dialog->location_label);
 
1218
    }
 
1219
 
 
1220
  /* update the volume */
 
1221
  if (G_LIKELY (volume != NULL))
 
1222
    {
 
1223
      gicon = g_volume_get_icon (volume);
 
1224
      gtk_image_set_from_gicon (GTK_IMAGE (dialog->volume_image), gicon, GTK_ICON_SIZE_MENU);
 
1225
      if (G_LIKELY (gicon != NULL))
 
1226
        g_object_unref (gicon);
 
1227
 
 
1228
      volume_name = g_volume_get_name (volume);
 
1229
      gtk_label_set_text (GTK_LABEL (dialog->volume_label), volume_name);
 
1230
      gtk_widget_show (dialog->volume_label);
 
1231
      g_free (volume_name);
 
1232
 
 
1233
      g_object_unref (G_OBJECT (volume));
 
1234
    }
 
1235
  else
 
1236
    {
 
1237
      gtk_widget_hide (dialog->volume_label);
 
1238
    }
 
1239
}
 
1240
 
 
1241
 
 
1242
 
 
1243
static void
 
1244
thunar_properties_dialog_update (ThunarPropertiesDialog *dialog)
 
1245
{
 
1246
  _thunar_return_if_fail (THUNAR_IS_PROPERTIES_DIALOG (dialog));
 
1247
  _thunar_return_if_fail (dialog->files != NULL);
 
1248
 
 
1249
  /* cancel any pending thumbnail requests */
 
1250
  if (dialog->thumbnail_request > 0)
 
1251
    {
 
1252
      thunar_thumbnailer_dequeue (dialog->thumbnailer, dialog->thumbnail_request);
 
1253
      dialog->thumbnail_request = 0;
 
1254
    }
 
1255
 
 
1256
  if (dialog->files->next == NULL)
 
1257
    {
 
1258
      /* show single file name box */
 
1259
      gtk_widget_show (dialog->single_box);
 
1260
 
 
1261
      /* update the properties for a dialog showing 1 file */
 
1262
      thunar_properties_dialog_update_single (dialog);
 
1263
 
 
1264
      /* place the initial focus on the name entry widget */
 
1265
      gtk_widget_grab_focus (dialog->name_entry);
 
1266
    }
 
1267
  else
 
1268
    {
 
1269
      /* show multiple files box */
 
1270
      gtk_widget_hide (dialog->single_box);
 
1271
 
 
1272
      /* update the properties for a dialog showing multiple files */
 
1273
      thunar_properties_dialog_update_multiple (dialog);
 
1274
    }
 
1275
}
 
1276
 
 
1277
 
 
1278
 
1038
1279
/**
1039
1280
 * thunar_properties_dialog_new:
 
1281
 * @parent: transient window or NULL;
1040
1282
 *
1041
1283
 * Allocates a new #ThunarPropertiesDialog instance,
1042
1284
 * that is not associated with any #ThunarFile.
1045
1287
 *               instance.
1046
1288
 **/
1047
1289
GtkWidget*
1048
 
thunar_properties_dialog_new (void)
 
1290
thunar_properties_dialog_new (GtkWindow *parent)
1049
1291
{
1050
 
  return g_object_new (THUNAR_TYPE_PROPERTIES_DIALOG, NULL);
 
1292
  _thunar_return_val_if_fail (parent == NULL || GTK_IS_WINDOW (parent), NULL);
 
1293
  return g_object_new (THUNAR_TYPE_PROPERTIES_DIALOG,
 
1294
                       "transient-for", parent,
 
1295
                       "destroy-with-parent", parent != NULL,
 
1296
                       NULL);
1051
1297
}
1052
1298
 
1053
1299
 
1054
1300
 
1055
1301
/**
1056
 
 * thunar_properties_dialog_get_file:
 
1302
 * thunar_properties_dialog_get_files:
1057
1303
 * @dialog : a #ThunarPropertiesDialog.
1058
1304
 *
1059
1305
 * Returns the #ThunarFile currently being displayed
1060
1306
 * by @dialog or %NULL if @dialog doesn't display
1061
1307
 * any file right now.
1062
1308
 *
1063
 
 * Return value: the #ThunarFile displayed by @dialog
 
1309
 * Return value: list of #ThunarFile's displayed by @dialog
1064
1310
 *               or %NULL.
1065
1311
 **/
1066
 
ThunarFile*
1067
 
thunar_properties_dialog_get_file (ThunarPropertiesDialog *dialog)
 
1312
static GList*
 
1313
thunar_properties_dialog_get_files (ThunarPropertiesDialog *dialog)
1068
1314
{
1069
1315
  _thunar_return_val_if_fail (THUNAR_IS_PROPERTIES_DIALOG (dialog), NULL);
1070
 
  return dialog->file;
 
1316
  return dialog->files;
1071
1317
}
1072
1318
 
1073
1319
 
1074
1320
 
1075
1321
/**
1076
 
 * thunar_properties_dialog_set_file:
 
1322
 * thunar_properties_dialog_set_files:
1077
1323
 * @dialog : a #ThunarPropertiesDialog.
1078
 
 * @file   : a #ThunarFile or %NULL.
 
1324
 * @files  : a GList of #ThunarFile's or %NULL.
1079
1325
 *
1080
1326
 * Sets the #ThunarFile that is displayed by @dialog
1081
 
 * to @file.
 
1327
 * to @files.
1082
1328
 **/
1083
1329
void
1084
 
thunar_properties_dialog_set_file (ThunarPropertiesDialog *dialog,
1085
 
                                   ThunarFile             *file)
 
1330
thunar_properties_dialog_set_files (ThunarPropertiesDialog *dialog,
 
1331
                                    GList                  *files)
1086
1332
{
 
1333
  GList      *lp;
 
1334
  ThunarFile *file;
 
1335
 
1087
1336
  _thunar_return_if_fail (THUNAR_IS_PROPERTIES_DIALOG (dialog));
1088
 
  _thunar_return_if_fail (file == NULL || THUNAR_IS_FILE (file));
1089
1337
 
1090
 
  /* check if we already display that file */
1091
 
  if (G_UNLIKELY (dialog->file == file))
 
1338
  /* check if the same lists are used (or null) */
 
1339
  if (G_UNLIKELY (dialog->files == files))
1092
1340
    return;
1093
1341
 
1094
 
  /* disconnect from any previously set file */
1095
 
  if (dialog->file != NULL)
 
1342
  /* disconnect from any previously set files */
 
1343
  for (lp = dialog->files; lp != NULL; lp = lp->next)
1096
1344
    {
 
1345
      file = THUNAR_FILE (lp->data);
 
1346
 
1097
1347
      /* unregister our file watch */
1098
 
      thunar_file_unwatch (dialog->file);
 
1348
      thunar_file_unwatch (file);
1099
1349
 
1100
1350
      /* unregister handlers */
1101
 
      g_signal_handlers_disconnect_by_func (G_OBJECT (dialog->file), thunar_properties_dialog_update, dialog);
1102
 
      g_signal_handlers_disconnect_by_func (G_OBJECT (dialog->file), gtk_widget_destroy, dialog);
 
1351
      g_signal_handlers_disconnect_by_func (G_OBJECT (file), thunar_properties_dialog_update, dialog);
 
1352
      g_signal_handlers_disconnect_by_func (G_OBJECT (file), gtk_widget_destroy, dialog);
1103
1353
 
1104
 
      g_object_unref (G_OBJECT (dialog->file));
 
1354
      g_object_unref (G_OBJECT (file));
1105
1355
    }
1106
 
 
1107
 
  /* activate the new file */
1108
 
  dialog->file = file;
1109
 
 
1110
 
  /* connect to the new file */
1111
 
  if (file != NULL)
 
1356
  g_list_free (dialog->files);
 
1357
 
 
1358
  /* activate the new list */
 
1359
  dialog->files = g_list_copy (files);
 
1360
 
 
1361
  /* connect to the new files */
 
1362
  for (lp = dialog->files; lp != NULL; lp = lp->next)
1112
1363
    {
1113
 
      g_object_ref (G_OBJECT (file));
 
1364
      _thunar_assert (THUNAR_IS_FILE (lp->data));
 
1365
      file = g_object_ref (G_OBJECT (lp->data));
1114
1366
 
1115
1367
      /* watch the file for changes */
1116
1368
      thunar_file_watch (file);
1118
1370
      /* install signal handlers */
1119
1371
      g_signal_connect_swapped (G_OBJECT (file), "changed", G_CALLBACK (thunar_properties_dialog_update), dialog);
1120
1372
      g_signal_connect_swapped (G_OBJECT (file), "destroy", G_CALLBACK (gtk_widget_destroy), dialog);
 
1373
    }
1121
1374
 
 
1375
  /* update the dialog contents */
 
1376
  if (dialog->files != NULL)
 
1377
    {
1122
1378
      /* update the UI for the new file */
1123
1379
      thunar_properties_dialog_update (dialog);
1124
1380
 
1125
1381
      /* update the provider property pages */
1126
1382
      thunar_properties_dialog_update_providers (dialog);
1127
 
 
1128
 
      /* hide the permissions chooser for trashed files */
1129
 
      if (thunar_file_is_trashed (file))
1130
 
        gtk_widget_hide (dialog->permissions_chooser);
1131
 
      else
1132
 
        gtk_widget_show (dialog->permissions_chooser);
1133
1383
    }
1134
1384
 
1135
1385
  /* tell everybody that we have a new file here */
1136
 
  g_object_notify (G_OBJECT (dialog), "file");
 
1386
  g_object_notify (G_OBJECT (dialog), "files");
 
1387
}
 
1388
 
 
1389
 
 
1390
 
 
1391
/**
 
1392
 * thunar_properties_dialog_set_file:
 
1393
 * @dialog : a #ThunarPropertiesDialog.
 
1394
 * @file   : a #ThunarFile or %NULL.
 
1395
 *
 
1396
 * Sets the #ThunarFile that is displayed by @dialog
 
1397
 * to @file.
 
1398
 **/
 
1399
void
 
1400
thunar_properties_dialog_set_file (ThunarPropertiesDialog *dialog,
 
1401
                                   ThunarFile             *file)
 
1402
{
 
1403
  GList foo;
 
1404
 
 
1405
  _thunar_return_if_fail (THUNAR_IS_PROPERTIES_DIALOG (dialog));
 
1406
  _thunar_return_if_fail (file == NULL || THUNAR_IS_FILE (file));
 
1407
 
 
1408
  if (file == NULL)
 
1409
    {
 
1410
      thunar_properties_dialog_set_files (dialog, NULL);
 
1411
    }
 
1412
  else
 
1413
    {
 
1414
      /* create a fake list */
 
1415
      foo.next = NULL;
 
1416
      foo.prev = NULL;
 
1417
      foo.data = file;
 
1418
 
 
1419
      thunar_properties_dialog_set_files (dialog, &foo);
 
1420
    }
1137
1421
}
1138
1422
 
1139
1423