1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 
3 /*
4  *  Engrampa
5  *
6  *  Copyright (C) 2004 Free Software Foundation, Inc.
7  *
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.
12  *
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.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, write to the Free Software
20  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21  */
22 
23 #include <config.h>
24 #include <glib.h>
25 #include <string.h>
26 #include <math.h>
27 #include <sys/types.h>
28 #include <sys/stat.h>
29 #include <fcntl.h>
30 #include "actions.h"
31 #include "dlg-add-files.h"
32 #include "dlg-add-folder.h"
33 #include "dlg-extract.h"
34 #include "dlg-delete.h"
35 #include "dlg-new.h"
36 #include "dlg-open-with.h"
37 #include "dlg-password.h"
38 #include "dlg-prop.h"
39 #include "gtk-utils.h"
40 #include "fr-window.h"
41 #include "file-utils.h"
42 #include "fr-process.h"
43 #include "glib-utils.h"
44 #include "fr-init.h"
45 #include "typedefs.h"
46 
47 
48 /* -- new archive -- */
49 
50 
51 static void
new_archive(DlgNewData * data,char * uri)52 new_archive (DlgNewData *data,
53          char       *uri)
54 {
55     GtkWidget  *archive_window;
56     gboolean    new_window;
57     const char *password;
58     gboolean    encrypt_header;
59     int         volume_size;
60 
61     new_window = fr_window_archive_is_present (data->window) && ! fr_window_is_batch_mode (data->window);
62     if (new_window)
63         archive_window = fr_window_new ();
64     else
65         archive_window = (GtkWidget *) data->window;
66 
67     password = dlg_new_data_get_password (data);
68     encrypt_header = dlg_new_data_get_encrypt_header (data);
69     volume_size = dlg_new_data_get_volume_size (data);
70 
71     fr_window_set_password (FR_WINDOW (archive_window), password);
72     fr_window_set_encrypt_header (FR_WINDOW (archive_window), encrypt_header);
73     fr_window_set_volume_size (FR_WINDOW (archive_window), volume_size);
74 
75     if (fr_window_archive_new (FR_WINDOW (archive_window), uri)) {
76         gtk_widget_destroy (data->dialog);
77         if (! fr_window_is_batch_mode (FR_WINDOW (archive_window)))
78             gtk_window_present (GTK_WINDOW (archive_window));
79     }
80     else if (new_window)
81         gtk_widget_destroy (archive_window);
82 }
83 
84 
85 /* when on Automatic the user provided extension needs to be supported,
86    otherwise an existing unsupported archive can be deleted (if the user
87    provided name matches with its name) before we find out that the
88    archive is unsupported
89 */
90 static gboolean
is_supported_extension(GtkWidget * file_sel,char * filename,int * file_type)91 is_supported_extension (GtkWidget *file_sel,
92             char      *filename,
93             int       *file_type)
94 {
95     int i;
96     for (i = 0; file_type[i] != -1; i++)
97         if (file_extension_is (filename, mime_type_desc[file_type[i]].default_ext))
98             return TRUE;
99     return FALSE;
100 }
101 
102 
103 static char *
get_full_uri(DlgNewData * data)104 get_full_uri (DlgNewData *data)
105 {
106     char        *full_uri = NULL;
107     char        *uri;
108     const char  *filename;
109     int          idx;
110 
111     uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (data->dialog));
112 
113     if ((uri == NULL) || (*uri == 0))
114         return NULL;
115 
116     filename = file_name_from_path (uri);
117     if ((filename == NULL) || (*filename == 0)) {
118         g_free (uri);
119         return NULL;
120     }
121 
122     idx = egg_file_format_chooser_get_format (EGG_FILE_FORMAT_CHOOSER (data->format_chooser), uri);
123     if (idx > 0) {
124         const char *uri_ext;
125         const char *default_ext;
126 
127         uri_ext = get_archive_filename_extension (uri);
128         default_ext = mime_type_desc[data->supported_types[idx-1]].default_ext;
129         if (strcmp_null_tolerant (uri_ext, default_ext) != 0)
130             full_uri = g_strconcat (uri, default_ext, NULL);
131     }
132     if (full_uri == NULL)
133         full_uri = uri;
134     else
135         g_free (uri);
136 
137     return full_uri;
138 }
139 
140 
141 static char *
get_archive_filename_from_selector(DlgNewData * data)142 get_archive_filename_from_selector (DlgNewData *data)
143 {
144     char      *uri = NULL;
145     GFile     *file, *dir;
146     GFileInfo *info;
147     GError    *err = NULL;
148 
149     uri = get_full_uri (data);
150     if ((uri == NULL) || (*uri == 0)) {
151         GtkWidget *dialog;
152 
153         g_free (uri);
154 
155         dialog = _gtk_error_dialog_new (GTK_WINDOW (data->dialog),
156                         GTK_DIALOG_DESTROY_WITH_PARENT,
157                         NULL,
158                         _("Could not create the archive"),
159                         "%s",
160                         _("You have to specify an archive name."));
161         gtk_dialog_run (GTK_DIALOG (dialog));
162         gtk_widget_destroy (GTK_WIDGET (dialog));
163 
164         return NULL;
165     }
166 
167     file = g_file_new_for_uri (uri);
168 
169     dir = g_file_get_parent (file);
170     info = g_file_query_info (dir,
171                   G_FILE_ATTRIBUTE_ACCESS_CAN_READ ","
172                   G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE ","
173                   G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE,
174                   0, NULL, &err);
175     if (err != NULL) {
176         g_warning ("Failed to get permission for extraction dir: %s",
177                err->message);
178         g_clear_error (&err);
179         g_object_unref (info);
180         g_object_unref (dir);
181         g_object_unref (file);
182         g_free (uri);
183         return NULL;
184     }
185 
186     if (! g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE)) {
187         GtkWidget *dialog;
188 
189         g_object_unref (info);
190         g_object_unref (dir);
191         g_object_unref (file);
192         g_free (uri);
193 
194         dialog = _gtk_error_dialog_new (GTK_WINDOW (data->dialog),
195                         GTK_DIALOG_DESTROY_WITH_PARENT,
196                         NULL,
197                         _("Could not create the archive"),
198                         "%s",
199                         _("You don't have permission to create an archive in this folder"));
200         gtk_dialog_run (GTK_DIALOG (dialog));
201         gtk_widget_destroy (GTK_WIDGET (dialog));
202         return NULL;
203     }
204     g_object_unref (info);
205     g_object_unref (dir);
206 
207     /* if the user did not specify a valid extension use the filetype combobox current type
208      * or tar.gz if automatic is selected. */
209     if (get_archive_filename_extension (uri) == NULL) {
210         int   idx;
211         char *new_uri;
212         const char *ext = NULL;
213 
214         idx = egg_file_format_chooser_get_format (EGG_FILE_FORMAT_CHOOSER (data->format_chooser), uri);
215         if (idx > 0)
216             ext = mime_type_desc[data->supported_types[idx-1]].default_ext;
217         else
218             ext = ".tar.gz";
219         new_uri = g_strconcat (uri, ext, NULL);
220         g_free (uri);
221         uri = new_uri;
222     }
223 
224     debug (DEBUG_INFO, "create/save %s\n", uri);
225 
226     if (uri_exists (uri)) {
227 
228         if (! is_supported_extension (data->dialog, uri, data->supported_types)) {
229             GtkWidget *dialog;
230             dialog = _gtk_error_dialog_new (GTK_WINDOW (data->dialog),
231                             GTK_DIALOG_MODAL,
232                             NULL,
233                             _("Could not create the archive"),
234                             "%s",
235                             _("Archive type not supported."));
236             gtk_dialog_run (GTK_DIALOG (dialog));
237             gtk_widget_destroy (GTK_WIDGET (dialog));
238             g_free (uri);
239 
240             return NULL;
241         }
242 
243         g_file_delete (file, NULL, &err);
244         if (err != NULL) {
245             GtkWidget *dialog;
246             dialog = _gtk_error_dialog_new (GTK_WINDOW (data->dialog),
247                             GTK_DIALOG_DESTROY_WITH_PARENT,
248                             NULL,
249                             _("Could not delete the old archive."),
250                             "%s",
251                             err->message);
252             gtk_dialog_run (GTK_DIALOG (dialog));
253             gtk_widget_destroy (GTK_WIDGET (dialog));
254             g_error_free (err);
255             g_free (uri);
256             g_object_unref (file);
257             return NULL;
258         }
259     }
260 
261     g_object_unref (file);
262 
263     return uri;
264 }
265 
266 
267 static void
new_file_response_cb(GtkWidget * w,int response,DlgNewData * data)268 new_file_response_cb (GtkWidget  *w,
269               int         response,
270               DlgNewData *data)
271 {
272     char *path;
273 
274     if ((response == GTK_RESPONSE_CANCEL) || (response == GTK_RESPONSE_DELETE_EVENT)) {
275         fr_archive_action_completed (data->window->archive,
276                          FR_ACTION_CREATING_NEW_ARCHIVE,
277                          FR_PROC_ERROR_STOPPED,
278                          NULL);
279         gtk_widget_destroy (data->dialog);
280         return;
281     }
282 
283     if (response == GTK_RESPONSE_HELP) {
284         show_help_dialog (GTK_WINDOW (data->dialog), "engrampa-create");
285         return;
286     }
287 
288     path = get_archive_filename_from_selector (data);
289     if (path != NULL) {
290         new_archive (data, path);
291         g_free (path);
292     }
293 }
294 
295 
296 void
show_new_archive_dialog(FrWindow * window,const char * archive_name)297 show_new_archive_dialog (FrWindow   *window,
298              const char *archive_name)
299 {
300     DlgNewData *data;
301 
302     if (archive_name != NULL)
303         data = dlg_save_as (window, archive_name);
304     else
305         data = dlg_new (window);
306 
307     g_signal_connect (G_OBJECT (data->dialog),
308               "response",
309               G_CALLBACK (new_file_response_cb),
310               data);
311     gtk_window_present (GTK_WINDOW (data->dialog));
312 }
313 
314 
315 void
activate_action_new(GtkAction * action,gpointer data)316 activate_action_new (GtkAction *action,
317              gpointer   data)
318 {
319     show_new_archive_dialog ((FrWindow*)data, NULL);
320 }
321 
322 
323 /* -- open archive -- */
324 
325 
326 static void
window_archive_loaded_cb(FrWindow * window,gboolean success,GtkWidget * file_sel)327 window_archive_loaded_cb (FrWindow  *window,
328               gboolean   success,
329               GtkWidget *file_sel)
330 {
331     if (success) {
332         g_signal_handlers_disconnect_by_data (window, file_sel);
333         gtk_widget_destroy (file_sel);
334     }
335     else {
336         FrWindow *original_window =  g_object_get_data (G_OBJECT (file_sel), "fr_window");
337         if (window != original_window)
338             fr_window_destroy_with_error_dialog (window);
339     }
340 }
341 
342 
343 static void
open_file_response_cb(GtkWidget * w,int response,GtkWidget * file_sel)344 open_file_response_cb (GtkWidget *w,
345                int        response,
346                GtkWidget *file_sel)
347 {
348     FrWindow *window = NULL;
349     char     *uri;
350 
351     if ((response == GTK_RESPONSE_CANCEL) || (response == GTK_RESPONSE_DELETE_EVENT)) {
352         gtk_widget_destroy (file_sel);
353         return;
354     }
355 
356     window = g_object_get_data (G_OBJECT (file_sel), "fr_window");
357     uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (file_sel));
358 
359     if ((window == NULL) || (uri == NULL))
360         return;
361 
362     if (fr_window_archive_is_present (window))
363         window = (FrWindow *) fr_window_new ();
364     g_signal_connect (G_OBJECT (window),
365               "archive_loaded",
366               G_CALLBACK (window_archive_loaded_cb),
367               file_sel);
368     fr_window_archive_open (window, uri, GTK_WINDOW (file_sel));
369 
370     g_free (uri);
371 }
372 
373 
374 void
activate_action_open(GtkAction * action,gpointer data)375 activate_action_open (GtkAction *action,
376               gpointer   data)
377 {
378     GtkWidget     *file_sel;
379     FrWindow      *window = data;
380     GtkFileFilter *filter;
381     int            i;
382 
383     file_sel = gtk_file_chooser_dialog_new (_("Open"),
384                         GTK_WINDOW (window),
385                         GTK_FILE_CHOOSER_ACTION_OPEN,
386                         "gtk-cancel", GTK_RESPONSE_CANCEL,
387                         "gtk-open", GTK_RESPONSE_OK,
388                         NULL);
389     gtk_dialog_set_default_response (GTK_DIALOG (file_sel), GTK_RESPONSE_OK);
390     gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (file_sel), FALSE);
391     gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (file_sel), fr_window_get_open_default_dir (window));
392 
393     filter = gtk_file_filter_new ();
394     gtk_file_filter_set_name (filter, _("All archives"));
395     for (i = 0; open_type[i] != -1; i++)
396         gtk_file_filter_add_mime_type (filter, mime_type_desc[open_type[i]].mime_type);
397     gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (file_sel), filter);
398     gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (file_sel), filter);
399 
400     filter = gtk_file_filter_new ();
401     gtk_file_filter_set_name (filter, _("All files"));
402     gtk_file_filter_add_pattern (filter, "*");
403     gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (file_sel), filter);
404 
405     /**/
406 
407     g_object_set_data (G_OBJECT (file_sel), "fr_window", window);
408 
409     g_signal_connect (G_OBJECT (file_sel),
410               "response",
411               G_CALLBACK (open_file_response_cb),
412               file_sel);
413 
414     gtk_window_set_modal (GTK_WINDOW (file_sel), TRUE);
415     gtk_widget_show (file_sel);
416 }
417 
418 
419 /* -- save archive -- */
420 
421 
422 static void
save_file_response_cb(GtkWidget * w,gint response,DlgNewData * data)423 save_file_response_cb (GtkWidget  *w,
424                gint        response,
425                DlgNewData *data)
426 {
427     char       *path;
428     const char *password;
429     gboolean    encrypt_header;
430     int         volume_size;
431     GSettings  *settings;
432 
433     if ((response == GTK_RESPONSE_CANCEL) || (response == GTK_RESPONSE_DELETE_EVENT)) {
434         gtk_widget_destroy (data->dialog);
435         return;
436     }
437 
438     if (response == GTK_RESPONSE_HELP) {
439         show_help_dialog (GTK_WINDOW (data->dialog), "engrampa-create#engrampa-convert-archive");
440         return;
441     }
442 
443     path = get_archive_filename_from_selector (data);
444     if (path == NULL)
445         return;
446 
447     password = dlg_new_data_get_password (data);
448     encrypt_header = dlg_new_data_get_encrypt_header (data);
449     volume_size = dlg_new_data_get_volume_size (data);
450 
451     settings = g_settings_new (ENGRAMPA_SCHEMA_BATCH_ADD);
452     g_settings_set_int (settings, PREF_BATCH_ADD_VOLUME_SIZE, volume_size);
453     g_object_unref (settings);
454 
455     fr_window_archive_save_as (data->window, path, password, encrypt_header, volume_size);
456     gtk_widget_destroy (data->dialog);
457 
458     g_free (path);
459 }
460 
461 
462 void
activate_action_save_as(GtkAction * action,gpointer callback_data)463 activate_action_save_as (GtkAction *action,
464              gpointer   callback_data)
465 {
466     FrWindow   *window = callback_data;
467     DlgNewData *data;
468     char       *archive_name = NULL;
469 
470     if (fr_window_get_archive_uri (window)) {
471         const char *uri;
472         GFile      *file;
473         GFileInfo  *info;
474         GError     *err = NULL;
475 
476         uri = fr_window_get_archive_uri (window);
477         file = g_file_new_for_uri (uri);
478         info = g_file_query_info (file,
479                       G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME,
480                       0, NULL, &err);
481 
482         if (err != NULL) {
483             g_warning ("Failed to get display name for uri %s: %s", uri, err->message);
484             g_clear_error (&err);
485         }
486         else
487             archive_name = g_strdup (g_file_info_get_display_name (info));
488 
489         g_object_unref (info);
490         g_object_unref (file);
491     }
492 
493     data = dlg_save_as (window, archive_name);
494     g_signal_connect (G_OBJECT (data->dialog),
495               "response",
496               G_CALLBACK (save_file_response_cb),
497               data);
498     gtk_window_present (GTK_WINDOW (data->dialog));
499 
500     g_free (archive_name);
501 }
502 
503 
504 void
activate_action_test_archive(GtkAction * action,gpointer data)505 activate_action_test_archive (GtkAction *action,
506                   gpointer   data)
507 {
508     FrWindow *window = data;
509 
510     fr_window_archive_test (window);
511 }
512 
513 
514 void
activate_action_properties(GtkAction * action,gpointer data)515 activate_action_properties (GtkAction *action,
516                 gpointer   data)
517 {
518     FrWindow *window = data;
519 
520     dlg_prop (window);
521 }
522 
523 
524 void
activate_action_close(GtkAction * action,gpointer data)525 activate_action_close (GtkAction *action,
526                gpointer   data)
527 {
528     FrWindow *window = data;
529 
530     fr_window_close (window);
531 }
532 
533 
534 void
activate_action_add_files(GtkAction * action,gpointer data)535 activate_action_add_files (GtkAction *action,
536                gpointer   data)
537 {
538     add_files_cb (NULL, data);
539 }
540 
541 
542 void
activate_action_add_folder(GtkAction * action,gpointer data)543 activate_action_add_folder (GtkAction *action,
544                 gpointer   data)
545 {
546     add_folder_cb (NULL, data);
547 }
548 
549 
550 void
activate_action_extract(GtkAction * action,gpointer data)551 activate_action_extract (GtkAction *action,
552              gpointer   data)
553 {
554     dlg_extract (NULL, data);
555 }
556 
557 
558 void
activate_action_extract_folder_from_sidebar(GtkAction * action,gpointer data)559 activate_action_extract_folder_from_sidebar (GtkAction *action,
560                          gpointer   data)
561 {
562     dlg_extract_folder_from_sidebar (NULL, data);
563 }
564 
565 
566 void
activate_action_copy(GtkAction * action,gpointer data)567 activate_action_copy (GtkAction *action,
568               gpointer   data)
569 {
570     fr_window_copy_selection ((FrWindow*) data, FALSE);
571 }
572 
573 
574 void
activate_action_cut(GtkAction * action,gpointer data)575 activate_action_cut (GtkAction *action,
576              gpointer   data)
577 {
578     fr_window_cut_selection ((FrWindow*) data, FALSE);
579 }
580 
581 
582 void
activate_action_paste(GtkAction * action,gpointer data)583 activate_action_paste (GtkAction *action,
584                gpointer   data)
585 {
586     fr_window_paste_selection ((FrWindow*) data, FALSE);
587 }
588 
589 
590 void
activate_action_rename(GtkAction * action,gpointer data)591 activate_action_rename (GtkAction *action,
592             gpointer   data)
593 {
594     fr_window_rename_selection ((FrWindow*) data, FALSE);
595 }
596 
597 
598 void
activate_action_delete(GtkAction * action,gpointer data)599 activate_action_delete (GtkAction *action,
600             gpointer   data)
601 {
602     dlg_delete (NULL, data);
603 }
604 
605 
606 void
activate_action_copy_folder_from_sidebar(GtkAction * action,gpointer data)607 activate_action_copy_folder_from_sidebar (GtkAction *action,
608                           gpointer   data)
609 {
610     fr_window_copy_selection ((FrWindow*) data, TRUE);
611 }
612 
613 
614 void
activate_action_cut_folder_from_sidebar(GtkAction * action,gpointer data)615 activate_action_cut_folder_from_sidebar (GtkAction *action,
616                          gpointer   data)
617 {
618     fr_window_cut_selection ((FrWindow*) data, TRUE);
619 }
620 
621 
622 void
activate_action_paste_folder_from_sidebar(GtkAction * action,gpointer data)623 activate_action_paste_folder_from_sidebar (GtkAction *action,
624                            gpointer   data)
625 {
626     fr_window_paste_selection ((FrWindow*) data, TRUE);
627 }
628 
629 
630 void
activate_action_rename_folder_from_sidebar(GtkAction * action,gpointer data)631 activate_action_rename_folder_from_sidebar (GtkAction *action,
632                         gpointer   data)
633 {
634     fr_window_rename_selection ((FrWindow*) data, TRUE);
635 }
636 
637 
638 void
activate_action_delete_folder_from_sidebar(GtkAction * action,gpointer data)639 activate_action_delete_folder_from_sidebar (GtkAction *action,
640                         gpointer   data)
641 {
642     dlg_delete_from_sidebar (NULL, data);
643 }
644 
645 
646 void
activate_action_find(GtkAction * action,gpointer data)647 activate_action_find (GtkAction *action,
648               gpointer   data)
649 {
650     FrWindow *window = data;
651 
652     fr_window_find (window);
653 }
654 
655 
656 void
activate_action_select_all(GtkAction * action,gpointer data)657 activate_action_select_all (GtkAction *action,
658                 gpointer   data)
659 {
660     FrWindow *window = data;
661 
662     fr_window_select_all (window);
663 }
664 
665 
666 void
activate_action_deselect_all(GtkAction * action,gpointer data)667 activate_action_deselect_all (GtkAction *action,
668                   gpointer   data)
669 {
670     FrWindow *window = data;
671 
672     fr_window_unselect_all (window);
673 }
674 
675 
676 void
activate_action_open_with(GtkAction * action,gpointer data)677 activate_action_open_with (GtkAction *action,
678                gpointer   data)
679 {
680     open_with_cb (NULL, (FrWindow*) data);
681 }
682 
683 
684 void
activate_action_view_or_open(GtkAction * action,gpointer data)685 activate_action_view_or_open (GtkAction *action,
686                   gpointer   data)
687 {
688     FrWindow *window = data;
689     GList    *file_list;
690 
691     file_list = fr_window_get_file_list_selection (window, FALSE, NULL);
692     if (file_list == NULL)
693         return;
694     fr_window_open_files (window, file_list, FALSE);
695     path_list_free (file_list);
696 }
697 
698 
699 void
activate_action_open_folder(GtkAction * action,gpointer data)700 activate_action_open_folder (GtkAction *action,
701                  gpointer   data)
702 {
703     FrWindow *window = data;
704     fr_window_current_folder_activated (window, FALSE);
705 }
706 
707 
708 void
activate_action_open_folder_from_sidebar(GtkAction * action,gpointer data)709 activate_action_open_folder_from_sidebar (GtkAction *action,
710                               gpointer   data)
711 {
712     FrWindow *window = data;
713     fr_window_current_folder_activated (window, TRUE);
714 }
715 
716 
717 void
activate_action_password(GtkAction * action,gpointer data)718 activate_action_password (GtkAction *action,
719               gpointer   data)
720 {
721     dlg_password (NULL, (FrWindow*) data);
722 }
723 
724 
725 void
activate_action_view_toolbar(GtkAction * action,gpointer data)726 activate_action_view_toolbar (GtkAction *action,
727                   gpointer   data)
728 {
729     GSettings *settings;
730 
731     settings = g_settings_new (ENGRAMPA_SCHEMA_UI);
732     g_settings_set_boolean (settings, PREF_UI_VIEW_TOOLBAR, gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)));
733     g_object_unref (settings);
734 }
735 
736 
737 void
activate_action_view_statusbar(GtkAction * action,gpointer data)738 activate_action_view_statusbar (GtkAction *action,
739                 gpointer   data)
740 {
741     GSettings *settings;
742 
743     settings = g_settings_new (ENGRAMPA_SCHEMA_UI);
744     g_settings_set_boolean (settings, PREF_UI_VIEW_STATUSBAR, gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)));
745     g_object_unref (settings);
746 }
747 
748 
749 void
activate_action_view_folders(GtkAction * action,gpointer data)750 activate_action_view_folders (GtkAction *action,
751                 gpointer   data)
752 {
753     GSettings *settings;
754 
755     settings = g_settings_new (ENGRAMPA_SCHEMA_UI);
756     g_settings_set_boolean (settings, PREF_UI_VIEW_FOLDERS, gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)));
757     g_object_unref (settings);
758 }
759 
760 
761 void
activate_action_stop(GtkAction * action,gpointer data)762 activate_action_stop (GtkAction *action,
763               gpointer   data)
764 {
765     FrWindow *window = data;
766     fr_window_stop (window);
767 }
768 
769 
770 void
activate_action_reload(GtkAction * action,gpointer data)771 activate_action_reload (GtkAction *action,
772             gpointer   data)
773 {
774     FrWindow *window = data;
775 
776     fr_window_archive_reload (window);
777 }
778 
779 
780 void
activate_action_sort_reverse_order(GtkAction * action,gpointer data)781 activate_action_sort_reverse_order (GtkAction *action,
782                     gpointer   data)
783 {
784     FrWindow *window = data;
785 
786     fr_window_set_sort_type (window, gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)) ? GTK_SORT_DESCENDING : GTK_SORT_ASCENDING);
787 }
788 
789 
790 void
activate_action_last_output(GtkAction * action,gpointer data)791 activate_action_last_output (GtkAction *action,
792                  gpointer   data)
793 {
794     FrWindow *window = data;
795     fr_window_view_last_output (window, _("Last Output"));
796 }
797 
798 
799 void
activate_action_go_back(GtkAction * action,gpointer data)800 activate_action_go_back (GtkAction *action,
801              gpointer   data)
802 {
803     FrWindow *window = data;
804     fr_window_go_back (window);
805 }
806 
807 
808 void
activate_action_go_forward(GtkAction * action,gpointer data)809 activate_action_go_forward (GtkAction *action,
810                 gpointer   data)
811 {
812     FrWindow *window = data;
813     fr_window_go_forward (window);
814 }
815 
816 
817 void
activate_action_go_up(GtkAction * action,gpointer data)818 activate_action_go_up (GtkAction *action,
819                gpointer   data)
820 {
821     FrWindow *window = data;
822     fr_window_go_up_one_level (window);
823 }
824 
825 
826 void
activate_action_go_home(GtkAction * action,gpointer data)827 activate_action_go_home (GtkAction *action,
828              gpointer   data)
829 {
830     FrWindow *window = data;
831     fr_window_go_to_location (window, "/", FALSE);
832 }
833 
834 
835 void
activate_action_manual(GtkAction * action,gpointer data)836 activate_action_manual (GtkAction *action,
837             gpointer   data)
838 {
839     FrWindow *window = data;
840 
841     show_help_dialog (GTK_WINDOW (window) , NULL);
842 }
843 
844 
845 #define ABOUT_GROUP "About"
846 #define EMAILIFY(string) (g_strdelimit ((string), "%", '@'))
847 
848 void
activate_action_about(GtkAction * action,gpointer gp)849 activate_action_about (GtkAction *action,
850                gpointer   gp)
851 {
852     FrWindow *window = gp;
853     const char *documenters [] = {
854         "Alexander Kirillov",
855         "Breda McColgan",
856         NULL
857     };
858     const char *license[] = {
859         N_("Engrampa is free software; you can redistribute it and/or modify "
860         "it under the terms of the GNU General Public License as published by "
861         "the Free Software Foundation; either version 2 of the License, or "
862         "(at your option) any later version."),
863         N_("Engrampa is distributed in the hope that it will be useful, "
864         "but WITHOUT ANY WARRANTY; without even the implied warranty of "
865         "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the "
866         "GNU General Public License for more details."),
867         N_("You should have received a copy of the GNU General Public License "
868         "along with Engrampa; if not, write to the Free Software Foundation, Inc., "
869         "51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA")
870     };
871     char *license_text;
872     GKeyFile *key_file;
873     GBytes *bytes;
874     const guint8 *data;
875     gsize data_len;
876     GError *error = NULL;
877     char **authors;
878     gsize n_authors = 0, i;
879 
880     bytes = g_resources_lookup_data (ENGRAMPA_RESOURCE_UI_PATH G_DIR_SEPARATOR_S "engrampa.about", G_RESOURCE_LOOKUP_FLAGS_NONE, &error);
881     g_assert_no_error (error);
882 
883     data = g_bytes_get_data (bytes, &data_len);
884     key_file = g_key_file_new ();
885     g_key_file_load_from_data (key_file, (const char *) data, data_len, 0, &error);
886     g_assert_no_error (error);
887 
888     authors = g_key_file_get_string_list (key_file, ABOUT_GROUP, "Authors", &n_authors, NULL);
889 
890     g_key_file_free (key_file);
891     g_bytes_unref (bytes);
892 
893     for (i = 0; i < n_authors; ++i)
894         authors[i] = EMAILIFY (authors[i]);
895 
896     license_text =  g_strjoin ("\n\n", _(license[0]), _(license[1]), _(license[2]), NULL);
897 
898     gtk_show_about_dialog (GTK_WINDOW (window),
899                    "version", VERSION,
900                    "copyright", _("Copyright \xc2\xa9 2001–2010 Free Software Foundation, Inc.\n"
901                                   "Copyright \xc2\xa9 2012–2021 The MATE developers"),
902                    "comments", _("Engrampa is an archive manager for the MATE Desktop Environment."),
903                    "authors", authors,
904                    "documenters", documenters,
905                    "translator-credits", _("translator-credits"),
906                    "logo-icon-name", "engrampa",
907                    "license", license_text,
908                    "wrap-license", TRUE,
909                    "website", PACKAGE_URL,
910                    NULL);
911 
912     g_strfreev (authors);
913     g_free (license_text);
914 }
915