1 /*
2  *      gtk-menu-trash.c
3  *
4  *      Copyright 2009 PCMan <pcman.tw@gmail.com>
5  *      Copyright 2013-2016 Andriy Grytsenko (LStranger) <andrej@rep.kiev.ua>
6  *
7  *      This program is free software; you can redistribute it and/or modify
8  *      it under the terms of the GNU General Public License as published by
9  *      the Free Software Foundation; either version 2 of the License, or
10  *      (at your option) any later version.
11  *
12  *      This program is distributed in the hope that it will be useful,
13  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *      GNU General Public License for more details.
16  *
17  *      You should have received a copy of the GNU General Public License
18  *      along with this program; if not, write to the Free Software
19  *      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
20  *      MA 02110-1301, USA.
21  */
22 
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26 
27 #include "fm-folder-view.h"
28 #include "fm-gtk-utils.h"
29 
30 #include <glib/gi18n-lib.h>
31 
on_untrash(GtkAction * action,gpointer user_data)32 static void on_untrash(GtkAction* action, gpointer user_data)
33 {
34     FmFileMenu *data = (FmFileMenu*)user_data;
35     GtkMenu *menu = fm_file_menu_get_menu(data);
36     GtkWindow *window = GTK_WINDOW(gtk_menu_get_attach_widget(menu));
37     FmFileInfoList *file_infos = fm_file_menu_get_file_info_list(data);
38     FmPathList *files = fm_path_list_new_from_file_info_list(file_infos);
39     fm_untrash_files(window, files);
40     fm_path_list_unref(files);
41 }
42 
on_empty_trash(GtkAction * act,gpointer user_data)43 static void on_empty_trash(GtkAction* act, gpointer user_data)
44 {
45     GtkWindow *window = GTK_WINDOW(user_data);
46     fm_empty_trash(window);
47 }
48 
_update_file_menu_for_trash(GtkWindow * window,GtkUIManager * ui,GString * xml,GtkActionGroup * act_grp,FmFileMenu * menu,FmFileInfoList * files,gboolean single_file)49 static void _update_file_menu_for_trash(GtkWindow* window, GtkUIManager* ui,
50                                         GString* xml, GtkActionGroup* act_grp,
51                                         FmFileMenu* menu, FmFileInfoList* files,
52                                         gboolean single_file)
53 {
54     gboolean can_restore = TRUE, is_trash_root = FALSE;
55     GList *l;
56     GtkAction *act;
57 
58     /* only immediate children of trash:/// can be restored. */
59     for(l = fm_file_info_list_peek_head_link(files);l;l=l->next)
60     {
61         FmPath *trash_path = fm_file_info_get_path(FM_FILE_INFO(l->data));
62         if(single_file)
63             is_trash_root = fm_path_is_trash_root(trash_path);
64         if(!fm_path_get_parent(trash_path) ||
65            !fm_path_is_trash_root(fm_path_get_parent(trash_path)))
66         {
67             can_restore = FALSE;
68             break;
69         }
70     }
71     if(can_restore)
72     {
73         act = gtk_action_new("UnTrash",
74                             _("_Restore"),
75                             _("Restore trashed files to original paths"),
76                             NULL);
77         g_signal_connect(act, "activate", G_CALLBACK(on_untrash), menu);
78         gtk_action_group_add_action(act_grp, act);
79         g_object_unref(act);
80         g_string_append(xml, "<popup><placeholder name='ph1'>"
81                              "<menuitem action='UnTrash'/>"
82                              "</placeholder></popup>");
83     }
84     else if (is_trash_root)
85     {
86         act = gtk_action_new("EmptyTrash",
87                              _("_Empty Trash Can"),
88                              NULL, NULL);
89         g_signal_connect(act, "activate", G_CALLBACK(on_empty_trash), window);
90         gtk_action_group_add_action(act_grp, act);
91         g_string_append(xml, "<popup><placeholder name='ph1'>"
92                              "<menuitem action='EmptyTrash'/>"
93                              "</placeholder></popup>");
94     }
95     act = gtk_ui_manager_get_action(ui, "/popup/Open");
96     gtk_action_set_visible(act, FALSE);
97     act = gtk_ui_manager_get_action(ui, "/popup/Rename");
98     gtk_action_set_visible(act, FALSE);
99     act = gtk_ui_manager_get_action(ui, "/popup/Copy");
100     gtk_action_set_visible(act, FALSE);
101     act = gtk_ui_manager_get_action(ui, "/popup/Paste");
102     gtk_action_set_visible(act, FALSE);
103     /* FIXME: can we cut files here? */
104 }
105 
_update_folder_menu_for_trash(FmFolderView * fv,GtkWindow * window,GtkUIManager * ui,GtkActionGroup * act_grp,FmFileInfoList * files)106 static void _update_folder_menu_for_trash(FmFolderView* fv, GtkWindow* window,
107                                           GtkUIManager* ui, GtkActionGroup* act_grp,
108                                           FmFileInfoList* files)
109 {
110     GtkAction *act;
111 
112     /* FIXME: should we show this item for trash root only? */
113     act = gtk_action_new("EmptyTrash",
114                          _("_Empty Trash Can"),
115                          NULL, NULL);
116     g_signal_connect(act, "activate", G_CALLBACK(on_empty_trash), window);
117     gtk_action_group_add_action(act_grp, act);
118     g_object_unref(act);
119     gtk_ui_manager_add_ui_from_string(ui, "<popup>"
120                                           "<placeholder name='CustomFileOps'>"
121                                           "<menuitem action='EmptyTrash'/>"
122                                           "</placeholder>"
123                                           "</popup>", -1, NULL);
124     act = gtk_ui_manager_get_action(ui, "/popup/Rename");
125     gtk_action_set_visible(act, FALSE);
126     act = gtk_ui_manager_get_action(ui, "/popup/CreateNew");
127     gtk_action_set_visible(act, FALSE);
128     if (!fm_path_is_trash_root(fm_folder_view_get_cwd(fv)))
129     {
130         /* we can paste (i.e. trash) files only into trash root */
131         act = gtk_ui_manager_get_action(ui, "/popup/Paste");
132         gtk_action_set_visible(act, FALSE);
133     }
134 }
135 
136 FM_DEFINE_MODULE(gtk_menu_scheme, trash)
137 
138 FmContextMenuSchemeAddonInit fm_module_init_gtk_menu_scheme = {
139     NULL,
140     NULL,
141     _update_file_menu_for_trash,
142     _update_folder_menu_for_trash
143 };
144