1/*-
2 * Copyright (c) 2017-2018 elementary LLC. (https://elementary.io),
3 *               2013 Julien Spautz <spautz.julien@gmail.com>
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Lesser General Public License version 3
7 * as published by the Free Software Foundation, either version 3 of the
8 * License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranties of
12 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
13 * PURPOSE. See the GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 *
18 * Authored by: Julien Spautz <spautz.julien@gmail.com>, Andrei-Costin Zisu <matzipan@gmail.com>
19 */
20
21namespace Scratch.FolderManager {
22    /**
23     * Normal item in the source list, represents a textfile.
24     */
25    public class FileItem : Item {
26        public FileItem (File file, FileView view) {
27            Object (file: file, view: view);
28        }
29
30        public override Gtk.Menu? get_context_menu () {
31            var new_window_menuitem = new Gtk.MenuItem.with_label (_("New Window"));
32            new_window_menuitem.activate.connect (() => {
33                var new_window = ((Scratch.Application) GLib.Application.get_default ()).new_window ();
34                var doc = new Scratch.Services.Document (new_window.actions, file.file);
35
36                new_window.open_document (doc, true);
37            });
38
39            var files_appinfo = AppInfo.get_default_for_type ("inode/directory", true);
40
41            var files_item_icon = new Gtk.Image.from_gicon (files_appinfo.get_icon (), Gtk.IconSize.MENU);
42            files_item_icon.pixel_size = 16;
43
44            var files_item_grid = new Gtk.Grid ();
45            files_item_grid.add (files_item_icon);
46            files_item_grid.add (new Gtk.Label (files_appinfo.get_name ()));
47
48            var files_menuitem = new Gtk.MenuItem ();
49            files_menuitem.add (files_item_grid);
50            files_menuitem.activate.connect (() => launch_app_with_file (files_appinfo, file.file));
51
52            var other_menuitem = new Gtk.MenuItem.with_label (_("Other Application…"));
53            other_menuitem.activate.connect (() => show_app_chooser (file));
54
55            var open_in_menu = new Gtk.Menu ();
56            if (file.is_valid_textfile) {
57                open_in_menu.add (new_window_menuitem);
58                open_in_menu.add (new Gtk.SeparatorMenuItem ());
59            }
60            open_in_menu.add (files_menuitem);
61
62            var contractor_menu = new Gtk.Menu ();
63
64            GLib.FileInfo info = null;
65
66            try {
67                info = file.file.query_info (GLib.FileAttribute.STANDARD_CONTENT_TYPE, 0);
68            } catch (Error e) {
69                warning (e.message);
70            }
71
72            if (info != null) {
73                var file_type = info.get_attribute_string (GLib.FileAttribute.STANDARD_CONTENT_TYPE);
74
75                List<AppInfo> external_apps = GLib.AppInfo.get_all_for_type (file_type);
76
77                foreach (AppInfo app_info in external_apps) {
78                    if (app_info.get_id () == GLib.Application.get_default ().application_id + ".desktop") {
79                        continue;
80                    }
81
82                    var menuitem_icon = new Gtk.Image.from_gicon (app_info.get_icon (), Gtk.IconSize.MENU);
83                    menuitem_icon.pixel_size = 16;
84
85                    var menuitem_grid = new Gtk.Grid ();
86                    menuitem_grid.add (menuitem_icon);
87                    menuitem_grid.add (new Gtk.Label (app_info.get_name ()));
88
89                    var item_app = new Gtk.MenuItem ();
90                    item_app.add (menuitem_grid);
91
92                    item_app.activate.connect (() => {
93                        launch_app_with_file (app_info, file.file);
94                    });
95                    open_in_menu.add (item_app);
96                }
97
98                try {
99                    var contracts = Granite.Services.ContractorProxy.get_contracts_by_mime (file_type);
100                    foreach (var contract in contracts) {
101                        var menu_item = new ContractMenuItem (contract, file.file);
102                        contractor_menu.append (menu_item);
103                        menu_item.show_all ();
104                    }
105                } catch (Error e) {
106                    warning (e.message);
107                }
108            }
109
110            open_in_menu.add (new Gtk.SeparatorMenuItem ());
111            open_in_menu.add (other_menuitem);
112
113            var open_in_item = new Gtk.MenuItem.with_label (_("Open In"));
114            open_in_item.submenu = open_in_menu;
115
116            var contractor_item = new Gtk.MenuItem.with_label (_("Other Actions"));
117            contractor_item.submenu = contractor_menu;
118
119            var rename_item = new Gtk.MenuItem.with_label (_("Rename"));
120            rename_item.activate.connect (() => {
121                view.ignore_next_select = true;
122                view.start_editing_item (this);
123            });
124
125            var delete_item = new Gtk.MenuItem.with_label (_("Move to Trash"));
126            delete_item.activate.connect (trash);
127
128            var menu = new Gtk.Menu ();
129            menu.append (open_in_item);
130            menu.append (contractor_item);
131            menu.append (new Gtk.SeparatorMenuItem ());
132            menu.append (rename_item);
133            menu.append (delete_item);
134            menu.show_all ();
135
136            return menu;
137        }
138    }
139}
140