[dconf-editor] Allow bookmarking a search.



commit 45d04967ed113b4b919c5f521f24dd0760160692
Author: Arnaud Bonatti <arnaud bonatti gmail com>
Date:   Thu Sep 13 17:06:23 2018 +0200

    Allow bookmarking a search.

 editor/bookmarks.ui               |   5 +-
 editor/bookmarks.vala             | 132 +++++++++++++++++++++++++++++---------
 editor/browser-view.vala          |   9 +--
 editor/dconf-editor.css           |   6 +-
 editor/dconf-editor.gresource.xml |   1 +
 editor/dconf-window.vala          |  59 ++++++++++++-----
 editor/key-list-box-row.vala      |  19 +++++-
 editor/meson.build                |   3 +-
 editor/pathentry.vala             |   4 +-
 editor/pathwidget.vala            |  50 ++++++---------
 editor/registry-list.vala         |  62 ++++++++++++------
 editor/registry-search.vala       |  19 +++++-
 editor/search-list-box-row.ui     |  28 ++++++++
 13 files changed, 284 insertions(+), 113 deletions(-)
---
diff --git a/editor/bookmarks.ui b/editor/bookmarks.ui
index df8d3ce..ad1cdad 100644
--- a/editor/bookmarks.ui
+++ b/editor/bookmarks.ui
@@ -14,9 +14,8 @@
         <property name="row-spacing">6</property>
         <property name="margin">4</property>
         <child>
-          <object class="GtkLabel">
+          <object class="GtkLabel" id="switch_label">
             <property name="visible">True</property>
-            <property name="label" translatable="yes">Bookmark this Location</property>
             <property name="margin-start">6</property>
             <property name="halign">start</property>
           </object>
@@ -30,7 +29,7 @@
             <property name="visible">True</property>
             <property name="halign">end</property>
             <property name="action-name">ui.empty</property>
-            <property name="action-target">''</property>
+            <property name="action-target">('',byte 255)</property>
             <child internal-child="accessible">
               <object class="AtkObject">
                 <property name="AtkObject::accessible-name" translatable="yes">Location bookmarked</property>
diff --git a/editor/bookmarks.vala b/editor/bookmarks.vala
index efd12e2..7427d0b 100644
--- a/editor/bookmarks.vala
+++ b/editor/bookmarks.vala
@@ -25,8 +25,10 @@ private class Bookmarks : MenuButton
 
     [GtkChild] private Image bookmarks_icon;
     [GtkChild] private Switch bookmarked_switch;
+    [GtkChild] private Label switch_label;
 
-    private string current_path = "/";
+    private string   current_path = "/";
+    private ViewType current_type = ViewType.FOLDER;
 
     private string schema_id = "ca.desrt.dconf-editor.Bookmarks";   // TODO move in a library
     public string schema_path { private get; internal construct; }
@@ -34,6 +36,8 @@ private class Bookmarks : MenuButton
 
     construct
     {
+        update_switch_label (ViewType.SEARCH, ViewType.FOLDER); // init text with "Bookmark this Location"
+
         install_action_entries ();
 
         settings = new GLib.Settings.with_path (schema_id, schema_path);
@@ -61,11 +65,11 @@ private class Bookmarks : MenuButton
 
     internal void set_path (ViewType type, string path)
     {
-        if (type == ViewType.SEARCH)
-            return;
+        update_switch_label (current_type, type);
+
+        current_path = path;
+        current_type = type;
 
-        if (current_path != path)
-            current_path = path;
         update_icon_and_switch ();
     }
 
@@ -84,7 +88,21 @@ private class Bookmarks : MenuButton
     }
 
     // keyboard call
