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

Jannis Pohlmann jannis at xfce.org
Thu Jul 10 12:14:50 CEST 2008


Author: jannis
Date: 2008-07-10 10:14:50 +0000 (Thu, 10 Jul 2008)
New Revision: 27251

Added:
   xfce4-settings/trunk/dialogs/keyboard-settings/shortcut-dialog.c
   xfce4-settings/trunk/dialogs/keyboard-settings/shortcut-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
Log:
	* dialogs/keyboard-settings/keyboard-dialog.glade,
	  dialogs/keyboard-settings/Makefile.am,
	  dialogs/keyboard-settings/main.c,
	  dialogs/keyboard-settings/shortcut-dialog.{c,h}:
	  Revamped the dialog a bit. Add dialog widget for entering
	  shortcuts. Rewrite the settings dialog and add support for
	  loading, saving, modifying and removing shortcuts. Not
	  supported yet: Adding new ones.
	* dialogs/appearance-settings/main.c: Load icon themes properly.

Modified: xfce4-settings/trunk/ChangeLog
===================================================================
--- xfce4-settings/trunk/ChangeLog	2008-07-09 22:23:53 UTC (rev 27250)
+++ xfce4-settings/trunk/ChangeLog	2008-07-10 10:14:50 UTC (rev 27251)
@@ -1,3 +1,14 @@
+2008-07-10	Jannis Pohlmann <jannis at xfce.org>
+
+	* dialogs/keyboard-settings/keyboard-dialog.glade,
+	  dialogs/keyboard-settings/Makefile.am,
+	  dialogs/keyboard-settings/main.c,
+	  dialogs/keyboard-settings/shortcut-dialog.{c,h}:
+	  Revamped the dialog a bit. Add dialog widget for entering
+	  shortcuts. Rewrite the settings dialog and add support for
+	  loading, saving, modifying and removing shortcuts. Not 
+	  supported yet: Adding new ones. 
+
 2008-07-04	Nick Schermer <nick at xfce.org>
 
 	* dialogs/mouse-settings/main.c: Bring support for the
@@ -38,7 +49,7 @@
 
 2008-07-02	Jannis Pohlmann <jannis at xfce.org>
 
-	* dialogs/appearance-dialog/main.c: Load icon themes properly.
+	* dialogs/appearance-settings/main.c: Load icon themes properly.
 	  I used some of the code from the old mcs ui plugin.
 	* AUTHORS: I took the liberty to add my name here. 
 

Modified: xfce4-settings/trunk/dialogs/keyboard-settings/Makefile.am
===================================================================
--- xfce4-settings/trunk/dialogs/keyboard-settings/Makefile.am	2008-07-09 22:23:53 UTC (rev 27250)
+++ xfce4-settings/trunk/dialogs/keyboard-settings/Makefile.am	2008-07-10 10:14:50 UTC (rev 27251)
@@ -2,6 +2,8 @@
 
 xfce4_keyboard_settings_SOURCES = \
 	main.c \
+	shortcut-dialog.c \
+	shortcut-dialog.h \
 	keyboard-dialog_glade.h
 
 xfce4_keyboard_settings_CFLAGS = \

Modified: xfce4-settings/trunk/dialogs/keyboard-settings/keyboard-dialog.glade
===================================================================
--- xfce4-settings/trunk/dialogs/keyboard-settings/keyboard-dialog.glade	2008-07-09 22:23:53 UTC (rev 27250)
+++ xfce4-settings/trunk/dialogs/keyboard-settings/keyboard-dialog.glade	2008-07-10 10:14:50 UTC (rev 27251)
@@ -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 Tue Jul  1 22:39:19 2008 -->
+<!--Generated with glade3 3.4.5 on Sat Jul  5 23:32:27 2008 -->
 <glade-interface>
   <requires lib="xfce4"/>
   <widget class="XfceTitledDialog" id="keyboard-settings-dialog">
@@ -23,114 +23,103 @@
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <child>
-                  <widget class="GtkHBox" id="hbox1">
+                  <widget class="GtkVBox" id="vbox2">
                     <property name="visible">True</property>
                     <property name="border_width">12</property>
-                    <property name="spacing">12</property>
+                    <property name="spacing">6</property>
                     <child>
-                      <widget class="GtkFrame" id="frame1">
+                      <widget class="GtkHBox" id="hbox1">
                         <property name="visible">True</property>
-                        <property name="label_xalign">0</property>
-                        <property name="shadow_type">GTK_SHADOW_NONE</property>
+                        <property name="spacing">12</property>
                         <child>
-                          <widget class="GtkAlignment" id="alignment1">
+                          <widget class="GtkFrame" id="frame1">
                             <property name="visible">True</property>
-                            <property name="border_width">6</property>
-                            <property name="left_padding">12</property>
+                            <property name="label_xalign">0</property>
+                            <property name="shadow_type">GTK_SHADOW_NONE</property>
                             <child>
-                              <widget class="GtkScrolledWindow" id="scrolledwindow1">
+                              <widget class="GtkAlignment" id="alignment1">
                                 <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="left_padding">12</property>
                                 <child>
-                                  <widget class="GtkTreeView" id="gtk_keytheme_treeview">
+                                  <widget class="GtkScrolledWindow" id="scrolledwindow1">
                                     <property name="visible">True</property>
                                     <property name="can_focus">True</property>
