The Birdfont Source Code


All Repositories / birdfont.git / blob – RSS feed

FileDialogTab.vala in libbirdfont

This file is a part of the Birdfont project.

Contributing

Send patches or pull requests to johan.mattsson.m@gmail.com.
Clone this repository: git clone https://github.com/johanmattssonm/birdfont.git

Revisions

View the latest version of libbirdfont/FileDialogTab.vala.
Fix file chooser on Windows
1 /* 2 Copyright (C) 2014 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 using Cairo; 15 using Math; 16 17 namespace BirdFont { 18 19 public class FileDialogTab : Table { 20 Gee.ArrayList<Row> rows; 21 22 const int DIRECTORY = -3; 23 const int FILE = -2; 24 25 Gee.ArrayList<string> files; 26 Gee.ArrayList<string> directories; 27 28 string title; 29 FileChooser action; 30 31 File current_dir; 32 33 string selected_filename; 34 TextListener listener; 35 36 private static bool has_drive_letters = false; 37 private static Gee.ArrayList<string> drive_letters; 38 39 public FileDialogTab (string title, FileChooser action) { 40 this.title = title; 41 this.action = action; 42 43 rows = new Gee.ArrayList<Row> (); 44 files = new Gee.ArrayList<string> (); 45 directories = new Gee.ArrayList<string> (); 46 47 selected_filename = ""; 48 selected_canvas (); 49 } 50 51 public static void add_drive_letter (char c) { 52 if (!has_drive_letters) { 53 drive_letters = new Gee.ArrayList<string> (); 54 has_drive_letters = true; 55 } 56 57 drive_letters.add (@"$((!) c.to_string ()):\\"); 58 } 59 60 public override void update_rows () { 61 Row row; 62 63 rows.clear (); 64 65 // add empty rows under the text area 66 row = new Row.headline (""); 67 rows.add (row); 68 69 if (directories.size > 0) { 70 row = new Row.headline (t_("Folders")); 71 rows.add (row); 72 } 73 74 foreach (string dir in directories) { 75 row = new Row.columns_1 (dir, DIRECTORY, false); 76 row.set_row_data (new SelectedFile (dir)); 77 rows.add (row); 78 } 79 80 if (files.size > 0) { 81 row = new Row.headline (t_("Files")); 82 rows.add (row); 83 } 84 85 foreach (string f in files) { 86 row = new Row.columns_1 (f, FILE, false); 87 row.set_row_data (new SelectedFile (f)); 88 rows.add (row); 89 } 90 91 GlyphCanvas.redraw (); 92 } 93 94 public override Gee.ArrayList<Row> get_rows () { 95 return rows; 96 } 97 98 public override void selected_row (Row row, int column, bool delete_button) { 99 SelectedFile f; 100 101 if (row.get_index () == FILE) { 102 return_if_fail (row.get_row_data () is SelectedFile); 103 f = (SelectedFile) row.get_row_data (); 104 selected_filename = f.file_name; 105 } else if (row.get_index () == DIRECTORY) { 106 return_if_fail (row.get_row_data () is SelectedFile); 107 f = (SelectedFile) row.get_row_data (); 108 selected_filename = ""; 109 propagate_files (f.file_name); 110 } 111 112 show_text_area (selected_filename); 113 } 114 115 public override void selected_canvas () { 116 string d; 117 show_text_area (""); 118 119 d = Preferences.get ("file_dialog_dir"); 120 121 if (d == "") { 122 d = Environment.get_home_dir (); 123 } 124 125 propagate_files (d); 126 base.selected_canvas (); 127 } 128 129 public void propagate_files (string dir) { 130 FileEnumerator enumerator; 131 FileInfo? file_info; 132 string fn; 133 134 files.clear (); 135 directories.clear (); 136 137 current_dir = File.new_for_path (dir); 138 139 Preferences.set ("file_dialog_dir", dir); 140 141 if (current_dir.get_parent () != null) { 142 directories.add (".."); 143 } 144 145 try { 146 enumerator = current_dir.enumerate_children (FileAttribute.STANDARD_NAME + "," + FileAttribute.STANDARD_TYPE, 0); 147 148 while ((file_info = enumerator.next_file ()) != null) { 149 fn = ((!)file_info).get_name (); 150 if (!fn.has_prefix (".")) { 151 if (((!)file_info).get_file_type () == FileType.DIRECTORY) { 152 directories.add (fn); 153 } else { 154 files.add (fn); 155 } 156 } 157 } 158 } catch (Error e) { 159 warning (e.message); 160 } 161 162 directories.sort (); 163 164 if (has_drive_letters) { 165 for (int i = drive_letters.size - 1; i >= 0; i--) { 166 directories.insert (0, drive_letters.get (i)); 167 } 168 } 169 170 files.sort (); 171 172 layout (); 173 base.selected_canvas (); 174 } 175 176 public void show_text_area (string text) { 177 listener = new TextListener ("", text, this.title); 178 179 listener.signal_text_input.connect ((text) => { 180 selected_filename = text; 181 }); 182 183 listener.signal_submit.connect (() => { 184 File f; 185 186 MainWindow.get_tab_bar ().close_display (this); 187 188 if (selected_filename == "") { 189 action.cancel (); 190 } else { 191 f = get_child (current_dir, selected_filename); 192 action.file_selected ((!)f.get_path ()); 193 } 194 }); 195 196 TabContent.show_text_input (listener); 197 } 198 199 public override void double_click (uint button, double ex, double ey) { 200 File f; 201 202 button_release ((int) button, ex, ey); 203 204 if (is_null (selected_filename)) { 205 warning ("No file."); 206 return; 207 } 208 209 if (selected_filename != "") { 210 f = get_child (current_dir, selected_filename); 211 action.file_selected ((!) f.get_path ()); 212 } 213 } 214 215 public override string get_label () { 216 return title; 217 } 218 219 public override string get_name () { 220 return "FileDialogTab"; 221 } 222 223 public override void button_release (int button, double ex, double ey) { 224 base.button_release (button, ex, ey); 225 show_text_area (selected_filename); 226 } 227 228 class SelectedFile : GLib.Object { 229 public string file_name; 230 231 public SelectedFile (string fn) { 232 file_name = fn; 233 } 234 } 235 } 236 237 } 238