-    internal void set_bookmarked (string path, bool new_state)
+    internal void bookmark_current_path ()
+    {
+        if (bookmarked_switch.get_active ())
+            return;
+        append_bookmark (current_path, current_type);
+    }
+
+    internal void unbookmark_current_path ()
+    {
+        if (!bookmarked_switch.get_active ())
+            return;
+        remove_bookmark (current_path, current_type);
+    }
+
+/*    internal void set_bookmarked (string path, bool new_state)
     {
         if (path == current_path && bookmarked_switch.get_active () == new_state)
             return;
@@ -93,7 +111,7 @@ private class Bookmarks : MenuButton
             append_bookmark (path);
         else
             remove_bookmark (path);
-    }
+    } */
 
     internal void update_bookmark_icon (string bookmark, bool bookmark_exists, bool bookmark_has_schema, 
bool bookmark_is_default)
     {
@@ -135,8 +153,8 @@ private class Bookmarks : MenuButton
 
     private const GLib.ActionEntry [] action_entries =
     {
-        {   "bookmark",   bookmark, "s" },
-        { "unbookmark", unbookmark, "s" }
+        {   "bookmark",   bookmark, "(sy)" },
+        { "unbookmark", unbookmark, "(sy)" }
     };
 
     private void bookmark (SimpleAction action, Variant? path_variant)
@@ -144,7 +162,10 @@ private class Bookmarks : MenuButton
     {
         bookmarks_popover.closed ();    // if the popover is visible, the size of the listbox could change 
1/2
 
-        append_bookmark (((!) path_variant).get_string ());
+        string bookmark;
+        uint8 type;
+        ((!) path_variant).@get ("(sy)", out bookmark, out type);
+        append_bookmark (bookmark, ViewType.from_byte (type));
     }
 
     private void unbookmark (SimpleAction action, Variant? path_variant)
@@ -152,36 +173,51 @@ private class Bookmarks : MenuButton
     {
         bookmarks_popover.closed ();    // if the popover is visible, the size of the listbox could change 
2/2
 
-        remove_bookmark (((!) path_variant).get_string ());
+        string bookmark;
+        uint8 type;
+        ((!) path_variant).@get ("(sy)", out bookmark, out type);
+        remove_bookmark (bookmark, ViewType.from_byte (type));
     }
 
     /*\
     * * Bookmarks management
     \*/
 
+    private const string bookmark_this_search_text = _("Bookmark this Search");
+    private const string bookmark_this_location_text = _("Bookmark this Location");
+    private void update_switch_label (ViewType old_type, ViewType new_type)
+    {
+        if (new_type == ViewType.SEARCH && old_type != ViewType.SEARCH)
+            switch_label.label = bookmark_this_search_text;
+        else if (new_type != ViewType.SEARCH && old_type == ViewType.SEARCH)
+            switch_label.label = bookmark_this_location_text;
+    }
+
     private void update_icon_and_switch ()
     {
-        Variant variant = new Variant.string (current_path);
-        if (current_path in settings.get_strv ("bookmarks"))
+        Variant variant = new Variant ("(sy)", current_path, ViewType.to_byte (current_type));
+        string [] bookmarks = settings.get_strv ("bookmarks");
+        if ((current_type == ViewType.SEARCH && ("?" + current_path) in bookmarks)
+         || (current_type != ViewType.SEARCH && current_path in bookmarks))
         {
             if (bookmarks_icon.icon_name != "starred-symbolic")
                 bookmarks_icon.icon_name = "starred-symbolic";
             update_switch (true);
-            bookmarked_switch.set_detailed_action_name ("bookmarks.unbookmark(" + variant.print (false) + 
")");
+            bookmarked_switch.set_detailed_action_name ("bookmarks.unbookmark(" + variant.print (true) + 
")");
         }
         else
         {
             if (bookmarks_icon.icon_name != "non-starred-symbolic")
                 bookmarks_icon.icon_name = "non-starred-symbolic";
             update_switch (false);
-            bookmarked_switch.set_detailed_action_name ("bookmarks.bookmark(" + variant.print (false) + ")");
+            bookmarked_switch.set_detailed_action_name ("bookmarks.bookmark(" + variant.print (true) + ")");
         }
     }
     private void update_switch (bool bookmarked)
     {
         if (bookmarked == bookmarked_switch.active)
             return;
-        bookmarked_switch.set_detailed_action_name ("ui.empty('')");
+        bookmarked_switch.set_detailed_action_name ("ui.empty(('',byte 255))");
         bookmarked_switch.active = bookmarked;
     }
 
@@ -190,7 +226,7 @@ private class Bookmarks : MenuButton
         bookmarks_list_box.@foreach ((widget) => widget.destroy ());
 
         Variant bookmarks_variant = settings.get_value ("bookmarks");
-        set_detailed_action_name ("ui.update-bookmarks-icons(" + bookmarks_variant.print (false) + ")");  // 
TODO disable action on popover closed
+        set_detailed_action_name ("ui.update-bookmarks-icons(" + bookmarks_variant.print (true) + ")");  // 
TODO disable action on popover closed
 
         string [] bookmarks = bookmarks_variant.get_strv ();
         string [] unduplicated_bookmarks = new string [0];
@@ -201,7 +237,12 @@ private class Bookmarks : MenuButton
             unduplicated_bookmarks += bookmark;
 
             Bookmark bookmark_row = new Bookmark (bookmark);
-            if (ModelUtils.is_key_path (bookmark))
+            if (bookmark.has_prefix ("?"))
+            {
+                Variant variant = new Variant.string (bookmark.slice (1, bookmark.length));
+                bookmark_row.set_detailed_action_name ("ui.open-search(" + variant.print (false) + ")");
+            }
+            else if (ModelUtils.is_key_path (bookmark))
             {
                 Variant variant = new Variant ("(sq)", bookmark, ModelUtils.undefined_context_id);
                 bookmark_row.set_detailed_action_name ("ui.open-object(" + variant.print (true) + ")");    
// TODO save context
@@ -219,21 +260,34 @@ private class Bookmarks : MenuButton
             bookmarks_list_box.select_row ((!) first_row);
     }
 
-    private void append_bookmark (string path)
+    private void append_bookmark (string path, ViewType type)
     {
+        string bookmark_name;
+        if (type == ViewType.SEARCH)
+            bookmark_name = "?" + path;
+        else
+            bookmark_name = path;
+
         string [] bookmarks = settings.get_strv ("bookmarks");
-        if (!(path in bookmarks))
-        {
-            bookmarks += path;
-            settings.set_strv ("bookmarks", bookmarks);
-        }
+        if (bookmark_name in bookmarks)
+            return;
+
+        bookmarks += bookmark_name;
+        settings.set_strv ("bookmarks", bookmarks);
     }
 
-    private void remove_bookmark (string bookmark_name)
+    private void remove_bookmark (string path, ViewType type)
     {
+        string bookmark_name;
+        if (type == ViewType.SEARCH)
+            bookmark_name = "?" + path;
+        else
+            bookmark_name = path;
+
         string [] old_bookmarks = settings.get_strv ("bookmarks");
         if (!(bookmark_name in old_bookmarks))
             return;
+
         string [] new_bookmarks = new string [0];
         foreach (string bookmark in old_bookmarks)
             if (bookmark != bookmark_name && !(bookmark in new_bookmarks))
@@ -254,10 +308,28 @@ private class Bookmark : ListBoxRow
     internal Bookmark (string _bookmark_name)
     {
         Object (bookmark_name: _bookmark_name);
-        if (ModelUtils.is_folder_path (bookmark_name))
-            main_grid.get_style_context ().add_class ("folder");
-        bookmark_label.set_label (bookmark_name);
-        Variant variant = new Variant.string (bookmark_name);
-        destroy_button.set_detailed_action_name ("bookmarks.unbookmark(" + variant.print (false) + ")");
+
+        string   bookmark_text;
+        ViewType bookmark_type;
+        if (bookmark_name.has_prefix ("?"))
+        {
+            bookmark_text = bookmark_name.slice (1, bookmark_name.length);
+            bookmark_type = ViewType.SEARCH;
+            main_grid.get_style_context ().add_class ("search");
+        }
+        else
+        {
+            bookmark_text = bookmark_name;
+            if (ModelUtils.is_folder_path (bookmark_text))  // class is updated elsewhere for keys
+            {
+                main_grid.get_style_context ().add_class ("folder");
+                bookmark_type = ViewType.FOLDER;
+            }
+            else
+                bookmark_type = ViewType.OBJECT;
+        }
+        bookmark_label.set_label (bookmark_text);
+        Variant variant = new Variant ("(sy)", bookmark_text, ViewType.to_byte (bookmark_type));
+        destroy_button.set_detailed_action_name ("bookmarks.unbookmark(" + variant.print (true) + ")");
     }
 }
diff --git a/editor/browser-view.vala b/editor/browser-view.vala
index 5ee7b44..e447645 100644
--- a/editor/browser-view.vala
+++ b/editor/browser-view.vala
@@ -19,6 +19,7 @@ using Gtk;
 
 private class SimpleSettingObject : Object
 {
+    public bool is_search           { internal get; internal construct; }
     public uint16 context_id        { internal get; internal construct; }
     public string name              { internal get; internal construct; }
     public string full_name         { internal get; internal construct; }
@@ -30,15 +31,15 @@ private class SimpleSettingObject : Object
         casefolded_name = name.casefold ();
     }
 
-    internal SimpleSettingObject.from_base_path (uint16 _context_id, string _name, string _base_path)
+    internal SimpleSettingObject.from_base_path (uint16 _context_id, string _name, string _base_path, bool 
_is_search = false)
     {
         string _full_name = ModelUtils.recreate_full_name (_base_path, _name, 
ModelUtils.is_folder_context_id (_context_id));
-        Object (context_id: _context_id, name: _name, full_name: _full_name);
+        Object (context_id: _context_id, name: _name, full_name: _full_name, is_search: _is_search);
     }
 
-    internal SimpleSettingObject.from_full_name (uint16 _context_id, string _name, string _full_name)
+    internal SimpleSettingObject.from_full_name (uint16 _context_id, string _name, string _full_name, bool 
_is_search = false)
     {
-        Object (context_id: _context_id, name: _name, full_name: _full_name);
+        Object (context_id: _context_id, name: _name, full_name: _full_name, is_search: _is_search);
     }
 }
 