-                                    <property name="headers_visible">False</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>
+                                    <child>
+                                      <widget class="GtkTreeView" id="gtk_keytheme_treeview">
+                                        <property name="visible">True</property>
+                                        <property name="can_focus">True</property>
+                                        <property name="headers_visible">False</property>
+                                      </widget>
+                                    </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="GtkLabel" id="label4">
+                          <widget class="GtkVBox" id="vbox3">
                             <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="vbox2">
-                        <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>
+                            <property name="spacing">6</property>
                             <child>
-                              <widget class="GtkAlignment" id="alignment2">
+                              <widget class="GtkFrame" id="frame2">
                                 <property name="visible">True</property>
-                                <property name="bottom_padding">6</property>
-                                <property name="left_padding">12</property>
+                                <property name="label_xalign">0</property>
+                                <property name="shadow_type">GTK_SHADOW_NONE</property>
                                 <child>
-                                  <widget class="GtkVBox" id="vbox3">
+                                  <widget class="GtkAlignment" id="alignment2">
                                     <property name="visible">True</property>
-                                    <property name="border_width">6</property>
-                                    <property name="spacing">6</property>
+                                    <property name="bottom_padding">6</property>
+                                    <property name="left_padding">12</property>
                                     <child>
-                                      <widget class="GtkCheckButton" id="xkb_key_repeat_check">
+                                      <widget class="GtkVBox" id="vbox3">
                                         <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="border_width">6</property>
+                                        <property name="spacing">6</property>
                                         <child>
-                                          <widget class="GtkVBox" id="vbox6">
+                                          <widget class="GtkCheckButton" id="xkb_key_repeat_check">
                                             <property name="visible">True</property>
-                                            <property name="spacing">6</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>
                                             <child>
-                                              <widget class="GtkLabel" id="label7">
+                                              <widget class="GtkVBox" id="vbox6">
                                                 <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>
-                                              </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>
+                                                <property name="spacing">6</property>
                                                 <child>
-                                                  <widget class="GtkLabel" id="label8">
+                                                  <widget class="GtkLabel" id="label7">
                                                     <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>
+                                                    <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>
@@ -138,22 +127,58 @@
                                                   </packing>
                                                 </child>
                                                 <child>
-                                                  <widget class="GtkHScale" id="xkb_key_repeat_delay_scale">
+                                                  <widget class="GtkHBox" id="hbox2">
                                                     <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>
+                                                    <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>
                                                   </widget>
                                                   <packing>
+                                                    <property name="expand">False</property>
+                                                    <property name="fill">False</property>
                                                     <property name="position">1</property>
                                                   </packing>
                                                 </child>
                                                 <child>
-                                                  <widget class="GtkLabel" id="label9">
+                                                  <widget class="GtkLabel" id="label10">
                                                     <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>
+                                                    <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>
@@ -161,158 +186,122 @@
                                                     <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="GtkLabel" id="label11">
+                                                  <widget class="GtkHBox" id="hbox3">
                                                     <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>
+                                                    <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>
                                                   </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="type">label_item</property>
+                                <property name="expand">False</property>
+                                <property name="fill">False</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="GtkAlignment" id="alignment3">
+                              <widget class="GtkFrame" id="frame3">
                                 <property name="visible">True</property>
-                                <property name="left_padding">12</property>
+                                <property name="label_xalign">0</property>
+                                <property name="shadow_type">GTK_SHADOW_NONE</property>
                                 <child>
-                                  <widget class="GtkVBox" id="vbox4">
+                                  <widget class="GtkAlignment" id="alignment3">
                                     <property name="visible">True</property>
-                                    <property name="border_width">6</property>
-                                    <property name="spacing">6</property>
+                                    <property name="left_padding">12</property>
                                     <child>
-                                      <widget class="GtkCheckButton" id="net_cursor_blink_check">
+                                      <widget class="GtkVBox" id="vbox4">
                                         <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="border_width">6</property>
+                                        <property name="spacing">6</property>
                                         <child>
-                                          <widget class="GtkVBox" id="vbox7">
+                                          <widget class="GtkCheckButton" id="net_cursor_blink_check">
                                             <property name="visible">True</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="GtkLabel" id="label13">
+                                              <widget class="GtkVBox" id="vbox7">
                                                 <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>
-                                              </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>
+                                                <property name="spacing">6</property>
                                                 <child>
-                                                  <widget class="GtkLabel" id="label14">
+                                                  <widget class="GtkLabel" id="label13">
                                                     <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>
+                                                    <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>
@@ -320,54 +309,74 @@
                                                   </packing>
                                                 </child>
                                                 <child>
-                                                  <widget class="GtkHScale" id="net_cursor_blink_time_scale">
+                                                  <widget class="GtkHBox" id="hbox4">
                                                     <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>
+                                                    <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>
                                                   </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>
+                                                    <property name="position">1</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="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="type">label_item</property>
+                                <property name="position">1</property>
                               </packing>
                             </child>
                           </widget>
@@ -376,10 +385,32 @@
                           </packing>
                         </child>
                       </widget>
+                    </child>
+                    <child>
+                      <widget class="GtkLabel" id="label1">
+                        <property name="visible">True</property>
+                        <property name="xalign">0</property>
+                        <property name="yalign">1</property>
+                        <property name="label" translatable="yes">Use this area to test the settings above:</property>
+                        <property name="wrap_mode">PANGO_WRAP_WORD_CHAR</property>
+                      </widget>
                       <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
                         <property name="position">1</property>
                       </packing>
                     </child>
+                    <child>
+                      <widget class="GtkEntry" id="entry1">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                      </widget>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                        <property name="position">2</property>
+                      </packing>
+                    </child>
                   </widget>
                 </child>
                 <child>
