[Xfce4-commits] r27304 - in xfce4-settings/trunk: . dialogs/keyboard-settings

Jannis Pohlmann jannis at xfce.org
Wed Jul 16 00:57:11 CEST 2008


Author: jannis
Date: 2008-07-15 22:57:11 +0000 (Tue, 15 Jul 2008)
New Revision: 27304

Added:
   xfce4-settings/trunk/dialogs/keyboard-settings/command-dialog.c
   xfce4-settings/trunk/dialogs/keyboard-settings/command-dialog.h
Modified:
   xfce4-settings/trunk/ChangeLog
   xfce4-settings/trunk/dialogs/keyboard-settings/Makefile.am
   xfce4-settings/trunk/dialogs/keyboard-settings/keyboard-dialog.glade
   xfce4-settings/trunk/dialogs/keyboard-settings/main.c
   xfce4-settings/trunk/dialogs/keyboard-settings/shortcut-dialog.c
   xfce4-settings/trunk/dialogs/keyboard-settings/shortcut-dialog.h
Log:
	* dialogs/keyboard-settings/Makefile.am,
	  dialogs/keyboard-settings/command-dialog{c,h},
	  dialogs/keyboard-settings/main.c,
	  dialogs/keyboard-settings/shortcut-dialog.{c,h}: Add command dialog
	  for entering/selecting a command for a shortcut. Finally implement
	  the button for adding a new shortcut. Editing both, shortcuts and
	  commands also works now. I might have to tweak the command dialog a
	  little so the file chooser behaves similar to the panel launcher
	  dialog. The last thing really missing now is that the
	  xfce4-settings-helper refreshes itself when a shortcut is
	  changed/removed/added.

Modified: xfce4-settings/trunk/ChangeLog
===================================================================
--- xfce4-settings/trunk/ChangeLog	2008-07-15 20:35:13 UTC (rev 27303)
+++ xfce4-settings/trunk/ChangeLog	2008-07-15 22:57:11 UTC (rev 27304)
@@ -1,10 +1,24 @@
-2008-07-14	Nick Schermer <nick at xfce.org>
+2008-07-16	Jannis Pohlmann <jannis at xfce.org>
 
+	* dialogs/keyboard-settings/Makefile.am,
+	  dialogs/keyboard-settings/command-dialog{c,h},
+	  dialogs/keyboard-settings/main.c,
+	  dialogs/keyboard-settings/shortcut-dialog.{c,h}: Add command dialog
+	  for entering/selecting a command for a shortcut. Finally implement
+	  the button for adding a new shortcut. Editing both, shortcuts and
+	  commands also works now. I might have to tweak the command dialog a
+	  little so the file chooser behaves similar to the panel launcher
+	  dialog. The last thing really missing now is that the
+	  xfce4-settings-helper refreshes itself when a shortcut is
+	  changed/removed/added.
+
+2008-07-15	Nick Schermer <nick at xfce.org>
+
 	* dialogs/display-settings/main.c: Read the gamma settings,
 	  free the xrandr screen info and usse permissions when reading
 	  from xf86vmode.
 
-2008-07-14	Nick Schermer <nick at xfce.org>
+2008-07-15	Nick Schermer <nick at xfce.org>
 
 	* configure.ac.in: Show if Xf86misc was found.
 

Modified: xfce4-settings/trunk/dialogs/keyboard-settings/Makefile.am
===================================================================
--- xfce4-settings/trunk/dialogs/keyboard-settings/Makefile.am	2008-07-15 20:35:13 UTC (rev 27303)
+++ xfce4-settings/trunk/dialogs/keyboard-settings/Makefile.am	2008-07-15 22:57:11 UTC (rev 27304)
@@ -3,6 +3,7 @@
 INCLUDES = \
 	-I${top_srcdir} \
 	-DDATADIR=\"$(datadir)\" \
+	-DBINDIR=\"$(bindir)\" \
 	-DSRCDIR=\"$(top_srcdir)\" \
 	-DLOCALEDIR=\"$(localedir)\" \
 	-DG_LOG_DOMAIN=\"xfce4-keyboard-settings\" \
@@ -15,6 +16,8 @@
 	main.c \
 	shortcut-dialog.c \
 	shortcut-dialog.h \
+	command-dialog.c \
+	command-dialog.h \
 	keyboard-dialog_glade.h
 
 xfce4_keyboard_settings_CFLAGS = \

