[Xfce4-commits] <xfce4-settings:nick/settings-editor> WIP: Make the properties dialog work.
Nick Schermer
noreply at xfce.org
Sun Feb 5 14:14:01 CET 2012
Updating branch refs/heads/nick/settings-editor
to 46204e9a5abf36dd12a55de22a0cb5e831f377d6 (commit)
from 06c13c07a9823f3a501f013e0498a7cf7f21adc5 (commit)
commit 46204e9a5abf36dd12a55de22a0cb5e831f377d6
Author: Nick Schermer <nick at xfce.org>
Date: Sun Feb 5 00:07:59 2012 +0100
WIP: Make the properties dialog work.
.../xfce-settings-editor-dialog.c | 77 +++--
xfce4-settings-editor/xfce-settings-prop-dialog.c | 310 ++++++++++++++++----
2 files changed, 308 insertions(+), 79 deletions(-)
diff --git a/xfce4-settings-editor/xfce-settings-editor-dialog.c b/xfce4-settings-editor/xfce-settings-editor-dialog.c
index 75a3126..318c36c 100644
--- a/xfce4-settings-editor/xfce-settings-editor-dialog.c
+++ b/xfce4-settings-editor/xfce-settings-editor-dialog.c
@@ -610,14 +610,15 @@ xfce_settings_editor_dialog_property_changed (XfconfChannel *channel,
const GValue *value,
XfceSettingsEditorDialog *dialog)
{
- GtkTreePath *path = NULL;
- DeleteContext *context;
- GtkTreeIter child_iter;
- GtkTreeModel *model;
- GValue parent_val = { 0, };
- GtkTreeIter parent_iter;
- gboolean empty_prop;
- gboolean has_parent;
+ GtkTreePath *path = NULL;
+ DeleteContext *context;
+ GtkTreeIter child_iter;
+ GtkTreeModel *model;
+ GValue parent_val = { 0, };
+ GtkTreeIter parent_iter;
+ gboolean empty_prop;
+ gboolean has_parent;
+ GtkTreeSelection *selection;
g_return_if_fail (GTK_IS_TREE_STORE (dialog->props_store));
g_return_if_fail (XFCONF_IS_CHANNEL (channel));
@@ -648,30 +649,44 @@ xfce_settings_editor_dialog_property_changed (XfconfChannel *channel,
{
if (gtk_tree_model_get_iter (model, &child_iter, context->path))
{
- /* delete the value */
- has_parent = gtk_tree_model_iter_parent (model, &parent_iter, &child_iter);
- gtk_tree_store_remove (GTK_TREE_STORE (model), &child_iter);
-
- /* remove the parent nodes if they are empty */
- while (has_parent)
+ if (gtk_tree_model_iter_has_child (model, &child_iter))
{
- /* if the parent still has children, stop cleaning */
- if (gtk_tree_model_iter_has_child (model, &parent_iter))
- break;
-
- /* maybe the parent has a value */
- gtk_tree_model_get_value (model, &parent_iter, PROP_COLUMN_FULL, &parent_val);
- empty_prop = g_value_get_string (&parent_val) == NULL;
- g_value_unset (&parent_val);
-
- /* nope it points to a real xfconf property */
- if (!empty_prop)
- break;
-
- /* get the parent and remove the empty row */
- child_iter = parent_iter;
+ /* the node has children, so only unset it */
+ gtk_tree_store_set (GTK_TREE_STORE (model), &child_iter,
+ PROP_COLUMN_FULL, NULL,
+ PROP_COLUMN_TYPE, NULL,
+ PROP_COLUMN_TYPE_NAME, _("Empty"),
+ PROP_COLUMN_LOCKED, FALSE,
+ PROP_COLUMN_VALUE, NULL,
+ -1);
+ }
+ else
+ {
+ /* delete the node */
has_parent = gtk_tree_model_iter_parent (model, &parent_iter, &child_iter);
gtk_tree_store_remove (GTK_TREE_STORE (model), &child_iter);
+
+ /* remove the parent nodes if they are empty */
+ while (has_parent)
+ {
+ /* if the parent still has children, stop cleaning */
+ if (gtk_tree_model_iter_has_child (model, &parent_iter))
+ break;
+
+ /* maybe the parent has a value */
+ gtk_tree_model_get_value (model, &parent_iter, PROP_COLUMN_FULL, &parent_val);
+ empty_prop = g_value_get_string (&parent_val) == NULL;
+ g_value_unset (&parent_val);
+
+ /* nope it points to a real xfconf property */
+ if (!empty_prop)
+ break;
+
+ /* get the parent and remove the empty row */
+ child_iter = parent_iter;
+ has_parent = gtk_tree_model_iter_parent (model, &parent_iter, &child_iter);
+ gtk_tree_store_remove (GTK_TREE_STORE (model), &child_iter);
+ }
}
}
@@ -680,6 +695,10 @@ xfce_settings_editor_dialog_property_changed (XfconfChannel *channel,
g_slice_free (DeleteContext, context);
}
+
+ /* update button sensitivity */
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dialog->props_treeview));
+ xfce_settings_editor_dialog_selection_changed (selection, dialog);
}
diff --git a/xfce4-settings-editor/xfce-settings-prop-dialog.c b/xfce4-settings-editor/xfce-settings-prop-dialog.c
index 5ae5f57..e2bcc35 100644
--- a/xfce4-settings-editor/xfce-settings-prop-dialog.c
+++ b/xfce4-settings-editor/xfce-settings-prop-dialog.c
@@ -50,11 +50,8 @@ struct _XfceSettingsPropDialog
GtkDialog __parent__;
XfconfChannel *channel;
- gchar *property;
- GValue cancel_value;
-
- gulong prop_binding;
+ GValue prop_value;
GtkWidget *prop_name;
GtkWidget *prop_type;
@@ -77,6 +74,8 @@ static void xfce_settings_prop_dialog_response (GtkDialog
gint response_id);
static void xfce_settings_prop_dialog_visible_bind (GtkWidget *widget,
GtkWidget *label);
+static void xfce_settings_prop_dialog_entry_validate (GtkWidget *entry,
+ XfceSettingsPropDialog *dialog);
static void xfce_settings_prop_dialog_button_toggled (GtkWidget *button);
static void xfce_settings_prop_dialog_type_changed (GtkWidget *combo,
XfceSettingsPropDialog *dialog);
@@ -140,7 +139,7 @@ xfce_settings_prop_dialog_init (XfceSettingsPropDialog *dialog)
guint i;
GtkCellRenderer *render;
- gtk_window_set_title (GTK_WINDOW (dialog), _("Edit Property"));
+ gtk_window_set_title (GTK_WINDOW (dialog), _("New Property"));
gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 200);
gtk_dialog_add_buttons (GTK_DIALOG (dialog),
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
@@ -165,6 +164,8 @@ xfce_settings_prop_dialog_init (XfceSettingsPropDialog *dialog)
gtk_table_attach (GTK_TABLE (table), entry, 1, 2, 0, 1,
GTK_FILL | GTK_EXPAND, GTK_FILL, 0, 0);
xfce_settings_prop_dialog_visible_bind (entry, label);
+ g_signal_connect (G_OBJECT (entry), "changed",
+ G_CALLBACK (xfce_settings_prop_dialog_entry_validate), dialog);
gtk_widget_show (entry);
label = gtk_label_new_with_mnemonic (_("_Type:"));
@@ -244,10 +245,8 @@ xfce_settings_prop_dialog_finalize (GObject *object)
if (dialog->channel != NULL)
g_object_unref (G_OBJECT (dialog->channel));
- if (G_IS_VALUE (&dialog->cancel_value))
- g_value_unset (&dialog->cancel_value);
-
- g_free (dialog->property);
+ if (G_IS_VALUE (&dialog->prop_value))
+ g_value_unset (&dialog->prop_value);
G_OBJECT_CLASS (xfce_settings_prop_dialog_parent_class)->finalize (object);
}
@@ -259,17 +258,73 @@ xfce_settings_prop_dialog_response (GtkDialog *widget,
gint response_id)
{
XfceSettingsPropDialog *dialog = XFCE_SETTINGS_PROP_DIALOG (widget);
+ const gchar *property;
+ ValueTypes *value_type;
+ GValue value = { 0, };
+ gdouble spin_value;
+ gint active;
g_return_if_fail (XFCONF_IS_CHANNEL (dialog->channel));
- if (response_id == GTK_RESPONSE_CANCEL
- && G_IS_VALUE (&dialog->cancel_value)
- && dialog->property != NULL)
+ if (response_id == GTK_RESPONSE_OK)
{
- /* restore value */
- xfconf_channel_set_property (dialog->channel,
- dialog->property,
- &dialog->cancel_value);
+ property = gtk_entry_get_text (GTK_ENTRY (dialog->prop_name));
+
+ active = gtk_combo_box_get_active (GTK_COMBO_BOX (dialog->prop_type));
+ g_assert (active >= 0 && active < (gint) G_N_ELEMENTS (value_types));
+ value_type = &value_types[active];
+
+ spin_value = gtk_spin_button_get_value (GTK_SPIN_BUTTON (dialog->prop_integer));
+
+ switch (value_type->type)
+ {
+ case G_TYPE_BOXED:
+ case G_TYPE_NONE:
+ return;
+
+ case G_TYPE_STRING:
+ g_value_init (&value, G_TYPE_STRING);
+ g_value_set_static_string (&value,
+ gtk_entry_get_text (GTK_ENTRY (dialog->prop_string)));
+ break;
+
+ case G_TYPE_BOOLEAN:
+ g_value_init (&value, G_TYPE_BOOLEAN);
+ g_value_set_boolean (&value,
+ gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->prop_bool)));
+ break;
+
+ case G_TYPE_INT:
+ g_value_init (&value, G_TYPE_INT);
+ g_value_set_int (&value, spin_value);
+ break;
+
+ case G_TYPE_DOUBLE:
+ g_value_init (&value, G_TYPE_DOUBLE);
+ g_value_set_double (&value, spin_value);
+ break;
+
+ case G_TYPE_UINT:
+ g_value_init (&value, G_TYPE_UINT);
+ g_value_set_uint (&value, spin_value);
+ break;
+
+ case G_TYPE_INT64:
+ g_value_init (&value, G_TYPE_INT64);
+ g_value_set_int64 (&value, spin_value);
+ break;
+
+ case G_TYPE_UINT64:
+ g_value_init (&value, G_TYPE_UINT64);
+ g_value_set_uint64 (&value, spin_value);
+ break;
+ }
+
+ if (G_IS_VALUE (&value))
+ {
+ xfconf_channel_set_property (dialog->channel, property, &value);
+ g_value_unset (&value);
+ }
}
}
@@ -314,6 +369,117 @@ xfce_settings_prop_dialog_visible_bind (GtkWidget *widget,
+/* Copied from xfconfd/xfconf-backend.c */
+static gboolean
+xfconf_property_is_valid (const gchar *property,
+ GError **error)
+{
+ const gchar *p = property;
+
+ if (!p || *p != '/')
+ {
+ if (error != NULL)
+ {
+ g_set_error (error, XFCONF_ERROR, XFCONF_ERROR_INVALID_PROPERTY,
+ _("Property names must start with a '/' character"));
+ }
+ return FALSE;
+ }
+
+ p++;
+ if (!*p)
+ {
+ if (error != NULL)
+ {
+ g_set_error (error, XFCONF_ERROR, XFCONF_ERROR_INVALID_PROPERTY,
+ _("The root element ('/') is not a valid property name"));
+ }
+ return FALSE;
+ }
+
+ while (*p)
+ {
+ if (!(*p >= 'A' && *p <= 'Z') && !(*p >= 'a' && *p <= 'z')
+ && !(*p >= '0' && *p <= '9')
+ && *p != '_' && *p != '-' && *p != '/'
+ && !(*p == '<' || *p == '>'))
+ {
+ if (error != NULL)
+ {
+ g_set_error (error, XFCONF_ERROR,
+ XFCONF_ERROR_INVALID_PROPERTY,
+ _("Property names can only include the ASCII "
+ "characters A-Z, a-z, 0-9, '_', '-', '<' "
+ "and '>', as well as '/' as a separator"));
+ }
+ return FALSE;
+ }
+
+ if ('/' == *p && '/' == *(p - 1))
+ {
+ if (error != NULL)
+ {
+ g_set_error (error, XFCONF_ERROR,
+ XFCONF_ERROR_INVALID_PROPERTY,
+ _("Property names cannot have two or more "
+ "consecutive '/' characters"));
+ }
+ return FALSE;
+ }
+
+ p++;
+ }
+
+ if (*(p - 1) == '/')
+ {
+ if (error != NULL)
+ {
+ g_set_error (error, XFCONF_ERROR, XFCONF_ERROR_INVALID_PROPERTY,
+ _("Property names cannot end with a '/' character"));
+ }
+
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+
+static void
+xfce_settings_prop_dialog_entry_validate (GtkWidget *entry,
+ XfceSettingsPropDialog *dialog)
+{
+ GtkWidget *save_button;
+ const gchar *text;
+ gboolean is_valid = FALSE;
+ GError *error = NULL;
+
+ text = gtk_entry_get_text (GTK_ENTRY (entry));
+
+ if (text != NULL && *text != '\0')
+ {
+ is_valid = xfconf_property_is_valid (text, &error);
+
+ gtk_entry_set_icon_from_stock (GTK_ENTRY (entry), GTK_ENTRY_ICON_SECONDARY,
+ is_valid ? NULL : GTK_STOCK_DIALOG_ERROR);
+ gtk_entry_set_icon_tooltip_text (GTK_ENTRY (entry), GTK_ENTRY_ICON_SECONDARY,
+ is_valid ? NULL : error->message);
+
+ if (error != NULL)
+ g_error_free (error);
+ }
+ else
+ {
+ gtk_entry_set_icon_from_stock (GTK_ENTRY (entry), GTK_ENTRY_ICON_SECONDARY, NULL);
+ }
+
+ save_button = gtk_dialog_get_widget_for_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
+ gtk_widget_set_sensitive (save_button, is_valid);
+}
+
+
+
static void
xfce_settings_prop_dialog_button_toggled (GtkWidget *button)
{
@@ -329,18 +495,18 @@ static void
xfce_settings_prop_dialog_type_changed (GtkWidget *combo,
XfceSettingsPropDialog *dialog)
{
- gint active;
- ValueTypes *value_type;
+ gint active;
+ ValueTypes *value_type;
+ const GValue *value = &dialog->prop_value;
gtk_widget_hide (dialog->prop_string);
gtk_widget_hide (dialog->prop_integer);
gtk_widget_hide (dialog->prop_bool);
- if (dialog->prop_binding != 0)
- {
- xfconf_g_property_unbind (dialog->prop_binding);
- dialog->prop_binding = 0;
- }
+ gtk_spin_button_set_digits (GTK_SPIN_BUTTON (dialog->prop_integer), 0);
+ gtk_entry_set_text (GTK_ENTRY (dialog->prop_string), "");
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (dialog->prop_integer), 0);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->prop_bool), FALSE);
active = gtk_combo_box_get_active (GTK_COMBO_BOX (combo));
if (active < 0 || active >= (gint) G_N_ELEMENTS (value_types))
@@ -351,51 +517,95 @@ xfce_settings_prop_dialog_type_changed (GtkWidget *combo,
switch (value_type->type)
{
case G_TYPE_NONE:
+ case G_TYPE_BOXED:
+ gtk_widget_grab_focus (dialog->prop_type);
return;
case G_TYPE_STRING:
gtk_widget_show (dialog->prop_string);
+ gtk_widget_grab_focus (dialog->prop_string);
- if (dialog->property != NULL)
+ if (G_VALUE_HOLDS_STRING (value))
{
- dialog->prop_binding = xfconf_g_property_bind (dialog->channel,
- dialog->property,
- G_TYPE_STRING,
- dialog->prop_string,
- "text");
+ gtk_entry_set_text (GTK_ENTRY (dialog->prop_string),
+ g_value_get_string (value));
}
break;
case G_TYPE_BOOLEAN:
gtk_widget_show (dialog->prop_bool);
+ gtk_widget_grab_focus (dialog->prop_bool);
- if (dialog->property != NULL)
+ if (G_VALUE_HOLDS_BOOLEAN (value))
{
- dialog->prop_binding = xfconf_g_property_bind (dialog->channel,
- dialog->property,
- G_TYPE_BOOLEAN,
- dialog->prop_bool,
- "active");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->prop_bool),
+ g_value_get_boolean (value));
}
break;
- case G_TYPE_BOXED:
+ case G_TYPE_INT:
+ gtk_widget_show (dialog->prop_integer);
+ gtk_widget_grab_focus (dialog->prop_integer);
+ gtk_spin_button_set_range (GTK_SPIN_BUTTON (dialog->prop_integer),
+ G_MININT, G_MAXINT);
+
+ if (G_VALUE_HOLDS_INT (value))
+ {
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (dialog->prop_integer),
+ g_value_get_int (value));
+ }
break;
- case G_TYPE_INT:
case G_TYPE_DOUBLE:
+ gtk_widget_show (dialog->prop_integer);
+ gtk_widget_grab_focus (dialog->prop_integer);
+ gtk_spin_button_set_digits (GTK_SPIN_BUTTON (dialog->prop_integer), 4);
+ gtk_spin_button_set_range (GTK_SPIN_BUTTON (dialog->prop_integer),
+ G_MINDOUBLE, G_MAXDOUBLE);
+
+ if (G_VALUE_HOLDS_DOUBLE (value))
+ {
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (dialog->prop_integer),
+ g_value_get_double (value));
+ }
+ break;
+
case G_TYPE_UINT:
+ gtk_widget_show (dialog->prop_integer);
+ gtk_widget_grab_focus (dialog->prop_integer);
+ gtk_spin_button_set_range (GTK_SPIN_BUTTON (dialog->prop_integer),
+ 0, G_MAXUINT);
+
+ if (G_VALUE_HOLDS_UINT (value))
+ {
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (dialog->prop_integer),
+ g_value_get_uint (value));
+ }
+ break;
+
case G_TYPE_INT64:
+ gtk_widget_show (dialog->prop_integer);
+ gtk_widget_grab_focus (dialog->prop_integer);
+ gtk_spin_button_set_range (GTK_SPIN_BUTTON (dialog->prop_integer),
+ G_MININT64, G_MAXINT64);
+
+ if (G_VALUE_HOLDS_INT64 (value))
+ {
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (dialog->prop_integer),
+ g_value_get_int64 (value));
+ }
+ break;
+
case G_TYPE_UINT64:
gtk_widget_show (dialog->prop_integer);
+ gtk_widget_grab_focus (dialog->prop_integer);
+ gtk_spin_button_set_range (GTK_SPIN_BUTTON (dialog->prop_integer),
+ 0, G_MAXUINT64);
- if (dialog->property != NULL)
+ if (G_VALUE_HOLDS_UINT64 (value))
{
- dialog->prop_binding = xfconf_g_property_bind (dialog->channel,
- dialog->property,
- value_type->type,
- dialog->prop_integer,
- "value");
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (dialog->prop_integer),
+ g_value_get_uint64 (value));
}
break;
}
@@ -437,19 +647,19 @@ xfce_settings_prop_dialog_new (GtkWindow *parent,
dialog = g_object_new (XFCE_TYPE_SETTINGS_PROP_DIALOG, NULL);
dialog->channel = g_object_ref (G_OBJECT (channel));
- dialog->property = g_strdup (property);
if (property != NULL)
{
- /* save property for restoring later */
- xfconf_channel_get_property (channel, property, &dialog->cancel_value);
-
gtk_entry_set_text (GTK_ENTRY (dialog->prop_name), property);
gtk_editable_set_editable (GTK_EDITABLE (dialog->prop_name), FALSE);
+ gtk_window_set_title (GTK_WINDOW (dialog), _("Edit Property"));
- xfce_settings_prop_dialog_type_set_active (dialog,
- G_VALUE_TYPE (&dialog->cancel_value));
- gtk_widget_set_sensitive (dialog->prop_type, FALSE);
+ if (xfconf_channel_get_property (channel, property, &dialog->prop_value))
+ {
+ xfce_settings_prop_dialog_type_set_active (dialog,
+ G_VALUE_TYPE (&dialog->prop_value));
+ gtk_widget_set_sensitive (dialog->prop_type, FALSE);
+ }
}
/* set the transient parent (if any) */
More information about the Xfce4-commits
mailing list