~elementary-apps/pantheon-files/trunk

« back to all changes in this revision

Viewing changes to filechooser-module/FileChooserDialog.vala

  • Committer: RabbitBot
  • Author(s): Corentin Noël
  • Date: 2016-04-13 22:08:46 UTC
  • mfrom: (2107.2.1 pantheon-files)
  • Revision ID: rabbitbot-20160413220846-fg1ouup2q237vroq
Update Gtk.FileChooserDialog plugin for Loki

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
 */
21
21
 
22
22
public class CustomFileChooserDialog : Object {
23
 
    private static Gtk.FileChooser chooser;
24
 
 
25
 
    private static Gtk.FileChooserDialog d;
 
23
    private static Gtk.FileChooserDialog chooser_dialog;
26
24
    private static Gtk.Widget rootwidget;
27
25
    
28
26
    private static Gtk.Box container_box;
29
27
    private static Gtk.Button? gtk_folder_button = null;
30
28
 
31
29
    /* Response to get parent of the bottom box */
32
 
    private const int BUTTON_RESPONSE = -6;    
 
30
    private const int BUTTON_RESPONSE = -6;
33
31
 
34
32
    /* Paths to widgets */
35
 
    private const string[] GTK_PATHBAR_PATH = { "widget", "browse_widgets_box", "browse_files_box", "browse_header_box" };
 
33
    private const string[] GTK_PATHBAR_PATH = { "widget", "browse_widgets_box", "browse_files_box", "browse_header_revealer" };
36
34
    private const string[] GTK_FILTERCHOOSER_PATH = { "extra_and_filters", "filter_combo_hbox" };
37
 
    private const string[] GTK_CREATEFOLDER_BUTTON_PATH = { "browse_header_stack", "browse_path_bar_hbox", "browse_new_folder_button" };
38
35
    private const string PLACES_SIDEBAR_PATH = "places_sidebar";
39
36
 
40
 
    private const string FILE_PREFIX = "file://";
41
 
 
42
 
    private GenericArray<string> forward_path_list = new GenericArray<string> ();
43
 
    private Gee.ArrayList<string> history  = new Gee.ArrayList<string> ();
44
 
 
45
 
    private static bool filters_available = false;
46
 
 
47
 
    private static string open_path;
48
 
    private string previous_path = "";
49
 
 
50
 