Added: xfce4-settings/trunk/dialogs/keyboard-settings/command-dialog.c
===================================================================
--- xfce4-settings/trunk/dialogs/keyboard-settings/command-dialog.c	                        (rev 0)
+++ xfce4-settings/trunk/dialogs/keyboard-settings/command-dialog.c	2008-07-15 22:57:11 UTC (rev 27304)
@@ -0,0 +1,313 @@
+/* vi:set sw=2 sts=2 ts=2 et ai: */
+/*-
+ * Copyright (c) 2008 Jannis Pohlmann <jannis at xfce.org>.
+ *
+ * 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.
+ *
+ * This 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.
+ *
+ * You should have received a copy of the GNU General Public License 
+ * along with this program; if not, write to the Free Software 
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
+ * MA  02111-1307  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gtk/gtk.h>
+
+#include <libxfce4util/libxfce4util.h>
+#include <libxfcegui4/libxfcegui4.h>
+
+#include "command-dialog.h"
+
+
+
+static void command_dialog_class_init      (CommandDialogClass *klass);
+static void command_dialog_init            (CommandDialog      *dialog);
+static void command_dialog_dispose         (GObject             *object);
+static void command_dialog_finalize        (GObject             *object);
+static void command_dialog_create_contents (CommandDialog      *dialog,
+                                            const gchar        *shortcut,
+                                            const gchar        *action);
+static void command_dialog_button_clicked  (CommandDialog      *dialog);
+
+
+
+struct _CommandDialogClass
+{
+  XfceTitledDialogClass __parent__;
+};
+
+struct _CommandDialog
+{
+  XfceTitledDialog __parent__;
+
+  GtkWidget *entry;
+  GtkWidget *button;
+};
+
+
+
+static GObjectClass *command_dialog_parent_class = NULL;
+
+
+
+GType
+command_dialog_get_type (void)
+{
+  static GType type = G_TYPE_INVALID;
+
+  if (G_UNLIKELY (type == G_TYPE_INVALID))
+    {
+      static const GTypeInfo info = 
+        {
+          sizeof (CommandDialogClass),
+          NULL,
+          NULL,
+          (GClassInitFunc) command_dialog_class_init,
+          NULL,
+          NULL,
+          sizeof (CommandDialog),
+          0,
+          (GInstanceInitFunc) command_dialog_init,
+          NULL,
+        };
+
+      type = g_type_register_static (XFCE_TYPE_TITLED_DIALOG, "CommandDialog", &info, 0);
+    }
+  
+  return type;
+}
+
+
+
+static void
+command_dialog_class_init (CommandDialogClass *klass)
+{
+  GObjectClass *gobject_class;
+
+  /* Determine parent type class */
+  command_dialog_parent_class = g_type_class_peek_parent (klass);
+
+  gobject_class = G_OBJECT_CLASS (klass);
+  gobject_class->dispose = command_dialog_dispose;
+  gobject_class->finalize = command_dialog_finalize;
+}
+
+
+
+static void
+command_dialog_init (CommandDialog *dialog)
+{
+  dialog->entry = NULL;
+  dialog->button = NULL;
+}
+
+
+
+static void
+command_dialog_dispose (GObject *object)
+{
+  (*G_OBJECT_CLASS (command_dialog_parent_class)->dispose) (object);
+}
+
+
+
+static void
+command_dialog_finalize (GObject *object)
+{
+  CommandDialog *dialog = COMMAND_DIALOG (object);
+
+  (*G_OBJECT_CLASS (command_dialog_parent_class)->finalize) (object);
+}
+
+
+
+GtkWidget*
+command_dialog_new (const gchar *shortcut,
+                    const gchar *action)
+{
+  CommandDialog *dialog;
+  
+  dialog = COMMAND_DIALOG (g_object_new (TYPE_COMMAND_DIALOG, NULL));
+
+  command_dialog_create_contents (dialog, shortcut, action);
+
+  return GTK_WIDGET (dialog);
+}
+
+
+
+static void 
+command_dialog_create_contents (CommandDialog *dialog,
+                                const gchar   *shortcut,
+                                const gchar   *action)
+{
+  GtkWidget *button;
+  GtkWidget *vbox;
+  GtkWidget *hbox;
+  GtkWidget *image;
+  GtkWidget *label;
+  gchar     *text;
+
+  /* Set dialog title and icon */
+  gtk_window_set_title (GTK_WINDOW (dialog), _("Select shortcut command"));
+  gtk_window_set_icon_name (GTK_WINDOW (dialog), "application-x-executable");
+
+  /* Set subtitle */
+  text = g_strdup_printf (_("Shortcut: %s"), shortcut != NULL ? shortcut : _("Undefined"));
+  xfce_titled_dialog_set_subtitle (XFCE_TITLED_DIALOG (dialog), text);
+  g_free (text);
+
+  /* Configure dialog */
+  gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
+
+  /* Create cancel button */
+  button = gtk_button_new_from_stock (GTK_STOCK_CANCEL);
+  gtk_dialog_add_action_widget (GTK_DIALOG (dialog), button, GTK_RESPONSE_CANCEL);
+  gtk_widget_show (button);
+
+  button = gtk_button_new_from_stock (GTK_STOCK_OK);
+  gtk_dialog_add_action_widget (GTK_DIALOG (dialog), button, GTK_RESPONSE_OK);
+  gtk_widget_show (button);
+
+  hbox = gtk_hbox_new (FALSE, 12);
+  gtk_container_set_border_width (GTK_CONTAINER (hbox), 6);
+  gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), hbox);
+  gtk_widget_show (hbox);
+
+  dialog->entry = gtk_entry_new ();
+  gtk_entry_set_text (GTK_ENTRY (dialog->entry), action != NULL ? action : "");
+  gtk_box_pack_start (GTK_BOX (hbox), dialog->entry, TRUE, TRUE, 0);
+  gtk_widget_show (dialog->entry);
+
+  dialog->button = gtk_button_new_from_stock (GTK_STOCK_OPEN);
+  g_signal_connect_swapped (dialog->button, "clicked", G_CALLBACK (command_dialog_button_clicked), dialog);
+  gtk_box_pack_start (GTK_BOX (hbox), dialog->button, FALSE, TRUE, 0);
+  gtk_widget_show (dialog->button);
+}
+
+
+
+const char*
+command_dialog_get_command (CommandDialog *dialog)
+{
+  g_return_val_if_fail (IS_COMMAND_DIALOG (dialog), NULL);
+  return gtk_entry_get_text (GTK_ENTRY (dialog->entry));
+}
+
+
+
+gint
+command_dialog_run (CommandDialog *dialog,
+                    GtkWidget     *parent)
+{
+  gint     response = GTK_RESPONSE_CANCEL;
+  gboolean finished = FALSE;
+
+  g_return_val_if_fail (IS_COMMAND_DIALOG (dialog), GTK_RESPONSE_CANCEL);
+
+  gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (gtk_widget_get_toplevel (parent)));
+  gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
+  gtk_window_set_destroy_with_parent (GTK_WINDOW (dialog), TRUE);
+
+  do 
+    {
+      response = gtk_dialog_run (GTK_DIALOG (dialog));
+
+      if (G_UNLIKELY (response != GTK_RESPONSE_CANCEL && g_utf8_strlen (command_dialog_get_command (dialog), -1) == 0))
+        xfce_err (_("The command may not be empty."));
+      else
+        finished = TRUE;
+    }
+  while (!finished);
+
+  return response;
+}
+
+
+
+static void 
+command_dialog_button_clicked (CommandDialog *dialog)
+{
+  GtkWidget     *chooser;
+  GtkFileFilter *filter;
+  gchar         *filename;
+
+  g_return_if_fail (IS_COMMAND_DIALOG (dialog));
+
+  chooser = gtk_file_chooser_dialog_new (_("Select command"), 
+                                         GTK_WINDOW (dialog), 
+                                         GTK_FILE_CHOOSER_ACTION_OPEN, 
+                                         GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+                                         GTK_STOCK_OPEN, GTK_RESPONSE_OK, NULL);
+
+  /* Add file chooser filters */
+  filter = gtk_file_filter_new ();
+  gtk_file_filter_set_name (filter, _("All Files"));
+  gtk_file_filter_add_pattern (filter, "*");
+  gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (chooser), filter);
+
+  filter = gtk_file_filter_new ();
+  gtk_file_filter_set_name (filter, _("Executable Files"));
+  gtk_file_filter_add_mime_type (filter, "application/x-csh");
+  gtk_file_filter_add_mime_type (filter, "application/x-executable");
+  gtk_file_filter_add_mime_type (filter, "application/x-perl");
+  gtk_file_filter_add_mime_type (filter, "application/x-python");
+  gtk_file_filter_add_mime_type (filter, "application/x-ruby");
+  gtk_file_filter_add_mime_type (filter, "application/x-shellscript");
+  gtk_file_filter_add_pattern (filter, "*.pl");
+  gtk_file_filter_add_pattern (filter, "*.py");
+  gtk_file_filter_add_pattern (filter, "*.rb");
+  gtk_file_filter_add_pattern (filter, "*.sh");
+  gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (chooser), filter);
+  gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (chooser), filter);
+
+  filter = gtk_file_filter_new ();
+  gtk_file_filter_set_name (filter, _("Perl Scripts"));
+  gtk_file_filter_add_mime_type (filter, "application/x-perl");
+  gtk_file_filter_add_pattern (filter, "*.pl");
+  gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (chooser), filter);
+
+  filter = gtk_file_filter_new ();
+  gtk_file_filter_set_name (filter, _("Python Scripts"));
+  gtk_file_filter_add_mime_type (filter, "application/x-python");
+  gtk_file_filter_add_pattern (filter, "*.py");
+  gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (chooser), filter);
+
+  filter = gtk_file_filter_new ();
+  gtk_file_filter_set_name (filter, _("Ruby Scripts"));
+  gtk_file_filter_add_mime_type (filter, "application/x-ruby");
+  gtk_file_filter_add_pattern (filter, "*.rb");
+  gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (chooser), filter);
+
+  filter = gtk_file_filter_new ();
+  gtk_file_filter_set_name (filter, _("Shell Scripts"));
+  gtk_file_filter_add_mime_type (filter, "application/x-csh");
+  gtk_file_filter_add_mime_type (filter, "application/x-shellscript");
+  gtk_file_filter_add_pattern (filter, "*.sh");
+  gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (chooser), filter);
+
+  /* Use bindir as default folder */
+  gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (chooser), BINDIR);
+
+  /* Run the file chooser */
+  if (G_LIKELY (gtk_dialog_run (GTK_DIALOG (chooser)) == GTK_RESPONSE_OK))
+    {
+      filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (chooser));
+      gtk_entry_set_text (GTK_ENTRY (dialog->entry), filename);
+      g_free (filename);
+    }
+
+  /* Destroy the dialog */
+  gtk_widget_destroy (chooser);
+}