diff --git a/editor/dconf-editor.css b/editor/dconf-editor.css
index 88f2c99..a72f39e 100644
--- a/editor/dconf-editor.css
+++ b/editor/dconf-editor.css
@@ -88,12 +88,12 @@ list.keys-list > grid.big-popover.dim-label.vertical + grid.vertical {
                                                                                   border-radius 0.3s; } 
stuttering of a single row is almost bearable */
 
                                    .keys-list          > .key-row    { min-height:4.2em; }
-                                   .keys-list          > .folder-row { min-height:2.1em; }
+                                   .keys-list          > .f-or-s-row { min-height:2.1em; }
                                    .keys-list          > row         { margin:0;      padding-top:0.25em; 
padding-bottom:0.25em; }
 .large-window                      .keys-list          > row         { margin:0.25em; padding-top:0;      
padding-bottom:0;      }
 
              .small-keys-list-rows .keys-list          > .key-row    { min-height:2.5em; }
-             .small-keys-list-rows .keys-list          > .folder-row { min-height:1.5em; }
+             .small-keys-list-rows .keys-list          > .f-or-s-row { min-height:1.5em; }
              .small-keys-list-rows .keys-list          > row         { margin:0; padding-top:0; 
padding-bottom:0; }
 .large-window.small-keys-list-rows .keys-list          > row         { margin:0; padding-top:0; 
padding-bottom:0; }
 