    public CustomFileChooserDialog (Gtk.FileChooserDialog _dialog) {
51
 
        /* The "d" variable is the main dialog */
52
 
        d = _dialog;
53
 
        d.can_focus = true;
54
 
        
55
 
        /* Main FileChooser interface */
56
 
        chooser = (d as Gtk.FileChooser);
57
 
 
58
 
        d.deletable = false;
 
37
    private GLib.Queue<string> previous_paths;
 
38
    private GLib.Queue<string> next_paths;
 
39
 
 
40
    private bool filters_available = false;
 
41
 
 
42
    private string current_path = null;
 
43
    private bool is_previous = false;
 
44
    private bool is_button_next = false;
 
45
 
 
46
    public CustomFileChooserDialog (Gtk.FileChooserDialog dialog) {
 
47
        previous_paths = new GLib.Queue<string> ();
 
48
        next_paths = new GLib.Queue<string> ();
 
49
        /* The "chooser_dialog" variable is the main dialog */
 
50
        chooser_dialog = dialog;
 
51
        chooser_dialog.can_focus = true;
 
52
        chooser_dialog.deletable = false;
 
53
 
59
54
        assign_container_box ();
 
55
        remove_gtk_widgets ();
60
56
        setup_filter_box ();
61
 
        remove_gtk_widgets ();
62
57
 
63
58
        var header_bar = new Gtk.HeaderBar ();
64
 
        
 
59
 
65
60
        var button_back = new Gtk.Button.from_icon_name ("go-previous-symbolic", Gtk.IconSize.LARGE_TOOLBAR);
66
61
        button_back.tooltip_text = _("Previous");
67
62
        button_back.sensitive = false;
68
 
        
 
63
 
69
64
        var button_forward = new Gtk.Button.from_icon_name ("go-next-symbolic", Gtk.IconSize.LARGE_TOOLBAR);
70
65
        button_forward.tooltip_text = _("Next");
71
66
        button_forward.sensitive = false;
72
67
 
73
68
        var location_bar = new Marlin.View.Chrome.BasicLocationBar ();
74
 
        location_bar.set_display_path (FILE_PREFIX + chooser.get_current_folder ());
 
69
        location_bar.set_display_path (chooser_dialog.get_current_folder_uri ());
75
70
        location_bar.hexpand = true;
76
71
 
77
72
        header_bar.pack_start (button_back);
78
73
        header_bar.pack_start (button_forward);
79
74
        header_bar.pack_start (location_bar);
80
 
        if ((gtk_folder_button != null) && (chooser.get_action () != Gtk.FileChooserAction.OPEN)) {
81
 
            var create_folder_button = new Gtk.Button.from_icon_name ("folder-new", Gtk.IconSize.LARGE_TOOLBAR);
82
 
            create_folder_button.set_tooltip_text (_("Create folder"));
83
 
            create_folder_button.clicked.connect (() => {
84
 
                gtk_folder_button.clicked ();
85
 
            });
86
 
 
87
 
            header_bar.pack_end (create_folder_button);
 
75
        if ((gtk_folder_button != null) && (chooser_dialog.get_action () != Gtk.FileChooserAction.OPEN)) {
 
76
            gtk_folder_button.image = new Gtk.Image.from_icon_name ("folder-new", Gtk.IconSize.LARGE_TOOLBAR);
 
77
            ((Gtk.Container) gtk_folder_button.get_parent ()).remove (gtk_folder_button);
 
78
            header_bar.pack_end (gtk_folder_button);
88
79
        }
89
80
 
90
 
        d.set_titlebar (header_bar);
91
 
        d.show_all ();
92
 
        
 
81
        chooser_dialog.set_titlebar (header_bar);
 
82
        chooser_dialog.show_all ();
 
83
 
93
84
        button_back.clicked.connect (() => {
94
 
            forward_path_list.add (chooser.get_current_folder ());
95
 
            
96
 
            history.remove (history.last ());
97
 
            chooser.set_current_folder (history.last ()); 
98
 
            history.remove (history.last ());
 
85
            is_previous = true;
 
86
            chooser_dialog.set_current_folder_uri (previous_paths.pop_head ());
99
87
        });
100
88
 
101
89
        button_forward.clicked.connect (() => {
102
 
            if (forward_path_list.length > 0) {
103
 
                int length = forward_path_list.length - 1;
104
 
                
105
 
                location_bar.set_display_path (FILE_PREFIX + forward_path_list.@get (length));
106
 
                chooser.set_current_folder (forward_path_list.@get (length));
107
 
                forward_path_list.remove (forward_path_list.@get (length));
108
 
            }
109
 
        });
110
 
 
111
 
        chooser.current_folder_changed.connect (() => {
112
 
            if (history.size > 0)
113
 
                previous_path = history.last (); 
114
 
            else if (open_path != chooser.get_current_folder ()) {
115
 
                previous_path = "";
116
 
                history.add (open_path);
117
 
            }
118
 
 
119
 
            button_back.sensitive = (history.size > 0);
120
 
            button_forward.sensitive = (forward_path_list.length > 0);
121
 
 
122
 
            if (chooser.get_current_folder () != previous_path)
123
 
                history.add (chooser.get_current_folder ());
124
 
 
125
 
            location_bar.set_display_path (FILE_PREFIX + chooser.get_current_folder ());
126
 
        });
127
 
        
 
90
            is_button_next = true;
 
91
            chooser_dialog.set_current_folder_uri (next_paths.pop_head ());
 
92
        });
 
93
 
 
94
        chooser_dialog.current_folder_changed.connect (() => {
 
95
            var previous_path = current_path;
 
96
            current_path = chooser_dialog.get_current_folder_uri ();
 
97
            if (previous_path == null || previous_path == current_path) {
 
98
                location_bar.set_display_path (current_path);
 
99
                return;
 
100
            }
 
101
 
 
102
            if (is_previous) {
 
103
                next_paths.push_head (previous_path);
 
104
                is_previous = false;
 
105
            } else {
 
106
                previous_paths.push_head (previous_path);
 
107
                if (!is_button_next) {
 
108
                    next_paths.clear ();
 
109
                } else {
 
110
                    is_button_next = false;
 
111
                }
 
112
            }
 
113
 
 
114
            button_back.sensitive = !previous_paths.is_empty ();
 
115
            button_forward.sensitive = !next_paths.is_empty ();
 
116
            location_bar.set_display_path (current_path);
 
117
        });
 
118
 
128
119
        location_bar.path_change_request.connect ((uri) => {
129
 
            chooser.set_current_folder (uri);
 
120
            chooser_dialog.set_current_folder (uri);
130
121
        });
131
122
    }
132
123
 
133
 