@@ -401,7 +432,7 @@
                       <widget class="GtkLabel" id="label16">
                         <property name="visible">True</property>
                         <property name="xalign">0</property>
-                        <property name="label" translatable="yes">label</property>
+                        <property name="label" translatable="yes">Define shortcuts for launching applications:</property>
                       </widget>
                       <packing>
                         <property name="expand">False</property>
@@ -416,9 +447,10 @@
                         <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
                         <property name="shadow_type">GTK_SHADOW_IN</property>
                         <child>
-                          <widget class="GtkTreeView" id="treeview2">
+                          <widget class="GtkTreeView" id="kbd_shortcuts_view">
                             <property name="visible">True</property>
                             <property name="can_focus">True</property>
+                            <property name="search_column">0</property>
                           </widget>
                         </child>
                       </widget>
@@ -433,7 +465,7 @@
                         <property name="spacing">12</property>
                         <property name="layout_style">GTK_BUTTONBOX_SPREAD</property>
                         <child>
-                          <widget class="GtkButton" id="button3">
+                          <widget class="GtkButton" id="add_shortcut_button">
                             <property name="visible">True</property>
                             <property name="can_focus">True</property>
                             <property name="receives_default">True</property>
@@ -443,7 +475,7 @@
                           </widget>
                         </child>
                         <child>
-                          <widget class="GtkButton" id="button4">
+                          <widget class="GtkButton" id="delete_shortcut_button">
                             <property name="visible">True</property>
                             <property name="can_focus">True</property>
                             <property name="receives_default">True</property>
@@ -483,31 +515,6 @@
                 <property name="position">1</property>
               </packing>
             </child>
-            <child>
-              <widget class="GtkLabel" id="label1">
-                <property name="visible">True</property>
-                <property name="xalign">0</property>
-                <property name="yalign">1</property>
-                <property name="label" translatable="yes">Use this area to test the settings above</property>
-                <property name="wrap_mode">PANGO_WRAP_WORD_CHAR</property>
-              </widget>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">2</property>
-              </packing>
-            </child>
-            <child>
-              <widget class="GtkEntry" id="entry1">
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-              </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>