@@ -153,6 +153,8 @@ list.keys-list > grid.big-popover.dim-label.vertical + grid.vertical {
              row        >                .folder               { 
background-image:-gtk-icontheme("folder-symbolic"); }
              row:active >                .folder               { 
background-image:-gtk-icontheme("folder-open-symbolic"); }
 
+             row >                       .search               { 
background-image:-gtk-icontheme("edit-find-symbolic"); }
+
              row >                       .key.delayed,
              row >             .dconf-key.key.delayed,
              row >  .edited.gsettings-key.key.delayed          { 
background-image:-gtk-icontheme("document-open-recent-symbolic"); }
diff --git a/editor/dconf-editor.gresource.xml b/editor/dconf-editor.gresource.xml
index 6ea530c..fe0bfe5 100644
--- a/editor/dconf-editor.gresource.xml
+++ b/editor/dconf-editor.gresource.xml
@@ -20,6 +20,7 @@
     <file preprocess="xml-stripblanks">registry-info.ui</file>
     <file preprocess="xml-stripblanks">registry-placeholder.ui</file>
     <file preprocess="xml-stripblanks">registry-view.ui</file>
+    <file preprocess="xml-stripblanks">search-list-box-row.ui</file>
   </gresource>
   <gresource prefix="/ca/desrt/dconf-editor/gtk">
     <file preprocess="xml-stripblanks">help-overlay.ui</file>
diff --git a/editor/dconf-window.vala b/editor/dconf-window.vala
index 06fba37..b124f24 100644
--- a/editor/dconf-window.vala
+++ b/editor/dconf-window.vala
@@ -29,7 +29,29 @@ internal enum RelocatableSchemasEnabledMappings
 internal enum ViewType {
     OBJECT,
     FOLDER,
-    SEARCH
+    SEARCH;
+
+    internal static uint8 to_byte (ViewType type)
+    {
+        switch (type)
+        {
+            case ViewType.OBJECT: return 0;
+            case ViewType.FOLDER: return 1;
+            case ViewType.SEARCH: return 2;
+            default: assert_not_reached ();
+        }
+    }
+
+    internal static ViewType from_byte (uint8 type)
+    {
+        switch (type)
+        {
+            case 0: return ViewType.OBJECT;
+            case 1: return ViewType.FOLDER;
+            case 2: return ViewType.SEARCH;
+            default: assert_not_reached ();
+        }
+    }
 }
 
 [GtkTemplate (ui = "/ca/desrt/dconf-editor/ui/dconf-editor.ui")]
@@ -422,6 +444,7 @@ private class DConfWindow : ApplicationWindow
 
         { "open-folder", open_folder, "s" },
         { "open-object", open_object, "(sq)" },
+        { "open-search", open_search, "s" },
         { "open-parent", open_parent, "s" },
 
         { "reload-folder", reload_folder },
@@ -488,6 +511,16 @@ private class DConfWindow : ApplicationWindow
         request_object (full_name, context_id);
     }
 