Added: xfce4-settings/trunk/dialogs/keyboard-settings/command-dialog.h
===================================================================
--- xfce4-settings/trunk/dialogs/keyboard-settings/command-dialog.h	                        (rev 0)
+++ xfce4-settings/trunk/dialogs/keyboard-settings/command-dialog.h	2008-07-15 22:57:11 UTC (rev 27304)
@@ -0,0 +1,48 @@
+/* vi:set sw=2 sts=2 ts=2 et ai: */
+/*-
+ * Copyright (c) 2008 Jannis Pohlmann <jannis at xfce.org>.
+ *
+ * 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.
+ *
+ * This 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.
+ *
+ * You should have received a copy of the GNU General Public License 
+ * along with this program; if not, write to the Free Software 
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
+ * MA  02111-1307  USA
+ */
+
+#ifndef __COMMAND_DIALOG_H__
+#define __COMMAND_DIALOG_H__
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS;
+
+typedef struct _CommandDialogClass CommandDialogClass;
+typedef struct _CommandDialog      CommandDialog;
+
+#define TYPE_COMMAND_DIALOG            (command_dialog_get_type ())
+#define COMMAND_DIALOG(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_COMMAND_DIALOG, CommandDialog))
+#define COMMAND_DIALOG_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_COMMAND_DIALOG, CommandDialogClass))
+#define IS_COMMAND_DIALOG(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_COMMAND_DIALOG))
+#define IS_COMMAND_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_COMMAND_DIALOG))
+#define COMMAND_DIALOG_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_COMMAND_DIALOG, CommandDialogClass))
+
+GType       command_dialog_get_type     (void) G_GNUC_CONST;
+
+GtkWidget  *command_dialog_new          (const gchar   *shortcut,
+                                         const gchar   *action);
+const char *command_dialog_get_command  (CommandDialog *dialog);
+gint        command_dialog_run          (CommandDialog *dialog,
+                                         GtkWidget     *parent);
+
+G_END_DECLS;
+
+#endif /* !__COMMAND_DIALOG_H__ */

Modified: xfce4-settings/trunk/dialogs/keyboard-settings/keyboard-dialog.glade
===================================================================
--- xfce4-settings/trunk/dialogs/keyboard-settings/keyboard-dialog.glade	2008-07-15 20:35:13 UTC (rev 27303)
+++ xfce4-settings/trunk/dialogs/keyboard-settings/keyboard-dialog.glade	2008-07-15 22:57:11 UTC (rev 27304)
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
-<!--Generated with glade3 3.4.5 on Sat Jul  5 23:32:27 2008 -->
+<!--Generated with glade3 3.4.5 on Tue Jul 15 19:54:16 2008 -->
 <glade-interface>
   <requires lib="xfce4"/>
   <widget class="XfceTitledDialog" id="keyboard-settings-dialog">
@@ -28,98 +28,69 @@
                     <property name="border_width">12</property>
                     <property name="spacing">6</property>
                     <child>
-                      <widget class="GtkHBox" id="hbox1">
+                      <widget class="GtkVBox" id="vbox3">
                         <property name="visible">True</property>
-                        <property name="spacing">12</property>
+                        <property name="spacing">6</property>
                         <child>
-                          <widget class="GtkFrame" id="frame1">
+                          <widget class="GtkFrame" id="frame2">
                             <property name="visible">True</property>
                             <property name="label_xalign">0</property>
                             <property name="shadow_type">GTK_SHADOW_NONE</property>
                             <child>
-                              <widget class="GtkAlignment" id="alignment1">
+                              <widget class="GtkAlignment" id="alignment2">
                                 <property name="visible">True</property>
-                                <property name="border_width">6</property>
+                                <property name="bottom_padding">6</property>
                                 <property name="left_padding">12</property>
                                 <child>
-                                  <widget class="GtkScrolledWindow" id="scrolledwindow1">
+                                  <widget class="GtkVBox" id="vbox3">
                                     <property name="visible">True</property>
-                                    <property name="can_focus">True</property>
-                                    <property name="hscrollbar_policy">GTK_POLICY_NEVER</property>
-                                    <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
-                                    <property name="shadow_type">GTK_SHADOW_IN</property>
+                                    <property name="border_width">6</property>
+                                    <property name="spacing">6</property>
                                     <child>
-                                      <widget class="GtkTreeView" id="gtk_keytheme_treeview">
+                                      <widget class="GtkCheckButton" id="xkb_key_repeat_check">
                                         <property name="visible">True</property>
                                         <property name="can_focus">True</property>
-                                        <property name="headers_visible">False</property>
+                                        <property name="label" translatable="yes">_Enable key repeat</property>
+                                        <property name="use_underline">True</property>
+                                        <property name="response_id">0</property>
+                                        <property name="draw_indicator">True</property>
                                       </widget>
+                                      <packing>
+                                        <property name="expand">False</property>
+                                        <property name="fill">False</property>
+                                      </packing>
                                     </child>
-                                  </widget>
-                                </child>
-                              </widget>
-                            </child>
-                            <child>
-                              <widget class="GtkLabel" id="label4">
-                                <property name="visible">True</property>
-                                <property name="label" translatable="yes">&lt;b&gt;Key Theme&lt;/b&gt;</property>
-                                <property name="use_markup">True</property>
-                              </widget>
-                              <packing>
-                                <property name="type">label_item</property>
-                              </packing>
-                            </child>
-                          </widget>
-                        </child>
-                        <child>
-                          <widget class="GtkVBox" id="vbox3">
-                            <property name="visible">True</property>
-                            <property name="spacing">6</property>
-                            <child>
-                              <widget class="GtkFrame" id="frame2">
-                                <property name="visible">True</property>
-                                <property name="label_xalign">0</property>
-                                <property name="shadow_type">GTK_SHADOW_NONE</property>
-                                <child>
-                                  <widget class="GtkAlignment" id="alignment2">
-                                    <property name="visible">True</property>
-                                    <property name="bottom_padding">6</property>
-                                    <property name="left_padding">12</property>
                                     <child>
-                                      <widget class="GtkVBox" id="vbox3">
+                                      <widget class="GtkAlignment" id="xkb_key_repeat_box">
                                         <property name="visible">True</property>
-                                        <property name="border_width">6</property>
-                                        <property name="spacing">6</property>
+                                        <property name="sensitive">False</property>
+                                        <property name="left_padding">12</property>
                                         <child>
-                                          <widget class="GtkCheckButton" id="xkb_key_repeat_check">
+                                          <widget class="GtkVBox" id="vbox6">
                                             <property name="visible">True</property>
-                                            <property name="can_focus">True</property>
-                                            <property name="label" translatable="yes">_Enable key repeat</property>
-                                            <property name="use_underline">True</property>
-                                            <property name="response_id">0</property>
-                                            <property name="draw_indicator">True</property>
-                                          </widget>
-                                          <packing>
-                                            <property name="expand">False</property>
-                                            <property name="fill">False</property>
-                                          </packing>
-                                        </child>
-                                        <child>
-                                          <widget class="GtkAlignment" id="xkb_key_repeat_box">
-                                            <property name="visible">True</property>
-                                            <property name="sensitive">False</property>
-                                            <property name="left_padding">12</property>
+                                            <property name="spacing">6</property>
                                             <child>
-                                              <widget class="GtkVBox" id="vbox6">
+                                              <widget class="GtkLabel" id="label7">
                                                 <property name="visible">True</property>
-                                                <property name="spacing">6</property>
+                                                <property name="xalign">0</property>
+                                                <property name="label" translatable="yes">_Repeat delay:</property>
+                                                <property name="use_underline">True</property>
+                                                <property name="mnemonic_widget">xkb_key_repeat_delay_scale</property>
+                                              </widget>
+                                              <packing>
+                                                <property name="expand">False</property>
+                                                <property name="fill">False</property>
+                                              </packing>
+                                            </child>
+                                            <child>
+                                              <widget class="GtkHBox" id="hbox2">
+                                                <property name="visible">True</property>
+                                                <property name="spacing">2</property>
                                                 <child>
-                                                  <widget class="GtkLabel" id="label7">
+                                                  <widget class="GtkLabel" id="label8">
                                                     <property name="visible">True</property>
-                                                    <property name="xalign">0</property>
-                                                    <property name="label" translatable="yes">_Repeat delay:</property>
-                                                    <property name="use_underline">True</property>
-                                                    <property name="mnemonic_widget">xkb_key_repeat_delay_scale</property>
+                                                    <property name="label" translatable="yes">&lt;small&gt;&lt;i&gt;Short&lt;/i&gt;&lt;/small&gt;</property>
+                                                    <property name="use_markup">True</property>
                                                   </widget>
                                                   <packing>
                                                     <property name="expand">False</property>