Modified: xfce4-settings/trunk/dialogs/keyboard-settings/main.c
===================================================================
--- xfce4-settings/trunk/dialogs/keyboard-settings/main.c	2008-07-09 22:23:53 UTC (rev 27250)
+++ xfce4-settings/trunk/dialogs/keyboard-settings/main.c	2008-07-10 10:14:50 UTC (rev 27251)
@@ -1,5 +1,6 @@
 /*
  *  Copyright (c) 2008 Stephan Arts <stephan at xfce.org>
+ *  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
@@ -16,140 +17,514 @@
  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
+#ifdef HAVE_CONFIG_H
 #include <config.h>
+#endif
+
+#include <stdlib.h>
 #include <string.h>
 
 #include <glib.h>
 
-#if defined(GETTEXT_PACKAGE)
-#include <glib/gi18n-lib.h>
-#else
-#include <glib/gi18n.h>
-#endif
+#include <gtk/gtk.h>
 
-#include <gtk/gtk.h>
 #include <glade/glade.h>
 
+#include <libxfce4util/libxfce4util.h>
 #include <libxfcegui4/libxfcegui4.h>
+
 #include <xfconf/xfconf.h>
+
 #include "keyboard-dialog_glade.h"
+#include "shortcut-dialog.h"
 
-typedef struct {
-    GtkWidget *slave;
-    XfconfChannel *channel;
-} PropertyPair;
 
-gboolean version = FALSE;
 
-static GOptionEntry entries[] =
+enum
 {
-    {    "version", 'v', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_NONE, &version,
-        N_("Version information"),
-        NULL
-    },
-    { NULL }
+  SHORTCUT_COLUMN,
+  ACTION_COLUMN,
 };
 
-void
-cb_xkb_key_repeat_toggled (GtkToggleButton *button, gpointer user_data)
+
+
+gboolean opt_version = FALSE;
+
+
+
+static GOptionEntry entries[] = {
+  { "version", 'v', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_NONE, &opt_version, N_("Version information"), NULL },
+  { NULL }
+};
+
+
+
+static void
+xkb_key_repeat_toggled (GtkToggleButton *button, 
+                        GladeXML        *gxml)
 {
-    GladeXML *gxml = GLADE_XML(user_data);
-    GtkWidget *box = glade_xml_get_widget (gxml, "xkb_key_repeat_box");
+    GtkWidget *box;
+    
+    box = glade_xml_get_widget (gxml, "xkb_key_repeat_box");
     gtk_widget_set_sensitive (box, gtk_toggle_button_get_active (button));
 }
 
-void
-cb_net_cursor_blink_toggled (GtkToggleButton *button, gpointer user_data)
+
+
+static void
+net_cursor_blink_toggled (GtkToggleButton *button, 
+                          GladeXML        *gxml)
 {
-    GladeXML *gxml = GLADE_XML(user_data);
-    GtkWidget *box = glade_xml_get_widget (gxml, "net_cursor_blink_box");
+    GtkWidget *box;
+    
+    box = glade_xml_get_widget (gxml, "net_cursor_blink_box");
     gtk_widget_set_sensitive (box, gtk_toggle_button_get_active (button));
 }
 
-GtkWidget *
+
+
+static void
+keyboard_settings_load_shortcut (const gchar  *key,
+                                 const GValue *value,
+                                 GtkListStore *list_store)
+{
+  const GPtrArray *array;
+  const GValue    *type_value;
+  const GValue    *action_value;
+  const gchar     *type;
+  const gchar     *action;
+  GtkTreeIter      iter;
+
+  /* MAke sure we only load shortcuts from string arrays */
+  if (G_UNLIKELY (G_VALUE_TYPE (value) != dbus_g_type_get_collection ("GPtrArray", G_TYPE_VALUE)))
+    return;
+
+  /* Get the pointer array */
+  array = g_value_get_boxed (value);
+
+  /* Make sure the array has exactly two members */
+  if (G_UNLIKELY (array->len != 2))
+    return;
+
+  /* Get GValues for the array members */
+  type_value = g_ptr_array_index (array, 0);
+  action_value = g_ptr_array_index (array, 1);
+
+  /* Make sure both are string values */
+  if (G_UNLIKELY (G_VALUE_TYPE (type_value) != G_TYPE_STRING || G_VALUE_TYPE (action_value) != G_TYPE_STRING))
+    return;
+
+  /* Get shortcut type and action */
+  type = g_value_get_string (type_value);
+  action = g_value_get_string (action_value);
+
+  /* Only add shortcuts with type 'execute' */
+  if (g_utf8_collate (type, "execute") == 0)
+    {
+      /* Add shortcut to the list store */
+      gtk_list_store_append (list_store, &iter);
+      gtk_list_store_set (list_store, &iter, SHORTCUT_COLUMN, key+1, ACTION_COLUMN, action, -1);
+    }
+}
+
+
+
+static void
+keyboard_settings_load_shortcuts (XfconfChannel *channel, 
+                                  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);
+
+  if (G_LIKELY (shortcuts != NULL))
+    {
+      g_hash_table_foreach (shortcuts, (GHFunc) keyboard_settings_load_shortcut, list_store);
+      g_hash_table_destroy (shortcuts);
+    }
+}
+
+
+
+static void
+keyboard_settings_add_shortcut (GtkTreeView *tree_view)
+{
+}
+
+
+
+static void
+keyboard_settings_delete_shortcut (GtkTreeView *tree_view)
+{
+  GtkTreeSelection *selection;
+  XfconfChannel    *channel;
+  GtkTreeModel     *model;
+  GtkTreePath      *path;
+  GtkTreeIter       iter;
+  GList            *rows;
+  GList            *row_iter;
+  GList            *row_references = NULL;
+  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);
+
+  for (row_iter = g_list_first (rows); row_iter != NULL; row_iter = g_list_next (row_iter))
+    row_references = g_list_append (row_references, gtk_tree_row_reference_new (model, (GtkTreePath *) (row_iter->data)));
+
+  for (row_iter = g_list_first (row_references); row_iter != NULL; row_iter = g_list_next (row_iter))
+    {
+      path = gtk_tree_row_reference_get_path ((GtkTreeRowReference *) (row_iter->data));
+
+      /* Conver tree path to tree iter */
+      if (G_LIKELY (gtk_tree_model_get_iter (model, &iter, path)))
+        {
+          /* Read row values */
+          gtk_tree_model_get (model, &iter, SHORTCUT_COLUMN, &shortcut, -1);
+
+          /* Delete row from the list store */
+          gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
+
+          /* Build property name */
+          property_name = g_strdup_printf ("/%s", shortcut);
+
+          /* Remove keyboard shortcut via xfconf */
+          xfconf_channel_remove_property (channel, property_name);
+
+          /* Free strings */
+          g_free (property_name);
+          g_free (shortcut);
+        }
+
+      gtk_tree_path_free (path);
+    }
+
+  /* Free row reference list */
+  g_list_foreach (row_references, (GFunc) gtk_tree_row_reference_free, NULL);
+  g_list_free (row_references);
+
+  /* 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);
+}
+
+
+
+static void
+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);
+
+  /* Get iter for the edited row */
+  if (G_LIKELY (gtk_tree_model_get_iter_from_string (model, &iter, path)))
+    {
+      /* Read row values */
+      gtk_tree_model_get (model, &iter, SHORTCUT_COLUMN, &shortcut, ACTION_COLUMN, &old_text, -1);
+
+      /* Check whether anything has changed at all */
+      if (G_LIKELY (g_utf8_collate (old_text, new_text) != 0))
+        {
+          /* Upate row data with the new text */
+          gtk_list_store_set (GTK_LIST_STORE (model), &iter, ACTION_COLUMN, new_text, -1);
+
+          /* Build xfconf property name */
+          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);
+
+          /* Free property name */
+          g_free (property_name);
+        }
+
+      /* Free strings */
+      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)
+{
+  XfconfChannel *channel;
+  GtkTreeModel  *model;
+  GtkTreeIter    iter;
+  GtkWidget     *dialog;
+  const gchar   *new_shortcut;
+  gchar         *current_shortcut;
+  gchar         *action;
+  gchar         *old_property;
+  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);
+
+  /* Convert tree path to tree iter */
+  if (G_LIKELY (gtk_tree_model_get_iter (model, &iter, path)))
+    {
+      /* Read current shortcut from the activated row */
+      gtk_tree_model_get (model, &iter, SHORTCUT_COLUMN, &current_shortcut, ACTION_COLUMN, &action, -1);
+
+      /* Request a new shortcut from the user */
+      dialog = shortcut_dialog_new (action);
+      g_signal_connect (dialog, "validate-shortcut", G_CALLBACK (keyboard_settings_validate_shortcut), tree_view);
+      response = shortcut_dialog_run (SHORTCUT_DIALOG (dialog), GTK_WIDGET (tree_view));
+
+      if (G_LIKELY (response != GTK_RESPONSE_CANCEL))
+        {
+          /* Build property name */
+          old_property = g_strdup_printf ("/%s", current_shortcut);
+
+          /* Remove old shortcut from the settings */
+          xfconf_channel_remove_property (channel, old_property);
+
+          /* Get the shortcut entered by the user */
+          new_shortcut = shortcut_dialog_get_shortcut (SHORTCUT_DIALOG (dialog));
+
+          /* Save the new shortcut */
+          gtk_list_store_set (GTK_LIST_STORE (model), &iter, SHORTCUT_COLUMN, new_shortcut, -1);
+
+          /* Only save new shortcut if it's not empty */
+          if (G_LIKELY (response == GTK_RESPONSE_OK && strlen (new_shortcut) > 0))
+            {
+              /* Build property name */
+              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);
+
+              /* Free property names */
+              g_free (new_property);
+            }
+
+          /* Free strings */
+          g_free (old_property);
+        }
+
+      /* Destroy the shortcut dialog */
+      gtk_widget_destroy (dialog);
+
+      /* Free strings */
+      g_free (action);
+      g_free (current_shortcut);
+    }
+
+  /* Release xfconf channel */
+  g_object_unref (channel);
+}
+
+
+
+GtkWidget*
 keyboard_settings_dialog_new_from_xml (GladeXML *gxml)
 {
-    XfconfChannel *xsettings_channel = xfconf_channel_new("xsettings");
-    XfconfChannel *xkb_channel = xfconf_channel_new("xkb");
+  GtkTreeViewColumn *column;
+  GtkCellRenderer *renderer;
+  XfconfChannel   *xsettings_channel;
+  XfconfChannel   *xkb_channel;
+  XfconfChannel   *kbd_channel;
+  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;
 
-    GtkWidget *net_cursor_blink_check = glade_xml_get_widget (gxml, "net_cursor_blink_check");
-    GtkWidget *net_cursor_blink_time_scale = (GtkWidget *)gtk_range_get_adjustment (GTK_RANGE (glade_xml_get_widget (gxml, "net_cursor_blink_time_scale")));
-    GtkWidget *xkb_key_repeat_check = glade_xml_get_widget (gxml, "xkb_key_repeat_check");
-    GtkWidget *xkb_key_repeat_delay_scale = (GtkWidget *)gtk_range_get_adjustment (GTK_RANGE (glade_xml_get_widget (gxml, "xkb_key_repeat_delay_scale")));
-    GtkWidget *xkb_key_repeat_rate_scale = (GtkWidget *)gtk_range_get_adjustment (GTK_RANGE (glade_xml_get_widget (gxml, "xkb_key_repeat_rate_scale")));
+  xsettings_channel = xfconf_channel_new ("xsettings");
+  xkb_channel = xfconf_channel_new ("xkb");
+  kbd_channel = xfconf_channel_new ("xfce4-keyboard-shortcuts");
 
-    g_signal_connect (G_OBJECT(net_cursor_blink_check), "toggled", (GCallback)cb_net_cursor_blink_toggled, gxml);
-    g_signal_connect (G_OBJECT(xkb_key_repeat_check), "toggled", (GCallback)cb_xkb_key_repeat_toggled, gxml);
+  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")));
+  xkb_key_repeat_check = glade_xml_get_widget (gxml, "xkb_key_repeat_check");
+  xkb_key_repeat_delay_scale = gtk_range_get_adjustment (GTK_RANGE (glade_xml_get_widget (gxml, "xkb_key_repeat_delay_scale")));
+  xkb_key_repeat_rate_scale = gtk_range_get_adjustment (GTK_RANGE (glade_xml_get_widget (gxml, "xkb_key_repeat_rate_scale")));
+  kbd_shortcuts_view = glade_xml_get_widget (gxml, "kbd_shortcuts_view");
+  add_shortcut_button = glade_xml_get_widget (gxml, "add_shortcut_button");
+  delete_shortcut_button = glade_xml_get_widget (gxml, "delete_shortcut_button");
 
+  g_signal_connect (net_cursor_blink_check, "toggled", G_CALLBACK (net_cursor_blink_toggled), gxml);
+  g_signal_connect (xkb_key_repeat_check, "toggled", G_CALLBACK (xkb_key_repeat_toggled), gxml);
 
-    /* XKB Settings */
-    xfconf_g_property_bind (xkb_channel, 
-                            "/Xkb/KeyRepeat",
-                            G_TYPE_BOOLEAN,
-                            (GObject *)xkb_key_repeat_check, "active");
-    xfconf_g_property_bind (xkb_channel, 
-                            "/Xkb/KeyRepeat/Rate",
-                            G_TYPE_INT,
-                            (GObject *)xkb_key_repeat_rate_scale, "value");
-    xfconf_g_property_bind (xkb_channel, 
-                            "/Xkb/KeyRepeat/Delay",
-                            G_TYPE_INT,
-                            (GObject *)xkb_key_repeat_delay_scale, "value");
-    /* XSETTINGS */
-    xfconf_g_property_bind (xsettings_channel, 
-                            "/Net/CursorBlink",
-                            G_TYPE_BOOLEAN,
-                            (GObject *)net_cursor_blink_check, "active");
-    xfconf_g_property_bind (xsettings_channel, 
-                            "/Net/CursorBlinkTime",
-                            G_TYPE_INT,
-                            (GObject *)net_cursor_blink_time_scale, "value");
+  /* XKB Settings */
+  xfconf_g_property_bind (xkb_channel, "/Xkb/KeyRepeat", G_TYPE_BOOLEAN, G_OBJECT (xkb_key_repeat_check), "active");
+  xfconf_g_property_bind (xkb_channel, "/Xkb/KeyRepeat/Rate", G_TYPE_INT, G_OBJECT (xkb_key_repeat_rate_scale), "value");
+  xfconf_g_property_bind (xkb_channel, "/Xkb/KeyRepeat/Delay", G_TYPE_INT, G_OBJECT (xkb_key_repeat_delay_scale), "value");
 
-    GtkWidget *dialog = glade_xml_get_widget (gxml, "keyboard-settings-dialog");
-    gtk_widget_show_all(dialog);
-    gtk_widget_hide(dialog);
-    return dialog;
+  /* XSETTINGS */
+  xfconf_g_property_bind (xsettings_channel, "/Net/CursorBlink", G_TYPE_BOOLEAN, G_OBJECT (net_cursor_blink_check), "active");
+  xfconf_g_property_bind (xsettings_channel, "/Net/CursorBlinkTime", G_TYPE_INT, G_OBJECT (net_cursor_blink_time_scale), "value");
+
+  /* Configure shortcuts tree view */
+  gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (kbd_shortcuts_view), TRUE);
+  gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (kbd_shortcuts_view)), GTK_SELECTION_MULTIPLE);
+  g_signal_connect (kbd_shortcuts_view, "row-activated", G_CALLBACK (keyboard_settings_row_activated), NULL);
+
+  /* Create list store for keyboard shortcuts */
+  list_store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
+  gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (list_store), SHORTCUT_COLUMN, GTK_SORT_ASCENDING);
+  gtk_tree_view_set_model (GTK_TREE_VIEW (kbd_shortcuts_view), GTK_TREE_MODEL (list_store));
+
+  /* Create shortcut column */
+  renderer = gtk_cell_renderer_text_new ();
+  column = gtk_tree_view_column_new_with_attributes (_("Shortcut"), renderer, "text", SHORTCUT_COLUMN, NULL);
+  gtk_tree_view_append_column (GTK_TREE_VIEW (kbd_shortcuts_view), column);
+
+  /* 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);
+
+  /* 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));
+  g_signal_connect_swapped (delete_shortcut_button, "clicked", G_CALLBACK (keyboard_settings_delete_shortcut), GTK_TREE_VIEW (kbd_shortcuts_view));
+
+  /* Get dialog widget */
+  dialog = glade_xml_get_widget (gxml, "keyboard-settings-dialog");
+  gtk_widget_show_all(dialog);
+  gtk_widget_hide(dialog);
+
+  g_object_unref (xsettings_channel);
+  g_object_unref (xkb_channel);
+  g_object_unref (kbd_channel);
+
+  return dialog;
 }
 
 int
 main(int argc, char **argv)
 {
-    GladeXML *gxml;
-    GError *cli_error = NULL;
+  GtkWidget *dialog;
+  GladeXML  *gxml;
+  GError    *error = NULL;
 
-    #ifdef ENABLE_NLS
-    bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
-    bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
-    textdomain (GETTEXT_PACKAGE);
-    #endif
+  /* Set translation domain */
+  xfce_textdomain (GETTEXT_PACKAGE, LOCALEDIR, "UTF-8");
 
-    if(!gtk_init_with_args(&argc, &argv, _("."), entries, PACKAGE, &cli_error))
+  /* Initialize GTK+ and parse command line options */
+  if(G_UNLIKELY (!gtk_init_with_args (&argc, &argv, _("."), entries, PACKAGE, &error)))
     {
-        if (cli_error != NULL)
+      /* Print error if that failed */
+      if (G_LIKELY (error != NULL))
         {
-            g_print (_("%s: %s\nTry %s --help to see a full list of available command line options.\n"), PACKAGE, cli_error->message, PACKAGE_NAME);
-            g_error_free (cli_error);
-            return 1;
+          g_print (_("%s: %s\nTry %s --help to see a full list of available command line options.\n"), PACKAGE, error->message, PACKAGE_NAME);
+          g_error_free (error);
+          return EXIT_FAILURE;
         }
     }
 
-    if(version)
+  /* Print version information and quit when the user entered --version or -v */
+  if (G_UNLIKELY (opt_version))
     {
-        g_print("%s\n", PACKAGE_STRING);
-        return 0;
+      g_print ("%s\n", PACKAGE_STRING);
+      return EXIT_SUCCESS;
     }
 
-    xfconf_init(NULL);
+  xfconf_init(NULL);
 
-    gxml = glade_xml_new_from_buffer (keyboard_dialog_glade,
-                                      keyboard_dialog_glade_length,
-                                      NULL, NULL);
+  /* Parse Glade XML */
+  gxml = glade_xml_new_from_buffer (keyboard_dialog_glade, keyboard_dialog_glade_length, NULL, NULL);
 
-    GtkWidget *dialog = keyboard_settings_dialog_new_from_xml (gxml);
+  /* 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));
+  xfconf_shutdown();
 
-    xfconf_shutdown();
-
-    return 0;
+  return EXIT_SUCCESS;
 }

Added: xfce4-settings/trunk/dialogs/keyboard-settings/shortcut-dialog.c
===================================================================
--- xfce4-settings/trunk/dialogs/keyboard-settings/shortcut-dialog.c	                        (rev 0)
+++ xfce4-settings/trunk/dialogs/keyboard-settings/shortcut-dialog.c	2008-07-10 10:14:50 UTC (rev 27251)
@@ -0,0 +1,348 @@
+/* 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 "shortcut-dialog.h"
+
+
+
+static void     shortcut_dialog_class_init       (ShortcutDialogClass *klass);
+static void     shortcut_dialog_init             (ShortcutDialog      *dialog);
+static void     shortcut_dialog_dispose          (GObject             *object);
+static void     shortcut_dialog_finalize         (GObject             *object);
+static void     shortcut_dialog_create_contents  (ShortcutDialog      *dialog,
+                                                  const gchar         *action);
+static gboolean shortcut_dialog_key_released     (ShortcutDialog      *dialog,
+                                                  GdkEventKey         *event);
+
+
+
+struct _ShortcutDialogClass
+{
+  GtkDialogClass __parent__;
+
+  gboolean (*validate_shortcut) (ShortcutDialog *dialog,
+                                 const gchar    *shortcut,
+                                 gpointer        user_data);
+
+  gint validate_shortcut_signal;
+};
+
+struct _ShortcutDialog
+{
+  GtkDialog __parent__;
+
+  gchar    *shortcut;
+};
+
+
+
+static GObjectClass *shortcut_dialog_parent_class = NULL;
+
+
+
+GType
+shortcut_dialog_get_type (void)
+{
+  static GType type = G_TYPE_INVALID;
+
+  if (G_UNLIKELY (type == G_TYPE_INVALID))
+    {
+      static const GTypeInfo info = 
+        {
+          sizeof (ShortcutDialogClass),
+          NULL,
+          NULL,
+          (GClassInitFunc) shortcut_dialog_class_init,
+          NULL,
+          NULL,
+          sizeof (ShortcutDialog),
+          0,
+          (GInstanceInitFunc) shortcut_dialog_init,
+          NULL,
+        };
+
+      type = g_type_register_static (GTK_TYPE_DIALOG, "ShortcutDialog", &info, 0);
+    }
+  
+  return type;
+}
+
+
+
+/**
+ * Taken from GTK+ (_gtk_marshal_BOOLEAN__SRING). Credits go out to the
+ * GTK+ devs for this.
+ */
+void
+marshal_BOOLEAN__STRING (GClosure     *closure,
+                         GValue       *return_value G_GNUC_UNUSED,
+                         guint         n_param_values,
+                         const GValue *param_values,
+                         gpointer      invocation_hint G_GNUC_UNUSED,
+                         gpointer      marshal_data)
+{
+  typedef gboolean (*GMarshalFunc_BOOLEAN__STRING) (gpointer     data1,
+                                                    gpointer     arg_1,
+                                                    gpointer     data2);
+  register GMarshalFunc_BOOLEAN__STRING callback;
+  register GCClosure *cc = (GCClosure*) closure;
+  register gpointer data1, data2;
+  gboolean v_return;
+
+  g_return_if_fail (return_value != NULL);
+  g_return_if_fail (n_param_values == 2);
+
+  if (G_CCLOSURE_SWAP_DATA (closure))
+    {
+      data1 = closure->data;
+      data2 = g_value_peek_pointer (param_values + 0);
+    }
+  else
+    {
+      data1 = g_value_peek_pointer (param_values + 0);
+      data2 = closure->data;
+    }
+
+  callback = (GMarshalFunc_BOOLEAN__STRING) (marshal_data ? marshal_data : cc->callback);
+
+  #define g_marshal_value_peek_string(v) (char*) g_value_get_string (v)
+  v_return = callback (data1, g_marshal_value_peek_string (param_values + 1), data2);
+
+  g_value_set_boolean (return_value, v_return);
+}
+
+
+
+
+static void
+shortcut_dialog_class_init (ShortcutDialogClass *klass)
+{
+  GObjectClass *gobject_class;
+
+  /* Determine parent type class */
+  shortcut_dialog_parent_class = g_type_class_peek_parent (klass);
+
+  gobject_class = G_OBJECT_CLASS (klass);
+  gobject_class->dispose = shortcut_dialog_dispose;
+  gobject_class->finalize = shortcut_dialog_finalize;
+
+  klass->validate_shortcut = NULL; 
+
+  /* Create 'validate-shortcut' signal */
+  klass->validate_shortcut_signal = g_signal_new ("validate-shortcut",
+                                                  G_TYPE_FROM_CLASS (klass),
+                                                  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+                                                  G_STRUCT_OFFSET (ShortcutDialogClass, validate_shortcut),
+                                                  NULL,
+                                                  NULL,
+                                                  marshal_BOOLEAN__STRING,
+                                                  G_TYPE_BOOLEAN,
+                                                  1,
+                                                  G_TYPE_STRING);
+}
+
+
+
+static void
+shortcut_dialog_init (ShortcutDialog *dialog)
+{
+  dialog->shortcut = NULL;
+}
+
+
+
+static void
+shortcut_dialog_dispose (GObject *object)
+{
+  (*G_OBJECT_CLASS (shortcut_dialog_parent_class)->dispose) (object);
+}
+
+
+
+static void
+shortcut_dialog_finalize (GObject *object)
+{
+  ShortcutDialog *dialog = SHORTCUT_DIALOG (object);
+
+  g_free (dialog->shortcut);
+
+  (*G_OBJECT_CLASS (shortcut_dialog_parent_class)->finalize) (object);
+}
+
+
+
+GtkWidget*
+shortcut_dialog_new (const gchar *action)
+{
+  ShortcutDialog *dialog;
+  
+  dialog = SHORTCUT_DIALOG (g_object_new (TYPE_SHORTCUT_DIALOG, NULL));
+
+  shortcut_dialog_create_contents (dialog, action);
+
+  return GTK_WIDGET (dialog);
+}
+
+
+
+static void
+shortcut_dialog_create_contents (ShortcutDialog *dialog,
+                                 const gchar    *action)
+{
+  GtkWidget *button;
+  GtkWidget *hbox;
+  GtkWidget *label;
+  GtkWidget *image;
+  gchar     *text;
+
+  /* Set dialog title */
+  gtk_window_set_title (GTK_WINDOW (dialog), _("Set shortcut"));
+
+  /* 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);
+
+  /* Create clear button */
+  button = GTK_WIDGET (xfce_create_mixed_button (GTK_STOCK_CLEAR, _("No shortcut")));
+  gtk_dialog_add_action_widget (GTK_DIALOG (dialog), button, GTK_RESPONSE_NO);
+  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);
+
+  image = gtk_image_new_from_icon_name ("input-keyboard", GTK_ICON_SIZE_DIALOG);
+  gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, TRUE, 0);
+  gtk_widget_show (image);
+
+  text = g_markup_printf_escaped ("%s\n<b>%s</b>", _("Set shortcut for command:"), action);
+
+  label = gtk_label_new (NULL);
+  gtk_label_set_markup (GTK_LABEL (label), text);
+  gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_CENTER);
+  gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
+  gtk_widget_show (label);
+
+  g_free (text);
+
+  /* Connect to key release signal for determining the new shortcut */
+  g_signal_connect_swapped (dialog, "key-release-event", G_CALLBACK (shortcut_dialog_key_released), dialog);
+}
+
+
+
+gint
+shortcut_dialog_run (ShortcutDialog *dialog,
+                     GtkWidget      *parent)
+{
+  gint response = GTK_RESPONSE_CANCEL;
+
+  g_return_val_if_fail (IS_SHORTCUT_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);
+
+  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))
+    {
+      /* Run the dialog and wait for the user to enter a valid shortcut */
+      response = gtk_dialog_run (GTK_DIALOG (dialog));
+
+      /* Clear shortcut if requested by the user */
+      if (G_UNLIKELY (response == GTK_RESPONSE_NO))
+        {
+          g_free (dialog->shortcut);
+          dialog->shortcut = g_strdup ("");
+        }
+
+      /* Release keyboard */
+      gdk_keyboard_ungrab (GDK_CURRENT_TIME);
+    }
+  else
+    g_warning ("%s", _("Could not grab the keyboard."));
+
+  /* Return the response ID */
+  return response;
+}
+
+
+
+static gboolean 
+shortcut_dialog_key_released (ShortcutDialog *dialog,
+                              GdkEventKey    *event)
+{
+  gboolean event_handled = FALSE;
+  gboolean shortcut_accepted = FALSE;
+  gchar   *shortcut;
+
+  /* Get GTK+ accelerator string */
+  shortcut = gtk_accelerator_name (event->keyval, event->state);
+
+  /* Let 'validate-shortcut' listeners decide whether this shortcut is ok or not */
+  g_signal_emit_by_name (dialog, "validate-shortcut", shortcut, &shortcut_accepted);
+
+  g_message ("shortcut accepted: %s", shortcut_accepted ? "yes" : "no");
+
+  /* Check if the shortcut was accepted */
+  if (G_LIKELY (shortcut_accepted))
+    {
+      /* Replace old shortcut */
+      g_free (dialog->shortcut);
+      dialog->shortcut = shortcut;
+
+      /* Release keyboard */
+      gdk_keyboard_ungrab (GDK_CURRENT_TIME);
+
+      /* Exit dialog with positive response */
+      gtk_dialog_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
+    }
+  else
+    {
+      /* Free shortcut string */
+      g_free (shortcut);
+    }
+
+  return event_handled;
+}
+
+
+
+const gchar*
+shortcut_dialog_get_shortcut (ShortcutDialog *dialog)
+{
+  g_return_val_if_fail (IS_SHORTCUT_DIALOG (dialog), NULL);
+  return dialog->shortcut;
+}