    public void set_open_path (string _open_path) {
134
 
        open_path = _open_path;
135
 
        previous_path = open_path;
136
 
        chooser.set_current_folder (open_path);
137
 
    }
 
124
    /*
 
125
     * Playing with the native Gtk dialog.
 
126
     */
138
127
 
139
128
    /* Remove GTK's native path bar and FileFilter chooser by widgets names */
140
 
    private static void remove_gtk_widgets () {
141
 
        foreach (var root in d.get_children ()) {
142
 
            foreach (var w0 in (root as Gtk.Container).get_children ()) {
 
129
    private void remove_gtk_widgets () {
 
130
        chooser_dialog.get_children ().foreach ((root) => {
 
131
            (root as Gtk.Container).get_children ().foreach ((w0) => {
143
132
                if (w0.get_name () == GTK_PATHBAR_PATH[0]) {
144
133
                    /* Add top separator between headerbar and filechooser when is not Save action */
145
134
                        var chooserwidget = w0 as Gtk.Container;
150
139
                        root_box.add (new Gtk.Separator (Gtk.Orientation.HORIZONTAL));
151
140
                        root_box.add (chooserwidget); 
152
141
 
153
 
                        if (chooser.get_extra_widget () == null)
154
 
                            root_box.add (new Gtk.Separator (Gtk.Orientation.HORIZONTAL));   
155
 
                                                 
 
142
                        if (chooser_dialog.get_extra_widget () == null) {
 
143
                            root_box.add (new Gtk.Separator (Gtk.Orientation.HORIZONTAL));
 
144
                        }
 
145
 
156
146
                        (root as Gtk.Container).add (root_box);
157
147
                        rootwidget = chooserwidget;
158
148
                        rootwidget = w0;
159
149
                        rootwidget.can_focus = true;
160
150
                        transform_rootwidget_container (rootwidget, w0);
161
151
                }
162
 
            }  
163
 
        }   
 
152
            });
 
153
        });
164
154
    }
165
155
 
166
 
    private static void transform_rootwidget_container (Gtk.Widget rootwidget, Gtk.Widget w0) {
167
 
        foreach (var w1 in (rootwidget as Gtk.Container).get_children ()) {
 
156
    private void transform_rootwidget_container (Gtk.Widget rootwidget, Gtk.Widget w0) {
 
157
        (rootwidget as Gtk.Container).get_children ().foreach ((w1) => {
168
158
            if (w1.name == "GtkBox" && w1.get_name () != GTK_PATHBAR_PATH[1]) {
169
 
                var new_w1 = w1.@ref ();
 
159
                w1.ref ();
170
160
                (rootwidget as Gtk.Container).remove (w1);
171
161
 
172
 
                foreach (var grid in (new_w1 as Gtk.Container).get_children ()) {
173
 
                    if (grid != null) {
174
 
                        var new_grid = grid.@ref ();
175
 
                        (new_grid as Gtk.Widget).margin = 0;
176
 
                        (new_w1 as Gtk.Container).remove (grid);
177
 
                        container_box.add (new_grid as Gtk.Widget);
178
 
                    }
179
 
                } 
180
 
                       
 
162
                (w1 as Gtk.Container).get_children ().foreach ((grid) => {
 
163
                    grid.ref ();
 
164
                    grid.margin = 0;
 
165
                    grid.valign = Gtk.Align.CENTER;
 
166
                    ((Gtk.Container) grid).border_width = 0;
 
167
                    (w1 as Gtk.Container).remove (grid);
 
168
                    container_box.pack_start (grid);
 
169
                    ((Gtk.ButtonBox) container_box).set_child_secondary (grid, true);
 
170
                    grid.unref ();
 
171
                });
 
172
 
 
173
                w1.unref ();
181
174
                container_box.show_all ();
182
 
            } else if (w1.get_name () == GTK_PATHBAR_PATH[1])
 
175
            } else if (w1.get_name () == GTK_PATHBAR_PATH[1]) {
183
176
                transform_w1_container (w1);
184
 
            else {
 
177
            } else {
185
178
                if (w1.get_name () == GTK_FILTERCHOOSER_PATH[0]) {
186
179
                    /* Remove extra_and_filters if there is no extra widget */
187
 
                    if (chooser.get_extra_widget () == null)
 
180
                    if (chooser_dialog.get_extra_widget () == null) {
188
181
                        (w0 as Gtk.Container).remove (w1);
189
 
                    else {
190
 
                        foreach (var w5 in (w1 as Gtk.Container).get_children ()) {
 
182
                    } else {
 
183
                        (w1 as Gtk.Container).get_children ().foreach ((w5) => {
191
184
                            if (w5.get_name () == GTK_FILTERCHOOSER_PATH[1])
192
185
                               (w1 as Gtk.Container).remove (w5);
193
 
                        }
 
186
                        });
194
187
                    }
195
188
                }
196
 
            }   
197
 
        }
 
189
            }
 
190
        });
198
191
    }
199
192
 
200
 
    private static void transform_w1_container (Gtk.Widget w1) {
201
 
        foreach (var paned in (w1 as Gtk.Container).get_children ()) {
202
 
            foreach (var w2 in (paned as Gtk.Container).get_children ()) {
203
 
                if (w2.get_name () == PLACES_SIDEBAR_PATH) {
 
193
    private void transform_w1_container (Gtk.Widget w1) {
 
194
        (w1 as Gtk.Container).get_children ().foreach ((paned) => {
 
195
            (paned as Gtk.Container).get_children ().foreach ((w2) => {
 
196
                if (w2 is Gtk.PlacesSidebar) {
204
197
                    (w2 as Gtk.PlacesSidebar).show_desktop = false; 
205
198
                    (w2 as Gtk.PlacesSidebar).show_enter_location = false;
206
 
                } else if (w2.get_name () == GTK_PATHBAR_PATH[2])
207
 
                    transform_w2_container (w2);   
208
 
            }
209
 
        }
 
199
                } else {
 
200
                    transform_w2_container (w2);
 
201
                }
 
202
            });
 
203
        });
210
204
    }
211
205
 
212
 
    private static void transform_w2_container (Gtk.Widget w2) {
213
 
        foreach (var w3 in (w2 as Gtk.Container).get_children ()) {
 
206
    private void transform_w2_container (Gtk.Widget w2) {
 
207
        (w2 as Gtk.Container).get_children ().foreach ((w3) => {
214
208
            if (w3.get_name () == GTK_PATHBAR_PATH[3]) {
215
 
                foreach (var w4 in (w3 as Gtk.Container).get_children ()) {
216
 
                    if (w4.get_name () == GTK_CREATEFOLDER_BUTTON_PATH[0]) {
217
 
                        foreach (var w5 in (w4 as Gtk.Container).get_children ()) {
218
 
                            if (w5.get_name () == GTK_CREATEFOLDER_BUTTON_PATH[1]) {
219
 
                                foreach (var w6 in (w5 as Gtk.Container).get_children ()) {
220
 
                                    if (w6.get_name () == GTK_CREATEFOLDER_BUTTON_PATH[2])
 
209
                (w3 as Gtk.Container).get_children ().foreach ((w4) => {
 
210
                    (w4 as Gtk.Container).get_children ().foreach ((w5) => {
 
211
                        (w5 as Gtk.Container).get_children ().foreach ((w6) => {
 
212
                            if (w6 is Gtk.Box) {
 
213
                                (w6 as Gtk.Container).get_children ().foreach ((w7) => {
 
214
                                    if (w7 is Gtk.Button) {
221
215
                                        /* Register the button so we can use it's signal */
222
 
                                        gtk_folder_button = w6.@ref () as Gtk.Button;
223
 
                                }   
 
216
                                        gtk_folder_button = w7 as Gtk.Button;
 
217
                                    }
 
218
                                });
224
219
                            }
225
 
                        }
226
 
                    }
227
 
                }
 
220
                        });
 
221
                    });
 
222
                });
228
223
 
229
224
                (w2 as Gtk.Container).remove (w3);
230
225
            }
231
 
        }        
232
 
    }
233
 
 
234
 
    private static void assign_container_box () {
235
 
        var tmp = d.get_widget_for_response (BUTTON_RESPONSE);
236
 
 
237
 
        var container = tmp.get_parent ();
238
 
        container_box = container.get_parent () as Gtk.Box;           
239
 
    }
240
 
    
241
 
    private static void setup_filter_box () {
242
 
        var filters = chooser.list_filters ();
243
 
        var current_filter_name = chooser.get_filter ().get_filter_name ();
 
226
        });
 
227
    }
 
228
 
 
229
    private void assign_container_box () {
 
230
        container_box = chooser_dialog.get_action_area () as Gtk.Box;
 
231
        container_box.valign = Gtk.Align.CENTER;
 
232
        container_box.get_children ().foreach ((child) => {
 
233
            child.valign = Gtk.Align.CENTER;
 
234
        });
 
235
    }
 
236
 
 
237
    private void setup_filter_box () {
 
238
        var filters = chooser_dialog.list_filters ();
 
239
        var current_filter_name = chooser_dialog.get_filter ().get_filter_name ();
244
240
 
245
241
        if (filters.length () > 0) {
246
242
            filters_available = true;
247
243
            var combo_box = new Gtk.ComboBoxText ();
248
 
            
249
 
            if (chooser.get_action () == Gtk.FileChooserAction.SAVE)
250
 
                combo_box.margin_top = 8;
251
 
            else    
252
 
                combo_box.margin_top = 4;
253
 
                
254
244
            combo_box.changed.connect (() => {
255
 
                chooser.list_filters ().@foreach ((filter) => {
 
245
                chooser_dialog.list_filters ().foreach ((filter) => {
256
246
                    if (filter.get_filter_name () == combo_box.get_active_text ())
257
 
                        chooser.set_filter (filter);
 
247
                        chooser_dialog.set_filter (filter);
258
248
                });
259
249
            });
260
250
 
265
255
                if (name == current_filter_name) {
266
256
                    combo_box.active = index;
267
257
                }
 
258
 
268
259
                index++;
269
260
            });
270
261
 
271
262
            var grid = new Gtk.Grid ();
272
 
            grid.margin_start = 5;
 
263
            grid.valign = Gtk.Align.CENTER;
273
264
            grid.add (combo_box);
274
 
            container_box.add (grid);   
 
265
            container_box.pack_end (grid);
 
266
            ((Gtk.ButtonBox) container_box).set_child_secondary (grid, true);
275
267
        }
276
268
    }
277
269
}