Merge lp:~jeremywootten/pantheon-files/refactor-location-bar-preparation into lp:~elementary-apps/pantheon-files/trunk
- refactor-location-bar-preparation
- Merge into trunk
Proposed by
Jeremy Wootten
Status: | Merged |
---|---|
Approved by: | Cody Garver |
Approved revision: | 1958 |
Merged at revision: | 1981 |
Proposed branch: | lp:~jeremywootten/pantheon-files/refactor-location-bar-preparation |
Merge into: | lp:~elementary-apps/pantheon-files/trunk |
Diff against target: |
1080 lines (+435/-101) 21 files modified
filechooser-module/CMakeLists.txt (+2/-2) libcore/AbstractSlot.vala (+1/-0) libcore/CMakeLists.txt (+5/-0) libcore/DndHandler.vala (+2/-2) libcore/Enums.vala (+7/-0) libwidgets/CMakeLists.txt (+17/-3) libwidgets/Chrome/TopMenu.vala (+27/-13) libwidgets/Chrome/ViewSwicher.vala (+0/-3) libwidgets/Chrome/ViewWindowInterface.vala (+35/-0) libwidgets/Chrome/Viewable.vala (+32/-0) libwidgets/Dialogs/ChooseAppDialog.vala (+62/-0) libwidgets/FileUtils.vala (+149/-0) libwidgets/LocationBar.vala (+16/-18) libwidgets/SearchResults.vala (+4/-9) src/CMakeLists.txt (+1/-24) src/View/AbstractDirectoryView.vala (+13/-19) src/View/Miller.vala (+4/-0) src/View/Sidebar.vala (+1/-1) src/View/Slot.vala (+5/-0) src/View/ViewContainer.vala (+8/-3) src/View/Window.vala (+44/-4) |
To merge this branch: | bzr merge lp:~jeremywootten/pantheon-files/refactor-location-bar-preparation |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
elementary Apps team | Pending | ||
Review via email: mp+273316@code.launchpad.net |
Commit message
Move TopMenu widgets into libwidgets and some supporting classes into libcore
Description of the change
This branch is the first of a series aimed at refactoring the location bar in particular and the topmenu in general. The intention is to make these widgets self-contained and testable with defined interfaces. See lp:~jeremywootten/pantheon-files/experimental-refactor-fix-1461060-browser-like-search for the (almost) final version. The refactored location bar will have a more browser-like search behaviour. A separate LocationBarChooser widget will not be needed.
This branch moves the existing topmenu widgets into libwidgets but does not changes their behaviour. Consequential changes are made so that they still work.
The linked bug is fixed in passing.
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'filechooser-module/CMakeLists.txt' |
2 | --- filechooser-module/CMakeLists.txt 2015-10-01 08:43:51 +0000 |
3 | +++ filechooser-module/CMakeLists.txt 2015-11-14 13:22:20 +0000 |
4 | @@ -9,8 +9,8 @@ |
5 | |
6 | vala_precompile (VALA_C ${MODULE_NAME} |
7 | ${CMAKE_SOURCE_DIR}/libwidgets/Resources.vala |
8 | - ${CMAKE_SOURCE_DIR}/libwidgets/LocationBar.vala |
9 | - ${CMAKE_SOURCE_DIR}/libwidgets/BreadcrumbsElements.vala |
10 | + ${CMAKE_SOURCE_DIR}/libwidgets/Chrome/LocationBar.vala |
11 | + ${CMAKE_SOURCE_DIR}/libwidgets/Chrome/BreadcrumbsElements.vala |
12 | LocationBarChooser.vala |
13 | FileChooserDialog.vala |
14 | Plugin.vala |
15 | |
16 | === modified file 'libcore/AbstractSlot.vala' |
17 | --- libcore/AbstractSlot.vala 2015-07-24 08:01:21 +0000 |
18 | +++ libcore/AbstractSlot.vala 2015-11-14 13:22:20 +0000 |
19 | @@ -65,6 +65,7 @@ |
20 | |
21 | public abstract unowned GLib.List<unowned GOF.File>? get_selected_files (); |
22 | public abstract void set_active_state (bool set_active); |
23 | + public abstract void set_frozen_state (bool is_frozen); |
24 | public abstract unowned AbstractSlot? get_current_slot (); |
25 | public abstract void reload (bool non_local_only = false); |
26 | public abstract void grab_focus (); |
27 | |
28 | === renamed file 'src/Bookmark.vala' => 'libcore/Bookmark.vala' |
29 | === renamed file 'src/BookmarkList.vala' => 'libcore/BookmarkList.vala' |
30 | === modified file 'libcore/CMakeLists.txt' |
31 | --- libcore/CMakeLists.txt 2015-05-03 06:44:42 +0000 |
32 | +++ libcore/CMakeLists.txt 2015-11-14 13:22:20 +0000 |
33 | @@ -16,6 +16,11 @@ |
34 | vala_precompile(VALA_C ${PKGNAME} |
35 | AbstractSidebar.vala |
36 | AbstractSlot.vala |
37 | + Bookmark.vala |
38 | + BookmarkList.vala |
39 | + DndHandler.vala |
40 | + Enums.vala |
41 | + MimeActions.vala |
42 | gof-callwhenready.vala |
43 | gof-directory-async.vala |
44 | gof-preferences.vala |
45 | |
46 | === renamed file 'src/DndHandler.vala' => 'libcore/DndHandler.vala' |
47 | --- src/DndHandler.vala 2015-07-03 13:48:11 +0000 |
48 | +++ libcore/DndHandler.vala 2015-11-14 13:22:20 +0000 |
49 | @@ -19,7 +19,7 @@ |
50 | Authors: Jeremy Wootten <jeremy@elementaryos.org> |
51 | ***/ |
52 | |
53 | -namespace FM { |
54 | +namespace Marlin { |
55 | public class DndHandler : GLib.Object { |
56 | Gdk.DragAction chosen = Gdk.DragAction.DEFAULT; |
57 | |
58 | @@ -249,7 +249,7 @@ |
59 | public bool selection_data_is_uri_list (Gtk.SelectionData selection_data, uint info, out string? text) { |
60 | text = null; |
61 | |
62 | - if (info == AbstractDirectoryView.TargetType.TEXT_URI_LIST && |
63 | + if (info == Marlin.TargetType.TEXT_URI_LIST && |
64 | selection_data.get_format () == 8 && |
65 | selection_data.get_length () > 0) { |
66 | |
67 | |
68 | === renamed file 'src/Enums.vala' => 'libcore/Enums.vala' |
69 | --- src/Enums.vala 2015-08-17 08:16:55 +0000 |
70 | +++ libcore/Enums.vala 2015-11-14 13:22:20 +0000 |
71 | @@ -142,4 +142,11 @@ |
72 | assert_not_reached (); |
73 | } |
74 | } |
75 | + |
76 | + public enum TargetType { |
77 | + STRING, |
78 | + TEXT_URI_LIST, |
79 | + XDND_DIRECT_SAVE0, |
80 | + NETSCAPE_URL |
81 | + } |
82 | } |
83 | |
84 | === renamed file 'src/MimeActions.vala' => 'libcore/MimeActions.vala' |
85 | === added directory 'libwidgets/Animations' |
86 | === renamed file 'libwidgets/Animations.vala' => 'libwidgets/Animations/Animations.vala' |
87 | === modified file 'libwidgets/CMakeLists.txt' |
88 | --- libwidgets/CMakeLists.txt 2015-11-05 11:26:27 +0000 |
89 | +++ libwidgets/CMakeLists.txt 2015-11-14 13:22:20 +0000 |
90 | @@ -33,25 +33,39 @@ |
91 | ) |
92 | link_directories(${LIB_PATHS}) |
93 | |
94 | +include_directories (${CMAKE_CURRENT_SOURCE_DIR}/../libcore/) |
95 | +include_directories (${CMAKE_CURRENT_BINARY_DIR}/../libcore/) |
96 | include_directories (${CMAKE_CURRENT_BINARY_DIR}) |
97 | include_directories (${CMAKE_BINARY_DIR}) |
98 | |
99 | vala_precompile(VALA_C ${PKGNAME} |
100 | + FileUtils.vala |
101 | Resources.vala |
102 | - Animations.vala |
103 | LocationBar.vala |
104 | - BreadcrumbsElements.vala |
105 | + SearchResults.vala |
106 | + Animations/Animations.vala |
107 | + Chrome/LocationBar.vala |
108 | + Chrome/BreadcrumbsElements.vala |
109 | + Chrome/TopMenu.vala |
110 | + Chrome/ButtonWithMenu.vala |
111 | + Chrome/ViewSwicher.vala |
112 | + Chrome/XsEntry.vala |
113 | + Chrome/ImgEventBox.vala |
114 | + Chrome/Viewable.vala |
115 | + Dialogs/ChooseAppDialog.vala |
116 | Welcome.vala |
117 | PACKAGES |
118 | gtk+-3.0 |
119 | granite |
120 | gee-0.8 |
121 | posix |
122 | + zeitgeist-2.0 |
123 | pantheon-files-core |
124 | pantheon-files-core-C |
125 | OPTIONS |
126 | --vapidir=${CMAKE_SOURCE_DIR}/libcore |
127 | --vapidir=${CMAKE_BINARY_DIR}/libcore |
128 | + --target-glib=2.32 # Needed for new thread API |
129 | --thread |
130 | GENERATE_VAPI |
131 | pantheon-files-widgets |
132 | @@ -66,4 +80,4 @@ |
133 | SOVERSION ${PANTHEON_FILES_WIDGETS_SOVERSION}) |
134 | |
135 | install (TARGETS ${PKGNAME} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/) |
136 | -target_link_libraries(${PKGNAME} ${DEPS_LIBRARIES}) |
137 | +target_link_libraries(${PKGNAME} pantheon-files-core ${DEPS_LIBRARIES}) |
138 | |
139 | === added directory 'libwidgets/Chrome' |
140 | === renamed file 'libwidgets/BreadcrumbsElements.vala' => 'libwidgets/Chrome/BreadcrumbsElements.vala' |
141 | === renamed file 'src/View/Chrome/ButtonWithMenu.vala' => 'libwidgets/Chrome/ButtonWithMenu.vala' |
142 | === renamed file 'src/View/Chrome/ImgEventBox.vala' => 'libwidgets/Chrome/ImgEventBox.vala' |
143 | === renamed file 'libwidgets/LocationBar.vala' => 'libwidgets/Chrome/LocationBar.vala' |
144 | === renamed file 'src/View/Chrome/TopMenu.vala' => 'libwidgets/Chrome/TopMenu.vala' |
145 | --- src/View/Chrome/TopMenu.vala 2015-05-03 06:44:42 +0000 |
146 | +++ libwidgets/Chrome/TopMenu.vala 2015-11-14 13:22:20 +0000 |
147 | @@ -26,7 +26,7 @@ |
148 | public class TopMenu : Gtk.HeaderBar { |
149 | public ViewSwitcher? view_switcher; |
150 | public LocationBar? location_bar; |
151 | - public Marlin.View.Window win; |
152 | + public Marlin.Viewable win; |
153 | public Chrome.ButtonWithMenu button_forward; |
154 | public Chrome.ButtonWithMenu button_back; |
155 | |
156 | @@ -40,7 +40,12 @@ |
157 | button_forward.set_sensitive (can); |
158 | } |
159 | |
160 | - public TopMenu (Marlin.View.Window window) { |
161 | + public signal void focus_location_request (GLib.File? location); |
162 | + public signal void path_change_request (string path, Marlin.OpenFlag flag); |
163 | + public signal void escape (); |
164 | + public signal void reload_request (); |
165 | + |
166 | + public TopMenu (ViewSwitcher switcher, Marlin.Viewable window) { |
167 | win = window; |
168 | |
169 | button_back = new Marlin.View.Chrome.ButtonWithMenu.from_icon_name ("go-previous-symbolic", Gtk.IconSize.LARGE_TOOLBAR); |
170 | @@ -62,27 +67,36 @@ |
171 | back (1); |
172 | }); |
173 | |
174 | - |
175 | - view_switcher = new ViewSwitcher (win.win_actions.lookup_action ("view_mode") as GLib.SimpleAction); |
176 | - |
177 | + view_switcher = switcher; |
178 | + view_switcher.margin_right = 20; |
179 | view_switcher.show_all (); |
180 | pack_start (view_switcher); |
181 | |
182 | location_bar = new LocationBar (win); |
183 | + connect_location_bar_signals (); |
184 | + location_bar.show_all (); |
185 | + pack_start (location_bar); |
186 | + |
187 | + show (); |
188 | + } |
189 | + |
190 | + private void connect_location_bar_signals () { |
191 | location_bar.escape.connect (win.grab_focus); |
192 | location_bar.activate.connect (win.file_path_change_request); |
193 | location_bar.activate_alternate.connect ((file) => { |
194 | win.add_tab (file, Marlin.ViewMode.CURRENT); |
195 | }); |
196 | - |
197 | - |
198 | - location_bar.show_all (); |
199 | - view_switcher.margin_right = 20; |
200 | - pack_start (location_bar); |
201 | - |
202 | - show (); |
203 | + location_bar.reload_request.connect (() => { |
204 | + reload_request (); |
205 | + }); |
206 | + location_bar.focus_in_event.connect ((event) => { |
207 | + return focus_in_event (event); |
208 | + }); |
209 | + location_bar.focus_out_event.connect ((event) => { |
210 | + return focus_out_event (event); |
211 | + }); |
212 | } |
213 | - |
214 | + |
215 | public void set_back_menu (Gee.List<string> path_list) { |
216 | /* Clear the back menu and re-add the correct entries. */ |
217 | var back_menu = new Gtk.Menu (); |
218 | |
219 | === renamed file 'src/View/Chrome/ViewSwicher.vala' => 'libwidgets/Chrome/ViewSwicher.vala' |
220 | --- src/View/Chrome/ViewSwicher.vala 2015-05-03 06:44:42 +0000 |
221 | +++ libwidgets/Chrome/ViewSwicher.vala 2015-11-14 13:22:20 +0000 |
222 | @@ -48,7 +48,6 @@ |
223 | break; |
224 | } |
225 | |
226 | - Preferences.settings.set_enum ("default-viewmode", value); |
227 | freeze_update = true; |
228 | switcher.set_active (active_index); |
229 | freeze_update = false; |
230 | @@ -92,8 +91,6 @@ |
231 | switcher.append (miller); |
232 | miller_sv = new GLib.Variant.string ("MILLER"); |
233 | |
234 | - mode = (Marlin.ViewMode) Preferences.settings.get_enum("default-viewmode"); |
235 | - |
236 | switcher.mode_changed.connect ((image) => { |
237 | if (freeze_update) { |
238 | return; |
239 | |
240 | === added file 'libwidgets/Chrome/ViewWindowInterface.vala' |
241 | --- libwidgets/Chrome/ViewWindowInterface.vala 1970-01-01 00:00:00 +0000 |
242 | +++ libwidgets/Chrome/ViewWindowInterface.vala 2015-11-14 13:22:20 +0000 |
243 | @@ -0,0 +1,35 @@ |
244 | +/* |
245 | + * ViewWindowInterface.vala |
246 | + * |
247 | + * Copyright 2015 jeremy <jeremy@jeremy-W54-55SU1-SUW> |
248 | + * |
249 | + * This program is free software; you can redistribute it and/or modify |
250 | + * it under the terms of the GNU General Public License as published by |
251 | + * the Free Software Foundation; either version 2 of the License, or |
252 | + * (at your option) any later version. |
253 | + * |
254 | + * This program is distributed in the hope that it will be useful, |
255 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
256 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
257 | + * GNU General Public License for more details. |
258 | + * |
259 | + * You should have received a copy of the GNU General Public License |
260 | + * along with this program; if not, write to the Free Software |
261 | + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, |
262 | + * MA 02110-1301, USA. |
263 | + * |
264 | + * |
265 | + */ |
266 | + |
267 | + |
268 | +public interface Marlin.Viewable : Gtk.ApplicationWindow { |
269 | + public abstract new void grab_focus (); |
270 | + public abstract void file_path_change_request (GLib.File file); |
271 | + public abstract void focus_location_request (GLib.File loc); |
272 | + public abstract void add_tab (GLib.File location = GLib.File.new_for_commandline_arg (GLib.Environment.get_home_dir ()), |
273 | + Marlin.ViewMode mode = Marlin.ViewMode.PREFERRED); |
274 | + public abstract GLib.File get_current_location (); |
275 | + public abstract bool get_frozen (); |
276 | + public abstract void refresh_view (); |
277 | + public abstract void go_to_parent (); |
278 | +} |
279 | |
280 | === added file 'libwidgets/Chrome/Viewable.vala' |
281 | --- libwidgets/Chrome/Viewable.vala 1970-01-01 00:00:00 +0000 |
282 | +++ libwidgets/Chrome/Viewable.vala 2015-11-14 13:22:20 +0000 |
283 | @@ -0,0 +1,32 @@ |
284 | +/*** |
285 | + Copyright (C) 2015 elementary Developers |
286 | + |
287 | + This program is free software: you can redistribute it and/or modify it |
288 | + under the terms of the GNU Lesser General Public License version 3, as published |
289 | + by the Free Software Foundation. |
290 | + |
291 | + This program is distributed in the hope that it will be useful, but |
292 | + WITHOUT ANY WARRANTY; without even the implied warranties of |
293 | + MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
294 | + PURPOSE. See the GNU General Public License for more details. |
295 | + |
296 | + You should have received a copy of the GNU General Public License along |
297 | + with this program. If not, see <http://www.gnu.org/licenses/>. |
298 | + |
299 | + Authors : Jeremy Wootten <jeremy@elementaryos.org> |
300 | +***/ |
301 | + |
302 | + |
303 | +public interface Marlin.Viewable : Gtk.ApplicationWindow { |
304 | + public abstract new void grab_focus (); |
305 | + public abstract void file_path_change_request (GLib.File file); |
306 | + public abstract void focus_location_request (GLib.File? loc, |
307 | + bool select_in_current_only = false, |
308 | + bool unselect_others = false); |
309 | + public abstract void add_tab (GLib.File location = GLib.File.new_for_commandline_arg (GLib.Environment.get_home_dir ()), |
310 | + Marlin.ViewMode mode = Marlin.ViewMode.PREFERRED); |
311 | + public abstract GLib.File get_current_location (); |
312 | + public abstract bool get_frozen (); |
313 | + public abstract void refresh_view (); |
314 | + public abstract void go_to_parent (); |
315 | +} |
316 | |
317 | === renamed file 'src/View/Chrome/XsEntry.vala' => 'libwidgets/Chrome/XsEntry.vala' |
318 | === added directory 'libwidgets/Dialogs' |
319 | === added file 'libwidgets/Dialogs/ChooseAppDialog.vala' |
320 | --- libwidgets/Dialogs/ChooseAppDialog.vala 1970-01-01 00:00:00 +0000 |
321 | +++ libwidgets/Dialogs/ChooseAppDialog.vala 2015-11-14 13:22:20 +0000 |
322 | @@ -0,0 +1,62 @@ |
323 | +/*** |
324 | + Copyright (C) 2015 elementary Developers |
325 | + |
326 | + This program is free software: you can redistribute it and/or modify it |
327 | + under the terms of the GNU Lesser General Public License version 3, as published |
328 | + by the Free Software Foundation. |
329 | + |
330 | + This program is distributed in the hope that it will be useful, but |
331 | + WITHOUT ANY WARRANTY; without even the implied warranties of |
332 | + MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
333 | + PURPOSE. See the GNU General Public License for more details. |
334 | + |
335 | + You should have received a copy of the GNU General Public License along |
336 | + with this program. If not, see <http://www.gnu.org/licenses/>. |
337 | + |
338 | + Authors : Jeremy Wootten <jeremy@elementaryos.org> |
339 | +***/ |
340 | + |
341 | +namespace PF { |
342 | + class ChooseAppDialog { |
343 | + Gtk.AppChooserDialog dialog; |
344 | + Gtk.CheckButton check_default; |
345 | + GLib.File file_to_open; |
346 | + public ChooseAppDialog (Gtk.Window parent, GLib.File file) { |
347 | + file_to_open = file; |
348 | + dialog = new Gtk.AppChooserDialog (parent, |
349 | + Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, |
350 | + file_to_open); |
351 | + |
352 | + dialog.set_deletable (false); |
353 | + var app_chooser = dialog.get_widget () as Gtk.AppChooserWidget; |
354 | + app_chooser.set_show_recommended (true); |
355 | + check_default = new Gtk.CheckButton.with_label (_("Set as default")); |
356 | + check_default.set_active (true); |
357 | + check_default.show (); |
358 | + var action_area = dialog.get_action_area () as Gtk.ButtonBox; |
359 | + action_area.add (check_default); |
360 | + action_area.set_child_secondary (check_default, true); |
361 | + dialog.show (); |
362 | + } |
363 | + |
364 | + public AppInfo? get_app_info () { |
365 | + AppInfo? app = null; |
366 | + int response = dialog.run (); |
367 | + if (response == Gtk.ResponseType.OK) { |
368 | + app = dialog.get_app_info (); |
369 | + if (check_default.get_active ()) { |
370 | + try { |
371 | + var info = file_to_open.query_info (FileAttribute.STANDARD_CONTENT_TYPE, |
372 | + FileQueryInfoFlags.NONE, null); |
373 | + app.set_as_default_for_type (info.get_content_type ()); |
374 | + } |
375 | + catch (GLib.Error error) { |
376 | + critical ("Could not set as default: %s", error.message); |
377 | + } |
378 | + } |
379 | + } |
380 | + dialog.destroy (); |
381 | + return app; |
382 | + } |
383 | + } |
384 | +} |
385 | |
386 | === added file 'libwidgets/FileUtils.vala' |
387 | --- libwidgets/FileUtils.vala 1970-01-01 00:00:00 +0000 |
388 | +++ libwidgets/FileUtils.vala 2015-11-14 13:22:20 +0000 |
389 | @@ -0,0 +1,149 @@ |
390 | +namespace PF.FileUtils { |
391 | + const string reserved_chars = (GLib.Uri.RESERVED_CHARS_GENERIC_DELIMITERS + GLib.Uri.RESERVED_CHARS_SUBCOMPONENT_DELIMITERS + " "); |
392 | + |
393 | + /** |
394 | + * Gets a properly escaped GLib.File for the given path |
395 | + **/ |
396 | + public File? get_file_for_path (string? path) { |
397 | + File? file = null; |
398 | + string new_path = sanitize_path (path); |
399 | + if (path.length > 0) { |
400 | + file = File.new_for_commandline_arg (new_path); |
401 | + } |
402 | + return file; |
403 | + } |
404 | + |
405 | + public string get_parent_path_from_path (string path) { |
406 | + File? file = File.new_for_commandline_arg (path); |
407 | + string parent_path = path; |
408 | + if (file != null) { |
409 | + File? parent = file.get_parent (); |
410 | + if (parent != null) { |
411 | + parent_path = parent.get_path (); |
412 | + } else { |
413 | + parent_path = construct_parent_path (path); |
414 | + } |
415 | + } |
416 | + return parent_path; |
417 | + } |
418 | + |
419 | + private string construct_parent_path (string path) { |
420 | + if (path.length < 2) { |
421 | + return Path.DIR_SEPARATOR_S; |
422 | + } |
423 | + StringBuilder sb = new StringBuilder (path); |
424 | + if (path.has_suffix (Path.DIR_SEPARATOR_S)) { |
425 | + sb.erase (sb.str.length - 1,-1); |
426 | + } |
427 | + int last_separator = sb.str.last_index_of (Path.DIR_SEPARATOR_S); |
428 | + if (last_separator < 0) { |
429 | + last_separator = 0; |
430 | + } |
431 | + sb.erase (last_separator, -1); |
432 | + string parent_path = sb.str + Path.DIR_SEPARATOR_S; |
433 | + return parent_path; |
434 | + } |
435 | + |
436 | + public bool path_has_parent (string new_path) { |
437 | + var file = File.new_for_commandline_arg (new_path); |
438 | + return file.get_parent () != null; |
439 | + } |
440 | + |
441 | + public string? escape_uri (string uri, bool allow_utf8 = true) { |
442 | + reserved_chars.replace("#", ""); |
443 | + return Uri.escape_string ((Uri.unescape_string (uri) ?? uri), reserved_chars, allow_utf8); |
444 | + } |
445 | + |
446 | + /** Produce a valid unescaped path **/ |
447 | + public string sanitize_path (string? p, string? cp = null) { |
448 | + string path = ""; |
449 | + string scheme = ""; |
450 | + string? current_path = null; |
451 | + string? current_scheme = null; |
452 | + |
453 | + if (p == null || p == "") { |
454 | + return cp ?? ""; |
455 | + } |
456 | + string? unescaped_p = Uri.unescape_string (p, null); |
457 | + if (unescaped_p == null) { |
458 | + unescaped_p = p; |
459 | + } |
460 | + |
461 | + split_protocol_from_path (unescaped_p, out scheme, out path); |
462 | + path = path.strip ().replace ("//", "/"); |
463 | + StringBuilder sb = new StringBuilder (path); |
464 | + if (cp != null) { |
465 | + split_protocol_from_path (cp, out current_scheme, out current_path); |
466 | + /* current_path is assumed already sanitized */ |
467 | + if (scheme == "" && path.has_prefix ("/./")) { |
468 | + sb.erase (0, 2); |
469 | + sb.prepend (cp); |
470 | + split_protocol_from_path (sb.str , out scheme, out path); |
471 | + sb.assign (path); |
472 | + } else if (path.has_prefix ("/../")) { |
473 | + sb.erase (0, 3); |
474 | + sb.prepend (get_parent_path_from_path (current_path)); |
475 | + sb.prepend (current_scheme); |
476 | + split_protocol_from_path (sb.str , out scheme, out path); |
477 | + sb.assign (path); |
478 | + } |
479 | + } |
480 | + |
481 | + if (path.length > 0) { |
482 | + if (scheme == "" && path.has_prefix ("/~/")) { |
483 | + sb.erase (0, 2); |
484 | + sb.prepend (Environment.get_home_dir ()); |
485 | + } |
486 | + } |
487 | + |
488 | + path = sb.str; |
489 | + do { |
490 | + path = path.replace ("//", "/"); |
491 | + } while (path.contains ("//")); |
492 | + |
493 | + string new_path = (scheme + path).replace("////", "///"); |
494 | + |
495 | + if (new_path.length > 0) { |
496 | + if (scheme != Marlin.ROOT_FS_URI && path != "/") { |
497 | + new_path = new_path.replace ("///", "//"); |
498 | + } |
499 | + new_path = new_path.replace("ssh:", "sftp:"); |
500 | + } |
501 | + |
502 | + return new_path; |
503 | + } |
504 | + |
505 | + /** Splits the path into a protocol ending in '://" (unless it is file:// which is replaced by "") |
506 | + * and a path beginning "/". |
507 | + **/ |
508 | + public void split_protocol_from_path (string path, out string protocol, out string new_path) { |
509 | + protocol = ""; |
510 | + new_path = path; |
511 | + |
512 | + string[] explode_protocol = new_path.split ("://"); |
513 | + if (explode_protocol.length > 2) { |
514 | + new_path = ""; |
515 | + return; |
516 | + } |
517 | + if (explode_protocol.length > 1) { |
518 | + if (explode_protocol[0] == "mtp") { |
519 | + string[] explode_path = explode_protocol[1].split ("]", 2); |
520 | + protocol = (explode_protocol[0] + "://" + explode_path[0] + "]").replace ("///", "//"); |
521 | + /* If path is being manually edited there may not be "]" so explode_path[1] may be null*/ |
522 | + new_path = explode_path [1] ?? ""; |
523 | + } else { |
524 | + protocol = explode_protocol[0] + "://"; |
525 | + new_path = explode_protocol[1]; |
526 | + } |
527 | + } else { |
528 | + protocol = Marlin.ROOT_FS_URI; |
529 | + } |
530 | + |
531 | + if (Marlin.ROOT_FS_URI.has_prefix (protocol)) { |
532 | + protocol = ""; |
533 | + } |
534 | + if (!new_path.has_prefix (Path.DIR_SEPARATOR_S)) { |
535 | + new_path = Path.DIR_SEPARATOR_S + new_path; |
536 | + } |
537 | + } |
538 | +} |
539 | \ No newline at end of file |
540 | |
541 | === renamed file 'src/View/LocationBar.vala' => 'libwidgets/LocationBar.vala' |
542 | --- src/View/LocationBar.vala 2015-11-13 18:58:58 +0000 |
543 | +++ libwidgets/LocationBar.vala 2015-11-14 13:22:20 +0000 |
544 | @@ -31,7 +31,7 @@ |
545 | if (new_path != null) { |
546 | _path = new_path; |
547 | |
548 | - if (!bread.is_focus && !win.freeze_view_changes) { |
549 | + if (!bread.is_focus && !win.get_frozen ()) { |
550 | bread.text = ""; |
551 | bread.change_breadcrumbs (new_path); |
552 | } |
553 | @@ -45,26 +45,26 @@ |
554 | } |
555 | } |
556 | |
557 | - Marlin.View.Window win; |
558 | + Marlin.Viewable win; |
559 | |
560 | public new signal void activate (GLib.File file); |
561 | public signal void activate_alternate (GLib.File file); |
562 | public signal void escape (); |
563 | public signal void search_mode_left (); |
564 | - |
565 | + public signal void reload_request (); |
566 | public override void get_preferred_width (out int minimum_width, out int natural_width) { |
567 | minimum_width = -1; |
568 | natural_width = 3000; |
569 | } |
570 | |
571 | - public LocationBar (Marlin.View.Window win) { |
572 | + public LocationBar (Marlin.Viewable win) { |
573 | this.win = win; |
574 | bread = new Breadcrumbs (win); |
575 | bread.escape.connect (() => { escape(); }); |
576 | bread.path_changed.connect (on_path_changed); |
577 | |
578 | bread.reload.connect (() => { |
579 | - win.win_actions.activate_action ("refresh", null); |
580 | + win.refresh_view (); |
581 | }); |
582 | |
583 | bread.activate_alternate.connect ((file) => { activate_alternate(file); }); |
584 | @@ -92,7 +92,8 @@ |
585 | } |
586 | |
587 | private void on_path_changed (File? file) { |
588 | - if (file == null || win.freeze_view_changes) |
589 | + if (file == null || win.get_frozen ()) |
590 | + if (file == null) |
591 | return; |
592 | |
593 | win.grab_focus (); |
594 | @@ -116,7 +117,7 @@ |
595 | |
596 | bool autocompleted = false; |
597 | |
598 | - Marlin.View.Window win; |
599 | + Marlin.Viewable win; |
600 | |
601 | double menu_x_root; |
602 | double menu_y_root; |
603 | @@ -124,14 +125,14 @@ |
604 | private bool drop_data_ready = false; /* whether the drop data was received already */ |
605 | private bool drop_occurred = false; /* whether the data was dropped */ |
606 | private GLib.List<GLib.File> drop_file_list = null; /* the list of URIs in the drop data */ |
607 | - protected static FM.DndHandler dnd_handler = new FM.DndHandler (); |
608 | + protected static Marlin.DndHandler dnd_handler = new Marlin.DndHandler (); |
609 | |
610 | Gdk.DragAction current_suggested_action = 0; /* No action */ |
611 | Gdk.DragAction current_actions = 0; /* No action */ |
612 | |
613 | GOF.File? drop_target_file = null; |
614 | |
615 | - public Breadcrumbs (Marlin.View.Window win) |
616 | + public Breadcrumbs (Marlin.Viewable win) |
617 | { |
618 | this.win = win; |
619 | /* FIXME the string split of the path url is kinda too basic, we should use the Gile to split our uris and determine the protocol (if any) with g_uri_parse_scheme or g_file_get_uri_scheme */ |
620 | @@ -230,7 +231,7 @@ |
621 | if (parent != null && file.get_uri () != parent.get_uri ()) |
622 | change_breadcrumbs (parent.get_uri ()); |
623 | |
624 | - win.go_up (); |
625 | + win.go_to_parent (); |
626 | grab_focus (); |
627 | }); |
628 | |
629 | @@ -262,18 +263,15 @@ |
630 | |
631 | search_results.file_selected.connect ((file) => { |
632 | win.grab_focus (); |
633 | - win.current_tab.focus_location (file); |
634 | - |
635 | - search_mode = false; |
636 | - escape (); |
637 | + win.focus_location_request (file, false, true); |
638 | }); |
639 | |
640 | search_results.cursor_changed.connect ((file) => { |
641 | - win.current_tab.focus_location_if_in_current_directory (file, true); |
642 | + win.focus_location_request (file, true, true); |
643 | }); |
644 | |
645 | search_results.first_match_found.connect ((file) => { |
646 | - win.current_tab.focus_location_if_in_current_directory (file, true); |
647 | + win.focus_location_request (file, true, true); |
648 | }); |
649 | |
650 | search_results.hide.connect (() => { |
651 | @@ -281,7 +279,7 @@ |
652 | }); |
653 | |
654 | search_changed.connect ((text) => { |
655 | - search_results.search (text, win.current_tab.location); |
656 | + search_results.search (text, win.get_current_location ()); |
657 | }); |
658 | } |
659 | |
660 | @@ -372,7 +370,7 @@ |
661 | |
662 | bool at_least_one = false; |
663 | foreach (AppInfo app_info in app_info_list) { |
664 | - if (app_info.get_executable () != APP_NAME) { |
665 | + if (app_info.get_executable () != Environment.get_application_name ()) { |
666 | at_least_one = true; |
667 | var menu_item = new Gtk.ImageMenuItem.with_label (app_info.get_name ()); |
668 | menu_item.set_data ("appinfo", app_info); |
669 | |
670 | === renamed file 'src/View/SearchResults.vala' => 'libwidgets/SearchResults.vala' |
671 | --- src/View/SearchResults.vala 2015-05-03 06:44:42 +0000 |
672 | +++ libwidgets/SearchResults.vala 2015-11-14 13:22:20 +0000 |
673 | @@ -101,8 +101,6 @@ |
674 | Gtk.TreeModelFilter filter; |
675 | Gtk.ScrolledWindow scroll; |
676 | |
677 | - ulong cursor_changed_handler_id; |
678 | - |
679 | public SearchResults (Gtk.Entry entry) |
680 | { |
681 | Object (entry: entry, |
682 | @@ -210,7 +208,6 @@ |
683 | Gtk.TreePath path; |
684 | Gtk.TreeIter iter; |
685 | |
686 | - SignalHandler.block (view, cursor_changed_handler_id); |
687 | view.get_path_at_pos ((int) e.x, (int) e.y, out path, null, null, null); |
688 | |
689 | if (path != null) { |
690 | @@ -218,12 +215,9 @@ |
691 | filter.convert_iter_to_child_iter (out iter, iter); |
692 | accept (iter); |
693 | } |
694 | - SignalHandler.unblock (view, cursor_changed_handler_id); |
695 | return true; |
696 | }); |
697 | |
698 | - cursor_changed_handler_id = view.cursor_changed.connect (on_cursor_changed); |
699 | - |
700 | key_release_event.connect (key_event); |
701 | key_press_event.connect (key_event); |
702 | |
703 | @@ -504,6 +498,7 @@ |
704 | || is_grabbing) |
705 | return; |
706 | |
707 | + view.cursor_changed.connect (on_cursor_changed); |
708 | resize_popup (); |
709 | |
710 | var toplevel = entry.get_toplevel (); |
711 | @@ -527,6 +522,7 @@ |
712 | |
713 | void popdown () |
714 | { |
715 | + view.cursor_changed.disconnect (on_cursor_changed); |
716 | entry.reset_im_context (); |
717 | |
718 | if (is_grabbing && device != null) { |
719 | @@ -644,10 +640,9 @@ |
720 | Gdk.beep (); |
721 | return; |
722 | } |
723 | - |
724 | + /* The order of these two lines is critical to prevent unwanted cursor-changed signals */ |
725 | + popdown (); |
726 | file_selected (file); |
727 | - |
728 | - popdown (); |
729 | } |
730 | |
731 | File? get_file_at_iter (Gtk.TreeIter? iter) |
732 | |
733 | === modified file 'src/CMakeLists.txt' |
734 | --- src/CMakeLists.txt 2015-11-03 15:58:50 +0000 |
735 | +++ src/CMakeLists.txt 2015-11-14 13:22:20 +0000 |
736 | @@ -51,17 +51,12 @@ |
737 | IF (WITH_UNITY AND UNITY_FOUND) |
738 | vala_precompile (VALA_C pantheon-files |
739 | Application.vala |
740 | - Bookmark.vala |
741 | - BookmarkList.vala |
742 | ConnectServerOperation.vala |
743 | - DndHandler.vala |
744 | - Enums.vala |
745 | AbstractEditableLabel.vala |
746 | SingleLineEditableLabel.vala |
747 | MultiLineEditableLabel.vala |
748 | main.vala |
749 | marlin-deep-count.vala |
750 | - MimeActions.vala |
751 | ProgressInfoWidget.vala |
752 | ProgressUIHandler.vala |
753 | TextRenderer.vala |
754 | @@ -75,21 +70,15 @@ |
755 | View/IconSpinnerRenderer.vala |
756 | View/DirectoryNotFound.vala |
757 | View/AbstractDirectoryView.vala |
758 | - View/SearchResults.vala |
759 | View/Window.vala |
760 | View/ViewContainer.vala |
761 | View/OverlayBar.vala |
762 | View/PropertiesWindow.vala |
763 | View/Browser.vala |
764 | - View/LocationBar.vala |
765 | View/Sidebar.vala |
766 | View/Slot.vala |
767 | View/Miller.vala |
768 | - View/Chrome/TopMenu.vala |
769 | - View/Chrome/ButtonWithMenu.vala |
770 | - View/Chrome/ViewSwicher.vala |
771 | - View/Chrome/XsEntry.vala |
772 | - View/Chrome/ImgEventBox.vala |
773 | + |
774 | PACKAGES |
775 | gtk+-3.0 |
776 | gio-2.0 |
777 | @@ -118,17 +107,12 @@ |
778 | ELSE (WITH_UNITY AND UNITY_FOUND) |
779 | vala_precompile (VALA_C pantheon-files |
780 | Application.vala |
781 | - Bookmark.vala |
782 | - BookmarkList.vala |
783 | ConnectServerOperation.vala |
784 | - DndHandler.vala |
785 | - Enums.vala |
786 | AbstractEditableLabel.vala |
787 | SingleLineEditableLabel.vala |
788 | MultiLineEditableLabel.vala |
789 | main.vala |
790 | marlin-deep-count.vala |
791 | - MimeActions.vala |
792 | ProgressInfoWidget.vala |
793 | ProgressUIHandler.vala |
794 | TextRenderer.vala |
795 | @@ -137,7 +121,6 @@ |
796 | View/IconView.vala |
797 | View/ListView.vala |
798 | ZeitgeistManager.vala |
799 | - View/SearchResults.vala |
800 | View/DiskRenderer.vala |
801 | View/DirectoryNotFound.vala |
802 | View/AbstractDirectoryView.vala |
803 | @@ -147,15 +130,9 @@ |
804 | View/OverlayBar.vala |
805 | View/PropertiesWindow.vala |
806 | View/Browser.vala |
807 | - View/LocationBar.vala |
808 | View/Sidebar.vala |
809 | View/Slot.vala |
810 | View/Miller.vala |
811 | - View/Chrome/TopMenu.vala |
812 | - View/Chrome/ButtonWithMenu.vala |
813 | - View/Chrome/ViewSwicher.vala |
814 | - View/Chrome/XsEntry.vala |
815 | - View/Chrome/ImgEventBox.vala |
816 | PACKAGES |
817 | gtk+-3.0 |
818 | gio-2.0 |
819 | |
820 | === modified file 'src/View/AbstractDirectoryView.vala' |
821 | --- src/View/AbstractDirectoryView.vala 2015-09-21 13:50:55 +0000 |
822 | +++ src/View/AbstractDirectoryView.vala 2015-11-14 13:22:20 +0000 |
823 | @@ -25,13 +25,6 @@ |
824 | namespace FM { |
825 | public abstract class AbstractDirectoryView : Gtk.ScrolledWindow { |
826 | |
827 | - public enum TargetType { |
828 | - STRING, |
829 | - TEXT_URI_LIST, |
830 | - XDND_DIRECT_SAVE0, |
831 | - NETSCAPE_URL |
832 | - } |
833 | - |
834 | protected enum ClickZone { |
835 | EXPANDER, |
836 | HELPER, |
837 | @@ -46,15 +39,15 @@ |
838 | const int MAX_TEMPLATES = 32; |
839 | |
840 | const Gtk.TargetEntry [] drag_targets = { |
841 | - {"text/plain", Gtk.TargetFlags.SAME_APP, TargetType.STRING}, |
842 | - {"text/uri-list", Gtk.TargetFlags.SAME_APP, TargetType.TEXT_URI_LIST} |
843 | + {"text/plain", Gtk.TargetFlags.SAME_APP, Marlin.TargetType.STRING}, |
844 | + {"text/uri-list", Gtk.TargetFlags.SAME_APP, Marlin.TargetType.TEXT_URI_LIST} |
845 | }; |
846 | |
847 | const Gtk.TargetEntry [] drop_targets = { |
848 | - {"text/uri-list", Gtk.TargetFlags.SAME_APP, TargetType.TEXT_URI_LIST}, |
849 | - {"text/uri-list", Gtk.TargetFlags.OTHER_APP, TargetType.TEXT_URI_LIST}, |
850 | - {"XdndDirectSave0", Gtk.TargetFlags.OTHER_APP, TargetType.XDND_DIRECT_SAVE0}, |
851 | - {"_NETSCAPE_URL", Gtk.TargetFlags.OTHER_APP, TargetType.NETSCAPE_URL} |
852 | + {"text/uri-list", Gtk.TargetFlags.SAME_APP, Marlin.TargetType.TEXT_URI_LIST}, |
853 | + {"text/uri-list", Gtk.TargetFlags.OTHER_APP, Marlin.TargetType.TEXT_URI_LIST}, |
854 | + {"XdndDirectSave0", Gtk.TargetFlags.OTHER_APP, Marlin.TargetType.XDND_DIRECT_SAVE0}, |
855 | + {"_NETSCAPE_URL", Gtk.TargetFlags.OTHER_APP, Marlin.TargetType.NETSCAPE_URL} |
856 | }; |
857 | |
858 | const Gdk.DragAction file_drag_actions = (Gdk.DragAction.COPY | Gdk.DragAction.MOVE | Gdk.DragAction.LINK); |
859 | @@ -235,7 +228,7 @@ |
860 | protected Marlin.IconRenderer icon_renderer; |
861 | protected unowned Marlin.View.Slot slot; |
862 | protected unowned Marlin.View.Window window; /*For convenience - this can be derived from slot */ |
863 | - protected static DndHandler dnd_handler = new FM.DndHandler (); |
864 | + protected static Marlin.DndHandler dnd_handler = new Marlin.DndHandler (); |
865 | |
866 | protected unowned Gtk.RecentManager recent; |
867 | |
868 | @@ -394,9 +387,10 @@ |
869 | Gtk.TreePath path = model.get_path (iter); |
870 | if (path != null) { |
871 | select_path (path); |
872 | - if (focus_location != null && focus_location.equal (file.location)) |
873 | + if (focus_location != null && focus_location.equal (file.location)) { |
874 | /* set cursor and scroll to focus location*/ |
875 | - set_cursor (path, false, false, true); |
876 | + set_cursor (path, false, false, true); |
877 | + } |
878 | } |
879 | } |
880 | }); |
881 | @@ -1536,19 +1530,19 @@ |
882 | slot.reload (true); /* non-local only */ |
883 | |
884 | switch (info) { |
885 | - case TargetType.XDND_DIRECT_SAVE0: |
886 | + case Marlin.TargetType.XDND_DIRECT_SAVE0: |
887 | success = dnd_handler.handle_xdnddirectsave (context, |
888 | drop_target_file, |
889 | selection_data); |
890 | break; |
891 | |
892 | - case TargetType.NETSCAPE_URL: |
893 | + case Marlin.TargetType.NETSCAPE_URL: |
894 | success = dnd_handler.handle_netscape_url (context, |
895 | drop_target_file, |
896 | selection_data); |
897 | break; |
898 | |
899 | - case TargetType.TEXT_URI_LIST: |
900 | + case Marlin.TargetType.TEXT_URI_LIST: |
901 | if ((current_actions & file_drag_actions) != 0) { |
902 | if (selected_files != null) |
903 | unselect_all (); |
904 | |
905 | === modified file 'src/View/Miller.vala' |
906 | --- src/View/Miller.vala 2015-07-24 08:01:21 +0000 |
907 | +++ src/View/Miller.vala 2015-11-14 13:22:20 +0000 |
908 | @@ -428,5 +428,9 @@ |
909 | public override bool set_all_selected (bool all) { |
910 | return ((Marlin.View.Slot)(current_slot)).set_all_selected (all); |
911 | } |
912 | + |
913 | + public override void set_frozen_state (bool freeze) { |
914 | + current_slot.set_frozen_state (freeze); |
915 | + } |
916 | } |
917 | } |
918 | |
919 | === modified file 'src/View/Sidebar.vala' |
920 | --- src/View/Sidebar.vala 2015-11-03 15:58:50 +0000 |
921 | +++ src/View/Sidebar.vala 2015-11-14 13:22:20 +0000 |
922 | @@ -37,7 +37,7 @@ |
923 | private const int ICON_XPAD = 6 + ROOT_INDENTATION_XPAD; |
924 | private const int PROP_0 = 0; |
925 | |
926 | - private static FM.DndHandler dnd_handler = new FM.DndHandler (); |
927 | + private static Marlin.DndHandler dnd_handler = new Marlin.DndHandler (); |
928 | |
929 | Gtk.TreeView tree_view; |
930 | Gtk.CellRenderer indent_renderer; |
931 | |
932 | === modified file 'src/View/Slot.vala' |
933 | --- src/View/Slot.vala 2015-09-12 09:33:43 +0000 |
934 | +++ src/View/Slot.vala 2015-11-14 13:22:20 +0000 |
935 | @@ -351,5 +351,10 @@ |
936 | directory.update_files (); |
937 | } |
938 | } |
939 | + |
940 | + public override void set_frozen_state (bool freeze) { |
941 | + set_view_updates_frozen (freeze); |
942 | + frozen_changed (freeze); |
943 | + } |
944 | } |
945 | } |
946 | |
947 | === modified file 'src/View/ViewContainer.vala' |
948 | --- src/View/ViewContainer.vala 2015-11-05 11:26:27 +0000 |
949 | +++ src/View/ViewContainer.vala 2015-11-14 13:22:20 +0000 |
950 | @@ -396,11 +396,16 @@ |
951 | if (aslot != null) |
952 | aslot.set_active_state (is_active); |
953 | } |
954 | - |
955 | + |
956 | + public void set_frozen_state (bool is_frozen) { |
957 | + var aslot = get_current_slot (); |
958 | + if (aslot != null) |
959 | + aslot.set_frozen_state (is_frozen); |
960 | + } |
961 | + |
962 | public void focus_location (GLib.File? file, |
963 | bool select_in_current_only = false, |
964 | bool unselect_others = false) { |
965 | - |
966 | if (unselect_others || file == null) { |
967 | get_current_slot ().set_all_selected (false); |
968 | selected_locations = null; |
969 | @@ -417,7 +422,7 @@ |
970 | File? parent = file.get_parent (); |
971 | if (parent != null && location.equal (file.get_parent ())) { |
972 | if (select_in_current_only || file.query_file_type (0) != FileType.DIRECTORY) { |
973 | - var list = new List<File> (); |
974 | + var list = new List<File> (); |
975 | list.prepend (file); |
976 | get_current_slot ().select_glib_files (list, file); |
977 | } else |
978 | |
979 | === modified file 'src/View/Window.vala' |
980 | --- src/View/Window.vala 2015-08-17 14:25:36 +0000 |
981 | +++ src/View/Window.vala 2015-11-14 13:22:20 +0000 |
982 | @@ -23,7 +23,7 @@ |
983 | |
984 | namespace Marlin.View { |
985 | |
986 | - public class Window : Gtk.ApplicationWindow |
987 | + public class Window : Gtk.ApplicationWindow, Marlin.Viewable |
988 | { |
989 | static const GLib.ActionEntry [] win_entries = { |
990 | {"new_window", action_new_window}, |
991 | @@ -54,6 +54,7 @@ |
992 | public Gtk.Builder ui; |
993 | private unowned UndoManager undo_manager; |
994 | public Chrome.TopMenu top_menu; |
995 | + public Chrome.ViewSwitcher view_switcher; |
996 | public Gtk.InfoBar info_bar; |
997 | public Granite.Widgets.DynamicNotebook tabs; |
998 | public Marlin.Places.Sidebar sidebar; |
999 | @@ -167,11 +168,13 @@ |
1000 | } |
1001 | |
1002 | private void construct_top_menu () { |
1003 | - top_menu = new Chrome.TopMenu(this); |
1004 | + view_switcher = new Chrome.ViewSwitcher (win_actions.lookup_action ("view_mode") as SimpleAction); |
1005 | + view_switcher.mode = Preferences.settings.get_enum("default-viewmode"); |
1006 | + top_menu = new Chrome.TopMenu(view_switcher, this as Marlin.Viewable); |
1007 | top_menu.set_show_close_button (true); |
1008 | top_menu.set_custom_title (new Gtk.Label (null)); |
1009 | } |
1010 | - |
1011 | + |
1012 | private void construct_info_bar () { |
1013 | info_bar = new Gtk.InfoBar (); |
1014 | |
1015 | @@ -210,6 +213,20 @@ |
1016 | |
1017 | top_menu.forward.connect (on_go_forward); |
1018 | top_menu.back.connect (on_go_back); |
1019 | + top_menu.focus_in_event.connect (() => { |
1020 | + current_tab.set_frozen_state (true); |
1021 | + return false; |
1022 | + }); |
1023 | + top_menu.focus_out_event.connect (() => { |
1024 | + current_tab.set_frozen_state (false); |
1025 | + grab_focus (); |
1026 | + return true; |
1027 | + }); |
1028 | + top_menu.escape.connect (() => { |
1029 | + current_tab.set_frozen_state (false); |
1030 | + grab_focus (); |
1031 | + }); |
1032 | + top_menu.reload_request.connect (action_reload); |
1033 | |
1034 | undo_manager.request_menu_update.connect (undo_redo_menu_update_callback); |
1035 | |
1036 | @@ -461,7 +478,7 @@ |
1037 | (application as Marlin.Application).quit (); |
1038 | } |
1039 | |
1040 | - private void action_reload (GLib.SimpleAction action, GLib.Variant? param) { |
1041 | + private void action_reload () { |
1042 | /* avoid spawning reload when key kept pressed */ |
1043 | if (tabs.current.working || !current_tab.ready) |
1044 | return; |
1045 | @@ -928,6 +945,7 @@ |
1046 | top_menu.set_back_menu (current_tab.get_go_back_path_list ()); |
1047 | top_menu.set_forward_menu (current_tab.get_go_forward_path_list ()); |
1048 | top_menu.view_switcher.mode = current_tab.view_mode; |
1049 | + Preferences.settings.set_enum ("default-viewmode", (int)(current_tab.view_mode)); |
1050 | } |
1051 | } |
1052 | |
1053 | @@ -997,5 +1015,27 @@ |
1054 | application.set_accels_for_action ("win.info::HELP", {"F1"}); |
1055 | application.set_accels_for_action ("win.info::ABOUT", {"F3"}); |
1056 | } |
1057 | + |
1058 | + public bool get_frozen () { |
1059 | + return freeze_view_changes; |
1060 | + } |
1061 | + |
1062 | + public GLib.File get_current_location () { |
1063 | + return current_tab.location; |
1064 | + } |
1065 | + |
1066 | + public void refresh_view () { |
1067 | + action_reload (); |
1068 | + } |
1069 | + |
1070 | + public void focus_location_request (GLib.File? loc, |
1071 | + bool select_in_current_only = false, |
1072 | + bool unselect_others = false) { |
1073 | + current_tab.focus_location (loc, select_in_current_only, unselect_others); |
1074 | + } |
1075 | + |
1076 | + public void go_to_parent () { |
1077 | + go_up (); |
1078 | + } |
1079 | } |
1080 | } |