@@ -127,58 +98,22 @@
                                                   </packing>
                                                 </child>
                                                 <child>
-                                                  <widget class="GtkHBox" id="hbox2">
+                                                  <widget class="GtkHScale" id="xkb_key_repeat_delay_scale">
                                                     <property name="visible">True</property>
-                                                    <property name="spacing">2</property>
-                                                    <child>
-                                                      <widget class="GtkLabel" id="label8">
-                                                        <property name="visible">True</property>
-                                                        <property name="label" translatable="yes">&lt;small&gt;&lt;i&gt;Short&lt;/i&gt;&lt;/small&gt;</property>
-                                                        <property name="use_markup">True</property>
-                                                      </widget>
-                                                      <packing>
-                                                        <property name="expand">False</property>
-                                                        <property name="fill">False</property>
-                                                      </packing>
-                                                    </child>
-                                                    <child>
-                                                      <widget class="GtkHScale" id="xkb_key_repeat_delay_scale">
-                                                        <property name="visible">True</property>
-                                                        <property name="can_focus">True</property>
-                                                        <property name="adjustment">100 100 2000 1 10 10</property>
-                                                        <property name="digits">0</property>
-                                                        <property name="draw_value">False</property>
-                                                      </widget>
-                                                      <packing>
-                                                        <property name="position">1</property>
-                                                      </packing>
-                                                    </child>
-                                                    <child>
-                                                      <widget class="GtkLabel" id="label9">
-                                                        <property name="visible">True</property>
-                                                        <property name="label" translatable="yes">&lt;small&gt;&lt;i&gt;Long&lt;/i&gt;&lt;/small&gt;</property>
-                                                        <property name="use_markup">True</property>
-                                                      </widget>
-                                                      <packing>
-                                                        <property name="expand">False</property>
-                                                        <property name="fill">False</property>
-                                                        <property name="position">2</property>
-                                                      </packing>
-                                                    </child>
+                                                    <property name="can_focus">True</property>
+                                                    <property name="adjustment">100 100 2000 1 10 10</property>
+                                                    <property name="digits">0</property>
+                                                    <property name="draw_value">False</property>
                                                   </widget>
                                                   <packing>
-                                                    <property name="expand">False</property>
-                                                    <property name="fill">False</property>
                                                     <property name="position">1</property>
                                                   </packing>
                                                 </child>
                                                 <child>
-                                                  <widget class="GtkLabel" id="label10">
+                                                  <widget class="GtkLabel" id="label9">
                                                     <property name="visible">True</property>
-                                                    <property name="xalign">0</property>
-                                                    <property name="label" translatable="yes">Repeat _speed:</property>
-                                                    <property name="use_underline">True</property>
-                                                    <property name="mnemonic_widget">xkb_key_repeat_rate_scale</property>
+                                                    <property name="label" translatable="yes">&lt;small&gt;&lt;i&gt;Long&lt;/i&gt;&lt;/small&gt;</property>
+                                                    <property name="use_markup">True</property>
                                                   </widget>
                                                   <packing>
                                                     <property name="expand">False</property>
@@ -186,122 +121,158 @@
                                                     <property name="position">2</property>
                                                   </packing>
                                                 </child>
+                                              </widget>
+                                              <packing>
+                                                <property name="expand">False</property>
+                                                <property name="fill">False</property>
+                                                <property name="position">1</property>
+                                              </packing>
+                                            </child>
+                                            <child>
+                                              <widget class="GtkLabel" id="label10">
+                                                <property name="visible">True</property>
+                                                <property name="xalign">0</property>
+                                                <property name="label" translatable="yes">Repeat _speed:</property>
+                                                <property name="use_underline">True</property>
+                                                <property name="mnemonic_widget">xkb_key_repeat_rate_scale</property>
+                                              </widget>
+                                              <packing>
+                                                <property name="expand">False</property>
+                                                <property name="fill">False</property>
+                                                <property name="position">2</property>
+                                              </packing>
+                                            </child>
+                                            <child>
+                                              <widget class="GtkHBox" id="hbox3">
+                                                <property name="visible">True</property>
+                                                <property name="spacing">2</property>
                                                 <child>
-                                                  <widget class="GtkHBox" id="hbox3">
+                                                  <widget class="GtkLabel" id="label11">
                                                     <property name="visible">True</property>
-                                                    <property name="spacing">2</property>
-                                                    <child>
-                                                      <widget class="GtkLabel" id="label11">
-                                                        <property name="visible">True</property>
-                                                        <property name="label" translatable="yes">&lt;small&gt;&lt;i&gt;Slow&lt;/i&gt;&lt;/small&gt;</property>
-                                                        <property name="use_markup">True</property>
-                                                      </widget>
-                                                      <packing>
-                                                        <property name="expand">False</property>
-                                                        <property name="fill">False</property>
-                                                      </packing>
-                                                    </child>
-                                                    <child>
-                                                      <widget class="GtkHScale" id="xkb_key_repeat_rate_scale">
-                                                        <property name="visible">True</property>
-                                                        <property name="can_focus">True</property>
-                                                        <property name="adjustment">10 10 500 1 10 10</property>
-                                                        <property name="draw_value">False</property>
-                                                      </widget>
-                                                      <packing>
-                                                        <property name="position">1</property>
-                                                      </packing>
-                                                    </child>
-                                                    <child>
-                                                      <widget class="GtkLabel" id="label12">
-                                                        <property name="visible">True</property>
-                                                        <property name="label" translatable="yes">&lt;small&gt;&lt;i&gt;Fast&lt;/i&gt;&lt;/small&gt;</property>
-                                                        <property name="use_markup">True</property>
-                                                      </widget>
-                                                      <packing>
-                                                        <property name="expand">False</property>
-                                                        <property name="fill">False</property>
-                                                        <property name="position">2</property>
-                                                      </packing>
-                                                    </child>
+                                                    <property name="label" translatable="yes">&lt;small&gt;&lt;i&gt;Slow&lt;/i&gt;&lt;/small&gt;</property>
+                                                    <property name="use_markup">True</property>
                                                   </widget>
                                                   <packing>
                                                     <property name="expand">False</property>
                                                     <property name="fill">False</property>
-                                                    <property name="position">3</property>
                                                   </packing>
                                                 </child>
+                                                <child>
+                                                  <widget class="GtkHScale" id="xkb_key_repeat_rate_scale">
+                                                    <property name="visible">True</property>
+                                                    <property name="can_focus">True</property>
+                                                    <property name="adjustment">10 10 500 1 10 10</property>
+                                                    <property name="draw_value">False</property>
+                                                  </widget>
+                                                  <packing>
+                                                    <property name="position">1</property>
+                                                  </packing>
+                                                </child>
+                                                <child>
+                                                  <widget class="GtkLabel" id="label12">
+                                                    <property name="visible">True</property>
+                                                    <property name="label" translatable="yes">&lt;small&gt;&lt;i&gt;Fast&lt;/i&gt;&lt;/small&gt;</property>
+                                                    <property name="use_markup">True</property>
+                                                  </widget>
+                                                  <packing>
+                                                    <property name="expand">False</property>
+                                                    <property name="fill">False</property>
+                                                    <property name="position">2</property>
+                                                  </packing>
+                                                </child>
                                               </widget>
+                                              <packing>
+                                                <property name="expand">False</property>
+                                                <property name="fill">False</property>
+                                                <property name="position">3</property>
+                                              </packing>
                                             </child>
                                           </widget>
-                                          <packing>
-                                            <property name="position">1</property>
-                                          </packing>
                                         </child>
                                       </widget>
+                                      <packing>
+                                        <property name="position">1</property>
+                                      </packing>
                                     </child>
                                   </widget>
                                 </child>
