1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
6
* Copyright (C) 2007 Free Software Foundation, Inc.
8
* This program is free software; you can redistribute it and/or modify
9
* it under the terms of the GNU General Public License as published by
10
* the Free Software Foundation; either version 2 of the License, or
11
* (at your option) any later version.
13
* This program is distributed in the hope that it will be useful,
14
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
* GNU General Public License for more details.
18
* You should have received a copy of the GNU General Public License
19
* along with this program. If not, see <http://www.gnu.org/licenses/>.
26
#include <glib/gi18n.h>
30
#include <gdk/gdkkeysyms.h>
31
#include <gdk-pixbuf/gdk-pixbuf.h>
34
#include "dlg-batch-add.h"
35
#include "dlg-delete.h"
36
#include "dlg-extract.h"
37
#include "dlg-open-with.h"
38
#include "dlg-ask-password.h"
39
#include "dlg-package-installer.h"
40
#include "dlg-update.h"
41
#include "eggtreemultidnd.h"
42
#include "fr-marshal.h"
43
#include "fr-list-model.h"
44
#include "fr-archive.h"
47
#include "fr-window.h"
48
#include "file-data.h"
49
#include "file-utils.h"
50
#include "glib-utils.h"
52
#include "gtk-utils.h"
53
#include "open-file.h"
57
#define LAST_OUTPUT_SCHEMA_NAME "LastOutput"
58
#define MAX_HISTORY_LEN 5
59
#define ACTIVITY_DELAY 100
60
#define ACTIVITY_PULSE_STEP (0.033)
61
#define MAX_MESSAGE_LENGTH 50
63
#define PROGRESS_DIALOG_DEFAULT_WIDTH 400
64
#define PROGRESS_TIMEOUT_MSECS 5000
65
#define PROGRESS_BAR_HEIGHT 10
68
#define HIDE_PROGRESS_TIMEOUT_MSECS 500
69
#define DEFAULT_NAME_COLUMN_WIDTH 250
70
#define OTHER_COLUMNS_WIDTH 100
71
#define RECENT_ITEM_MAX_WIDTH 25
73
#define DEF_WIN_WIDTH 600
74
#define DEF_WIN_HEIGHT 480
75
#define DEF_SIDEBAR_WIDTH 200
77
#define FILE_LIST_ICON_SIZE GTK_ICON_SIZE_LARGE_TOOLBAR
78
#define DIR_TREE_ICON_SIZE GTK_ICON_SIZE_MENU
80
#define BAD_CHARS "/\\*"
82
static GHashTable *pixbuf_hash = NULL;
83
static GHashTable *tree_pixbuf_hash = NULL;
84
static GtkIconTheme *icon_theme = NULL;
85
static int file_list_icon_size = 0;
86
static int dir_tree_icon_size = 0;
88
#define XDS_FILENAME "xds.txt"
89
#define MAX_XDS_ATOM_VAL_LEN 4096
90
#define XDS_ATOM gdk_atom_intern ("XdndDirectSave0", FALSE)
91
#define TEXT_ATOM gdk_atom_intern ("text/plain", FALSE)
92
#define OCTET_ATOM gdk_atom_intern ("application/octet-stream", FALSE)
93
#define XFR_ATOM gdk_atom_intern ("XdndFileRoller0", FALSE)
95
#define FR_CLIPBOARD (gdk_atom_intern_static_string ("_FILE_ROLLER_SPECIAL_CLIPBOARD"))
96
#define FR_SPECIAL_URI_LIST (gdk_atom_intern_static_string ("application/file-roller-uri-list"))
98
static GtkTargetEntry clipboard_targets[] = {
99
{ "application/file-roller-uri-list", 0, 1 }
102
static GtkTargetEntry target_table[] = {
103
{ "XdndFileRoller0", 0, 0 },
104
{ "text/uri-list", 0, 1 },
107
static GtkTargetEntry folder_tree_targets[] = {
108
{ "XdndFileRoller0", 0, 0 },
109
{ "XdndDirectSave0", 0, 2 }
114
FrBatchActionType type;
121
guint converting : 1;
123
FrArchive *new_archive;
125
gboolean encrypt_header;
139
char *extract_to_dir;
145
gboolean extract_here;
150
FR_WINDOW_AREA_MENUBAR,
151
FR_WINDOW_AREA_TOOLBAR,
152
FR_WINDOW_AREA_LOCATIONBAR,
153
FR_WINDOW_AREA_CONTENTS,
154
FR_WINDOW_AREA_FILTERBAR,
155
FR_WINDOW_AREA_STATUSBAR,
160
DIALOG_RESPONSE_NONE = 1,
161
DIALOG_RESPONSE_OPEN_ARCHIVE,
162
DIALOG_RESPONSE_OPEN_DESTINATION_FOLDER,
167
/* -- FrClipboardData -- */
172
char *archive_filename;
173
char *archive_password;
182
static FrClipboardData*
183
fr_clipboard_data_new (void)
185
FrClipboardData *data;
187
data = g_new0 (FrClipboardData, 1);
194
static FrClipboardData *
195
fr_clipboard_data_ref (FrClipboardData *clipboard_data)
197
clipboard_data->refs++;
198
return clipboard_data;
203
fr_clipboard_data_unref (FrClipboardData *clipboard_data)
205
if (clipboard_data == NULL)
207
if (--clipboard_data->refs > 0)
210
g_free (clipboard_data->archive_filename);
211
g_free (clipboard_data->archive_password);
212
g_free (clipboard_data->base_dir);
213
g_free (clipboard_data->tmp_dir);
214
g_free (clipboard_data->current_dir);
215
g_list_foreach (clipboard_data->files, (GFunc) g_free, NULL);
216
g_list_free (clipboard_data->files);
217
g_free (clipboard_data);
222
fr_clipboard_data_set_password (FrClipboardData *clipboard_data,
223
const char *password)
225
if (clipboard_data->archive_password != password)
226
g_free (clipboard_data->archive_password);
227
if (password != NULL)
228
clipboard_data->archive_password = g_strdup (password);
241
static GtkWindowClass *parent_class = NULL;
242
static guint fr_window_signals[LAST_SIGNAL] = { 0 };
244
struct _FrWindowPrivateData {
247
GtkWidget *list_view;
248
GtkListStore *list_store;
249
GtkWidget *tree_view;
250
GtkTreeStore *tree_store;
252
GtkWidget *statusbar;
253
GtkWidget *progress_bar;
254
GtkWidget *location_bar;
255
GtkWidget *location_entry;
256
GtkWidget *location_label;
257
GtkWidget *filter_bar;
258
GtkWidget *filter_entry;
261
GtkTreePath *tree_hover_path;
262
GtkTreePath *list_hover_path;
263
GtkTreeViewColumn *filename_column;
265
gboolean filter_mode;
266
gint current_view_length;
268
guint help_message_cid;
271
char * last_status_message;
273
GtkWidget * up_arrows[5];
274
GtkWidget * down_arrows[5];
277
gboolean archive_present;
278
gboolean archive_new; /* A new archive has been created
279
* but it doesn't contain any
280
* file yet. The real file will
281
* be created only when the user
282
* adds some file to the
286
char * open_default_dir; /* default directory to be used
287
* in the Open dialog. */
288
char * add_default_dir; /* default directory to be used
289
* in the Add dialog. */
290
char * extract_default_dir; /* default directory to be used
291
* in the Extract dialog. */
292
gboolean freeze_default_dir;
293
gboolean asked_for_password;
294
gboolean ask_to_open_destination_after_extraction;
295
gboolean destroy_with_error_dialog;
297
FRBatchAction current_batch_action;
299
gboolean give_focus_to_the_list;
300
gboolean single_click;
301
GtkTreePath *path_clicked;
303
FrWindowSortMethod sort_method;
304
GtkSortType sort_type;
306
char * last_location;
308
gboolean view_folders;
309
FrWindowListMode list_mode;
310
FrWindowListMode last_list_mode;
312
GList * history_current;
314
char * password_for_paste;
315
gboolean encrypt_header;
316
FrCompression compression;
319
guint activity_timeout_handle; /* activity timeout
321
gint activity_ref; /* when > 0 some activity
324
guint update_timeout_handle; /* update file list
327
FRConvertData convert_data;
332
FrClipboardData *clipboard_data;
333
FrClipboardData *copy_data;
335
FrArchive *copy_from_archive;
337
GtkActionGroup *actions;
339
GtkRecentManager *recent_manager;
340
GtkWidget *recent_chooser_menu;
341
GtkWidget *recent_chooser_toolbar;
343
GtkWidget *file_popup_menu;
344
GtkWidget *folder_popup_menu;
345
GtkWidget *sidebar_folder_popup_menu;
346
GtkWidget *mitem_recents_menu;
347
GtkWidget *recent_toolbar_menu;
348
GtkAction *open_action;
350
/* dragged files data */
352
char *drag_destination_folder;
355
GList *drag_file_list; /* the list of files we are
358
/* progress dialog data */
360
GtkWidget *progress_dialog;
361
GtkWidget *pd_action;
362
GtkWidget *pd_archive;
363
GtkWidget *pd_message;
364
GtkWidget *pd_progress_bar;
365
GtkWidget *pd_cancel_button;
366
GtkWidget *pd_close_button;
367
GtkWidget *pd_open_archive_button;
368
GtkWidget *pd_open_destination_button;
369
GtkWidget *pd_quit_button;
370
gboolean progress_pulse;
371
guint progress_timeout; /* Timeout to display the progress dialog. */
372
guint hide_progress_timeout; /* Timeout to hide the progress dialog. */
373
FrAction pd_last_action;
374
char *pd_last_archive;
375
char *working_archive;
376
double pd_last_fraction;
377
char *pd_last_message;
378
gboolean use_progress_dialog;
380
/* update dialog data */
382
gpointer update_dialog;
385
/* batch mode data */
387
gboolean batch_mode; /* whether we are in a non interactive
389
GList *batch_action_list; /* FRBatchAction * elements */
390
GList *batch_action; /* current action. */
394
GSettings *settings_listing;
395
GSettings *settings_ui;
396
GSettings *settings_general;
397
GSettings *settings_dialogs;
398
GSettings *settings_nautilus;
400
gulong theme_changed_handler_id;
401
gboolean non_interactive;
402
char *extract_here_dir;
403
gboolean extract_interact_use_default_dir;
404
gboolean update_dropped_files;
405
gboolean batch_adding_one_file;
407
GtkWindow *load_error_parent_window;
408
gboolean showing_error_dialog;
409
GtkWindow *error_dialog_parent;
413
/* -- fr_window_free_private_data -- */
417
fr_window_free_batch_data (FrWindow *window)
421
for (scan = window->priv->batch_action_list; scan; scan = scan->next) {
422
FRBatchAction *adata = scan->data;
424
if ((adata->data != NULL) && (adata->free_func != NULL))
425
(*adata->free_func) (adata->data);
429
g_list_free (window->priv->batch_action_list);
430
window->priv->batch_action_list = NULL;
431
window->priv->batch_action = NULL;
436
gh_unref_pixbuf (gpointer key,
440
g_object_unref (value);
445
fr_window_clipboard_remove_file_list (FrWindow *window,
450
if (window->priv->copy_data == NULL)
453
if (file_list == NULL) {
454
fr_clipboard_data_unref (window->priv->copy_data);
455
window->priv->copy_data = NULL;
459
for (scan1 = file_list; scan1; scan1 = scan1->next) {
460
const char *name1 = scan1->data;
463
for (scan2 = window->priv->copy_data->files; scan2;) {
464
const char *name2 = scan2->data;
466
if (strcmp (name1, name2) == 0) {
467
GList *tmp = scan2->next;
468
window->priv->copy_data->files = g_list_remove_link (window->priv->copy_data->files, scan2);
469
g_free (scan2->data);
478
if (window->priv->copy_data->files == NULL) {
479
fr_clipboard_data_unref (window->priv->copy_data);
480
window->priv->copy_data = NULL;
486
fr_window_history_clear (FrWindow *window)
488
if (window->priv->history != NULL)
489
path_list_free (window->priv->history);
490
window->priv->history = NULL;
491
window->priv->history_current = NULL;
492
g_free (window->priv->last_location);
493
window->priv->last_location = NULL;
498
fr_window_free_open_files (FrWindow *window)
502
for (scan = window->priv->open_files; scan; scan = scan->next) {
503
OpenFile *file = scan->data;
505
if (file->monitor != NULL)
506
g_file_monitor_cancel (file->monitor);
507
open_file_free (file);
509
g_list_free (window->priv->open_files);
510
window->priv->open_files = NULL;
515
fr_window_convert_data_free (FrWindow *window,
519
g_free (window->priv->convert_data.new_file);
520
window->priv->convert_data.new_file = NULL;
523
window->priv->convert_data.converting = FALSE;
525
if (window->priv->convert_data.temp_dir != NULL) {
526
g_free (window->priv->convert_data.temp_dir);
527
window->priv->convert_data.temp_dir = NULL;
530
if (window->priv->convert_data.new_archive != NULL) {
531
g_object_unref (window->priv->convert_data.new_archive);
532
window->priv->convert_data.new_archive = NULL;
535
if (window->priv->convert_data.password != NULL) {
536
g_free (window->priv->convert_data.password);
537
window->priv->convert_data.password = NULL;
543
fr_window_free_private_data (FrWindow *window)
545
if (window->priv->update_timeout_handle != 0) {
546
g_source_remove (window->priv->update_timeout_handle);
547
window->priv->update_timeout_handle = 0;
550
if (window->priv->open_action != NULL) {
551
g_object_unref (window->priv->open_action);
552
window->priv->open_action = NULL;
555
if (window->priv->recent_toolbar_menu != NULL) {
556
gtk_widget_destroy (window->priv->recent_toolbar_menu);
557
window->priv->recent_toolbar_menu = NULL;
560
while (window->priv->activity_ref > 0)
561
fr_window_stop_activity_mode (window);
563
if (window->priv->progress_timeout != 0) {
564
g_source_remove (window->priv->progress_timeout);
565
window->priv->progress_timeout = 0;
568
if (window->priv->hide_progress_timeout != 0) {
569
g_source_remove (window->priv->hide_progress_timeout);
570
window->priv->hide_progress_timeout = 0;
573
if (window->priv->theme_changed_handler_id != 0)
574
g_signal_handler_disconnect (icon_theme, window->priv->theme_changed_handler_id);
576
fr_window_history_clear (window);
578
g_free (window->priv->open_default_dir);
579
g_free (window->priv->add_default_dir);
580
g_free (window->priv->extract_default_dir);
581
g_free (window->priv->archive_uri);
583
g_free (window->priv->password);
584
g_free (window->priv->password_for_paste);
586
g_object_unref (window->priv->list_store);
588
if (window->priv->clipboard_data != NULL) {
589
fr_clipboard_data_unref (window->priv->clipboard_data);
590
window->priv->clipboard_data = NULL;
592
if (window->priv->copy_data != NULL) {
593
fr_clipboard_data_unref (window->priv->copy_data);
594
window->priv->copy_data = NULL;
596
if (window->priv->copy_from_archive != NULL) {
597
g_object_unref (window->priv->copy_from_archive);
598
window->priv->copy_from_archive = NULL;
601
fr_window_free_open_files (window);
603
fr_window_convert_data_free (window, TRUE);
605
g_clear_error (&window->priv->drag_error);
606
path_list_free (window->priv->drag_file_list);
607
window->priv->drag_file_list = NULL;
609
if (window->priv->file_popup_menu != NULL) {
610
gtk_widget_destroy (window->priv->file_popup_menu);
611
window->priv->file_popup_menu = NULL;
614
if (window->priv->folder_popup_menu != NULL) {
615
gtk_widget_destroy (window->priv->folder_popup_menu);
616
window->priv->folder_popup_menu = NULL;
619
if (window->priv->sidebar_folder_popup_menu != NULL) {
620
gtk_widget_destroy (window->priv->sidebar_folder_popup_menu);
621
window->priv->sidebar_folder_popup_menu = NULL;
624
g_free (window->priv->last_location);
626
fr_window_free_batch_data (window);
627
fr_window_reset_current_batch_action (window);
629
g_free (window->priv->pd_last_archive);
630
g_free (window->priv->pd_last_message);
631
g_free (window->priv->extract_here_dir);
632
g_free (window->priv->last_status_message);
634
g_settings_set_enum (window->priv->settings_listing, PREF_LISTING_SORT_METHOD, window->priv->sort_method);
635
g_settings_set_enum (window->priv->settings_listing, PREF_LISTING_SORT_TYPE, window->priv->sort_type);
636
g_settings_set_enum (window->priv->settings_listing, PREF_LISTING_LIST_MODE, window->priv->last_list_mode);
638
_g_object_unref (window->priv->settings_listing);
639
_g_object_unref (window->priv->settings_ui);
640
_g_object_unref (window->priv->settings_general);
641
_g_object_unref (window->priv->settings_dialogs);
642
_g_object_unref (window->priv->settings_nautilus);
647
fr_window_finalize (GObject *object)
649
FrWindow *window = FR_WINDOW (object);
651
fr_window_free_open_files (window);
653
if (window->archive != NULL) {
654
g_object_unref (window->archive);
655
window->archive = NULL;
658
if (window->priv != NULL) {
659
fr_window_free_private_data (window);
660
g_free (window->priv);
664
WindowList = g_list_remove (WindowList, window);
666
G_OBJECT_CLASS (parent_class)->finalize (object);
668
if (WindowList == NULL) {
669
if (pixbuf_hash != NULL) {
670
g_hash_table_foreach (pixbuf_hash,
673
g_hash_table_destroy (pixbuf_hash);
676
if (tree_pixbuf_hash != NULL) {
677
g_hash_table_foreach (tree_pixbuf_hash,
680
g_hash_table_destroy (tree_pixbuf_hash);
681
tree_pixbuf_hash = NULL;
690
close__step2 (gpointer data)
692
gtk_widget_destroy (GTK_WIDGET (data));
698
fr_window_close (FrWindow *window)
700
if (window->priv->activity_ref > 0)
703
window->priv->closing = TRUE;
705
if (gtk_widget_get_realized (GTK_WIDGET (window))) {
708
width = gtk_widget_get_allocated_width (GTK_WIDGET (window));
709
height = gtk_widget_get_allocated_height (GTK_WIDGET (window));
710
g_settings_set_int (window->priv->settings_ui, PREF_UI_WINDOW_WIDTH, width);
711
g_settings_set_int (window->priv->settings_ui, PREF_UI_WINDOW_HEIGHT, height);
713
width = gtk_paned_get_position (GTK_PANED (window->priv->paned));
715
g_settings_set_int (window->priv->settings_ui, PREF_UI_SIDEBAR_WIDTH, width);
717
width = gtk_tree_view_column_get_width (window->priv->filename_column);
719
g_settings_set_int (window->priv->settings_listing, PREF_LISTING_NAME_COLUMN_WIDTH, width);
722
g_idle_add (close__step2, window);
727
fr_window_class_init (FrWindowClass *class)
729
GObjectClass *gobject_class;
730
GtkWidgetClass *widget_class;
732
parent_class = g_type_class_peek_parent (class);
734
fr_window_signals[ARCHIVE_LOADED] =
735
g_signal_new ("archive-loaded",
736
G_TYPE_FROM_CLASS (class),
738
G_STRUCT_OFFSET (FrWindowClass, archive_loaded),
740
fr_marshal_VOID__BOOLEAN,
743
fr_window_signals[PROGRESS] =
744
g_signal_new ("progress",
745
G_TYPE_FROM_CLASS (class),
747
G_STRUCT_OFFSET (FrWindowClass, progress),
749
fr_marshal_VOID__DOUBLE_STRING,
753
fr_window_signals[READY] =
754
g_signal_new ("ready",
755
G_TYPE_FROM_CLASS (class),
757
G_STRUCT_OFFSET (FrWindowClass, ready),
759
fr_marshal_VOID__POINTER,
763
gobject_class = (GObjectClass*) class;
764
gobject_class->finalize = fr_window_finalize;
766
widget_class = (GtkWidgetClass*) class;
770
static void fr_window_update_paste_command_sensitivity (FrWindow *, GtkClipboard *);
774
clipboard_owner_change_cb (GtkClipboard *clipboard,
778
fr_window_update_paste_command_sensitivity ((FrWindow *) user_data, clipboard);
783
fr_window_realized (GtkWidget *window,
786
GtkClipboard *clipboard;
788
clipboard = gtk_widget_get_clipboard (window, FR_CLIPBOARD);
789
g_signal_connect (clipboard,
791
G_CALLBACK (clipboard_owner_change_cb),
797
fr_window_unrealized (GtkWidget *window,
800
GtkClipboard *clipboard;
802
clipboard = gtk_widget_get_clipboard (window, FR_CLIPBOARD);
803
g_signal_handlers_disconnect_by_func (clipboard,
804
G_CALLBACK (clipboard_owner_change_cb),
810
fr_window_init (FrWindow *window)
812
window->priv = g_new0 (FrWindowPrivateData, 1);
813
window->priv->update_dropped_files = FALSE;
814
window->priv->filter_mode = FALSE;
815
window->priv->use_progress_dialog = TRUE;
817
g_signal_connect (window,
819
G_CALLBACK (fr_window_realized),
821
g_signal_connect (window,
823
G_CALLBACK (fr_window_unrealized),
826
WindowList = g_list_prepend (WindowList, window);
831
fr_window_get_type (void)
833
static GType type = 0;
836
GTypeInfo type_info = {
837
sizeof (FrWindowClass),
840
(GClassInitFunc) fr_window_class_init,
845
(GInstanceInitFunc) fr_window_init
848
type = g_type_register_static (GTK_TYPE_WINDOW,
858
/* -- window history -- */
863
fr_window_history_print (FrWindow *window)
867
debug (DEBUG_INFO, "history:\n");
868
for (list = window->priv->history; list; list = list->next)
869
g_print ("\t%s %s\n",
871
(list == window->priv->history_current)? "<-": "");
878
fr_window_history_add (FrWindow *window,
881
if ((window->priv->history != NULL) && (window->priv->history_current != NULL)) {
882
if (strcmp (window->priv->history_current->data, path) == 0)
885
/* Add locations visited using the back button to the history
887
if (window->priv->history != window->priv->history_current) {
888
GList *scan = window->priv->history->next;
889
while (scan != window->priv->history_current->next) {
890
window->priv->history = g_list_prepend (window->priv->history, g_strdup (scan->data));
896
window->priv->history = g_list_prepend (window->priv->history, g_strdup (path));
897
window->priv->history_current = window->priv->history;
902
fr_window_history_pop (FrWindow *window)
906
if (window->priv->history == NULL)
909
first = window->priv->history;
910
window->priv->history = g_list_remove_link (window->priv->history, first);
911
if (window->priv->history_current == first)
912
window->priv->history_current = window->priv->history;
913
g_free (first->data);
918
/* -- window_update_file_list -- */
922
fr_window_get_current_dir_list (FrWindow *window)
927
files = g_ptr_array_sized_new (128);
929
for (i = 0; i < window->archive->command->files->len; i++) {
930
FileData *fdata = g_ptr_array_index (window->archive->command->files, i);
932
if (fdata->list_name == NULL)
934
g_ptr_array_add (files, fdata);
942
sort_by_name (gconstpointer ptr1,
945
FileData *fdata1 = *((FileData **) ptr1);
946
FileData *fdata2 = *((FileData **) ptr2);
948
if (file_data_is_dir (fdata1) != file_data_is_dir (fdata2)) {
949
if (file_data_is_dir (fdata1))
955
return strcasecmp (fdata1->list_name, fdata2->list_name);
960
sort_by_size (gconstpointer ptr1,
963
FileData *fdata1 = *((FileData **) ptr1);
964
FileData *fdata2 = *((FileData **) ptr2);
966
if (file_data_is_dir (fdata1) != file_data_is_dir (fdata2)) {
967
if (file_data_is_dir (fdata1))
972
else if (file_data_is_dir (fdata1) && file_data_is_dir (fdata2)) {
973
if (fdata1->dir_size > fdata2->dir_size)
979
if (fdata1->size == fdata2->size)
980
return sort_by_name (ptr1, ptr2);
981
else if (fdata1->size > fdata2->size)
989
sort_by_type (gconstpointer ptr1,
992
FileData *fdata1 = *((FileData **) ptr1);
993
FileData *fdata2 = *((FileData **) ptr2);
995
const char *desc1, *desc2;
997
if (file_data_is_dir (fdata1) != file_data_is_dir (fdata2)) {
998
if (file_data_is_dir (fdata1))
1003
else if (file_data_is_dir (fdata1) && file_data_is_dir (fdata2))
1004
return sort_by_name (ptr1, ptr2);
1006
desc1 = g_content_type_get_description (fdata1->content_type);
1007
desc2 = g_content_type_get_description (fdata2->content_type);
1009
result = strcasecmp (desc1, desc2);
1011
return sort_by_name (ptr1, ptr2);
1018
sort_by_time (gconstpointer ptr1,
1021
FileData *fdata1 = *((FileData **) ptr1);
1022
FileData *fdata2 = *((FileData **) ptr2);
1024
if (file_data_is_dir (fdata1) != file_data_is_dir (fdata2)) {
1025
if (file_data_is_dir (fdata1))
1030
else if (file_data_is_dir (fdata1) && file_data_is_dir (fdata2))
1031
return sort_by_name (ptr1, ptr2);
1033
if (fdata1->modified == fdata2->modified)
1034
return sort_by_name (ptr1, ptr2);
1035
else if (fdata1->modified > fdata2->modified)
1043
sort_by_path (gconstpointer ptr1,
1046
FileData *fdata1 = *((FileData **) ptr1);
1047
FileData *fdata2 = *((FileData **) ptr2);
1050
if (file_data_is_dir (fdata1) != file_data_is_dir (fdata2)) {
1051
if (file_data_is_dir (fdata1))
1056
else if (file_data_is_dir (fdata1) && file_data_is_dir (fdata2))
1057
return sort_by_name (ptr1, ptr2);
1061
result = strcasecmp (fdata1->path, fdata2->path);
1063
return sort_by_name (ptr1, ptr2);
1070
get_dir_size (FrWindow *window,
1071
const char *current_dir,
1079
dirname = g_strconcat (current_dir, name, "/", NULL);
1080
dirname_l = strlen (dirname);
1083
for (i = 0; i < window->archive->command->files->len; i++) {
1084
FileData *fd = g_ptr_array_index (window->archive->command->files, i);
1086
if (strncmp (dirname, fd->full_path, dirname_l) == 0)
1097
file_data_respects_filter (FrWindow *window,
1102
filter = gtk_entry_get_text (GTK_ENTRY (window->priv->filter_entry));
1103
if ((fdata == NULL) || (filter == NULL) || (*filter == '\0'))
1106
if (fdata->dir || (fdata->name == NULL))
1109
return strncasecmp (fdata->name, filter, strlen (filter)) == 0;
1114
compute_file_list_name (FrWindow *window,
1116
const char *current_dir,
1117
int current_dir_len,
1118
GHashTable *names_hash,
1119
gboolean *different_name)
1121
register char *scan, *end;
1123
*different_name = FALSE;
1125
if (! file_data_respects_filter (window, fdata))
1128
if (window->priv->list_mode == FR_WINDOW_LIST_MODE_FLAT) {
1129
fdata->list_name = g_strdup (fdata->name);
1131
fdata->dir_size = 0;
1135
if (strncmp (fdata->full_path, current_dir, current_dir_len) != 0) {
1136
*different_name = TRUE;
1140
if (strlen (fdata->full_path) == current_dir_len)
1143
scan = fdata->full_path + current_dir_len;
1144
end = strchr (scan, '/');
1145
if ((end == NULL) && ! fdata->dir) { /* file */
1146
fdata->list_name = g_strdup (scan);
1152
dir_name = g_strndup (scan, end - scan);
1154
dir_name = g_strdup (scan);
1156
/* avoid to insert duplicated folders */
1157
if (g_hash_table_lookup (names_hash, dir_name) != NULL) {
1161
g_hash_table_insert (names_hash, dir_name, GINT_TO_POINTER (1));
1163
if ((end != NULL) && (*(end + 1) != '\0'))
1164
fdata->list_dir = TRUE;
1165
fdata->list_name = dir_name;
1166
fdata->dir_size = get_dir_size (window, current_dir, dir_name);
1174
fr_window_compute_list_names (FrWindow *window,
1177
const char *current_dir;
1178
int current_dir_len;
1179
GHashTable *names_hash;
1181
gboolean visible_list_started = FALSE;
1182
gboolean visible_list_completed = FALSE;
1183
gboolean different_name;
1185
current_dir = fr_window_get_current_location (window);
1186
current_dir_len = strlen (current_dir);
1187
names_hash = g_hash_table_new (g_str_hash, g_str_equal);
1189
for (i = 0; i < files->len; i++) {
1190
FileData *fdata = g_ptr_array_index (files, i);
1192
g_free (fdata->list_name);
1193
fdata->list_name = NULL;
1194
fdata->list_dir = FALSE;
1196
/* the files array is sorted by path, when the visible list
1197
* is started and we find a path that doesn't match the
1198
* current_dir path, the following files can't match
1199
* the current_dir path. */
1201
if (visible_list_completed)
1204
if (compute_file_list_name (window, fdata, current_dir, current_dir_len, names_hash, &different_name)) {
1205
visible_list_started = TRUE;
1207
else if (visible_list_started && different_name)
1208
visible_list_completed = TRUE;
1211
g_hash_table_destroy (names_hash);
1216
fr_window_dir_exists_in_archive (FrWindow *window,
1217
const char *dir_name)
1222
if (dir_name == NULL)
1225
dir_name_len = strlen (dir_name);
1226
if (dir_name_len == 0)
1229
if (strcmp (dir_name, "/") == 0)
1232
for (i = 0; i < window->archive->command->files->len; i++) {
1233
FileData *fdata = g_ptr_array_index (window->archive->command->files, i);
1235
if (strncmp (dir_name, fdata->full_path, dir_name_len) == 0) {
1239
&& (fdata->full_path[strlen (fdata->full_path)] != '/')
1240
&& (strncmp (dir_name, fdata->full_path, dir_name_len - 1) == 0))
1251
get_parent_dir (const char *current_dir)
1257
if (current_dir == NULL)
1259
if (strcmp (current_dir, "/") == 0)
1260
return g_strdup ("/");
1262
dir = g_strdup (current_dir);
1263
dir[strlen (dir) - 1] = 0;
1264
new_dir = remove_level_from_path (dir);
1267
if (new_dir[strlen (new_dir) - 1] == '/')
1270
retval = g_strconcat (new_dir, "/", NULL);
1278
static void fr_window_update_statusbar_list_info (FrWindow *window);
1282
get_mime_type_icon (const char *mime_type)
1284
GdkPixbuf *pixbuf = NULL;
1286
pixbuf = g_hash_table_lookup (tree_pixbuf_hash, mime_type);
1287
if (pixbuf != NULL) {
1288
g_object_ref (G_OBJECT (pixbuf));
1292
pixbuf = get_mime_type_pixbuf (mime_type, file_list_icon_size, icon_theme);
1296
pixbuf = gdk_pixbuf_copy (pixbuf);
1297
g_hash_table_insert (tree_pixbuf_hash, (gpointer) mime_type, pixbuf);
1298
g_object_ref (G_OBJECT (pixbuf));
1305
get_icon (GtkWidget *widget,
1308
GdkPixbuf *pixbuf = NULL;
1309
const char *content_type;
1312
if (file_data_is_dir (fdata))
1313
content_type = MIME_TYPE_DIRECTORY;
1315
content_type = fdata->content_type;
1317
/* look in the hash table. */
1319
pixbuf = g_hash_table_lookup (pixbuf_hash, content_type);
1320
if (pixbuf != NULL) {
1321
g_object_ref (G_OBJECT (pixbuf));
1325
icon = g_content_type_get_icon (content_type);
1326
pixbuf = get_icon_pixbuf (icon, file_list_icon_size, icon_theme);
1327
g_object_unref (icon);
1332
pixbuf = gdk_pixbuf_copy (pixbuf);
1333
g_hash_table_insert (pixbuf_hash, (gpointer) content_type, pixbuf);
1334
g_object_ref (G_OBJECT (pixbuf));
1341
get_emblem (GtkWidget *widget,
1344
GdkPixbuf *pixbuf = NULL;
1346
if (! fdata->encrypted)
1351
pixbuf = g_hash_table_lookup (pixbuf_hash, "emblem-nowrite");
1352
if (pixbuf != NULL) {
1353
g_object_ref (G_OBJECT (pixbuf));
1357
pixbuf = gtk_icon_theme_load_icon (icon_theme,
1359
file_list_icon_size,
1365
pixbuf = gdk_pixbuf_copy (pixbuf);
1366
g_hash_table_insert (pixbuf_hash, (gpointer) "emblem-nowrite", pixbuf);
1367
g_object_ref (G_OBJECT (pixbuf));
1374
get_column_from_sort_method (FrWindowSortMethod sort_method)
1376
switch (sort_method) {
1377
case FR_WINDOW_SORT_BY_NAME: return COLUMN_NAME;
1378
case FR_WINDOW_SORT_BY_SIZE: return COLUMN_SIZE;
1379
case FR_WINDOW_SORT_BY_TYPE: return COLUMN_TYPE;
1380
case FR_WINDOW_SORT_BY_TIME: return COLUMN_TIME;
1381
case FR_WINDOW_SORT_BY_PATH: return COLUMN_PATH;
1391
get_sort_method_from_column (int column_id)
1393
switch (column_id) {
1394
case COLUMN_NAME: return FR_WINDOW_SORT_BY_NAME;
1395
case COLUMN_SIZE: return FR_WINDOW_SORT_BY_SIZE;
1396
case COLUMN_TYPE: return FR_WINDOW_SORT_BY_TYPE;
1397
case COLUMN_TIME: return FR_WINDOW_SORT_BY_TIME;
1398
case COLUMN_PATH: return FR_WINDOW_SORT_BY_PATH;
1403
return FR_WINDOW_SORT_BY_NAME;
1408
add_selected_from_list_view (GtkTreeModel *model,
1413
GList **list = data;
1416
gtk_tree_model_get (model, iter,
1417
COLUMN_FILE_DATA, &fdata,
1419
*list = g_list_prepend (*list, fdata);
1424
add_selected_from_tree_view (GtkTreeModel *model,
1429
GList **list = data;
1432
gtk_tree_model_get (model, iter,
1433
TREE_COLUMN_PATH, &dir_path,
1435
*list = g_list_prepend (*list, dir_path);
1440
add_selected_fd (GtkTreeModel *model,
1445
GList **list = data;
1448
gtk_tree_model_get (model, iter,
1449
COLUMN_FILE_DATA, &fdata,
1451
if (! fdata->list_dir)
1452
*list = g_list_prepend (*list, fdata);
1457
get_selection_as_fd (FrWindow *window)
1459
GtkTreeSelection *selection;
1462
if (! gtk_widget_get_realized (window->priv->list_view))
1465
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (window->priv->list_view));
1466
if (selection == NULL)
1468
gtk_tree_selection_selected_foreach (selection, add_selected_fd, &list);
1475
fr_window_update_statusbar_list_info (FrWindow *window)
1477
char *info, *archive_info, *selected_info;
1478
char *size_txt, *sel_size_txt;
1480
goffset tot_size, sel_size;
1486
if ((window->archive == NULL) || (window->archive->command == NULL)) {
1487
gtk_statusbar_pop (GTK_STATUSBAR (window->priv->statusbar), window->priv->list_info_cid);
1494
if (window->priv->archive_present) {
1495
GPtrArray *files = fr_window_get_current_dir_list (window);
1498
for (i = 0; i < files->len; i++) {
1499
FileData *fd = g_ptr_array_index (files, i);
1502
if (! file_data_is_dir (fd))
1503
tot_size += fd->size;
1505
tot_size += fd->dir_size;
1507
g_ptr_array_free (files, TRUE);
1513
if (window->priv->archive_present) {
1514
GList *selection = get_selection_as_fd (window);
1516
for (scan = selection; scan; scan = scan->next) {
1517
FileData *fd = scan->data;
1520
if (! file_data_is_dir (fd))
1521
sel_size += fd->size;
1523
g_list_free (selection);
1526
size_txt = g_format_size_for_display (tot_size);
1527
sel_size_txt = g_format_size_for_display (sel_size);
1530
archive_info = g_strdup ("");
1532
archive_info = g_strdup_printf (ngettext ("%d object (%s)", "%d objects (%s)", tot_n), tot_n, size_txt);
1535
selected_info = g_strdup ("");
1537
selected_info = g_strdup_printf (ngettext ("%d object selected (%s)", "%d objects selected (%s)", sel_n), sel_n, sel_size_txt);
1539
info = g_strconcat (archive_info,
1540
((sel_n == 0) ? NULL : ", "),
1544
gtk_statusbar_push (GTK_STATUSBAR (window->priv->statusbar), window->priv->list_info_cid, info);
1547
g_free (sel_size_txt);
1548
g_free (archive_info);
1549
g_free (selected_info);
1555
fr_window_populate_file_list (FrWindow *window,
1560
gtk_list_store_clear (window->priv->list_store);
1562
gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (window->priv->list_store),
1563
GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID,
1564
GTK_SORT_ASCENDING);
1566
for (i = 0; i < files->len; i++) {
1567
FileData *fdata = g_ptr_array_index (files, i);
1569
GdkPixbuf *icon, *emblem;
1572
if (fdata->list_name == NULL)
1575
gtk_list_store_append (window->priv->list_store, &iter);
1577
icon = get_icon (GTK_WIDGET (window), fdata);
1578
utf8_name = g_filename_display_name (fdata->list_name);
1579
emblem = get_emblem (GTK_WIDGET (window), fdata);
1581
if (file_data_is_dir (fdata)) {
1587
if (fdata->list_dir)
1588
tmp = remove_ending_separator (fr_window_get_current_location (window));
1591
tmp = remove_level_from_path (fdata->path);
1592
utf8_path = g_filename_display_name (tmp);
1595
s_size = g_format_size_for_display (fdata->dir_size);
1597
if (fdata->list_dir)
1598
s_time = g_strdup ("");
1600
s_time = get_time_string (fdata->modified);
1602
gtk_list_store_set (window->priv->list_store, &iter,
1603
COLUMN_FILE_DATA, fdata,
1605
COLUMN_NAME, utf8_name,
1606
COLUMN_EMBLEM, emblem,
1607
COLUMN_TYPE, _("Folder"),
1608
COLUMN_SIZE, s_size,
1609
COLUMN_TIME, s_time,
1610
COLUMN_PATH, utf8_path,
1622
utf8_path = g_filename_display_name (fdata->path);
1624
s_size = g_format_size_for_display (fdata->size);
1625
s_time = get_time_string (fdata->modified);
1626
desc = g_content_type_get_description (fdata->content_type);
1628
gtk_list_store_set (window->priv->list_store, &iter,
1629
COLUMN_FILE_DATA, fdata,
1631
COLUMN_NAME, utf8_name,
1632
COLUMN_EMBLEM, emblem,
1634
COLUMN_SIZE, s_size,
1635
COLUMN_TIME, s_time,
1636
COLUMN_PATH, utf8_path,
1644
g_object_unref (icon);
1646
g_object_unref (emblem);
1649
gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (window->priv->list_store),
1650
get_column_from_sort_method (window->priv->sort_method),
1651
window->priv->sort_type);
1653
fr_window_update_statusbar_list_info (window);
1654
fr_window_stop_activity_mode (window);
1659
path_compare (gconstpointer a,
1662
char *path_a = *((char**) a);
1663
char *path_b = *((char**) b);
1665
return strcmp (path_a, path_b);
1670
get_tree_iter_from_path (FrWindow *window,
1672
GtkTreeIter *parent,
1675
gboolean result = FALSE;
1677
if (! gtk_tree_model_iter_children (GTK_TREE_MODEL (window->priv->tree_store), iter, parent))
1684
if (get_tree_iter_from_path (window, path, iter, &tmp)) {
1689
gtk_tree_model_get (GTK_TREE_MODEL (window->priv->tree_store),
1691
TREE_COLUMN_PATH, &iter_path,
1694
if ((iter_path != NULL) && (strcmp (path, iter_path) == 0)) {
1700
} while (gtk_tree_model_iter_next (GTK_TREE_MODEL (window->priv->tree_store), iter));
1707
set_sensitive (FrWindow *window,
1708
const char *action_name,
1713
action = gtk_action_group_get_action (window->priv->actions, action_name);
1714
g_object_set (action, "sensitive", sensitive, NULL);
1719
fr_window_update_current_location (FrWindow *window)
1721
const char *current_dir = fr_window_get_current_location (window);
1725
if (window->priv->list_mode == FR_WINDOW_LIST_MODE_FLAT) {
1726
gtk_widget_hide (window->priv->location_bar);
1730
gtk_widget_show (window->priv->location_bar);
1732
gtk_entry_set_text (GTK_ENTRY (window->priv->location_entry), window->priv->archive_present? current_dir: "");
1734
set_sensitive (window, "GoBack", window->priv->archive_present && (current_dir != NULL) && (window->priv->history_current != NULL) && (window->priv->history_current->next != NULL));
1735
set_sensitive (window, "GoForward", window->priv->archive_present && (current_dir != NULL) && (window->priv->history_current != NULL) && (window->priv->history_current->prev != NULL));
1736
set_sensitive (window, "GoUp", window->priv->archive_present && (current_dir != NULL) && (strcmp (current_dir, "/") != 0));
1737
set_sensitive (window, "GoHome", window->priv->archive_present);
1738
gtk_widget_set_sensitive (window->priv->location_entry, window->priv->archive_present);
1739
gtk_widget_set_sensitive (window->priv->location_label, window->priv->archive_present);
1740
gtk_widget_set_sensitive (window->priv->filter_entry, window->priv->archive_present);
1743
fr_window_history_print (window);
1746
path = remove_ending_separator (current_dir);
1747
if (get_tree_iter_from_path (window, path, NULL, &iter)) {
1748
GtkTreeSelection *selection;
1749
GtkTreePath *t_path;
1751
t_path = gtk_tree_model_get_path (GTK_TREE_MODEL (window->priv->tree_store), &iter);
1752
gtk_tree_view_expand_to_path (GTK_TREE_VIEW (window->priv->tree_view), t_path);
1753
gtk_tree_path_free (t_path);
1755
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (window->priv->tree_view));
1756
gtk_tree_selection_select_iter (selection, &iter);
1763
fr_window_update_dir_tree (FrWindow *window)
1766
GHashTable *dir_cache;
1770
gtk_tree_store_clear (window->priv->tree_store);
1772
if (! window->priv->view_folders
1773
|| ! window->priv->archive_present
1774
|| (window->priv->list_mode == FR_WINDOW_LIST_MODE_FLAT))
1776
gtk_widget_set_sensitive (window->priv->tree_view, FALSE);
1777
gtk_widget_hide (window->priv->sidepane);
1781
gtk_widget_set_sensitive (window->priv->tree_view, TRUE);
1782
if (! gtk_widget_get_visible (window->priv->sidepane))
1783
gtk_widget_show_all (window->priv->sidepane);
1786
if (gtk_widget_get_realized (window->priv->tree_view))
1787
gtk_tree_view_scroll_to_point (GTK_TREE_VIEW (window->priv->tree_view), 0, 0);
1791
dirs = g_ptr_array_sized_new (128);
1793
dir_cache = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL);
1794
for (i = 0; i < window->archive->command->files->len; i++) {
1795
FileData *fdata = g_ptr_array_index (window->archive->command->files, i);
1798
if (gtk_entry_get_text (GTK_ENTRY (window->priv->filter_entry)) != NULL) {
1799
if (! file_data_respects_filter (window, fdata))
1804
dir = remove_ending_separator (fdata->full_path);
1806
dir = remove_level_from_path (fdata->full_path);
1808
while ((dir != NULL) && (strcmp (dir, "/") != 0)) {
1811
if (g_hash_table_lookup (dir_cache, dir) != NULL)
1815
g_ptr_array_add (dirs, new_dir);
1816
g_hash_table_replace (dir_cache, new_dir, "1");
1818
dir = remove_level_from_path (new_dir);
1823
g_hash_table_destroy (dir_cache);
1825
g_ptr_array_sort (dirs, path_compare);
1826
dir_cache = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) gtk_tree_path_free);
1830
icon = get_mime_type_icon (MIME_TYPE_ARCHIVE);
1836
uri = g_file_get_uri (window->archive->file);
1837
name = g_uri_display_basename (uri);
1839
gtk_tree_store_append (window->priv->tree_store, &node, NULL);
1840
gtk_tree_store_set (window->priv->tree_store, &node,
1841
TREE_COLUMN_ICON, icon,
1842
TREE_COLUMN_NAME, name,
1843
TREE_COLUMN_PATH, "/",
1844
TREE_COLUMN_WEIGHT, PANGO_WEIGHT_BOLD,
1846
g_hash_table_replace (dir_cache, "/", gtk_tree_model_get_path (GTK_TREE_MODEL (window->priv->tree_store), &node));
1851
g_object_unref (icon);
1855
icon = get_mime_type_icon (MIME_TYPE_DIRECTORY);
1856
for (i = 0; i < dirs->len; i++) {
1857
char *dir = g_ptr_array_index (dirs, i);
1859
GtkTreePath *parent_path;
1863
parent_dir = remove_level_from_path (dir);
1864
if (parent_dir == NULL)
1867
parent_path = g_hash_table_lookup (dir_cache, parent_dir);
1868
gtk_tree_model_get_iter (GTK_TREE_MODEL (window->priv->tree_store),
1871
gtk_tree_store_append (window->priv->tree_store, &node, &parent);
1872
gtk_tree_store_set (window->priv->tree_store, &node,
1873
TREE_COLUMN_ICON, icon,
1874
TREE_COLUMN_NAME, file_name_from_path (dir),
1875
TREE_COLUMN_PATH, dir,
1876
TREE_COLUMN_WEIGHT, PANGO_WEIGHT_NORMAL,
1878
g_hash_table_replace (dir_cache, dir, gtk_tree_model_get_path (GTK_TREE_MODEL (window->priv->tree_store), &node));
1880
g_free (parent_dir);
1882
g_hash_table_destroy (dir_cache);
1884
g_object_unref (icon);
1886
g_ptr_array_free (dirs, TRUE);
1888
fr_window_update_current_location (window);
1893
fr_window_update_filter_bar_visibility (FrWindow *window)
1897
filter = gtk_entry_get_text (GTK_ENTRY (window->priv->filter_entry));
1898
if ((filter == NULL) || (*filter == '\0'))
1899
gtk_widget_hide (window->priv->filter_bar);
1901
gtk_widget_show (window->priv->filter_bar);
1906
fr_window_update_file_list (FrWindow *window,
1907
gboolean update_view)
1910
gboolean free_files = FALSE;
1912
if (gtk_widget_get_realized (window->priv->list_view))
1913
gtk_tree_view_scroll_to_point (GTK_TREE_VIEW (window->priv->list_view), 0, 0);
1915
if (! window->priv->archive_present || window->priv->archive_new) {
1917
gtk_list_store_clear (window->priv->list_store);
1919
window->priv->current_view_length = 0;
1921
if (window->priv->archive_new) {
1922
gtk_widget_set_sensitive (window->priv->list_view, TRUE);
1923
gtk_widget_show_all (gtk_widget_get_parent (window->priv->list_view));
1926
gtk_widget_set_sensitive (window->priv->list_view, FALSE);
1927
gtk_widget_hide (gtk_widget_get_parent (window->priv->list_view));
1933
gtk_widget_set_sensitive (window->priv->list_view, TRUE);
1934
gtk_widget_show_all (gtk_widget_get_parent (window->priv->list_view));
1937
if (window->priv->give_focus_to_the_list) {
1938
gtk_widget_grab_focus (window->priv->list_view);
1939
window->priv->give_focus_to_the_list = FALSE;
1944
fr_window_start_activity_mode (window);
1946
if (window->priv->list_mode == FR_WINDOW_LIST_MODE_FLAT) {
1947
fr_window_compute_list_names (window, window->archive->command->files);
1948
files = window->archive->command->files;
1952
char *current_dir = g_strdup (fr_window_get_current_location (window));
1954
while (! fr_window_dir_exists_in_archive (window, current_dir)) {
1957
fr_window_history_pop (window);
1959
tmp = get_parent_dir (current_dir);
1960
g_free (current_dir);
1963
fr_window_history_add (window, current_dir);
1965
g_free (current_dir);
1967
fr_window_compute_list_names (window, window->archive->command->files);
1968
files = fr_window_get_current_dir_list (window);
1973
window->priv->current_view_length = files->len;
1975
window->priv->current_view_length = 0;
1978
fr_window_populate_file_list (window, files);
1981
g_ptr_array_free (files, TRUE);
1986
fr_window_update_list_order (FrWindow *window)
1988
gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (window->priv->list_store), get_column_from_sort_method (window->priv->sort_method), window->priv->sort_type);
1993
fr_window_update_title (FrWindow *window)
1995
if (! window->priv->archive_present)
1996
gtk_window_set_title (GTK_WINDOW (window), _("Archive Manager"));
2001
name = g_uri_display_basename (fr_window_get_archive_uri (window));
2002
title = g_strdup_printf ("%s %s",
2004
window->archive->read_only ? _("[read only]") : "");
2006
gtk_window_set_title (GTK_WINDOW (window), title);
2014
check_whether_has_a_dir (GtkTreeModel *model,
2019
gboolean *has_a_dir = data;
2022
gtk_tree_model_get (model, iter,
2023
COLUMN_FILE_DATA, &fdata,
2025
if (file_data_is_dir (fdata))
2031
selection_has_a_dir (FrWindow *window)
2033
GtkTreeSelection *selection;
2034
gboolean has_a_dir = FALSE;
2036
if (! gtk_widget_get_realized (window->priv->list_view))
2039
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (window->priv->list_view));
2040
if (selection == NULL)
2043
gtk_tree_selection_selected_foreach (selection,
2044
check_whether_has_a_dir,
2052
set_active (FrWindow *window,
2053
const char *action_name,
2058
action = gtk_action_group_get_action (window->priv->actions, action_name);
2059
gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), is_active);
2064
fr_window_update_paste_command_sensitivity (FrWindow *window,
2065
GtkClipboard *clipboard)
2068
gboolean no_archive;
2070
gboolean compr_file;
2072
if (window->priv->closing)
2075
if (clipboard == NULL)
2076
clipboard = gtk_widget_get_clipboard (GTK_WIDGET (window), FR_CLIPBOARD);
2077
running = window->priv->activity_ref > 0;
2078
no_archive = (window->archive == NULL) || ! window->priv->archive_present;
2079
ro = ! no_archive && window->archive->read_only;
2080
compr_file = ! no_archive && window->archive->is_compressed_file;
2082
set_sensitive (window, "Paste", ! no_archive && ! ro && ! running && ! compr_file && (window->priv->list_mode != FR_WINDOW_LIST_MODE_FLAT) && gtk_clipboard_wait_is_target_available (clipboard, FR_SPECIAL_URI_LIST));
2087
fr_window_update_sensitivity (FrWindow *window)
2089
gboolean no_archive;
2093
gboolean compr_file;
2094
gboolean sel_not_null;
2095
gboolean one_file_selected;
2096
gboolean dir_selected;
2099
if (window->priv->batch_mode)
2102
running = window->priv->activity_ref > 0;
2103
no_archive = (window->archive == NULL) || ! window->priv->archive_present;
2104
ro = ! no_archive && window->archive->read_only;
2105
file_op = ! no_archive && ! window->priv->archive_new && ! running;
2106
compr_file = ! no_archive && window->archive->is_compressed_file;
2107
n_selected = fr_window_get_n_selected_files (window);
2108
sel_not_null = n_selected > 0;
2109
one_file_selected = n_selected == 1;
2110
dir_selected = selection_has_a_dir (window);
2112
set_sensitive (window, "AddFiles", ! no_archive && ! ro && ! running && ! compr_file);
2113
set_sensitive (window, "AddFiles_Toolbar", ! no_archive && ! ro && ! running && ! compr_file);
2114
set_sensitive (window, "AddFolder", ! no_archive && ! ro && ! running && ! compr_file);
2115
set_sensitive (window, "AddFolder_Toolbar", ! no_archive && ! ro && ! running && ! compr_file);
2116
set_sensitive (window, "Copy", ! no_archive && ! ro && ! running && ! compr_file && sel_not_null && (window->priv->list_mode != FR_WINDOW_LIST_MODE_FLAT));
2117
set_sensitive (window, "Cut", ! no_archive && ! ro && ! running && ! compr_file && sel_not_null && (window->priv->list_mode != FR_WINDOW_LIST_MODE_FLAT));
2118
set_sensitive (window, "Delete", ! no_archive && ! ro && ! window->priv->archive_new && ! running && ! compr_file);
2119
set_sensitive (window, "DeselectAll", ! no_archive && sel_not_null);
2120
set_sensitive (window, "Extract", file_op);
2121
set_sensitive (window, "Extract_Toolbar", file_op);
2122
set_sensitive (window, "Find", ! no_archive);
2123
set_sensitive (window, "LastOutput", ((window->archive != NULL)
2124
&& (window->archive->process != NULL)
2125
&& (window->archive->process->out.raw != NULL)));
2126
set_sensitive (window, "New", ! running);
2127
set_sensitive (window, "Open", ! running);
2128
set_sensitive (window, "Open_Toolbar", ! running);
2129
set_sensitive (window, "OpenSelection", file_op && sel_not_null && ! dir_selected);
2130
set_sensitive (window, "OpenFolder", file_op && one_file_selected && dir_selected);
2131
set_sensitive (window, "Password", ! running && (window->priv->asked_for_password || (! no_archive && window->archive->command->propPassword)));
2132
set_sensitive (window, "Properties", file_op);
2133
set_sensitive (window, "Close", !running || window->priv->stoppable);
2134
set_sensitive (window, "Reload", ! (no_archive || running));
2135
set_sensitive (window, "Rename", ! no_archive && ! ro && ! running && ! compr_file && one_file_selected);
2136
set_sensitive (window, "SaveAs", ! no_archive && ! compr_file && ! running);
2137
set_sensitive (window, "SelectAll", ! no_archive);
2138
set_sensitive (window, "Stop", running && window->priv->stoppable);
2139
set_sensitive (window, "TestArchive", ! no_archive && ! running && window->archive->command->propTest);
2140
set_sensitive (window, "ViewSelection", file_op && one_file_selected && ! dir_selected);
2141
set_sensitive (window, "ViewSelection_Toolbar", file_op && one_file_selected && ! dir_selected);
2143
if (window->priv->progress_dialog != NULL)
2144
gtk_dialog_set_response_sensitive (GTK_DIALOG (window->priv->progress_dialog),
2146
running && window->priv->stoppable);
2148
fr_window_update_paste_command_sensitivity (window, NULL);
2150
set_sensitive (window, "SelectAll", (window->priv->current_view_length > 0) && (window->priv->current_view_length != n_selected));
2151
set_sensitive (window, "DeselectAll", n_selected > 0);
2152
set_sensitive (window, "OpenRecentMenu", ! running);
2154
set_sensitive (window, "ViewFolders", (window->priv->list_mode == FR_WINDOW_LIST_MODE_AS_DIR));
2156
set_sensitive (window, "ViewAllFiles", ! window->priv->filter_mode);
2157
set_sensitive (window, "ViewAsFolder", ! window->priv->filter_mode);
2162
location_entry_key_press_event_cb (GtkWidget *widget,
2166
if ((event->keyval == GDK_KEY_Return)
2167
|| (event->keyval == GDK_KEY_KP_Enter)
2168
|| (event->keyval == GDK_KEY_ISO_Enter))
2170
fr_window_go_to_location (window, gtk_entry_get_text (GTK_ENTRY (window->priv->location_entry)), FALSE);
2178
real_close_progress_dialog (gpointer data)
2180
FrWindow *window = data;
2182
if (window->priv->hide_progress_timeout != 0) {
2183
g_source_remove (window->priv->hide_progress_timeout);
2184
window->priv->hide_progress_timeout = 0;
2187
if (window->priv->progress_dialog != NULL)
2188
gtk_widget_hide (window->priv->progress_dialog);
2195
close_progress_dialog (FrWindow *window,
2198
if (window->priv->progress_timeout != 0) {
2199
g_source_remove (window->priv->progress_timeout);
2200
window->priv->progress_timeout = 0;
2203
if (! window->priv->batch_mode && gtk_widget_get_mapped (GTK_WIDGET (window)))
2204
gtk_widget_hide (window->priv->progress_bar);
2206
if (window->priv->progress_dialog == NULL)
2210
if (window->priv->hide_progress_timeout != 0) {
2211
g_source_remove (window->priv->hide_progress_timeout);
2212
window->priv->hide_progress_timeout = 0;
2214
real_close_progress_dialog (window);
2217
if (window->priv->hide_progress_timeout != 0)
2219
window->priv->hide_progress_timeout = g_timeout_add (HIDE_PROGRESS_TIMEOUT_MSECS,
2220
real_close_progress_dialog,
2227
progress_dialog_delete_event (GtkWidget *caller,
2231
if (window->priv->stoppable) {
2232
activate_action_stop (NULL, window);
2233
close_progress_dialog (window, TRUE);
2241
open_folder (GtkWindow *parent,
2244
GError *error = NULL;
2249
if (! show_uri (gtk_window_get_screen (parent), folder, GDK_CURRENT_TIME, &error)) {
2254
utf8_name = g_filename_display_name (folder);
2255
message = g_strdup_printf (_("Could not display the folder \"%s\""), utf8_name);
2258
d = _gtk_error_dialog_new (parent,
2264
gtk_dialog_run (GTK_DIALOG (d));
2265
gtk_widget_destroy (d);
2268
g_clear_error (&error);
2274
fr_window_view_extraction_destination_folder (FrWindow *window)
2276
open_folder (GTK_WINDOW (window), fr_archive_get_last_extraction_destination (window->archive));
2281
progress_dialog_response (GtkDialog *dialog,
2285
GtkWidget *new_window;
2287
switch (response_id) {
2288
case GTK_RESPONSE_CANCEL:
2289
if (window->priv->stoppable) {
2290
activate_action_stop (NULL, window);
2291
close_progress_dialog (window, TRUE);
2294
case GTK_RESPONSE_CLOSE:
2295
close_progress_dialog (window, TRUE);
2297
case DIALOG_RESPONSE_OPEN_ARCHIVE:
2298
new_window = fr_window_new ();
2299
gtk_widget_show (new_window);
2300
fr_window_archive_open (FR_WINDOW (new_window), window->priv->convert_data.new_file, GTK_WINDOW (new_window));
2301
close_progress_dialog (window, TRUE);
2303
case DIALOG_RESPONSE_OPEN_DESTINATION_FOLDER:
2304
fr_window_view_extraction_destination_folder (window);
2305
close_progress_dialog (window, TRUE);
2307
case DIALOG_RESPONSE_QUIT:
2308
fr_window_close (window);
2317
get_message_from_action (FrAction action)
2322
case FR_ACTION_CREATING_NEW_ARCHIVE:
2323
message = _("Creating archive");
2325
case FR_ACTION_LOADING_ARCHIVE:
2326
message = _("Loading archive");
2328
case FR_ACTION_LISTING_CONTENT:
2329
message = _("Reading archive");
2331
case FR_ACTION_DELETING_FILES:
2332
message = _("Deleting files from archive");
2334
case FR_ACTION_TESTING_ARCHIVE:
2335
message = _("Testing archive");
2337
case FR_ACTION_GETTING_FILE_LIST:
2338
message = _("Getting the file list");
2340
case FR_ACTION_COPYING_FILES_FROM_REMOTE:
2341
message = _("Copying the file list");
2343
case FR_ACTION_ADDING_FILES:
2344
message = _("Adding files to archive");
2346
case FR_ACTION_EXTRACTING_FILES:
2347
message = _("Extracting files from archive");
2349
case FR_ACTION_COPYING_FILES_TO_REMOTE:
2350
message = _("Copying the file list");
2352
case FR_ACTION_CREATING_ARCHIVE:
2353
message = _("Creating archive");
2355
case FR_ACTION_SAVING_REMOTE_ARCHIVE:
2356
message = _("Saving archive");
2368
progress_dialog__set_last_action (FrWindow *window,
2374
window->priv->pd_last_action = action;
2375
title = get_message_from_action (window->priv->pd_last_action);
2376
gtk_window_set_title (GTK_WINDOW (window->priv->progress_dialog), title);
2377
markup = g_markup_printf_escaped ("<span weight=\"bold\" size=\"larger\">%s</span>", title);
2378
gtk_label_set_markup (GTK_LABEL (window->priv->pd_action), markup);
2384
pd_update_archive_name (FrWindow *window)
2386
char *current_archive;
2388
if (window->priv->convert_data.converting)
2389
current_archive = window->priv->convert_data.new_file;
2390
else if (window->priv->working_archive != NULL)
2391
current_archive = window->priv->working_archive;
2393
current_archive = window->priv->archive_uri;
2395
if (strcmp_null_tolerant (window->priv->pd_last_archive, current_archive) != 0) {
2396
g_free (window->priv->pd_last_archive);
2397
if (current_archive == NULL) {
2398
window->priv->pd_last_archive = NULL;
2399
gtk_label_set_text (GTK_LABEL (window->priv->pd_archive), "");
2401
g_print ("archive name > (none)\n");
2407
window->priv->pd_last_archive = g_strdup (current_archive);
2409
name = g_uri_display_basename (window->priv->pd_last_archive);
2410
gtk_label_set_text (GTK_LABEL (window->priv->pd_archive), name);
2412
g_print ("archive name > %s\n", name);
2421
fr_window_working_archive_cb (FrCommand *command,
2422
const char *archive_filename,
2425
g_free (window->priv->working_archive);
2426
window->priv->working_archive = NULL;
2427
if (archive_filename != NULL)
2428
window->priv->working_archive = g_strdup (archive_filename);
2429
pd_update_archive_name (window);
2436
fr_window_message_cb (FrCommand *command,
2440
if (window->priv->progress_dialog == NULL)
2451
gtk_label_set_text (GTK_LABEL (window->priv->pd_message), "");
2456
if (! g_utf8_validate (msg, -1, NULL))
2457
utf8_msg = g_locale_to_utf8 (msg, -1 , 0, 0, 0);
2459
utf8_msg = g_strdup (msg);
2460
if (utf8_msg == NULL)
2463
if (g_utf8_validate (utf8_msg, -1, NULL))
2464
gtk_label_set_text (GTK_LABEL (window->priv->pd_message), utf8_msg);
2466
g_free (window->priv->pd_last_message);
2467
window->priv->pd_last_message = g_strdup (utf8_msg);
2469
g_signal_emit (G_OBJECT (window),
2470
fr_window_signals[PROGRESS],
2472
window->priv->pd_last_fraction,
2473
window->priv->pd_last_message);
2476
g_print ("message > %s\n", utf8_msg);
2482
if (window->priv->convert_data.converting) {
2483
if (window->priv->pd_last_action != FR_ACTION_CREATING_ARCHIVE)
2484
progress_dialog__set_last_action (window, FR_ACTION_CREATING_ARCHIVE);
2486
else if (window->priv->pd_last_action != window->priv->action)
2487
progress_dialog__set_last_action (window, window->priv->action);
2489
pd_update_archive_name (window);
2496
create_the_progress_dialog (FrWindow *window)
2502
GtkWidget *progress_vbox;
2506
PangoAttrList *attr_list;
2508
if (window->priv->progress_dialog != NULL)
2511
if (window->priv->batch_mode)
2514
parent = GTK_WINDOW (window);
2516
window->priv->pd_last_action = window->priv->action;
2517
title = get_message_from_action (window->priv->pd_last_action);
2518
window->priv->progress_dialog = gtk_dialog_new_with_buttons (title,
2520
GTK_DIALOG_DESTROY_WITH_PARENT,
2523
window->priv->pd_quit_button = gtk_dialog_add_button (GTK_DIALOG (window->priv->progress_dialog), GTK_STOCK_QUIT, DIALOG_RESPONSE_QUIT);
2524
window->priv->pd_open_archive_button = gtk_dialog_add_button (GTK_DIALOG (window->priv->progress_dialog), _("_Open the Archive"), DIALOG_RESPONSE_OPEN_ARCHIVE);
2525
window->priv->pd_open_destination_button = gtk_dialog_add_button (GTK_DIALOG (window->priv->progress_dialog), _("_Show the Files"), DIALOG_RESPONSE_OPEN_DESTINATION_FOLDER);
2526
window->priv->pd_close_button = gtk_dialog_add_button (GTK_DIALOG (window->priv->progress_dialog), GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE);
2527
window->priv->pd_cancel_button = gtk_dialog_add_button (GTK_DIALOG (window->priv->progress_dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
2529
d = GTK_DIALOG (window->priv->progress_dialog);
2530
gtk_window_set_resizable (GTK_WINDOW (d), TRUE);
2531
gtk_dialog_set_default_response (GTK_DIALOG (d), GTK_RESPONSE_OK);
2532
gtk_window_set_default_size (GTK_WINDOW (d), PROGRESS_DIALOG_DEFAULT_WIDTH, -1);
2536
vbox = gtk_vbox_new (FALSE, 5);
2537
gtk_container_set_border_width (GTK_CONTAINER (vbox), 6);
2538
gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (d)), vbox, FALSE, FALSE, 10);
2542
lbl = window->priv->pd_action = gtk_label_new ("");
2544
markup = g_markup_printf_escaped ("<span weight=\"bold\" size=\"larger\">%s</span>", title);
2545
gtk_label_set_markup (GTK_LABEL (lbl), markup);
2548
align = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
2549
gtk_alignment_set_padding (GTK_ALIGNMENT (align), 0, 12, 0, 0);
2551
gtk_misc_set_alignment (GTK_MISC (lbl), 0.0, 0.5);
2552
gtk_misc_set_padding (GTK_MISC (lbl), 0, 0);
2553
gtk_label_set_ellipsize (GTK_LABEL (lbl), PANGO_ELLIPSIZE_END);
2555
gtk_container_add (GTK_CONTAINER (align), lbl);
2556
gtk_box_pack_start (GTK_BOX (vbox), align, TRUE, TRUE, 0);
2560
g_free (window->priv->pd_last_archive);
2561
window->priv->pd_last_archive = NULL;
2562
if (window->priv->archive_uri != NULL) {
2566
hbox = gtk_hbox_new (FALSE, 6);
2567
gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
2569
lbl = gtk_label_new ("");
2570
markup = g_markup_printf_escaped ("<b>%s</b>", _("Archive:"));
2571
gtk_label_set_markup (GTK_LABEL (lbl), markup);
2573
gtk_box_pack_start (GTK_BOX (hbox), lbl, FALSE, FALSE, 0);
2575
window->priv->pd_last_archive = g_strdup (window->priv->archive_uri);
2576
name = g_uri_display_basename (window->priv->pd_last_archive);
2577
lbl = window->priv->pd_archive = gtk_label_new (name);
2580
gtk_misc_set_alignment (GTK_MISC (lbl), 0.0, 0.5);
2581
gtk_label_set_ellipsize (GTK_LABEL (lbl), PANGO_ELLIPSIZE_END);
2582
gtk_box_pack_start (GTK_BOX (hbox), lbl, TRUE, TRUE, 0);
2585
/* progress and details */
2587
align = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
2588
gtk_alignment_set_padding (GTK_ALIGNMENT (align), 0, 6, 0, 0);
2590
progress_vbox = gtk_vbox_new (FALSE, 6);
2591
gtk_container_add (GTK_CONTAINER (align), progress_vbox);
2592
gtk_box_pack_start (GTK_BOX (vbox), align, TRUE, TRUE, 0);
2596
window->priv->pd_progress_bar = gtk_progress_bar_new ();
2597
gtk_progress_bar_set_pulse_step (GTK_PROGRESS_BAR (window->priv->pd_progress_bar), ACTIVITY_PULSE_STEP);
2598
gtk_box_pack_start (GTK_BOX (progress_vbox), window->priv->pd_progress_bar, TRUE, TRUE, 0);
2602
lbl = window->priv->pd_message = gtk_label_new ("");
2604
attr_list = pango_attr_list_new ();
2605
pango_attr_list_insert (attr_list, pango_attr_style_new (PANGO_STYLE_ITALIC));
2606
gtk_label_set_attributes (GTK_LABEL (lbl), attr_list);
2607
pango_attr_list_unref (attr_list);
2609
gtk_misc_set_alignment (GTK_MISC (lbl), 0.0, 0.5);
2610
gtk_label_set_ellipsize (GTK_LABEL (lbl), PANGO_ELLIPSIZE_END);
2611
gtk_box_pack_start (GTK_BOX (progress_vbox), lbl, TRUE, TRUE, 0);
2613
gtk_widget_show_all (vbox);
2617
g_signal_connect (G_OBJECT (window->priv->progress_dialog),
2619
G_CALLBACK (progress_dialog_response),
2621
g_signal_connect (G_OBJECT (window->priv->progress_dialog),
2623
G_CALLBACK (progress_dialog_delete_event),
2629
display_progress_dialog (gpointer data)
2631
FrWindow *window = data;
2633
if (window->priv->progress_timeout != 0)
2634
g_source_remove (window->priv->progress_timeout);
2636
if (window->priv->use_progress_dialog && (window->priv->progress_dialog != NULL)) {
2637
gtk_dialog_set_response_sensitive (GTK_DIALOG (window->priv->progress_dialog),
2639
window->priv->stoppable);
2640
if (! window->priv->non_interactive)
2641
gtk_widget_show (GTK_WIDGET (window));
2642
gtk_widget_hide (window->priv->progress_bar);
2643
gtk_widget_show (window->priv->progress_dialog);
2644
fr_window_message_cb (NULL, window->priv->last_status_message, window);
2647
window->priv->progress_timeout = 0;
2654
open_progress_dialog (FrWindow *window,
2657
if (window->priv->hide_progress_timeout != 0) {
2658
g_source_remove (window->priv->hide_progress_timeout);
2659
window->priv->hide_progress_timeout = 0;
2663
if (window->priv->progress_timeout != 0)
2664
g_source_remove (window->priv->progress_timeout);
2665
window->priv->progress_timeout = 0;
2668
if ((window->priv->progress_timeout != 0)
2669
|| ((window->priv->progress_dialog != NULL) && gtk_widget_get_visible (window->priv->progress_dialog)))
2672
if (! window->priv->batch_mode && ! open_now)
2673
gtk_widget_show (window->priv->progress_bar);
2675
create_the_progress_dialog (window);
2676
gtk_widget_show (window->priv->pd_cancel_button);
2677
gtk_widget_hide (window->priv->pd_open_archive_button);
2678
gtk_widget_hide (window->priv->pd_open_destination_button);
2679
gtk_widget_hide (window->priv->pd_quit_button);
2680
gtk_widget_hide (window->priv->pd_close_button);
2683
display_progress_dialog (window);
2685
window->priv->progress_timeout = g_timeout_add (PROGRESS_TIMEOUT_MSECS,
2686
display_progress_dialog,
2692
fr_window_progress_cb (FrCommand *command,
2696
window->priv->progress_pulse = (fraction < 0.0);
2697
if (! window->priv->progress_pulse) {
2698
fraction = CLAMP (fraction, 0.0, 1.0);
2699
if (window->priv->progress_dialog != NULL)
2700
gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (window->priv->pd_progress_bar), fraction);
2701
gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (window->priv->progress_bar), fraction);
2703
window->priv->pd_last_fraction = fraction;
2705
g_signal_emit (G_OBJECT (window),
2706
fr_window_signals[PROGRESS],
2708
window->priv->pd_last_fraction,
2709
window->priv->pd_last_message);
2712
g_print ("progress > %2.2f\n", fraction);
2720
open_progress_dialog_with_open_destination (FrWindow *window)
2722
window->priv->ask_to_open_destination_after_extraction = FALSE;
2724
if (window->priv->hide_progress_timeout != 0) {
2725
g_source_remove (window->priv->hide_progress_timeout);
2726
window->priv->hide_progress_timeout = 0;
2728
if (window->priv->progress_timeout != 0) {
2729
g_source_remove (window->priv->progress_timeout);
2730
window->priv->progress_timeout = 0;
2733
create_the_progress_dialog (window);
2734
gtk_widget_hide (window->priv->pd_cancel_button);
2735
gtk_widget_hide (window->priv->pd_open_archive_button);
2736
gtk_widget_show (window->priv->pd_open_destination_button);
2737
gtk_widget_show (window->priv->pd_quit_button);
2738
gtk_widget_show (window->priv->pd_close_button);
2739
display_progress_dialog (window);
2740
fr_window_progress_cb (NULL, 1.0, window);
2741
fr_window_message_cb (NULL, _("Extraction completed successfully"), window);
2746
open_progress_dialog_with_open_archive (FrWindow *window)
2748
if (window->priv->hide_progress_timeout != 0) {
2749
g_source_remove (window->priv->hide_progress_timeout);
2750
window->priv->hide_progress_timeout = 0;
2752
if (window->priv->progress_timeout != 0) {
2753
g_source_remove (window->priv->progress_timeout);
2754
window->priv->progress_timeout = 0;
2757
create_the_progress_dialog (window);
2758
gtk_widget_hide (window->priv->pd_cancel_button);
2759
gtk_widget_hide (window->priv->pd_open_destination_button);
2760
gtk_widget_show (window->priv->pd_open_archive_button);
2761
gtk_widget_show (window->priv->pd_close_button);
2762
display_progress_dialog (window);
2763
fr_window_progress_cb (NULL, 1.0, window);
2764
fr_window_message_cb (NULL, _("Archive created successfully"), window);
2769
fr_window_push_message (FrWindow *window,
2772
if (! gtk_widget_get_mapped (GTK_WIDGET (window)))
2775
g_free (window->priv->last_status_message);
2776
window->priv->last_status_message = g_strdup (msg);
2778
gtk_statusbar_push (GTK_STATUSBAR (window->priv->statusbar), window->priv->progress_cid, window->priv->last_status_message);
2779
if (window->priv->progress_dialog != NULL)
2780
gtk_label_set_text (GTK_LABEL (window->priv->pd_message), window->priv->last_status_message);
2785
fr_window_pop_message (FrWindow *window)
2787
if (! gtk_widget_get_mapped (GTK_WIDGET (window)))
2789
gtk_statusbar_pop (GTK_STATUSBAR (window->priv->statusbar), window->priv->progress_cid);
2790
if (window->priv->progress_dialog != NULL)
2791
gtk_label_set_text (GTK_LABEL (window->priv->pd_message), "");
2796
action_started (FrArchive *archive,
2800
FrWindow *window = data;
2801
const char *message;
2804
window->priv->action = action;
2805
fr_window_start_activity_mode (window);
2808
debug (DEBUG_INFO, "%s [START] (FR::Window)\n", action_names[action]);
2811
message = get_message_from_action (action);
2812
full_msg = g_strdup_printf ("%s, %s", message, _("please wait..."));
2813
fr_window_push_message (window, full_msg);
2816
case FR_ACTION_EXTRACTING_FILES:
2817
open_progress_dialog (window, window->priv->ask_to_open_destination_after_extraction || window->priv->convert_data.converting || window->priv->batch_mode);
2820
open_progress_dialog (window, window->priv->batch_mode);
2824
if (archive->command != NULL) {
2825
fr_command_progress (archive->command, -1.0);
2826
fr_command_message (archive->command, message);
2834
fr_window_add_to_recent_list (FrWindow *window,
2837
if (window->priv->batch_mode)
2840
if (is_temp_dir (uri))
2843
if (window->archive->content_type != NULL) {
2844
GtkRecentData *recent_data;
2846
recent_data = g_new0 (GtkRecentData, 1);
2847
recent_data->mime_type = g_content_type_get_mime_type (window->archive->content_type);
2848
recent_data->app_name = "File Roller";
2849
recent_data->app_exec = "file-roller";
2850
gtk_recent_manager_add_full (window->priv->recent_manager, uri, recent_data);
2852
g_free (recent_data);
2855
gtk_recent_manager_add_item (window->priv->recent_manager, uri);
2860
fr_window_remove_from_recent_list (FrWindow *window,
2863
if (filename != NULL)
2864
gtk_recent_manager_remove_item (window->priv->recent_manager, filename, NULL);
2869
error_dialog_response_cb (GtkDialog *dialog,
2873
FrWindow *window = user_data;
2874
GtkWindow *dialog_parent = window->priv->error_dialog_parent;
2876
window->priv->showing_error_dialog = FALSE;
2877
window->priv->error_dialog_parent = NULL;
2879
if ((dialog_parent != NULL) && (gtk_widget_get_toplevel (GTK_WIDGET (dialog_parent)) != (GtkWidget*) dialog_parent))
2880
gtk_window_set_modal (dialog_parent, TRUE);
2881
gtk_widget_destroy (GTK_WIDGET (dialog));
2883
if (window->priv->destroy_with_error_dialog)
2884
gtk_widget_destroy (GTK_WIDGET (window));
2889
fr_window_show_error_dialog (FrWindow *window,
2891
GtkWindow *dialog_parent,
2892
const char *details)
2894
if (window->priv->batch_mode && ! window->priv->use_progress_dialog) {
2897
error = g_error_new_literal (FR_ERROR, FR_PROC_ERROR_GENERIC, details ? details : _("Command exited abnormally."));
2898
g_signal_emit (window,
2899
fr_window_signals[READY],
2903
gtk_widget_destroy (GTK_WIDGET (window));
2908
close_progress_dialog (window, TRUE);
2910
if (window->priv->batch_mode)
2911
fr_window_destroy_with_error_dialog (window);
2913
if (dialog_parent != NULL)
2914
gtk_window_set_modal (dialog_parent, FALSE);
2915
g_signal_connect (dialog,
2917
G_CALLBACK (error_dialog_response_cb),
2919
gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
2920
gtk_widget_show (dialog);
2922
window->priv->showing_error_dialog = TRUE;
2923
window->priv->error_dialog_parent = dialog_parent;
2928
fr_window_destroy_with_error_dialog (FrWindow *window)
2930
window->priv->destroy_with_error_dialog = TRUE;
2935
handle_errors (FrWindow *window,
2940
if (error->type == FR_PROC_ERROR_ASK_PASSWORD) {
2941
close_progress_dialog (window, TRUE);
2942
dlg_ask_password (window);
2945
else if (error->type == FR_PROC_ERROR_UNSUPPORTED_FORMAT) {
2946
close_progress_dialog (window, TRUE);
2947
dlg_package_installer (window, archive, action);
2951
else if (error->type == FR_PROC_ERROR_BAD_CHARSET) {
2952
close_progress_dialog (window, TRUE);
2953
/* dlg_ask_archive_charset (window); FIXME: implement after feature freeze */
2957
else if (error->type == FR_PROC_ERROR_STOPPED) {
2960
else if (error->type != FR_PROC_ERROR_NONE) {
2963
char *details = NULL;
2964
GtkWindow *dialog_parent;
2966
FrProcess *process = archive->process;
2967
GList *output = NULL;
2969
if (window->priv->batch_mode) {
2970
dialog_parent = NULL;
2971
window->priv->load_error_parent_window = NULL;
2974
dialog_parent = (GtkWindow *) window;
2975
if (window->priv->load_error_parent_window == NULL)
2976
window->priv->load_error_parent_window = (GtkWindow *) window;
2979
if ((action == FR_ACTION_LISTING_CONTENT) || (action == FR_ACTION_LOADING_ARCHIVE))
2980
fr_window_archive_close (window);
2983
case FR_ACTION_CREATING_NEW_ARCHIVE:
2984
dialog_parent = window->priv->load_error_parent_window;
2985
msg = _("Could not create the archive");
2988
case FR_ACTION_EXTRACTING_FILES:
2989
case FR_ACTION_COPYING_FILES_TO_REMOTE:
2990
msg = _("An error occurred while extracting files.");
2993
case FR_ACTION_LOADING_ARCHIVE:
2994
dialog_parent = window->priv->load_error_parent_window;
2995
utf8_name = g_uri_display_basename (window->priv->archive_uri);
2996
msg = g_strdup_printf (_("Could not open \"%s\""), utf8_name);
3000
case FR_ACTION_LISTING_CONTENT:
3001
msg = _("An error occurred while loading the archive.");
3004
case FR_ACTION_DELETING_FILES:
3005
msg = _("An error occurred while deleting files from the archive.");
3008
case FR_ACTION_ADDING_FILES:
3009
case FR_ACTION_GETTING_FILE_LIST:
3010
case FR_ACTION_COPYING_FILES_FROM_REMOTE:
3011
msg = _("An error occurred while adding files to the archive.");
3014
case FR_ACTION_TESTING_ARCHIVE:
3015
msg = _("An error occurred while testing archive.");
3018
case FR_ACTION_SAVING_REMOTE_ARCHIVE:
3019
msg = _("An error occurred while saving the archive.");
3023
msg = _("An error occurred.");
3027
switch (error->type) {
3028
case FR_PROC_ERROR_COMMAND_NOT_FOUND:
3029
details = _("Command not found.");
3031
case FR_PROC_ERROR_EXITED_ABNORMALLY:
3032
details = _("Command exited abnormally.");
3034
case FR_PROC_ERROR_SPAWN:
3035
details = error->gerror->message;
3038
if (error->gerror != NULL)
3039
details = error->gerror->message;
3045
if (error->type != FR_PROC_ERROR_GENERIC)
3046
output = (process->err.raw != NULL) ? process->err.raw : process->out.raw;
3048
dialog = _gtk_error_dialog_new (dialog_parent,
3052
((details != NULL) ? "%s" : NULL),
3054
fr_window_show_error_dialog (window, dialog, dialog_parent, details);
3064
convert__action_performed (FrArchive *archive,
3069
FrWindow *window = data;
3072
debug (DEBUG_INFO, "%s [CONVERT::DONE] (FR::Window)\n", action_names[action]);
3075
if ((action == FR_ACTION_GETTING_FILE_LIST) || (action == FR_ACTION_ADDING_FILES)) {
3076
fr_window_stop_activity_mode (window);
3077
fr_window_pop_message (window);
3078
close_progress_dialog (window, FALSE);
3081
if (action != FR_ACTION_ADDING_FILES)
3084
handle_errors (window, archive, action, error);
3086
if (error->type == FR_PROC_ERROR_NONE)
3087
open_progress_dialog_with_open_archive (window);
3089
remove_local_directory (window->priv->convert_data.temp_dir);
3090
fr_window_convert_data_free (window, FALSE);
3092
fr_window_update_sensitivity (window);
3093
fr_window_update_statusbar_list_info (window);
3097
static void fr_window_exec_next_batch_action (FrWindow *window);
3101
action_performed (FrArchive *archive,
3106
FrWindow *window = data;
3107
gboolean continue_batch = FALSE;
3112
debug (DEBUG_INFO, "%s [DONE] (FR::Window)\n", action_names[action]);
3115
fr_window_stop_activity_mode (window);
3116
fr_window_pop_message (window);
3118
continue_batch = handle_errors (window, archive, action, error);
3120
if ((error->type == FR_PROC_ERROR_ASK_PASSWORD)
3121
|| (error->type == FR_PROC_ERROR_UNSUPPORTED_FORMAT)
3122
/*|| (error->type == FR_PROC_ERROR_BAD_CHARSET)*/)
3128
case FR_ACTION_CREATING_NEW_ARCHIVE:
3129
case FR_ACTION_CREATING_ARCHIVE:
3130
close_progress_dialog (window, FALSE);
3131
if (error->type != FR_PROC_ERROR_STOPPED) {
3132
fr_window_history_clear (window);
3133
fr_window_go_to_location (window, "/", TRUE);
3134
fr_window_update_dir_tree (window);
3135
fr_window_update_title (window);
3136
fr_window_update_sensitivity (window);
3140
case FR_ACTION_LOADING_ARCHIVE:
3141
close_progress_dialog (window, FALSE);
3142
if (error->type != FR_PROC_ERROR_NONE) {
3143
fr_window_remove_from_recent_list (window, window->priv->archive_uri);
3144
if (window->priv->non_interactive) {
3145
fr_window_archive_close (window);
3146
fr_window_stop_batch (window);
3150
fr_window_add_to_recent_list (window, window->priv->archive_uri);
3151
if (! window->priv->non_interactive)
3152
gtk_window_present (GTK_WINDOW (window));
3154
continue_batch = FALSE;
3155
g_signal_emit (window,
3156
fr_window_signals[ARCHIVE_LOADED],
3158
error->type == FR_PROC_ERROR_NONE);
3161
case FR_ACTION_LISTING_CONTENT:
3162
/* update the uri because multi-volume archives can have
3163
* a different name after loading. */
3164
g_free (window->priv->archive_uri);
3165
window->priv->archive_uri = g_file_get_uri (window->archive->file);
3167
close_progress_dialog (window, FALSE);
3168
if (error->type != FR_PROC_ERROR_NONE) {
3169
fr_window_remove_from_recent_list (window, window->priv->archive_uri);
3170
fr_window_archive_close (window);
3171
fr_window_set_password (window, NULL);
3175
archive_dir = remove_level_from_path (window->priv->archive_uri);
3176
temp_dir = is_temp_dir (archive_dir);
3177
if (! window->priv->archive_present) {
3178
window->priv->archive_present = TRUE;
3180
fr_window_history_clear (window);
3181
fr_window_history_add (window, "/");
3184
fr_window_set_open_default_dir (window, archive_dir);
3185
fr_window_set_add_default_dir (window, archive_dir);
3186
if (! window->priv->freeze_default_dir)
3187
fr_window_set_extract_default_dir (window, archive_dir, FALSE);
3190
window->priv->archive_new = FALSE;
3192
g_free (archive_dir);
3195
fr_window_add_to_recent_list (window, window->priv->archive_uri);
3197
fr_window_update_title (window);
3198
fr_window_go_to_location (window, fr_window_get_current_location (window), TRUE);
3199
fr_window_update_dir_tree (window);
3200
if (! window->priv->batch_mode && window->priv->non_interactive)
3201
gtk_window_present (GTK_WINDOW (window));
3204
case FR_ACTION_DELETING_FILES:
3205
close_progress_dialog (window, FALSE);
3206
fr_window_archive_reload (window);
3209
case FR_ACTION_ADDING_FILES:
3210
close_progress_dialog (window, FALSE);
3212
/* update the uri because multi-volume archives can have
3213
* a different name after creation. */
3214
g_free (window->priv->archive_uri);
3215
window->priv->archive_uri = g_file_get_uri (window->archive->file);
3217
if (error->type == FR_PROC_ERROR_NONE) {
3218
if (window->priv->archive_new)
3219
window->priv->archive_new = FALSE;
3220
fr_window_add_to_recent_list (window, window->priv->archive_uri);
3222
if (! window->priv->batch_mode) {
3223
fr_window_archive_reload (window);
3228
case FR_ACTION_TESTING_ARCHIVE:
3229
close_progress_dialog (window, FALSE);
3230
if (error->type == FR_PROC_ERROR_NONE)
3231
fr_window_view_last_output (window, _("Test Result"));
3234
case FR_ACTION_EXTRACTING_FILES:
3235
if (error->type != FR_PROC_ERROR_NONE) {
3236
if (window->priv->convert_data.converting) {
3237
remove_local_directory (window->priv->convert_data.temp_dir);
3238
fr_window_convert_data_free (window, TRUE);
3242
if (window->priv->convert_data.converting) {
3245
source_dir = g_filename_to_uri (window->priv->convert_data.temp_dir, NULL, NULL);
3246
fr_archive_add_with_wildcard (
3247
window->priv->convert_data.new_archive,
3255
window->priv->convert_data.password,
3256
window->priv->convert_data.encrypt_header,
3257
window->priv->compression,
3258
window->priv->convert_data.volume_size);
3259
g_free (source_dir);
3262
if (window->priv->ask_to_open_destination_after_extraction)
3263
open_progress_dialog_with_open_destination (window);
3265
close_progress_dialog (window, FALSE);
3270
close_progress_dialog (window, FALSE);
3271
continue_batch = FALSE;
3275
if (window->priv->batch_action == NULL) {
3276
fr_window_update_sensitivity (window);
3277
fr_window_update_statusbar_list_info (window);
3280
if (continue_batch) {
3281
if (error->type != FR_PROC_ERROR_NONE)
3282
fr_window_stop_batch (window);
3284
fr_window_exec_next_batch_action (window);
3289
/* -- selections -- */
3293
get_dir_list_from_path (FrWindow *window,
3301
if (path[strlen (path) - 1] != '/')
3302
dirname = g_strconcat (path, "/", NULL);
3304
dirname = g_strdup (path);
3305
dirname_l = strlen (dirname);
3306
for (i = 0; i < window->archive->command->files->len; i++) {
3307
FileData *fd = g_ptr_array_index (window->archive->command->files, i);
3309
if (strncmp (dirname, fd->full_path, dirname_l) == 0)
3310
list = g_list_prepend (list, g_strdup (fd->original_path));
3314
return g_list_reverse (list);
3319
get_dir_list_from_file_data (FrWindow *window,
3325
dirname = g_strconcat (fr_window_get_current_location (window),
3328
list = get_dir_list_from_path (window, dirname);
3336
fr_window_get_file_list_selection (FrWindow *window,
3340
GtkTreeSelection *selection;
3341
GList *selections = NULL, *list, *scan;
3343
g_return_val_if_fail (window != NULL, NULL);
3345
if (has_dirs != NULL)
3348
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (window->priv->list_view));
3349
if (selection == NULL)
3351
gtk_tree_selection_selected_foreach (selection, add_selected_from_list_view, &selections);
3354
for (scan = selections; scan; scan = scan->next) {
3355
FileData *fd = scan->data;
3360
if (file_data_is_dir (fd)) {
3361
if (has_dirs != NULL)
3365
list = g_list_concat (list, get_dir_list_from_file_data (window, fd));
3368
list = g_list_prepend (list, g_strdup (fd->original_path));
3371
g_list_free (selections);
3373
return g_list_reverse (list);
3378
fr_window_get_folder_tree_selection (FrWindow *window,
3382
GtkTreeSelection *tree_selection;
3383
GList *selections, *list, *scan;
3385
g_return_val_if_fail (window != NULL, NULL);
3387
if (has_dirs != NULL)
3390
tree_selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (window->priv->tree_view));
3391
if (tree_selection == NULL)
3395
gtk_tree_selection_selected_foreach (tree_selection, add_selected_from_tree_view, &selections);
3396
if (selections == NULL)
3399
if (has_dirs != NULL)
3403
for (scan = selections; scan; scan = scan->next) {
3404
char *path = scan->data;
3407
list = g_list_concat (list, get_dir_list_from_path (window, path));
3409
path_list_free (selections);
3411
return g_list_reverse (list);
3416
fr_window_get_file_list_from_path_list (FrWindow *window,
3420
GtkTreeModel *model;
3421
GList *selections, *list, *scan;
3423
g_return_val_if_fail (window != NULL, NULL);
3425
model = GTK_TREE_MODEL (window->priv->list_store);
3428
if (has_dirs != NULL)
3431
for (scan = path_list; scan; scan = scan->next) {
3432
GtkTreeRowReference *reference = scan->data;
3437
path = gtk_tree_row_reference_get_path (reference);
3441
if (! gtk_tree_model_get_iter (model, &iter, path))
3444
gtk_tree_model_get (model, &iter,
3445
COLUMN_FILE_DATA, &fdata,
3448
selections = g_list_prepend (selections, fdata);
3452
for (scan = selections; scan; scan = scan->next) {
3453
FileData *fd = scan->data;
3458
if (file_data_is_dir (fd)) {
3459
if (has_dirs != NULL)
3461
list = g_list_concat (list, get_dir_list_from_file_data (window, fd));
3464
list = g_list_prepend (list, g_strdup (fd->original_path));
3467
if (selections != NULL)
3468
g_list_free (selections);
3470
return g_list_reverse (list);
3475
fr_window_get_file_list_pattern (FrWindow *window,
3476
const char *pattern)
3482
g_return_val_if_fail (window != NULL, NULL);
3484
regexps = search_util_get_regexps (pattern, G_REGEX_CASELESS);
3486
for (i = 0; i < window->archive->command->files->len; i++) {
3487
FileData *fd = g_ptr_array_index (window->archive->command->files, i);
3490
/* FIXME: only files in the current location ? */
3495
utf8_name = g_filename_to_utf8 (fd->name, -1, NULL, NULL, NULL);
3496
if (match_regexps (regexps, utf8_name, 0))
3497
list = g_list_prepend (list, g_strdup (fd->original_path));
3500
free_regexps (regexps);
3502
return g_list_reverse (list);
3507
fr_window_get_n_selected_files (FrWindow *window)
3509
return _gtk_count_selected (gtk_tree_view_get_selection (GTK_TREE_VIEW (window->priv->list_view)));
3517
dir_tree_button_press_cb (GtkWidget *widget,
3518
GdkEventButton *event,
3521
FrWindow *window = data;
3522
GtkTreeSelection *selection;
3524
if (event->window != gtk_tree_view_get_bin_window (GTK_TREE_VIEW (window->priv->tree_view)))
3527
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (window->priv->tree_view));
3528
if (selection == NULL)
3531
if ((event->type == GDK_BUTTON_PRESS) && (event->button == 3)) {
3535
if (gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (window->priv->tree_view),
3537
&path, NULL, NULL, NULL)) {
3539
if (! gtk_tree_model_get_iter (GTK_TREE_MODEL (window->priv->tree_store), &iter, path)) {
3540
gtk_tree_path_free (path);
3543
gtk_tree_path_free (path);
3545
if (! gtk_tree_selection_iter_is_selected (selection, &iter)) {
3546
gtk_tree_selection_unselect_all (selection);
3547
gtk_tree_selection_select_iter (selection, &iter);
3550
gtk_menu_popup (GTK_MENU (window->priv->sidebar_folder_popup_menu),
3557
gtk_tree_selection_unselect_all (selection);
3561
else if ((event->type == GDK_BUTTON_PRESS) && (event->button == 8)) {
3562
fr_window_go_back (window);
3565
else if ((event->type == GDK_BUTTON_PRESS) && (event->button == 9)) {
3566
fr_window_go_forward (window);
3575
fr_window_get_selected_item_from_file_list (FrWindow *window)
3577
GtkTreeSelection *tree_selection;
3579
FileData *fdata = NULL;
3581
g_return_val_if_fail (window != NULL, NULL);
3583
tree_selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (window->priv->list_view));
3584
if (tree_selection == NULL)
3588
gtk_tree_selection_selected_foreach (tree_selection, add_selected_from_list_view, &selection);
3589
if ((selection == NULL) || (selection->next != NULL)) {
3590
/* return NULL if the selection contains more than one entry. */
3591
g_list_free (selection);
3595
fdata = file_data_copy (selection->data);
3596
g_list_free (selection);
3603
fr_window_get_selected_folder_in_tree_view (FrWindow *window)
3605
GtkTreeSelection *tree_selection;
3609
g_return_val_if_fail (window != NULL, NULL);
3611
tree_selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (window->priv->tree_view));
3612
if (tree_selection == NULL)
3616
gtk_tree_selection_selected_foreach (tree_selection, add_selected_from_tree_view, &selections);
3618
if (selections != NULL) {
3619
path = selections->data;
3620
g_list_free (selections);
3628
fr_window_current_folder_activated (FrWindow *window,
3629
gboolean from_sidebar)
3633
if (! from_sidebar) {
3637
fdata = fr_window_get_selected_item_from_file_list (window);
3638
if ((fdata == NULL) || ! file_data_is_dir (fdata)) {
3639
file_data_free (fdata);
3642
dir_name = g_strdup (fdata->list_name);
3643
dir_path = g_strconcat (fr_window_get_current_location (window),
3648
file_data_free (fdata);
3651
dir_path = fr_window_get_selected_folder_in_tree_view (window);
3653
fr_window_go_to_location (window, dir_path, FALSE);
3660
row_activated_cb (GtkTreeView *tree_view,
3662
GtkTreeViewColumn *column,
3665
FrWindow *window = data;
3669
if (! gtk_tree_model_get_iter (GTK_TREE_MODEL (window->priv->list_store),
3674
gtk_tree_model_get (GTK_TREE_MODEL (window->priv->list_store), &iter,
3675
COLUMN_FILE_DATA, &fdata,
3678
if (! file_data_is_dir (fdata)) {
3679
GList *list = g_list_prepend (NULL, fdata->original_path);
3680
fr_window_open_files (window, list, FALSE);
3683
else if (window->priv->list_mode == FR_WINDOW_LIST_MODE_AS_DIR) {
3685
new_dir = g_strconcat (fr_window_get_current_location (window),
3689
fr_window_go_to_location (window, new_dir, FALSE);
3698
file_button_press_cb (GtkWidget *widget,
3699
GdkEventButton *event,
3702
FrWindow *window = data;
3703
GtkTreeSelection *selection;
3705
if (event->window != gtk_tree_view_get_bin_window (GTK_TREE_VIEW (window->priv->list_view)))
3708
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (window->priv->list_view));
3709
if (selection == NULL)
3712
if (window->priv->path_clicked != NULL) {
3713
gtk_tree_path_free (window->priv->path_clicked);
3714
window->priv->path_clicked = NULL;
3717
if ((event->type == GDK_BUTTON_PRESS) && (event->button == 3)) {
3722
if (gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (window->priv->list_view),
3724
&path, NULL, NULL, NULL)) {
3726
if (! gtk_tree_model_get_iter (GTK_TREE_MODEL (window->priv->list_store), &iter, path)) {
3727
gtk_tree_path_free (path);
3730
gtk_tree_path_free (path);
3732
if (! gtk_tree_selection_iter_is_selected (selection, &iter)) {
3733
gtk_tree_selection_unselect_all (selection);
3734
gtk_tree_selection_select_iter (selection, &iter);
3738
gtk_tree_selection_unselect_all (selection);
3740
n_selected = fr_window_get_n_selected_files (window);
3741
if ((n_selected == 1) && selection_has_a_dir (window))
3742
gtk_menu_popup (GTK_MENU (window->priv->folder_popup_menu),
3748
gtk_menu_popup (GTK_MENU (window->priv->file_popup_menu),
3755
else if ((event->type == GDK_BUTTON_PRESS) && (event->button == 1)) {
3756
GtkTreePath *path = NULL;
3758
if (! gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (window->priv->list_view),
3760
&path, NULL, NULL, NULL)) {
3761
gtk_tree_selection_unselect_all (selection);
3764
if (window->priv->path_clicked != NULL) {
3765
gtk_tree_path_free (window->priv->path_clicked);
3766
window->priv->path_clicked = NULL;
3770
window->priv->path_clicked = gtk_tree_path_copy (path);
3771
gtk_tree_path_free (path);
3776
else if ((event->type == GDK_BUTTON_PRESS) && (event->button == 8)) {
3778
fr_window_go_back (window);
3781
else if ((event->type == GDK_BUTTON_PRESS) && (event->button == 9)) {
3783
fr_window_go_forward (window);
3792
file_button_release_cb (GtkWidget *widget,
3793
GdkEventButton *event,
3796
FrWindow *window = data;
3797
GtkTreeSelection *selection;
3799
if (event->window != gtk_tree_view_get_bin_window (GTK_TREE_VIEW (window->priv->list_view)))
3802
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (window->priv->list_view));
3803
if (selection == NULL)
3806
if (window->priv->path_clicked == NULL)
3809
if ((event->type == GDK_BUTTON_RELEASE)
3810
&& (event->button == 1)
3811
&& (window->priv->path_clicked != NULL)) {
3812
GtkTreePath *path = NULL;
3814
if (gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (window->priv->list_view),
3816
&path, NULL, NULL, NULL)) {
3818
if ((gtk_tree_path_compare (window->priv->path_clicked, path) == 0)
3819
&& window->priv->single_click
3820
&& ! ((event->state & GDK_CONTROL_MASK) || (event->state & GDK_SHIFT_MASK))) {
3821
gtk_tree_view_set_cursor (GTK_TREE_VIEW (widget),
3825
gtk_tree_view_row_activated (GTK_TREE_VIEW (widget),
3832
gtk_tree_path_free (path);
3835
if (window->priv->path_clicked != NULL) {
3836
gtk_tree_path_free (window->priv->path_clicked);
3837
window->priv->path_clicked = NULL;
3845
file_motion_notify_callback (GtkWidget *widget,
3846
GdkEventMotion *event,
3849
FrWindow *window = user_data;
3851
GtkTreePath *last_hover_path;
3854
if (! window->priv->single_click)
3857
if (event->window != gtk_tree_view_get_bin_window (GTK_TREE_VIEW (window->priv->list_view)))
3860
last_hover_path = window->priv->list_hover_path;
3862
gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (widget),
3864
&window->priv->list_hover_path,
3867
if (window->priv->list_hover_path != NULL)
3868
cursor = gdk_cursor_new (GDK_HAND2);
3872
gdk_window_set_cursor (event->window, cursor);
3874
/* only redraw if the hover row has changed */
3875
if (!(last_hover_path == NULL && window->priv->list_hover_path == NULL) &&
3876
(!(last_hover_path != NULL && window->priv->list_hover_path != NULL) ||
3877
gtk_tree_path_compare (last_hover_path, window->priv->list_hover_path)))
3879
if (last_hover_path) {
3880
gtk_tree_model_get_iter (GTK_TREE_MODEL (window->priv->list_store),
3881
&iter, last_hover_path);
3882
gtk_tree_model_row_changed (GTK_TREE_MODEL (window->priv->list_store),
3883
last_hover_path, &iter);
3886
if (window->priv->list_hover_path) {
3887
gtk_tree_model_get_iter (GTK_TREE_MODEL (window->priv->list_store),
3888
&iter, window->priv->list_hover_path);
3889
gtk_tree_model_row_changed (GTK_TREE_MODEL (window->priv->list_store),
3890
window->priv->list_hover_path, &iter);
3894
gtk_tree_path_free (last_hover_path);
3901
file_leave_notify_callback (GtkWidget *widget,
3902
GdkEventCrossing *event,
3905
FrWindow *window = user_data;
3908
if (window->priv->single_click && (window->priv->list_hover_path != NULL)) {
3909
gtk_tree_model_get_iter (GTK_TREE_MODEL (window->priv->list_store),
3911
window->priv->list_hover_path);
3912
gtk_tree_model_row_changed (GTK_TREE_MODEL (window->priv->list_store),
3913
window->priv->list_hover_path,
3916
gtk_tree_path_free (window->priv->list_hover_path);
3917
window->priv->list_hover_path = NULL;
3924
/* -- drag and drop -- */
3928
get_uri_list_from_selection_data (char *uri_list)
3934
if (uri_list == NULL)
3937
uris = g_uri_list_extract_uris (uri_list);
3938
for (i = 0; uris[i] != NULL; i++)
3939
list = g_list_prepend (list, g_strdup (uris[i]));
3942
return g_list_reverse (list);
3947
fr_window_drag_motion (GtkWidget *widget,
3948
GdkDragContext *context,
3954
FrWindow *window = user_data;
3956
if ((gtk_drag_get_source_widget (context) == window->priv->list_view)
3957
|| (gtk_drag_get_source_widget (context) == window->priv->tree_view))
3959
gdk_drag_status (context, 0, time);
3967
static void fr_window_paste_from_clipboard_data (FrWindow *window, FrClipboardData *data);
3970
static FrClipboardData*
3971
get_clipboard_data_from_selection_data (FrWindow *window,
3974
FrClipboardData *clipboard_data;
3978
clipboard_data = fr_clipboard_data_new ();
3980
uris = g_strsplit (data, "\r\n", -1);
3982
clipboard_data->archive_filename = g_strdup (uris[0]);
3983
if (window->priv->password_for_paste != NULL)
3984
clipboard_data->archive_password = g_strdup (window->priv->password_for_paste);
3985
else if (strcmp (uris[1], "") != 0)
3986
clipboard_data->archive_password = g_strdup (uris[1]);
3987
clipboard_data->op = (strcmp (uris[2], "copy") == 0) ? FR_CLIPBOARD_OP_COPY : FR_CLIPBOARD_OP_CUT;
3988
clipboard_data->base_dir = g_strdup (uris[3]);
3989
for (i = 4; uris[i] != NULL; i++)
3990
if (uris[i][0] != '\0')
3991
clipboard_data->files = g_list_prepend (clipboard_data->files, g_strdup (uris[i]));
3992
clipboard_data->files = g_list_reverse (clipboard_data->files);
3996
return clipboard_data;
4001
fr_window_drag_data_received (GtkWidget *widget,
4002
GdkDragContext *context,
4005
GtkSelectionData *data,
4008
gpointer extra_data)
4010
FrWindow *window = extra_data;
4013
gboolean is_an_archive;
4015
debug (DEBUG_INFO, "::DragDataReceived -->\n");
4017
if ((gtk_drag_get_source_widget (context) == window->priv->list_view)
4018
|| (gtk_drag_get_source_widget (context) == window->priv->tree_view))
4020
gtk_drag_finish (context, FALSE, FALSE, time);
4024
if (! ((gtk_selection_data_get_length (data) >= 0) && (gtk_selection_data_get_format (data) == 8))) {
4025
gtk_drag_finish (context, FALSE, FALSE, time);
4029
if (window->priv->activity_ref > 0) {
4030
gtk_drag_finish (context, FALSE, FALSE, time);
4034
gtk_drag_finish (context, TRUE, FALSE, time);
4036
if (gtk_selection_data_get_target (data) == XFR_ATOM) {
4037
FrClipboardData *dnd_data;
4039
dnd_data = get_clipboard_data_from_selection_data (window, (char*) gtk_selection_data_get_data (data));
4040
dnd_data->current_dir = g_strdup (fr_window_get_current_location (window));
4041
fr_window_paste_from_clipboard_data (window, dnd_data);
4046
list = get_uri_list_from_selection_data ((char*) gtk_selection_data_get_data (data));
4050
d = _gtk_error_dialog_new (GTK_WINDOW (window),
4053
_("Could not perform the operation"),
4055
gtk_dialog_run (GTK_DIALOG (d));
4056
gtk_widget_destroy(d);
4061
one_file = (list->next == NULL);
4063
is_an_archive = uri_is_archive (list->data);
4065
is_an_archive = FALSE;
4067
if (window->priv->archive_present
4068
&& (window->archive != NULL)
4069
&& ! window->archive->read_only
4070
&& ! window->archive->is_compressed_file)
4072
if (one_file && is_an_archive) {
4076
d = _gtk_message_dialog_new (GTK_WINDOW (window),
4078
GTK_STOCK_DIALOG_QUESTION,
4079
_("Do you want to add this file to the current archive or open it as a new archive?"),
4081
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
4086
gtk_dialog_set_default_response (GTK_DIALOG (d), 2);
4088
r = gtk_dialog_run (GTK_DIALOG (d));
4089
gtk_widget_destroy (GTK_WIDGET (d));
4091
if (r == 0) /* Add */
4092
fr_window_archive_add_dropped_items (window, list, FALSE);
4093
else if (r == 1) /* Open */
4094
fr_window_archive_open (window, list->data, GTK_WINDOW (window));
4097
fr_window_archive_add_dropped_items (window, list, FALSE);
4100
if (one_file && is_an_archive)
4101
fr_window_archive_open (window, list->data, GTK_WINDOW (window));
4106
d = _gtk_message_dialog_new (GTK_WINDOW (window),
4108
GTK_STOCK_DIALOG_QUESTION,
4109
_("Do you want to create a new archive with these files?"),
4111
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
4112
_("Create _Archive"), GTK_RESPONSE_YES,
4115
gtk_dialog_set_default_response (GTK_DIALOG (d), GTK_RESPONSE_YES);
4116
r = gtk_dialog_run (GTK_DIALOG (d));
4117
gtk_widget_destroy (GTK_WIDGET (d));
4119
if (r == GTK_RESPONSE_YES) {
4122
char *local_path = NULL;
4123
char *utf8_path = NULL;
4124
const char *archive_name;
4126
fr_window_free_batch_data (window);
4127
fr_window_append_batch_action (window,
4128
FR_BATCH_ACTION_ADD,
4129
path_list_dup (list),
4130
(GFreeFunc) path_list_free);
4132
first_item = (char*) list->data;
4133
folder = remove_level_from_path (first_item);
4135
fr_window_set_open_default_dir (window, folder);
4137
if ((list->next != NULL) && (folder != NULL)) {
4138
archive_name = file_name_from_path (folder);
4141
if (uri_is_local (first_item)) {
4142
local_path = g_filename_from_uri (first_item, NULL, NULL);
4144
utf8_path = g_filename_to_utf8 (local_path, -1, NULL, NULL, NULL);
4146
utf8_path= g_strdup (first_item);
4147
g_free (local_path);
4150
utf8_path = g_strdup (first_item);
4152
archive_name = file_name_from_path (utf8_path);
4155
show_new_archive_dialog (window, archive_name);
4163
path_list_free (list);
4165
debug (DEBUG_INFO, "::DragDataReceived <--\n");
4170
file_list_drag_begin (GtkWidget *widget,
4171
GdkDragContext *context,
4174
FrWindow *window = data;
4176
debug (DEBUG_INFO, "::DragBegin -->\n");
4178
if (window->priv->activity_ref > 0)
4181
g_free (window->priv->drag_destination_folder);
4182
window->priv->drag_destination_folder = NULL;
4184
g_free (window->priv->drag_base_dir);
4185
window->priv->drag_base_dir = NULL;
4187
gdk_property_change (gdk_drag_context_get_source_window (context),
4188
XDS_ATOM, TEXT_ATOM,
4189
8, GDK_PROP_MODE_REPLACE,
4190
(guchar *) XDS_FILENAME,
4191
strlen (XDS_FILENAME));
4198
file_list_drag_end (GtkWidget *widget,
4199
GdkDragContext *context,
4202
FrWindow *window = data;
4204
debug (DEBUG_INFO, "::DragEnd -->\n");
4206
gdk_property_delete (gdk_drag_context_get_source_window (context), XDS_ATOM);
4208
if (window->priv->drag_error != NULL) {
4209
_gtk_error_dialog_run (GTK_WINDOW (window),
4210
_("Extraction not performed"),
4212
window->priv->drag_error->message);
4213
g_clear_error (&window->priv->drag_error);
4215
else if (window->priv->drag_destination_folder != NULL) {
4216
fr_window_archive_extract (window,
4217
window->priv->drag_file_list,
4218
window->priv->drag_destination_folder,
4219
window->priv->drag_base_dir,
4224
path_list_free (window->priv->drag_file_list);
4225
window->priv->drag_file_list = NULL;
4228
debug (DEBUG_INFO, "::DragEnd <--\n");
4232
/* The following three functions taken from bugzilla
4233
* (http://bugzilla.gnome.org/attachment.cgi?id=49362&action=view)
4234
* Author: Christian Neumair
4235
* Copyright: 2005 Free Software Foundation, Inc
4238
get_xds_atom_value (GdkDragContext *context)
4242
g_return_val_if_fail (context != NULL, NULL);
4243
g_return_val_if_fail (gdk_drag_context_get_source_window (context) != NULL, NULL);
4245
if (gdk_property_get (gdk_drag_context_get_source_window (context),
4246
XDS_ATOM, TEXT_ATOM,
4247
0, MAX_XDS_ATOM_VAL_LEN,
4248
FALSE, NULL, NULL, NULL,
4249
(unsigned char **) &ret))
4257
context_offers_target (GdkDragContext *context,
4260
return (g_list_find (gdk_drag_context_list_targets (context), target) != NULL);
4265
nautilus_xds_dnd_is_valid_xds_context (GdkDragContext *context)
4270
g_return_val_if_fail (context != NULL, FALSE);
4273
if (context_offers_target (context, XDS_ATOM)) {
4274
tmp = get_xds_atom_value (context);
4277
ret = (tmp != NULL);
4285
get_selection_data_from_clipboard_data (FrWindow *window,
4286
FrClipboardData *data)
4289
char *local_filename;
4292
list = g_string_new (NULL);
4294
local_filename = g_file_get_uri (window->archive->local_copy);
4295
g_string_append (list, local_filename);
4296
g_free (local_filename);
4298
g_string_append (list, "\r\n");
4299
if (window->priv->password != NULL)
4300
g_string_append (list, window->priv->password);
4301
g_string_append (list, "\r\n");
4302
g_string_append (list, (data->op == FR_CLIPBOARD_OP_COPY) ? "copy" : "cut");
4303
g_string_append (list, "\r\n");
4304
g_string_append (list, data->base_dir);
4305
g_string_append (list, "\r\n");
4306
for (scan = data->files; scan; scan = scan->next) {
4307
g_string_append (list, scan->data);
4308
g_string_append (list, "\r\n");
4311
return g_string_free (list, FALSE);
4316
fr_window_folder_tree_drag_data_get (GtkWidget *widget,
4317
GdkDragContext *context,
4318
GtkSelectionData *selection_data,
4323
FrWindow *window = user_data;
4326
char *destination_folder;
4328
debug (DEBUG_INFO, "::DragDataGet -->\n");
4330
if (window->priv->activity_ref > 0)
4333
file_list = fr_window_get_folder_tree_selection (window, TRUE, NULL);
4334
if (file_list == NULL)
4337
if (gtk_selection_data_get_target (selection_data) == XFR_ATOM) {
4338
FrClipboardData *tmp;
4341
tmp = fr_clipboard_data_new ();
4342
tmp->files = file_list;
4343
tmp->op = FR_CLIPBOARD_OP_COPY;
4344
tmp->base_dir = g_strdup (fr_window_get_current_location (window));
4346
data = get_selection_data_from_clipboard_data (window, tmp);
4347
gtk_selection_data_set (selection_data, XFR_ATOM, 8, (guchar *) data, strlen (data));
4349
fr_clipboard_data_unref (tmp);
4355
if (! nautilus_xds_dnd_is_valid_xds_context (context))
4358
destination = get_xds_atom_value (context);
4359
g_return_val_if_fail (destination != NULL, FALSE);
4361
destination_folder = remove_level_from_path (destination);
4362
g_free (destination);
4364
/* check whether the extraction can be performed in the destination
4367
g_clear_error (&window->priv->drag_error);
4369
if (! check_permissions (destination_folder, R_OK | W_OK)) {
4370
char *destination_folder_display_name;
4372
destination_folder_display_name = g_filename_display_name (destination_folder);
4373
window->priv->drag_error = g_error_new (FR_ERROR, 0, _("You don't have the right permissions to extract archives in the folder \"%s\""), destination_folder_display_name);
4374
g_free (destination_folder_display_name);
4377
if (window->priv->drag_error == NULL) {
4378
g_free (window->priv->drag_destination_folder);
4379
g_free (window->priv->drag_base_dir);
4380
path_list_free (window->priv->drag_file_list);
4381
window->priv->drag_destination_folder = g_strdup (destination_folder);
4382
window->priv->drag_base_dir = fr_window_get_selected_folder_in_tree_view (window);
4383
window->priv->drag_file_list = file_list;
4386
g_free (destination_folder);
4388
/* sends back the response */
4390
gtk_selection_data_set (selection_data, gtk_selection_data_get_target (selection_data), 8, (guchar *) ((window->priv->drag_error == NULL) ? "S" : "E"), 1);
4392
debug (DEBUG_INFO, "::DragDataGet <--\n");
4399
fr_window_file_list_drag_data_get (FrWindow *window,
4400
GdkDragContext *context,
4401
GtkSelectionData *selection_data,
4405
char *destination_folder;
4407
debug (DEBUG_INFO, "::DragDataGet -->\n");
4409
if (window->priv->path_clicked != NULL) {
4410
gtk_tree_path_free (window->priv->path_clicked);
4411
window->priv->path_clicked = NULL;
4414
if (window->priv->activity_ref > 0)
4417
if (gtk_selection_data_get_target (selection_data) == XFR_ATOM) {
4418
FrClipboardData *tmp;
4421
tmp = fr_clipboard_data_new ();
4422
tmp->files = fr_window_get_file_list_selection (window, TRUE, NULL);
4423
tmp->op = FR_CLIPBOARD_OP_COPY;
4424
tmp->base_dir = g_strdup (fr_window_get_current_location (window));
4426
data = get_selection_data_from_clipboard_data (window, tmp);
4427
gtk_selection_data_set (selection_data, XFR_ATOM, 8, (guchar *) data, strlen (data));
4429
fr_clipboard_data_unref (tmp);
4435
if (! nautilus_xds_dnd_is_valid_xds_context (context))
4438
destination = get_xds_atom_value (context);
4439
g_return_val_if_fail (destination != NULL, FALSE);
4441
destination_folder = remove_level_from_path (destination);
4442
g_free (destination);
4444
/* check whether the extraction can be performed in the destination
4447
g_clear_error (&window->priv->drag_error);
4449
if (! check_permissions (destination_folder, R_OK | W_OK)) {
4450
char *destination_folder_display_name;
4452
destination_folder_display_name = g_filename_display_name (destination_folder);
4453
window->priv->drag_error = g_error_new (FR_ERROR, 0, _("You don't have the right permissions to extract archives in the folder \"%s\""), destination_folder_display_name);
4454
g_free (destination_folder_display_name);
4457
if (window->priv->drag_error == NULL) {
4458
g_free (window->priv->drag_destination_folder);
4459
g_free (window->priv->drag_base_dir);
4460
path_list_free (window->priv->drag_file_list);
4461
window->priv->drag_destination_folder = g_strdup (destination_folder);
4462
window->priv->drag_base_dir = g_strdup (fr_window_get_current_location (window));
4463
window->priv->drag_file_list = fr_window_get_file_list_from_path_list (window, path_list, NULL);
4466
g_free (destination_folder);
4468
/* sends back the response */
4470
gtk_selection_data_set (selection_data, gtk_selection_data_get_target (selection_data), 8, (guchar *) ((window->priv->drag_error == NULL) ? "S" : "E"), 1);
4472
debug (DEBUG_INFO, "::DragDataGet <--\n");
4478
/* -- window_new -- */
4482
fr_window_deactivate_filter (FrWindow *window)
4484
window->priv->filter_mode = FALSE;
4485
window->priv->list_mode = window->priv->last_list_mode;
4487
gtk_entry_set_text (GTK_ENTRY (window->priv->filter_entry), "");
4488
fr_window_update_filter_bar_visibility (window);
4490
gtk_list_store_clear (window->priv->list_store);
4492
fr_window_update_columns_visibility (window);
4493
fr_window_update_file_list (window, TRUE);
4494
fr_window_update_dir_tree (window);
4495
fr_window_update_current_location (window);
4500
key_press_cb (GtkWidget *widget,
4504
FrWindow *window = data;
4505
gboolean retval = FALSE;
4508
if (gtk_widget_has_focus (window->priv->location_entry))
4511
if (gtk_widget_has_focus (window->priv->filter_entry)) {
4512
switch (event->keyval) {
4513
case GDK_KEY_Escape:
4514
fr_window_deactivate_filter (window);
4523
alt = (event->state & GDK_MOD1_MASK) == GDK_MOD1_MASK;
4525
switch (event->keyval) {
4526
case GDK_KEY_Escape:
4527
activate_action_stop (NULL, window);
4528
if (window->priv->filter_mode)
4529
fr_window_deactivate_filter (window);
4534
if (event->state & GDK_SHIFT_MASK) {
4535
GtkTreeSelection *selection;
4537
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (window->priv->list_view));
4538
if (selection == NULL)
4541
gtk_menu_popup (GTK_MENU (window->priv->file_popup_menu),
4553
fr_window_go_up_one_level (window);
4558
case GDK_KEY_BackSpace:
4559
fr_window_go_up_one_level (window);
4564
case GDK_KEY_KP_Right:
4566
fr_window_go_forward (window);
4572
case GDK_KEY_KP_Left:
4574
fr_window_go_back (window);
4580
case GDK_KEY_KP_Home:
4582
fr_window_go_to_location (window, "/", FALSE);
4596
dir_tree_selection_changed_cb (GtkTreeSelection *selection,
4599
FrWindow *window = user_data;
4602
if (gtk_tree_selection_get_selected (selection, NULL, &iter)) {
4605
gtk_tree_model_get (GTK_TREE_MODEL (window->priv->tree_store),
4607
TREE_COLUMN_PATH, &path,
4609
fr_window_go_to_location (window, path, FALSE);
4618
selection_changed_cb (GtkTreeSelection *selection,
4621
FrWindow *window = user_data;
4623
fr_window_update_statusbar_list_info (window);
4624
fr_window_update_sensitivity (window);
4631
fr_window_delete_event_cb (GtkWidget *caller,
4635
fr_window_close (window);
4640
is_single_click_policy (FrWindow *window)
4645
value = g_settings_get_string (window->priv->settings_nautilus, NAUTILUS_CLICK_POLICY);
4646
result = (value != NULL) && (strncmp (value, "single", 6) == 0);
4654
filename_cell_data_func (GtkTreeViewColumn *column,
4655
GtkCellRenderer *renderer,
4656
GtkTreeModel *model,
4662
PangoUnderline underline;
4664
gtk_tree_model_get (model, iter,
4668
if (window->priv->single_click) {
4669
path = gtk_tree_model_get_path (model, iter);
4671
if ((window->priv->list_hover_path == NULL)
4672
|| gtk_tree_path_compare (path, window->priv->list_hover_path))
4673
underline = PANGO_UNDERLINE_NONE;
4675
underline = PANGO_UNDERLINE_SINGLE;
4677
gtk_tree_path_free (path);
4680
underline = PANGO_UNDERLINE_NONE;
4682
g_object_set (G_OBJECT (renderer),
4684
"underline", underline,
4692
add_dir_tree_columns (FrWindow *window,
4693
GtkTreeView *treeview)
4695
GtkCellRenderer *renderer;
4696
GtkTreeViewColumn *column;
4697
GValue value = { 0, };
4701
column = gtk_tree_view_column_new ();
4702
gtk_tree_view_column_set_title (column, _("Folders"));
4706
renderer = gtk_cell_renderer_pixbuf_new ();
4707
gtk_tree_view_column_pack_start (column, renderer, FALSE);
4708
gtk_tree_view_column_set_attributes (column, renderer,
4709
"pixbuf", TREE_COLUMN_ICON,
4714
renderer = gtk_cell_renderer_text_new ();
4716
g_value_init (&value, PANGO_TYPE_ELLIPSIZE_MODE);
4717
g_value_set_enum (&value, PANGO_ELLIPSIZE_END);
4718
g_object_set_property (G_OBJECT (renderer), "ellipsize", &value);
4719
g_value_unset (&value);
4721
gtk_tree_view_column_pack_start (column,
4724
gtk_tree_view_column_set_attributes (column, renderer,
4725
"text", TREE_COLUMN_NAME,
4726
"weight", TREE_COLUMN_WEIGHT,
4729
gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
4730
gtk_tree_view_column_set_sort_column_id (column, TREE_COLUMN_NAME);
4732
gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
4737
add_file_list_columns (FrWindow *window,
4738
GtkTreeView *treeview)
4740
static char *titles[] = {NC_("File", "Size"),
4741
NC_("File", "Type"),
4742
NC_("File", "Date Modified"),
4743
NC_("File", "Location")};
4744
GtkCellRenderer *renderer;
4745
GtkTreeViewColumn *column;
4746
GValue value = { 0, };
4751
window->priv->filename_column = column = gtk_tree_view_column_new ();
4752
gtk_tree_view_column_set_title (column, C_("File", "Name"));
4756
renderer = gtk_cell_renderer_pixbuf_new ();
4757
gtk_tree_view_column_pack_end (column, renderer, FALSE);
4758
gtk_tree_view_column_set_attributes (column, renderer,
4759
"pixbuf", COLUMN_EMBLEM,
4764
renderer = gtk_cell_renderer_pixbuf_new ();
4765
gtk_tree_view_column_pack_start (column, renderer, FALSE);
4766
gtk_tree_view_column_set_attributes (column, renderer,
4767
"pixbuf", COLUMN_ICON,
4772
window->priv->single_click = is_single_click_policy (window);
4774
renderer = gtk_cell_renderer_text_new ();
4776
g_value_init (&value, PANGO_TYPE_ELLIPSIZE_MODE);
4777
g_value_set_enum (&value, PANGO_ELLIPSIZE_END);
4778
g_object_set_property (G_OBJECT (renderer), "ellipsize", &value);
4779
g_value_unset (&value);
4781
gtk_tree_view_column_pack_start (column,
4784
gtk_tree_view_column_set_attributes (column, renderer,
4785
"text", COLUMN_NAME,
4788
gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_FIXED);
4789
w = g_settings_get_int (window->priv->settings_listing, PREF_LISTING_NAME_COLUMN_WIDTH);
4791
w = DEFAULT_NAME_COLUMN_WIDTH;
4792
gtk_tree_view_column_set_fixed_width (column, w);
4793
gtk_tree_view_column_set_resizable (column, TRUE);
4794
gtk_tree_view_column_set_sort_column_id (column, COLUMN_NAME);
4795
gtk_tree_view_column_set_cell_data_func (column, renderer,
4796
(GtkTreeCellDataFunc) filename_cell_data_func,
4799
gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
4803
for (j = 0, i = COLUMN_SIZE; i < NUMBER_OF_COLUMNS; i++, j++) {
4804
GValue value = { 0, };
4806
renderer = gtk_cell_renderer_text_new ();
4807
column = gtk_tree_view_column_new_with_attributes (g_dpgettext2 (NULL, "File", titles[j]),
4812
gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_FIXED);
4813
gtk_tree_view_column_set_fixed_width (column, OTHER_COLUMNS_WIDTH);
4814
gtk_tree_view_column_set_resizable (column, TRUE);
4816
gtk_tree_view_column_set_sort_column_id (column, i);
4818
g_value_init (&value, PANGO_TYPE_ELLIPSIZE_MODE);
4819
g_value_set_enum (&value, PANGO_ELLIPSIZE_END);
4820
g_object_set_property (G_OBJECT (renderer), "ellipsize", &value);
4821
g_value_unset (&value);
4823
gtk_tree_view_append_column (treeview, column);
4829
name_column_sort_func (GtkTreeModel *model,
4834
FileData *fdata1, *fdata2;
4836
gtk_tree_model_get (model, a, COLUMN_FILE_DATA, &fdata1, -1);
4837
gtk_tree_model_get (model, b, COLUMN_FILE_DATA, &fdata2, -1);
4839
return sort_by_name (&fdata1, &fdata2);
4844
size_column_sort_func (GtkTreeModel *model,
4849
FileData *fdata1, *fdata2;
4851
gtk_tree_model_get (model, a, COLUMN_FILE_DATA, &fdata1, -1);
4852
gtk_tree_model_get (model, b, COLUMN_FILE_DATA, &fdata2, -1);
4854
return sort_by_size (&fdata1, &fdata2);
4859
type_column_sort_func (GtkTreeModel *model,
4864
FileData *fdata1, *fdata2;
4866
gtk_tree_model_get (model, a, COLUMN_FILE_DATA, &fdata1, -1);
4867
gtk_tree_model_get (model, b, COLUMN_FILE_DATA, &fdata2, -1);
4869
return sort_by_type (&fdata1, &fdata2);
4874
time_column_sort_func (GtkTreeModel *model,
4879
FileData *fdata1, *fdata2;
4881
gtk_tree_model_get (model, a, COLUMN_FILE_DATA, &fdata1, -1);
4882
gtk_tree_model_get (model, b, COLUMN_FILE_DATA, &fdata2, -1);
4884
return sort_by_time (&fdata1, &fdata2);
4889
path_column_sort_func (GtkTreeModel *model,
4894
FileData *fdata1, *fdata2;
4896
gtk_tree_model_get (model, a, COLUMN_FILE_DATA, &fdata1, -1);
4897
gtk_tree_model_get (model, b, COLUMN_FILE_DATA, &fdata2, -1);
4899
return sort_by_path (&fdata1, &fdata2);
4904
no_sort_column_sort_func (GtkTreeModel *model,
4914
sort_column_changed_cb (GtkTreeSortable *sortable,
4917
FrWindow *window = user_data;
4921
if (! gtk_tree_sortable_get_sort_column_id (sortable,
4926
window->priv->sort_method = get_sort_method_from_column (column_id);
4927
window->priv->sort_type = order;
4929
/*set_active (window, get_action_from_sort_method (window->priv->sort_method), TRUE);
4930
set_active (window, "SortReverseOrder", (window->priv->sort_type == GTK_SORT_DESCENDING));*/
4935
fr_window_show_cb (GtkWidget *widget,
4938
fr_window_update_current_location (window);
4940
set_active (window, "ViewToolbar", g_settings_get_boolean (window->priv->settings_ui, PREF_UI_VIEW_TOOLBAR));
4941
set_active (window, "ViewStatusbar", g_settings_get_boolean (window->priv->settings_ui, PREF_UI_VIEW_STATUSBAR));
4943
window->priv->view_folders = g_settings_get_boolean (window->priv->settings_ui, PREF_UI_VIEW_FOLDERS);
4944
set_active (window, "ViewFolders", window->priv->view_folders);
4946
fr_window_update_filter_bar_visibility (window);
4952
/* preferences changes notification callbacks */
4956
pref_history_len_changed (GSettings *settings,
4960
FrWindow *window = user_data;
4962
gtk_recent_chooser_set_limit (GTK_RECENT_CHOOSER (window->priv->recent_chooser_menu),
4963
g_settings_get_int (settings, PREF_UI_HISTORY_LEN));
4964
gtk_recent_chooser_set_limit (GTK_RECENT_CHOOSER (window->priv->recent_chooser_toolbar),
4965
g_settings_get_int (settings, PREF_UI_HISTORY_LEN));
4970
pref_view_toolbar_changed (GSettings *settings,
4974
FrWindow *window = user_data;
4976
fr_window_set_toolbar_visibility (window, g_settings_get_boolean (settings, key));
4981
pref_view_statusbar_changed (GSettings *settings,
4985
FrWindow *window = user_data;
4987
fr_window_set_statusbar_visibility (window, g_settings_get_boolean (settings, key));
4992
pref_view_folders_changed (GSettings *settings,
4996
FrWindow *window = user_data;
4998
fr_window_set_folders_visibility (window, g_settings_get_boolean (settings, key));
5003
pref_show_field_changed (GSettings *settings,
5007
FrWindow *window = user_data;
5009
fr_window_update_columns_visibility (window);
5014
pref_click_policy_changed (GSettings *settings,
5018
FrWindow *window = user_data;
5019
GdkWindow *win = gtk_tree_view_get_bin_window (GTK_TREE_VIEW (window->priv->list_view));
5020
GdkDisplay *display;
5022
window->priv->single_click = is_single_click_policy (window);
5024
gdk_window_set_cursor (win, NULL);
5025
display = gtk_widget_get_display (GTK_WIDGET (window->priv->list_view));
5026
if (display != NULL)
5027
gdk_display_flush (display);
5031
static void gh_unref_pixbuf (gpointer key,
5033
gpointer user_data);
5037
pref_use_mime_icons_changed (GSettings *settings,
5041
FrWindow *window = user_data;
5043
if (pixbuf_hash != NULL) {
5044
g_hash_table_foreach (pixbuf_hash,
5047
g_hash_table_destroy (pixbuf_hash);
5048
pixbuf_hash = g_hash_table_new (g_str_hash, g_str_equal);
5050
if (tree_pixbuf_hash != NULL) {
5051
g_hash_table_foreach (tree_pixbuf_hash,
5054
g_hash_table_destroy (tree_pixbuf_hash);
5055
tree_pixbuf_hash = g_hash_table_new (g_str_hash, g_str_equal);
5058
fr_window_update_file_list (window, FALSE);
5059
fr_window_update_dir_tree (window);
5064
theme_changed_cb (GtkIconTheme *theme, FrWindow *window)
5066
int icon_width, icon_height;
5068
gtk_icon_size_lookup_for_settings (gtk_widget_get_settings (GTK_WIDGET (window)),
5069
FILE_LIST_ICON_SIZE,
5070
&icon_width, &icon_height);
5071
file_list_icon_size = MAX (icon_width, icon_height);
5073
gtk_icon_size_lookup_for_settings (gtk_widget_get_settings (GTK_WIDGET (window)),
5075
&icon_width, &icon_height);
5076
dir_tree_icon_size = MAX (icon_width, icon_height);
5078
if (pixbuf_hash != NULL) {
5079
g_hash_table_foreach (pixbuf_hash,
5082
g_hash_table_destroy (pixbuf_hash);
5083
pixbuf_hash = g_hash_table_new (g_str_hash, g_str_equal);
5085
if (tree_pixbuf_hash != NULL) {
5086
g_hash_table_foreach (tree_pixbuf_hash,
5089
g_hash_table_destroy (tree_pixbuf_hash);
5090
tree_pixbuf_hash = g_hash_table_new (g_str_hash, g_str_equal);
5093
fr_window_update_file_list (window, TRUE);
5094
fr_window_update_dir_tree (window);
5099
fr_window_stoppable_cb (FrCommand *command,
5103
window->priv->stoppable = stoppable;
5104
set_sensitive (window, "Stop", stoppable);
5105
if (window->priv->progress_dialog != NULL)
5106
gtk_dialog_set_response_sensitive (GTK_DIALOG (window->priv->progress_dialog),
5114
fr_window_fake_load (FrArchive *archive,
5117
/* fake loads are disabled to allow exact progress dialogs (#153281) */
5122
FrWindow *window = data;
5123
gboolean add_after_opening = FALSE;
5124
gboolean extract_after_opening = FALSE;
5127
/* fake loads are used only in batch mode to avoid unnecessary
5128
* archive loadings. */
5130
if (! window->priv->batch_mode)
5133
/* Check whether there is an ADD or EXTRACT action in the batch list. */
5135
for (scan = window->priv->batch_action; scan; scan = scan->next) {
5136
FRBatchAction *action;
5138
action = (FRBatchAction *) scan->data;
5139
if (action->type == FR_BATCH_ACTION_ADD) {
5140
add_after_opening = TRUE;
5143
if ((action->type == FR_BATCH_ACTION_EXTRACT)
5144
|| (action->type == FR_BATCH_ACTION_EXTRACT_HERE)
5145
|| (action->type == FR_BATCH_ACTION_EXTRACT_INTERACT))
5147
extract_after_opening = TRUE;
5152
/* use fake load when in batch mode and the archive type supports all
5153
* of the required features */
5155
return (window->priv->batch_mode
5156
&& ! (add_after_opening && window->priv->update_dropped_files && ! archive->command->propAddCanUpdate)
5157
&& ! (add_after_opening && ! window->priv->update_dropped_files && ! archive->command->propAddCanReplace)
5158
&& ! (extract_after_opening && !archive->command->propCanExtractAll));
5164
fr_window_add_is_stoppable (FrArchive *archive,
5167
FrWindow *window = data;
5168
return window->priv->archive_new;
5173
menu_item_select_cb (GtkMenuItem *proxy,
5179
action = gtk_activatable_get_related_action (GTK_ACTIVATABLE (proxy));
5180
g_return_if_fail (action != NULL);
5182
g_object_get (G_OBJECT (action), "tooltip", &message, NULL);
5184
gtk_statusbar_push (GTK_STATUSBAR (window->priv->statusbar),
5185
window->priv->help_message_cid, message);
5192
menu_item_deselect_cb (GtkMenuItem *proxy,
5195
gtk_statusbar_pop (GTK_STATUSBAR (window->priv->statusbar),
5196
window->priv->help_message_cid);
5201
disconnect_proxy_cb (GtkUIManager *manager,
5206
if (GTK_IS_MENU_ITEM (proxy)) {
5207
g_signal_handlers_disconnect_by_func
5208
(proxy, G_CALLBACK (menu_item_select_cb), window);
5209
g_signal_handlers_disconnect_by_func
5210
(proxy, G_CALLBACK (menu_item_deselect_cb), window);
5216
connect_proxy_cb (GtkUIManager *manager,
5221
if (GTK_IS_MENU_ITEM (proxy)) {
5222
g_signal_connect (proxy, "select",
5223
G_CALLBACK (menu_item_select_cb), window);
5224
g_signal_connect (proxy, "deselect",
5225
G_CALLBACK (menu_item_deselect_cb), window);
5231
view_as_radio_action (GtkAction *action,
5232
GtkRadioAction *current,
5235
FrWindow *window = data;
5236
fr_window_set_list_mode (window, gtk_radio_action_get_current_value (current));
5241
sort_by_radio_action (GtkAction *action,
5242
GtkRadioAction *current,
5245
FrWindow *window = data;
5247
window->priv->sort_method = gtk_radio_action_get_current_value (current);
5248
window->priv->sort_type = GTK_SORT_ASCENDING;
5249
fr_window_update_list_order (window);
5254
recent_chooser_item_activated_cb (GtkRecentChooser *chooser,
5259
uri = gtk_recent_chooser_get_current_uri (chooser);
5261
fr_window_archive_open (window, uri, GTK_WINDOW (window));
5268
fr_window_init_recent_chooser (FrWindow *window,
5269
GtkRecentChooser *chooser)
5271
GtkRecentFilter *filter;
5274
g_return_if_fail (chooser != NULL);
5276
filter = gtk_recent_filter_new ();
5277
gtk_recent_filter_set_name (filter, _("All archives"));
5278
for (i = 0; open_type[i] != -1; i++)
5279
gtk_recent_filter_add_mime_type (filter, mime_type_desc[open_type[i]].mime_type);
5280
gtk_recent_filter_add_application (filter, "File Roller");
5281
gtk_recent_chooser_add_filter (chooser, filter);
5283
gtk_recent_chooser_set_local_only (chooser, FALSE);
5284
gtk_recent_chooser_set_limit (chooser, g_settings_get_int (window->priv->settings_ui, PREF_UI_HISTORY_LEN));
5285
gtk_recent_chooser_set_show_not_found (chooser, TRUE);
5286
gtk_recent_chooser_set_sort_type (chooser, GTK_RECENT_SORT_MRU);
5288
g_signal_connect (G_OBJECT (chooser),
5290
G_CALLBACK (recent_chooser_item_activated_cb),
5296
close_sidepane_button_clicked_cb (GtkButton *button,
5299
fr_window_set_folders_visibility (window, FALSE);
5304
fr_window_activate_filter (FrWindow *window)
5306
GtkTreeView *tree_view = GTK_TREE_VIEW (window->priv->list_view);
5307
GtkTreeViewColumn *column;
5309
fr_window_update_filter_bar_visibility (window);
5310
window->priv->list_mode = FR_WINDOW_LIST_MODE_FLAT;
5312
gtk_list_store_clear (window->priv->list_store);
5314
column = gtk_tree_view_get_column (tree_view, 4);
5315
gtk_tree_view_column_set_visible (column, TRUE);
5317
fr_window_update_file_list (window, TRUE);
5318
fr_window_update_dir_tree (window);
5319
fr_window_update_current_location (window);
5324
filter_entry_activate_cb (GtkEntry *entry,
5327
fr_window_activate_filter (window);
5332
filter_entry_icon_release_cb (GtkEntry *entry,
5333
GtkEntryIconPosition icon_pos,
5334
GdkEventButton *event,
5337
FrWindow *window = FR_WINDOW (user_data);
5339
if ((event->button == 1) && (icon_pos == GTK_ENTRY_ICON_SECONDARY))
5340
fr_window_deactivate_filter (window);
5345
fr_window_attach (FrWindow *window,
5351
g_return_if_fail (window != NULL);
5352
g_return_if_fail (FR_IS_WINDOW (window));
5353
g_return_if_fail (child != NULL);
5354
g_return_if_fail (GTK_IS_WIDGET (child));
5357
case FR_WINDOW_AREA_MENUBAR:
5360
case FR_WINDOW_AREA_TOOLBAR:
5363
case FR_WINDOW_AREA_LOCATIONBAR:
5366
case FR_WINDOW_AREA_CONTENTS:
5368
if (window->priv->contents != NULL)
5369
gtk_widget_destroy (window->priv->contents);
5370
window->priv->contents = child;
5372
case FR_WINDOW_AREA_FILTERBAR:
5375
case FR_WINDOW_AREA_STATUSBAR:
5379
g_critical ("%s: area not recognized!", G_STRFUNC);
5384
gtk_table_attach (GTK_TABLE (window->priv->layout),
5387
position, position + 1,
5388
GTK_EXPAND | GTK_FILL,
5389
((area == FR_WINDOW_AREA_CONTENTS) ? GTK_EXPAND : 0) | GTK_FILL,
5395
set_action_important (GtkUIManager *ui,
5396
const char *action_name)
5400
action = gtk_ui_manager_get_action (ui, action_name);
5401
g_object_set (action, "is_important", TRUE, NULL);
5402
g_object_unref (action);
5407
fr_window_construct (FrWindow *window)
5411
GtkWidget *list_scrolled_window;
5412
GtkWidget *location_box;
5413
GtkStatusbar *statusbar;
5414
GtkWidget *statusbar_box;
5415
GtkWidget *filter_box;
5416
GtkWidget *tree_scrolled_window;
5417
GtkWidget *sidepane_title;
5418
GtkWidget *sidepane_title_box;
5419
GtkWidget *sidepane_title_label;
5420
GtkWidget *close_sidepane_button;
5421
GtkTreeSelection *selection;
5422
int icon_width, icon_height;
5423
GtkActionGroup *actions;
5425
GtkToolItem *open_recent_tool_item;
5426
GtkWidget *menu_item;
5427
GError *error = NULL;
5429
/* data common to all windows. */
5431
if (pixbuf_hash == NULL)
5432
pixbuf_hash = g_hash_table_new (g_str_hash, g_str_equal);
5433
if (tree_pixbuf_hash == NULL)
5434
tree_pixbuf_hash = g_hash_table_new (g_str_hash, g_str_equal);
5435
if (icon_theme == NULL)
5436
icon_theme = gtk_icon_theme_get_default ();
5438
/* Create the settings objects */
5440
window->priv->settings_listing = g_settings_new (FILE_ROLLER_SCHEMA_LISTING);
5441
window->priv->settings_ui = g_settings_new (FILE_ROLLER_SCHEMA_UI);
5442
window->priv->settings_general = g_settings_new (FILE_ROLLER_SCHEMA_GENERAL);
5443
window->priv->settings_dialogs = g_settings_new (FILE_ROLLER_SCHEMA_DIALOGS);
5444
window->priv->settings_nautilus = g_settings_new (NAUTILUS_SCHEMA);
5446
/* Create the application. */
5448
window->priv->layout = gtk_table_new (4, 1, FALSE);
5449
gtk_container_add (GTK_CONTAINER (window), window->priv->layout);
5450
gtk_widget_show (window->priv->layout);
5452
gtk_window_set_title (GTK_WINDOW (window), _("Archive Manager"));
5453
gtk_window_set_has_resize_grip (GTK_WINDOW (window), TRUE);
5455
g_signal_connect (G_OBJECT (window),
5457
G_CALLBACK (fr_window_delete_event_cb),
5460
g_signal_connect (G_OBJECT (window),
5462
G_CALLBACK (fr_window_show_cb),
5465
window->priv->theme_changed_handler_id =
5466
g_signal_connect (icon_theme,
5468
G_CALLBACK (theme_changed_cb),
5471
gtk_icon_size_lookup_for_settings (gtk_widget_get_settings (GTK_WIDGET (window)),
5472
FILE_LIST_ICON_SIZE,
5473
&icon_width, &icon_height);
5474
file_list_icon_size = MAX (icon_width, icon_height);
5476
gtk_icon_size_lookup_for_settings (gtk_widget_get_settings (GTK_WIDGET (window)),
5478
&icon_width, &icon_height);
5479
dir_tree_icon_size = MAX (icon_width, icon_height);
5481
gtk_window_set_default_size (GTK_WINDOW (window),
5482
g_settings_get_int (window->priv->settings_ui, PREF_UI_WINDOW_WIDTH),
5483
g_settings_get_int (window->priv->settings_ui, PREF_UI_WINDOW_HEIGHT));
5485
gtk_drag_dest_set (GTK_WIDGET (window),
5486
GTK_DEST_DEFAULT_ALL,
5487
target_table, G_N_ELEMENTS (target_table),
5490
g_signal_connect (G_OBJECT (window),
5491
"drag_data_received",
5492
G_CALLBACK (fr_window_drag_data_received),
5494
g_signal_connect (G_OBJECT (window),
5496
G_CALLBACK (fr_window_drag_motion),
5499
g_signal_connect (G_OBJECT (window),
5501
G_CALLBACK (key_press_cb),
5504
/* Initialize Data. */
5506
window->archive = fr_archive_new ();
5507
g_signal_connect (G_OBJECT (window->archive),
5509
G_CALLBACK (action_started),
5511
g_signal_connect (G_OBJECT (window->archive),
5513
G_CALLBACK (action_performed),
5515
g_signal_connect (G_OBJECT (window->archive),
5517
G_CALLBACK (fr_window_progress_cb),
5519
g_signal_connect (G_OBJECT (window->archive),
5521
G_CALLBACK (fr_window_message_cb),
5523
g_signal_connect (G_OBJECT (window->archive),
5525
G_CALLBACK (fr_window_stoppable_cb),
5527
g_signal_connect (G_OBJECT (window->archive),
5529
G_CALLBACK (fr_window_working_archive_cb),
5532
fr_archive_set_fake_load_func (window->archive,
5533
fr_window_fake_load,
5535
fr_archive_set_add_is_stoppable_func (window->archive,
5536
fr_window_add_is_stoppable,
5539
window->priv->sort_method = g_settings_get_enum (window->priv->settings_listing, PREF_LISTING_SORT_METHOD);
5540
window->priv->sort_type = g_settings_get_enum (window->priv->settings_listing, PREF_LISTING_SORT_TYPE);
5542
window->priv->list_mode = window->priv->last_list_mode = g_settings_get_enum (window->priv->settings_listing, PREF_LISTING_LIST_MODE);
5543
g_settings_set_boolean (window->priv->settings_listing, PREF_LISTING_SHOW_PATH, (window->priv->list_mode == FR_WINDOW_LIST_MODE_FLAT));
5545
window->priv->history = NULL;
5546
window->priv->history_current = NULL;
5548
window->priv->action = FR_ACTION_NONE;
5550
window->priv->open_default_dir = g_strdup (get_home_uri ());
5551
window->priv->add_default_dir = g_strdup (get_home_uri ());
5552
window->priv->extract_default_dir = g_strdup (get_home_uri ());
5554
window->priv->give_focus_to_the_list = FALSE;
5556
window->priv->activity_ref = 0;
5557
window->priv->activity_timeout_handle = 0;
5559
window->priv->update_timeout_handle = 0;
5561
window->priv->archive_present = FALSE;
5562
window->priv->archive_new = FALSE;
5563
window->priv->archive_uri = NULL;
5565
window->priv->drag_destination_folder = NULL;
5566
window->priv->drag_base_dir = NULL;
5567
window->priv->drag_error = NULL;
5568
window->priv->drag_file_list = NULL;
5570
window->priv->batch_mode = FALSE;
5571
window->priv->batch_action_list = NULL;
5572
window->priv->batch_action = NULL;
5573
window->priv->extract_interact_use_default_dir = FALSE;
5574
window->priv->non_interactive = FALSE;
5576
window->priv->password = NULL;
5577
window->priv->compression = g_settings_get_enum (window->priv->settings_general, PREF_GENERAL_COMPRESSION_LEVEL);
5578
window->priv->encrypt_header = g_settings_get_boolean (window->priv->settings_general, PREF_GENERAL_ENCRYPT_HEADER);
5579
window->priv->volume_size = 0;
5581
window->priv->convert_data.converting = FALSE;
5582
window->priv->convert_data.temp_dir = NULL;
5583
window->priv->convert_data.new_archive = NULL;
5584
window->priv->convert_data.password = NULL;
5585
window->priv->convert_data.encrypt_header = FALSE;
5586
window->priv->convert_data.volume_size = 0;
5588
window->priv->stoppable = TRUE;
5590
window->priv->batch_adding_one_file = FALSE;
5592
window->priv->path_clicked = NULL;
5594
window->priv->current_view_length = 0;
5596
window->priv->current_batch_action.type = FR_BATCH_ACTION_NONE;
5597
window->priv->current_batch_action.data = NULL;
5598
window->priv->current_batch_action.free_func = NULL;
5600
window->priv->pd_last_archive = NULL;
5601
window->priv->pd_last_message = NULL;
5602
window->priv->pd_last_fraction = 0.0;
5604
/* Create the widgets. */
5608
window->priv->list_store = fr_list_model_new (NUMBER_OF_COLUMNS,
5617
g_object_set_data (G_OBJECT (window->priv->list_store), "FrWindow", window);
5618
window->priv->list_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (window->priv->list_store));
5620
gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (window->priv->list_view), TRUE);
5621
add_file_list_columns (window, GTK_TREE_VIEW (window->priv->list_view));
5622
gtk_tree_view_set_enable_search (GTK_TREE_VIEW (window->priv->list_view),
5624
gtk_tree_view_set_search_column (GTK_TREE_VIEW (window->priv->list_view),
5627
gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (window->priv->list_store),
5628
COLUMN_NAME, name_column_sort_func,
5630
gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (window->priv->list_store),
5631
COLUMN_SIZE, size_column_sort_func,
5633
gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (window->priv->list_store),
5634
COLUMN_TYPE, type_column_sort_func,
5636
gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (window->priv->list_store),
5637
COLUMN_TIME, time_column_sort_func,
5639
gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (window->priv->list_store),
5640
COLUMN_PATH, path_column_sort_func,
5643
gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (window->priv->list_store),
5644
no_sort_column_sort_func,
5647
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (window->priv->list_view));
5648
gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE);
5650
g_signal_connect (selection,
5652
G_CALLBACK (selection_changed_cb),
5654
g_signal_connect (G_OBJECT (window->priv->list_view),
5656
G_CALLBACK (row_activated_cb),
5659
g_signal_connect (G_OBJECT (window->priv->list_view),
5660
"button_press_event",
5661
G_CALLBACK (file_button_press_cb),
5663
g_signal_connect (G_OBJECT (window->priv->list_view),
5664
"button_release_event",
5665
G_CALLBACK (file_button_release_cb),
5667
g_signal_connect (G_OBJECT (window->priv->list_view),
5668
"motion_notify_event",
5669
G_CALLBACK (file_motion_notify_callback),
5671
g_signal_connect (G_OBJECT (window->priv->list_view),
5672
"leave_notify_event",
5673
G_CALLBACK (file_leave_notify_callback),
5676
g_signal_connect (G_OBJECT (window->priv->list_store),
5677
"sort_column_changed",
5678
G_CALLBACK (sort_column_changed_cb),
5681
g_signal_connect (G_OBJECT (window->priv->list_view),
5683
G_CALLBACK (file_list_drag_begin),
5685
g_signal_connect (G_OBJECT (window->priv->list_view),
5687
G_CALLBACK (file_list_drag_end),
5689
egg_tree_multi_drag_add_drag_support (GTK_TREE_VIEW (window->priv->list_view));
5691
list_scrolled_window = gtk_scrolled_window_new (NULL, NULL);
5692
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (list_scrolled_window),
5693
GTK_POLICY_AUTOMATIC,
5694
GTK_POLICY_AUTOMATIC);
5695
gtk_container_add (GTK_CONTAINER (list_scrolled_window), window->priv->list_view);
5699
window->priv->filter_bar = filter_box = gtk_hbox_new (FALSE, 6);
5700
gtk_container_set_border_width (GTK_CONTAINER (filter_box), 3);
5701
fr_window_attach (FR_WINDOW (window), window->priv->filter_bar, FR_WINDOW_AREA_FILTERBAR);
5703
gtk_box_pack_start (GTK_BOX (filter_box),
5704
gtk_label_new (_("Find:")), FALSE, FALSE, 0);
5706
/* * filter entry */
5708
window->priv->filter_entry = GTK_WIDGET (gtk_entry_new ());
5709
gtk_entry_set_icon_from_stock (GTK_ENTRY (window->priv->filter_entry),
5710
GTK_ENTRY_ICON_SECONDARY,
5713
gtk_widget_set_size_request (window->priv->filter_entry, 300, -1);
5714
gtk_box_pack_start (GTK_BOX (filter_box),
5715
window->priv->filter_entry, FALSE, FALSE, 6);
5717
g_signal_connect (G_OBJECT (window->priv->filter_entry),
5719
G_CALLBACK (filter_entry_activate_cb),
5721
g_signal_connect (G_OBJECT (window->priv->filter_entry),
5723
G_CALLBACK (filter_entry_icon_release_cb),
5726
gtk_widget_show_all (filter_box);
5730
window->priv->tree_store = gtk_tree_store_new (TREE_NUMBER_OF_COLUMNS,
5735
window->priv->tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (window->priv->tree_store));
5736
gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (window->priv->tree_view), FALSE);
5737
add_dir_tree_columns (window, GTK_TREE_VIEW (window->priv->tree_view));
5739
g_signal_connect (G_OBJECT (window->priv->tree_view),
5740
"button_press_event",
5741
G_CALLBACK (dir_tree_button_press_cb),
5744
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (window->priv->tree_view));
5745
g_signal_connect (selection,
5747
G_CALLBACK (dir_tree_selection_changed_cb),
5750
g_signal_connect (G_OBJECT (window->priv->tree_view),
5752
G_CALLBACK (file_list_drag_begin),
5754
g_signal_connect (G_OBJECT (window->priv->tree_view),
5756
G_CALLBACK (file_list_drag_end),
5758
g_signal_connect (G_OBJECT (window->priv->tree_view),
5760
G_CALLBACK (fr_window_folder_tree_drag_data_get),
5762
gtk_drag_source_set (window->priv->tree_view,
5764
folder_tree_targets, G_N_ELEMENTS (folder_tree_targets),
5767
tree_scrolled_window = gtk_scrolled_window_new (NULL, NULL);
5768
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (tree_scrolled_window),
5769
GTK_POLICY_AUTOMATIC,
5770
GTK_POLICY_AUTOMATIC);
5771
gtk_container_add (GTK_CONTAINER (tree_scrolled_window), window->priv->tree_view);
5775
window->priv->sidepane = gtk_vbox_new (FALSE, 0);
5777
sidepane_title = gtk_frame_new (NULL);
5778
gtk_frame_set_shadow_type (GTK_FRAME (sidepane_title), GTK_SHADOW_ETCHED_IN);
5780
sidepane_title_box = gtk_hbox_new (FALSE, 0);
5781
gtk_container_set_border_width (GTK_CONTAINER (sidepane_title_box), 2);
5782
gtk_container_add (GTK_CONTAINER (sidepane_title), sidepane_title_box);
5783
sidepane_title_label = gtk_label_new (_("Folders"));
5785
gtk_misc_set_alignment (GTK_MISC (sidepane_title_label), 0.0, 0.5);
5786
gtk_box_pack_start (GTK_BOX (sidepane_title_box), sidepane_title_label, TRUE, TRUE, 0);
5788
close_sidepane_button = gtk_button_new ();
5789
gtk_container_add (GTK_CONTAINER (close_sidepane_button), gtk_image_new_from_stock (GTK_STOCK_CLOSE, GTK_ICON_SIZE_MENU));
5790
gtk_button_set_relief (GTK_BUTTON (close_sidepane_button), GTK_RELIEF_NONE);
5791
gtk_widget_set_tooltip_text (close_sidepane_button, _("Close the folders pane"));
5792
g_signal_connect (close_sidepane_button,
5794
G_CALLBACK (close_sidepane_button_clicked_cb),
5796
gtk_box_pack_end (GTK_BOX (sidepane_title_box), close_sidepane_button, FALSE, FALSE, 0);
5798
gtk_box_pack_start (GTK_BOX (window->priv->sidepane), sidepane_title, FALSE, FALSE, 0);
5799
gtk_box_pack_start (GTK_BOX (window->priv->sidepane), tree_scrolled_window, TRUE, TRUE, 0);
5803
window->priv->paned = gtk_paned_new (GTK_ORIENTATION_HORIZONTAL);
5804
gtk_paned_pack1 (GTK_PANED (window->priv->paned), window->priv->sidepane, FALSE, TRUE);
5805
gtk_paned_pack2 (GTK_PANED (window->priv->paned), list_scrolled_window, TRUE, TRUE);
5806
gtk_paned_set_position (GTK_PANED (window->priv->paned), g_settings_get_int (window->priv->settings_ui, PREF_UI_SIDEBAR_WIDTH));
5808
fr_window_attach (FR_WINDOW (window), window->priv->paned, FR_WINDOW_AREA_CONTENTS);
5809
gtk_widget_show_all (window->priv->paned);
5811
/* Build the menu and the toolbar. */
5813
ui = gtk_ui_manager_new ();
5815
window->priv->actions = actions = gtk_action_group_new ("Actions");
5816
gtk_action_group_set_translation_domain (actions, NULL);
5817
gtk_action_group_add_actions (actions,
5821
gtk_action_group_add_toggle_actions (actions,
5822
action_toggle_entries,
5823
n_action_toggle_entries,
5825
gtk_action_group_add_radio_actions (actions,
5828
window->priv->list_mode,
5829
G_CALLBACK (view_as_radio_action),
5831
gtk_action_group_add_radio_actions (actions,
5834
window->priv->sort_type,
5835
G_CALLBACK (sort_by_radio_action),
5838
g_signal_connect (ui, "connect_proxy",
5839
G_CALLBACK (connect_proxy_cb), window);
5840
g_signal_connect (ui, "disconnect_proxy",
5841
G_CALLBACK (disconnect_proxy_cb), window);
5843
gtk_ui_manager_insert_action_group (ui, actions, 0);
5844
gtk_window_add_accel_group (GTK_WINDOW (window),
5845
gtk_ui_manager_get_accel_group (ui));
5847
/* Add a hidden short cut Ctrl-Q for power users */
5848
gtk_accel_group_connect (gtk_ui_manager_get_accel_group (ui),
5849
GDK_KEY_q, GDK_CONTROL_MASK, 0,
5850
g_cclosure_new_swap (G_CALLBACK (fr_window_close), window, NULL));
5853
if (!gtk_ui_manager_add_ui_from_string (ui, ui_info, -1, &error)) {
5854
g_message ("building menus failed: %s", error->message);
5855
g_error_free (error);
5858
menubar = gtk_ui_manager_get_widget (ui, "/MenuBar");
5859
fr_window_attach (FR_WINDOW (window), menubar, FR_WINDOW_AREA_MENUBAR);
5860
gtk_widget_show (menubar);
5862
window->priv->toolbar = toolbar = gtk_ui_manager_get_widget (ui, "/ToolBar");
5863
gtk_toolbar_set_show_arrow (GTK_TOOLBAR (toolbar), TRUE);
5864
gtk_style_context_add_class (gtk_widget_get_style_context (toolbar), GTK_STYLE_CLASS_PRIMARY_TOOLBAR);
5865
set_action_important (ui, "/ToolBar/Extract_Toolbar");
5869
window->priv->location_bar = gtk_ui_manager_get_widget (ui, "/LocationBar");
5870
gtk_toolbar_set_show_arrow (GTK_TOOLBAR (window->priv->location_bar), FALSE);
5871
gtk_toolbar_set_style (GTK_TOOLBAR (window->priv->location_bar), GTK_TOOLBAR_BOTH_HORIZ);
5872
gtk_style_context_add_class (gtk_widget_get_style_context (window->priv->location_bar), GTK_STYLE_CLASS_TOOLBAR);
5873
set_action_important (ui, "/LocationBar/GoBack");
5875
/* current location */
5877
location_box = gtk_hbox_new (FALSE, 6);
5878
/* Translators: after the colon there is a folder name. */
5879
window->priv->location_label = gtk_label_new_with_mnemonic (_("_Location:"));
5880
gtk_box_pack_start (GTK_BOX (location_box),
5881
window->priv->location_label, FALSE, FALSE, 5);
5883
window->priv->location_entry = gtk_entry_new ();
5884
gtk_entry_set_icon_from_stock (GTK_ENTRY (window->priv->location_entry),
5885
GTK_ENTRY_ICON_PRIMARY,
5886
GTK_STOCK_DIRECTORY);
5888
gtk_box_pack_start (GTK_BOX (location_box),
5889
window->priv->location_entry, TRUE, TRUE, 5);
5891
g_signal_connect (G_OBJECT (window->priv->location_entry),
5893
G_CALLBACK (location_entry_key_press_event_cb),
5897
GtkToolItem *tool_item;
5899
tool_item = gtk_separator_tool_item_new ();
5900
gtk_widget_show_all (GTK_WIDGET (tool_item));
5901
gtk_toolbar_insert (GTK_TOOLBAR (window->priv->location_bar), tool_item, -1);
5903
tool_item = gtk_tool_item_new ();
5904
gtk_tool_item_set_expand (tool_item, TRUE);
5905
gtk_container_add (GTK_CONTAINER (tool_item), location_box);
5906
gtk_widget_show_all (GTK_WIDGET (tool_item));
5907
gtk_toolbar_insert (GTK_TOOLBAR (window->priv->location_bar), tool_item, -1);
5910
fr_window_attach (FR_WINDOW (window), window->priv->location_bar, FR_WINDOW_AREA_LOCATIONBAR);
5911
if (window->priv->list_mode == FR_WINDOW_LIST_MODE_FLAT)
5912
gtk_widget_hide (window->priv->location_bar);
5914
gtk_widget_show (window->priv->location_bar);
5916
/* Recent manager */
5918
window->priv->recent_manager = gtk_recent_manager_get_default ();
5920
window->priv->recent_chooser_menu = gtk_recent_chooser_menu_new_for_manager (window->priv->recent_manager);
5921
gtk_recent_chooser_set_sort_type (GTK_RECENT_CHOOSER (window->priv->recent_chooser_menu), GTK_RECENT_SORT_MRU);
5922
fr_window_init_recent_chooser (window, GTK_RECENT_CHOOSER (window->priv->recent_chooser_menu));
5923
menu_item = gtk_ui_manager_get_widget (ui, "/MenuBar/Archive/OpenRecentMenu");
5924
gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item), window->priv->recent_chooser_menu);
5926
window->priv->recent_chooser_toolbar = gtk_recent_chooser_menu_new_for_manager (window->priv->recent_manager);
5927
fr_window_init_recent_chooser (window, GTK_RECENT_CHOOSER (window->priv->recent_chooser_toolbar));
5929
/* Add the recent menu tool item */
5931
open_recent_tool_item = gtk_menu_tool_button_new_from_stock (GTK_STOCK_OPEN);
5932
gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (open_recent_tool_item), window->priv->recent_chooser_toolbar);
5933
gtk_tool_item_set_homogeneous (open_recent_tool_item, FALSE);
5934
gtk_widget_set_tooltip_text (GTK_WIDGET (open_recent_tool_item), _("Open archive"));
5935
gtk_menu_tool_button_set_arrow_tooltip_text (GTK_MENU_TOOL_BUTTON (open_recent_tool_item), _("Open a recently used archive"));
5937
window->priv->open_action = gtk_action_new ("Toolbar_Open", _("Open"), _("Open archive"), GTK_STOCK_OPEN);
5938
g_object_set (window->priv->open_action, "is_important", TRUE, NULL);
5939
g_signal_connect (window->priv->open_action,
5941
G_CALLBACK (activate_action_open),
5943
gtk_activatable_set_related_action (GTK_ACTIVATABLE (open_recent_tool_item), window->priv->open_action);
5945
gtk_widget_show (GTK_WIDGET (open_recent_tool_item));
5946
gtk_toolbar_insert (GTK_TOOLBAR (toolbar), open_recent_tool_item, 1);
5950
fr_window_attach (FR_WINDOW (window), window->priv->toolbar, FR_WINDOW_AREA_TOOLBAR);
5951
if (g_settings_get_boolean (window->priv->settings_ui, PREF_UI_VIEW_TOOLBAR))
5952
gtk_widget_show (toolbar);
5954
gtk_widget_hide (toolbar);
5956
window->priv->file_popup_menu = gtk_ui_manager_get_widget (ui, "/FilePopupMenu");
5957
window->priv->folder_popup_menu = gtk_ui_manager_get_widget (ui, "/FolderPopupMenu");
5958
window->priv->sidebar_folder_popup_menu = gtk_ui_manager_get_widget (ui, "/SidebarFolderPopupMenu");
5960
/* Create the statusbar. */
5962
window->priv->statusbar = gtk_statusbar_new ();
5963
window->priv->help_message_cid = gtk_statusbar_get_context_id (GTK_STATUSBAR (window->priv->statusbar), "help_message");
5964
window->priv->list_info_cid = gtk_statusbar_get_context_id (GTK_STATUSBAR (window->priv->statusbar), "list_info");
5965
window->priv->progress_cid = gtk_statusbar_get_context_id (GTK_STATUSBAR (window->priv->statusbar), "progress");
5967
statusbar = GTK_STATUSBAR (window->priv->statusbar);
5968
#if GTK_CHECK_VERSION (2, 19, 1)
5969
statusbar_box = gtk_statusbar_get_message_area (statusbar);
5970
gtk_box_set_homogeneous (GTK_BOX (statusbar_box), FALSE);
5971
gtk_box_set_spacing (GTK_BOX (statusbar_box), 4);
5972
gtk_box_set_child_packing (GTK_BOX (statusbar_box), gtk_statusbar_get_message_area (statusbar), TRUE, TRUE, 0, GTK_PACK_START );
5974
statusbar_box = gtk_hbox_new (FALSE, 4);
5975
g_object_ref (statusbar->label);
5976
gtk_container_remove (GTK_CONTAINER (statusbar->frame), statusbar->label);
5977
gtk_box_pack_start (GTK_BOX (statusbar_box), statusbar->label, TRUE, TRUE, 0);
5978
g_object_unref (statusbar->label);
5979
gtk_container_add (GTK_CONTAINER (statusbar->frame), statusbar_box);
5982
window->priv->progress_bar = gtk_progress_bar_new ();
5983
gtk_progress_bar_set_pulse_step (GTK_PROGRESS_BAR (window->priv->progress_bar), ACTIVITY_PULSE_STEP);
5984
gtk_widget_set_size_request (window->priv->progress_bar, -1, PROGRESS_BAR_HEIGHT);
5988
vbox = gtk_vbox_new (FALSE, 0);
5989
gtk_box_pack_start (GTK_BOX (statusbar_box), vbox, FALSE, FALSE, 0);
5990
gtk_box_pack_start (GTK_BOX (vbox), window->priv->progress_bar, TRUE, TRUE, 1);
5991
gtk_widget_show (vbox);
5993
gtk_widget_show (statusbar_box);
5995
fr_window_attach (FR_WINDOW (window), window->priv->statusbar, FR_WINDOW_AREA_STATUSBAR);
5996
if (g_settings_get_boolean (window->priv->settings_ui, PREF_UI_VIEW_STATUSBAR))
5997
gtk_widget_show (window->priv->statusbar);
5999
gtk_widget_hide (window->priv->statusbar);
6003
fr_window_update_title (window);
6004
fr_window_update_sensitivity (window);
6005
fr_window_update_file_list (window, FALSE);
6006
fr_window_update_dir_tree (window);
6007
fr_window_update_current_location (window);
6008
fr_window_update_columns_visibility (window);
6010
/* Add notification callbacks. */
6012
g_signal_connect (window->priv->settings_ui,
6013
"changed::" PREF_UI_HISTORY_LEN,
6014
G_CALLBACK (pref_history_len_changed),
6016
g_signal_connect (window->priv->settings_ui,
6017
"changed::" PREF_UI_VIEW_TOOLBAR,
6018
G_CALLBACK (pref_view_toolbar_changed),
6020
g_signal_connect (window->priv->settings_ui,
6021
"changed::" PREF_UI_VIEW_STATUSBAR,
6022
G_CALLBACK (pref_view_statusbar_changed),
6024
g_signal_connect (window->priv->settings_ui,
6025
"changed::" PREF_UI_VIEW_FOLDERS,
6026
G_CALLBACK (pref_view_folders_changed),
6028
g_signal_connect (window->priv->settings_listing,
6029
"changed::" PREF_LISTING_SHOW_TYPE,
6030
G_CALLBACK (pref_show_field_changed),
6032
g_signal_connect (window->priv->settings_listing,
6033
"changed::" PREF_LISTING_SHOW_SIZE,
6034
G_CALLBACK (pref_show_field_changed),
6036
g_signal_connect (window->priv->settings_listing,
6037
"changed::" PREF_LISTING_SHOW_TIME,
6038
G_CALLBACK (pref_show_field_changed),
6040
g_signal_connect (window->priv->settings_listing,
6041
"changed::" PREF_LISTING_SHOW_PATH,
6042
G_CALLBACK (pref_show_field_changed),
6044
g_signal_connect (window->priv->settings_listing,
6045
"changed::" PREF_LISTING_USE_MIME_ICONS,
6046
G_CALLBACK (pref_use_mime_icons_changed),
6048
g_signal_connect (window->priv->settings_nautilus,
6049
"changed::" NAUTILUS_CLICK_POLICY,
6050
G_CALLBACK (pref_click_policy_changed),
6053
/* Give focus to the list. */
6055
gtk_widget_grab_focus (window->priv->list_view);
6060
fr_window_new (void)
6064
window = g_object_new (FR_TYPE_WINDOW, NULL);
6065
fr_window_construct ((FrWindow*) window);
6072
fr_window_set_archive_uri (FrWindow *window,
6075
if (window->priv->archive_uri != NULL)
6076
g_free (window->priv->archive_uri);
6077
window->priv->archive_uri = g_strdup (uri);
6082
fr_window_archive_new (FrWindow *window,
6085
g_return_val_if_fail (window != NULL, FALSE);
6087
if (! fr_archive_create (window->archive, uri)) {
6088
GtkWindow *file_sel = g_object_get_data (G_OBJECT (window), "fr_file_sel");
6090
window->priv->load_error_parent_window = file_sel;
6091
fr_archive_action_completed (window->archive,
6092
FR_ACTION_CREATING_NEW_ARCHIVE,
6093
FR_PROC_ERROR_GENERIC,
6094
_("Archive type not supported."));
6099
fr_window_set_archive_uri (window, uri);
6100
window->priv->archive_present = TRUE;
6101
window->priv->archive_new = TRUE;
6103
fr_archive_action_completed (window->archive,
6104
FR_ACTION_CREATING_NEW_ARCHIVE,
6113
fr_window_archive_open (FrWindow *current_window,
6117
FrWindow *window = current_window;
6119
if (current_window->priv->archive_present)
6120
window = (FrWindow *) fr_window_new ();
6122
g_return_val_if_fail (window != NULL, FALSE);
6124
fr_window_archive_close (window);
6126
fr_window_set_archive_uri (window, uri);
6127
window->priv->archive_present = FALSE;
6128
window->priv->give_focus_to_the_list = TRUE;
6129
window->priv->load_error_parent_window = parent;
6131
fr_window_set_current_batch_action (window,
6132
FR_BATCH_ACTION_LOAD,
6133
g_strdup (window->priv->archive_uri),
6134
(GFreeFunc) g_free);
6136
fr_archive_load (window->archive, window->priv->archive_uri, window->priv->password);
6143
fr_window_archive_close (FrWindow *window)
6145
g_return_if_fail (window != NULL);
6147
if (! window->priv->archive_new && ! window->priv->archive_present)
6150
fr_window_free_open_files (window);
6151
fr_clipboard_data_unref (window->priv->copy_data);
6152
window->priv->copy_data = NULL;
6154
fr_window_set_password (window, NULL);
6155
fr_window_set_volume_size(window, 0);
6156
fr_window_history_clear (window);
6158
window->priv->archive_new = FALSE;
6159
window->priv->archive_present = FALSE;
6161
fr_window_update_title (window);
6162
fr_window_update_sensitivity (window);
6163
fr_window_update_file_list (window, FALSE);
6164
fr_window_update_dir_tree (window);
6165
fr_window_update_current_location (window);
6166
fr_window_update_statusbar_list_info (window);
6171
fr_window_get_archive_uri (FrWindow *window)
6173
g_return_val_if_fail (window != NULL, NULL);
6175
return window->priv->archive_uri;
6180
fr_window_get_paste_archive_uri (FrWindow *window)
6182
g_return_val_if_fail (window != NULL, NULL);
6184
if (window->priv->clipboard_data != NULL)
6185
return window->priv->clipboard_data->archive_filename;
6192
fr_window_archive_is_present (FrWindow *window)
6194
g_return_val_if_fail (window != NULL, FALSE);
6196
return window->priv->archive_present;
6203
gboolean encrypt_header;
6209
save_as_data_new (const char *uri,
6210
const char *password,
6211
gboolean encrypt_header,
6216
sdata = g_new0 (SaveAsData, 1);
6218
sdata->uri = g_strdup (uri);
6219
if (password != NULL)
6220
sdata->password = g_strdup (password);
6221
sdata->encrypt_header = encrypt_header;
6222
sdata->volume_size = volume_size;
6229
save_as_data_free (SaveAsData *sdata)
6233
g_free (sdata->uri);
6234
g_free (sdata->password);
6240
fr_window_archive_save_as (FrWindow *window,
6242
const char *password,
6243
gboolean encrypt_header,
6246
g_return_if_fail (window != NULL);
6247
g_return_if_fail (uri != NULL);
6248
g_return_if_fail (window->archive != NULL);
6250
fr_window_convert_data_free (window, TRUE);
6251
window->priv->convert_data.new_file = g_strdup (uri);
6253
/* create the new archive */
6255
window->priv->convert_data.new_archive = fr_archive_new ();
6256
if (! fr_archive_create (window->priv->convert_data.new_archive, uri)) {
6261
utf8_name = g_uri_display_basename (uri);
6262
message = g_strdup_printf (_("Could not save the archive \"%s\""), utf8_name);
6265
d = _gtk_error_dialog_new (GTK_WINDOW (window),
6266
GTK_DIALOG_DESTROY_WITH_PARENT,
6270
_("Archive type not supported."));
6271
gtk_dialog_run (GTK_DIALOG (d));
6272
gtk_widget_destroy (d);
6276
g_object_unref (window->priv->convert_data.new_archive);
6277
window->priv->convert_data.new_archive = NULL;
6282
g_return_if_fail (window->priv->convert_data.new_archive->command != NULL);
6284
if (password != NULL) {
6285
window->priv->convert_data.password = g_strdup (password);
6286
window->priv->convert_data.encrypt_header = encrypt_header;
6289
window->priv->convert_data.encrypt_header = FALSE;
6290
window->priv->convert_data.volume_size = volume_size;
6292
fr_window_set_current_batch_action (window,
6293
FR_BATCH_ACTION_SAVE_AS,
6294
save_as_data_new (uri, password, encrypt_header, volume_size),
6295
(GFreeFunc) save_as_data_free);
6297
g_signal_connect (G_OBJECT (window->priv->convert_data.new_archive),
6299
G_CALLBACK (action_started),
6301
g_signal_connect (G_OBJECT (window->priv->convert_data.new_archive),
6303
G_CALLBACK (convert__action_performed),
6305
g_signal_connect (G_OBJECT (window->priv->convert_data.new_archive),
6307
G_CALLBACK (fr_window_progress_cb),
6309
g_signal_connect (G_OBJECT (window->priv->convert_data.new_archive),
6311
G_CALLBACK (fr_window_message_cb),
6313
g_signal_connect (G_OBJECT (window->priv->convert_data.new_archive),
6315
G_CALLBACK (fr_window_stoppable_cb),
6318
window->priv->convert_data.converting = TRUE;
6319
window->priv->convert_data.temp_dir = get_temp_work_dir (NULL);
6321
fr_process_clear (window->archive->process);
6322
fr_archive_extract_to_local (window->archive,
6324
window->priv->convert_data.temp_dir,
6329
window->priv->password);
6330
fr_process_start (window->archive->process);
6335
fr_window_archive_reload (FrWindow *window)
6337
g_return_if_fail (window != NULL);
6339
if (window->priv->activity_ref > 0)
6341
if (window->priv->archive_new)
6344
fr_archive_reload (window->archive, window->priv->password);
6349
fr_window_archive_rename (FrWindow *window,
6352
g_return_if_fail (window != NULL);
6354
if (window->priv->archive_new) {
6355
fr_window_archive_new (window, uri);
6359
fr_archive_rename (window->archive, uri);
6360
fr_window_set_archive_uri (window, uri);
6362
fr_window_update_title (window);
6363
fr_window_add_to_recent_list (window, window->priv->archive_uri);
6371
fr_window_archive_add_files (FrWindow *window,
6372
GList *file_list, /* GFile list */
6378
GList *files = NULL;
6382
base = g_file_get_parent ((GFile *) file_list->data);
6383
base_dir = g_file_get_path (base);
6385
if (strcmp (base_dir, "/") != 0)
6386
base_len = strlen (base_dir);
6388
for (scan = file_list; scan; scan = scan->next) {
6389
GFile *file = scan->data;
6393
path = g_file_get_path (file);
6394
rel_path = g_strdup (path + base_len + 1);
6395
files = g_list_prepend (files, rel_path);
6400
base_uri = g_file_get_uri (base);
6402
fr_archive_add_files (window->archive,
6405
fr_window_get_current_location (window),
6407
window->priv->password,
6408
window->priv->encrypt_header,
6409
window->priv->compression,
6410
window->priv->volume_size);
6413
path_list_free (files);
6415
g_object_unref (base);
6420
fr_window_archive_add_with_wildcard (FrWindow *window,
6421
const char *include_files,
6422
const char *exclude_files,
6423
const char *exclude_folders,
6424
const char *base_dir,
6425
const char *dest_dir,
6427
gboolean follow_links)
6429
fr_archive_add_with_wildcard (window->archive,
6434
(dest_dir == NULL)? fr_window_get_current_location (window): dest_dir,
6437
window->priv->password,
6438
window->priv->encrypt_header,
6439
window->priv->compression,
6440
window->priv->volume_size);
6445
fr_window_archive_add_directory (FrWindow *window,
6446
const char *directory,
6447
const char *base_dir,
6448
const char *dest_dir,
6451
fr_archive_add_directory (window->archive,
6454
(dest_dir == NULL)? fr_window_get_current_location (window): dest_dir,
6456
window->priv->password,
6457
window->priv->encrypt_header,
6458
window->priv->compression,
6459
window->priv->volume_size);
6464
fr_window_archive_add_items (FrWindow *window,
6466
const char *base_dir,
6467
const char *dest_dir,
6470
fr_archive_add_items (window->archive,
6473
(dest_dir == NULL)? fr_window_get_current_location (window): dest_dir,
6475
window->priv->password,
6476
window->priv->encrypt_header,
6477
window->priv->compression,
6478
window->priv->volume_size);
6483
fr_window_archive_add_dropped_items (FrWindow *window,
6487
fr_archive_add_dropped_items (window->archive,
6489
fr_window_get_current_location (window),
6490
fr_window_get_current_location (window),
6492
window->priv->password,
6493
window->priv->encrypt_header,
6494
window->priv->compression,
6495
window->priv->volume_size);
6500
fr_window_archive_remove (FrWindow *window,
6503
fr_window_clipboard_remove_file_list (window, file_list);
6505
fr_process_clear (window->archive->process);
6506
fr_archive_remove (window->archive, file_list, window->priv->compression);
6507
fr_process_start (window->archive->process);
6511
/* -- window_archive_extract -- */
6515
extract_data_new (GList *file_list,
6516
const char *extract_to_dir,
6517
const char *base_dir,
6518
gboolean skip_older,
6520
gboolean junk_paths,
6521
gboolean extract_here)
6525
edata = g_new0 (ExtractData, 1);
6526
edata->file_list = path_list_dup (file_list);
6527
if (extract_to_dir != NULL)
6528
edata->extract_to_dir = g_strdup (extract_to_dir);
6529
edata->skip_older = skip_older;
6530
edata->overwrite = overwrite;
6531
edata->junk_paths = junk_paths;
6532
if (base_dir != NULL)
6533
edata->base_dir = g_strdup (base_dir);
6534
edata->extract_here = extract_here;
6541
extract_to_data_new (const char *extract_to_dir)
6543
return extract_data_new (NULL,
6554
extract_data_free (ExtractData *edata)
6556
g_return_if_fail (edata != NULL);
6558
path_list_free (edata->file_list);
6559
g_free (edata->extract_to_dir);
6560
g_free (edata->base_dir);
6567
archive_is_encrypted (FrWindow *window,
6570
gboolean encrypted = FALSE;
6572
if (file_list == NULL) {
6575
for (i = 0; ! encrypted && i < window->archive->command->files->len; i++) {
6576
FileData *fdata = g_ptr_array_index (window->archive->command->files, i);
6578
if (fdata->encrypted)
6584
GHashTable *file_hash;
6588
file_hash = g_hash_table_new (g_str_hash, g_str_equal);
6589
for (i = 0; i < window->archive->command->files->len; i++) {
6590
FileData *fdata = g_ptr_array_index (window->archive->command->files, i);
6591
g_hash_table_insert (file_hash, fdata->original_path, fdata);
6594
for (scan = file_list; ! encrypted && scan; scan = scan->next) {
6595
char *filename = scan->data;
6598
fdata = g_hash_table_lookup (file_hash, filename);
6599
g_return_val_if_fail (fdata != NULL, FALSE);
6601
if (fdata->encrypted)
6605
g_hash_table_destroy (file_hash);
6613
fr_window_archive_extract_here (FrWindow *window,
6614
gboolean skip_older,
6616
gboolean junk_paths)
6620
edata = extract_data_new (NULL,
6627
fr_window_set_current_batch_action (window,
6628
FR_BATCH_ACTION_EXTRACT,
6630
(GFreeFunc) extract_data_free);
6632
if (archive_is_encrypted (window, NULL) && (window->priv->password == NULL)) {
6633
dlg_ask_password (window);
6637
window->priv->ask_to_open_destination_after_extraction = FALSE;
6639
fr_process_clear (window->archive->process);
6640
if (fr_archive_extract_here (window->archive,
6644
window->priv->password))
6646
fr_process_start (window->archive->process);
6652
fr_window_archive_extract (FrWindow *window,
6654
const char *extract_to_dir,
6655
const char *base_dir,
6656
gboolean skip_older,
6658
gboolean junk_paths,
6659
gboolean ask_to_open_destination)
6662
gboolean do_not_extract = FALSE;
6663
GError *error = NULL;
6665
edata = extract_data_new (file_list,
6673
fr_window_set_current_batch_action (window,
6674
FR_BATCH_ACTION_EXTRACT,
6676
(GFreeFunc) extract_data_free);
6678
if (archive_is_encrypted (window, edata->file_list) && (window->priv->password == NULL)) {
6679
dlg_ask_password (window);
6683
if (! uri_is_dir (edata->extract_to_dir)) {
6684
if (! ForceDirectoryCreation) {
6690
folder_name = g_filename_display_name (edata->extract_to_dir);
6691
msg = g_strdup_printf (_("Destination folder \"%s\" does not exist.\n\nDo you want to create it?"), folder_name);
6692
g_free (folder_name);
6694
d = _gtk_message_dialog_new (GTK_WINDOW (window),
6696
GTK_STOCK_DIALOG_QUESTION,
6699
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
6700
_("Create _Folder"), GTK_RESPONSE_YES,
6703
gtk_dialog_set_default_response (GTK_DIALOG (d), GTK_RESPONSE_YES);
6704
r = gtk_dialog_run (GTK_DIALOG (d));
6705
gtk_widget_destroy (GTK_WIDGET (d));
6709
if (r != GTK_RESPONSE_YES)
6710
do_not_extract = TRUE;
6713
if (! do_not_extract && ! ensure_dir_exists (edata->extract_to_dir, 0755, &error)) {
6717
details = g_strdup_printf (_("Could not create the destination folder: %s."), error->message);
6718
d = _gtk_error_dialog_new (GTK_WINDOW (window),
6721
_("Extraction not performed"),
6724
g_clear_error (&error);
6725
fr_window_show_error_dialog (window, d, GTK_WINDOW (window), details);
6726
fr_window_stop_batch (window);
6734
if (do_not_extract) {
6737
d = _gtk_message_dialog_new (GTK_WINDOW (window),
6739
GTK_STOCK_DIALOG_WARNING,
6740
_("Extraction not performed"),
6742
GTK_STOCK_OK, GTK_RESPONSE_OK,
6744
gtk_dialog_set_default_response (GTK_DIALOG (d), GTK_RESPONSE_OK);
6745
fr_window_show_error_dialog (window, d, GTK_WINDOW (window), _("Extraction not performed"));
6746
fr_window_stop_batch (window);
6751
window->priv->ask_to_open_destination_after_extraction = ask_to_open_destination;
6753
fr_process_clear (window->archive->process);
6754
fr_archive_extract (window->archive,
6756
edata->extract_to_dir,
6761
window->priv->password);
6762
fr_process_start (window->archive->process);
6767
fr_window_archive_test (FrWindow *window)
6769
fr_window_set_current_batch_action (window,
6770
FR_BATCH_ACTION_TEST,
6773
fr_archive_test (window->archive, window->priv->password);
6778
fr_window_set_password (FrWindow *window,
6779
const char *password)
6781
g_return_if_fail (window != NULL);
6783
if (window->priv->password != NULL) {
6784
g_free (window->priv->password);
6785
window->priv->password = NULL;
6788
if ((password != NULL) && (password[0] != '\0'))
6789
window->priv->password = g_strdup (password);
6793
fr_window_set_password_for_paste (FrWindow *window,
6794
const char *password)
6796
g_return_if_fail (window != NULL);
6798
if (window->priv->password_for_paste != NULL) {
6799
g_free (window->priv->password_for_paste);
6800
window->priv->password_for_paste = NULL;
6803
if ((password != NULL) && (password[0] != '\0'))
6804
window->priv->password_for_paste = g_strdup (password);
6808
fr_window_get_password (FrWindow *window)
6810
g_return_val_if_fail (window != NULL, NULL);
6812
return window->priv->password;
6817
fr_window_set_encrypt_header (FrWindow *window,
6818
gboolean encrypt_header)
6820
g_return_if_fail (window != NULL);
6822
window->priv->encrypt_header = encrypt_header;
6827
fr_window_get_encrypt_header (FrWindow *window)
6829
return window->priv->encrypt_header;
6834
fr_window_set_compression (FrWindow *window,
6835
FrCompression compression)
6837
g_return_if_fail (window != NULL);
6839
window->priv->compression = compression;
6844
fr_window_get_compression (FrWindow *window)
6846
return window->priv->compression;
6851
fr_window_set_volume_size (FrWindow *window,
6854
g_return_if_fail (window != NULL);
6856
window->priv->volume_size = volume_size;
6861
fr_window_get_volume_size (FrWindow *window)
6863
return window->priv->volume_size;
6868
fr_window_go_to_location (FrWindow *window,
6870
gboolean force_update)
6874
g_return_if_fail (window != NULL);
6875
g_return_if_fail (path != NULL);
6878
g_free (window->priv->last_location);
6879
window->priv->last_location = NULL;
6882
if (path[strlen (path) - 1] != '/')
6883
dir = g_strconcat (path, "/", NULL);
6885
dir = g_strdup (path);
6887
if ((window->priv->last_location == NULL) || (strcmp (window->priv->last_location, dir) != 0)) {
6888
g_free (window->priv->last_location);
6889
window->priv->last_location = dir;
6891
fr_window_history_add (window, dir);
6892
fr_window_update_file_list (window, TRUE);
6893
fr_window_update_current_location (window);
6901
fr_window_get_current_location (FrWindow *window)
6903
if (window->priv->history_current == NULL) {
6904
fr_window_history_add (window, "/");
6905
return window->priv->history_current->data;
6908
return (const char*) window->priv->history_current->data;
6913
fr_window_go_up_one_level (FrWindow *window)
6917
g_return_if_fail (window != NULL);
6919
parent_dir = get_parent_dir (fr_window_get_current_location (window));
6920
fr_window_go_to_location (window, parent_dir, FALSE);
6921
g_free (parent_dir);
6926
fr_window_go_back (FrWindow *window)
6928
g_return_if_fail (window != NULL);
6930
if (window->priv->history == NULL)
6932
if (window->priv->history_current == NULL)
6934
if (window->priv->history_current->next == NULL)
6936
window->priv->history_current = window->priv->history_current->next;
6938
fr_window_go_to_location (window, window->priv->history_current->data, FALSE);
6943
fr_window_go_forward (FrWindow *window)
6945
g_return_if_fail (window != NULL);
6947
if (window->priv->history == NULL)
6949
if (window->priv->history_current == NULL)
6951
if (window->priv->history_current->prev == NULL)
6953
window->priv->history_current = window->priv->history_current->prev;
6955
fr_window_go_to_location (window, window->priv->history_current->data, FALSE);
6960
fr_window_set_list_mode (FrWindow *window,
6961
FrWindowListMode list_mode)
6963
g_return_if_fail (window != NULL);
6965
window->priv->list_mode = window->priv->last_list_mode = list_mode;
6966
if (window->priv->list_mode == FR_WINDOW_LIST_MODE_FLAT) {
6967
fr_window_history_clear (window);
6968
fr_window_history_add (window, "/");
6971
g_settings_set_enum (window->priv->settings_listing, PREF_LISTING_LIST_MODE, window->priv->last_list_mode);
6972
g_settings_set_boolean (window->priv->settings_listing, PREF_LISTING_SHOW_PATH, (window->priv->list_mode == FR_WINDOW_LIST_MODE_FLAT));
6974
fr_window_update_file_list (window, TRUE);
6975
fr_window_update_dir_tree (window);
6976
fr_window_update_current_location (window);
6981
fr_window_get_list_store (FrWindow *window)
6983
return GTK_TREE_MODEL (window->priv->list_store);
6988
fr_window_find (FrWindow *window)
6990
window->priv->filter_mode = TRUE;
6991
gtk_widget_show (window->priv->filter_bar);
6992
gtk_widget_grab_focus (window->priv->filter_entry);
6997
fr_window_select_all (FrWindow *window)
6999
gtk_tree_selection_select_all (gtk_tree_view_get_selection (GTK_TREE_VIEW (window->priv->list_view)));
7004
fr_window_unselect_all (FrWindow *window)
7006
gtk_tree_selection_unselect_all (gtk_tree_view_get_selection (GTK_TREE_VIEW (window->priv->list_view)));
7011
fr_window_set_sort_type (FrWindow *window,
7012
GtkSortType sort_type)
7014
window->priv->sort_type = sort_type;
7015
fr_window_update_list_order (window);
7020
fr_window_stop (FrWindow *window)
7022
if (! window->priv->stoppable)
7025
if (window->priv->activity_ref > 0)
7026
fr_archive_stop (window->archive);
7028
if (window->priv->convert_data.converting)
7029
fr_window_convert_data_free (window, TRUE);
7033
/* -- start/stop activity mode -- */
7037
activity_cb (gpointer data)
7039
FrWindow *window = data;
7041
if ((window->priv->pd_progress_bar != NULL) && window->priv->progress_pulse)
7042
gtk_progress_bar_pulse (GTK_PROGRESS_BAR (window->priv->pd_progress_bar));
7043
if (window->priv->progress_pulse)
7044
gtk_progress_bar_pulse (GTK_PROGRESS_BAR (window->priv->progress_bar));
7051
fr_window_start_activity_mode (FrWindow *window)
7053
g_return_if_fail (window != NULL);
7055
if (window->priv->activity_ref++ > 0)
7058
window->priv->activity_timeout_handle = g_timeout_add (ACTIVITY_DELAY,
7061
fr_window_update_sensitivity (window);
7066
fr_window_stop_activity_mode (FrWindow *window)
7068
g_return_if_fail (window != NULL);
7070
if (window->priv->activity_ref == 0)
7073
window->priv->activity_ref--;
7075
if (window->priv->activity_ref > 0)
7078
if (window->priv->activity_timeout_handle == 0)
7081
g_source_remove (window->priv->activity_timeout_handle);
7082
window->priv->activity_timeout_handle = 0;
7084
if (! gtk_widget_get_realized (GTK_WIDGET (window)))
7087
if (window->priv->progress_dialog != NULL)
7088
gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (window->priv->pd_progress_bar), 0.0);
7090
if (! window->priv->batch_mode) {
7091
if (window->priv->progress_bar != NULL)
7092
gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (window->priv->progress_bar), 0.0);
7093
fr_window_update_sensitivity (window);
7099
last_output_window__unrealize_cb (GtkWidget *widget,
7102
pref_util_save_window_geometry (GTK_WINDOW (widget), LAST_OUTPUT_SCHEMA_NAME);
7108
fr_window_view_last_output (FrWindow *window,
7113
GtkWidget *text_view;
7114
GtkWidget *scrolled;
7115
GtkTextBuffer *text_buffer;
7120
title = _("Last Output");
7122
dialog = gtk_dialog_new_with_buttons (title,
7123
GTK_WINDOW (window),
7124
GTK_DIALOG_DESTROY_WITH_PARENT,
7125
GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
7127
gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_CLOSE);
7128
gtk_window_set_resizable (GTK_WINDOW (dialog), TRUE);
7129
gtk_widget_set_size_request (dialog, 500, 300);
7133
scrolled = gtk_scrolled_window_new (NULL, NULL);
7134
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled),
7135
GTK_POLICY_AUTOMATIC,
7136
GTK_POLICY_AUTOMATIC);
7137
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled),
7138
GTK_SHADOW_ETCHED_IN);
7140
text_buffer = gtk_text_buffer_new (NULL);
7141
gtk_text_buffer_create_tag (text_buffer, "monospace",
7142
"family", "monospace", NULL);
7144
text_view = gtk_text_view_new_with_buffer (text_buffer);
7145
g_object_unref (text_buffer);
7146
gtk_text_view_set_editable (GTK_TEXT_VIEW (text_view), FALSE);
7147
gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (text_view), FALSE);
7151
vbox = gtk_vbox_new (FALSE, 6);
7152
gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);
7154
gtk_container_add (GTK_CONTAINER (scrolled), text_view);
7155
gtk_box_pack_start (GTK_BOX (vbox), scrolled,
7158
gtk_widget_show_all (vbox);
7159
gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
7165
g_signal_connect (G_OBJECT (dialog),
7167
G_CALLBACK (gtk_widget_destroy),
7170
g_signal_connect (G_OBJECT (dialog),
7172
G_CALLBACK (last_output_window__unrealize_cb),
7177
gtk_text_buffer_get_iter_at_offset (text_buffer, &iter, 0);
7178
scan = window->archive->process->out.raw;
7179
for (; scan; scan = scan->next) {
7180
char *line = scan->data;
7182
gsize bytes_written;
7184
utf8_line = g_locale_to_utf8 (line, -1, NULL, &bytes_written, NULL);
7185
gtk_text_buffer_insert_with_tags_by_name (text_buffer,
7191
gtk_text_buffer_insert (text_buffer, &iter, "\n", 1);
7196
pref_util_restore_window_geometry (GTK_WINDOW (dialog), LAST_OUTPUT_SCHEMA_NAME);
7200
/* -- fr_window_rename_selection -- */
7204
char *path_to_rename;
7209
gboolean dir_in_archive;
7210
char *original_path;
7215
rename_data_new (const char *path_to_rename,
7216
const char *old_name,
7217
const char *new_name,
7218
const char *current_dir,
7220
gboolean dir_in_archive,
7221
const char *original_path)
7225
rdata = g_new0 (RenameData, 1);
7226
rdata->path_to_rename = g_strdup (path_to_rename);
7227
if (old_name != NULL)
7228
rdata->old_name = g_strdup (old_name);
7229
if (new_name != NULL)
7230
rdata->new_name = g_strdup (new_name);
7231
if (current_dir != NULL)
7232
rdata->current_dir = g_strdup (current_dir);
7233
rdata->is_dir = is_dir;
7234
rdata->dir_in_archive = dir_in_archive;
7235
if (original_path != NULL)
7236
rdata->original_path = g_strdup (original_path);
7243
rename_data_free (RenameData *rdata)
7245
g_return_if_fail (rdata != NULL);
7247
g_free (rdata->path_to_rename);
7248
g_free (rdata->old_name);
7249
g_free (rdata->new_name);
7250
g_free (rdata->current_dir);
7251
g_free (rdata->original_path);
7257
rename_selection (FrWindow *window,
7258
const char *path_to_rename,
7259
const char *old_name,
7260
const char *new_name,
7261
const char *current_dir,
7263
gboolean dir_in_archive,
7264
const char *original_path)
7266
FrArchive *archive = window->archive;
7272
GList *new_file_list;
7275
rdata = rename_data_new (path_to_rename,
7282
fr_window_set_current_batch_action (window,
7283
FR_BATCH_ACTION_RENAME,
7285
(GFreeFunc) rename_data_free);
7287
fr_process_clear (archive->process);
7289
tmp_dir = get_temp_work_dir (NULL);
7292
file_list = get_dir_list_from_path (window, rdata->path_to_rename);
7294
file_list = g_list_append (NULL, g_strdup (rdata->path_to_rename));
7296
fr_archive_extract_to_local (archive,
7303
window->priv->password);
7305
/* temporarily add the dir to rename to the list if it's stored in the
7306
* archive, this way it will be removed from the archive... */
7308
if (is_dir && dir_in_archive && ! g_list_find_custom (file_list, original_path, (GCompareFunc) strcmp)) {
7309
file_list = g_list_prepend (file_list, g_strdup (original_path));
7313
fr_archive_remove (archive, file_list, window->priv->compression);
7314
fr_window_clipboard_remove_file_list (window, file_list);
7316
/* ...and remove it from the list again */
7321
file_list = g_list_remove_link (file_list, tmp);
7327
/* rename the files. */
7329
new_dirname = g_build_filename (rdata->current_dir + 1, rdata->new_name, "/", NULL);
7330
new_file_list = NULL;
7331
if (rdata->is_dir) {
7335
old_path = g_build_filename (tmp_dir, rdata->current_dir, rdata->old_name, NULL);
7336
new_path = g_build_filename (tmp_dir, rdata->current_dir, rdata->new_name, NULL);
7338
fr_process_begin_command (archive->process, "mv");
7339
fr_process_add_arg (archive->process, "-f");
7340
fr_process_add_arg (archive->process, old_path);
7341
fr_process_add_arg (archive->process, new_path);
7342
fr_process_end_command (archive->process);
7348
for (scan = file_list; scan; scan = scan->next) {
7349
const char *current_dir_relative = rdata->current_dir + 1;
7350
const char *filename = (char*) scan->data;
7351
char *old_path = NULL, *common = NULL, *new_path = NULL;
7354
old_path = g_build_filename (tmp_dir, filename, NULL);
7356
if (strlen (filename) > (strlen (rdata->current_dir) + strlen (rdata->old_name)))
7357
common = g_strdup (filename + strlen (rdata->current_dir) + strlen (rdata->old_name));
7358
new_path = g_build_filename (tmp_dir, rdata->current_dir, rdata->new_name, common, NULL);
7360
if (! rdata->is_dir) {
7361
fr_process_begin_command (archive->process, "mv");
7362
fr_process_add_arg (archive->process, "-f");
7363
fr_process_add_arg (archive->process, old_path);
7364
fr_process_add_arg (archive->process, new_path);
7365
fr_process_end_command (archive->process);
7368
new_filename = g_build_filename (current_dir_relative, rdata->new_name, common, NULL);
7369
new_file_list = g_list_prepend (new_file_list, new_filename);
7375
new_file_list = g_list_reverse (new_file_list);
7377
/* FIXME: this is broken for tar archives.
7378
if (is_dir && dir_in_archive && ! g_list_find_custom (new_file_list, new_dirname, (GCompareFunc) strcmp))
7379
new_file_list = g_list_prepend (new_file_list, g_build_filename (rdata->current_dir + 1, rdata->new_name, NULL));
7382
fr_archive_add (archive,
7388
window->priv->password,
7389
window->priv->encrypt_header,
7390
window->priv->compression,
7391
window->priv->volume_size);
7393
g_free (new_dirname);
7394
path_list_free (new_file_list);
7395
path_list_free (file_list);
7397
/* remove the tmp dir */
7399
fr_process_begin_command (archive->process, "rm");
7400
fr_process_set_working_dir (archive->process, g_get_tmp_dir ());
7401
fr_process_set_sticky (archive->process, TRUE);
7402
fr_process_add_arg (archive->process, "-rf");
7403
fr_process_add_arg (archive->process, tmp_dir);
7404
fr_process_end_command (archive->process);
7406
fr_process_start (archive->process);
7413
valid_name (const char *new_name,
7414
const char *old_name,
7417
char *utf8_new_name;
7418
gboolean retval = TRUE;
7420
new_name = eat_spaces (new_name);
7421
utf8_new_name = g_filename_display_name (new_name);
7423
if (*new_name == '\0') {
7424
/* Translators: the name references to a filename. This message can appear when renaming a file. */
7425
*reason = g_strdup_printf ("%s\n\n%s", _("The new name is void."), _("Please use a different name."));
7428
else if (strcmp (new_name, old_name) == 0) {
7429
/* Translators: the name references to a filename. This message can appear when renaming a file. */
7430
*reason = g_strdup_printf ("%s\n\n%s", _("The new name is equal to the old one."), _("Please use a different name."));
7433
else if (strchrs (new_name, BAD_CHARS)) {
7434
/* Translators: the name references to a filename. This message can appear when renaming a file. */
7435
*reason = g_strdup_printf (_("The name \"%s\" is not valid because it cannot contain the characters: %s\n\n%s"), utf8_new_name, BAD_CHARS, _("Please use a different name."));
7439
g_free (utf8_new_name);
7446
name_is_present (FrWindow *window,
7447
const char *current_dir,
7448
const char *new_name,
7451
gboolean retval = FALSE;
7458
new_filename = g_build_filename (current_dir, new_name, NULL);
7459
new_filename_l = strlen (new_filename);
7461
for (i = 0; i < window->archive->command->files->len; i++) {
7462
FileData *fdata = g_ptr_array_index (window->archive->command->files, i);
7463
const char *filename = fdata->full_path;
7465
if ((strncmp (filename, new_filename, new_filename_l) == 0)
7466
&& ((filename[new_filename_l] == '\0')
7467
|| (filename[new_filename_l] == G_DIR_SEPARATOR))) {
7468
char *utf8_name = g_filename_display_name (new_name);
7470
if (filename[new_filename_l] == G_DIR_SEPARATOR)
7471
*reason = g_strdup_printf (_("A folder named \"%s\" already exists.\n\n%s"), utf8_name, _("Please use a different name."));
7473
*reason = g_strdup_printf (_("A file named \"%s\" already exists.\n\n%s"), utf8_name, _("Please use a different name."));
7480
g_free (new_filename);
7487
fr_window_rename_selection (FrWindow *window,
7488
gboolean from_sidebar)
7490
char *path_to_rename;
7493
gboolean renaming_dir = FALSE;
7494
gboolean dir_in_archive = FALSE;
7495
char *original_path = NULL;
7496
char *utf8_old_name;
7497
char *utf8_new_name;
7500
path_to_rename = fr_window_get_selected_folder_in_tree_view (window);
7501
if (path_to_rename == NULL)
7503
parent_dir = remove_level_from_path (path_to_rename);
7504
old_name = g_strdup (file_name_from_path (path_to_rename));
7505
renaming_dir = TRUE;
7508
FileData *selected_item;
7510
selected_item = fr_window_get_selected_item_from_file_list (window);
7511
if (selected_item == NULL)
7514
renaming_dir = file_data_is_dir (selected_item);
7515
dir_in_archive = selected_item->dir;
7516
original_path = g_strdup (selected_item->original_path);
7518
if (renaming_dir && ! dir_in_archive) {
7519
parent_dir = g_strdup (fr_window_get_current_location (window));
7520
old_name = g_strdup (selected_item->list_name);
7521
path_to_rename = g_build_filename (parent_dir, old_name, NULL);
7525
path_to_rename = remove_ending_separator (selected_item->full_path);
7526
parent_dir = remove_level_from_path (path_to_rename);
7529
path_to_rename = g_strdup (selected_item->original_path);
7530
parent_dir = remove_level_from_path (selected_item->full_path);
7532
old_name = g_strdup (selected_item->name);
7535
file_data_free (selected_item);
7538
retry__rename_selection:
7539
utf8_old_name = g_locale_to_utf8 (old_name, -1 ,0 ,0 ,0);
7540
utf8_new_name = _gtk_request_dialog_run (GTK_WINDOW (window),
7541
(GTK_DIALOG_DESTROY_WITH_PARENT
7542
| GTK_DIALOG_MODAL),
7544
(renaming_dir ? _("New folder name") : _("New file name")),
7549
g_free (utf8_old_name);
7551
if (utf8_new_name != NULL) {
7553
char *reason = NULL;
7555
new_name = g_filename_from_utf8 (utf8_new_name, -1, 0, 0, 0);
7556
g_free (utf8_new_name);
7558
if (! valid_name (new_name, old_name, &reason)) {
7559
char *utf8_name = g_filename_display_name (new_name);
7562
dlg = _gtk_error_dialog_new (GTK_WINDOW (window),
7563
GTK_DIALOG_DESTROY_WITH_PARENT,
7565
(renaming_dir ? _("Could not rename the folder") : _("Could not rename the file")),
7568
gtk_dialog_run (GTK_DIALOG (dlg));
7569
gtk_widget_destroy (dlg);
7575
goto retry__rename_selection;
7578
if (name_is_present (window, parent_dir, new_name, &reason)) {
7582
dlg = _gtk_message_dialog_new (GTK_WINDOW (window),
7584
GTK_STOCK_DIALOG_QUESTION,
7585
(renaming_dir ? _("Could not rename the folder") : _("Could not rename the file")),
7587
GTK_STOCK_CLOSE, GTK_RESPONSE_OK,
7589
r = gtk_dialog_run (GTK_DIALOG (dlg));
7590
gtk_widget_destroy (dlg);
7593
goto retry__rename_selection;
7596
rename_selection (window,
7609
g_free (parent_dir);
7610
g_free (path_to_rename);
7611
g_free (original_path);
7616
fr_clipboard_get (GtkClipboard *clipboard,
7617
GtkSelectionData *selection_data,
7619
gpointer user_data_or_owner)
7621
FrWindow *window = user_data_or_owner;
7624
if (gtk_selection_data_get_target (selection_data) != FR_SPECIAL_URI_LIST)
7627
data = get_selection_data_from_clipboard_data (window, window->priv->copy_data);
7628
gtk_selection_data_set (selection_data,
7629
gtk_selection_data_get_target (selection_data),
7638
fr_clipboard_clear (GtkClipboard *clipboard,
7639
gpointer user_data_or_owner)
7641
FrWindow *window = user_data_or_owner;
7643
if (window->priv->copy_data != NULL) {
7644
fr_clipboard_data_unref (window->priv->copy_data);
7645
window->priv->copy_data = NULL;
7651
fr_window_get_selection (FrWindow *window,
7652
gboolean from_sidebar,
7653
char **return_base_dir)
7659
char *selected_folder;
7660
char *parent_folder;
7662
files = fr_window_get_folder_tree_selection (window, TRUE, NULL);
7663
selected_folder = fr_window_get_selected_folder_in_tree_view (window);
7664
parent_folder = remove_level_from_path (selected_folder);
7665
if (parent_folder == NULL)
7666
base_dir = g_strdup ("/");
7667
else if (parent_folder[strlen (parent_folder) - 1] == '/')
7668
base_dir = g_strdup (parent_folder);
7670
base_dir = g_strconcat (parent_folder, "/", NULL);
7671
g_free (selected_folder);
7672
g_free (parent_folder);
7675
files = fr_window_get_file_list_selection (window, TRUE, NULL);
7676
base_dir = g_strdup (fr_window_get_current_location (window));
7679
if (return_base_dir)
7680
*return_base_dir = base_dir;
7689
fr_window_copy_or_cut_selection (FrWindow *window,
7691
gboolean from_sidebar)
7695
GtkClipboard *clipboard;
7697
files = fr_window_get_selection (window, from_sidebar, &base_dir);
7699
if (window->priv->copy_data != NULL)
7700
fr_clipboard_data_unref (window->priv->copy_data);
7701
window->priv->copy_data = fr_clipboard_data_new ();
7702
window->priv->copy_data->files = files;
7703
window->priv->copy_data->op = op;
7704
window->priv->copy_data->base_dir = base_dir;
7706
clipboard = gtk_clipboard_get (FR_CLIPBOARD);
7707
gtk_clipboard_set_with_owner (clipboard,
7709
G_N_ELEMENTS (clipboard_targets),
7714
fr_window_update_sensitivity (window);
7719
fr_window_copy_selection (FrWindow *window,
7720
gboolean from_sidebar)
7722
fr_window_copy_or_cut_selection (window, FR_CLIPBOARD_OP_COPY, from_sidebar);
7727
fr_window_cut_selection (FrWindow *window,
7728
gboolean from_sidebar)
7730
fr_window_copy_or_cut_selection (window, FR_CLIPBOARD_OP_CUT, from_sidebar);
7735
always_fake_load (FrArchive *archive,
7743
add_pasted_files (FrWindow *window,
7744
FrClipboardData *data)
7746
const char *current_dir_relative = data->current_dir + 1;
7748
GList *new_file_list = NULL;
7750
if (window->priv->password_for_paste != NULL) {
7751
g_free (window->priv->password_for_paste);
7752
window->priv->password_for_paste = NULL;
7755
fr_process_clear (window->archive->process);
7756
for (scan = data->files; scan; scan = scan->next) {
7757
const char *old_name = (char*) scan->data;
7758
char *new_name = g_build_filename (current_dir_relative, old_name + strlen (data->base_dir) - 1, NULL);
7762
if ((strcmp (old_name, new_name) != 0)
7763
&& (old_name[strlen (old_name) - 1] != '/'))
7765
fr_process_begin_command (window->archive->process, "mv");
7766
fr_process_set_working_dir (window->archive->process, data->tmp_dir);
7767
fr_process_add_arg (window->archive->process, "-f");
7768
fr_process_add_arg (window->archive->process, old_name);
7769
fr_process_add_arg (window->archive->process, new_name);
7770
fr_process_end_command (window->archive->process);
7773
new_file_list = g_list_prepend (new_file_list, new_name);
7776
fr_archive_add (window->archive,
7782
window->priv->password,
7783
window->priv->encrypt_header,
7784
window->priv->compression,
7785
window->priv->volume_size);
7787
path_list_free (new_file_list);
7789
/* remove the tmp dir */
7791
fr_process_begin_command (window->archive->process, "rm");
7792
fr_process_set_working_dir (window->archive->process, g_get_tmp_dir ());
7793
fr_process_set_sticky (window->archive->process, TRUE);
7794
fr_process_add_arg (window->archive->process, "-rf");
7795
fr_process_add_arg (window->archive->process, data->tmp_dir);
7796
fr_process_end_command (window->archive->process);
7798
fr_process_start (window->archive->process);
7803
copy_from_archive_action_performed_cb (FrArchive *archive,
7808
FrWindow *window = data;
7809
gboolean continue_batch = FALSE;
7812
debug (DEBUG_INFO, "%s [DONE] (FR::Window)\n", action_names[action]);
7815
fr_window_stop_activity_mode (window);
7816
fr_window_pop_message (window);
7817
close_progress_dialog (window, FALSE);
7819
if (error->type == FR_PROC_ERROR_ASK_PASSWORD) {
7820
dlg_ask_password_for_paste_operation (window);
7824
continue_batch = handle_errors (window, archive, action, error);
7826
if (error->type != FR_PROC_ERROR_NONE) {
7827
fr_clipboard_data_unref (window->priv->clipboard_data);
7828
window->priv->clipboard_data = NULL;
7833
case FR_ACTION_LISTING_CONTENT:
7834
fr_process_clear (window->priv->copy_from_archive->process);
7835
fr_archive_extract_to_local (window->priv->copy_from_archive,
7836
window->priv->clipboard_data->files,
7837
window->priv->clipboard_data->tmp_dir,
7842
window->priv->clipboard_data->archive_password);
7843
fr_process_start (window->priv->copy_from_archive->process);
7846
case FR_ACTION_EXTRACTING_FILES:
7847
if (window->priv->clipboard_data->op == FR_CLIPBOARD_OP_CUT) {
7848
fr_process_clear (window->priv->copy_from_archive->process);
7849
fr_archive_remove (window->priv->copy_from_archive,
7850
window->priv->clipboard_data->files,
7851
window->priv->compression);
7852
fr_process_start (window->priv->copy_from_archive->process);
7855
add_pasted_files (window, window->priv->clipboard_data);
7858
case FR_ACTION_DELETING_FILES:
7859
add_pasted_files (window, window->priv->clipboard_data);
7869
fr_window_paste_from_clipboard_data (FrWindow *window,
7870
FrClipboardData *data)
7872
const char *current_dir_relative;
7873
GHashTable *created_dirs;
7876
if (window->priv->password_for_paste != NULL)
7877
fr_clipboard_data_set_password (data, window->priv->password_for_paste);
7879
if (window->priv->clipboard_data != data) {
7880
fr_clipboard_data_unref (window->priv->clipboard_data);
7881
window->priv->clipboard_data = data;
7884
fr_window_set_current_batch_action (window,
7885
FR_BATCH_ACTION_PASTE,
7886
fr_clipboard_data_ref (data),
7887
(GFreeFunc) fr_clipboard_data_unref);
7889
current_dir_relative = data->current_dir + 1;
7891
data->tmp_dir = get_temp_work_dir (NULL);
7892
created_dirs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
7893
for (scan = data->files; scan; scan = scan->next) {
7894
const char *old_name = (char*) scan->data;
7895
char *new_name = g_build_filename (current_dir_relative, old_name + strlen (data->base_dir) - 1, NULL);
7896
char *dir = remove_level_from_path (new_name);
7898
if ((dir != NULL) && (g_hash_table_lookup (created_dirs, dir) == NULL)) {
7901
dir_path = g_build_filename (data->tmp_dir, dir, NULL);
7902
debug (DEBUG_INFO, "mktree %s\n", dir_path);
7903
make_directory_tree_from_path (dir_path, 0700, NULL);
7906
g_hash_table_replace (created_dirs, g_strdup (dir), "1");
7912
g_hash_table_destroy (created_dirs);
7916
if (window->priv->copy_from_archive == NULL) {
7917
window->priv->copy_from_archive = fr_archive_new ();
7918
g_signal_connect (G_OBJECT (window->priv->copy_from_archive),
7920
G_CALLBACK (action_started),
7922
g_signal_connect (G_OBJECT (window->priv->copy_from_archive),
7924
G_CALLBACK (copy_from_archive_action_performed_cb),
7926
g_signal_connect (G_OBJECT (window->priv->copy_from_archive),
7928
G_CALLBACK (fr_window_progress_cb),
7930
g_signal_connect (G_OBJECT (window->priv->copy_from_archive),
7932
G_CALLBACK (fr_window_message_cb),
7934
g_signal_connect (G_OBJECT (window->priv->copy_from_archive),
7936
G_CALLBACK (fr_window_stoppable_cb),
7938
fr_archive_set_fake_load_func (window->priv->copy_from_archive, always_fake_load, NULL);
7940
fr_archive_load_local (window->priv->copy_from_archive,
7941
data->archive_filename,
7942
data->archive_password);
7947
fr_window_paste_selection_to (FrWindow *window,
7948
const char *current_dir)
7950
GtkClipboard *clipboard;
7951
GtkSelectionData *selection_data;
7952
FrClipboardData *paste_data;
7954
clipboard = gtk_clipboard_get (FR_CLIPBOARD);
7955
selection_data = gtk_clipboard_wait_for_contents (clipboard, FR_SPECIAL_URI_LIST);
7956
if (selection_data == NULL)
7959
paste_data = get_clipboard_data_from_selection_data (window, (char*) gtk_selection_data_get_data (selection_data));
7960
paste_data->current_dir = g_strdup (current_dir);
7961
fr_window_paste_from_clipboard_data (window, paste_data);
7963
gtk_selection_data_free (selection_data);
7968
fr_window_paste_selection (FrWindow *window,
7969
gboolean from_sidebar)
7971
char *utf8_path, *utf8_old_path, *destination;
7974
if (window->priv->list_mode == FR_WINDOW_LIST_MODE_FLAT)
7979
utf8_old_path = g_filename_to_utf8 (fr_window_get_current_location (window), -1, NULL, NULL, NULL);
7980
utf8_path = _gtk_request_dialog_run (GTK_WINDOW (window),
7981
(GTK_DIALOG_DESTROY_WITH_PARENT
7982
| GTK_DIALOG_MODAL),
7983
_("Paste Selection"),
7984
_("Destination folder"),
7989
g_free (utf8_old_path);
7990
if (utf8_path == NULL)
7993
destination = g_filename_from_utf8 (utf8_path, -1, NULL, NULL, NULL);
7996
if (destination[0] != '/')
7997
current_dir = build_uri (fr_window_get_current_location (window), destination, NULL);
7999
current_dir = g_strdup (destination);
8000
g_free (destination);
8002
fr_window_paste_selection_to (window, current_dir);
8004
g_free (current_dir);
8008
/* -- fr_window_open_files -- */
8012
fr_window_open_files_with_command (FrWindow *window,
8017
GError *error = NULL;
8019
app = g_app_info_create_from_commandline (command, NULL, G_APP_INFO_CREATE_NONE, &error);
8020
if (error != NULL) {
8021
_gtk_error_dialog_run (GTK_WINDOW (window),
8022
_("Could not perform the operation"),
8025
g_clear_error (&error);
8029
fr_window_open_files_with_application (window, file_list, app);
8034
fr_window_open_files_with_application (FrWindow *window,
8040
GdkAppLaunchContext *context;
8041
GError *error = NULL;
8043
if (window->priv->activity_ref > 0)
8047
for (scan = file_list; scan; scan = scan->next)
8048
uris = g_list_prepend (uris, g_filename_to_uri (scan->data, NULL, NULL));
8050
context = gdk_display_get_app_launch_context (gtk_widget_get_display (GTK_WIDGET (window)));
8051
gdk_app_launch_context_set_screen (context, gtk_widget_get_screen (GTK_WIDGET (window)));
8052
gdk_app_launch_context_set_timestamp (context, 0);
8054
if (! g_app_info_launch_uris (app, uris, G_APP_LAUNCH_CONTEXT (context), &error)) {
8055
_gtk_error_dialog_run (GTK_WINDOW (window),
8056
_("Could not perform the operation"),
8059
g_clear_error (&error);
8062
g_object_unref (context);
8063
path_list_free (uris);
8070
gboolean ask_application;
8075
static OpenFilesData*
8076
open_files_data_new (FrWindow *window,
8078
gboolean ask_application)
8081
OpenFilesData *odata;
8084
odata = g_new0 (OpenFilesData, 1);
8085
odata->window = window;
8086
odata->file_list = path_list_dup (file_list);
8087
odata->ask_application = ask_application;
8088
odata->cdata = g_new0 (CommandData, 1);
8089
odata->cdata->temp_dir = get_temp_work_dir (NULL);
8090
odata->cdata->file_list = NULL;
8091
for (scan = file_list; scan; scan = scan->next) {
8092
char *file = scan->data;
8095
filename = g_strconcat (odata->cdata->temp_dir,
8099
odata->cdata->file_list = g_list_prepend (odata->cdata->file_list, filename);
8102
/* Add to CommandList so the cdata is released on exit. */
8103
CommandList = g_list_prepend (CommandList, odata->cdata);
8110
open_files_data_free (OpenFilesData *odata)
8112
g_return_if_fail (odata != NULL);
8114
path_list_free (odata->file_list);
8120
fr_window_update_dialog_closed (FrWindow *window)
8122
window->priv->update_dialog = NULL;
8127
fr_window_update_files (FrWindow *window,
8132
if (window->priv->activity_ref > 0)
8135
if (window->archive->read_only)
8138
fr_process_clear (window->archive->process);
8140
for (scan = file_list; scan; scan = scan->next) {
8141
OpenFile *file = scan->data;
8142
GList *local_file_list;
8144
local_file_list = g_list_append (NULL, file->path);
8145
fr_archive_add (window->archive,
8151
window->priv->password,
8152
window->priv->encrypt_header,
8153
window->priv->compression,
8154
window->priv->volume_size);
8155
g_list_free (local_file_list);
8158
fr_process_start (window->archive->process);
8165
open_file_modified_cb (GFileMonitor *monitor,
8166
GFile *monitor_file,
8168
GFileMonitorEvent event_type,
8171
FrWindow *window = user_data;
8176
if ((event_type != G_FILE_MONITOR_EVENT_CHANGED)
8177
&& (event_type != G_FILE_MONITOR_EVENT_CREATED))
8182
monitor_uri = g_file_get_uri (monitor_file);
8184
for (scan = window->priv->open_files; scan; scan = scan->next) {
8185
OpenFile *test = scan->data;
8186
if (uricmp (test->extracted_uri, monitor_uri) == 0) {
8191
g_free (monitor_uri);
8193
g_return_if_fail (file != NULL);
8195
if (window->priv->update_dialog == NULL)
8196
window->priv->update_dialog = dlg_update (window);
8197
dlg_update_add_file (window->priv->update_dialog, file);
8202
fr_window_monitor_open_file (FrWindow *window,
8207
window->priv->open_files = g_list_prepend (window->priv->open_files, file);
8208
f = g_file_new_for_uri (file->extracted_uri);
8209
file->monitor = g_file_monitor_file (f, 0, NULL, NULL);
8210
g_signal_connect (file->monitor,
8212
G_CALLBACK (open_file_modified_cb),
8219
monitor_extracted_files (OpenFilesData *odata)
8221
FrWindow *window = odata->window;
8222
GList *scan1, *scan2;
8224
for (scan1 = odata->file_list, scan2 = odata->cdata->file_list;
8226
scan1 = scan1->next, scan2 = scan2->next)
8229
const char *file = scan1->data;
8230
const char *extracted_path = scan2->data;
8232
ofile = open_file_new (file, extracted_path, odata->cdata->temp_dir);
8234
fr_window_monitor_open_file (window, ofile);
8240
fr_window_open_extracted_files (OpenFilesData *odata)
8242
GList *file_list = odata->cdata->file_list;
8243
const char *first_file;
8244
const char *first_mime_type;
8246
GList *files_to_open = NULL;
8247
GdkAppLaunchContext *context;
8249
GError *error = NULL;
8251
g_return_val_if_fail (file_list != NULL, FALSE);
8253
first_file = (char*) file_list->data;
8254
if (first_file == NULL)
8257
if (! odata->window->archive->read_only)
8258
monitor_extracted_files (odata);
8260
if (odata->ask_application) {
8261
dlg_open_with (odata->window, file_list);
8265
first_mime_type = get_file_mime_type_for_path (first_file, FALSE);
8266
app = g_app_info_get_default_for_type (first_mime_type, FALSE);
8269
dlg_open_with (odata->window, file_list);
8273
files_to_open = g_list_append (files_to_open, g_filename_to_uri (first_file, NULL, NULL));
8275
if (g_app_info_supports_files (app)) {
8278
for (scan = file_list->next; scan; scan = scan->next) {
8279
const char *path = scan->data;
8280
const char *mime_type;
8282
mime_type = get_file_mime_type_for_path (path, FALSE);
8283
if (mime_type == NULL)
8286
if (strcmp (mime_type, first_mime_type) == 0) {
8287
files_to_open = g_list_append (files_to_open, g_filename_to_uri (path, NULL, NULL));
8292
app2 = g_app_info_get_default_for_type (mime_type, FALSE);
8293
if (g_app_info_equal (app, app2))
8294
files_to_open = g_list_append (files_to_open, g_filename_to_uri (path, NULL, NULL));
8295
g_object_unref (app2);
8300
context = gdk_display_get_app_launch_context (gtk_widget_get_display (GTK_WIDGET (odata->window)));
8301
gdk_app_launch_context_set_screen (context, gtk_widget_get_screen (GTK_WIDGET (odata->window)));
8302
gdk_app_launch_context_set_timestamp (context, 0);
8303
result = g_app_info_launch_uris (app, files_to_open, G_APP_LAUNCH_CONTEXT (context), &error);
8305
_gtk_error_dialog_run (GTK_WINDOW (odata->window),
8306
_("Could not perform the operation"),
8309
g_clear_error (&error);
8312
g_object_unref (context);
8313
g_object_unref (app);
8314
path_list_free (files_to_open);
8321
fr_window_open_files__extract_done_cb (FrArchive *archive,
8324
gpointer callback_data)
8326
OpenFilesData *odata = callback_data;
8328
g_signal_handlers_disconnect_matched (G_OBJECT (archive),
8329
G_SIGNAL_MATCH_DATA,
8335
if (error->type == FR_PROC_ERROR_NONE)
8336
fr_window_open_extracted_files (odata);
8341
fr_window_open_files (FrWindow *window,
8343
gboolean ask_application)
8345
OpenFilesData *odata;
8347
if (window->priv->activity_ref > 0)
8350
odata = open_files_data_new (window, file_list, ask_application);
8351
fr_window_set_current_batch_action (window,
8352
FR_BATCH_ACTION_OPEN_FILES,
8354
(GFreeFunc) open_files_data_free);
8356
g_signal_connect (G_OBJECT (window->archive),
8358
G_CALLBACK (fr_window_open_files__extract_done_cb),
8361
fr_process_clear (window->archive->process);
8362
fr_archive_extract_to_local (window->archive,
8364
odata->cdata->temp_dir,
8369
window->priv->password);
8370
fr_process_start (window->archive->process);
8378
get_default_dir (const char *dir)
8380
if (! is_temp_dir (dir))
8381
return g_strdup (dir);
8388
fr_window_set_open_default_dir (FrWindow *window,
8389
const char *default_dir)
8391
g_return_if_fail (window != NULL);
8392
g_return_if_fail (default_dir != NULL);
8394
if (window->priv->open_default_dir != NULL)
8395
g_free (window->priv->open_default_dir);
8396
window->priv->open_default_dir = get_default_dir (default_dir);
8401
fr_window_get_open_default_dir (FrWindow *window)
8403
if (window->priv->open_default_dir == NULL)
8404
return get_home_uri ();
8406
return window->priv->open_default_dir;
8411
fr_window_set_add_default_dir (FrWindow *window,
8412
const char *default_dir)
8414
g_return_if_fail (window != NULL);
8415
g_return_if_fail (default_dir != NULL);
8417
if (window->priv->add_default_dir != NULL)
8418
g_free (window->priv->add_default_dir);
8419
window->priv->add_default_dir = get_default_dir (default_dir);
8424
fr_window_get_add_default_dir (FrWindow *window)
8426
if (window->priv->add_default_dir == NULL)
8427
return get_home_uri ();
8429
return window->priv->add_default_dir;
8434
fr_window_set_extract_default_dir (FrWindow *window,
8435
const char *default_dir,
8438
g_return_if_fail (window != NULL);
8439
g_return_if_fail (default_dir != NULL);
8441
/* do not change this dir while it's used by the non-interactive
8442
* extraction operation. */
8443
if (window->priv->extract_interact_use_default_dir)
8446
window->priv->extract_interact_use_default_dir = freeze;
8448
if (window->priv->extract_default_dir != NULL)
8449
g_free (window->priv->extract_default_dir);
8450
window->priv->extract_default_dir = get_default_dir (default_dir);
8455
fr_window_get_extract_default_dir (FrWindow *window)
8457
if (window->priv->extract_default_dir == NULL)
8458
return get_home_uri ();
8460
return window->priv->extract_default_dir;
8465
fr_window_set_default_dir (FrWindow *window,
8466
const char *default_dir,
8469
g_return_if_fail (window != NULL);
8470
g_return_if_fail (default_dir != NULL);
8472
window->priv->freeze_default_dir = freeze;
8474
fr_window_set_open_default_dir (window, default_dir);
8475
fr_window_set_add_default_dir (window, default_dir);
8476
fr_window_set_extract_default_dir (window, default_dir, FALSE);
8481
fr_window_update_columns_visibility (FrWindow *window)
8483
GtkTreeView *tree_view = GTK_TREE_VIEW (window->priv->list_view);
8484
GtkTreeViewColumn *column;
8486
column = gtk_tree_view_get_column (tree_view, 1);
8487
gtk_tree_view_column_set_visible (column, g_settings_get_boolean (window->priv->settings_listing, PREF_LISTING_SHOW_SIZE));
8489
column = gtk_tree_view_get_column (tree_view, 2);
8490
gtk_tree_view_column_set_visible (column, g_settings_get_boolean (window->priv->settings_listing, PREF_LISTING_SHOW_TYPE));
8492
column = gtk_tree_view_get_column (tree_view, 3);
8493
gtk_tree_view_column_set_visible (column, g_settings_get_boolean (window->priv->settings_listing, PREF_LISTING_SHOW_TIME));
8495
column = gtk_tree_view_get_column (tree_view, 4);
8496
gtk_tree_view_column_set_visible (column, g_settings_get_boolean (window->priv->settings_listing, PREF_LISTING_SHOW_PATH));
8501
fr_window_set_toolbar_visibility (FrWindow *window,
8504
g_return_if_fail (window != NULL);
8507
gtk_widget_show (window->priv->toolbar);
8509
gtk_widget_hide (window->priv->toolbar);
8511
set_active (window, "ViewToolbar", visible);
8516
fr_window_set_statusbar_visibility (FrWindow *window,
8519
g_return_if_fail (window != NULL);
8522
gtk_widget_show (window->priv->statusbar);
8524
gtk_widget_hide (window->priv->statusbar);
8526
set_active (window, "ViewStatusbar", visible);
8531
fr_window_set_folders_visibility (FrWindow *window,
8534
g_return_if_fail (window != NULL);
8536
window->priv->view_folders = value;
8537
fr_window_update_dir_tree (window);
8539
set_active (window, "ViewFolders", window->priv->view_folders);
8544
fr_window_use_progress_dialog (FrWindow *window,
8547
window->priv->use_progress_dialog = value;
8551
/* -- batch mode procedures -- */
8554
static void fr_window_exec_current_batch_action (FrWindow *window);
8558
fr_window_exec_batch_action (FrWindow *window,
8559
FRBatchAction *action)
8563
OpenFilesData *odata;
8566
switch (action->type) {
8567
case FR_BATCH_ACTION_LOAD:
8568
debug (DEBUG_INFO, "[BATCH] LOAD\n");
8570
if (! uri_exists ((char*) action->data))
8571
fr_window_archive_new (window, (char*) action->data);
8573
fr_window_archive_open (window, (char*) action->data, GTK_WINDOW (window));
8576
case FR_BATCH_ACTION_ADD:
8577
debug (DEBUG_INFO, "[BATCH] ADD\n");
8579
fr_window_archive_add_dropped_items (window, (GList*) action->data, FALSE);
8582
case FR_BATCH_ACTION_OPEN:
8583
debug (DEBUG_INFO, "[BATCH] OPEN\n");
8585
fr_window_push_message (window, _("Add files to an archive"));
8586
dlg_batch_add_files (window, (GList*) action->data);
8589
case FR_BATCH_ACTION_EXTRACT:
8590
debug (DEBUG_INFO, "[BATCH] EXTRACT\n");
8592
edata = action->data;
8593
fr_window_archive_extract (window,
8595
edata->extract_to_dir,
8603
case FR_BATCH_ACTION_EXTRACT_HERE:
8604
debug (DEBUG_INFO, "[BATCH] EXTRACT HERE\n");
8606
edata = action->data;
8607
fr_window_archive_extract_here (window,
8613
case FR_BATCH_ACTION_EXTRACT_INTERACT:
8614
debug (DEBUG_INFO, "[BATCH] EXTRACT_INTERACT\n");
8616
if (window->priv->extract_interact_use_default_dir
8617
&& (window->priv->extract_default_dir != NULL))
8619
fr_window_archive_extract (window,
8621
window->priv->extract_default_dir,
8629
fr_window_push_message (window, _("Extract archive"));
8630
dlg_extract (NULL, window);
8634
case FR_BATCH_ACTION_RENAME:
8635
debug (DEBUG_INFO, "[BATCH] RENAME\n");
8637
rdata = action->data;
8638
rename_selection (window,
8639
rdata->path_to_rename,
8644
rdata->dir_in_archive,
8645
rdata->original_path);
8648
case FR_BATCH_ACTION_PASTE:
8649
debug (DEBUG_INFO, "[BATCH] PASTE\n");
8651
fr_window_paste_from_clipboard_data (window, (FrClipboardData*) action->data);
8654
case FR_BATCH_ACTION_OPEN_FILES:
8655
debug (DEBUG_INFO, "[BATCH] OPEN FILES\n");
8657
odata = action->data;
8658
fr_window_open_files (window, odata->file_list, odata->ask_application);
8661
case FR_BATCH_ACTION_SAVE_AS:
8662
debug (DEBUG_INFO, "[BATCH] SAVE_AS\n");
8664
sdata = action->data;
8665
fr_window_archive_save_as (window,
8668
sdata->encrypt_header,
8669
sdata->volume_size);
8672
case FR_BATCH_ACTION_TEST:
8673
debug (DEBUG_INFO, "[BATCH] TEST\n");
8675
fr_window_archive_test (window);
8678
case FR_BATCH_ACTION_CLOSE:
8679
debug (DEBUG_INFO, "[BATCH] CLOSE\n");
8681
fr_window_archive_close (window);
8682
fr_window_exec_next_batch_action (window);
8685
case FR_BATCH_ACTION_QUIT:
8686
debug (DEBUG_INFO, "[BATCH] QUIT\n");
8688
g_signal_emit (window,
8689
fr_window_signals[READY],
8693
if ((window->priv->progress_dialog != NULL) && (gtk_widget_get_parent (window->priv->progress_dialog) != GTK_WIDGET (window)))
8694
gtk_widget_destroy (window->priv->progress_dialog);
8695
gtk_widget_destroy (GTK_WIDGET (window));
8705
fr_window_reset_current_batch_action (FrWindow *window)
8707
FRBatchAction *adata = &window->priv->current_batch_action;
8709
if ((adata->data != NULL) && (adata->free_func != NULL))
8710
(*adata->free_func) (adata->data);
8711
adata->type = FR_BATCH_ACTION_NONE;
8713
adata->free_func = NULL;
8718
fr_window_set_current_batch_action (FrWindow *window,
8719
FrBatchActionType action,
8721
GFreeFunc free_func)
8723
FRBatchAction *adata = &window->priv->current_batch_action;
8725
fr_window_reset_current_batch_action (window);
8727
adata->type = action;
8729
adata->free_func = free_func;
8734
fr_window_restart_current_batch_action (FrWindow *window)
8736
fr_window_exec_batch_action (window, &window->priv->current_batch_action);
8741
fr_window_append_batch_action (FrWindow *window,
8742
FrBatchActionType action,
8744
GFreeFunc free_func)
8746
FRBatchAction *a_desc;
8748
g_return_if_fail (window != NULL);
8750
a_desc = g_new0 (FRBatchAction, 1);
8751
a_desc->type = action;
8752
a_desc->data = data;
8753
a_desc->free_func = free_func;
8755
window->priv->batch_action_list = g_list_append (window->priv->batch_action_list, a_desc);
8760
fr_window_exec_current_batch_action (FrWindow *window)
8762
FRBatchAction *action;
8764
if (window->priv->batch_action == NULL) {
8765
window->priv->batch_mode = FALSE;
8768
action = (FRBatchAction *) window->priv->batch_action->data;
8769
fr_window_exec_batch_action (window, action);
8774
fr_window_exec_next_batch_action (FrWindow *window)
8776
if (window->priv->batch_action != NULL)
8777
window->priv->batch_action = g_list_next (window->priv->batch_action);
8779
window->priv->batch_action = window->priv->batch_action_list;
8780
fr_window_exec_current_batch_action (window);
8785
fr_window_start_batch (FrWindow *window)
8787
g_return_if_fail (window != NULL);
8789
if (window->priv->batch_mode)
8792
if (window->priv->batch_action_list == NULL)
8795
window->priv->batch_mode = TRUE;
8796
window->priv->batch_action = window->priv->batch_action_list;
8797
window->archive->can_create_compressed_file = window->priv->batch_adding_one_file;
8799
fr_window_exec_current_batch_action (window);
8804
fr_window_stop_batch (FrWindow *window)
8806
if (! window->priv->non_interactive)
8809
window->priv->extract_interact_use_default_dir = FALSE;
8810
window->archive->can_create_compressed_file = FALSE;
8812
if (window->priv->batch_mode) {
8813
if (! window->priv->showing_error_dialog) {
8814
gtk_widget_destroy (GTK_WIDGET (window));
8819
gtk_window_present (GTK_WINDOW (window));
8820
fr_window_archive_close (window);
8823
window->priv->batch_mode = FALSE;
8828
fr_window_resume_batch (FrWindow *window)
8830
fr_window_exec_current_batch_action (window);
8835
fr_window_is_batch_mode (FrWindow *window)
8837
return window->priv->batch_mode;
8842
fr_window_new_batch (FrWindow *window)
8844
fr_window_free_batch_data (window);
8845
window->priv->non_interactive = TRUE;
8850
fr_window_set_batch__extract_here (FrWindow *window,
8851
const char *filename)
8853
g_return_if_fail (window != NULL);
8854
g_return_if_fail (filename != NULL);
8856
fr_window_append_batch_action (window,
8857
FR_BATCH_ACTION_LOAD,
8858
g_strdup (filename),
8859
(GFreeFunc) g_free);
8860
fr_window_append_batch_action (window,
8861
FR_BATCH_ACTION_EXTRACT_HERE,
8862
extract_to_data_new (NULL),
8863
(GFreeFunc) extract_data_free);
8864
fr_window_append_batch_action (window,
8865
FR_BATCH_ACTION_CLOSE,
8872
fr_window_set_batch__extract (FrWindow *window,
8873
const char *filename,
8874
const char *dest_dir)
8876
g_return_if_fail (window != NULL);
8877
g_return_if_fail (filename != NULL);
8879
fr_window_append_batch_action (window,
8880
FR_BATCH_ACTION_LOAD,
8881
g_strdup (filename),
8882
(GFreeFunc) g_free);
8883
if (dest_dir != NULL)
8884
fr_window_append_batch_action (window,
8885
FR_BATCH_ACTION_EXTRACT,
8886
extract_to_data_new (dest_dir),
8887
(GFreeFunc) extract_data_free);
8889
fr_window_append_batch_action (window,
8890
FR_BATCH_ACTION_EXTRACT_INTERACT,
8893
fr_window_append_batch_action (window,
8894
FR_BATCH_ACTION_CLOSE,
8901
fr_window_set_batch__add (FrWindow *window,
8902
const char *archive,
8905
window->priv->batch_adding_one_file = (file_list->next == NULL) && (uri_is_file (file_list->data));
8907
if (archive != NULL)
8908
fr_window_append_batch_action (window,
8909
FR_BATCH_ACTION_LOAD,
8911
(GFreeFunc) g_free);
8913
fr_window_append_batch_action (window,
8914
FR_BATCH_ACTION_OPEN,
8917
fr_window_append_batch_action (window,
8918
FR_BATCH_ACTION_ADD,
8921
fr_window_append_batch_action (window,
8922
FR_BATCH_ACTION_CLOSE,