.
1 /*
2 Copyright (C) 2015 Johan Mattsson
3
4 This library is free software; you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as
6 published by the Free Software Foundation; either version 3 of the
7 License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful, but
10 WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
13 */
14
15 using Cairo;
16 using Math;
17
18 namespace BirdFont {
19
20 /** A list of recently edited fonts. */
21 public class RecentFiles : Table {
22 Gee.ArrayList<Row> rows = new Gee.ArrayList<Row> ();
23
24 const int NEW_FONT = -5;
25 const int CURRENT_FONT = -4;
26 const int RECENT_FONT = -3;
27 const int BACKUP = -2;
28
29 public RecentFiles () {
30 }
31
32 public override Gee.ArrayList<Row> get_rows () {
33 return rows;
34 }
35
36 public override void selected_row (Row row, int column, bool delete_button) {
37 Font f;
38
39 if (row.get_index () == NEW_FONT) {
40 MenuTab.new_file ();
41 MenuTab.select_overview ();
42 } else if (row.get_index () == RECENT_FONT) {
43 return_if_fail (row.get_row_data () is Font);
44 f = (Font) row.get_row_data ();
45 load_font (f.get_path ());
46 } else if (row.get_index () == BACKUP) {
47 return_if_fail (row.get_row_data () is Font);
48 f = (Font) row.get_row_data ();
49 delete_backup (f.get_file_name ());
50 }
51 }
52
53 public override void update_rows () {
54 Row row;
55 Gee.ArrayList<Font> recent_fonts = get_recent_font_files ();
56 Gee.ArrayList<Font> backups = get_backups ();
57 Font current_font = BirdFont.get_current_font ();
58
59 rows.clear ();
60
61 if (recent_fonts.size == 0) {
62 row = new Row.headline (t_("No fonts created yet"));
63 rows.add (row);
64
65 row = new Row.columns_1 (t_("Create a New Font"), NEW_FONT, false);
66 rows.add (row);
67 }
68
69 if (current_font.font_file != null) {
70 row = new Row.headline (current_font.get_file_name ());
71 rows.add (row);
72
73 row = new Row.columns_1 (t_("Folder") + ": " + (!) current_font.get_folder ().get_path (), CURRENT_FONT, false);
74 rows.add (row);
75
76 row = new Row.columns_1 (t_("Glyphs") + @": $(current_font.length ())", CURRENT_FONT, false);
77 rows.add (row);
78 }
79
80 if (recent_fonts.size > 0) {
81 row = new Row.headline (t_("Recent Files"));
82 rows.add (row);
83 }
84
85 foreach (Font font in recent_fonts) {
86 row = new Row.columns_1 (font.get_file_name (), RECENT_FONT, false);
87 row.set_row_data (font);
88 rows.add (row);
89 }
90
91 if (backups.size > 0) {
92 row = new Row.headline (t_("Backups"));
93 rows.add (row);
94 }
95
96 foreach (Font font in backups) {
97 row = new Row.columns_1 (font.get_file_name (), BACKUP, true);
98 row.set_row_data (font);
99 rows.add (row);
100 }
101
102 GlyphCanvas.redraw ();
103 }
104
105 public override string get_label () {
106 return t_("Files");
107 }
108
109 public override string get_name () {
110 return "Files";
111 }
112
113 public Gee.ArrayList<Font> get_recent_font_files () {
114 File file;
115 Font font;
116 bool unique;
117 Gee.ArrayList<Font> fonts = new Gee.ArrayList<Font> ();
118
119 foreach (string f in Preferences.get_recent_files ()) {
120 if (f == "") {
121 continue;
122 }
123
124 file = File.new_for_path (f);
125
126 font = new Font ();
127 font.set_font_file (f);
128
129 unique = true;
130 foreach (Font recent_font in fonts) {
131 if (recent_font.get_path () == f) {
132 unique = false;
133 }
134 }
135
136 if (unique && file.query_exists ()) {
137 fonts.insert (0, font);
138 }
139 }
140
141 return fonts;
142 }
143
144 public Gee.ArrayList<Font> get_backups () {
145 FileEnumerator enumerator;
146 string file_name;
147 FileInfo? file_info;
148 Gee.ArrayList<Font> backups = new Gee.ArrayList<Font> ();
149 File dir = BirdFont.get_backup_directory ();
150 Font font = BirdFont.get_current_font ();
151 Font backup_font;
152
153 try {
154 enumerator = dir.enumerate_children (FileAttribute.STANDARD_NAME, 0);
155 while ((file_info = enumerator.next_file ()) != null) {
156 file_name = ((!) file_info).get_name ();
157
158 // ignore old backup files
159 if (file_name.has_prefix ("current_font_")) {
160 continue;
161 }
162
163 // ignore backup of the current font
164 if (file_name == @"$(font.get_name ()).bf") {
165 continue;
166 }
167
168 backup_font = new Font ();
169 backup_font.set_font_file ((!) get_child (dir, file_name).get_path ());
170 backups.insert (0, backup_font);
171 }
172 } catch (Error e) {
173 warning (e.message);
174 }
175
176 return backups;
177 }
178
179 public void delete_backup (string file_name) {
180 File backup_file;
181
182 try {
183 backup_file = BirdFont.get_backup_directory ();
184 backup_file = get_child (backup_file, file_name);
185 if (backup_file.query_exists ()) {
186 backup_file.delete ();
187 }
188 } catch (GLib.Error e) {
189 warning (e.message);
190 }
191
192 selected_canvas ();
193 }
194
195 public static void load_font (string fn) {
196 Font font;
197 SaveDialogListener dialog = new SaveDialogListener ();
198
199 if (MenuTab.suppress_event) {
200 return;
201 }
202
203 font = BirdFont.get_current_font ();
204
205 MenuTab.load_callback = new LoadCallback ();
206 MenuTab.load_callback.file_loaded.connect (() => {
207 Font f;
208
209 if (MenuTab.suppress_event) {
210 return;
211 }
212
213 f = BirdFont.get_current_font ();
214
215 MainWindow.get_drawing_tools ().remove_all_grid_buttons ();
216 foreach (string v in f.grid_width) {
217 MainWindow.get_drawing_tools ().parse_grid (v);
218 }
219
220 DrawingTools.background_scale.set_value (f.background_scale);
221 KerningTools.update_kerning_classes ();
222 MenuTab.show_all_available_characters ();
223 });
224
225 MenuTab.load_callback.file_loaded.connect (() => {
226 Font f = BirdFont.get_current_font ();
227 MenuTab.set_font_setting_from_tools (f);
228 });
229
230 dialog.signal_discard.connect (() => {
231 Font f;
232
233 if (MenuTab.suppress_event) {
234 return;
235 }
236
237 f = BirdFont.new_font ();
238
239 MainWindow.clear_glyph_cache ();
240 MainWindow.close_all_tabs ();
241
242 f.set_file (fn);
243 Preferences.add_recent_files (fn);
244
245 MainWindow.native_window.load (); // background thread
246 });
247
248 dialog.signal_save.connect (() => {
249 if (MenuTab.suppress_event) {
250 warn_if_test ("Event suppressed.");
251 return;
252 }
253
254 MenuTab.set_save_callback (new SaveCallback ());
255 MenuTab.save_callback.file_saved.connect (() => {
256 dialog.signal_discard ();
257 });
258 MenuTab.save_callback.save (); // background thread
259 });
260
261 dialog.signal_cancel.connect (() => {
262 MainWindow.hide_dialog ();
263 });
264
265 if (!font.is_modified ()) {
266 dialog.signal_discard ();
267 } else {
268 MainWindow.show_dialog (new SaveDialog (dialog));
269 }
270 }
271 }
272
273 }
274