+    private void open_search (SimpleAction action, Variant? search_variant)
+        requires (search_variant != null)
+    {
+        path_widget.close_popovers ();
+
+        string search = ((!) search_variant).get_string ();
+
+        request_search (true, PathEntry.SearchMode.EDIT_PATH_SELECT_ALL, search);
+    }
+
     private void open_parent (SimpleAction action, Variant? path_variant)
         requires (path_variant != null)
     {
@@ -530,6 +563,8 @@ private class DConfWindow : ApplicationWindow
 
         foreach (string bookmark in bookmarks)
         {
+            if (bookmark.has_prefix ("?"))
+                continue;
             if (ModelUtils.is_folder_path (bookmark))
                 continue;   // TODO check folder existence
 
@@ -694,7 +729,7 @@ private class DConfWindow : ApplicationWindow
         // path_widget.search_mode_enabled = false; // do last to avoid flickering RegistryView before 
PropertiesView when selecting a search result
     }
 
-    private void request_search (bool reload, PathEntry.SearchMode mode = PathEntry.SearchMode.UNCLEAR)
+    private void request_search (bool reload, PathEntry.SearchMode mode = PathEntry.SearchMode.UNCLEAR, 
string? search = null)
     {
         string selected_row = browser_view.get_selected_row_name ();
         if (reload)
@@ -704,8 +739,9 @@ private class DConfWindow : ApplicationWindow
             reload_search_next = false;
         }
         if (mode != PathEntry.SearchMode.UNCLEAR)
-            path_widget.prepare_search (mode);
-        update_current_path (ViewType.SEARCH, path_widget.text);
+            path_widget.prepare_search (mode, search);
+        string search_text = search == null ? path_widget.text : (!) search;
+        update_current_path (ViewType.SEARCH, search_text);
         browser_view.select_row (selected_row);
         if (!path_widget.entry_has_focus)
             path_widget.entry_grab_focus_without_selecting ();
@@ -893,20 +929,16 @@ private class DConfWindow : ApplicationWindow
                     return true;
 
                 case "d":
-                    if (!path_widget.is_bookmarks_button_sensitive)
-                        return true;
                     if (info_button.active)
                         info_button.active = false;
                     browser_view.discard_row_popover ();
-                    path_widget.set_bookmarked (current_path, true);
+                    path_widget.bookmark_current_path ();
                     return true;
                 case "D":
-                    if (!path_widget.is_bookmarks_button_sensitive)
-                        return true;
                     if (info_button.active)
                         info_button.active = false;
                     browser_view.discard_row_popover ();
-                    path_widget.set_bookmarked (current_path, false);
+                    path_widget.unbookmark_current_path ();
                     return true;
 
                 case "f":
@@ -1031,12 +1063,9 @@ private class DConfWindow : ApplicationWindow
         if (name == "Return" || name == "KP_Enter")
         {
             if (browser_view.current_view == ViewType.SEARCH
-            && path_widget.entry_has_focus
-            && browser_view.return_pressed ())
-            {
-                stop_search ();
+             && path_widget.entry_has_focus
+             && browser_view.return_pressed ())
                 return true;
-            }
             return false;
         }
 
diff --git a/editor/key-list-box-row.vala b/editor/key-list-box-row.vala
index ce5176e..2c7dd84 100644
--- a/editor/key-list-box-row.vala
+++ b/editor/key-list-box-row.vala
@@ -138,6 +138,18 @@ private class FolderListBoxRow : ClickableListBoxRow
     }
 }
 
