1/*
2 * This file is part of GNOME LaTeX.
3 *
4 * Copyright © 2012, 2017 Sébastien Wilmet
5 *
6 * GNOME LaTeX is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * GNOME LaTeX is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with GNOME LaTeX.  If not, see <http://www.gnu.org/licenses/>.
18 *
19 * Author: Sébastien Wilmet
20 */
21
22using Gtk;
23
24// The File menu of a MainWindow
25
26public class MainWindowFile
27{
28    private const Gtk.ActionEntry[] _action_entries =
29    {
30        { "File", null, N_("_File") },
31
32        { "FileNew", "document-new", N_("_New"), "<Control>N",
33            N_("New file"), on_file_new },
34
35        { "FileNewWindow", null, N_("New _Window"), null,
36            N_("Create a new window") },
37
38        { "FileOpen", "document-open", N_("_Open"), "<Control>O",
39            N_("Open a file"), on_file_open },
40
41        { "FileSave", "document-save", N_("_Save"), "<Control>S",
42            N_("Save the current file"), on_file_save },
43
44        { "FileSaveAs", "document-save-as", N_("Save _As"), "<Shift><Control>S",
45            N_("Save the current file with a different name"), on_file_save_as },
46
47        { "FileCreateTemplate", null, N_("Create _Template From Document…"), null,
48            N_("Create a new template from the current document"), on_create_template },
49
50        { "FileManageTemplates", null, N_("_Manage Personal Templates…"), null,
51            N_("Manage personal templates"), on_manage_templates },
52
53        { "FileClose", "window-close", N_("_Close"), "<Control>W",
54            N_("Close the current file"), on_file_close }
55    };
56
57    private unowned MainWindow _main_window;
58    private Gtk.ActionGroup _action_group;
59
60    public MainWindowFile (MainWindow main_window, UIManager ui_manager)
61    {
62        _main_window = main_window;
63
64        _action_group = new Gtk.ActionGroup ("FileMenuActionGroup");
65        _action_group.set_translation_domain (Config.GETTEXT_PACKAGE);
66        _action_group.add_actions (_action_entries, this);
67
68        // recent documents
69        Gtk.Action recent_action = new RecentAction ("FileOpenRecent", _("Open _Recent"),
70            _("Open recently used files"), "");
71        configure_recent_chooser (recent_action as RecentChooser);
72        _action_group.add_action (recent_action);
73
74        ui_manager.insert_action_group (_action_group, 0);
75
76        GlatexApp app = GlatexApp.get_instance ();
77        Amtk.utils_bind_g_action_to_gtk_action (app, "tepl-new-window",
78            _action_group, "FileNewWindow");
79    }
80
81    public ToolItem get_toolbar_open_button ()
82    {
83        RecentManager recent_manager = RecentManager.get_default ();
84        Widget recent_menu = new RecentChooserMenu.for_manager (recent_manager);
85        configure_recent_chooser (recent_menu as RecentChooser);
86
87        MenuToolButton open_button = new MenuToolButton (null, null);
88        open_button.icon_name = "document-open";
89        open_button.set_menu (recent_menu);
90        open_button.set_tooltip_text (_("Open a file"));
91        open_button.set_arrow_tooltip_text (_("Open a recently used file"));
92
93        Gtk.Action action = _action_group.get_action ("FileOpen");
94        open_button.set_related_action (action);
95
96        return open_button;
97    }
98
99    private void configure_recent_chooser (RecentChooser recent_chooser)
100    {
101        recent_chooser.set_local_only (false);
102        recent_chooser.set_show_tips (true);
103        recent_chooser.set_sort_type (RecentSortType.MRU);
104
105        RecentFilter filter = new RecentFilter ();
106        filter.add_application (Config.PACKAGE_NAME);
107        recent_chooser.set_filter (filter);
108
109        recent_chooser.item_activated.connect ((chooser) =>
110        {
111            string uri = chooser.get_current_uri ();
112            _main_window.open_document (File.new_for_uri (uri));
113        });
114    }
115
116    /* Sensitivity */
117
118    public void update_sensitivity ()
119    {
120        Tepl.ApplicationWindow tepl_window =
121            Tepl.ApplicationWindow.get_from_gtk_application_window (_main_window);
122        bool sensitive = tepl_window.active_tab != null;
123
124        string[] action_names =
125        {
126            "FileSave",
127            "FileSaveAs",
128            "FileClose",
129            "FileCreateTemplate"
130        };
131
132        foreach (string action_name in action_names)
133        {
134            Gtk.Action action = _action_group.get_action (action_name);
135            action.sensitive = sensitive;
136        }
137    }
138
139    /* Gtk.Action callbacks */
140
141    public void on_file_new ()
142    {
143        string contents = Latexila.templates_dialogs_open (_main_window);
144
145        if (contents != null)
146        {
147            DocumentTab tab = _main_window.create_tab (true);
148            tab.document.set_contents (contents);
149        }
150    }
151
152    public void on_file_open ()
153    {
154        FileChooserDialog file_chooser = new FileChooserDialog (_("Open Files"),
155            _main_window,
156            FileChooserAction.OPEN,
157            _("_Cancel"), ResponseType.CANCEL,
158            _("_Open"), ResponseType.ACCEPT
159        );
160
161        // Open in the directory of the current document
162        if (_main_window.active_document != null &&
163            _main_window.active_document.location != null)
164        {
165            File location = _main_window.active_document.location;
166            string dirname = location.get_parent ().get_path ();
167            file_chooser.set_current_folder (dirname);
168        }
169        else if (_main_window.default_location != null)
170            file_chooser.set_current_folder (_main_window.default_location);
171
172        file_chooser.set_local_only (false);
173        file_chooser.select_multiple = true;
174
175        // Filter: by default show only .tex and .bib files
176        FileFilter latex_filter = new FileFilter ();
177        latex_filter.set_filter_name (_("All LaTeX Files"));
178        latex_filter.add_pattern ("*.tex");
179        latex_filter.add_pattern ("*.bib");
180        file_chooser.add_filter (latex_filter);
181
182        // All files filter
183        FileFilter all_files_filter = new FileFilter ();
184        all_files_filter.set_filter_name (_("All Files"));
185        all_files_filter.add_pattern ("*");
186        file_chooser.add_filter (all_files_filter);
187
188        SList<File> files_to_open = null;
189        if (file_chooser.run () == ResponseType.ACCEPT)
190            files_to_open = file_chooser.get_files ();
191
192        _main_window.default_location = file_chooser.get_current_folder ();
193        file_chooser.destroy ();
194
195        // We open the files after closing the dialog, because open a lot of documents can
196        // take some time (this is not async).
197        bool jump_to = true;
198        foreach (File file in files_to_open)
199        {
200            _main_window.open_document (file, jump_to);
201            jump_to = false;
202        }
203    }
204
205    public void on_file_save ()
206    {
207        return_if_fail (_main_window.active_tab != null);
208        _main_window.save_document (_main_window.active_document, false);
209    }
210
211    public void on_file_save_as ()
212    {
213        return_if_fail (_main_window.active_tab != null);
214        _main_window.save_document (_main_window.active_document, true);
215    }
216
217    public void on_create_template ()
218    {
219        return_if_fail (_main_window.active_tab != null);
220
221        // get the template's contents
222        TextIter start;
223        TextIter end;
224        Document doc = _main_window.active_document;
225        doc.get_bounds (out start, out end);
226        string template_contents = doc.get_text (start, end, false);
227
228        Latexila.templates_dialogs_create_template (_main_window, template_contents);
229    }
230
231    public void on_manage_templates ()
232    {
233        Dialog dialog = new Latexila.TemplatesManageDialog (_main_window);
234        dialog.run ();
235        dialog.destroy ();
236    }
237
238    public void on_file_close ()
239    {
240        return_if_fail (_main_window.active_tab != null);
241        _main_window.close_tab (_main_window.active_tab);
242    }
243}
244