|
Packit Service |
f2b131 |
/*
|
|
Packit Service |
f2b131 |
This file is part of Dconf Editor
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
Dconf Editor is free software: you can redistribute it and/or modify
|
|
Packit Service |
f2b131 |
it under the terms of the GNU General Public License as published by
|
|
Packit Service |
f2b131 |
the Free Software Foundation, either version 3 of the License, or
|
|
Packit Service |
f2b131 |
(at your option) any later version.
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
Dconf Editor is distributed in the hope that it will be useful,
|
|
Packit Service |
f2b131 |
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
f2b131 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit Service |
f2b131 |
GNU General Public License for more details.
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
You should have received a copy of the GNU General Public License
|
|
Packit Service |
f2b131 |
along with Dconf Editor. If not, see <https://www.gnu.org/licenses/>.
|
|
Packit Service |
f2b131 |
*/
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
using Gtk;
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
public interface KeyEditorChild : Widget
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
public signal void value_has_changed (bool is_valid = true);
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
public abstract Variant get_variant ();
|
|
Packit Service |
f2b131 |
public signal void child_activated ();
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
public abstract void reload (Variant gvariant);
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
private class KeyEditorChildSingle : Label, KeyEditorChild
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
private Variant variant;
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
public KeyEditorChildSingle (Variant key_value, string text)
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
variant = key_value;
|
|
Packit Service |
f2b131 |
set_label (text);
|
|
Packit Service |
f2b131 |
show ();
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
public Variant get_variant ()
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
return variant;
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
public void reload (Variant gvariant) {}
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
private class KeyEditorChildEnum : MenuButton, KeyEditorChild
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
private Variant variant;
|
|
Packit Service |
f2b131 |
private GLib.Action action;
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
public KeyEditorChildEnum (Variant initial_value, bool delay_mode, bool has_planned_change, Variant range_content)
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
this.visible = true;
|
|
Packit Service |
f2b131 |
this.hexpand = true;
|
|
Packit Service |
f2b131 |
this.halign = Align.START;
|
|
Packit Service |
f2b131 |
this.use_popover = true;
|
|
Packit Service |
f2b131 |
this.width_request = 100;
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
ContextPopover popover = new ContextPopover ();
|
|
Packit Service |
f2b131 |
action = popover.create_buttons_list (false, delay_mode, has_planned_change, "<enum>", initial_value, range_content);
|
|
Packit Service |
f2b131 |
popover.set_relative_to (this);
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
popover.value_changed.connect ((gvariant) => {
|
|
Packit Service |
f2b131 |
if (gvariant == null) // TODO better (1/3)
|
|
Packit Service |
f2b131 |
assert_not_reached ();
|
|
Packit Service |
f2b131 |
reload ((!) gvariant);
|
|
Packit Service |
f2b131 |
popover.closed ();
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
value_has_changed ();
|
|
Packit Service |
f2b131 |
});
|
|
Packit Service |
f2b131 |
reload (initial_value);
|
|
Packit Service |
f2b131 |
this.set_popover ((Popover) popover);
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
public Variant get_variant ()
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
return variant;
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
public void reload (Variant gvariant)
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
variant = gvariant;
|
|
Packit Service |
f2b131 |
VariantType type = gvariant.get_type ();
|
|
Packit Service |
f2b131 |
label = type == VariantType.STRING ? gvariant.get_string () : gvariant.print (false);
|
|
Packit Service |
f2b131 |
action.change_state (new Variant.maybe (null, new Variant.maybe (type, gvariant)));
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
private class KeyEditorChildFlags : Grid, KeyEditorChild
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
private string [] all_flags;
|
|
Packit Service |
f2b131 |
private ContextPopover popover = new ContextPopover ();
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
private Variant variant;
|
|
Packit Service |
f2b131 |
private Label label = new Label ("");
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
public KeyEditorChildFlags (Variant initial_value, string [] _all_flags, string [] active_flags)
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
all_flags = _all_flags;
|
|
Packit Service |
f2b131 |
this.visible = true;
|
|
Packit Service |
f2b131 |
this.hexpand = true;
|
|
Packit Service |
f2b131 |
this.orientation = Orientation.HORIZONTAL;
|
|
Packit Service |
f2b131 |
this.column_spacing = 8;
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
MenuButton button = new MenuButton ();
|
|
Packit Service |
f2b131 |
button.visible = true;
|
|
Packit Service |
f2b131 |
button.use_popover = true;
|
|
Packit Service |
f2b131 |
button.halign = Align.START;
|
|
Packit Service |
f2b131 |
button.get_style_context ().add_class ("image-button");
|
|
Packit Service |
f2b131 |
this.add (button);
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
label.visible = true;
|
|
Packit Service |
f2b131 |
label.halign = Align.START;
|
|
Packit Service |
f2b131 |
label.hexpand = true;
|
|
Packit Service |
f2b131 |
this.add (label);
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
popover.create_flags_list (active_flags, all_flags);
|
|
Packit Service |
f2b131 |
popover.set_relative_to (button);
|
|
Packit Service |
f2b131 |
popover.value_changed.connect ((gvariant) => {
|
|
Packit Service |
f2b131 |
if (gvariant == null) // TODO better (2/3)
|
|
Packit Service |
f2b131 |
assert_not_reached ();
|
|
Packit Service |
f2b131 |
reload ((!) gvariant);
|
|
Packit Service |
f2b131 |
value_has_changed ();
|
|
Packit Service |
f2b131 |
});
|
|
Packit Service |
f2b131 |
reload (initial_value);
|
|
Packit Service |
f2b131 |
button.set_popover ((Popover) popover);
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
public void update_flags (string [] active_flags)
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
foreach (string flag in all_flags)
|
|
Packit Service |
f2b131 |
popover.update_flag_status (flag, flag in active_flags);
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
public Variant get_variant ()
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
return variant;
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
public void reload (Variant gvariant)
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
this.variant = gvariant;
|
|
Packit Service |
f2b131 |
label.label = gvariant.print (false);
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
private class KeyEditorChildNullableBool : MenuButton, KeyEditorChild
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
private Variant variant;
|
|
Packit Service |
f2b131 |
private Variant? maybe_variant;
|
|
Packit Service |
f2b131 |
private GLib.Action action;
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
public KeyEditorChildNullableBool (Variant initial_value, bool delay_mode, bool has_planned_change, Variant? range_content_or_null)
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
this.visible = true;
|
|
Packit Service |
f2b131 |
this.hexpand = true;
|
|
Packit Service |
f2b131 |
this.halign = Align.START;
|
|
Packit Service |
f2b131 |
this.use_popover = true;
|
|
Packit Service |
f2b131 |
this.width_request = 100;
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
ContextPopover popover = new ContextPopover ();
|
|
Packit Service |
f2b131 |
action = popover.create_buttons_list (false, delay_mode, has_planned_change, "mb", initial_value, range_content_or_null);
|
|
Packit Service |
f2b131 |
popover.set_relative_to (this);
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
popover.value_changed.connect ((gvariant) => {
|
|
Packit Service |
f2b131 |
if (gvariant == null) // TODO better (3/3)
|
|
Packit Service |
f2b131 |
assert_not_reached ();
|
|
Packit Service |
f2b131 |
reload ((!) gvariant);
|
|
Packit Service |
f2b131 |
popover.closed ();
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
value_has_changed ();
|
|
Packit Service |
f2b131 |
});
|
|
Packit Service |
f2b131 |
reload (initial_value);
|
|
Packit Service |
f2b131 |
this.set_popover ((Popover) popover);
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
public Variant get_variant ()
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
return variant;
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
public void reload (Variant gvariant)
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
variant = gvariant;
|
|
Packit Service |
f2b131 |
maybe_variant = variant.get_maybe ();
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
if (maybe_variant == null)
|
|
Packit Service |
f2b131 |
label = Key.cool_boolean_text_value (null);
|
|
Packit Service |
f2b131 |
else
|
|
Packit Service |
f2b131 |
label = Key.cool_boolean_text_value (((!) maybe_variant).get_boolean ());
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
action.change_state (new Variant.maybe (null, new Variant.maybe (new VariantType ("mb"), gvariant)));
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
private class KeyEditorChildBool : Box, KeyEditorChild // might be managed by action, but can't find a way to ensure one-and-only-one button is active // https://bugzilla.gnome.org/show_bug.cgi?id=769876
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
private ToggleButton button_true;
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
public KeyEditorChildBool (bool initial_value)
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
this.visible = true;
|
|
Packit Service |
f2b131 |
this.hexpand = true;
|
|
Packit Service |
f2b131 |
this.orientation = Orientation.HORIZONTAL;
|
|
Packit Service |
f2b131 |
this.halign = Align.START;
|
|
Packit Service |
f2b131 |
this.homogeneous = true;
|
|
Packit Service |
f2b131 |
this.width_request = 100;
|
|
Packit Service |
f2b131 |
this.get_style_context ().add_class ("linked");
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
ToggleButton button_false = new ToggleButton ();
|
|
Packit Service |
f2b131 |
button_false.visible = true;
|
|
Packit Service |
f2b131 |
button_false.label = Key.cool_boolean_text_value (false);
|
|
Packit Service |
f2b131 |
this.add (button_false);
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
button_true = new ToggleButton ();
|
|
Packit Service |
f2b131 |
button_true.visible = true;
|
|
Packit Service |
f2b131 |
button_true.label = Key.cool_boolean_text_value (true);
|
|
Packit Service |
f2b131 |
this.add (button_true);
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
button_true.active = initial_value;
|
|
Packit Service |
f2b131 |
button_true.bind_property ("active", button_false, "active", BindingFlags.INVERT_BOOLEAN|BindingFlags.SYNC_CREATE|BindingFlags.BIDIRECTIONAL);
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
button_true.toggled.connect (() => value_has_changed ());
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
public Variant get_variant ()
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
return new Variant.boolean (button_true.active);
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
public void reload (Variant gvariant)
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
button_true.active = gvariant.get_boolean ();
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
private class KeyEditorChildNumberDouble : Entry, KeyEditorChild
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
private Variant variant;
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
private ulong deleted_text_handler = 0;
|
|
Packit Service |
f2b131 |
private ulong inserted_text_handler = 0;
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
construct
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
get_style_context ().add_class ("key-editor-child-entry");
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
public KeyEditorChildNumberDouble (Variant initial_value)
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
this.variant = initial_value;
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
this.visible = true;
|
|
Packit Service |
f2b131 |
this.hexpand = true;
|
|
Packit Service |
f2b131 |
this.secondary_icon_activatable = false;
|
|
Packit Service |
f2b131 |
this.set_icon_tooltip_text (EntryIconPosition.SECONDARY, _("Failed to parse as double."));
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
this.text = initial_value.print (false);
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
EntryBuffer ref_buffer = buffer; // an EntryBuffer doesn't emit a "destroy" signal
|
|
Packit Service |
f2b131 |
deleted_text_handler = ref_buffer.deleted_text.connect (() => value_has_changed (test_value ()));
|
|
Packit Service |
f2b131 |
inserted_text_handler = ref_buffer.inserted_text.connect (() => value_has_changed (test_value ()));
|
|
Packit Service |
f2b131 |
ulong entry_activate_handler = activate.connect (() => { if (test_value ()) child_activated (); });
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
destroy.connect (() => {
|
|
Packit Service |
f2b131 |
ref_buffer.disconnect (deleted_text_handler);
|
|
Packit Service |
f2b131 |
ref_buffer.disconnect (inserted_text_handler);
|
|
Packit Service |
f2b131 |
disconnect (entry_activate_handler);
|
|
Packit Service |
f2b131 |
});
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
private bool test_value ()
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
string tmp_text = this.text; // don't put in the try{} for correct C code
|
|
Packit Service |
f2b131 |
try
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
Variant? tmp_variant = Variant.parse (VariantType.DOUBLE, tmp_text);
|
|
Packit Service |
f2b131 |
variant = (!) tmp_variant;
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
StyleContext context = get_style_context ();
|
|
Packit Service |
f2b131 |
if (context.has_class ("error"))
|
|
Packit Service |
f2b131 |
context.remove_class ("error");
|
|
Packit Service |
f2b131 |
set_icon_from_icon_name (EntryIconPosition.SECONDARY, null);
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
return true;
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
catch (VariantParseError e)
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
StyleContext context = get_style_context ();
|
|
Packit Service |
f2b131 |
if (!context.has_class ("error"))
|
|
Packit Service |
f2b131 |
context.add_class ("error");
|
|
Packit Service |
f2b131 |
secondary_icon_name = "dialog-error-symbolic";
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
return false;
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
public Variant get_variant ()
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
return variant;
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
private void set_lock (bool state)
|
|
Packit Service |
f2b131 |
requires (deleted_text_handler != 0 && inserted_text_handler != 0)
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
if (state)
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
SignalHandler.block (buffer, deleted_text_handler);
|
|
Packit Service |
f2b131 |
SignalHandler.block (buffer, inserted_text_handler);
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
else
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
SignalHandler.unblock (buffer, deleted_text_handler);
|
|
Packit Service |
f2b131 |
SignalHandler.unblock (buffer, inserted_text_handler);
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
public void reload (Variant gvariant)
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
set_lock (true);
|
|
Packit Service |
f2b131 |
this.text = gvariant.print (false);
|
|
Packit Service |
f2b131 |
if (!test_value ())
|
|
Packit Service |
f2b131 |
assert_not_reached ();
|
|
Packit Service |
f2b131 |
set_lock (false);
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
private class KeyEditorChildNumberInt : SpinButton, KeyEditorChild
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
private string key_type;
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
private ulong deleted_text_handler = 0;
|
|
Packit Service |
f2b131 |
private ulong inserted_text_handler = 0;
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
public KeyEditorChildNumberInt (Variant initial_value, string type_string, Variant? range_content_or_null)
|
|
Packit Service |
f2b131 |
requires (type_string == "y" || type_string == "n" || type_string == "q" || type_string == "i" || type_string == "u" || type_string == "h") // TODO type_string == "x" || type_string == "t" ||
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
this.key_type = type_string;
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
this.visible = true;
|
|
Packit Service |
f2b131 |
this.hexpand = true;
|
|
Packit Service |
f2b131 |
this.halign = Align.START;
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
double min, max;
|
|
Packit Service |
f2b131 |
if (range_content_or_null != null)
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
min = get_variant_as_double (((!) range_content_or_null).get_child_value (0));
|
|
Packit Service |
f2b131 |
max = get_variant_as_double (((!) range_content_or_null).get_child_value (1));
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
else
|
|
Packit Service |
f2b131 |
get_min_and_max_double (out min, out max, type_string);
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
Adjustment adjustment = new Adjustment (get_variant_as_double (initial_value), min, max, 1.0, 5.0, 0.0);
|
|
Packit Service |
f2b131 |
this.configure (adjustment, 1.0, 0);
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
this.update_policy = SpinButtonUpdatePolicy.IF_VALID;
|
|
Packit Service |
f2b131 |
this.snap_to_ticks = true;
|
|
Packit Service |
f2b131 |
this.numeric = true;
|
|
Packit Service |
f2b131 |
this.input_purpose = InputPurpose.NUMBER; // TODO could be DIGITS for UnsignedInt
|
|
Packit Service |
f2b131 |
this.width_chars = 30;
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
EntryBuffer ref_buffer = buffer; // an EntryBuffer doesn't emit a "destroy" signal
|
|
Packit Service |
f2b131 |
deleted_text_handler = ref_buffer.deleted_text.connect (() => value_has_changed ());
|
|
Packit Service |
f2b131 |
inserted_text_handler = ref_buffer.inserted_text.connect (() => value_has_changed ());
|
|
Packit Service |
f2b131 |
ulong entry_activate_handler = activate.connect (() => { update (); child_activated (); });
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
destroy.connect (() => {
|
|
Packit Service |
f2b131 |
ref_buffer.disconnect (deleted_text_handler);
|
|
Packit Service |
f2b131 |
ref_buffer.disconnect (inserted_text_handler);
|
|
Packit Service |
f2b131 |
disconnect (entry_activate_handler);
|
|
Packit Service |
f2b131 |
});
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
private static void get_min_and_max_double (out double min, out double max, string variant_type)
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
switch (variant_type)
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
case "y": min = (double) uint8.MIN; max = (double) uint8.MAX; break;
|
|
Packit Service |
f2b131 |
case "n": min = (double) int16.MIN; max = (double) int16.MAX; break;
|
|
Packit Service |
f2b131 |
case "q": min = (double) uint16.MIN; max = (double) uint16.MAX; break;
|
|
Packit Service |
f2b131 |
case "i": min = (double) int32.MIN; max = (double) int32.MAX; break;
|
|
Packit Service |
f2b131 |
case "u": min = (double) uint32.MIN; max = (double) uint32.MAX; break;
|
|
Packit Service |
f2b131 |
case "h": min = (double) int32.MIN; max = (double) int32.MAX; break;
|
|
Packit Service |
f2b131 |
default: assert_not_reached ();
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
private static double get_variant_as_double (Variant variant)
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
switch (variant.classify ())
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
case Variant.Class.BYTE: return (double) variant.get_byte ();
|
|
Packit Service |
f2b131 |
case Variant.Class.INT16: return (double) variant.get_int16 ();
|
|
Packit Service |
f2b131 |
case Variant.Class.UINT16: return (double) variant.get_uint16 ();
|
|
Packit Service |
f2b131 |
case Variant.Class.INT32: return (double) variant.get_int32 ();
|
|
Packit Service |
f2b131 |
case Variant.Class.UINT32: return (double) variant.get_uint32 ();
|
|
Packit Service |
f2b131 |
case Variant.Class.HANDLE: return (double) variant.get_handle ();
|
|
Packit Service |
f2b131 |
default: assert_not_reached ();
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
public Variant get_variant () // TODO test_value against range
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
switch (key_type)
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
case "y": return new Variant.byte ((uchar) get_int64_from_entry ()); // TODO uchar or uint8?
|
|
Packit Service |
f2b131 |
case "n": return new Variant.int16 ((int16) get_int64_from_entry ());
|
|
Packit Service |
f2b131 |
case "q": return new Variant.uint16 ((uint16) get_int64_from_entry ());
|
|
Packit Service |
f2b131 |
case "i": return new Variant.int32 ((int32) get_int64_from_entry ());
|
|
Packit Service |
f2b131 |
case "u": return new Variant.uint32 ((uint32) get_int64_from_entry ()); // TODO also use get_value_as_int?
|
|
Packit Service |
f2b131 |
case "h": return new Variant.handle ((int32) get_int64_from_entry ());
|
|
Packit Service |
f2b131 |
default: assert_not_reached ();
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
private int64 get_int64_from_entry ()
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
return int64.parse (this.get_text ());
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
private void set_lock (bool state)
|
|
Packit Service |
f2b131 |
requires (deleted_text_handler != 0 && inserted_text_handler != 0)
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
if (state)
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
SignalHandler.block (buffer, deleted_text_handler);
|
|
Packit Service |
f2b131 |
SignalHandler.block (buffer, inserted_text_handler);
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
else
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
SignalHandler.unblock (buffer, deleted_text_handler);
|
|
Packit Service |
f2b131 |
SignalHandler.unblock (buffer, inserted_text_handler);
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
public void reload (Variant gvariant) // TODO "key_editor_child_number_int_real_reload: assertion 'gvariant != NULL' failed" two times when ghosting a key
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
set_lock (true);
|
|
Packit Service |
f2b131 |
this.set_value (get_variant_as_double (gvariant));
|
|
Packit Service |
f2b131 |
set_lock (false);
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
private class KeyEditorChildArray : Grid, KeyEditorChild
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
private TextView text_view;
|
|
Packit Service |
f2b131 |
private Revealer error_revealer;
|
|
Packit Service |
f2b131 |
private string key_type;
|
|
Packit Service |
f2b131 |
private Variant variant;
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
private ulong deleted_text_handler = 0;
|
|
Packit Service |
f2b131 |
private ulong inserted_text_handler = 0;
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
construct
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
get_style_context ().add_class ("key-editor-child-array");
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
public KeyEditorChildArray (string type_string, Variant initial_value)
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
this.visible = true;
|
|
Packit Service |
f2b131 |
this.hexpand = true;
|
|
Packit Service |
f2b131 |
this.vexpand = false;
|
|
Packit Service |
f2b131 |
orientation = Orientation.VERTICAL;
|
|
Packit Service |
f2b131 |
get_style_context ().add_class ("frame");
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
this.key_type = type_string;
|
|
Packit Service |
f2b131 |
this.variant = initial_value;
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
ScrolledWindow scrolled_window = new ScrolledWindow (null, null);
|
|
Packit Service |
f2b131 |
scrolled_window.visible = true;
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
text_view = new TextView ();
|
|
Packit Service |
f2b131 |
text_view.visible = true;
|
|
Packit Service |
f2b131 |
text_view.expand = true;
|
|
Packit Service |
f2b131 |
text_view.wrap_mode = WrapMode.WORD;
|
|
Packit Service |
f2b131 |
text_view.monospace = true;
|
|
Packit Service |
f2b131 |
text_view.key_press_event.connect ((event) => {
|
|
Packit Service |
f2b131 |
string keyval_name = (!) (Gdk.keyval_name (event.keyval) ?? "");
|
|
Packit Service |
f2b131 |
if ((keyval_name == "Return" || keyval_name == "KP_Enter")
|
|
Packit Service |
f2b131 |
&& ((event.state & Gdk.ModifierType.MODIFIER_MASK) == 0)
|
|
Packit Service |
f2b131 |
&& (test_value ()))
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
child_activated ();
|
|
Packit Service |
f2b131 |
return true;
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
return base.key_press_event (event);
|
|
Packit Service |
f2b131 |
});
|
|
Packit Service |
f2b131 |
// https://bugzilla.gnome.org/show_bug.cgi?id=789676
|
|
Packit Service |
f2b131 |
text_view.button_press_event.connect_after (() => Gdk.EVENT_STOP);
|
|
Packit Service |
f2b131 |
text_view.button_release_event.connect_after (() => Gdk.EVENT_STOP);
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
scrolled_window.add (text_view);
|
|
Packit Service |
f2b131 |
add (scrolled_window);
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
error_revealer = new Revealer ();
|
|
Packit Service |
f2b131 |
error_revealer.visible = true;
|
|
Packit Service |
f2b131 |
error_revealer.transition_type = RevealerTransitionType.SLIDE_UP;
|
|
Packit Service |
f2b131 |
error_revealer.reveal_child = false;
|
|
Packit Service |
f2b131 |
add (error_revealer);
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
ActionBar error_bar = new ActionBar ();
|
|
Packit Service |
f2b131 |
error_bar.visible = true;
|
|
Packit Service |
f2b131 |
error_revealer.add (error_bar);
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
Image error_icon = new Image.from_icon_name ("dialog-error-symbolic", IconSize.BUTTON);
|
|
Packit Service |
f2b131 |
error_icon.visible = true;
|
|
Packit Service |
f2b131 |
error_bar.pack_start (error_icon);
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
Label error_label = new Label (_("This value is invalid for the key type."));
|
|
Packit Service |
f2b131 |
error_label.visible = true;
|
|
Packit Service |
f2b131 |
error_bar.pack_start (error_label);
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
text_view.buffer.text = initial_value.print (false);
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
TextBuffer ref_buffer = text_view.buffer; // an TextBuffer doesn't emit a "destroy" signal
|
|
Packit Service |
f2b131 |
deleted_text_handler = ref_buffer.delete_range.connect_after (() => value_has_changed (test_value ()));
|
|
Packit Service |
f2b131 |
inserted_text_handler = ref_buffer.insert_text.connect_after (() => value_has_changed (test_value ()));
|
|
Packit Service |
f2b131 |
destroy.connect (() => {
|
|
Packit Service |
f2b131 |
ref_buffer.disconnect (deleted_text_handler);
|
|
Packit Service |
f2b131 |
ref_buffer.disconnect (inserted_text_handler);
|
|
Packit Service |
f2b131 |
});
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
private bool test_value ()
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
string tmp_text = text_view.buffer.text; // don't put in the try{} for correct C code
|
|
Packit Service |
f2b131 |
try
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
Variant? tmp_variant = Variant.parse (new VariantType (key_type), tmp_text);
|
|
Packit Service |
f2b131 |
variant = (!) tmp_variant;
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
StyleContext context = get_style_context ();
|
|
Packit Service |
f2b131 |
if (context.has_class ("error"))
|
|
Packit Service |
f2b131 |
context.remove_class ("error");
|
|
Packit Service |
f2b131 |
error_revealer.reveal_child = false;
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
return true;
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
catch (VariantParseError e)
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
StyleContext context = get_style_context ();
|
|
Packit Service |
f2b131 |
if (!context.has_class ("error"))
|
|
Packit Service |
f2b131 |
context.add_class ("error");
|
|
Packit Service |
f2b131 |
error_revealer.reveal_child = true;
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
return false;
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
public Variant get_variant ()
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
return variant;
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
private void set_lock (bool state)
|
|
Packit Service |
f2b131 |
requires (deleted_text_handler != 0 && inserted_text_handler != 0)
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
if (state)
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
SignalHandler.block (text_view.buffer, deleted_text_handler);
|
|
Packit Service |
f2b131 |
SignalHandler.block (text_view.buffer, inserted_text_handler);
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
else
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
SignalHandler.unblock (text_view.buffer, deleted_text_handler);
|
|
Packit Service |
f2b131 |
SignalHandler.unblock (text_view.buffer, inserted_text_handler);
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
public void reload (Variant gvariant)
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
set_lock (true);
|
|
Packit Service |
f2b131 |
text_view.buffer.text = gvariant.print (false);
|
|
Packit Service |
f2b131 |
if (!test_value ())
|
|
Packit Service |
f2b131 |
assert_not_reached ();
|
|
Packit Service |
f2b131 |
set_lock (false);
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
private class KeyEditorChildDefault : Entry, KeyEditorChild
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
private string key_type;
|
|
Packit Service |
f2b131 |
private Variant variant;
|
|
Packit Service |
f2b131 |
private bool is_string;
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
private ulong deleted_text_handler = 0;
|
|
Packit Service |
f2b131 |
private ulong inserted_text_handler = 0;
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
construct
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
get_style_context ().add_class ("key-editor-child-entry");
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
public KeyEditorChildDefault (string type_string, Variant initial_value)
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
this.key_type = type_string;
|
|
Packit Service |
f2b131 |
this.variant = initial_value;
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
this.visible = true;
|
|
Packit Service |
f2b131 |
this.hexpand = true;
|
|
Packit Service |
f2b131 |
this.secondary_icon_activatable = false;
|
|
Packit Service |
f2b131 |
this.set_icon_tooltip_text (EntryIconPosition.SECONDARY, _("This value is invalid for the key type."));
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
this.is_string = type_string == "s" || type_string == "o" || type_string == "g";
|
|
Packit Service |
f2b131 |
this.text = is_string ? initial_value.get_string () : initial_value.print (false);
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
EntryBuffer ref_buffer = buffer; // an EntryBuffer doesn't emit a "destroy" signal
|
|
Packit Service |
f2b131 |
deleted_text_handler = ref_buffer.deleted_text.connect (() => value_has_changed (test_value ()));
|
|
Packit Service |
f2b131 |
inserted_text_handler = ref_buffer.inserted_text.connect (() => value_has_changed (test_value ()));
|
|
Packit Service |
f2b131 |
ulong entry_activate_handler = activate.connect (() => { if (test_value ()) child_activated (); });
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
destroy.connect (() => {
|
|
Packit Service |
f2b131 |
ref_buffer.disconnect (deleted_text_handler);
|
|
Packit Service |
f2b131 |
ref_buffer.disconnect (inserted_text_handler);
|
|
Packit Service |
f2b131 |
disconnect (entry_activate_handler);
|
|
Packit Service |
f2b131 |
});
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
private bool test_value ()
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
if (key_type == "s")
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
variant = new Variant.string (this.text);
|
|
Packit Service |
f2b131 |
return true;
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
string tmp_text = is_string ? @"'$text'" : this.text; // don't put in the try{} for correct C code
|
|
Packit Service |
f2b131 |
try
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
Variant? tmp_variant = Variant.parse (new VariantType (key_type), tmp_text);
|
|
Packit Service |
f2b131 |
variant = (!) tmp_variant;
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
StyleContext context = get_style_context ();
|
|
Packit Service |
f2b131 |
if (context.has_class ("error"))
|
|
Packit Service |
f2b131 |
context.remove_class ("error");
|
|
Packit Service |
f2b131 |
set_icon_from_icon_name (EntryIconPosition.SECONDARY, null);
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
return true;
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
catch (VariantParseError e)
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
StyleContext context = get_style_context ();
|
|
Packit Service |
f2b131 |
if (!context.has_class ("error"))
|
|
Packit Service |
f2b131 |
context.add_class ("error");
|
|
Packit Service |
f2b131 |
secondary_icon_name = "dialog-error-symbolic";
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
return false;
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
public Variant get_variant ()
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
return variant;
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
private void set_lock (bool state)
|
|
Packit Service |
f2b131 |
requires (deleted_text_handler != 0 && inserted_text_handler != 0)
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
if (state)
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
SignalHandler.block (buffer, deleted_text_handler);
|
|
Packit Service |
f2b131 |
SignalHandler.block (buffer, inserted_text_handler);
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
else
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
SignalHandler.unblock (buffer, deleted_text_handler);
|
|
Packit Service |
f2b131 |
SignalHandler.unblock (buffer, inserted_text_handler);
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
|
|
Packit Service |
f2b131 |
public void reload (Variant gvariant)
|
|
Packit Service |
f2b131 |
{
|
|
Packit Service |
f2b131 |
set_lock (true);
|
|
Packit Service |
f2b131 |
this.text = is_string ? gvariant.get_string () : gvariant.print (false);
|
|
Packit Service |
f2b131 |
if (!test_value ())
|
|
Packit Service |
f2b131 |
assert_not_reached ();
|
|
Packit Service |
f2b131 |
set_lock (false);
|
|
Packit Service |
f2b131 |
}
|
|
Packit Service |
f2b131 |
}
|