+[GtkTemplate (ui = "/ca/desrt/dconf-editor/ui/search-list-box-row.ui")]
+private class SearchListBoxRow : ClickableListBoxRow
+{
+    [GtkChild] private Label search_label;
+
+    internal SearchListBoxRow (string search)
+    {
+        Object (full_name: search, context_id: ModelUtils.undefined_context_id);
+        search_label.set_text (search);
+    }
+}
+
 [GtkTemplate (ui = "/ca/desrt/dconf-editor/ui/key-list-box-row.ui")]
 private class KeyListBoxRow : ClickableListBoxRow
 {
@@ -393,10 +405,13 @@ private class ContextPopover : Popover
             case "erase":           action_text = _("Erase key");           break;
 
             /* Translators: "open folder" action in the right-click menu on a folder */
-            case "open":            action_text = _("Open");                break;
+            case "open-folder":     action_text = _("Open");                break;
+
+            /* Translators: "open search" action in the right-click menu on a search */
+            case "open-search":     action_text = _("Search");                break;
 
             /* Translators: "open parent folder" action in the right-click menu on a folder in a search 
result */
-            case "open_parent":     action_text = _("Open parent folder");  break;
+            case "open-parent":     action_text = _("Open parent folder");  break;
 
             /* Translators: "reset recursively" action in the right-click menu on a folder */
             case "recursivereset":  action_text = _("Reset recursively");   break;
diff --git a/editor/meson.build b/editor/meson.build
index aef074f..90f5141 100644
--- a/editor/meson.build
+++ b/editor/meson.build
@@ -112,7 +112,8 @@ resource_data = files(
   'property-row.ui',
   'registry-info.ui',
   'registry-placeholder.ui',
-  'registry-view.ui'
+  'registry-view.ui',
+  'search-list-box-row.ui'
 )
 
 sources += gnome.compile_resources(
diff --git a/editor/pathentry.vala b/editor/pathentry.vala
index 9b19366..2b54087 100644
--- a/editor/pathentry.vala
+++ b/editor/pathentry.vala
@@ -63,7 +63,7 @@ private class PathEntry : Box
 //        if (type == ViewType.SEARCH)
     }
 
-    internal void prepare (SearchMode mode)
+    internal void prepare (SearchMode mode, string? search = null)
     {
         switch (mode)
         {
@@ -73,7 +73,7 @@ private class PathEntry : Box
                 return;
 
             case SearchMode.EDIT_PATH_SELECT_ALL:
-                search_entry.text = current_path;
+                search_entry.text = search == null ? current_path : (!) search;
                 search_entry.grab_focus ();
                 return;
 
diff --git a/editor/pathwidget.vala b/editor/pathwidget.vala
index d0fe5f8..38f2d79 100644
--- a/editor/pathwidget.vala
+++ b/editor/pathwidget.vala
@@ -113,13 +113,12 @@ private class PathWidget : Box
         return true;
     }
 
-    internal void prepare_search (PathEntry.SearchMode mode)
+    internal void prepare_search (PathEntry.SearchMode mode, string? search)
     {
-        searchentry.prepare (mode);
+        searchentry.prepare (mode, search);
     }
 
     /* bookmarks button */
-    internal bool is_bookmarks_button_sensitive { get { return bookmarks_button.sensitive;  }}
     internal bool is_bookmarks_button_active    { get { return bookmarks_button.active;     }}
 
     internal string [] get_bookmarks ()
@@ -127,9 +126,23 @@ private class PathWidget : Box
         return bookmarks_button.get_bookmarks ();
     }
 
-    internal void set_bookmarked (string path, bool new_state)
+    internal void click_bookmarks_button ()
     {
-        bookmarks_button.set_bookmarked (path, new_state);
+        bookmarks_button.clicked ();
+    }
+
+    internal void   bookmark_current_path () {   bookmarks_button.bookmark_current_path (); }
+    internal void unbookmark_current_path () { bookmarks_button.unbookmark_current_path (); }
+
+    internal void close_popovers ()
+    {
+        if (bookmarks_button.active)
+            bookmarks_button.active = false;
+    }
+
+    internal void update_bookmark_icon (string bookmark, bool bookmark_exists, bool bookmark_has_schema = 
false, bool bookmark_is_default = false)
+    {
+        bookmarks_button.update_bookmark_icon (bookmark, bookmark_exists, bookmark_has_schema, 
bookmark_is_default);
     }
 
 /*      string [] tokens = full_name.split (" ");
@@ -146,33 +159,6 @@ private class PathWidget : Box
             index++;
         } */
 
-    /*\
-    * * bookmarks
-    \*/
-
-    construct
-    {
-        // TODO here again, allow to use in UI file "bind-property" without "bind-source", using the 
instanciated object as source
-        bind_property ("search-mode-enabled", bookmarks_button, "sensitive", BindingFlags.SYNC_CREATE | 
BindingFlags.INVERT_BOOLEAN);
-    }
-
-    internal void close_popovers ()
-    {
-        if (bookmarks_button.active)
-            bookmarks_button.active = false;
-    }
-
-    internal void click_bookmarks_button ()
-    {
-        if (bookmarks_button.sensitive)
-            bookmarks_button.clicked ();
-    }
-
-    internal void update_bookmark_icon (string bookmark, bool bookmark_exists, bool bookmark_has_schema = 
false, bool bookmark_is_default = false)
-    {
-        bookmarks_button.update_bookmark_icon (bookmark, bookmark_exists, bookmark_has_schema, 
bookmark_is_default);
-    }
-
     /*\
     * * sizing
     \*/
diff --git a/editor/registry-list.vala b/editor/registry-list.vala
index 16551c1..a351396 100644
--- a/editor/registry-list.vala
+++ b/editor/registry-list.vala
@@ -187,12 +187,12 @@ private abstract class RegistryList : Grid, BrowsableView
 
         ClickableListBoxRow row = (ClickableListBoxRow) ((!) selected_row).get_child ();
 
-        if (ModelUtils.is_folder_context_id (row.context_id))
-            return _get_folder_copy_text (row);
+        if (ModelUtils.is_folder_context_id (row.context_id) || ModelUtils.is_undefined_context_id 
(row.context_id))
+            return _get_folder_or_search_copy_text (row);
         else
             return _get_key_copy_text (row, modifications_handler);
     }