-                                <child>
-                                  <widget class="GtkLabel" id="label5">
-                                    <property name="visible">True</property>
-                                    <property name="label" translatable="yes">&lt;b&gt;Typing Settings&lt;/b&gt;</property>
-                                    <property name="use_markup">True</property>
-                                  </widget>
-                                  <packing>
-                                    <property name="type">label_item</property>
-                                  </packing>
-                                </child>
                               </widget>
+                            </child>
+                            <child>
+                              <widget class="GtkLabel" id="label5">
+                                <property name="visible">True</property>
+                                <property name="label" translatable="yes">&lt;b&gt;Typing Settings&lt;/b&gt;</property>
+                                <property name="use_markup">True</property>
+                              </widget>
                               <packing>
-                                <property name="expand">False</property>
-                                <property name="fill">False</property>
+                                <property name="type">label_item</property>
                               </packing>
                             </child>
+                          </widget>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">False</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <widget class="GtkFrame" id="frame3">
+                            <property name="visible">True</property>
+                            <property name="label_xalign">0</property>
+                            <property name="shadow_type">GTK_SHADOW_NONE</property>
                             <child>
-                              <widget class="GtkFrame" id="frame3">
+                              <widget class="GtkAlignment" id="alignment3">
                                 <property name="visible">True</property>
-                                <property name="label_xalign">0</property>
-                                <property name="shadow_type">GTK_SHADOW_NONE</property>
+                                <property name="left_padding">12</property>
                                 <child>
-                                  <widget class="GtkAlignment" id="alignment3">
+                                  <widget class="GtkVBox" id="vbox4">
                                     <property name="visible">True</property>
-                                    <property name="left_padding">12</property>
+                                    <property name="border_width">6</property>
+                                    <property name="spacing">6</property>
                                     <child>
-                                      <widget class="GtkVBox" id="vbox4">
+                                      <widget class="GtkCheckButton" id="net_cursor_blink_check">
                                         <property name="visible">True</property>
-                                        <property name="border_width">6</property>
-                                        <property name="spacing">6</property>
+                                        <property name="can_focus">True</property>
+                                        <property name="label" translatable="yes">Show _blinking</property>
+                                        <property name="use_underline">True</property>
+                                        <property name="response_id">0</property>
+                                        <property name="draw_indicator">True</property>
+                                      </widget>
+                                      <packing>
+                                        <property name="expand">False</property>
+                                        <property name="fill">False</property>
+                                      </packing>
+                                    </child>
+                                    <child>
+                                      <widget class="GtkAlignment" id="net_cursor_blink_box">
+                                        <property name="visible">True</property>
+                                        <property name="sensitive">False</property>
+                                        <property name="left_padding">12</property>
                                         <child>
-                                          <widget class="GtkCheckButton" id="net_cursor_blink_check">
+                                          <widget class="GtkVBox" id="vbox7">
                                             <property name="visible">True</property>
-                                            <property name="can_focus">True</property>
-                                            <property name="label" translatable="yes">Show _blinking</property>
-                                            <property name="use_underline">True</property>
-                                            <property name="response_id">0</property>
-                                            <property name="draw_indicator">True</property>
-                                          </widget>
-                                          <packing>
-                                            <property name="expand">False</property>
-                                            <property name="fill">False</property>
-                                          </packing>
-                                        </child>
-                                        <child>
-                                          <widget class="GtkAlignment" id="net_cursor_blink_box">
-                                            <property name="visible">True</property>
-                                            <property name="sensitive">False</property>
-                                            <property name="left_padding">12</property>
+                                            <property name="spacing">6</property>
                                             <child>
-                                              <widget class="GtkVBox" id="vbox7">
+                                              <widget class="GtkLabel" id="label13">
                                                 <property name="visible">True</property>
-                                                <property name="spacing">6</property>
+                                                <property name="xalign">0</property>
+                                                <property name="label" translatable="yes">Blink _delay:</property>
+                                                <property name="use_underline">True</property>
+                                                <property name="mnemonic_widget">net_cursor_blink_time_scale</property>
+                                              </widget>
+                                              <packing>
+                                                <property name="expand">False</property>
+                                                <property name="fill">False</property>
+                                              </packing>
+                                            </child>
+                                            <child>
+                                              <widget class="GtkHBox" id="hbox4">
+                                                <property name="visible">True</property>
+                                                <property name="spacing">2</property>
                                                 <child>
-                                                  <widget class="GtkLabel" id="label13">
+                                                  <widget class="GtkLabel" id="label14">
                                                     <property name="visible">True</property>
-                                                    <property name="xalign">0</property>
-                                                    <property name="label" translatable="yes">Blink _delay:</property>
-                                                    <property name="use_underline">True</property>
-                                                    <property name="mnemonic_widget">net_cursor_blink_time_scale</property>
+                                                    <property name="label" translatable="yes">&lt;small&gt;&lt;i&gt;Short&lt;/i&gt;&lt;/small&gt;</property>
+                                                    <property name="use_markup">True</property>
                                                   </widget>
                                                   <packing>
                                                     <property name="expand">False</property>
@@ -309,74 +280,55 @@
                                                   </packing>
                                                 </child>
                                                 <child>
-                                                  <widget class="GtkHBox" id="hbox4">
+                                                  <widget class="GtkHScale" id="net_cursor_blink_time_scale">
                                                     <property name="visible">True</property>
-                                                    <property name="spacing">2</property>
-                                                    <child>
-                                                      <widget class="GtkLabel" id="label14">
-                                                        <property name="visible">True</property>
-                                                        <property name="label" translatable="yes">&lt;small&gt;&lt;i&gt;Short&lt;/i&gt;&lt;/small&gt;</property>
-                                                        <property name="use_markup">True</property>
-                                                      </widget>
-                                                      <packing>
-                                                        <property name="expand">False</property>
-                                                        <property name="fill">False</property>
-                                                      </packing>
-                                                    </child>
-                                                    <child>
-                                                      <widget class="GtkHScale" id="net_cursor_blink_time_scale">
-                                                        <property name="visible">True</property>
-                                                        <property name="can_focus">True</property>
-                                                        <property name="adjustment">100 100 2000 100 10 10</property>
-                                                        <property name="draw_value">False</property>
-                                                      </widget>
-                                                      <packing>
-                                                        <property name="position">1</property>
-                                                      </packing>
-                                                    </child>
-                                                    <child>
-                                                      <widget class="GtkLabel" id="label15">
-                                                        <property name="visible">True</property>
-                                                        <property name="label" translatable="yes">&lt;small&gt;&lt;i&gt;Long&lt;/i&gt;&lt;/small&gt;</property>
-                                                        <property name="use_markup">True</property>
-                                                      </widget>
-                                                      <packing>
-                                                        <property name="expand">False</property>
-                                                        <property name="fill">False</property>
-                                                        <property name="position">2</property>
-                                                      </packing>
-                                                    </child>
+                                                    <property name="can_focus">True</property>
+                                                    <property name="adjustment">100 100 2000 100 10 10</property>
+                                                    <property name="draw_value">False</property>
                                                   </widget>
                                                   <packing>
+                                                    <property name="position">1</property>
+                                                  </packing>
+                                                </child>
+                                                <child>
+                                                  <widget class="GtkLabel" id="label15">
+                                                    <property name="visible">True</property>
+                                                    <property name="label" translatable="yes">&lt;small&gt;&lt;i&gt;Long&lt;/i&gt;&lt;/small&gt;</property>
+                                                    <property name="use_markup">True</property>
+                                                  </widget>
+                                                  <packing>
                                                     <property name="expand">False</property>
                                                     <property name="fill">False</property>
-                                                    <property name="position">1</property>
+                                                    <property name="position">2</property>
                                                   </packing>
                                                 </child>
                                               </widget>
+                                              <packing>
+                                                <property name="expand">False</property>
+                                                <property name="fill">False</property>
+                                                <property name="position">1</property>
+                                              </packing>
                                             </child>
                                           </widget>
-                                          <packing>
-                                            <property name="position">1</property>
-                                          </packing>
                                         </child>
                                       </widget>
