.
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 override void draw (WidgetAllocation allocation, Context cr) {
196 MainWindow.get_overview ().allocation = allocation;
197 base.draw (allocation, cr);
198 }
199
200 public static void load_font (string fn) {
201 Font font;
202 SaveDialogListener dialog = new SaveDialogListener ();
203
204 if (MenuTab.has_suppress_event ()) {
205 return;
206 }
207
208 font = BirdFont.get_current_font ();
209
210 MenuTab.load_callback = new LoadCallback ();
211 MenuTab.load_callback.file_loaded.connect (() => {
212 Font f;
213
214 if (MenuTab.has_suppress_event ()) {
215 warning ("Load font event suppressed.");
216 return;
217 }
218
219 f = BirdFont.get_current_font ();
220
221 MainWindow.get_drawing_tools ().remove_all_grid_buttons ();
222 foreach (string v in f.grid_width) {
223 MainWindow.get_drawing_tools ().parse_grid (v);
224 }
225
226 DrawingTools.background_scale.set_value (f.background_scale);
227 KerningTools.update_kerning_classes ();
228 MenuTab.apply_font_setting (f);
229
230 MenuTab.show_default_characters ();
231 MainWindow.get_overview ().selected_canvas ();
232 });
233
234 dialog.signal_discard.connect (() => {
235 Font f;
236
237 if (MenuTab.has_suppress_event ()) {
238 return;
239 }
240
241 f = BirdFont.new_font ();
242
243 MainWindow.clear_glyph_cache ();
244 MainWindow.close_all_tabs ();
245
246 f.set_file (fn);
247 Preferences.add_recent_files (fn);
248
249 MainWindow.native_window.load (); // background thread
250 });
251
252 dialog.signal_save.connect (() => {
253 if (MenuTab.has_suppress_event ()) {
254 warn_if_test ("Event suppressed.");
255 return;
256 }
257
258 MenuTab.set_save_callback (new SaveCallback ());
259 MenuTab.save_callback.file_saved.connect (() => {
260 dialog.signal_discard ();
261 });
262 MenuTab.save_callback.save (); // background thread
263 });
264
265 dialog.signal_cancel.connect (() => {
266 MainWindow.hide_dialog ();
267 });
268
269 if (!font.is_modified ()) {
270 dialog.signal_discard ();
271 } else {
272 MainWindow.show_dialog (new SaveDialog (dialog));
273 }
274 }
275 }
276
277 }
278