-    private static inline string _get_folder_copy_text (ClickableListBoxRow row)
+    private static inline string _get_folder_or_search_copy_text (ClickableListBoxRow row)
     {
         return row.full_name;
     }
@@ -298,7 +298,11 @@ private abstract class RegistryList : Grid, BrowsableView
                                          && (search_is_path_search
                                           || ModelUtils.get_parent_path (full_name) != (!) 
current_path_if_search_mode);
 
-        if (ModelUtils.is_folder_context_id (context_id))
+        if (setting_object.is_search)
+        {
+            row = new SearchListBoxRow (full_name.slice (1, full_name.length));
+        }
+        else if (ModelUtils.is_folder_context_id (context_id))
         {
             row = new FolderListBoxRow (setting_object.name, full_name, search_mode_non_local_result);
         }
@@ -402,9 +406,15 @@ private abstract class RegistryList : Grid, BrowsableView
 
         wrapper.set_halign (Align.CENTER);
         wrapper.add (row);
-        if (ModelUtils.is_folder_context_id (row.context_id))
+        if (ModelUtils.is_undefined_context_id (row.context_id))
+        {
+            wrapper.get_style_context ().add_class ("f-or-s-row");
+            wrapper.action_name = "ui.open-search";
+            wrapper.set_action_target ("s", row.full_name);
+        }
+        else if (ModelUtils.is_folder_context_id (row.context_id))
         {
-            wrapper.get_style_context ().add_class ("folder-row");
+            wrapper.get_style_context ().add_class ("f-or-s-row");
             wrapper.action_name = "ui.open-folder";
             wrapper.set_action_target ("s", row.full_name);
         }
@@ -597,8 +607,8 @@ private abstract class RegistryList : Grid, BrowsableView
     {
         switch (row.context_id)
         {
-            case ModelUtils.undefined_context_id:
-                assert_not_reached ();
+            case ModelUtils.undefined_context_id:   // TODO search_context_id, and assert_not_reached() on 
undefined_context_id
+                return generate_search_popover (row);
 
             case ModelUtils.folder_context_id:
                 return generate_folder_popover (row);
@@ -614,9 +624,23 @@ private abstract class RegistryList : Grid, BrowsableView
         }
     }
 