Added: xfce4-settings/trunk/dialogs/keyboard-settings/shortcut-dialog.h
===================================================================
--- xfce4-settings/trunk/dialogs/keyboard-settings/shortcut-dialog.h	                        (rev 0)
+++ xfce4-settings/trunk/dialogs/keyboard-settings/shortcut-dialog.h	2008-07-10 10:14:50 UTC (rev 27251)
@@ -0,0 +1,47 @@
+/* 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 __SHORTCUT_DIALOG_H__
+#define __SHORTCUT_DIALOG_H__
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS;
+
+typedef struct _ShortcutDialogClass ShortcutDialogClass;
+typedef struct _ShortcutDialog      ShortcutDialog;
+
+#define TYPE_SHORTCUT_DIALOG            (shortcut_dialog_get_type ())
+#define SHORTCUT_DIALOG(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_SHORTCUT_DIALOG, ShortcutDialog))
+#define SHORTCUT_DIALOG_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_SHORTCUT_DIALOG, ShortcutDialogClass))
+#define IS_SHORTCUT_DIALOG(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_SHORTCUT_DIALOG))
+#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;
+
+GtkWidget   *shortcut_dialog_new          (const gchar    *action);
+gint         shortcut_dialog_run          (ShortcutDialog *dialog,
+                                           GtkWidget      *parent);
+const gchar *shortcut_dialog_get_shortcut (ShortcutDialog *dialog);
+
+G_END_DECLS;
+
+#endif /* !__SHORTCUT_DIALOG_H__ */



More information about the Xfce4-commits mailing list