+                                      <packing>
+                                        <property name="expand">False</property>
+                                        <property name="position">1</property>
+                                      </packing>
                                     </child>
                                   </widget>
                                 </child>
-                                <child>
-                                  <widget class="GtkLabel" id="label6">
-                                    <property name="visible">True</property>
-                                    <property name="label" translatable="yes">&lt;b&gt;Cursor&lt;/b&gt;</property>
-                                    <property name="use_markup">True</property>
-                                  </widget>
-                                  <packing>
-                                    <property name="type">label_item</property>
-                                  </packing>
-                                </child>
                               </widget>
+                            </child>
+                            <child>
+                              <widget class="GtkLabel" id="label6">
+                                <property name="visible">True</property>
+                                <property name="label" translatable="yes">&lt;b&gt;Cursor&lt;/b&gt;</property>
+                                <property name="use_markup">True</property>
+                              </widget>
                               <packing>
-                                <property name="position">1</property>
+                                <property name="type">label_item</property>
                               </packing>
                             </child>
                           </widget>
@@ -387,6 +339,15 @@
                       </widget>
                     </child>
                     <child>
+                      <widget class="GtkHSeparator" id="hseparator1">
+                        <property name="visible">True</property>
+                      </widget>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                    <child>
                       <widget class="GtkLabel" id="label1">
                         <property name="visible">True</property>
                         <property name="xalign">0</property>
@@ -397,7 +358,7 @@
                       <packing>
                         <property name="expand">False</property>
                         <property name="fill">False</property>
-                        <property name="position">1</property>
+                        <property name="position">2</property>
                       </packing>
                     </child>
                     <child>
@@ -408,7 +369,7 @@
                       <packing>
                         <property name="expand">False</property>
                         <property name="fill">False</property>
-                        <property name="position">2</property>
+                        <property name="position">3</property>
                       </packing>
                     </child>
                   </widget>
@@ -448,6 +409,7 @@
                         <property name="shadow_type">GTK_SHADOW_IN</property>
                         <child>
                           <widget class="GtkTreeView" id="kbd_shortcuts_view">
+                            <property name="width_request">400</property>
                             <property name="visible">True</property>
                             <property name="can_focus">True</property>
                             <property name="search_column">0</property>

Modified: xfce4-settings/trunk/dialogs/keyboard-settings/main.c
===================================================================
--- xfce4-settings/trunk/dialogs/keyboard-settings/main.c	2008-07-15 20:35:13 UTC (rev 27303)
+++ xfce4-settings/trunk/dialogs/keyboard-settings/main.c	2008-07-15 22:57:11 UTC (rev 27304)
@@ -41,6 +41,7 @@
 
 #include "keyboard-dialog_glade.h"
 #include "shortcut-dialog.h"
+#include "command-dialog.h"
 
 
 
@@ -69,11 +70,11 @@
 
 
 static void