+    private static bool generate_search_popover (ClickableListBoxRow row)
+    {
+        if (row.nullable_popover == null)   // do not place in requires 1/5
+            assert_not_reached ();
+
+        ContextPopover popover = (!) row.nullable_popover;
+        Variant variant = new Variant.string (row.full_name);
+
+        popover.new_gaction ("open-search", "ui.open-search(" + variant.print (false) + ")");
+        popover.new_gaction ("copy", "app.copy(" + _get_folder_or_search_copy_text_variant (row).print 
(false) + ")");
+
+        return true;
+    }
+
     private static bool generate_folder_popover (ClickableListBoxRow row)
     {
-        if (row.nullable_popover == null)   // do not place in requires 1/4
+        if (row.nullable_popover == null)   // do not place in requires 2/5
             assert_not_reached ();
 
         ContextPopover popover = (!) row.nullable_popover;
@@ -624,12 +648,12 @@ private abstract class RegistryList : Grid, BrowsableView
 
         if (row.search_result_mode)
         {
-            popover.new_gaction ("open_parent", "ui.open-parent(" + variant.print (false) + ")");
+            popover.new_gaction ("open-parent", "ui.open-parent(" + variant.print (false) + ")");
             popover.new_section ();
         }
 
-        popover.new_gaction ("open", "ui.open-folder(" + variant.print (false) + ")");
-        popover.new_gaction ("copy", "app.copy(" + _get_folder_copy_text_variant (row).print (false) + ")");
+        popover.new_gaction ("open-folder", "ui.open-folder(" + variant.print (false) + ")");
+        popover.new_gaction ("copy", "app.copy(" + _get_folder_or_search_copy_text_variant (row).print 
(false) + ")");
 
         popover.new_section ();
         popover.new_gaction ("recursivereset", "ui.reset-recursive(" + variant.print (false) + ")");
@@ -639,7 +663,7 @@ private abstract class RegistryList : Grid, BrowsableView
 
     private static bool generate_gsettings_popover (KeyListBoxRow row, ModificationsHandler 
modifications_handler, Variant copy_text_variant)
     {
-        if (row.nullable_popover == null)   // do not place in requires 2/4
+        if (row.nullable_popover == null)   // do not place in requires 3/5
             assert_not_reached ();
 
         SettingsModel model = modifications_handler.model;
@@ -671,7 +695,7 @@ private abstract class RegistryList : Grid, BrowsableView
 
         if (row.search_result_mode)
         {
-            popover.new_gaction ("open_parent", "ui.open-parent(" + variant_s.print (false) + ")");
+            popover.new_gaction ("open-parent", "ui.open-parent(" + variant_s.print (false) + ")");
             popover.new_section ();
         }
 
@@ -759,7 +783,7 @@ private abstract class RegistryList : Grid, BrowsableView
 
     private static bool generate_ghost_popover (ClickableListBoxRow row, Variant copy_text_variant)
     {
-        if (row.nullable_popover == null)   // do not place in requires 3/4
+        if (row.nullable_popover == null)   // do not place in requires 4/5
             assert_not_reached ();
 
         ContextPopover popover = (!) row.nullable_popover;
@@ -769,7 +793,7 @@ private abstract class RegistryList : Grid, BrowsableView
 
     private static bool generate_dconf_popover (KeyListBoxRow row, ModificationsHandler 
modifications_handler, Variant copy_text_variant)
     {
-        if (row.nullable_popover == null)   // do not place in requires 4/4
+        if (row.nullable_popover == null)   // do not place in requires 5/5
             assert_not_reached ();
 
         SettingsModel model = modifications_handler.model;
@@ -779,7 +803,7 @@ private abstract class RegistryList : Grid, BrowsableView
 
         if (row.search_result_mode)
         {
-            popover.new_gaction ("open_parent", "ui.open-parent(" + variant_s.print (false) + ")");
+            popover.new_gaction ("open-parent", "ui.open-parent(" + variant_s.print (false) + ")");
             popover.new_section ();
         }
 
@@ -840,9 +864,9 @@ private abstract class RegistryList : Grid, BrowsableView
         row.set_key_value (gvariant);
     }
 
-    private static inline Variant _get_folder_copy_text_variant (ClickableListBoxRow row)
+    private static inline Variant _get_folder_or_search_copy_text_variant (ClickableListBoxRow row)
     {
-        return new Variant.string (_get_folder_copy_text (row));
+        return new Variant.string (_get_folder_or_search_copy_text (row));
     }
     private static inline Variant _get_key_copy_text_variant (ClickableListBoxRow row, ModificationsHandler 
modifications_handler)
     {
diff --git a/editor/registry-search.vala b/editor/registry-search.vala
index a61213a..4395664 100644
--- a/editor/registry-search.vala
+++ b/editor/registry-search.vala
@@ -365,15 +365,28 @@ private class RegistrySearch : RegistryList
                 continue;
             if (ModelUtils.get_parent_path (bookmark) == ModelUtils.get_base_path (current_path))
                 continue;
+            if (bookmark == "?" + term)
+                continue;
 
             uint16 context_id;
             string name;
-            if (!model.get_object (bookmark, out context_id, out name))
-                continue;
+            bool is_search;
+            if (bookmark.has_prefix ("?"))
+            {
+                context_id = ModelUtils.undefined_context_id;
+                name = ModelUtils.get_name (bookmark.slice (1, bookmark.length));
+                is_search = true;
+            }
+            else
+            {
+                if (!model.get_object (bookmark, out context_id, out name, !(ModelUtils.get_parent_path 
(bookmark) in bookmarks)))
+                    continue;
+                is_search = false;
+            }
 
             if (term in name)
             {
-                SimpleSettingObject sso = new SimpleSettingObject.from_full_name (context_id, name, 
bookmark);
+                SimpleSettingObject sso = new SimpleSettingObject.from_full_name (context_id, name, 
bookmark, is_search);
                 list_model.insert (post_bookmarks, sso);
                 post_bookmarks++;
             }
diff --git a/editor/search-list-box-row.ui b/editor/search-list-box-row.ui
new file mode 100644
index 0000000..4bd644b
--- /dev/null
+++ b/editor/search-list-box-row.ui
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <!-- interface-requires gtk+ 3.0 -->
+  <template class="SearchListBoxRow" parent="ClickableListBoxRow">
+    <property name="visible">True</property>
+    <style>
+      <class name="managed"/>
+      <class name="search"/>
+    </style>
+    <child>
+      <object class="GtkGrid">
+        <property name="visible">True</property>
+        <property name="orientation">horizontal</property>
+        <child>
+          <object class="GtkLabel" id="search_label">
+            <property name="visible">True</property>
+            <property name="vexpand">True</property>
+            <property name="xalign">0</property>
+            <property name="ellipsize">end</property> <!-- Epiphany web apps during search... -->
+            <style>
+              <class name="key-name"/>
+            </style>
+          </object>
+        </child>
+      </object>
+    </child>
+  </template>
+</interface>


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]