1 class ConfigurationEditor
: Gtk
.Application
3 private SettingsModel model
;
5 private Settings settings
;
6 private Gtk
.Builder ui
;
7 private Gtk
.ApplicationWindow window
;
8 private int window_width
= 0;
9 private int window_height
= 0;
10 private bool window_is_maximized
= false;
11 private bool window_is_fullscreen
= false;
12 private Gtk
.TreeView dir_tree_view
;
13 private Gtk
.TreeView key_tree_view
;
14 private Gtk
.Grid key_info_grid
;
15 private Gtk
.Label schema_label
;
16 private Gtk
.Label summary_label
;
17 private Gtk
.Label description_label
;
18 private Gtk
.Label type_label
;
19 private Gtk
.Label default_label
;
20 private Gtk
.Action set_default_action
;
21 private Gtk
.Box search_box
;
22 private Gtk
.Entry search_entry
;
23 private Gtk
.Label search_label
;
25 private Key? selected_key
;
27 private const GLib
.ActionEntry
[] action_entries
=
30 { "about", about_cb
},
34 public ConfigurationEditor()
36 Object(application_id
: "ca.desrt.dconf-editor", flags
: ApplicationFlags
.FLAGS_NONE
);
39 protected override void startup()
43 Environment
.set_application_name (_("dconf Editor"));
45 add_action_entries (action_entries
, this
);
47 settings
= new
Settings ("ca.desrt.dconf-editor.Settings");
49 model
= new
SettingsModel();
51 ui
= new Gtk
.Builder();
54 ui
.add_from_resource("/ca/desrt/dconf-editor/dconf-editor.ui");
58 error("Failed to load UI: %s", e
.message
);
60 window
= new Gtk
.ApplicationWindow(this
);
61 window
.set_default_size(600, 300);
62 window
.title
= _("dconf Editor");
63 window
.window_state_event
.connect(main_window_window_state_event_cb
);
64 window
.configure_event
.connect(main_window_configure_event_cb
);
65 window
.add(ui
.get_object("box1") as Gtk
.Box
);
67 var menu_ui
= new Gtk
.Builder();
70 menu_ui
.add_from_resource("/ca/desrt/dconf-editor/dconf-editor-menu.ui");
74 error("Failed to load menu UI: %s", e
.message
);
76 set_app_menu((MenuModel
)menu_ui
.get_object("menu"));
78 window
.set_default_size (settings
.get_int ("window-width"), settings
.get_int ("window-height"));
79 if (settings
.get_boolean ("window-is-fullscreen"))
81 else if (settings
.get_boolean ("window-is-maximized"))
84 dir_tree_view
= new
DConfDirView();
85 dir_tree_view
.set_model(model
);
86 dir_tree_view
.get_selection().changed
.connect(dir_selected_cb
); // FIXME: Put in view
88 var scroll
= ui
.get_object("directory_scrolledwindow") as Gtk
.ScrolledWindow
;
89 scroll
.add(dir_tree_view
);
91 key_tree_view
= new
DConfKeyView();
93 key_tree_view
.get_selection().changed
.connect(key_selected_cb
);
94 scroll
= ui
.get_object("key_scrolledwindow") as Gtk
.ScrolledWindow
;
95 scroll
.add(key_tree_view
);
97 key_info_grid
= ui
.get_object("key_info_grid") as Gtk
.Grid
;
98 schema_label
= ui
.get_object("schema_label") as Gtk
.Label
;
99 summary_label
= ui
.get_object("summary_label") as Gtk
.Label
;
100 description_label
= ui
.get_object("description_label") as Gtk
.Label
;
101 type_label
= ui
.get_object("type_label") as Gtk
.Label
;
102 default_label
= ui
.get_object("default_label") as Gtk
.Label
;
103 set_default_action
= ui
.get_object("set_default_action") as Gtk
.Action
;
104 set_default_action
.activate
.connect(set_default_cb
);
106 search_box
= ui
.get_object("search_box") as Gtk
.Box
;
107 search_box
.key_press_event
.connect ((event
) =>
109 if (event
.keyval
== Gdk
.Key
.Escape
)
116 search_entry
= ui
.get_object("search_entry") as Gtk
.Entry
;
117 search_label
= ui
.get_object("search_label") as Gtk
.Label
;
118 search_entry
.activate
.connect(find_next_cb
);
119 var search_box_close_button
= ui
.get_object("search_box_close_button") as Gtk
.Button
;
120 search_box_close_button
.clicked
.connect(() =>
125 var search_next_button
= ui
.get_object("search_next_button") as Gtk
.Button
;
126 search_next_button
.clicked
.connect(find_next_cb
);
128 /* Always select something */
130 if (model
.get_iter_first(out iter
))
131 dir_tree_view
.get_selection().select_iter(iter
);
134 protected override void activate()
139 protected override void shutdown ()
142 settings
.set_int ("window-width", window_width
);
143 settings
.set_int ("window-height", window_height
);
144 settings
.set_boolean ("window-is-maximized", window_is_maximized
);
145 settings
.set_boolean ("window-is-fullscreen", window_is_fullscreen
);
148 private void dir_selected_cb()
150 KeyModel? key_model
= null;
153 if (dir_tree_view
.get_selection().get_selected(null, out iter
))
154 key_model
= model
.get_directory(iter
).key_model
;
156 key_tree_view
.set_model(key_model
);
158 /* Always select something */
159 if (key_model
!= null && key_model
.get_iter_first(out iter
))
160 key_tree_view
.get_selection().select_iter(iter
);
163 private string key_to_description(Key key
)
165 switch(key
.schema
.type
)
176 if (key
.schema
.range
!= null)
178 min
= key
.schema
.range
.min
;
179 max
= key
.schema
.range
.max
;
186 return _("Integer [%s..%s]").printf(min
.print(false), max
.print(false));
192 return _("Enumeration");
194 return key
.schema
.type
;
198 private void key_selected_cb()
200 if(selected_key
!= null)
201 selected_key
.value_changed
.disconnect(key_changed_cb
);
205 if (key_tree_view
.get_selection().get_selected(out model
, out iter
))
207 var key_model
= (KeyModel
) model
;
208 selected_key
= key_model
.get_key(iter
);
213 if(selected_key
!= null)
214 selected_key
.value_changed
.connect(key_changed_cb
);
216 key_info_grid
.sensitive
= selected_key
!= null;
217 set_default_action
.sensitive
= selected_key
!= null && !selected_key
.is_default
;
219 string schema_name
= "", summary
= "", description
= "", type
= "", default_value
= "";
221 if (selected_key
!= null)
223 if (selected_key
.schema
!= null)
225 var gettext_domain
= selected_key
.schema
.gettext_domain
;
226 schema_name
= selected_key
.schema
.schema
.id
;
227 if (selected_key
.schema
.summary
!= null)
228 summary
= selected_key
.schema
.summary
;
229 if (gettext_domain
!= null && summary
!= "")
230 summary
= dgettext(gettext_domain
, summary
);
231 if (selected_key
.schema
.description
!= null)
232 description
= selected_key
.schema
.description
;
233 if (gettext_domain
!= null && description
!= "")
234 description
= dgettext(gettext_domain
, description
);
235 type
= key_to_description(selected_key
);
236 default_value
= selected_key
.schema
.default_value
.print(false);
240 schema_name
= _("No schema");
244 schema_label
.set_text(schema_name
);
245 summary_label
.set_text(summary
.strip());
246 description_label
.set_text(description
.strip());
247 type_label
.set_text(type
);
248 default_label
.set_text(default_value
);
251 private void key_changed_cb(Key key
)
253 set_default_action
.sensitive
= selected_key
!= null && !selected_key
.is_default
;
256 private void set_default_cb (Gtk
.Action action
)
258 if (selected_key
== null)
260 selected_key
.set_to_default();
263 private bool main_window_configure_event_cb (Gtk
.Widget widget
, Gdk
.EventConfigure event
)
265 if (!window_is_maximized
&& !window_is_fullscreen
)
267 window_width
= event
.width
;
268 window_height
= event
.height
;
274 private bool main_window_window_state_event_cb (Gtk
.Widget widget
, Gdk
.EventWindowState event
)
276 if ((event
.changed_mask
& Gdk
.WindowState
.MAXIMIZED
) != 0)
277 window_is_maximized
= (event
.new_window_state
& Gdk
.WindowState
.MAXIMIZED
) != 0;
278 if ((event
.changed_mask
& Gdk
.WindowState
.FULLSCREEN
) != 0)
279 window_is_fullscreen
= (event
.new_window_state
& Gdk
.WindowState
.FULLSCREEN
) != 0;
284 private void find_cb()
287 search_entry
.grab_focus();
290 private void find_next_cb()
292 search_label
.set_text("");
294 /* Get the current position in the tree */
296 var key_iter
= Gtk
.TreeIter();
297 var have_key_iter
= false;
298 if (dir_tree_view
.get_selection().get_selected(null, out iter
))
300 if (key_tree_view
.get_selection().get_selected(null, out key_iter
))
302 var dir
= model
.get_directory(iter
);
303 if (dir
.key_model
.iter_next(ref key_iter
))
304 have_key_iter
= true;
306 get_next_iter(ref iter
);
309 else if (!model
.get_iter_first(out iter
))
312 var on_first_directory
= true;
315 /* Select next directory that matches */
316 var dir
= model
.get_directory(iter
);
319 have_key_iter
= dir
.key_model
.get_iter_first(out key_iter
);
320 if (!on_first_directory
&& dir
.name
.index_of(search_entry
.text
) >= 0)
322 dir_tree_view
.expand_to_path(model
.get_path(iter
));
323 dir_tree_view
.get_selection().select_iter(iter
);
324 dir_tree_view
.scroll_to_cell(model
.get_path(iter
), null, false, 0, 0);
328 on_first_directory
= false;
330 /* Select next key that matches */
335 var key
= dir
.key_model
.get_key(key_iter
);
336 if (key_matches(key
, search_entry
.text
))
338 dir_tree_view
.expand_to_path(model
.get_path(iter
));
339 dir_tree_view
.get_selection().select_iter(iter
);
340 dir_tree_view
.scroll_to_cell(model
.get_path(iter
), null, false, 0, 0);
341 key_tree_view
.get_selection().select_iter(key_iter
);
342 key_tree_view
.scroll_to_cell(dir
.key_model
.get_path(key_iter
), null, false, 0, 0);
345 } while(dir
.key_model
.iter_next(ref key_iter
));
347 have_key_iter
= false;
348 } while(get_next_iter(ref iter
));
350 search_label
.set_text(_("Not found"));
353 private bool key_matches (Key key
, string text
)
356 if (key
.name
.index_of(text
) >= 0)
359 /* Check key schema (description) */
360 if (key
.schema
!= null)
362 if (key
.schema
.summary
!= null && key
.schema
.summary
.index_of(text
) >= 0)
364 if (key
.schema
.description
!= null && key
.schema
.description
.index_of(text
) >= 0)
368 /* Check key value */
369 if (key
.value
.is_of_type(VariantType
.STRING
) && key
.value
.get_string().index_of(text
) >= 0)
375 private bool get_next_iter(ref Gtk
.TreeIter iter
)
377 /* Search children next */
378 if (model
.iter_has_child(iter
))
380 model
.iter_nth_child(out iter
, iter
, 0);
384 /* Move to the next branch */
385 while (!model
.iter_next(ref iter
))
387 /* Otherwise move to the parent and onto the next iter */
388 if (!model
.iter_parent(out iter
, iter
))
395 private void about_cb()
397 string[] authors
= { "Robert Ancell", null };
398 string license
= _("This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.\n\nThis program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA");
399 Gtk
.show_about_dialog (window
,
400 "program-name", _("dconf Editor"),
401 "version", Config
.VERSION
,
403 _("Directly edit your entire configuration database"),
404 "copyright", _("Copyright \xc2\xa9 Canonical Ltd"),
406 "wrap-license", true,
408 "translator-credits", _("translator-credits"),
409 "logo-icon-name", "dconf-editor",
413 private void quit_cb()
418 public static int main(string[] args
)
420 Intl
.setlocale (LocaleCategory
.ALL
, "");
421 Intl
.bindtextdomain (Config
.GETTEXT_PACKAGE
, Config
.LOCALEDIR
);
422 Intl
.bind_textdomain_codeset (Config
.GETTEXT_PACKAGE
, "UTF-8");
423 Intl
.textdomain (Config
.GETTEXT_PACKAGE
);
425 var app
= new
ConfigurationEditor();
426 return app
.run(args
);