-xkb_key_repeat_toggled (GtkToggleButton *button, 
+xkb_key_repeat_toggled (GtkToggleButton *button,
                         GladeXML        *gxml)
 {
     GtkWidget *box;
-    
+
     box = glade_xml_get_widget (gxml, "xkb_key_repeat_box");
     gtk_widget_set_sensitive (box, gtk_toggle_button_get_active (button));
 }
@@ -81,11 +82,11 @@
 
 
 static void
-net_cursor_blink_toggled (GtkToggleButton *button, 
+net_cursor_blink_toggled (GtkToggleButton *button,
                           GladeXML        *gxml)
 {
     GtkWidget *box;
-    
+
     box = glade_xml_get_widget (gxml, "net_cursor_blink_box");
     gtk_widget_set_sensitive (box, gtk_toggle_button_get_active (button));
 }
@@ -139,16 +140,15 @@
 
 
 static void
-keyboard_settings_load_shortcuts (XfconfChannel *channel, 
-                                  GtkWidget     *kbd_shortcuts_view, 
-                                  GtkListStore  *list_store)
+keyboard_settings_load_shortcuts (GtkWidget    *kbd_shortcuts_view,
+                                  GtkListStore *list_store)
 {
   GHashTable *shortcuts;
 
   g_return_if_fail (GTK_IS_TREE_VIEW (kbd_shortcuts_view));
   g_return_if_fail (GTK_IS_LIST_STORE (list_store));
 
-  shortcuts = xfconf_channel_get_all (channel);
+  shortcuts = xfconf_channel_get_all (kbd_channel);
 
   if (G_LIKELY (shortcuts != NULL))
     {
@@ -159,9 +159,112 @@
 
 
 
+static gboolean
+keyboard_settings_validate_shortcut (ShortcutDialog *dialog,
+                                     const gchar    *shortcut,
+                                     GtkTreeView    *tree_view)
+{
+  GtkTreeSelection *selection;
+  GtkTreeModel     *model;
+  GtkTreeIter       iter;
+  gboolean          shortcut_accepted = TRUE;
+  gchar            *current_shortcut;
+  gchar            *property;
+
+#if 1
+  /* Ignore raw 'Return' since that may have been used to activate the shortcut row */
+  if (G_UNLIKELY (g_utf8_collate (shortcut, "Return") == 0
+                  || g_utf8_collate (shortcut, "space") == 0))
+    return FALSE;
+#endif
+
+  selection = gtk_tree_view_get_selection (tree_view);
+
+  if (G_LIKELY (gtk_tree_selection_get_selected (selection, &model, &iter)))
+    {
+      gtk_tree_model_get (model, &iter, SHORTCUT_COLUMN, &current_shortcut, -1);
+
+      property = g_strdup_printf ("/%s", shortcut);
+
+      if (G_UNLIKELY (xfconf_channel_has_property (kbd_channel, property) && g_utf8_collate (current_shortcut, shortcut) != 0))
+        {
+          xfce_err (_("Keyboard shortcut '%s' is already being used for something else."), shortcut);
+          shortcut_accepted = FALSE;
+        }
+
+      g_free (property);
+      g_free (current_shortcut);
+    }
+
+  return shortcut_accepted;
+}
+
+
+
 static void
 keyboard_settings_add_shortcut (GtkTreeView *tree_view)
 {
+  GtkTreeModel *model;
+  GtkTreeIter   iter;
+  GtkWidget    *dialog;
+  const gchar  *shortcut = NULL;
+  gboolean      finished = FALSE;
+  gchar        *command = NULL;
+  gint          response;
+
+  /* Create command dialog */
+  dialog = command_dialog_new (NULL, NULL);
+
+  /* Run command dialog until a vaild (non-empty) command is entered or the dialog is cancelled */
+  do
+    {
+      response = command_dialog_run (COMMAND_DIALOG (dialog), GTK_WIDGET (tree_view));
+
+      if (G_UNLIKELY (response == GTK_RESPONSE_OK && g_utf8_strlen (command_dialog_get_command (COMMAND_DIALOG (dialog)), -1) == 0))
+        xfce_err (_("Short command may not be empty."));
+      else
+        finished = TRUE;
+    }
+  while (!finished);
+
+  /* Abort if the dialog was cancelled */
+  if (G_UNLIKELY (response == GTK_RESPONSE_CANCEL))
+    return;
+
+  /* Get the command */
+  command = g_strdup (command_dialog_get_command (COMMAND_DIALOG (dialog)));
+
+  /* Destroy the dialog */
+  gtk_widget_destroy (dialog);
+
+  /* Create shortcut dialog */
+  dialog = shortcut_dialog_new (command);
+  g_signal_connect (dialog, "validate-shortcut", G_CALLBACK (keyboard_settings_validate_shortcut), tree_view);
+
+  /* Run shortcut dialog until a valid shortcut is entered or the dialog is cancelled */
+  response = shortcut_dialog_run (SHORTCUT_DIALOG (dialog), GTK_WIDGET (tree_view));
+
+  /* Only continue if the shortcut dialog succeeded */
+  if (G_LIKELY (response == GTK_RESPONSE_OK))
+    {
+      /* Get shortcut */
+      shortcut = shortcut_dialog_get_shortcut (SHORTCUT_DIALOG (dialog));
+
+      /* Get tree view list store */
+      model = gtk_tree_view_get_model (tree_view);
+
+      /* Append new row to the list store */
+      gtk_list_store_append (GTK_LIST_STORE (model), &iter);
+
+      /* Set row values */
+      gtk_list_store_set (GTK_LIST_STORE (model), &iter, SHORTCUT_COLUMN, shortcut, ACTION_COLUMN, command, -1);
+    }
+
+  /* Destroy the shortcut dialog */
+  gtk_widget_destroy (dialog);
+
+  /* Free command string */
+  g_free (command);
 }
 
 
@@ -170,7 +273,6 @@
 keyboard_settings_delete_shortcut (GtkTreeView *tree_view)
 {
   GtkTreeSelection *selection;
-  XfconfChannel    *channel;
   GtkTreeModel     *model;
   GtkTreePath      *path;
   GtkTreeIter       iter;
@@ -180,9 +282,6 @@
   gchar            *shortcut;
   gchar            *property_name;
 
-  /* Get reference on the keyboard shortcuts channel */
-  channel = xfconf_channel_new ("xfce4-keyboard-shortcuts");
-
   /* Determine selected rows */
   selection = gtk_tree_view_get_selection (tree_view);
   rows = gtk_tree_selection_get_selected_rows (selection, &model);
@@ -207,7 +306,7 @@
           property_name = g_strdup_printf ("/%s", shortcut);
 
           /* Remove keyboard shortcut via xfconf */
-          xfconf_channel_remove_property (channel, property_name);
+          xfconf_channel_remove_property (kbd_channel, property_name);
 
           /* Free strings */
           g_free (property_name);
@@ -224,9 +323,6 @@
   /* Free row list */
   g_list_foreach (rows, (GFunc) gtk_tree_path_free, NULL);
   g_list_free (rows);
-
-  /* Release reference on the channel */
-  g_object_unref (channel);
 }
 
 
@@ -235,18 +331,14 @@
 keyboard_settings_shortcut_action_edited (GtkTreeView *tree_view,
                                           gchar       *path,
                                           gchar       *new_text)
-                                          
+
 {
-  XfconfChannel *channel;
   GtkTreeModel  *model;
   GtkTreeIter    iter;
   gchar         *shortcut;
   gchar         *old_text;
   gchar         *property_name;
 
-  /* Get reference on the keyboard shortcuts channel */
-  channel = xfconf_channel_new ("xfce4-keyboard-shortcuts");
-
   /* Get tree model */
   model = gtk_tree_view_get_model (tree_view);
 
@@ -266,7 +358,7 @@
           property_name = g_strdup_printf ("/%s", shortcut);
 
           /* Save new shortcut settings */
-          xfconf_channel_set_array (channel, property_name, G_TYPE_STRING, "execute", G_TYPE_STRING, new_text, G_TYPE_INVALID);
+          xfconf_channel_set_array (kbd_channel, property_name, G_TYPE_STRING, "execute", G_TYPE_STRING, new_text, G_TYPE_INVALID);
 
           /* Free property name */
           g_free (property_name);
@@ -276,65 +368,14 @@
       g_free (shortcut);
       g_free (old_text);
     }
-
-  /* Release reference on the channel */
-  g_object_unref (channel);
 }
 
 
 
-static gboolean
-keyboard_settings_validate_shortcut (ShortcutDialog *dialog,
-                                     const gchar    *shortcut,
-                                     GtkTreeView    *tree_view)
-{
-  GtkTreeSelection *selection;
-  XfconfChannel    *channel;
-  GtkTreeModel     *model;
-  GtkTreeIter       iter;
-  gboolean          shortcut_accepted = TRUE;
-  gchar            *current_shortcut;
-  gchar            *property;
-
-#if 1
-  /* Ignore raw 'Return' since that may have been used to activate the shortcut row */
-  if (G_UNLIKELY (g_utf8_collate (shortcut, "Return") == 0 
-                  || g_utf8_collate (shortcut, "space") == 0))
-    return FALSE;
-#endif
-
-  selection = gtk_tree_view_get_selection (tree_view);
-
-  if (G_LIKELY (gtk_tree_selection_get_selected (selection, &model, &iter)))
-    {
-      gtk_tree_model_get (model, &iter, SHORTCUT_COLUMN, &current_shortcut, -1);
-
-      channel = xfconf_channel_new ("xfce4-keyboard-shortcuts");
-      property = g_strdup_printf ("/%s", shortcut);
-      
-      if (G_UNLIKELY (xfconf_channel_has_property (channel, property) && g_utf8_collate (current_shortcut, shortcut) != 0))
-        {
-          xfce_err (_("Keyboard shortcut '%s' is already being used for something else."), shortcut);
-          shortcut_accepted = FALSE;
-        }
-
-      g_free (property);
-      g_free (current_shortcut);
-
-      g_object_unref (channel);
-    }
-
-  return shortcut_accepted;
-}
-
-
-
 static void
-keyboard_settings_row_activated (GtkTreeView       *tree_view,
-                                 GtkTreePath       *path,
-                                 GtkTreeViewColumn *column)
+keyboard_settings_edit_shortcut (GtkTreeView *tree_view,
+                                 GtkTreePath *path)
 {
-  XfconfChannel *channel;
   GtkTreeModel  *model;
   GtkTreeIter    iter;
   GtkWidget     *dialog;
@@ -345,12 +386,6 @@
   gchar         *new_property;
   gint           response;
 
-  if (G_UNLIKELY (column != gtk_tree_view_get_column (tree_view, SHORTCUT_COLUMN)))
-    return;
-
-  /* Get reference on the keyboard shortcuts channel */
-  channel = xfconf_channel_new ("xfce4-keyboard-shortcuts");
-
   /* Get tree view model */
   model = gtk_tree_view_get_model (tree_view);
 
@@ -371,7 +406,7 @@
           old_property = g_strdup_printf ("/%s", current_shortcut);
 
           /* Remove old shortcut from the settings */
-          xfconf_channel_remove_property (channel, old_property);
+          xfconf_channel_remove_property (kbd_channel, old_property);
 
           /* Get the shortcut entered by the user */
           new_shortcut = shortcut_dialog_get_shortcut (SHORTCUT_DIALOG (dialog));
@@ -386,7 +421,7 @@
               new_property = g_strdup_printf ("/%s", new_shortcut);
 
               /* Save new shortcut to the settings */
-              xfconf_channel_set_array (channel, new_property, G_TYPE_STRING, "execute", G_TYPE_STRING, action, G_TYPE_INVALID);
+              xfconf_channel_set_array (kbd_channel, new_property, G_TYPE_STRING, "execute", G_TYPE_STRING, action, G_TYPE_INVALID);
 
               /* Free property names */
               g_free (new_property);
@@ -403,28 +438,93 @@
       g_free (action);
       g_free (current_shortcut);
     }
+}
 
-  /* Release xfconf channel */
-  g_object_unref (channel);
+
+
+static void
+keyboard_settings_edit_action (GtkTreeView *tree_view,
+                               GtkTreePath *path)
+{
+  GtkTreeModel *model;
+  GtkTreeIter   iter;
+  GtkWidget    *dialog;
+  gchar        *shortcut;
+  gchar        *current_action;
+  const gchar  *new_action;
+  gchar        *property;
+  gint          response;
+
+  /* Get tree view model */
+  model = gtk_tree_view_get_model (tree_view);
+
+  /* Convert tree path to tree iter */
+  if (G_LIKELY (gtk_tree_model_get_iter (model, &iter, path)))
+    {
+      /* Read shortcut and current action from the activated row */
+      gtk_tree_model_get (model, &iter, SHORTCUT_COLUMN, &shortcut, ACTION_COLUMN, &current_action, -1);
+
+      /* Build property name */
+      property = g_strdup_printf ("/%s", shortcut);
+
+      /* Request a new action from the user */
+      dialog = command_dialog_new (shortcut, current_action);
+      response = command_dialog_run (COMMAND_DIALOG (dialog), GTK_WIDGET (tree_view));
+
+      if (G_LIKELY (response != GTK_RESPONSE_CANCEL))
+        {
+          /* Get the action entered by the user */
+          new_action = command_dialog_get_command (COMMAND_DIALOG (dialog));
+
+          /* Replace the old action in the tree view */
+          gtk_list_store_set (GTK_LIST_STORE (model), &iter, ACTION_COLUMN, new_action, -1);
+
+          /* Save new action to the settings */
+          xfconf_channel_set_array (kbd_channel, property, G_TYPE_STRING, "execute", G_TYPE_STRING, new_action, G_TYPE_INVALID);
+        }
+
+      /* Destroy the shortcut dialog */
+      gtk_widget_destroy (dialog);
+
+      /* Free strings */
+      g_free (property);
+      g_free (shortcut);
+      g_free (current_action);
+    }
 }
 
 
 
+static void
+keyboard_settings_row_activated (GtkTreeView       *tree_view,
+                                 GtkTreePath       *path,
+                                 GtkTreeViewColumn *column)
+{
+  if (column == gtk_tree_view_get_column (tree_view, SHORTCUT_COLUMN))
+    keyboard_settings_edit_shortcut (tree_view, path);
+  else
+    keyboard_settings_edit_action (tree_view, path);
+
+  return;
+}
+
+
+
 GtkWidget*
 keyboard_settings_dialog_new_from_xml (GladeXML *gxml)
 {
   GtkTreeViewColumn *column;
-  GtkCellRenderer *renderer;
-  GtkAdjustment   *net_cursor_blink_time_scale;
-  GtkAdjustment   *xkb_key_repeat_delay_scale;
-  GtkAdjustment   *xkb_key_repeat_rate_scale;
-  GtkListStore    *list_store;
-  GtkWidget       *kbd_shortcuts_view;
-  GtkWidget       *net_cursor_blink_check;
-  GtkWidget       *xkb_key_repeat_check;
-  GtkWidget       *add_shortcut_button;
-  GtkWidget       *delete_shortcut_button;
-  GtkWidget       *dialog;
+  GtkCellRenderer   *renderer;
+  GtkAdjustment     *net_cursor_blink_time_scale;
+  GtkAdjustment     *xkb_key_repeat_delay_scale;
+  GtkAdjustment     *xkb_key_repeat_rate_scale;
+  GtkListStore      *list_store;
+  GtkWidget         *kbd_shortcuts_view;
+  GtkWidget         *net_cursor_blink_check;
+  GtkWidget         *xkb_key_repeat_check;
+  GtkWidget         *add_shortcut_button;
+  GtkWidget         *delete_shortcut_button;
+  GtkWidget         *dialog;
 
   net_cursor_blink_check = glade_xml_get_widget (gxml, "net_cursor_blink_check");
   net_cursor_blink_time_scale = gtk_range_get_adjustment (GTK_RANGE (glade_xml_get_widget (gxml, "net_cursor_blink_time_scale")));
@@ -464,13 +564,11 @@
 
   /* Create renderer for the action columns */
   renderer = gtk_cell_renderer_text_new ();
-  g_object_set (G_OBJECT (renderer), "editable", TRUE, NULL);
-  g_signal_connect_swapped (renderer, "edited", G_CALLBACK (keyboard_settings_shortcut_action_edited), GTK_TREE_VIEW (kbd_shortcuts_view));
   column = gtk_tree_view_column_new_with_attributes (_("Command"), renderer, "text", ACTION_COLUMN, NULL);
   gtk_tree_view_append_column (GTK_TREE_VIEW (kbd_shortcuts_view), column);
 
   /* Load keyboard shortcuts */
-  keyboard_settings_load_shortcuts (kbd_channel, kbd_shortcuts_view, list_store);
+  keyboard_settings_load_shortcuts (kbd_shortcuts_view, list_store);
 
   /* Connect to add/delete button signals */
   g_signal_connect_swapped (add_shortcut_button, "clicked", G_CALLBACK (keyboard_settings_add_shortcut), GTK_TREE_VIEW (kbd_shortcuts_view));
@@ -498,7 +596,7 @@
   if(G_UNLIKELY (!gtk_init_with_args (&argc, &argv, "", entries, PACKAGE, &error)))
     {
       /* Print error if that failed */
-      if (G_LIKELY (error))
+      if (G_LIKELY (error != NULL))
         {
           /* print error */
           g_print ("%s: %s.\n", G_LOG_DOMAIN, error->message);
@@ -509,10 +607,8 @@
           g_error_free (error);
         }
       else
-        {
-          g_error ("Unable to open display.");
-        }
-        
+        g_error ("Unable to open display.");
+
         return EXIT_FAILURE;
     }
 
@@ -524,12 +620,12 @@
       g_print ("\t%s\n\n", _("The Xfce development team. All rights reserved."));
       g_print (_("Please report bugs to <%s>."), PACKAGE_BUGREPORT);
       g_print ("\n");
-      
+
       return EXIT_SUCCESS;
     }
 
   /* Initialize xfconf */
-  if (!xfconf_init (&error))
+  if (G_UNLIKELY (!xfconf_init (&error)))
     {
       /* print error and exit */
       g_error ("Failed to connect to xfconf daemon: %s.", error->message);
@@ -537,7 +633,7 @@
 
       return EXIT_FAILURE;
     }
-  
+
   /* load channels */
   xsettings_channel = xfconf_channel_new ("xsettings");
   xkb_channel = xfconf_channel_new ("xkb");
@@ -548,15 +644,15 @@
 
   /* Create settings dialog and run it */
   dialog = keyboard_settings_dialog_new_from_xml (gxml);
-  gtk_dialog_run(GTK_DIALOG(dialog));
-  
+  gtk_dialog_run (GTK_DIALOG (dialog));
   gtk_widget_destroy (dialog);
-  
+
+  /* Unload channels */
   g_object_unref (xsettings_channel);
   g_object_unref (xkb_channel);
   g_object_unref (kbd_channel);
 
-  xfconf_shutdown();
+  xfconf_shutdown ();
 
   return EXIT_SUCCESS;
 }

Modified: xfce4-settings/trunk/dialogs/keyboard-settings/shortcut-dialog.c
===================================================================
--- xfce4-settings/trunk/dialogs/keyboard-settings/shortcut-dialog.c	2008-07-15 20:35:13 UTC (rev 27303)
+++ xfce4-settings/trunk/dialogs/keyboard-settings/shortcut-dialog.c	2008-07-15 22:57:11 UTC (rev 27304)
@@ -274,8 +274,6 @@
   gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
   gtk_window_set_destroy_with_parent (GTK_WINDOW (dialog), TRUE);
 
-  gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
-
   /* Take control on the keyboard */
   if (G_LIKELY (gdk_keyboard_grab (gtk_widget_get_root_window (parent), TRUE, GDK_CURRENT_TIME) == GDK_GRAB_SUCCESS))
     {

Modified: xfce4-settings/trunk/dialogs/keyboard-settings/shortcut-dialog.h
===================================================================
--- xfce4-settings/trunk/dialogs/keyboard-settings/shortcut-dialog.h	2008-07-15 20:35:13 UTC (rev 27303)
+++ xfce4-settings/trunk/dialogs/keyboard-settings/shortcut-dialog.h	2008-07-15 22:57:11 UTC (rev 27304)
@@ -35,7 +35,7 @@
 #define IS_SHORTCUT_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_SHORTCUT_DIALOG))
 #define SHORTCUT_DIALOG_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_SHORTCUT_DIALOG, ShortcutDialogClass))
 
-GType     shortcut_dialog_get_type (void) G_GNUC_CONST;
+GType        shortcut_dialog_get_type     (void) G_GNUC_CONST;
 
 GtkWidget   *shortcut_dialog_new          (const gchar    *action);
 gint         shortcut_dialog_run          (ShortcutDialog *dialog,



More information about the Xfce4-commits mailing list