Added a patch that sync with upstream snapshot
authorAndrew Lee (李健秋) <ajqlee@debian.org>
Sat, 7 Aug 2010 18:54:07 +0000 (14:54 -0400)
committerAndrew Lee (李健秋) <ajqlee@debian.org>
Sat, 7 Aug 2010 18:54:07 +0000 (14:54 -0400)
debian/patches/lxappearance-0.4.0+git20100807.patch [new file with mode: 0644]
debian/patches/series

diff --git a/debian/patches/lxappearance-0.4.0+git20100807.patch b/debian/patches/lxappearance-0.4.0+git20100807.patch
new file mode 100644 (file)
index 0000000..b9d6b6e
--- /dev/null
@@ -0,0 +1,4989 @@
+diff --git a/Makefile.am b/Makefile.am
+index ca014cc..01adef9 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -1,36 +1,7 @@
+ NULL=
+-SUBDIRS = src po man
+-
+-ui_in_files= \
+-      data/lxappearance.glade \
+-      data/demo.glade \
+-      $(NULL)
+-uidir=$(datadir)/lxappearance
+-ui_DATA = $(ui_in_files:.glade=.ui)
+-
+-%.ui: %.glade
+-      cp $< $@
+-
+-support_scriptdir=$(datadir)/lxappearance
+-support_script_DATA= \
+-        scripts/install-icon-theme.sh \
+-        $(NULL)
+-
+-desktopdir=$(datadir)/applications
+-desktop_in_files=lxappearance.desktop.in
+-desktop_DATA = $(desktop_in_files:.desktop.in=.desktop)
+-@INTLTOOL_DESKTOP_RULE@
+-
+-install-data-hook:
+-      for script in $(DESTDIR)$(support_scriptdir)/*.sh; do \
+-          chmod +x $$script; \
+-      done
++SUBDIRS=src po data
+ EXTRA_DIST = \
+-      autogen.sh \
+-      $(ui_DATA) \
+-      $(support_script_DATA) \
+-      $(desktop_DATA) \
+       $(NULL)
+diff --git a/autogen.sh b/autogen.sh
+index 869cae8..aaaed56 100755
+--- a/autogen.sh
++++ b/autogen.sh
+@@ -7,7 +7,7 @@ AM_INSTALLED_VERSION=$($AUTOMAKE --version | sed -e '2,$ d' -e 's/.* \([0-9]*\.[
+ if [ "$AM_INSTALLED_VERSION" != "1.10" \
+     -a "$AM_INSTALLED_VERSION" != "1.11" ];then
+       echo
+-      echo "You must have automake > 1.10 or 1.11 installed to compile lxappearance."
++      echo "You must have automake > 1.10 or 1.11 installed to compile this program."
+       echo "Install the appropriate package for your distribution,"
+       echo "or get the source tarball at http://ftp.gnu.org/gnu/automake/"
+       exit 1
+diff --git a/configure.ac b/configure.ac
+new file mode 100644
+index 0000000..a80dbe5
+--- /dev/null
++++ b/configure.ac
+@@ -0,0 +1,114 @@
++#                                               -*- Autoconf -*-
++# Process this file with autoconf to produce a configure script.
++
++prog_name = lxappearance
++
++AC_PREREQ([2.63])
++AC_INIT([lxappearance], [0.5.0], [http://lxde.org/])
++AM_INIT_AUTOMAKE([-Wall -Werror foreign])
++
++AC_CONFIG_HEADERS([config.h])
++
++# Checks for programs.
++AC_PROG_CC
++# AM_PROG_LIBTOOL
++
++# Checks for libraries.
++
++# Checks for header files.
++AC_HEADER_STDC
++
++# Checks for typedefs, structures, and compiler characteristics.
++
++# Checks for library functions.
++
++# intltool
++IT_PROG_INTLTOOL([0.40.0])
++
++PKG_CHECK_MODULES(XLIB, "x11")
++AC_SUBST(XLIB_CFLAGS)
++AC_SUBST(XLIB_LIBS)
++
++gtk_modules="gtk+-2.0 >= 2.12.0 gthread-2.0"
++PKG_CHECK_MODULES(GTK, [$gtk_modules])
++AC_SUBST(GTK_CFLAGS)
++AC_SUBST(GTK_LIBS)
++
++gmodule_modules="gmodule-export-2.0"
++PKG_CHECK_MODULES(GMODULE, [$gmodule_modules])
++AC_SUBST(GMODULE_CFLAGS)
++AC_SUBST(GMODULE_LIBS)
++
++# gio_modules="gthread-2.0 gio-unix-2.0 glib-2.0 >= 2.18.0"
++# PKG_CHECK_MODULES(GIO, [$gio_modules])
++# AC_SUBST(GIO_CFLAGS)
++# AC_SUBST(GIO_LIBS)
++
++# menu_modules="libmenu-cache >= 0.3.2"
++# PKG_CHECK_MODULES(MENU_CACHE, [$menu_modules])
++# AC_SUBST(MENU_CACHE_CFLAGS)
++# AC_SUBST(MENU_CACHE_LIBS)
++
++AC_ARG_ENABLE(debug,
++    [AC_HELP_STRING([--enable-debug],
++        [build libfm with debug support @<:@default=no@:>@])],
++    [enable_debug="${enableval}"],
++    [enable_debug=no]
++)
++if test "$enable_debug" = "yes"; then
++    # turn on debug and disable optimization
++    CPPFLAGS="$CPPFLAGS -DG_ENABLE_DEBUG -O0 -g"
++else
++    # turn off glib debug checks
++    CPPFLAGS="$CPPFLAGS -DG_DISABLE_ASSERT -DG_DISABLE_CHECKS -DG_DISABLE_CAST_CHECKS"
++fi
++
++# Generate po/LINGUAS on the fly rather than relying on translators
++# to maintain it manually. This also overcome the problem that Transifex
++# cannot add a language to po/LINGUAS if a new po file is submitted.
++rm -f $srcdir/po/LINGUAS
++for po_file in `ls $srcdir/po/*.po | sort`;
++do
++    lang=`echo "$po_file" | sed "s|.*/po/\(.*\)\.po|\1|g"`
++    echo $lang >> $srcdir/po/LINGUAS
++done
++
++GETTEXT_PACKAGE=lxappearance
++AC_SUBST(GETTEXT_PACKAGE)
++AM_GLIB_GNU_GETTEXT
++AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GETTEXT_PACKAGE", [Gettext package.])
++
++AC_CONFIG_FILES([
++    Makefile
++    src/Makefile
++    data/Makefile
++    data/ui/Makefile
++    data/ui/about.glade
++    data/lxappearance.pc
++    po/Makefile.in
++])
++
++AC_OUTPUT
++
++if test x"$sysconfdir" != x'/etc'; then
++    echo
++    echo
++    echo 'Error: sysconfdir is not /etc.'
++    echo 'Please consider passing --sysconfdir=/etc to configure.';
++    echo 'Otherwise default config files will be installed to wrong place.'
++    echo
++    echo
++else
++    echo
++    echo lxappearance....................... : Version $VERSION
++    echo
++    echo Enable debug....................: "$enable_debug"
++    echo Prefix..........................: $prefix
++    echo
++    echo The binary will be installed in $prefix/bin
++    echo
++    echo http://lxde.org/
++    echo
++    echo "Ready to make lxappearance. Type 'make' to continue."
++    echo
++fi
+diff --git a/data/Makefile.am b/data/Makefile.am
+new file mode 100644
+index 0000000..06ccfdd
+--- /dev/null
++++ b/data/Makefile.am
+@@ -0,0 +1,19 @@
++NULL=
++
++SUBDIRS= \
++      ui \
++      $(NULL)
++
++pkgconfigdir   = $(libdir)/pkgconfig
++pkgconfig_DATA = lxappearance.pc
++
++desktopdir=$(datadir)/applications
++desktop_in_files = \
++      lxappearance.desktop.in \
++      $(NULL)
++desktop_DATA = $(desktop_in_files:.desktop.in=.desktop)
++@INTLTOOL_DESKTOP_RULE@
++
++EXTRA_DIST= \
++      $(desktop_DATA) \
++      $(NULL)
+diff --git a/data/lxappearance.desktop.in b/data/lxappearance.desktop.in
+new file mode 100644
+index 0000000..39f22bf
+--- /dev/null
++++ b/data/lxappearance.desktop.in
+@@ -0,0 +1,9 @@
++[Desktop Entry]
++Type=Application
++_Name=Customize Look and Feel
++_GenericName=Customize Look and Feel
++_Comment=Customizes look and feel of your desktop and applications
++Icon=preferences-desktop-theme
++Exec=lxappearance
++StartupNotify=true
++Categories=Settings;DesktopSettings;GTK;X-LXDE-Settings;
+diff --git a/data/lxappearance.pc.in b/data/lxappearance.pc.in
+new file mode 100644
+index 0000000..9abd35e
+--- /dev/null
++++ b/data/lxappearance.pc.in
+@@ -0,0 +1,10 @@
++prefix=@prefix@
++exec_prefix=@exec_prefix@
++libdir=@libdir@
++includedir=@includedir@
++datadir=@datadir@
++
++Name: lxappearance
++Description: Tool used to customize look and feel of gtk+ applications.
++Requires: gtk+-2.0 >= 2.12
++Version: @VERSION@
+diff --git a/data/ui/Makefile.am b/data/ui/Makefile.am
+new file mode 100644
+index 0000000..f14c11f
+--- /dev/null
++++ b/data/ui/Makefile.am
+@@ -0,0 +1,22 @@
++NULL=
++
++# GtkBuilder UI definition files
++uidir=$(datadir)/lxappearance/ui
++ui_in_files= \
++      about.glade \
++      lxappearance.glade \
++      $(NULL)
++ui_DATA = $(ui_in_files:.glade=.ui)
++
++CLEANFILES = \
++      $(ui_DATA) \
++      $(NULL)
++
++# Purge GtkBuilder UI files
++%.ui: %.glade
++      cp $< $@
++      $(top_srcdir)/src/xml-purge $@
++
++EXTRA_DIST= \
++      $(ui_DATA) \
++      $(NULL)
+diff --git a/data/ui/about.glade.in b/data/ui/about.glade.in
+new file mode 100644
+index 0000000..0227724
+--- /dev/null
++++ b/data/ui/about.glade.in
+@@ -0,0 +1,52 @@
++<?xml version="1.0"?>
++<interface>
++  <!-- interface-requires gtk+ 2.12 -->
++  <!-- interface-naming-policy toplevel-contextual -->
++  <object class="GtkAboutDialog" id="dlg">
++    <property name="border_width">5</property>
++    <property name="window_position">center-on-parent</property>
++    <property name="type_hint">dialog</property>
++    <property name="has_separator">False</property>
++    <property name="program_name">LXAppearance</property>
++    <property name="version">@VERSION@</property>
++    <property name="copyright" translatable="yes">Copyright (C) 2010 LXDE Project</property>
++    <property name="comments" translatable="yes">Customizes look and feel of your desktop</property>
++    <property name="website">http://lxde.org/</property>
++    <property name="license">Copyright (C) 2010 LXDE Team
++
++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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.</property>
++    <property name="authors">&#x6D2A;&#x4EFB;&#x8AED; Hong Jen Yee (PCMan) &lt;pcman.tw@gmail.com&gt;</property>
++    <property name="translator_credits" translatable="yes" comments="Please replace this line with your own names, one name per line. ">translator-credits</property>
++    <property name="artists"></property>
++    <property name="wrap_license">True</property>
++    <child internal-child="vbox">
++      <object class="GtkVBox" id="dialog-vbox1">
++        <property name="visible">True</property>
++        <property name="spacing">2</property>
++        <child internal-child="action_area">
++          <object class="GtkHButtonBox" id="dialog-action_area1">
++            <property name="visible">True</property>
++            <property name="layout_style">end</property>
++          </object>
++          <packing>
++            <property name="expand">False</property>
++            <property name="pack_type">end</property>
++            <property name="position">0</property>
++          </packing>
++        </child>
++      </object>
++    </child>
++  </object>
++</interface>
+diff --git a/data/ui/lxappearance.glade b/data/ui/lxappearance.glade
+new file mode 100644
+index 0000000..b65bb40
+--- /dev/null
++++ b/data/ui/lxappearance.glade
+@@ -0,0 +1,1588 @@
++<?xml version="1.0"?>
++<interface>
++  <requires lib="gtk+" version="2.16"/>
++  <!-- interface-naming-policy project-wide -->
++  <object class="GtkAdjustment" id="cursor_size_adj">
++    <property name="lower">1</property>
++    <property name="upper">138</property>
++    <property name="step_increment">1</property>
++    <property name="page_increment">10</property>
++    <property name="page_size">10</property>
++  </object>
++  <object class="GtkListStore" id="icon_demo_store">
++    <columns>
++      <!-- column-name icon-name -->
++      <column type="gchararray"/>
++    </columns>
++    <data>
++      <row>
++        <col id="0">user-home</col>
++      </row>
++      <row>
++        <col id="0">user-desktop</col>
++      </row>
++      <row>
++        <col id="0">folder</col>
++      </row>
++      <row>
++        <col id="0">folder-remote</col>
++      </row>
++      <row>
++        <col id="0">user-trash</col>
++      </row>
++      <row>
++        <col id="0">x-office-document</col>
++      </row>
++      <row>
++        <col id="0">application-x-executable</col>
++      </row>
++      <row>
++        <col id="0">image-x-generic</col>
++      </row>
++      <row>
++        <col id="0">text-x-generic</col>
++      </row>
++      <row>
++        <col id="0">text-html</col>
++      </row>
++    </data>
++  </object>
++  <object class="GtkListStore" id="tb_style_store">
++    <columns>
++      <!-- column-name item -->
++      <column type="gchararray"/>
++    </columns>
++    <data>
++      <row>
++        <col id="0" translatable="yes">Icons only</col>
++      </row>
++      <row>
++        <col id="0" translatable="yes">Text only</col>
++      </row>
++      <row>
++        <col id="0" translatable="yes">Text below icons</col>
++      </row>
++      <row>
++        <col id="0" translatable="yes">Text beside icons</col>
++      </row>
++    </data>
++  </object>
++  <object class="GtkListStore" id="tb_icon_size_store">
++    <columns>
++      <!-- column-name name -->
++      <column type="gchararray"/>
++    </columns>
++    <data>
++      <row>
++        <col id="0" translatable="yes">Same as menu items</col>
++      </row>
++      <row>
++        <col id="0" translatable="yes">Small toolbar icon</col>
++      </row>
++      <row>
++        <col id="0" translatable="yes">Large toolbar icon</col>
++      </row>
++      <row>
++        <col id="0" translatable="yes">Same as buttons</col>
++      </row>
++      <row>
++        <col id="0" translatable="yes">Same as drag icons</col>
++      </row>
++      <row>
++        <col id="0" translatable="yes">Same as dialogs</col>
++      </row>
++    </data>
++  </object>
++  <object class="GtkDialog" id="dlg">
++    <property name="border_width">5</property>
++    <property name="title" translatable="yes">Customize Look and Feel</property>
++    <property name="default_width">540</property>
++    <property name="icon_name">preferences-desktop-theme</property>
++    <property name="type_hint">normal</property>
++    <property name="has_separator">False</property>
++    <child internal-child="vbox">
++      <object class="GtkVBox" id="dialog-vbox1">
++        <property name="visible">True</property>
++        <property name="spacing">2</property>
++        <child>
++          <object class="GtkNotebook" id="notebook">
++            <property name="visible">True</property>
++            <property name="can_focus">True</property>
++            <child>
++              <object class="GtkHBox" id="hbox2">
++                <property name="visible">True</property>
++                <property name="border_width">12</property>
++                <property name="spacing">6</property>
++                <child>
++                  <object class="GtkScrolledWindow" id="scrolledwindow2">
++                    <property name="width_request">150</property>
++                    <property name="visible">True</property>
++                    <property name="can_focus">True</property>
++                    <property name="hscrollbar_policy">automatic</property>
++                    <property name="vscrollbar_policy">automatic</property>
++                    <property name="shadow_type">etched-in</property>
++                    <child>
++                      <object class="GtkTreeView" id="widget_theme_view">
++                        <property name="visible">True</property>
++                        <property name="can_focus">True</property>
++                        <property name="has_focus">True</property>
++                        <property name="headers_visible">False</property>
++                        <child>
++                          <object class="GtkTreeViewColumn" id="treeviewcolumn3">
++                            <child>
++                              <object class="GtkCellRendererText" id="cellrenderertext7"/>
++                              <attributes>
++                                <attribute name="text">0</attribute>
++                              </attributes>
++                            </child>
++                          </object>
++                        </child>
++                      </object>
++                    </child>
++                  </object>
++                  <packing>
++                    <property name="position">0</property>
++                  </packing>
++                </child>
++                <child>
++                  <object class="GtkVBox" id="vbox6">
++                    <property name="visible">True</property>
++                    <property name="spacing">6</property>
++                    <child>
++                      <object class="GtkLabel" id="label11">
++                        <property name="visible">True</property>
++                        <property name="xalign">0</property>
++                        <property name="label" translatable="yes">Preview of the selected widget style</property>
++                      </object>
++                      <packing>
++                        <property name="expand">False</property>
++                        <property name="position">0</property>
++                      </packing>
++                    </child>
++                    <child>
++                      <object class="GtkFrame" id="frame1">
++                        <property name="visible">True</property>
++                        <property name="label_xalign">0</property>
++                        <child>
++                          <object class="GtkEventBox" id="demo">
++                            <property name="visible">True</property>
++                            <child>
++                              <object class="GtkEventBox" id="eventbox1">
++                                <property name="visible">True</property>
++                                <property name="border_width">10</property>
++                                <child>
++                                  <object class="GtkVBox" id="demo_vbox">
++                                    <property name="visible">True</property>
++                                    <property name="border_width">2</property>
++                                    <child>
++                                      <object class="GtkMenuBar" id="menubar1">
++                                        <property name="visible">True</property>
++                                        <child>
++                                          <object class="GtkMenuItem" id="menuitem1">
++                                            <property name="visible">True</property>
++                                            <property name="label" translatable="yes">_File</property>
++                                            <property name="use_underline">True</property>
++                                            <child type="submenu">
++                                              <object class="GtkMenu" id="menuitem1_menu">
++                                                <child>
++                                                  <object class="GtkImageMenuItem" id="new1">
++                                                    <property name="label">gtk-new</property>
++                                                    <property name="visible">True</property>
++                                                    <property name="use_underline">True</property>
++                                                    <property name="use_stock">True</property>
++                                                  </object>
++                                                </child>
++                                                <child>
++                                                  <object class="GtkImageMenuItem" id="open1">
++                                                    <property name="label">gtk-open</property>
++                                                    <property name="visible">True</property>
++                                                    <property name="use_underline">True</property>
++                                                    <property name="use_stock">True</property>
++                                                  </object>
++                                                </child>
++                                                <child>
++                                                  <object class="GtkImageMenuItem" id="save1">
++                                                    <property name="label">gtk-save</property>
++                                                    <property name="visible">True</property>
++                                                    <property name="use_underline">True</property>
++                                                    <property name="use_stock">True</property>
++                                                  </object>
++                                                </child>
++                                                <child>
++                                                  <object class="GtkImageMenuItem" id="save_as1">
++                                                    <property name="label">gtk-save-as</property>
++                                                    <property name="visible">True</property>
++                                                    <property name="use_underline">True</property>
++                                                    <property name="use_stock">True</property>
++                                                  </object>
++                                                </child>
++                                                <child>
++                                                  <object class="GtkSeparatorMenuItem" id="separatormenuitem1">
++                                                    <property name="visible">True</property>
++                                                  </object>
++                                                </child>
++                                                <child>
++                                                  <object class="GtkImageMenuItem" id="quit1">
++                                                    <property name="label">gtk-quit</property>
++                                                    <property name="visible">True</property>
++                                                    <property name="use_underline">True</property>
++                                                    <property name="use_stock">True</property>
++                                                  </object>
++                                                </child>
++                                              </object>
++                                            </child>
++                                          </object>
++                                        </child>
++                                        <child>
++                                          <object class="GtkMenuItem" id="menuitem2">
++                                            <property name="visible">True</property>
++                                            <property name="label" translatable="yes">_Edit</property>
++                                            <property name="use_underline">True</property>
++                                            <child type="submenu">
++                                              <object class="GtkMenu" id="menuitem2_menu">
++                                                <child>
++                                                  <object class="GtkImageMenuItem" id="cut1">
++                                                    <property name="label">gtk-cut</property>
++                                                    <property name="visible">True</property>
++                                                    <property name="use_underline">True</property>
++                                                    <property name="use_stock">True</property>
++                                                  </object>
++                                                </child>
++                                                <child>
++                                                  <object class="GtkImageMenuItem" id="copy1">
++                                                    <property name="label">gtk-copy</property>
++                                                    <property name="visible">True</property>
++                                                    <property name="use_underline">True</property>
++                                                    <property name="use_stock">True</property>
++                                                  </object>
++                                                </child>
++                                                <child>
++                                                  <object class="GtkImageMenuItem" id="paste1">
++                                                    <property name="label">gtk-paste</property>
++                                                    <property name="visible">True</property>
++                                                    <property name="use_underline">True</property>
++                                                    <property name="use_stock">True</property>
++                                                  </object>
++                                                </child>
++                                                <child>
++                                                  <object class="GtkImageMenuItem" id="delete1">
++                                                    <property name="label">gtk-delete</property>
++                                                    <property name="visible">True</property>
++                                                    <property name="use_underline">True</property>
++                                                    <property name="use_stock">True</property>
++                                                  </object>
++                                                </child>
++                                              </object>
++                                            </child>
++                                          </object>
++                                        </child>
++                                        <child>
++                                          <object class="GtkMenuItem" id="menuitem4">
++                                            <property name="visible">True</property>
++                                            <property name="label" translatable="yes">_Help</property>
++                                            <property name="use_underline">True</property>
++                                            <child type="submenu">
++                                              <object class="GtkMenu" id="menuitem4_menu">
++                                                <child>
++                                                  <object class="GtkImageMenuItem" id="about1">
++                                                    <property name="label">gtk-about</property>
++                                                    <property name="visible">True</property>
++                                                    <property name="use_underline">True</property>
++                                                    <property name="use_stock">True</property>
++                                                  </object>
++                                                </child>
++                                              </object>
++                                            </child>
++                                          </object>
++                                        </child>
++                                      </object>
++                                      <packing>
++                                        <property name="expand">False</property>
++                                        <property name="fill">False</property>
++                                        <property name="position">0</property>
++                                      </packing>
++                                    </child>
++                                    <child>
++                                      <object class="GtkHandleBox" id="handlebox1">
++                                        <property name="visible">True</property>
++                                        <child>
++                                          <object class="GtkToolbar" id="toolbar">
++                                            <property name="visible">True</property>
++                                            <property name="toolbar_style">icons</property>
++                                            <property name="show_arrow">False</property>
++                                            <child>
++                                              <object class="GtkToolButton" id="toolbutton1">
++                                                <property name="visible">True</property>
++                                                <property name="is_important">True</property>
++                                                <property name="stock_id">gtk-go-back</property>
++                                              </object>
++                                              <packing>
++                                                <property name="expand">False</property>
++                                                <property name="homogeneous">True</property>
++                                              </packing>
++                                            </child>
++                                            <child>
++                                              <object class="GtkToolButton" id="toolbutton2">
++                                                <property name="visible">True</property>
++                                                <property name="stock_id">gtk-go-forward</property>
++                                              </object>
++                                              <packing>
++                                                <property name="expand">False</property>
++                                                <property name="homogeneous">True</property>
++                                              </packing>
++                                            </child>
++                                            <child>
++                                              <object class="GtkToolButton" id="toolbutton3">
++                                                <property name="visible">True</property>
++                                                <property name="is_important">True</property>
++                                                <property name="stock_id">gtk-stop</property>
++                                              </object>
++                                              <packing>
++                                                <property name="expand">False</property>
++                                                <property name="homogeneous">True</property>
++                                              </packing>
++                                            </child>
++                                            <child>
++                                              <object class="GtkToolItem" id="toolbutton4">
++                                                <property name="visible">True</property>
++                                                <child>
++                                                  <object class="GtkEntry" id="entry1">
++                                                    <property name="visible">True</property>
++                                                    <property name="can_focus">True</property>
++                                                    <property name="invisible_char">&#x25CF;</property>
++                                                  </object>
++                                                </child>
++                                              </object>
++                                              <packing>
++                                                <property name="expand">True</property>
++                                                <property name="homogeneous">True</property>
++                                              </packing>
++                                            </child>
++                                          </object>
++                                        </child>
++                                      </object>
++                                      <packing>
++                                        <property name="expand">False</property>
++                                        <property name="fill">False</property>
++                                        <property name="position">1</property>
++                                      </packing>
++                                    </child>
++                                    <child>
++                                      <object class="GtkNotebook" id="notebook2">
++                                        <property name="visible">True</property>
++                                        <property name="can_focus">True</property>
++                                        <property name="border_width">5</property>
++                                        <child>
++                                          <object class="GtkHBox" id="hbox3">
++                                            <property name="visible">True</property>
++                                            <child>
++                                              <object class="GtkFrame" id="frame2">
++                                                <property name="visible">True</property>
++                                                <property name="border_width">4</property>
++                                                <property name="label_xalign">0</property>
++                                                <child>
++                                                  <object class="GtkAlignment" id="alignment2">
++                                                    <property name="visible">True</property>
++                                                    <property name="bottom_padding">4</property>
++                                                    <property name="left_padding">4</property>
++                                                    <child>
++                                                      <object class="GtkVBox" id="vbox7">
++                                                        <property name="visible">True</property>
++                                                        <property name="spacing">4</property>
++                                                        <child>
++                                                          <object class="GtkRadioButton" id="radiobutton1">
++                                                            <property name="label" translatable="yes">Radio Button</property>
++                                                            <property name="visible">True</property>
++                                                            <property name="can_focus">True</property>
++                                                            <property name="receives_default">False</property>
++                                                            <property name="use_underline">True</property>
++                                                            <property name="draw_indicator">True</property>
++                                                          </object>
++                                                          <packing>
++                                                            <property name="expand">False</property>
++                                                            <property name="fill">False</property>
++                                                            <property name="position">0</property>
++                                                          </packing>
++                                                        </child>
++                                                        <child>
++                                                          <object class="GtkCheckButton" id="checkbutton1">
++                                                            <property name="label" translatable="yes">Check Button</property>
++                                                            <property name="visible">True</property>
++                                                            <property name="can_focus">True</property>
++                                                            <property name="receives_default">False</property>
++                                                            <property name="use_underline">True</property>
++                                                            <property name="draw_indicator">True</property>
++                                                          </object>
++                                                          <packing>
++                                                            <property name="expand">False</property>
++                                                            <property name="fill">False</property>
++                                                            <property name="position">1</property>
++                                                          </packing>
++                                                        </child>
++                                                        <child>
++                                                          <object class="GtkHBox" id="hbox4">
++                                                            <property name="visible">True</property>
++                                                            <child>
++                                                            <object class="GtkSpinButton" id="spinbutton1">
++                                                            <property name="visible">True</property>
++                                                            <property name="can_focus">True</property>
++                                                            <property name="invisible_char">&#x25CF;</property>
++                                                            <property name="climb_rate">1</property>
++                                                            </object>
++                                                            <packing>
++                                                            <property name="position">0</property>
++                                                            </packing>
++                                                            </child>
++                                                            <child>
++                                                            <object class="GtkButton" id="button1">
++                                                            <property name="visible">True</property>
++                                                            <property name="can_focus">True</property>
++                                                            <property name="receives_default">True</property>
++                                                            <child>
++                                                            <object class="GtkAlignment" id="alignment3">
++                                                            <property name="visible">True</property>
++                                                            <property name="xscale">0</property>
++                                                            <property name="yscale">0</property>
++                                                            <child>
++                                                            <object class="GtkHBox" id="hbox6">
++                                                            <property name="visible">True</property>
++                                                            <property name="spacing">2</property>
++                                                            <child>
++                                                            <object class="GtkImage" id="image1">
++                                                            <property name="visible">True</property>
++                                                            <property name="stock">gtk-find</property>
++                                                            </object>
++                                                            <packing>
++                                                            <property name="expand">False</property>
++                                                            <property name="fill">False</property>
++                                                            <property name="position">0</property>
++                                                            </packing>
++                                                            </child>
++                                                            <child>
++                                                            <object class="GtkLabel" id="label18">
++                                                            <property name="visible">True</property>
++                                                            <property name="label" translatable="yes">button</property>
++                                                            <property name="use_underline">True</property>
++                                                            </object>
++                                                            <packing>
++                                                            <property name="expand">False</property>
++                                                            <property name="fill">False</property>
++                                                            <property name="position">1</property>
++                                                            </packing>
++                                                            </child>
++                                                            </object>
++                                                            </child>
++                                                            </object>
++                                                            </child>
++                                                            </object>
++                                                            <packing>
++                                                            <property name="expand">False</property>
++                                                            <property name="fill">False</property>
++                                                            <property name="position">1</property>
++                                                            </packing>
++                                                            </child>
++                                                          </object>
++                                                          <packing>
++                                                            <property name="expand">False</property>
++                                                            <property name="position">2</property>
++                                                          </packing>
++                                                        </child>
++                                                      </object>
++                                                    </child>
++                                                  </object>
++                                                </child>
++                                                <child type="label">
++                                                  <object class="GtkLabel" id="label16">
++                                                    <property name="visible">True</property>
++                                                    <property name="label" translatable="yes">Demo</property>
++                                                    <property name="use_markup">True</property>
++                                                  </object>
++                                                </child>
++                                              </object>
++                                              <packing>
++                                                <property name="position">0</property>
++                                              </packing>
++                                            </child>
++                                            <child>
++                                              <object class="GtkVBox" id="vbox9">
++                                                <property name="visible">True</property>
++                                                <property name="border_width">4</property>
++                                                <child>
++                                                  <object class="GtkProgressBar" id="progressbar1">
++                                                    <property name="visible">True</property>
++                                                    <property name="show_text">True</property>
++                                                    <property name="fraction">0.60000002384200002</property>
++                                                    <property name="pulse_step">0.10000000149</property>
++                                                    <property name="text">60 %</property>
++                                                  </object>
++                                                  <packing>
++                                                    <property name="expand">False</property>
++                                                    <property name="fill">False</property>
++                                                    <property name="position">0</property>
++                                                  </packing>
++                                                </child>
++                                                <child>
++                                                  <object class="GtkHScale" id="hscale1">
++                                                    <property name="visible">True</property>
++                                                    <property name="can_focus">True</property>
++                                                  </object>
++                                                  <packing>
++                                                    <property name="expand">False</property>
++                                                    <property name="position">1</property>
++                                                  </packing>
++                                                </child>
++                                                <child>
++                                                  <object class="GtkComboBox" id="combobox2">
++                                                    <property name="visible">True</property>
++                                                    <child>
++                                                      <object class="GtkCellRendererText" id="cellrenderertext1"/>
++                                                      <attributes>
++                                                        <attribute name="text">0</attribute>
++                                                      </attributes>
++                                                    </child>
++                                                  </object>
++                                                  <packing>
++                                                    <property name="expand">False</property>
++                                                    <property name="position">2</property>
++                                                  </packing>
++                                                </child>
++                                              </object>
++                                              <packing>
++                                                <property name="position">1</property>
++                                              </packing>
++                                            </child>
++                                          </object>
++                                        </child>
++                                        <child type="tab">
++                                          <object class="GtkLabel" id="label13">
++                                            <property name="visible">True</property>
++                                            <property name="label" translatable="yes">Page1</property>
++                                          </object>
++                                          <packing>
++                                            <property name="tab_fill">False</property>
++                                          </packing>
++                                        </child>
++                                        <child>
++                                          <object class="GtkScrolledWindow" id="scrolledwindow6">
++                                            <property name="visible">True</property>
++                                            <property name="can_focus">True</property>
++                                            <property name="hscrollbar_policy">never</property>
++                                            <property name="shadow_type">in</property>
++                                            <child>
++                                              <object class="GtkTreeView" id="demo_treeview">
++                                                <property name="visible">True</property>
++                                                <property name="can_focus">True</property>
++                                                <property name="model">icon_demo_store</property>
++                                                <property name="headers_clickable">False</property>
++                                                <property name="rules_hint">True</property>
++                                                <child>
++                                                  <object class="GtkTreeViewColumn" id="treeviewcolumn1">
++                                                    <property name="title">column</property>
++                                                    <child>
++                                                      <object class="GtkCellRendererPixbuf" id="cellrendererpixbuf1"/>
++                                                      <attributes>
++                                                        <attribute name="icon-name">0</attribute>
++                                                      </attributes>
++                                                    </child>
++                                                  </object>
++                                                </child>
++                                                <child>
++                                                  <object class="GtkTreeViewColumn" id="treeviewcolumn2">
++                                                    <property name="title">column</property>
++                                                    <child>
++                                                      <object class="GtkCellRendererText" id="cellrenderertext6"/>
++                                                      <attributes>
++                                                        <attribute name="text">0</attribute>
++                                                      </attributes>
++                                                    </child>
++                                                  </object>
++                                                </child>
++                                              </object>
++                                            </child>
++                                          </object>
++                                          <packing>
++                                            <property name="position">1</property>
++                                          </packing>
++                                        </child>
++                                        <child type="tab">
++                                          <object class="GtkLabel" id="label14">
++                                            <property name="visible">True</property>
++                                            <property name="label" translatable="yes">Page2</property>
++                                          </object>
++                                          <packing>
++                                            <property name="position">1</property>
++                                            <property name="tab_fill">False</property>
++                                          </packing>
++                                        </child>
++                                      </object>
++                                      <packing>
++                                        <property name="position">2</property>
++                                      </packing>
++                                    </child>
++                                    <child>
++                                      <object class="GtkStatusbar" id="statusbar1">
++                                        <property name="visible">True</property>
++                                        <property name="spacing">2</property>
++                                      </object>
++                                      <packing>
++                                        <property name="expand">False</property>
++                                        <property name="fill">False</property>
++                                        <property name="position">3</property>
++                                      </packing>
++                                    </child>
++                                  </object>
++                                </child>
++                              </object>
++                            </child>
++                          </object>
++                        </child>
++                        <child type="label_item">
++                          <placeholder/>
++                        </child>
++                      </object>
++                      <packing>
++                        <property name="expand">False</property>
++                        <property name="position">1</property>
++                      </packing>
++                    </child>
++                    <child>
++                      <object class="GtkHBox" id="hbox8">
++                        <property name="visible">True</property>
++                        <property name="spacing">12</property>
++                        <child>
++                          <object class="GtkLabel" id="label12">
++                            <property name="visible">True</property>
++                            <property name="xalign">0</property>
++                            <property name="label" translatable="yes">Default font:</property>
++                          </object>
++                          <packing>
++                            <property name="expand">False</property>
++                            <property name="position">0</property>
++                          </packing>
++                        </child>
++                        <child>
++                          <object class="GtkFontButton" id="default_font">
++                            <property name="visible">True</property>
++                            <property name="can_focus">True</property>
++                            <property name="receives_default">True</property>
++                          </object>
++                          <packing>
++                            <property name="position">1</property>
++                          </packing>
++                        </child>
++                      </object>
++                      <packing>
++                        <property name="expand">False</property>
++                        <property name="position">2</property>
++                      </packing>
++                    </child>
++                  </object>
++                  <packing>
++                    <property name="position">1</property>
++                  </packing>
++                </child>
++              </object>
++            </child>
++            <child type="tab">
++              <object class="GtkLabel" id="label1">
++                <property name="visible">True</property>
++                <property name="label" translatable="yes">Widget</property>
++              </object>
++              <packing>
++                <property name="tab_fill">False</property>
++              </packing>
++            </child>
++            <child>
++              <object class="GtkVBox" id="color_page">
++                <property name="visible">True</property>
++                <property name="border_width">12</property>
++                <property name="spacing">6</property>
++                <child>
++                  <object class="GtkLabel" id="no_custom_colors">
++                    <property name="xalign">0</property>
++                    <property name="label" translatable="yes">Color scheme is not supported by currently selected widget theme.</property>
++                  </object>
++                  <packing>
++                    <property name="expand">False</property>
++                    <property name="position">0</property>
++                  </packing>
++                </child>
++                <child>
++                  <object class="GtkCheckButton" id="custom_colors">
++                    <property name="label" translatable="yes">Use customized color scheme</property>
++                    <property name="visible">True</property>
++                    <property name="can_focus">True</property>
++                    <property name="receives_default">False</property>
++                    <property name="draw_indicator">True</property>
++                  </object>
++                  <packing>
++                    <property name="expand">False</property>
++                    <property name="position">1</property>
++                  </packing>
++                </child>
++                <child>
++                  <object class="GtkTable" id="color_table">
++                    <property name="visible">True</property>
++                    <property name="n_rows">5</property>
++                    <property name="n_columns">3</property>
++                    <property name="column_spacing">12</property>
++                    <property name="row_spacing">6</property>
++                    <child>
++                      <object class="GtkLabel" id="label3">
++                        <property name="visible">True</property>
++                        <property name="xalign">0</property>
++                        <property name="label" translatable="yes">Normal windows:</property>
++                      </object>
++                      <packing>
++                        <property name="top_attach">1</property>
++                        <property name="bottom_attach">2</property>
++                        <property name="x_options">GTK_FILL</property>
++                        <property name="y_options">GTK_FILL</property>
++                      </packing>
++                    </child>
++                    <child>
++                      <object class="GtkLabel" id="label8">
++                        <property name="visible">True</property>
++                        <property name="xalign">0</property>
++                        <property name="label" translatable="yes">Text windows:</property>
++                      </object>
++                      <packing>
++                        <property name="top_attach">2</property>
++                        <property name="bottom_attach">3</property>
++                        <property name="x_options">GTK_FILL</property>
++                        <property name="y_options">GTK_FILL</property>
++                      </packing>
++                    </child>
++                    <child>
++                      <object class="GtkLabel" id="label15">
++                        <property name="visible">True</property>
++                        <property name="xalign">0</property>
++                        <property name="label" translatable="yes">Selected items:</property>
++                      </object>
++                      <packing>
++                        <property name="top_attach">3</property>
++                        <property name="bottom_attach">4</property>
++                        <property name="x_options">GTK_FILL</property>
++                        <property name="y_options">GTK_FILL</property>
++                      </packing>
++                    </child>
++                    <child>
++                      <object class="GtkLabel" id="label17">
++                        <property name="visible">True</property>
++                        <property name="xalign">0</property>
++                        <property name="label" translatable="yes">Tooltips:</property>
++                      </object>
++                      <packing>
++                        <property name="top_attach">4</property>
++                        <property name="bottom_attach">5</property>
++                        <property name="x_options">GTK_FILL</property>
++                        <property name="y_options">GTK_FILL</property>
++                      </packing>
++                    </child>
++                    <child>
++                      <object class="GtkLabel" id="label20">
++                        <property name="visible">True</property>
++                        <property name="label" translatable="yes">Background</property>
++                      </object>
++                      <packing>
++                        <property name="left_attach">1</property>
++                        <property name="right_attach">2</property>
++                        <property name="x_options">GTK_FILL</property>
++                        <property name="y_options">GTK_FILL</property>
++                      </packing>
++                    </child>
++                    <child>
++                      <object class="GtkLabel" id="label21">
++                        <property name="visible">True</property>
++                        <property name="label" translatable="yes">Foreground</property>
++                      </object>
++                      <packing>
++                        <property name="left_attach">2</property>
++                        <property name="right_attach">3</property>
++                        <property name="x_options">GTK_FILL</property>
++                        <property name="y_options">GTK_FILL</property>
++                      </packing>
++                    </child>
++                    <child>
++                      <object class="GtkColorButton" id="bg_color">
++                        <property name="visible">True</property>
++                        <property name="can_focus">True</property>
++                        <property name="receives_default">True</property>
++                        <property name="color">#000000000000</property>
++                      </object>
++                      <packing>
++                        <property name="left_attach">1</property>
++                        <property name="right_attach">2</property>
++                        <property name="top_attach">1</property>
++                        <property name="bottom_attach">2</property>
++                        <property name="y_options">GTK_FILL</property>
++                      </packing>
++                    </child>
++                    <child>
++                      <object class="GtkColorButton" id="fg_color">
++                        <property name="visible">True</property>
++                        <property name="can_focus">True</property>
++                        <property name="receives_default">True</property>
++                        <property name="color">#000000000000</property>
++                      </object>
++                      <packing>
++                        <property name="left_attach">2</property>
++                        <property name="right_attach">3</property>
++                        <property name="top_attach">1</property>
++                        <property name="bottom_attach">2</property>
++                        <property name="y_options">GTK_FILL</property>
++                      </packing>
++                    </child>
++                    <child>
++                      <object class="GtkColorButton" id="base_color">
++                        <property name="visible">True</property>
++                        <property name="can_focus">True</property>
++                        <property name="receives_default">True</property>
++                        <property name="color">#000000000000</property>
++                      </object>
++                      <packing>
++                        <property name="left_attach">1</property>
++                        <property name="right_attach">2</property>
++                        <property name="top_attach">2</property>
++                        <property name="bottom_attach">3</property>
++                        <property name="y_options">GTK_FILL</property>
++                      </packing>
++                    </child>
++                    <child>
++                      <object class="GtkColorButton" id="text_color">
++                        <property name="visible">True</property>
++                        <property name="can_focus">True</property>
++                        <property name="receives_default">True</property>
++                        <property name="color">#000000000000</property>
++                      </object>
++                      <packing>
++                        <property name="left_attach">2</property>
++                        <property name="right_attach">3</property>
++                        <property name="top_attach">2</property>
++                        <property name="bottom_attach">3</property>
++                        <property name="y_options">GTK_FILL</property>
++                      </packing>
++                    </child>
++                    <child>
++                      <object class="GtkColorButton" id="selected_bg_color">
++                        <property name="visible">True</property>
++                        <property name="can_focus">True</property>
++                        <property name="receives_default">True</property>
++                        <property name="color">#000000000000</property>
++                      </object>
++                      <packing>
++                        <property name="left_attach">1</property>
++                        <property name="right_attach">2</property>
++                        <property name="top_attach">3</property>
++                        <property name="bottom_attach">4</property>
++                        <property name="y_options">GTK_FILL</property>
++                      </packing>
++                    </child>
++                    <child>
++                      <object class="GtkColorButton" id="selected_fg_color">
++                        <property name="visible">True</property>
++                        <property name="can_focus">True</property>
++                        <property name="receives_default">True</property>
++                        <property name="color">#000000000000</property>
++                      </object>
++                      <packing>
++                        <property name="left_attach">2</property>
++                        <property name="right_attach">3</property>
++                        <property name="top_attach">3</property>
++                        <property name="bottom_attach">4</property>
++                        <property name="y_options">GTK_FILL</property>
++                      </packing>
++                    </child>
++                    <child>
++                      <object class="GtkColorButton" id="tooltip_bg_color">
++                        <property name="visible">True</property>
++                        <property name="can_focus">True</property>
++                        <property name="receives_default">True</property>
++                        <property name="color">#000000000000</property>
++                      </object>
++                      <packing>
++                        <property name="left_attach">1</property>
++                        <property name="right_attach">2</property>
++                        <property name="top_attach">4</property>
++                        <property name="bottom_attach">5</property>
++                        <property name="y_options">GTK_FILL</property>
++                      </packing>
++                    </child>
++                    <child>
++                      <object class="GtkColorButton" id="tooltip_fg_color">
++                        <property name="visible">True</property>
++                        <property name="can_focus">True</property>
++                        <property name="receives_default">True</property>
++                        <property name="color">#000000000000</property>
++                      </object>
++                      <packing>
++                        <property name="left_attach">2</property>
++                        <property name="right_attach">3</property>
++                        <property name="top_attach">4</property>
++                        <property name="bottom_attach">5</property>
++                        <property name="y_options">GTK_FILL</property>
++                      </packing>
++                    </child>
++                    <child>
++                      <placeholder/>
++                    </child>
++                  </object>
++                  <packing>
++                    <property name="expand">False</property>
++                    <property name="position">2</property>
++                  </packing>
++                </child>
++              </object>
++              <packing>
++                <property name="position">1</property>
++              </packing>
++            </child>
++            <child type="tab">
++              <object class="GtkLabel" id="label9">
++                <property name="visible">True</property>
++                <property name="label" translatable="yes">Color</property>
++              </object>
++              <packing>
++                <property name="position">1</property>
++                <property name="tab_fill">False</property>
++              </packing>
++            </child>
++            <child>
++              <object class="GtkHBox" id="hbox1">
++                <property name="visible">True</property>
++                <property name="border_width">12</property>
++                <property name="spacing">6</property>
++                <child>
++                  <object class="GtkVBox" id="vbox10">
++                    <property name="visible">True</property>
++                    <property name="spacing">6</property>
++                    <child>
++                      <object class="GtkScrolledWindow" id="scrolledwindow1">
++                        <property name="width_request">150</property>
++                        <property name="visible">True</property>
++                        <property name="can_focus">True</property>
++                        <property name="hscrollbar_policy">automatic</property>
++                        <property name="vscrollbar_policy">automatic</property>
++                        <property name="shadow_type">etched-in</property>
++                        <child>
++                          <object class="GtkTreeView" id="icon_theme_view">
++                            <property name="visible">True</property>
++                            <property name="can_focus">True</property>
++                            <property name="headers_visible">False</property>
++                            <child>
++                              <object class="GtkTreeViewColumn" id="treeviewcolumn4">
++                                <child>
++                                  <object class="GtkCellRendererText" id="cellrenderertext8"/>
++                                  <attributes>
++                                    <attribute name="text">0</attribute>
++                                  </attributes>
++                                </child>
++                              </object>
++                            </child>
++                          </object>
++                        </child>
++                      </object>
++                      <packing>
++                        <property name="position">0</property>
++                      </packing>
++                    </child>
++                    <child>
++                      <object class="GtkButton" id="install_icon_theme">
++                        <property name="label" translatable="yes">Install</property>
++                        <property name="visible">True</property>
++                        <property name="can_focus">True</property>
++                        <property name="receives_default">True</property>
++                        <property name="image">image2</property>
++                      </object>
++                      <packing>
++                        <property name="expand">False</property>
++                        <property name="position">1</property>
++                      </packing>
++                    </child>
++                    <child>
++                      <object class="GtkButton" id="remove_icon_theme">
++                        <property name="label" translatable="yes">Remove</property>
++                        <property name="visible">True</property>
++                        <property name="can_focus">True</property>
++                        <property name="receives_default">True</property>
++                        <property name="image">image3</property>
++                      </object>
++                      <packing>
++                        <property name="expand">False</property>
++                        <property name="position">2</property>
++                      </packing>
++                    </child>
++                  </object>
++                  <packing>
++                    <property name="position">0</property>
++                  </packing>
++                </child>
++                <child>
++                  <object class="GtkVBox" id="vbox2">
++                    <property name="visible">True</property>
++                    <property name="spacing">18</property>
++                    <child>
++                      <object class="GtkVBox" id="vbox4">
++                        <property name="visible">True</property>
++                        <child>
++                          <object class="GtkLabel" id="label6">
++                            <property name="visible">True</property>
++                            <property name="xalign">0</property>
++                            <property name="label" translatable="yes">Preview of the selected icon theme</property>
++                          </object>
++                          <packing>
++                            <property name="expand">False</property>
++                            <property name="position">0</property>
++                          </packing>
++                        </child>
++                        <child>
++                          <object class="GtkScrolledWindow" id="scrolledwindow3">
++                            <property name="visible">True</property>
++                            <property name="can_focus">True</property>
++                            <property name="hscrollbar_policy">automatic</property>
++                            <property name="vscrollbar_policy">automatic</property>
++                            <property name="shadow_type">etched-in</property>
++                            <child>
++                              <object class="GtkIconView" id="icon_demo_view">
++                                <property name="visible">True</property>
++                                <property name="can_focus">True</property>
++                                <property name="model">icon_demo_store</property>
++                                <child>
++                                  <object class="GtkCellRendererPixbuf" id="cellrenderertext3">
++                                    <property name="stock_size">6</property>
++                                  </object>
++                                  <attributes>
++                                    <attribute name="icon-name">0</attribute>
++                                  </attributes>
++                                </child>
++                              </object>
++                            </child>
++                          </object>
++                          <packing>
++                            <property name="position">1</property>
++                          </packing>
++                        </child>
++                      </object>
++                      <packing>
++                        <property name="position">0</property>
++                      </packing>
++                    </child>
++                  </object>
++                  <packing>
++                    <property name="position">1</property>
++                  </packing>
++                </child>
++              </object>
++              <packing>
++                <property name="position">2</property>
++              </packing>
++            </child>
++            <child type="tab">
++              <object class="GtkLabel" id="label2">
++                <property name="visible">True</property>
++                <property name="label" translatable="yes">Icon Theme</property>
++              </object>
++              <packing>
++                <property name="position">2</property>
++                <property name="tab_fill">False</property>
++              </packing>
++            </child>
++            <child>
++              <object class="GtkHBox" id="hbox7">
++                <property name="visible">True</property>
++                <property name="border_width">12</property>
++                <property name="spacing">6</property>
++                <child>
++                  <object class="GtkVBox" id="vbox3">
++                    <property name="visible">True</property>
++                    <property name="spacing">6</property>
++                    <child>
++                      <object class="GtkScrolledWindow" id="scrolledwindow4">
++                        <property name="width_request">150</property>
++                        <property name="visible">True</property>
++                        <property name="can_focus">True</property>
++                        <property name="hscrollbar_policy">automatic</property>
++                        <property name="vscrollbar_policy">automatic</property>
++                        <property name="shadow_type">etched-in</property>
++                        <child>
++                          <object class="GtkTreeView" id="cursor_theme_view">
++                            <property name="visible">True</property>
++                            <property name="can_focus">True</property>
++                            <property name="headers_visible">False</property>
++                            <child>
++                              <object class="GtkTreeViewColumn" id="treeviewcolumn5">
++                                <child>
++                                  <object class="GtkCellRendererText" id="cellrenderertext9"/>
++                                  <attributes>
++                                    <attribute name="text">0</attribute>
++                                  </attributes>
++                                </child>
++                              </object>
++                            </child>
++                          </object>
++                        </child>
++                      </object>
++                      <packing>
++                        <property name="position">0</property>
++                      </packing>
++                    </child>
++                    <child>
++                      <object class="GtkButton" id="install_cursor_theme">
++                        <property name="label" translatable="yes">Install</property>
++                        <property name="visible">True</property>
++                        <property name="can_focus">True</property>
++                        <property name="receives_default">True</property>
++                        <property name="image">image4</property>
++                      </object>
++                      <packing>
++                        <property name="expand">False</property>
++                        <property name="position">1</property>
++                      </packing>
++                    </child>
++                    <child>
++                      <object class="GtkButton" id="remove_cursor_theme">
++                        <property name="label" translatable="yes">Remove</property>
++                        <property name="visible">True</property>
++                        <property name="can_focus">True</property>
++                        <property name="receives_default">True</property>
++                        <property name="image">image5</property>
++                      </object>
++                      <packing>
++                        <property name="expand">False</property>
++                        <property name="position">2</property>
++                      </packing>
++                    </child>
++                  </object>
++                  <packing>
++                    <property name="position">0</property>
++                  </packing>
++                </child>
++                <child>
++                  <object class="GtkVBox" id="vbox11">
++                    <property name="visible">True</property>
++                    <property name="spacing">6</property>
++                    <child>
++                      <object class="GtkLabel" id="label7">
++                        <property name="visible">True</property>
++                        <property name="xalign">0</property>
++                        <property name="label" translatable="yes">Preview of the selected cursor theme</property>
++                      </object>
++                      <packing>
++                        <property name="expand">False</property>
++                        <property name="position">0</property>
++                      </packing>
++                    </child>
++                    <child>
++                      <object class="GtkScrolledWindow" id="scrolledwindow5">
++                        <property name="visible">True</property>
++                        <property name="can_focus">True</property>
++                        <property name="hscrollbar_policy">automatic</property>
++                        <property name="vscrollbar_policy">automatic</property>
++                        <property name="shadow_type">etched-in</property>
++                        <child>
++                          <object class="GtkIconView" id="cursor_demo_view">
++                            <property name="visible">True</property>
++                            <property name="can_focus">True</property>
++                          </object>
++                        </child>
++                      </object>
++                      <packing>
++                        <property name="position">1</property>
++                      </packing>
++                    </child>
++                    <child>
++                      <object class="GtkLabel" id="label26">
++                        <property name="xalign">0</property>
++                        <property name="label" translatable="yes">Size of cursors</property>
++                      </object>
++                      <packing>
++                        <property name="expand">False</property>
++                        <property name="position">2</property>
++                      </packing>
++                    </child>
++                    <child>
++                      <object class="GtkHBox" id="hbox5">
++                        <property name="spacing">12</property>
++                        <child>
++                          <object class="GtkLabel" id="label29">
++                            <property name="visible">True</property>
++                            <property name="label" translatable="yes">Smaller</property>
++                          </object>
++                          <packing>
++                            <property name="expand">False</property>
++                            <property name="position">0</property>
++                          </packing>
++                        </child>
++                        <child>
++                          <object class="GtkHScale" id="cursor_size">
++                            <property name="visible">True</property>
++                            <property name="can_focus">True</property>
++                            <property name="update_policy">delayed</property>
++                            <property name="adjustment">cursor_size_adj</property>
++                            <property name="digits">0</property>
++                            <property name="value_pos">left</property>
++                          </object>
++                          <packing>
++                            <property name="position">1</property>
++                          </packing>
++                        </child>
++                        <child>
++                          <object class="GtkLabel" id="label27">
++                            <property name="visible">True</property>
++                            <property name="label" translatable="yes">Bigger</property>
++                          </object>
++                          <packing>
++                            <property name="expand">False</property>
++                            <property name="position">2</property>
++                          </packing>
++                        </child>
++                      </object>
++                      <packing>
++                        <property name="expand">False</property>
++                        <property name="position">3</property>
++                      </packing>
++                    </child>
++                    <child>
++                      <object class="GtkLabel" id="label30">
++                        <property name="visible">True</property>
++                        <property name="xalign">0</property>
++                        <property name="yalign">0</property>
++                        <property name="label" translatable="yes">&lt;b&gt;Note:&lt;/b&gt; Not all of the desktop applications support changing cursor theme on-the-fly. So your changes here might not be fully applied to all applications till next login.</property>
++                        <property name="use_markup">True</property>
++                        <property name="wrap">True</property>
++                      </object>
++                      <packing>
++                        <property name="expand">False</property>
++                        <property name="position">4</property>
++                      </packing>
++                    </child>
++                  </object>
++                  <packing>
++                    <property name="position">1</property>
++                  </packing>
++                </child>
++              </object>
++              <packing>
++                <property name="position">3</property>
++              </packing>
++            </child>
++            <child type="tab">
++              <object class="GtkLabel" id="label5">
++                <property name="visible">True</property>
++                <property name="label" translatable="yes">Mouse Cursor</property>
++              </object>
++              <packing>
++                <property name="position">3</property>
++                <property name="tab_fill">False</property>
++              </packing>
++            </child>
++            <child>
++              <object class="GtkVBox" id="wm_page">
++                <property name="border_width">12</property>
++                <property name="spacing">18</property>
++                <child>
++                  <placeholder/>
++                </child>
++              </object>
++              <packing>
++                <property name="position">4</property>
++              </packing>
++            </child>
++            <child type="tab">
++              <object class="GtkLabel" id="label10">
++                <property name="visible">True</property>
++                <property name="label" translatable="yes">Window Border</property>
++              </object>
++              <packing>
++                <property name="position">4</property>
++                <property name="tab_fill">False</property>
++              </packing>
++            </child>
++            <child>
++              <object class="GtkVBox" id="vbox1">
++                <property name="visible">True</property>
++                <property name="border_width">12</property>
++                <property name="spacing">18</property>
++                <child>
++                  <object class="GtkFrame" id="frame4">
++                    <property name="visible">True</property>
++                    <property name="label_xalign">0</property>
++                    <property name="shadow_type">none</property>
++                    <child>
++                      <object class="GtkAlignment" id="alignment4">
++                        <property name="visible">True</property>
++                        <property name="left_padding">12</property>
++                        <child>
++                          <object class="GtkVBox" id="vbox5">
++                            <property name="visible">True</property>
++                            <property name="spacing">6</property>
++                            <child>
++                              <object class="GtkTable" id="table2">
++                                <property name="visible">True</property>
++                                <property name="n_rows">2</property>
++                                <property name="n_columns">2</property>
++                                <property name="column_spacing">12</property>
++                                <property name="row_spacing">6</property>
++                                <child>
++                                  <object class="GtkLabel" id="label24">
++                                    <property name="visible">True</property>
++                                    <property name="xalign">0</property>
++                                    <property name="label" translatable="yes">Toolbar Style: </property>
++                                  </object>
++                                  <packing>
++                                    <property name="x_options">GTK_FILL</property>
++                                    <property name="y_options">GTK_FILL</property>
++                                  </packing>
++                                </child>
++                                <child>
++                                  <object class="GtkLabel" id="label25">
++                                    <property name="visible">True</property>
++                                    <property name="xalign">0</property>
++                                    <property name="label" translatable="yes">Toolbar Icon Size: </property>
++                                  </object>
++                                  <packing>
++                                    <property name="top_attach">1</property>
++                                    <property name="bottom_attach">2</property>
++                                    <property name="x_options">GTK_FILL</property>
++                                    <property name="y_options">GTK_FILL</property>
++                                  </packing>
++                                </child>
++                                <child>
++                                  <object class="GtkComboBox" id="tb_style">
++                                    <property name="visible">True</property>
++                                    <property name="model">tb_style_store</property>
++                                    <child>
++                                      <object class="GtkCellRendererText" id="cellrenderertext2"/>
++                                      <attributes>
++                                        <attribute name="text">0</attribute>
++                                      </attributes>
++                                    </child>
++                                  </object>
++                                  <packing>
++                                    <property name="left_attach">1</property>
++                                    <property name="right_attach">2</property>
++                                    <property name="x_options">GTK_FILL</property>
++                                    <property name="y_options">GTK_FILL</property>
++                                  </packing>
++                                </child>
++                                <child>
++                                  <object class="GtkComboBox" id="tb_icon_size">
++                                    <property name="visible">True</property>
++                                    <property name="model">tb_icon_size_store</property>
++                                    <child>
++                                      <object class="GtkCellRendererText" id="cellrenderertext5"/>
++                                      <attributes>
++                                        <attribute name="text">0</attribute>
++                                      </attributes>
++                                    </child>
++                                  </object>
++                                  <packing>
++                                    <property name="left_attach">1</property>
++                                    <property name="right_attach">2</property>
++                                    <property name="top_attach">1</property>
++                                    <property name="bottom_attach">2</property>
++                                    <property name="x_options">GTK_FILL</property>
++                                    <property name="y_options">GTK_FILL</property>
++                                  </packing>
++                                </child>
++                              </object>
++                              <packing>
++                                <property name="position">0</property>
++                              </packing>
++                            </child>
++                            <child>
++                              <object class="GtkCheckButton" id="button_images">
++                                <property name="label" translatable="yes">Show images on buttons</property>
++                                <property name="visible">True</property>
++                                <property name="can_focus">True</property>
++                                <property name="receives_default">False</property>
++                                <property name="draw_indicator">True</property>
++                              </object>
++                              <packing>
++                                <property name="position">1</property>
++                              </packing>
++                            </child>
++                            <child>
++                              <object class="GtkCheckButton" id="menu_images">
++                                <property name="label" translatable="yes">Show images in menus</property>
++                                <property name="visible">True</property>
++                                <property name="can_focus">True</property>
++                                <property name="receives_default">False</property>
++                                <property name="draw_indicator">True</property>
++                              </object>
++                              <packing>
++                                <property name="position">2</property>
++                              </packing>
++                            </child>
++                          </object>
++                        </child>
++                      </object>
++                    </child>
++                    <child type="label">
++                      <object class="GtkLabel" id="label19">
++                        <property name="visible">True</property>
++                        <property name="label" translatable="yes">&lt;b&gt;GUI Options&lt;/b&gt;</property>
++                        <property name="use_markup">True</property>
++                      </object>
++                    </child>
++                  </object>
++                  <packing>
++                    <property name="expand">False</property>
++                    <property name="fill">False</property>
++                    <property name="position">0</property>
++                  </packing>
++                </child>
++                <child>
++                  <object class="GtkFrame" id="sound_effect">
++                    <property name="label_xalign">0</property>
++                    <property name="shadow_type">none</property>
++                    <child>
++                      <object class="GtkAlignment" id="alignment5">
++                        <property name="visible">True</property>
++                        <property name="left_padding">12</property>
++                        <child>
++                          <object class="GtkVBox" id="vbox13">
++                            <property name="visible">True</property>
++                            <property name="spacing">6</property>
++                            <child>
++                              <object class="GtkCheckButton" id="event_sound">
++                                <property name="label" translatable="yes">Play event sounds</property>
++                                <property name="visible">True</property>
++                                <property name="can_focus">True</property>
++                                <property name="receives_default">False</property>
++                                <property name="draw_indicator">True</property>
++                              </object>
++                              <packing>
++                                <property name="position">0</property>
++                              </packing>
++                            </child>
++                            <child>
++                              <object class="GtkCheckButton" id="input_feedback_sound">
++                                <property name="label" translatable="yes">play event sounds as feedback to user input</property>
++                                <property name="visible">True</property>
++                                <property name="can_focus">True</property>
++                                <property name="receives_default">False</property>
++                                <property name="draw_indicator">True</property>
++                              </object>
++                              <packing>
++                                <property name="position">1</property>
++                              </packing>
++                            </child>
++                          </object>
++                        </child>
++                      </object>
++                    </child>
++                    <child type="label">
++                      <object class="GtkLabel" id="label28">
++                        <property name="visible">True</property>
++                        <property name="label" translatable="yes">&lt;b&gt;Sound Effect&lt;/b&gt;</property>
++                        <property name="use_markup">True</property>
++                      </object>
++                    </child>
++                  </object>
++                  <packing>
++                    <property name="expand">False</property>
++                    <property name="fill">False</property>
++                    <property name="position">1</property>
++                  </packing>
++                </child>
++              </object>
++              <packing>
++                <property name="position">5</property>
++              </packing>
++            </child>
++            <child type="tab">
++              <object class="GtkLabel" id="label4">
++                <property name="visible">True</property>
++                <property name="label" translatable="yes">Other</property>
++              </object>
++              <packing>
++                <property name="position">5</property>
++                <property name="tab_fill">False</property>
++              </packing>
++            </child>
++          </object>
++          <packing>
++            <property name="position">1</property>
++          </packing>
++        </child>
++        <child internal-child="action_area">
++          <object class="GtkHButtonBox" id="dialog-action_area1">
++            <property name="visible">True</property>
++            <property name="layout_style">end</property>
++            <child>
++              <object class="GtkButton" id="about">
++                <property name="label">gtk-about</property>
++                <property name="visible">True</property>
++                <property name="can_focus">True</property>
++                <property name="receives_default">True</property>
++                <property name="use_stock">True</property>
++              </object>
++              <packing>
++                <property name="expand">False</property>
++                <property name="fill">False</property>
++                <property name="position">0</property>
++                <property name="secondary">True</property>
++              </packing>
++            </child>
++            <child>
++              <object class="GtkButton" id="apply">
++                <property name="label">gtk-apply</property>
++                <property name="visible">True</property>
++                <property name="sensitive">False</property>
++                <property name="can_focus">True</property>
++                <property name="receives_default">True</property>
++                <property name="use_stock">True</property>
++              </object>
++              <packing>
++                <property name="expand">False</property>
++                <property name="fill">False</property>
++                <property name="position">1</property>
++              </packing>
++            </child>
++            <child>
++              <object class="GtkButton" id="close">
++                <property name="label">gtk-close</property>
++                <property name="visible">True</property>
++                <property name="can_focus">True</property>
++                <property name="receives_default">True</property>
++                <property name="use_stock">True</property>
++              </object>
++              <packing>
++                <property name="expand">False</property>
++                <property name="fill">False</property>
++                <property name="position">1</property>
++              </packing>
++            </child>
++          </object>
++          <packing>
++            <property name="expand">False</property>
++            <property name="pack_type">end</property>
++            <property name="position">0</property>
++          </packing>
++        </child>
++      </object>
++    </child>
++    <action-widgets>
++      <action-widget response="1">about</action-widget>
++      <action-widget response="-10">apply</action-widget>
++      <action-widget response="-7">close</action-widget>
++    </action-widgets>
++  </object>
++  <object class="GtkImage" id="image2">
++    <property name="visible">True</property>
++    <property name="stock">gtk-add</property>
++  </object>
++  <object class="GtkImage" id="image3">
++    <property name="visible">True</property>
++    <property name="stock">gtk-remove</property>
++  </object>
++  <object class="GtkImage" id="image4">
++    <property name="visible">True</property>
++    <property name="stock">gtk-add</property>
++  </object>
++  <object class="GtkImage" id="image5">
++    <property name="visible">True</property>
++    <property name="stock">gtk-remove</property>
++  </object>
++</interface>
+diff --git a/po/Makefile.in.in b/po/Makefile.in.in
+index 402a25f..cc8a222 100644
+--- a/po/Makefile.in.in
++++ b/po/Makefile.in.in
+@@ -129,7 +129,7 @@ install-data-yes: all
+       done
+ # Empty stubs to satisfy archaic automake needs
+-dvi info tags TAGS ID:
++dvi info ctags tags CTAGS TAGS ID:
+ # Define this as empty until I found a useful application.
+ install-exec installcheck:
+diff --git a/po/POTFILES.in b/po/POTFILES.in
+index 94e457b..4072671 100644
+--- a/po/POTFILES.in
++++ b/po/POTFILES.in
+@@ -1,9 +1,6 @@
+ # List of source files containing translatable strings.
+-src/main.c
+-src/main-dlg.c
+-src/demo.c
+-data/demo.glade
+-data/lxappearance.glade
+-# files added by intltool-prepare
+-lxappearance.desktop.in
++data/lxappearance.desktop.in
++data/ui/about.glade.in
++data/ui/lxappearance.glade
++src/utils.c
+diff --git a/po/POTFILES.skip b/po/POTFILES.skip
+new file mode 100644
+index 0000000..9686cfe
+--- /dev/null
++++ b/po/POTFILES.skip
+@@ -0,0 +1 @@
++# List of source files which should be skipped during translation
+diff --git a/po/lxappearance.pot b/po/lxappearance.pot
+new file mode 100644
+index 0000000..10bd1d5
+--- /dev/null
++++ b/po/lxappearance.pot
+@@ -0,0 +1,253 @@
++# SOME DESCRIPTIVE TITLE.
++# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
++# This file is distributed under the same license as the PACKAGE package.
++# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
++#
++#, fuzzy
++msgid ""
++msgstr ""
++"Project-Id-Version: PACKAGE VERSION\n"
++"Report-Msgid-Bugs-To: \n"
++"POT-Creation-Date: 2010-08-08 01:59+0800\n"
++"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
++"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
++"Language-Team: LANGUAGE <LL@li.org>\n"
++"MIME-Version: 1.0\n"
++"Content-Type: text/plain; charset=CHARSET\n"
++"Content-Transfer-Encoding: 8bit\n"
++
++#: ../data/lxappearance.desktop.in.h:1 ../data/ui/lxappearance.glade.h:9
++msgid "Customize Look and Feel"
++msgstr ""
++
++#: ../data/lxappearance.desktop.in.h:2
++msgid "Customizes look and feel of your desktop and applications"
++msgstr ""
++
++#: ../data/ui/about.glade.in.h:1
++msgid "Copyright (C) 2010 LXDE Project"
++msgstr ""
++
++#: ../data/ui/about.glade.in.h:2
++msgid "Customizes look and feel of your desktop"
++msgstr ""
++
++#. Please replace this line with your own names, one name per line.
++#: ../data/ui/about.glade.in.h:4
++msgid "translator-credits"
++msgstr ""
++
++#: ../data/ui/lxappearance.glade.h:1
++msgid "<b>GUI Options</b>"
++msgstr ""
++
++#: ../data/ui/lxappearance.glade.h:2
++msgid ""
++"<b>Note:</b> Not all of the desktop applications support changing cursor "
++"theme on-the-fly. So your changes here might not be fully applied to all "
++"applications till next login."
++msgstr ""
++
++#: ../data/ui/lxappearance.glade.h:3
++msgid "<b>Sound Effect</b>"
++msgstr ""
++
++#: ../data/ui/lxappearance.glade.h:4
++msgid "Background"
++msgstr ""
++
++#: ../data/ui/lxappearance.glade.h:5
++msgid "Bigger"
++msgstr ""
++
++#: ../data/ui/lxappearance.glade.h:6
++msgid "Check Button"
++msgstr ""
++
++#: ../data/ui/lxappearance.glade.h:7
++msgid "Color"
++msgstr ""
++
++#: ../data/ui/lxappearance.glade.h:8
++msgid "Color scheme is not supported by currently selected widget theme."
++msgstr ""
++
++#: ../data/ui/lxappearance.glade.h:10
++msgid "Default font:"
++msgstr ""
++
++#: ../data/ui/lxappearance.glade.h:11
++msgid "Demo"
++msgstr ""
++
++#: ../data/ui/lxappearance.glade.h:12
++msgid "Foreground"
++msgstr ""
++
++#: ../data/ui/lxappearance.glade.h:13
++msgid "Icon Theme"
++msgstr ""
++
++#: ../data/ui/lxappearance.glade.h:14
++msgid "Icons only"
++msgstr ""
++
++#: ../data/ui/lxappearance.glade.h:15
++msgid "Install"
++msgstr ""
++
++#: ../data/ui/lxappearance.glade.h:16
++msgid "Large toolbar icon"
++msgstr ""
++
++#: ../data/ui/lxappearance.glade.h:17
++msgid "Mouse Cursor"
++msgstr ""
++
++#: ../data/ui/lxappearance.glade.h:18
++msgid "Normal windows:"
++msgstr ""
++
++#: ../data/ui/lxappearance.glade.h:19
++msgid "Other"
++msgstr ""
++
++#: ../data/ui/lxappearance.glade.h:20
++msgid "Page1"
++msgstr ""
++
++#: ../data/ui/lxappearance.glade.h:21
++msgid "Page2"
++msgstr ""
++
++#: ../data/ui/lxappearance.glade.h:22
++msgid "Play event sounds"
++msgstr ""
++
++#: ../data/ui/lxappearance.glade.h:23
++msgid "Preview of the selected cursor theme"
++msgstr ""
++
++#: ../data/ui/lxappearance.glade.h:24
++msgid "Preview of the selected icon theme"
++msgstr ""
++
++#: ../data/ui/lxappearance.glade.h:25
++msgid "Preview of the selected widget style"
++msgstr ""
++
++#: ../data/ui/lxappearance.glade.h:26
++msgid "Radio Button"
++msgstr ""
++
++#: ../data/ui/lxappearance.glade.h:27
++msgid "Remove"
++msgstr ""
++
++#: ../data/ui/lxappearance.glade.h:28
++msgid "Same as buttons"
++msgstr ""
++
++#: ../data/ui/lxappearance.glade.h:29
++msgid "Same as dialogs"
++msgstr ""
++
++#: ../data/ui/lxappearance.glade.h:30
++msgid "Same as drag icons"
++msgstr ""
++
++#: ../data/ui/lxappearance.glade.h:31
++msgid "Same as menu items"
++msgstr ""
++
++#: ../data/ui/lxappearance.glade.h:32
++msgid "Selected items:"
++msgstr ""
++
++#: ../data/ui/lxappearance.glade.h:33
++msgid "Show images in menus"
++msgstr ""
++
++#: ../data/ui/lxappearance.glade.h:34
++msgid "Show images on buttons"
++msgstr ""
++
++#: ../data/ui/lxappearance.glade.h:35
++msgid "Size of cursors"
++msgstr ""
++
++#: ../data/ui/lxappearance.glade.h:36
++msgid "Small toolbar icon"
++msgstr ""
++
++#: ../data/ui/lxappearance.glade.h:37
++msgid "Smaller"
++msgstr ""
++
++#: ../data/ui/lxappearance.glade.h:38
++msgid "Text below icons"
++msgstr ""
++
++#: ../data/ui/lxappearance.glade.h:39
++msgid "Text beside icons"
++msgstr ""
++
++#: ../data/ui/lxappearance.glade.h:40
++msgid "Text only"
++msgstr ""
++
++#: ../data/ui/lxappearance.glade.h:41
++msgid "Text windows:"
++msgstr ""
++
++#: ../data/ui/lxappearance.glade.h:42
++msgid "Toolbar Icon Size: "
++msgstr ""
++
++#: ../data/ui/lxappearance.glade.h:43
++msgid "Toolbar Style: "
++msgstr ""
++
++#: ../data/ui/lxappearance.glade.h:44
++msgid "Tooltips:"
++msgstr ""
++
++#: ../data/ui/lxappearance.glade.h:45
++msgid "Use customized color scheme"
++msgstr ""
++
++#: ../data/ui/lxappearance.glade.h:46
++msgid "Widget"
++msgstr ""
++
++#: ../data/ui/lxappearance.glade.h:47
++msgid "Window Border"
++msgstr ""
++
++#: ../data/ui/lxappearance.glade.h:48
++msgid "_Edit"
++msgstr ""
++
++#: ../data/ui/lxappearance.glade.h:49
++msgid "_File"
++msgstr ""
++
++#: ../data/ui/lxappearance.glade.h:50
++msgid "_Help"
++msgstr ""
++
++#: ../data/ui/lxappearance.glade.h:51
++msgid "button"
++msgstr ""
++
++#: ../data/ui/lxappearance.glade.h:52
++msgid "play event sounds as feedback to user input"
++msgstr ""
++
++#: ../src/utils.c:212
++msgid "Select an icon theme"
++msgstr ""
++
++#: ../src/utils.c:219
++msgid "*.tar.gz, *.tar.bz2 (Icon Theme)"
++msgstr ""
+diff --git a/po/zh_TW.po b/po/zh_TW.po
+index 5a4db14..3e05395 100644
+--- a/po/zh_TW.po
++++ b/po/zh_TW.po
+@@ -7,209 +7,248 @@ msgid ""
+ msgstr ""
+ "Project-Id-Version: 0.1\n"
+ "Report-Msgid-Bugs-To: \n"
+-"POT-Creation-Date: 2009-12-20 15:11+0100\n"
+-"PO-Revision-Date: 2009-12-19 14:33+0800\n"
++"POT-Creation-Date: 2010-08-08 01:59+0800\n"
++"PO-Revision-Date: 2010-08-08 01:59+0800\n"
+ "Last-Translator: 洪任諭 <pcman.tw@gmail.com>\n"
+-"Language-Team: zh_TW <LL@li.org>\n"
++"Language-Team: zh_TW <zh@li.org>\n"
+ "MIME-Version: 1.0\n"
+ "Content-Type: text/plain; charset=utf-8\n"
+ "Content-Transfer-Encoding: 8bit\n"
+-"X-Generator: Pootle 1.1.0\n"
+ "X-Poedit-Language: Chinese\n"
+ "X-Poedit-Country: TAIWAN\n"
+-"X-Poedit-SourceCharset: iso-8859-1\n"
++"X-Poedit-SourceCharset: utf-8\n"
+-#: ../src/main-dlg.c:650
+-msgid "Select an icon theme"
+-msgstr "選擇一個圖示佈景主題"
++#: ../data/lxappearance.desktop.in.h:1
++#: ../data/ui/lxappearance.glade.h:9
++msgid "Customize Look and Feel"
++msgstr "自訂外觀風格"
+-#: ../src/main-dlg.c:657
+-msgid "*.tar.gz, *.tar.bz2 (Icon Theme)"
+-msgstr "*.tar.gz, *.tar.bz2 (圖示佈景主題)"
++#: ../data/lxappearance.desktop.in.h:2
++msgid "Customizes look and feel of your desktop and applications"
++msgstr "自訂桌面和應用程式的外觀風格"
++
++#: ../data/ui/about.glade.in.h:1
++msgid "Copyright (C) 2010 LXDE Project"
++msgstr "版權所有 (C) 2010 LXDE 專案"
++
++#: ../data/ui/about.glade.in.h:2
++msgid "Customizes look and feel of your desktop"
++msgstr "自訂桌面外觀風格"
++
++#. Please replace this line with your own names, one name per line.
++#: ../data/ui/about.glade.in.h:4
++msgid "translator-credits"
++msgstr "洪任諭 (PCMan) <pcman.tw@gmail.com>"
++
++#: ../data/ui/lxappearance.glade.h:1
++msgid "<b>GUI Options</b>"
++msgstr "<b>圖形介面選項</b>"
+-#: ../src/demo.c:56
+-msgid "Column"
+-msgstr "欄位"
++#: ../data/ui/lxappearance.glade.h:2
++msgid "<b>Note:</b> Not all of the desktop applications support changing cursor theme on-the-fly. So your changes here might not be fully applied to all applications till next login."
++msgstr "<b>注意:</b>並非所有桌面應用程式都能支援動態變更滑鼠游標,所以你的部份變更可能要到下次登入時才會被完全套用。"
+-#: ../src/demo.c:65
+-msgid "Item"
+-msgstr "項目"
++#: ../data/ui/lxappearance.glade.h:3
++msgid "<b>Sound Effect</b>"
++msgstr "<b>音效</b>"
+-#: ../data/demo.glade.h:1
++#: ../data/ui/lxappearance.glade.h:4
++msgid "Background"
++msgstr "背景"
++
++#: ../data/ui/lxappearance.glade.h:5
++msgid "Bigger"
++msgstr "較大"
++
++#: ../data/ui/lxappearance.glade.h:6
+ msgid "Check Button"
+-msgstr "Check Button"
++msgstr "核取方塊"
++
++#: ../data/ui/lxappearance.glade.h:7
++msgid "Color"
++msgstr "色彩"
++
++#: ../data/ui/lxappearance.glade.h:8
++msgid "Color scheme is not supported by currently selected widget theme."
++msgstr "目前選取的佈景主題不支援變更色彩"
+-#: ../data/demo.glade.h:2
++#: ../data/ui/lxappearance.glade.h:10
++msgid "Default font:"
++msgstr "預設字型:"
++
++#: ../data/ui/lxappearance.glade.h:11
+ msgid "Demo"
+ msgstr "展示"
+-#: ../data/demo.glade.h:3
+-msgid "Radio Button"
+-msgstr "Radio Button"
++#: ../data/ui/lxappearance.glade.h:12
++msgid "Foreground"
++msgstr "前景"
+-#: ../data/demo.glade.h:4
+-msgid "Tab1"
+-msgstr "分頁1"
++#: ../data/ui/lxappearance.glade.h:13
++msgid "Icon Theme"
++msgstr "圖示佈景主題"
+-#: ../data/demo.glade.h:5
+-msgid "Tab2"
+-msgstr "分頁2"
++#: ../data/ui/lxappearance.glade.h:14
++msgid "Icons only"
++msgstr "只有圖示"
+-#: ../data/demo.glade.h:6
+-msgid "Tab3"
+-msgstr "分頁3"
++#: ../data/ui/lxappearance.glade.h:15
++msgid "Install"
++msgstr "安裝"
+-#: ../data/demo.glade.h:7
+-msgid "Tab4"
+-msgstr "分頁4"
++#: ../data/ui/lxappearance.glade.h:16
++msgid "Large toolbar icon"
++msgstr "大型工具列圖示"
+-#: ../data/demo.glade.h:8
+-msgid "Test Item 1"
+-msgstr "測試項目1"
++#: ../data/ui/lxappearance.glade.h:17
++msgid "Mouse Cursor"
++msgstr "滑鼠游標"
+-#: ../data/demo.glade.h:9
+-msgid "Test Item 2"
+-msgstr "測試項目2"
++#: ../data/ui/lxappearance.glade.h:18
++msgid "Normal windows:"
++msgstr "正常視窗:"
+-#: ../data/demo.glade.h:10
+-msgid "Test Item 3"
+-msgstr "測試項目3"
++#: ../data/ui/lxappearance.glade.h:19
++msgid "Other"
++msgstr "其他"
+-#: ../data/demo.glade.h:11
+-msgid "Type some characters here to test currently selected font."
+-msgstr "在這裡打一些字測試目前選擇的字型"
++#: ../data/ui/lxappearance.glade.h:20
++msgid "Page1"
++msgstr "第一頁"
+-#: ../data/demo.glade.h:12
+-msgid "_Edit"
+-msgstr "編輯(_E)"
++#: ../data/ui/lxappearance.glade.h:21
++msgid "Page2"
++msgstr "第二頁"
+-#: ../data/demo.glade.h:13
+-msgid "_File"
+-msgstr "檔案(_F)"
++#: ../data/ui/lxappearance.glade.h:22
++msgid "Play event sounds"
++msgstr "播放事件音效"
+-#: ../data/demo.glade.h:14
+-msgid "_Help"
+-msgstr "說明(_H)"
++#: ../data/ui/lxappearance.glade.h:23
++msgid "Preview of the selected cursor theme"
++msgstr "預覽選取的滑鼠游標佈景主題"
+-#: ../data/demo.glade.h:15
+-msgid "button"
+-msgstr "按鈕"
++#: ../data/ui/lxappearance.glade.h:24
++msgid "Preview of the selected icon theme"
++msgstr "預覽選取的圖示佈景主題"
+-#: ../data/lxappearance.glade.h:1
+-msgid "<b>Preview</b>"
+-msgstr "<b>預覽</b>"
++#: ../data/ui/lxappearance.glade.h:25
++msgid "Preview of the selected widget style"
++msgstr "預覽選取的視窗元件佈景主題"
+-#: ../data/lxappearance.glade.h:2
+-msgid "Appearance Settings"
+-msgstr "外觀設定"
++#: ../data/ui/lxappearance.glade.h:26
++msgid "Radio Button"
++msgstr "Radio 按鈕"
+-#: ../data/lxappearance.glade.h:3
+-msgid "Available Cursor Themes"
+-msgstr "可用的滑鼠游標佈景主題"
++#: ../data/ui/lxappearance.glade.h:27
++msgid "Remove"
++msgstr "移除"
+-#: ../data/lxappearance.glade.h:4
+-msgid "Available Icon Themes"
+-msgstr "可用的圖示佈景主題"
++#: ../data/ui/lxappearance.glade.h:28
++msgid "Same as buttons"
++msgstr "和按鈕相同"
+-#: ../data/lxappearance.glade.h:5
+-msgid "Available Window Themes"
+-msgstr "可用的視窗佈景主題"
++#: ../data/ui/lxappearance.glade.h:29
++msgid "Same as dialogs"
++msgstr "和對話框相同"
+-#: ../data/lxappearance.glade.h:6
+-msgid "Cursor"
+-msgstr "游標"
++#: ../data/ui/lxappearance.glade.h:30
++msgid "Same as drag icons"
++msgstr "和滑鼠拖放時相同"
+-#: ../data/lxappearance.glade.h:7
+-msgid "Icon"
+-msgstr "圖示"
++#: ../data/ui/lxappearance.glade.h:31
++msgid "Same as menu items"
++msgstr "和選單項目相同"
+-#: ../data/lxappearance.glade.h:8
+-msgid "Icons only"
+-msgstr "只顯示圖示"
++#: ../data/ui/lxappearance.glade.h:32
++msgid "Selected items:"
++msgstr "選取的項目:"
+-#: ../data/lxappearance.glade.h:9
+-msgid "Large"
+-msgstr "大"
++#: ../data/ui/lxappearance.glade.h:33
++msgid "Show images in menus"
++msgstr "在選單中顯示圖示"
+-#: ../data/lxappearance.glade.h:10
+-msgid "Other"
+-msgstr "其他"
++#: ../data/ui/lxappearance.glade.h:34
++msgid "Show images on buttons"
++msgstr "在按鈕上顯示圖示"
++
++#: ../data/ui/lxappearance.glade.h:35
++msgid "Size of cursors"
++msgstr "游標大小"
+-#: ../data/lxappearance.glade.h:11
+-msgid "Size"
+-msgstr "大小"
++#: ../data/ui/lxappearance.glade.h:36
++msgid "Small toolbar icon"
++msgstr "小型工具列圖示"
+-#: ../data/lxappearance.glade.h:12
+-msgid "Small"
+-msgstr "小"
++#: ../data/ui/lxappearance.glade.h:37
++msgid "Smaller"
++msgstr "較小"
+-#: ../data/lxappearance.glade.h:13
++#: ../data/ui/lxappearance.glade.h:38
+ msgid "Text below icons"
+ msgstr "文字在圖示下方"
+-#: ../data/lxappearance.glade.h:14
++#: ../data/ui/lxappearance.glade.h:39
+ msgid "Text beside icons"
+ msgstr "文字在圖示旁"
+-#: ../data/lxappearance.glade.h:15
++#: ../data/ui/lxappearance.glade.h:40
+ msgid "Text only"
+-msgstr "只顯示文字"
++msgstr "只有文字"
++
++#: ../data/ui/lxappearance.glade.h:41
++msgid "Text windows:"
++msgstr "文字視窗:"
++
++#: ../data/ui/lxappearance.glade.h:42
++msgid "Toolbar Icon Size: "
++msgstr "工具列圖示大小:"
+-#: ../data/lxappearance.glade.h:16
++#: ../data/ui/lxappearance.glade.h:43
+ msgid "Toolbar Style: "
+-msgstr "工具列樣式:"
+-
+-#: ../data/lxappearance.glade.h:17
+-msgid "Window"
+-msgstr "視窗"
+-
+-#: ../data/lxappearance.glade.h:18
+-msgid "_Font:"
+-msgstr "字型"
+-
+-#: ../data/lxappearance.glade.h:19
+-msgid "_Install"
+-msgstr "安裝(_I)"
+-
+-#: ../lxappearance.desktop.in.h:1
+-msgid "Appearance"
+-msgstr "外觀設定"
+-
+-#: ../lxappearance.desktop.in.h:2
+-msgid "Customize the look of the desktop"
+-msgstr "自訂桌面外觀"
+-
+-#~ msgid "Back"
+-#~ msgstr "上一頁"
+-
+-#~ msgid "Forward"
+-#~ msgstr "下一頁"
+-
+-#~ msgid "Stop"
+-#~ msgstr "停止"
+-
+-#~ msgid ""
+-#~ "Test Item 1\n"
+-#~ "Test Item 2\n"
+-#~ "Test Item 3"
+-#~ msgstr ""
+-#~ "測試項目 1\n"
+-#~ "測試項目 2\n"
+-#~ "測試項目 3"
+-
+-#~ msgid "Couldn't find pixmap file: %s"
+-#~ msgstr "沒發現pixmap 檔:%s"
+-
+-#~ msgid ""
+-#~ "Icons only\n"
+-#~ "Text only\n"
+-#~ "Text below icons\n"
+-#~ "Text beside icons"
+-#~ msgstr ""
+-#~ "只有小圖示\n"
+-#~ "只有文字\n"
+-#~ "文字在圖示之下\n"
+-#~ "文字在圖示中間"
+-
+-#~ msgid "Available Fonts"
+-#~ msgstr "可用的字型"
++msgstr "工具列風格:"
++
++#: ../data/ui/lxappearance.glade.h:44
++msgid "Tooltips:"
++msgstr "工具提示:"
++
++#: ../data/ui/lxappearance.glade.h:45
++msgid "Use customized color scheme"
++msgstr "使用自訂的色彩"
++
++#: ../data/ui/lxappearance.glade.h:46
++msgid "Widget"
++msgstr "圖形元件"
++
++#: ../data/ui/lxappearance.glade.h:47
++msgid "Window Border"
++msgstr "視窗邊框"
++
++#: ../data/ui/lxappearance.glade.h:48
++msgid "_Edit"
++msgstr "編輯(_E)"
++
++#: ../data/ui/lxappearance.glade.h:49
++msgid "_File"
++msgstr "檔案(_F)"
++
++#: ../data/ui/lxappearance.glade.h:50
++msgid "_Help"
++msgstr "說明(_H)"
++
++#: ../data/ui/lxappearance.glade.h:51
++msgid "button"
++msgstr "按鈕"
++
++#: ../data/ui/lxappearance.glade.h:52
++msgid "play event sounds as feedback to user input"
++msgstr "使用者輸入時播放回饋音效"
++
++#: ../src/utils.c:212
++msgid "Select an icon theme"
++msgstr "選取一個圖示佈景主題"
++
++#: ../src/utils.c:219
++msgid "*.tar.gz, *.tar.bz2 (Icon Theme)"
++msgstr "*.tar.gz, *.tar.bz2 (圖示佈景主題)"
++
+diff --git a/src/Makefile.am b/src/Makefile.am
+index 4296a6c..f9ae7c9 100644
+--- a/src/Makefile.am
++++ b/src/Makefile.am
+@@ -1,22 +1,51 @@
+ NULL=
+-INCLUDES = \
+-      -DPACKAGE_DATA_DIR=\""$(datadir)"\" \
++AM_CPPFLAGS = \
++      -I$(srcdir) \
++      -DPACKAGE_DATA_DIR=\""$(datadir)/lxappearance"\" \
++      -DPACKAGE_UI_DIR=\""$(datadir)/lxappearance/ui"\" \
++      -DPACKAGE_LIB_DIR=\""$(libdir)"\" \
+       -DPACKAGE_LOCALE_DIR=\""$(prefix)/$(DATADIRNAME)/locale"\" \
+-      $(PACKAGE_CFLAGS) \
+       $(NULL)
+-bin_PROGRAMS = lxappearance
++lxappearance_includedir = $(includedir)/lxappearance
++lxappearance_include_HEADERS = lxappearance.h
++bin_PROGRAMS = lxappearance
+ lxappearance_SOURCES = \
+-      main.c \
+-      main-dlg.c main-dlg.h \
+-      demo.c demo.h \
++      lxappearance.c \
++      lxappearance.h \
++      widget-theme.c \
++      widget-theme.h \
++      color-scheme.c \
++      color-scheme.h \
++      icon-theme.c \
++      icon-theme.h \
++      cursor-theme.c \
++      cursor-theme.h \
++      other.c \
++      other.h \
++      utils.c \
++      utils.h \
++      plugin.c \
++      plugin.h \
+       $(NULL)
+ lxappearance_CFLAGS = \
+-      -Wl,--export-dynamic \
++      $(GTK_CFLAGS) \
++      $(GMODULE_CFLAGS) \
+       -Werror-implicit-function-declaration \
+       $(NULL)
+-lxappearance_LDADD = $(PACKAGE_LIBS) $(INTLLIBS)
++lxappearance_LDADD = \
++      $(GTK_LIBS) \
++      $(GMODULE_LIBS) \
++      $(INTLLIBS) \
++      $(NULL)
++
++
++# Little program to optimize size of xml files
++noinst_PROGRAMS=xml-purge
++xml_purge_SOURCES=$(top_srcdir)/src/xml-purge.c
++xml_purge_CFLAGS=$(GTK_CFLAGS)
++xml_purge_LDADD=$(GTK_LIBS)
+diff --git a/src/color-scheme.c b/src/color-scheme.c
+new file mode 100644
+index 0000000..4b78193
+--- /dev/null
++++ b/src/color-scheme.c
+@@ -0,0 +1,294 @@
++//      color-scheme.c
++//
++//      Copyright 2010 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
++//
++//      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., 51 Franklin Street, Fifth Floor, Boston,
++//      MA 02110-1301, USA.
++
++#include "lxappearance.h"
++#include "color-scheme.h"
++#include <string.h>
++
++static GRegex* gtkrc_include_reg = NULL;
++static GRegex* gtkrc_color_scheme_reg = NULL;
++
++/* http://live.gnome.org/GnomeArt/Tutorials/GtkThemes/SymbolicColors/#Default_colors_in_GNOME */
++static const char* gnome_color_names[] = {
++    "fg_color", /* The base for the foreground colors. */
++    "bg_color", /* Color to generate the background colors from. */
++    "base_color", /* The base color. */
++    "text_color", /* The text color in input widgets. */
++    "selected_bg_color", /* Color for the background of selected text. */
++    "selected_fg_color", /* Color of selected text. */
++    "tooltip_bg_color", /* Background color of tooltips. */
++    "tooltip_fg_color", /* Text color for text in tooltips. */
++};
++
++char* color_scheme_hash_to_str(GHashTable* hash)
++{
++    GHashTableIter it;
++    char* key, *val;
++    GString* ret = g_string_sized_new(100);
++    g_hash_table_iter_init (&it, hash);
++    while(g_hash_table_iter_next(&it, (gpointer*)&key, (gpointer*)&val))
++        g_string_append_printf(ret, "%s:%s\n", key, val);
++    return g_string_free(ret, FALSE);
++}
++
++void color_scheme_str_to_hash(GHashTable* hash, const char* color_str)
++{
++    /* g_debug("color_str: %s", color_str); */
++    /* split color scheme string into key/value pairs */
++    char** pairs = g_strsplit_set(color_str, "\n;", -1);
++    char** pair;
++    for(pair = pairs; *pair; ++pair)
++    {
++        char* name = strtok(*pair, ": \t");
++        /* g_debug("color_name = %s", name); */
++        if(name)
++        {
++            char* val = strtok(NULL, " \t");
++            if(val)
++                g_hash_table_replace(hash, g_strdup(name), g_strdup(val));
++        }
++    }
++    g_strfreev(pairs);
++}
++
++static void on_color_set(GtkColorButton* btn, const char* color_name)
++{
++    GdkColor clr;
++    char* color_str;
++    gtk_color_button_get_color(btn, &clr);
++    color_str = gdk_color_to_string(&clr);
++
++    g_hash_table_replace(app.color_scheme_hash, g_strdup(color_name), color_str);
++    g_free(app.color_scheme);
++    app.color_scheme = color_scheme_hash_to_str(app.color_scheme_hash);
++
++    g_object_set(gtk_settings_get_default(), "gtk-color-scheme", app.color_scheme, NULL);
++
++    lxappearance_changed();
++}
++
++static void update_color_buttons()
++{
++    int i;
++    /* set the color to buttons */
++    GHashTable* hash;
++
++    /* if custom color scheme is not used, use the default one. */
++    if(app.color_scheme)
++        hash = app.color_scheme_hash;
++    else
++        hash = app.default_color_scheme_hash;
++
++    for(i = 0; i < 8; ++i)
++    {
++        GtkWidget* btn = app.color_btns[i];
++        const char* color_name = gnome_color_names[i];
++        const char* color_str = (const char*)g_hash_table_lookup(hash, color_name);
++        /* g_debug("%s ='%s'", gnome_color_names[i], color_str); */
++        if(color_str)
++        {
++            GdkColor clr;
++            if(gdk_color_parse(color_str, &clr))
++            {
++                /* prevent invoking color-set handlers here. */
++                g_signal_handlers_block_by_func(btn, on_color_set, (gpointer)color_name);
++                gtk_color_button_set_color(GTK_COLOR_BUTTON(btn), &clr);
++                g_signal_handlers_unblock_by_func(btn, on_color_set, (gpointer)color_name);
++            }
++            gtk_widget_set_sensitive(btn, TRUE);
++        }
++        else
++            gtk_widget_set_sensitive(btn, FALSE);
++    }
++}
++
++static void hash_table_copy(GHashTable* dest, GHashTable* src)
++{
++    GHashTableIter it;
++    char* key, *val;
++    g_hash_table_remove_all(dest);
++    g_hash_table_iter_init(&it, src);
++    while(g_hash_table_iter_next(&it, (gpointer*)&key, (gpointer*)&val))
++        g_hash_table_insert(dest, g_strdup(key), g_strdup(val));
++}
++
++static void on_custom_color_toggled(GtkToggleButton* btn, gpointer user_data)
++{
++    g_free(app.color_scheme);
++    if(gtk_toggle_button_get_active(btn)) /* use customized color scheme. */
++    {
++        gtk_widget_set_sensitive(app.color_table, TRUE);
++        /* copy default colors to custom color hash table */
++        hash_table_copy(app.color_scheme_hash, app.default_color_scheme_hash);
++        app.color_scheme = color_scheme_hash_to_str(app.color_scheme_hash);
++        g_object_set(gtk_settings_get_default(), "gtk-color-scheme", app.color_scheme, NULL);
++    }
++    else /* use default colors provided by the theme. */
++    {
++        char* color_scheme_str;
++        gtk_widget_set_sensitive(app.color_table, FALSE);
++        /* restore default colors */
++        app.color_scheme = NULL;
++        g_hash_table_remove_all(app.color_scheme_hash);
++        if(g_hash_table_size(app.default_color_scheme_hash) > 0)
++            color_scheme_str = color_scheme_hash_to_str(app.default_color_scheme_hash);
++        else
++            color_scheme_str = g_strdup("");
++        g_object_set(gtk_settings_get_default(), "gtk-color-scheme", color_scheme_str, NULL);
++        g_free(color_scheme_str);
++    }
++    update_color_buttons();
++
++    lxappearance_changed();
++}
++
++void color_scheme_init(GtkBuilder* b)
++{
++    int i;
++    /* regular expressions used to parse gtkrc files */
++    gtkrc_include_reg = g_regex_new(
++        "[\\s]*include[\\s]+(\"([^\"]+)\"|'([^']+)')",
++        G_REGEX_MULTILINE|G_REGEX_OPTIMIZE, 0, NULL);
++
++    gtkrc_color_scheme_reg = g_regex_new(
++        "[\\s]*(gtk-color-scheme|gtk_color_scheme)[\\s]*=[\\s]*(\"([^\"]+)\"|'([^']+)')",
++        G_REGEX_MULTILINE|G_REGEX_OPTIMIZE, 0, NULL);
++
++    app.color_table = GTK_WIDGET(gtk_builder_get_object(b, "color_table"));
++    app.custom_colors = GTK_WIDGET(gtk_builder_get_object(b, "custom_colors"));
++    app.no_custom_colors = GTK_WIDGET(gtk_builder_get_object(b, "no_custom_colors"));
++
++    /* toggle the check box if we have custom color scheme */
++    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(app.custom_colors), app.color_scheme != NULL);
++    g_signal_connect(app.custom_colors, "toggled", G_CALLBACK(on_custom_color_toggled), NULL);
++
++    /* hash table of the default color scheme of currently selected theme. */
++    app.default_color_scheme_hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
++
++    for(i = 0; i < 8; ++i)
++        app.color_btns[i] = GTK_WIDGET(gtk_builder_get_object(b, gnome_color_names[i]));;
++
++    /* update color scheme page for currently selected gtk theme. */
++    color_scheme_update();
++
++    for(i = 0; i < 8; ++i)
++        g_signal_connect(app.color_btns[i], "color-set", G_CALLBACK(on_color_set), (gpointer)gnome_color_names[i]);
++}
++
++/* return FALSE when the gtkrc file does not exists. */
++gboolean gtkrc_file_get_color_scheme(const char* gtkrc_file, GHashTable* hash)
++{
++    char* content;
++    /* g_debug("check: %s", gtkrc_file); */
++    if(g_file_get_contents(gtkrc_file, &content, NULL, NULL))
++    {
++        GMatchInfo* match_info;
++
++        /* find gtkrc files included in this file. */
++        g_regex_match(gtkrc_include_reg, content, 0, &match_info);
++        while(g_match_info_matches (match_info))
++        {
++            gchar* include = g_match_info_fetch(match_info, 2);
++            /* try to load color schemes in every included gtkrc file. */
++            if(!g_path_is_absolute(include)) /* make a full path when needed. */
++            {
++                char* dirname = g_path_get_dirname(gtkrc_file);
++                char* file = g_build_filename(dirname, include, NULL);
++                g_free(dirname);
++                g_free(include);
++                include = file;
++            }
++            gtkrc_file_get_color_scheme(include, hash);
++            g_free(include);
++            g_match_info_next(match_info, NULL);
++        }
++
++        /* try to extract gtk-color-scheme from the gtkrc file. */
++        g_regex_match(gtkrc_color_scheme_reg, content, 0, &match_info);
++        while(g_match_info_matches (match_info))
++        {
++            char *color_scheme_str = g_match_info_fetch(match_info, 3);
++            /* need to unescape the string to replace "\\n" with "\n" */
++            char* unescaped = g_strcompress(color_scheme_str);
++            g_free (color_scheme_str);
++            color_scheme_str_to_hash(hash, unescaped);
++            g_free(unescaped);
++            g_match_info_next(match_info, NULL);
++        }
++        g_match_info_free(match_info);
++        g_free(content);
++    }
++    else
++        return FALSE;
++    return TRUE;
++}
++
++/* update the color scheme page for currently selected gtk theme.
++ * called when currently selected gtk theme gets changed. */
++void color_scheme_update()
++{
++    /* the current gtk theme gets changed.
++     * reload the default color scheme of current theme. */
++    g_hash_table_remove_all(app.default_color_scheme_hash);
++
++    if(app.widget_theme)
++    {
++        gboolean file_found;
++        char* gtkrc = g_build_filename(g_get_home_dir(), ".themes", app.widget_theme, "gtk-2.0/gtkrc", NULL);
++        /* if the theme is found in user-custom theme dir */
++        file_found = gtkrc_file_get_color_scheme(gtkrc, app.default_color_scheme_hash);
++        g_free(gtkrc);
++
++        if(!file_found)
++        {
++            /* if the theme is found in system-wide theme dir */
++            gtkrc = g_build_filename(gtk_rc_get_theme_dir(), app.widget_theme, "gtk-2.0/gtkrc", NULL);
++            gtkrc_file_get_color_scheme(gtkrc, app.default_color_scheme_hash);
++            g_free(gtkrc);
++        }
++        app.color_scheme_supported = (g_hash_table_size(app.default_color_scheme_hash) > 0);
++    }
++    else
++        app.color_scheme_supported = FALSE;
++
++    if(app.color_scheme_supported)
++    {
++        gtk_widget_set_sensitive(app.custom_colors, TRUE);
++        gtk_widget_set_sensitive(app.color_table, app.color_scheme != NULL);
++        gtk_widget_hide(app.no_custom_colors);
++
++        /* if customized color scheme is not used,
++         * use default colors of the theme. */
++        if(!app.color_scheme)
++        {
++            char* color_scheme_str = color_scheme_hash_to_str(app.default_color_scheme_hash);
++            g_object_set(gtk_settings_get_default(), "gtk-color-scheme", color_scheme_str, NULL);
++            g_free(color_scheme_str);
++        }
++    }
++    else
++    {
++        gtk_widget_set_sensitive(app.color_table, FALSE);
++        gtk_widget_set_sensitive(app.custom_colors, FALSE);
++        gtk_widget_show(app.no_custom_colors);
++    }
++    /* set the color to buttons */
++    update_color_buttons();
++}
++
+diff --git a/src/color-scheme.h b/src/color-scheme.h
+new file mode 100644
+index 0000000..7397143
+--- /dev/null
++++ b/src/color-scheme.h
+@@ -0,0 +1,44 @@
++//      color-scheme.h
++//
++//      Copyright 2010 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
++//
++//      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., 51 Franklin Street, Fifth Floor, Boston,
++//      MA 02110-1301, USA.
++
++
++#ifndef __COLOR_SCHEME_H__
++#define __COLOR_SCHEME_H__
++
++G_BEGIN_DECLS
++
++/* initialize gtk color scheme support. */
++void color_scheme_init(GtkBuilder* b);
++
++/* update the color scheme page for currently selected gtk theme.
++ * should be called when currently selected gtk theme gets changed. */
++void color_scheme_update();
++
++/* load gtk-color-scheme from gtkrc file into hash table if it's available. */
++gboolean gtkrc_file_get_color_scheme(const char* gtkrc_file, GHashTable* hash);
++
++/* convert a color scheme hash table to string */
++char* color_scheme_hash_to_str(GHashTable* hash);
++
++/* merge a color scheme string to hash table. */
++void color_scheme_str_to_hash(GHashTable* hash, const char* color_str);
++
++G_END_DECLS
++
++#endif /* __COLOR_SCHEME_H__ */
+diff --git a/src/cursor-theme.c b/src/cursor-theme.c
+new file mode 100644
+index 0000000..4e77d68
+--- /dev/null
++++ b/src/cursor-theme.c
+@@ -0,0 +1,127 @@
++/*
++ *      cursor-theme.c
++ *
++ *      Copyright 2010 PCMan <pcman.tw@gmail.com>
++ *
++ *      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., 51 Franklin Street, Fifth Floor, Boston,
++ *      MA 02110-1301, USA.
++ */
++
++#include "cursor-theme.h"
++#include "icon-theme.h"
++#include "lxappearance.h"
++#include <gdk/gdkx.h>
++
++static void update_cursor_demo()
++{
++    GtkListStore* store = gtk_list_store_new(1, GDK_TYPE_PIXBUF);
++    GdkCursor* cursor;
++    GdkCursorType types[] = {
++        GDK_LEFT_PTR,
++        GDK_HAND2,
++        GDK_WATCH,
++        GDK_FLEUR,
++        GDK_XTERM,
++        GDK_LEFT_SIDE,
++        GDK_TOP_LEFT_CORNER,
++        GDK_SB_H_DOUBLE_ARROW};
++    int i, n;
++    for(i = 0; i < G_N_ELEMENTS(types); ++i)
++    {
++        GtkTreeIter it;
++        cursor = gdk_cursor_new(types[i]);
++        GdkPixbuf* pix = gdk_cursor_get_image(cursor);
++        gdk_cursor_unref(cursor);
++        gtk_list_store_insert_with_values(store, &it, -1, 0, pix, -1);
++        g_object_unref(pix);
++    }
++    gtk_icon_view_set_model(GTK_ICON_VIEW(app.cursor_demo_view), GTK_TREE_MODEL(store));
++    g_object_unref(store);
++
++    /* gtk+ programs should reload named cursors correctly.
++     * However, if the cursor is inherited from the root window,
++     * gtk+ won't change it. So we need to update the cursor of root window.
++     * Unfortunately, this doesn't work for non-gtk+ programs.
++     * KDE programs seem to require special handling with XFixes */
++    cursor = gdk_cursor_new(GDK_LEFT_PTR);
++    i = gdk_display_get_n_screens(gdk_display_get_default());
++    while(--i >= 0)
++    {
++        GdkScreen* screen = gdk_display_get_screen(gdk_display_get_default(), i);
++        gdk_window_set_cursor(gdk_screen_get_root_window(screen), cursor);
++    }
++    gdk_cursor_unref(cursor);
++}
++
++static void on_cursor_theme_sel_changed(GtkTreeSelection* tree_sel, gpointer user_data)
++{
++    GtkTreeModel* model;
++    GtkTreeIter it;
++    if(gtk_tree_selection_get_selected(tree_sel, &model, &it))
++    {
++        IconTheme* theme;
++        gtk_tree_model_get(model, &it, 1, &theme, -1);
++        if(g_strcmp0(theme->name, app.cursor_theme))
++        {
++            g_free(app.cursor_theme);
++            app.cursor_theme = g_strdup(theme->name);
++            g_object_set(gtk_settings_get_default(), "gtk-cursor-theme-name", app.cursor_theme, NULL);
++
++            update_cursor_demo();
++            lxappearance_changed();
++        }
++
++        gtk_widget_set_sensitive(app.cursor_theme_remove_btn, theme->is_removable);
++    }
++}
++
++static void on_cursor_theme_size_changed(GtkRange* range, gpointer user_data)
++{
++    int size = (int)gtk_range_get_value(range);
++    if(size != app.cursor_theme_size)
++    {
++        app.cursor_theme_size = size;
++        g_object_set(gtk_settings_get_default(), "gtk-cursor-theme-size", size, NULL);
++
++        update_cursor_demo();
++        lxappearance_changed();
++    }
++}
++
++void cursor_theme_init(GtkBuilder* b)
++{
++    int max_cursor_w, max_cursor_h, max_size;
++    GtkTreeSelection* sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(app.cursor_theme_view));
++    /* treeview and model are already set up in icon_theme_init() */
++    g_signal_connect(sel, "changed", G_CALLBACK(on_cursor_theme_sel_changed), NULL);
++
++    gdk_display_get_maximal_cursor_size(gdk_display_get_default(), &max_cursor_w, &max_cursor_h);
++    max_size = MAX(max_cursor_w, max_cursor_h);
++
++    /* FIXME: this isn't fully working... */
++    app.cursor_size_range = GTK_WIDGET(gtk_builder_get_object(b, "cursor_size"));
++    if(max_size < 128)
++        gtk_range_set_range(GTK_RANGE(app.cursor_size_range), 1, max_size + 10); /* 10 is page size */
++    gtk_range_set_value(GTK_RANGE(app.cursor_size_range), app.cursor_theme_size);
++    g_signal_connect(app.cursor_size_range, "value-changed", G_CALLBACK(on_cursor_theme_size_changed), NULL);
++
++    /* set up demo for cursors */
++    app.cursor_demo_view = GTK_WIDGET(gtk_builder_get_object(b, "cursor_demo_view"));
++    gtk_icon_view_set_pixbuf_column(GTK_ICON_VIEW(app.cursor_demo_view), 0);
++    update_cursor_demo();
++
++    /* install and remove */
++    /* this part is already done in icon-theme.c */
++}
+diff --git a/src/cursor-theme.h b/src/cursor-theme.h
+new file mode 100644
+index 0000000..5d5c567
+--- /dev/null
++++ b/src/cursor-theme.h
+@@ -0,0 +1,33 @@
++/*
++ *      cursor-theme.h
++ *
++ *      Copyright 2010 PCMan <pcman.tw@gmail.com>
++ *
++ *      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., 51 Franklin Street, Fifth Floor, Boston,
++ *      MA 02110-1301, USA.
++ */
++
++#ifndef _CURSOR_THEME_H_
++#define _CURSOR_THEME_H_
++
++#include <gtk/gtk.h>
++
++G_BEGIN_DECLS
++
++void cursor_theme_init(GtkBuilder* b);
++
++G_END_DECLS
++
++#endif
+diff --git a/src/icon-theme.c b/src/icon-theme.c
+new file mode 100644
+index 0000000..396c00b
+--- /dev/null
++++ b/src/icon-theme.c
+@@ -0,0 +1,304 @@
++/*
++ *      icon-theme.c
++ *
++ *      Copyright 2010 PCMan <pcman.tw@gmail.com>
++ *
++ *      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., 51 Franklin Street, Fifth Floor, Boston,
++ *      MA 02110-1301, USA.
++ */
++
++#include "icon-theme.h"
++#include "lxappearance.h"
++#include <string.h>
++#include <unistd.h>
++#include "utils.h"
++
++char** icon_theme_dirs = NULL;
++
++gint icon_theme_cmp_name(IconTheme* t, const char* name)
++{
++    return strcmp(t->name, name);
++}
++
++gint icon_theme_cmp_disp_name(IconTheme* t1, IconTheme* t2)
++{
++    return g_utf8_collate(t1->disp_name, t2->disp_name);
++}
++
++static void icon_theme_free(IconTheme* theme)
++{
++    g_free(theme->comment);
++    g_free(theme->name);
++    if(theme->disp_name != theme->name)
++        g_free(theme->disp_name);
++    g_slice_free(IconTheme, theme);
++}
++
++void load_icon_themes_from_dir(const char* base_dir, const char* theme_dir, GKeyFile* kf)
++{
++    /* NOTE:
++     * 1. theoratically, base_dir is identical to theme_dir
++     * the only case that they are different is when we try to install
++     * a new theme. icon themes in a temporary theme dir may later be
++     * installed to base_dir, and we load it from temp. theme dir
++     * before installation. So theme_dir is the temporary dir containing
++     * the themes to install. base_dir is the destination directory to be
++     * installed to.
++     * 2. base_dir is actually a component of global variable icon_theme_dirs.
++     * so it's safe to use this string without strdup() since its life
++     * span is the same as the whole program and won't be freed. */
++
++    GDir* dir = g_dir_open(theme_dir, 0, NULL);
++    if(dir)
++    {
++        const char* name;
++        while(name = g_dir_read_name(dir))
++        {
++            /* skip "default" */
++            if(G_UNLIKELY(strcmp(name, "default") == 0))
++                continue;
++            /* test if we already have this in list */
++            if(!g_slist_find_custom(app.icon_themes, name, (GCompareFunc)icon_theme_cmp_name))
++            {
++                IconTheme* theme = g_slice_new0(IconTheme);
++                char* index_theme;
++                char* cursor_subdir;
++
++                theme->name = g_strdup(name);
++                index_theme = g_build_filename(theme_dir, name, "index.theme", NULL);
++                theme->base_dir = base_dir;
++                theme->is_removable = (0 == access(base_dir, W_OK));
++
++                if(g_key_file_load_from_file(kf, index_theme, 0, NULL))
++                {
++                    /* skip hidden ones */
++                    if(!g_key_file_get_boolean(kf, "Icon Theme", "Hidden", NULL))
++                    {
++                        theme->disp_name = g_key_file_get_locale_string(kf, "Icon Theme", "Name", NULL, NULL);
++                        /* test if this is a icon theme or it's a cursor theme */
++                        theme->comment = g_key_file_get_locale_string(kf, "Icon Theme", "Comment", NULL, NULL);
++
++                        /* icon theme must have this key, so it has icons if it has this key */
++                        theme->has_icon = g_key_file_has_key(kf, "Icon Theme", "Directories", NULL);
++                    }
++                }
++                else
++                    theme->disp_name = theme->name;
++                g_free(index_theme);
++
++                cursor_subdir = g_build_filename(theme_dir, name, "cursors", NULL);
++                /* it contains a cursor theme */
++                if(g_file_test(cursor_subdir, G_FILE_TEST_IS_DIR))
++                    theme->has_cursor = TRUE;
++                g_free(cursor_subdir);
++
++                if(theme->has_icon || theme->has_cursor)
++                    app.icon_themes = g_slist_insert_sorted(app.icon_themes, theme,
++                                            (GCompareFunc)icon_theme_cmp_disp_name);
++                else /* this dir contains no icon or cursor theme, drop it. */
++                    icon_theme_free(theme);
++            }
++        }
++        g_dir_close(dir);
++    }
++}
++
++static void load_icon_themes()
++{
++    int n, i;
++    gtk_icon_theme_get_search_path(gtk_icon_theme_get_default(), &icon_theme_dirs, &n);
++    GKeyFile* kf = g_key_file_new();
++    for(i = 0; i < n; ++i)
++    {
++        load_icon_themes_from_dir(icon_theme_dirs[i], icon_theme_dirs[i], kf);
++        /* g_debug("icon_theme_dirs[%d] = %s", i, icon_theme_dirs[i]); */
++    }
++    g_key_file_free(kf);
++}
++
++
++static void on_icon_theme_sel_changed(GtkTreeSelection* tree_sel, gpointer user_data)
++{
++    GtkTreeModel* model;
++    GtkTreeIter it;
++    if(gtk_tree_selection_get_selected(tree_sel, &model, &it))
++    {
++        IconTheme* theme;
++        gtk_tree_model_get(model, &it, 1, &theme, -1);
++        if(g_strcmp0(theme->name, app.icon_theme))
++        {
++            g_free(app.icon_theme);
++            app.icon_theme = g_strdup(theme->name);
++            g_object_set(gtk_settings_get_default(), "gtk-icon-theme-name", app.icon_theme, NULL);
++
++            lxappearance_changed();
++        }
++
++        gtk_widget_set_sensitive(app.icon_theme_remove_btn, theme->is_removable);
++    }
++}
++
++static void on_install_theme_clicked(GtkButton* btn, gpointer user_data)
++{
++    install_icon_theme(GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(btn))));
++}
++
++static void on_remove_theme_clicked(GtkButton* btn, gpointer user_data)
++{
++    char* theme_name;
++    GtkTreeSelection* sel;
++    GtkTreeModel* model;
++    GtkTreeIter it;
++
++    if(btn == (GtkButton*)app.icon_theme_remove_btn) /* remove icon theme */
++        sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(app.icon_theme_view));
++    else if(btn == (GtkButton*)app.cursor_theme_remove_btn) /* remove cursor theme */
++        sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(app.cursor_theme_view));
++    else
++        return;
++
++    if(gtk_tree_selection_get_selected(sel, &model, &it))
++    {
++        IconTheme* theme;
++        gboolean both = theme->has_icon && theme->has_cursor;
++
++        if(gtk_tree_model_iter_n_children(model, NULL) < 2)
++        {
++            /* FIXME: the user shouldn't remove the last available theme.
++             * another list needs to be checked, too. */
++            return;
++        }
++
++        gtk_tree_model_get(model, &it, 1, &theme, -1);
++        if(remove_icon_theme(GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(btn))), theme))
++        {
++            gtk_list_store_remove(GTK_LIST_STORE(model), &it);
++
++            /* select the first theme */
++            gtk_tree_model_get_iter_first(model, &it);
++            gtk_tree_selection_select_iter(sel, &it);
++
++            /* FIXME: in rare case, a theme can contain both icons and cursors */
++            if(both) /* we need to remove item in another list store, too */
++            {
++                model = GTK_TREE_MODEL(model == (GtkTreeModel*)app.icon_theme_store ? app.cursor_theme_store : app.icon_theme_store);
++                /* find the item in another store */
++                if(gtk_tree_model_get_iter_first(model, &it))
++                {
++                    IconTheme* theme2;
++                    do
++                    {
++                        gtk_tree_model_get(model, &it, 1, &theme2, -1);
++                        if(theme2 == theme)
++                        {
++                            gtk_list_store_remove(GTK_LIST_STORE(model), &it);
++                            /* select the first theme */
++                            gtk_tree_model_get_iter_first(model, &it);
++                            gtk_tree_selection_select_iter(sel, &it);
++                            break;
++                        }
++                    }while(gtk_tree_model_iter_next(model, &it));
++                }
++            }
++        }
++    }
++}
++
++void icon_theme_init(GtkBuilder* b)
++{
++    GSList* l;
++    GtkTreeIter it;
++    GtkTreeIter icon_theme_sel_it = {0};
++    GtkTreeIter cursor_theme_sel_it = {0};
++    GtkTreeSelection* sel;
++    GtkWidget* btn;
++
++    app.icon_theme_store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_POINTER);
++    app.cursor_theme_store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_POINTER);
++    app.icon_theme_view = GTK_WIDGET(gtk_builder_get_object(b, "icon_theme_view"));
++    app.cursor_theme_view = GTK_WIDGET(gtk_builder_get_object(b, "cursor_theme_view"));
++
++    /* install icon and cursor theme */
++    btn = GTK_WIDGET(gtk_builder_get_object(b, "install_icon_theme"));
++    g_signal_connect(btn, "clicked", G_CALLBACK(on_install_theme_clicked), NULL);
++
++    btn = GTK_WIDGET(gtk_builder_get_object(b, "install_cursor_theme"));
++    g_signal_connect(btn, "clicked", G_CALLBACK(on_install_theme_clicked), NULL);
++
++    /* remove icon theme */
++    app.icon_theme_remove_btn = GTK_WIDGET(gtk_builder_get_object(b, "remove_icon_theme"));
++    g_signal_connect(app.icon_theme_remove_btn, "clicked", G_CALLBACK(on_remove_theme_clicked), NULL);
++
++    app.cursor_theme_remove_btn = GTK_WIDGET(gtk_builder_get_object(b, "remove_cursor_theme"));
++    g_signal_connect(app.cursor_theme_remove_btn, "clicked", G_CALLBACK(on_remove_theme_clicked), NULL);
++
++    /* load icon and cursor themes */
++    load_icon_themes();
++
++    for(l = app.icon_themes; l; l=l->next)
++    {
++        IconTheme* theme = (IconTheme*)l->data;
++
++        if(theme->has_icon)
++        {
++            gtk_list_store_insert_with_values(app.icon_theme_store, &it, -1, 0, theme->disp_name, 1, theme, -1);
++            if(!icon_theme_sel_it.user_data)
++            {
++                if(strcmp(theme->name, app.icon_theme) == 0)
++                    icon_theme_sel_it = it;
++            }
++        }
++
++        if(theme->has_cursor)
++        {
++            gtk_list_store_insert_with_values(app.cursor_theme_store, &it, -1, 0, theme->disp_name, 1, theme, -1);
++            if(!cursor_theme_sel_it.user_data)
++            {
++                if(g_strcmp0(theme->name, app.cursor_theme) == 0)
++                    cursor_theme_sel_it = it;
++            }
++        }
++    }
++
++    /* select the currently used theme from the list */
++    gtk_tree_view_set_model(GTK_TREE_VIEW(app.icon_theme_view), GTK_TREE_MODEL(app.icon_theme_store));
++    sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(app.icon_theme_view));
++    if(icon_theme_sel_it.user_data)
++    {
++        IconTheme* theme;
++        GtkTreePath* tp = gtk_tree_model_get_path(GTK_TREE_MODEL(app.icon_theme_store), &icon_theme_sel_it);
++        gtk_tree_selection_select_iter(sel, &icon_theme_sel_it);
++        gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(app.icon_theme_view), tp, NULL, FALSE, 0, 0);
++        gtk_tree_path_free(tp);
++
++        gtk_tree_model_get(GTK_TREE_MODEL(app.icon_theme_store), &icon_theme_sel_it, 1, &theme, -1);
++        gtk_widget_set_sensitive(app.icon_theme_remove_btn, theme->is_removable);
++    }
++    g_signal_connect(sel, "changed", G_CALLBACK(on_icon_theme_sel_changed), NULL);
++
++    gtk_tree_view_set_model(GTK_TREE_VIEW(app.cursor_theme_view), GTK_TREE_MODEL(app.cursor_theme_store));
++    sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(app.cursor_theme_view));
++    if(cursor_theme_sel_it.user_data)
++    {
++        IconTheme* theme;
++        GtkTreePath* tp = gtk_tree_model_get_path(GTK_TREE_MODEL(app.cursor_theme_store), &cursor_theme_sel_it);
++        gtk_tree_selection_select_iter(sel, &cursor_theme_sel_it);
++        gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(app.cursor_theme_view), tp, NULL, FALSE, 0, 0);
++        gtk_tree_path_free(tp);
++
++        gtk_tree_model_get(GTK_TREE_MODEL(app.cursor_theme_store), &cursor_theme_sel_it, 1, &theme, -1);
++        gtk_widget_set_sensitive(app.cursor_theme_remove_btn, theme->is_removable);
++    }
++}
+diff --git a/src/icon-theme.h b/src/icon-theme.h
+new file mode 100644
+index 0000000..46ab1d7
+--- /dev/null
++++ b/src/icon-theme.h
+@@ -0,0 +1,50 @@
++/*
++ *      icon-theme.h
++ *
++ *      Copyright 2010 PCMan <pcman.tw@gmail.com>
++ *
++ *      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., 51 Franklin Street, Fifth Floor, Boston,
++ *      MA 02110-1301, USA.
++ */
++
++#ifndef _ICON_THEME_H_
++#define _ICON_THEME_H_
++
++#include <gtk/gtk.h>
++
++G_BEGIN_DECLS
++
++extern char** icon_theme_dirs;
++
++typedef struct
++{
++    char* name;
++    char* disp_name;
++    char* comment;
++    const char* base_dir;
++    gboolean has_icon : 1;
++    gboolean has_cursor : 1;
++    gboolean is_removable : 1;
++}IconTheme;
++
++void icon_theme_init(GtkBuilder* b);
++void load_icon_themes_from_dir(const char* base_dir, const char* theme_dir, GKeyFile* kf);
++
++gint icon_theme_cmp_name(IconTheme* t, const char* name);
++gint icon_theme_cmp_disp_name(IconTheme* t1, IconTheme* t2);
++
++G_END_DECLS
++
++#endif
+diff --git a/src/lxappearance.c b/src/lxappearance.c
+new file mode 100644
+index 0000000..a98855e
+--- /dev/null
++++ b/src/lxappearance.c
+@@ -0,0 +1,432 @@
++/*
++ *      lxappearance.c
++ *
++ *      Copyright 2010 PCMan <pcman.tw@gmail.com>
++ *
++ *      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., 51 Franklin Street, Fifth Floor, Boston,
++ *      MA 02110-1301, USA.
++ */
++
++#ifdef HAVE_CONFIG_H
++#include <config.h>
++#endif
++
++#include "lxappearance.h"
++
++#include <gtk/gtk.h>
++#include <glib/gi18n.h>
++
++#include <X11/X.h>
++#include <X11/Xatom.h>
++#include <X11/Xlib.h>
++#include <gdk/gdkx.h>
++#include <string.h>
++
++#include "widget-theme.h"
++#include "color-scheme.h"
++#include "icon-theme.h"
++#include "cursor-theme.h"
++#include "other.h"
++#include "plugin.h"
++
++LXAppearance app = {0};
++
++Atom lxsession_atom = 0;
++static const char* lxsession_name = NULL;
++
++static void check_lxsession()
++{
++    lxsession_atom = XInternAtom( GDK_DISPLAY(), "_LXSESSION", True );
++    if( lxsession_atom != None )
++    {
++        XGrabServer( GDK_DISPLAY() );
++        if( XGetSelectionOwner( GDK_DISPLAY(), lxsession_atom ) )
++        {
++            app.use_lxsession = TRUE;
++            lxsession_name = g_getenv("DESKTOP_SESSION");
++        }
++        XUngrabServer( GDK_DISPLAY() );
++    }
++}
++
++static GOptionEntry option_entries[] =
++{
++    { NULL }
++};
++
++static void save_cursor_theme_name()
++{
++    char* dir_path;
++    if(!app.cursor_theme || !g_strcmp0(app.cursor_theme, "default"))
++        return;
++
++    dir_path = g_build_filename(g_get_home_dir(), ".icons/default", NULL);
++    if(0 == g_mkdir_with_parents(dir_path, 0700))
++    {
++        char* index_theme = g_build_filename(dir_path, "index.theme", NULL);
++        char* content = g_strdup_printf(
++            "# This file is written by LXAppearance. Do not edit."
++            "[Icon Theme]\n"
++            "Name=Default\n"
++            "Comment=Default Cursor Theme\n"
++            "Inherits=%s\n", app.cursor_theme);
++        g_file_set_contents(index_theme, content, -1, NULL);
++        g_free(content);
++        g_free(index_theme);
++    }
++    g_free(dir_path);
++
++    /*
++    dir_path = g_build_filename(g_get_home_dir(), ".Xdefaults", NULL);
++    Xcursor.theme: name
++    Xcursor.size: [size]
++    g_file_set_contents(dir_path, "", -1, NULL);
++    g_free(dir_path);
++    */
++}
++
++static void reload_all_programs()
++{
++    GdkEventClient event;
++    event.type = GDK_CLIENT_EVENT;
++    event.send_event = TRUE;
++    event.window = NULL;
++
++    if( app.use_lxsession )
++    {
++        event.message_type = gdk_atom_intern_static_string("_LXSESSION");
++        event.data.b[0] = 0;    /* LXS_RELOAD */
++    }
++    else
++    {
++        /* if( icon_only )
++            event.message_type = gdk_atom_intern("_GTK_LOAD_ICONTHEMES", FALSE);
++        */
++        event.message_type = gdk_atom_intern("_GTK_READ_RCFILES", FALSE);
++    }
++    event.data_format = 8;
++    gdk_event_send_clientmessage_toall((GdkEvent *)&event);
++}
++
++static const char* bool2str(gboolean val)
++{
++    return val ? "TRUE" : "FALSE";
++}
++
++static void lxappearance_save_gtkrc()
++{
++    static const char* tb_styles[]={
++        "GTK_TOOLBAR_ICONS",
++        "GTK_TOOLBAR_TEXT",
++        "GTK_TOOLBAR_BOTH",
++        "GTK_TOOLBAR_BOTH_HORIZ"
++    };
++    static const char* tb_icon_sizes[]={
++        "GTK_ICON_SIZE_INVALID",
++        "GTK_ICON_SIZE_MENU",
++        "GTK_ICON_SIZE_SMALL_TOOLBAR",
++        "GTK_ICON_SIZE_LARGE_TOOLBAR",
++        "GTK_ICON_SIZE_BUTTON",
++        "GTK_ICON_SIZE_DND",
++        "GTK_ICON_SIZE_DIALOG"
++    };
++
++    char* file_path = g_build_filename(g_get_home_dir(), ".gtkrc-2.0", NULL);
++    GString* content = g_string_sized_new(512);
++    g_string_append_printf(content,
++        "# DO NOT EDIT! This file will be overwritten by LXAppearance.\n"
++        "# Any customization should be done in ~/.gtkrc-2.0.mine instead.\n\n"
++        "gtk-theme-name=\"%s\"\n"
++        "gtk-icon-theme-name=\"%s\"\n"
++        "gtk-font-name=\"%s\"\n"
++        "gtk-toolbar-style=%s\n"
++        "gtk-toolbar-icon-size=%s\n"
++        "gtk-cursor-theme-name=\"%s\"\n"
++        "gtk-cursor-theme-size=%d\n"
++        "gtk-button-images=%s\n"
++        "gtk-menu-images=%s\n"
++#if GTK_CHECK_VERSION(2, 14, 0)
++        "gtk-enable-event-sounds=%s\n"
++        "gtk-enable-input-feedback-sounds=%s\n",
++#endif
++        app.widget_theme,
++        app.icon_theme,
++        app.default_font,
++        tb_styles[app.toolbar_style],
++        tb_icon_sizes[app.toolbar_icon_size],
++        app.cursor_theme,
++        app.cursor_theme_size,
++        bool2str(app.button_images),
++        bool2str(app.menu_images),
++#if GTK_CHECK_VERSION(2, 14, 0)
++        bool2str(app.enable_event_sound),
++        bool2str(app.enable_input_feedback)
++#endif
++        );
++
++    if(app.color_scheme)
++    {
++        char* escaped = g_strescape(app.color_scheme, NULL);
++        g_string_append_printf(content,
++            "gtk-color-scheme=\"\"\n",
++            escaped);
++        g_free(escaped);
++    }
++
++    g_string_append_printf(content,
++        "include \"%s/.gtkrc-2.0.mine\"\n",
++        g_get_home_dir());
++
++    g_file_set_contents(file_path, content->str, content->len, NULL);
++    g_string_free(content, TRUE);
++    g_free(file_path);
++}
++
++static void lxappearance_save_lxsession()
++{
++    char* rel_path = g_strconcat("lxsession/", lxsession_name, "/desktop.conf", NULL);
++    char* user_config_file = g_build_filename(g_get_user_config_dir(), rel_path, NULL);
++    char* buf;
++    int len;
++    GKeyFile* kf = g_key_file_new();
++
++    if(!g_key_file_load_from_file(kf, user_config_file, G_KEY_FILE_KEEP_COMMENTS|G_KEY_FILE_KEEP_TRANSLATIONS, NULL))
++    {
++        /* the user config file doesn't exist, create its parent dir */
++        len = strlen(user_config_file) - strlen("/desktop.conf");
++        user_config_file[len] = '\0';
++        g_debug("user_config_file = %s", user_config_file);
++        g_mkdir_with_parents(user_config_file, 0700);
++        user_config_file[len] = '/';
++
++        g_key_file_load_from_dirs(kf, rel_path, (const char**)g_get_system_config_dirs(), NULL,
++                                  G_KEY_FILE_KEEP_COMMENTS|G_KEY_FILE_KEEP_TRANSLATIONS, NULL);
++    }
++
++    g_free(rel_path);
++
++    g_key_file_set_string( kf, "GTK", "sNet/ThemeName", app.widget_theme );
++    g_key_file_set_string( kf, "GTK", "sGtk/FontName", app.default_font );
++
++    g_key_file_set_string( kf, "GTK", "sGtk/ColorScheme", app.color_scheme ? app.color_scheme : "" );
++
++    g_key_file_set_string( kf, "GTK", "sNet/IconThemeName", app.icon_theme );
++
++    g_key_file_set_string( kf, "GTK", "sGtk/CursorThemeName", app.cursor_theme );
++    g_key_file_set_integer( kf, "GTK", "iGtk/CursorThemeSize", app.cursor_theme_size );
++    save_cursor_theme_name();
++
++    g_key_file_set_integer( kf, "GTK", "iGtk/ToolbarStyle", app.toolbar_style );
++    g_key_file_set_integer( kf, "GTK", "iGtk/ToolbarIconSize", app.toolbar_icon_size );
++
++    g_key_file_set_integer( kf, "GTK", "iGtk/ToolbarStyle", app.toolbar_style );
++    g_key_file_set_integer( kf, "GTK", "iGtk/ToolbarIconSize", app.toolbar_icon_size );
++
++    g_key_file_set_integer( kf, "GTK", "iGtk/ButtonImages", app.button_images );
++    g_key_file_set_integer( kf, "GTK", "iGtk/MenuImages", app.menu_images );
++
++#if GTK_CHECK_VERSION(2, 14, 0)
++    /* "Net/SoundThemeName\0"      "gtk-sound-theme-name\0" */
++    g_key_file_set_integer( kf, "GTK", "iNet/EnableEventSounds", app.enable_event_sound);
++    g_key_file_set_integer( kf, "GTK", "iNet/EnableInputFeedbackSounds", app.enable_input_feedback);
++#endif
++
++    buf = g_key_file_to_data( kf, &len, NULL );
++    g_key_file_free(kf);
++
++    g_file_set_contents(user_config_file, buf, len, NULL);
++    g_free(buf);
++    g_free(user_config_file);
++}
++
++static void on_dlg_response(GtkDialog* dlg, int res, gpointer user_data)
++{
++    switch(res)
++    {
++    case GTK_RESPONSE_APPLY:
++
++        if(app.use_lxsession)
++            lxappearance_save_lxsession();
++        else
++            lxappearance_save_gtkrc();
++
++        reload_all_programs();
++
++        app.changed = FALSE;
++        gtk_dialog_set_response_sensitive(GTK_DIALOG(app.dlg), GTK_RESPONSE_APPLY, FALSE);
++        break;
++    case 1: /* about dialog */
++        {
++            GtkBuilder* b = gtk_builder_new();
++            if(gtk_builder_add_from_file(b, PACKAGE_UI_DIR "/about.ui", NULL))
++            {
++                GtkWidget* dlg = GTK_WIDGET(gtk_builder_get_object(b, "dlg"));
++                gtk_dialog_run(GTK_DIALOG(dlg));
++                gtk_widget_destroy(dlg);
++            }
++            g_object_unref(b);
++        }
++        break;
++    default:
++        gtk_main_quit();
++    }
++}
++
++static void settings_init()
++{
++    GtkSettings* settings = gtk_settings_get_default();
++    g_object_get(settings,
++                "gtk-theme-name", &app.widget_theme,
++                "gtk-font-name", &app.default_font,
++                "gtk-icon-theme-name", &app.icon_theme,
++                "gtk-cursor-theme-name", &app.cursor_theme,
++                "gtk-cursor-theme-size", &app.cursor_theme_size,
++                "gtk-toolbar-style", &app.toolbar_style,
++                "gtk-toolbar-icon-size", &app.toolbar_icon_size,
++                "gtk-button-images", &app.button_images,
++                "gtk-menu-images", &app.menu_images,
++#if GTK_CHECK_VERSION(2, 14, 0)
++                "gtk-enable-event-sounds", &app.enable_event_sound,
++                "gtk-enable-input-feedback-sounds", &app.enable_input_feedback,
++#endif
++                NULL);
++    /* try to figure out cursor theme used. */
++    if(!app.cursor_theme || g_strcmp0(app.cursor_theme, "default") == 0)
++    {
++        /* get the real theme name from default. */
++        GKeyFile* kf = g_key_file_new();
++        char* fpath = g_build_filename(g_get_home_dir(), ".icons/default/index.theme", NULL);
++        gboolean ret = g_key_file_load_from_file(kf, fpath, 0, NULL);
++        g_free(fpath);
++
++        if(!ret)
++            ret = g_key_file_load_from_data_dirs(kf, "icons/default/index.theme", NULL, 0, NULL);
++
++        if(ret)
++        {
++            g_free(app.cursor_theme);
++            app.cursor_theme = g_key_file_get_string(kf, "Icon Theme", "Inherits", NULL);
++            g_debug("cursor theme name: %s", app.cursor_theme);
++        }
++        g_key_file_free(kf);
++    }
++
++    app.color_scheme_hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
++    /* try to load custom color scheme if available */
++    if(app.use_lxsession)
++    {
++        char* rel_path = g_strconcat("lxsession/", lxsession_name, "/desktop.conf", NULL);
++        char* user_config_file = g_build_filename(g_get_user_config_dir(), rel_path, NULL);
++        GKeyFile* kf = g_key_file_new();
++        if(g_key_file_load_from_file(kf, user_config_file, 0, NULL))
++            app.color_scheme = g_key_file_get_string(kf, "GTK", "sGtk/ColorScheme", NULL);
++        else if(g_key_file_load_from_dirs(kf, rel_path, (const char**)g_get_system_config_dirs(), NULL, 0, NULL))
++            app.color_scheme = g_key_file_get_string(kf, "GTK", "sGtk/ColorScheme", NULL);
++        g_key_file_free(kf);
++        g_free(rel_path);
++        g_free(user_config_file);
++
++        if(app.color_scheme)
++        {
++            if(*app.color_scheme)
++                color_scheme_str_to_hash(app.color_scheme_hash, app.color_scheme);
++            else
++            {
++                g_free(app.color_scheme);
++                app.color_scheme = NULL;
++            }
++        }
++    }
++    else
++    {
++        char* gtkrc_file = g_build_filename(g_get_home_dir(), ".gtkrc-2.0", NULL);
++        gtkrc_file_get_color_scheme(gtkrc_file, app.color_scheme_hash);
++        g_free(gtkrc_file);
++        if(g_hash_table_size(app.color_scheme_hash) > 0)
++            app.color_scheme = color_scheme_hash_to_str(app.color_scheme_hash);
++    }
++}
++
++int main(int argc, char** argv)
++{
++    GError* err = NULL;
++    GtkBuilder* b;
++
++    /* gettext support */
++#ifdef ENABLE_NLS
++    bindtextdomain ( GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR );
++    bind_textdomain_codeset ( GETTEXT_PACKAGE, "UTF-8" );
++    textdomain ( GETTEXT_PACKAGE );
++#endif
++
++    g_thread_init(NULL);
++    /* initialize GTK+ and parse the command line arguments */
++    if( G_UNLIKELY( ! gtk_init_with_args( &argc, &argv, "", option_entries, GETTEXT_PACKAGE, &err ) ) )
++    {
++        g_print( "Error: %s\n", err->message );
++        return 1;
++    }
++
++    app.abi_version = LXAPPEARANCE_ABI_VERSION;
++
++    /* check if we're under LXSession */
++    check_lxsession();
++
++    /* create GUI here */
++    b = gtk_builder_new();
++    if(!gtk_builder_add_from_file(b, PACKAGE_UI_DIR "/lxappearance.ui", NULL))
++        return 1;
++
++    /* NOTE: GUI must be created prior to loading settings from GtkSettings object.
++     * Some properties of GtkSettings class are installed by some other gtk classes.
++     * For example, "gtk-menu-images" property is actually installed by initialization
++     * of GtkImageMenuItem class. If we load the GUI first, then when the menu items
++     * are created, this property gets correctly registered. So later it can be read. */
++
++    /* load config values */
++    settings_init();
++
++    app.dlg = GTK_WIDGET(gtk_builder_get_object(b, "dlg"));
++
++    widget_theme_init(b);
++    color_scheme_init(b);
++    icon_theme_init(b);
++    cursor_theme_init(b);
++    other_init(b);
++    /* the page for window manager plugins */
++    app.wm_page = GTK_WIDGET(gtk_builder_get_object(b, "wm_page"));
++
++    plugins_init(b);
++
++    g_signal_connect(app.dlg, "response", G_CALLBACK(on_dlg_response), NULL);
++
++    gtk_window_present(GTK_WINDOW(app.dlg));
++    g_object_unref(b);
++
++    gtk_main();
++
++    plugins_finalize();
++
++    return 0;
++}
++
++void lxappearance_changed()
++{
++    if(!app.changed)
++    {
++        app.changed = TRUE;
++        gtk_dialog_set_response_sensitive(GTK_DIALOG(app.dlg), GTK_RESPONSE_APPLY, TRUE);
++    }
++}
+diff --git a/src/lxappearance.h b/src/lxappearance.h
+new file mode 100644
+index 0000000..38542ae
+--- /dev/null
++++ b/src/lxappearance.h
+@@ -0,0 +1,102 @@
++/*
++ *      lxappearance.h
++ *
++ *      Copyright 2010 PCMan <pcman.tw@gmail.com>
++ *
++ *      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., 51 Franklin Street, Fifth Floor, Boston,
++ *      MA 02110-1301, USA.
++ */
++
++#ifndef _LXAPPEARANCE_H_
++#define _LXAPPEARANCE_H_
++
++#include <gtk/gtk.h>
++
++#define LXAPPEARANCE_ABI_VERSION    1
++
++typedef struct _LXAppearance    LXAppearance;
++struct _LXAppearance
++{
++    guint32 abi_version;
++    GtkWidget* dlg;
++    GtkWidget* notebook;
++
++    /* gtk theme */
++    GtkWidget* widget_theme_view;
++    GtkListStore* widget_theme_store;
++    GtkWidget* default_font_btn;
++
++    /* color scheme */
++    GtkWidget* color_table;
++    GtkWidget* custom_colors;
++    GtkWidget* no_custom_colors;
++    GHashTable* color_scheme_hash; /* the custom color scheme set by the user */
++    GHashTable* default_color_scheme_hash; /* default colors of current gtk theme */
++    gboolean color_scheme_supported; /* if color scheme is supported by current gtk theme */
++    /* color buttons in color scheme page. */
++    GtkWidget* color_btns[8]; /* FIXME: this value might be changed in the future */
++
++    /* icon theme */
++    GtkWidget* icon_theme_view;
++    GtkListStore* icon_theme_store;
++    GtkWidget* icon_theme_remove_btn;
++
++    /* cursor theme */
++    GtkWidget* cursor_theme_view;
++    GtkWidget* cursor_demo_view;
++    GtkListStore* cursor_theme_store;
++    GtkWidget* cursor_size_range;
++    GtkWidget* cursor_theme_remove_btn;
++
++    GSList* icon_themes; /* a list of IconTheme struct representing all icon and cursor themes */
++
++    /* toolbar style and icon size */
++    GtkWidget* tb_style_combo;
++    GtkWidget* tb_icon_size_combo;
++
++    GtkWidget* button_images_check;
++    GtkWidget* menu_images_check;
++
++    /* the page for window manager plugins */
++    GtkWidget* wm_page;
++
++    char* widget_theme;
++    char* default_font;
++    char* icon_theme;
++    char* cursor_theme;
++    int cursor_theme_size;
++    char* color_scheme;
++    int toolbar_style;
++    int toolbar_icon_size;
++
++    gboolean button_images;
++    gboolean menu_images;
++
++#if GTK_CHECK_VERSION(2, 14, 0)
++    GtkWidget* event_sound_check;
++    GtkWidget* input_feedback_check;
++    gboolean enable_event_sound;
++    gboolean enable_input_feedback;
++#endif
++
++    gboolean changed;
++    gboolean use_lxsession;
++};
++
++extern LXAppearance app;
++
++void lxappearance_changed();
++
++#endif
+diff --git a/src/other.c b/src/other.c
+new file mode 100644
+index 0000000..d0ac12e
+--- /dev/null
++++ b/src/other.c
+@@ -0,0 +1,82 @@
++//      other.c
++//
++//      Copyright 2010 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
++//
++//      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., 51 Franklin Street, Fifth Floor, Boston,
++//      MA 02110-1301, USA.
++
++
++#include "lxappearance.h"
++#include "other.h"
++#include <glib/gi18n.h>
++
++static void on_tb_style_changed(GtkComboBox* combo, gpointer user_data)
++{
++    app.toolbar_style = gtk_combo_box_get_active(combo) + GTK_TOOLBAR_ICONS;
++    lxappearance_changed();
++}
++
++static void on_tb_icon_size_changed(GtkComboBox* combo, gpointer user_data)
++{
++    app.toolbar_icon_size = gtk_combo_box_get_active(combo) + GTK_ICON_SIZE_MENU;
++    lxappearance_changed();
++}
++
++static void on_check_button_toggled(GtkToggleButton* btn, gpointer user_data)
++{
++    gboolean* val = (gboolean*)user_data;
++    gboolean new_val = gtk_toggle_button_get_active(btn);
++    if(new_val != *val)
++    {
++        *val = new_val;
++        lxappearance_changed();
++    }
++}
++
++void other_init(GtkBuilder* b)
++{
++    int idx;
++    app.tb_style_combo = GTK_WIDGET(gtk_builder_get_object(b, "tb_style"));
++    idx = app.toolbar_style - GTK_TOOLBAR_ICONS;
++    gtk_combo_box_set_active(GTK_COMBO_BOX(app.tb_style_combo), idx);
++    g_signal_connect(app.tb_style_combo, "changed", G_CALLBACK(on_tb_style_changed), NULL);
++
++    app.tb_icon_size_combo = GTK_WIDGET(gtk_builder_get_object(b, "tb_icon_size"));
++    idx = app.toolbar_icon_size - GTK_ICON_SIZE_MENU;
++    gtk_combo_box_set_active(GTK_COMBO_BOX(app.tb_icon_size_combo), idx);
++    g_signal_connect(app.tb_icon_size_combo, "changed", G_CALLBACK(on_tb_icon_size_changed), NULL);
++
++    app.button_images_check = GTK_WIDGET(gtk_builder_get_object(b, "button_images"));
++    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(app.button_images_check), app.button_images);
++    g_signal_connect(app.button_images_check, "toggled", G_CALLBACK(on_check_button_toggled), &app.button_images);
++
++    app.menu_images_check = GTK_WIDGET(gtk_builder_get_object(b, "menu_images"));
++    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(app.menu_images_check), app.menu_images);
++    g_signal_connect(app.menu_images_check, "toggled", G_CALLBACK(on_check_button_toggled), &app.menu_images);
++
++#if GTK_CHECK_VERSION(2, 14, 0)
++    app.event_sound_check = GTK_WIDGET(gtk_builder_get_object(b, "event_sound"));
++    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(app.event_sound_check), app.enable_event_sound);
++    g_signal_connect(app.event_sound_check, "toggled", G_CALLBACK(on_check_button_toggled), &app.enable_event_sound);
++
++    app.input_feedback_check = GTK_WIDGET(gtk_builder_get_object(b, "input_feedback_sound"));
++    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(app.input_feedback_check), app.enable_input_feedback);
++    g_signal_connect(app.input_feedback_check, "toggled", G_CALLBACK(on_check_button_toggled), &app.enable_input_feedback);
++
++    /* event sound support */
++    gtk_widget_show_all(GTK_WIDGET(gtk_builder_get_object(b, "sound_effect")));
++#endif
++}
++
+diff --git a/src/other.h b/src/other.h
+new file mode 100644
+index 0000000..be72511
+--- /dev/null
++++ b/src/other.h
+@@ -0,0 +1,30 @@
++//      other.h
++//
++//      Copyright 2010 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
++//
++//      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., 51 Franklin Street, Fifth Floor, Boston,
++//      MA 02110-1301, USA.
++
++
++#ifndef __OTHER_H__
++#define __OTHER_H__
++
++G_BEGIN_DECLS
++
++void other_init(GtkBuilder* b);
++
++G_END_DECLS
++
++#endif /* __OTHER_H__ */
+diff --git a/src/plugin.c b/src/plugin.c
+new file mode 100644
+index 0000000..bd22c18
+--- /dev/null
++++ b/src/plugin.c
+@@ -0,0 +1,93 @@
++//      plugin.c
++//
++//      Copyright 2010 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
++//
++//      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., 51 Franklin Street, Fifth Floor, Boston,
++//      MA 02110-1301, USA.
++
++#ifdef HAVE_CONFIG_H
++#include <config.h>
++#endif
++
++#include "plugin.h"
++#include "lxappearance.h"
++#include <gmodule.h>
++
++#define PLUGIN_DIR  PACKAGE_LIB_DIR"/lxappearance/plugins"
++
++typedef gboolean (*PluginLoadFunc)(LXAppearance*, GtkBuilder*);
++typedef void (*PluginUnloadFunc)(LXAppearance*);
++
++typedef struct _Plugin Plugin;
++struct _Plugin
++{
++    GModule* module;
++    PluginLoadFunc load;
++    PluginUnloadFunc unload;
++};
++
++static GSList* plugins = NULL;
++
++void plugins_init(GtkBuilder* builder)
++{
++    GDir* dir = g_dir_open(PLUGIN_DIR, 0, NULL);
++    const char* name;
++    if(!dir)
++        return;
++    while(name = g_dir_read_name(dir))
++    {
++        if(g_str_has_suffix(name, ".so"))
++        {
++            char* file = g_build_filename(PLUGIN_DIR, name, NULL);
++            GModule* mod = g_module_open(file, 0);
++            g_free(file);
++            if(mod)
++            {
++                PluginLoadFunc load;
++                gboolean loaded = FALSE;
++                g_debug("module: %s", g_module_name(mod));
++                if(g_module_symbol(mod, "plugin_load", (gpointer*)&load))
++                    loaded = load(&app, builder);
++                if(loaded)
++                {
++                    Plugin* plugin = g_slice_new0(Plugin);
++                    plugin->module = mod;
++                    plugin->load = load;
++                    g_module_symbol(mod, "plugin_unload", (gpointer*)&plugin->unload);
++                    plugins = g_slist_prepend(plugins, plugin);
++                }
++                else
++                    g_module_close(mod);
++            }
++            else
++                g_debug("open failed: %s\n%s", name, g_module_error());
++        }
++    }
++    g_dir_close(dir);
++}
++
++void plugins_finalize()
++{
++    GSList* l;
++    for(l = plugins; l; l=l->next)
++    {
++        Plugin* plugin = (Plugin*)l->data;
++        if(plugin->unload)
++            plugin->unload(&app);
++        g_module_close(plugin->module);
++        g_slice_free(Plugin, plugin);
++    }
++    g_slist_free(plugins);
++}
+diff --git a/src/plugin.h b/src/plugin.h
+new file mode 100644
+index 0000000..fea7e33
+--- /dev/null
++++ b/src/plugin.h
+@@ -0,0 +1,28 @@
++//      plugin.c
++//
++//      Copyright 2010 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
++//
++//      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., 51 Franklin Street, Fifth Floor, Boston,
++//      MA 02110-1301, USA.
++
++#ifndef __PLUGIN_H__
++#define __PLUGIN_H__
++
++#include <gtk/gtk.h>
++
++void plugins_init(GtkBuilder* builder);
++void plugins_finalize();
++
++#endif
+diff --git a/src/utils.c b/src/utils.c
+new file mode 100644
+index 0000000..f3dddfc
+--- /dev/null
++++ b/src/utils.c
+@@ -0,0 +1,267 @@
++/*
++ *      utils.c
++ *
++ *      Copyright 2010 PCMan <pcman.tw@gmail.com>
++ *
++ *      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., 51 Franklin Street, Fifth Floor, Boston,
++ *      MA 02110-1301, USA.
++ */
++
++#include "utils.h"
++#include "lxappearance.h"
++#include <glib/gi18n.h>
++#include <sys/types.h>
++#include <signal.h>
++#include <sys/wait.h>
++#include <stdlib.h>
++#include <glib/gstdio.h>
++
++#include "icon-theme.h"
++
++static void on_pid_exit(GPid pid, gint status, gpointer user_data)
++{
++    GtkDialog* dlg = GTK_DIALOG(user_data);
++    gtk_dialog_response(dlg, GTK_RESPONSE_OK);
++    g_debug("pid exit");
++}
++
++static void on_progress_dlg_response(GtkDialog* dlg, int res, gpointer user_data)
++{
++    if(res != GTK_RESPONSE_OK)
++    {
++        GPid* ppid = (GPid*)user_data;
++        int status;
++        kill(*ppid, SIGTERM);
++        waitpid(*ppid, &status, WNOHANG);
++    }
++}
++
++static gboolean on_progress_timeout(GtkProgressBar* progress)
++{
++    gtk_progress_bar_pulse(progress);
++    return TRUE;
++}
++
++gboolean show_progress_for_pid(GtkWindow* parent, const char* title, const char* msg, GPid pid)
++{
++    gint res;
++    GtkWidget* dlg = gtk_dialog_new_with_buttons(title, parent,
++                            GTK_DIALOG_NO_SEPARATOR|GTK_DIALOG_MODAL,
++                            GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL);
++    GtkWidget* progress = gtk_progress_bar_new();
++    GtkWidget* vbox = gtk_dialog_get_content_area(GTK_DIALOG(dlg));
++    GtkWidget* label = gtk_label_new(msg);
++
++    guint child_watch = g_child_watch_add(pid, on_pid_exit, dlg);
++    guint timeout = g_timeout_add(300, (GSourceFunc)on_progress_timeout, progress);
++
++    gtk_window_set_default_size(GTK_WINDOW(dlg), 240, -1);
++    gtk_box_set_spacing(GTK_BOX(vbox), 6);
++    gtk_widget_show(label);
++    gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, TRUE, 0);
++    gtk_widget_show(progress);
++    gtk_box_pack_start(GTK_BOX(vbox), progress, FALSE, TRUE, 0);
++    gtk_progress_set_activity_mode(GTK_PROGRESS(progress), TRUE);
++    g_signal_connect(dlg, "response", G_CALLBACK(on_progress_dlg_response), &pid);
++
++    res = gtk_dialog_run(GTK_DIALOG(dlg));
++
++    g_source_remove(child_watch);
++    g_source_remove(timeout);
++    gtk_widget_destroy(dlg);
++
++    return (res == GTK_RESPONSE_OK);
++}
++
++static void insert_theme_to_models(IconTheme* theme)
++{
++    int icon_theme_pos = 0;
++    int cursor_theme_pos = 0;
++    GSList* l;
++    GtkTreeIter it;
++
++    for(l = app.icon_themes; l; l=l->next)
++    {
++        IconTheme* theme2 = (IconTheme*)l->data;
++        if(l->data == theme)
++            break;
++        if(theme2->has_icon)
++            ++icon_theme_pos;
++        if(theme2->has_cursor)
++            ++cursor_theme_pos;
++    }
++    if(theme->has_icon)
++        gtk_list_store_insert_with_values(app.icon_theme_store, &it, icon_theme_pos, 0, theme->disp_name, 1, theme, -1);
++
++    if(theme->has_cursor)
++        gtk_list_store_insert_with_values(app.cursor_theme_store, &it, cursor_theme_pos, 0, theme->disp_name, 1, theme, -1);
++}
++
++static gboolean install_icon_theme_package(const char* package_path)
++{
++    GPid pid = -1;
++    const char* user_icons_dir = icon_theme_dirs[0];
++    char* tmp_dir = g_build_filename(user_icons_dir, "tmp.XXXXXX", NULL);
++    char* argv[]= {
++        "tar",
++        NULL,
++        "-C",
++        tmp_dir,
++        "-xf",
++        (char*)package_path,
++        NULL
++    };
++
++    if(g_mkdir_with_parents(user_icons_dir, 0700) == -1)
++        return FALSE;
++
++    if(!mkdtemp(tmp_dir))
++        return FALSE;
++
++    if(g_str_has_suffix(package_path, ".tar.gz"))
++        argv[1] = "--gzip";
++    else if(g_str_has_suffix(package_path, ".tar.bz2"))
++        argv[1] = "--bzip2";
++    else /* the file format is not supported */
++        goto _out;
++
++    char* cmd = g_strjoinv(" ", argv);
++    g_debug("extract: %s", cmd);
++    g_free(cmd);
++
++    if(g_spawn_async(NULL, argv, NULL, G_SPAWN_SEARCH_PATH|G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL, &pid, NULL))
++    {
++        g_debug("pid = %d", pid);
++        /* show progress UI for this pid */
++        if(show_progress_for_pid(GTK_WINDOW(app.dlg), "Install themes", "Installing...", pid))
++        {
++            /* move files in tmp_dir to user_icons_dir */
++            GDir* dir;
++            GKeyFile* kf = g_key_file_new();
++
++            /* convert the themes in the dir to IconTheme structs and add them to app.icon_themes list */
++            load_icon_themes_from_dir(user_icons_dir, tmp_dir, kf);
++            g_key_file_free(kf);
++
++            /* now really move this themes to ~/.icons dir and also update the GUI */
++            dir = g_dir_open(tmp_dir, 0, NULL);
++            if(dir)
++            {
++                char* name;
++                while(name = (char*)g_dir_read_name(dir))
++                {
++                    char* index_theme = g_build_filename(tmp_dir, name, "index.theme", NULL);
++                    gboolean is_theme = g_file_test(index_theme, G_FILE_TEST_EXISTS);
++                    g_free(index_theme);
++                    if(is_theme)
++                    {
++                        char* theme_tmp = g_build_filename(tmp_dir, name, NULL);
++                        char* theme_target = g_build_filename(user_icons_dir, name, NULL);
++                        if(g_rename(theme_tmp, theme_target) == 0)
++                        {
++                            /* the theme is already installed to ~/.icons */
++                            GSList* l= g_slist_find_custom(app.icon_themes, name, (GCompareFunc)icon_theme_cmp_name);
++                            if(l)
++                            {
++                                IconTheme* theme = (IconTheme*)l->data;
++                                g_debug("installed theme: %p, %s", theme, theme->name);
++                                /* update UI */
++                                insert_theme_to_models(theme);
++                            }
++                        }
++                        else
++                        {
++                            /* errors happened */
++                        }
++                        g_free(theme_target);
++                        g_free(theme_tmp);
++                    }
++                }
++                g_dir_close(dir);
++
++                /* remove remaining files. FIXME: will this cause problems? */
++                name = g_strdup_printf("rm -rf '%s'", tmp_dir);
++                g_spawn_command_line_sync(name, NULL, NULL, NULL, NULL);
++                g_free(name);
++            }
++        }
++    }
++
++_out:
++    g_free(tmp_dir);
++    return (pid != -1);
++}
++
++gboolean install_icon_theme(GtkWindow* parent)
++{
++    GtkFileFilter* filter = gtk_file_filter_new();
++    char* file = NULL;
++    int res;
++    GtkWidget* fc = gtk_file_chooser_dialog_new( _("Select an icon theme"), NULL,
++                                        GTK_FILE_CHOOSER_ACTION_OPEN,
++                                        GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
++                                        GTK_STOCK_OPEN, GTK_RESPONSE_OK, NULL );
++    gtk_window_set_transient_for(GTK_WINDOW(fc), GTK_WINDOW(app.dlg));
++    gtk_file_filter_add_pattern( filter, "*.tar.gz" );
++    gtk_file_filter_add_pattern( filter, "*.tar.bz2" );
++    gtk_file_filter_set_name( filter, _("*.tar.gz, *.tar.bz2 (Icon Theme)") );
++
++    gtk_file_chooser_add_filter( GTK_FILE_CHOOSER(fc), filter );
++    gtk_file_chooser_set_filter( GTK_FILE_CHOOSER(fc), filter );
++
++    res = gtk_dialog_run( (GtkDialog*)fc );
++    file = gtk_file_chooser_get_filename( GTK_FILE_CHOOSER(fc) );
++    gtk_widget_destroy( fc );
++
++    if( res == GTK_RESPONSE_OK )
++        install_icon_theme_package(file);
++
++    g_free(file);
++    return TRUE;
++}
++
++gboolean remove_icon_theme(GtkWindow* parent, IconTheme* theme)
++{
++    gboolean ret = TRUE;
++    char* dir = g_build_filename(theme->base_dir, theme->name, NULL);
++    char* tmp_dir = g_build_filename(theme->base_dir, "tmp.XXXXXX", NULL);
++g_debug("tmp_dir = %s", tmp_dir);
++    /* move the theme to a tmp dir first. so we can make the
++     * removal atomic. */
++    if(mkdtemp(tmp_dir))
++    {
++        char* tmp_dest = g_build_filename(tmp_dir, theme->name, NULL);
++        if(g_rename(dir, tmp_dest) == 0)
++        {
++            char* argv[] = {
++                "rm",
++                "-rf",
++                tmp_dir,
++                NULL
++            };
++            GPid pid;
++            if(g_spawn_async(NULL, argv, NULL, G_SPAWN_SEARCH_PATH|G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL, &pid, NULL))
++            {
++                ret = show_progress_for_pid(GTK_WINDOW(app.dlg), "Remove icon theme", "Removing...", pid);
++            }
++        }
++        g_free(tmp_dest);
++    }
++    else
++        ret = FALSE;
++
++    g_free(dir);
++    return ret;
++}
+diff --git a/src/utils.h b/src/utils.h
+new file mode 100644
+index 0000000..d008025
+--- /dev/null
++++ b/src/utils.h
+@@ -0,0 +1,37 @@
++/*
++ *      utils.h
++ *
++ *      Copyright 2010 PCMan <pcman.tw@gmail.com>
++ *
++ *      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., 51 Franklin Street, Fifth Floor, Boston,
++ *      MA 02110-1301, USA.
++ */
++
++#ifndef _UTILS_H_
++#define _UTILS_H_
++
++#include <gtk/gtk.h>
++#include "icon-theme.h"
++
++G_BEGIN_DECLS
++
++gboolean show_progress_for_pid(GtkWindow* parent, const char* title, const char* msg, GPid pid);
++
++gboolean install_icon_theme(GtkWindow* parent);
++gboolean remove_icon_theme(GtkWindow* parent, IconTheme* theme);
++
++G_END_DECLS
++
++#endif
+diff --git a/src/widget-theme.c b/src/widget-theme.c
+new file mode 100644
+index 0000000..f891e99
+--- /dev/null
++++ b/src/widget-theme.c
+@@ -0,0 +1,147 @@
++/*
++ *      widget-theme.c
++ *
++ *      Copyright 2010 PCMan <pcman.tw@gmail.com>
++ *
++ *      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., 51 Franklin Street, Fifth Floor, Boston,
++ *      MA 02110-1301, USA.
++ */
++
++#include "lxappearance.h"
++#include "widget-theme.h"
++#include "color-scheme.h"
++#include <string.h>
++
++static GSList* load_themes_in_dir(const char* theme_dir, GSList* themes)
++{
++    GDir* dir = g_dir_open(theme_dir, 0, NULL);
++    if(dir)
++    {
++        const char* name;
++        while(name = g_dir_read_name(dir))
++        {
++            /* test if we already have this in list */
++            if(!g_slist_find_custom(themes, name, (GCompareFunc)strcmp))
++            {
++                /* test if this is a gtk theme */
++                char* gtkrc = g_build_filename(theme_dir, name, "gtk-2.0/gtkrc", NULL);
++                if(g_file_test(gtkrc, G_FILE_TEST_EXISTS))
++                    themes = g_slist_prepend(themes, g_strdup(name));
++                g_free(gtkrc);
++            }
++        }
++        g_dir_close(dir);
++    }
++    return themes;
++}
++
++static void on_sel_changed(GtkTreeSelection* sel, gpointer user_data)
++{
++    GtkTreeIter it;
++    GtkTreeModel* model;
++    if(gtk_tree_selection_get_selected(sel, &model, &it))
++    {
++        g_free(app.widget_theme);
++        gtk_tree_model_get(model, &it, 0, &app.widget_theme, -1);
++        g_object_set(gtk_settings_get_default(), "gtk-theme-name", app.widget_theme, NULL);
++        lxappearance_changed();
++
++        /* check if current theme support color schemes. */
++        color_scheme_update();
++    }
++}
++
++static void load_themes()
++{
++    char* dir;
++    GSList* themes = NULL, *l;
++    GtkTreeIter sel_it = {0};
++    GtkTreeSelection* tree_sel;
++
++    /* load user dir */
++    dir = g_build_filename(g_get_home_dir(), ".themes", NULL);
++    themes = load_themes_in_dir(dir, themes);
++    g_free(dir);
++
++    /* load system default */
++    dir = gtk_rc_get_theme_dir();
++    themes = load_themes_in_dir(dir, themes);
++    g_free(dir);
++
++    themes = g_slist_sort(themes, (GCompareFunc)strcmp);
++    for(l = themes; l; l=l->next)
++    {
++        GtkTreeIter it;
++        char* name = (char*)l->data;
++        gtk_list_store_insert_with_values(app.widget_theme_store, &it, -1, 0, name, -1);
++        /* if this theme is the one currently in use */
++        if(!sel_it.user_data)
++        {
++            if(strcmp(name, app.widget_theme) == 0)
++                sel_it = it;
++        }
++        g_free(name);
++    }
++
++    gtk_tree_view_set_model(GTK_TREE_VIEW(app.widget_theme_view), GTK_TREE_MODEL(app.widget_theme_store));
++    tree_sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(app.widget_theme_view));
++    if(sel_it.user_data)
++    {
++        GtkTreePath* tp = gtk_tree_model_get_path(GTK_TREE_MODEL(app.widget_theme_store), &sel_it);
++        gtk_tree_selection_select_iter(tree_sel, &sel_it);
++        gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(app.widget_theme_view), tp, NULL, FALSE, 0, 0);
++        gtk_tree_path_free(tp);
++    }
++
++    g_slist_free(themes);
++
++    g_signal_connect(tree_sel, "changed", G_CALLBACK(on_sel_changed), NULL);
++
++    /* FIXME: we need to handle this, too. */
++    // g_signal_connect(gtk_settings_get_default(), "notify::gtk-theme-name", G_CALLBACK(on_sel_changed), NULL);
++}
++
++static void on_font_set(GtkFontButton* btn, gpointer user_data)
++{
++    const char* font_name = gtk_font_button_get_font_name(btn);
++    if(g_strcmp0(font_name, app.default_font))
++    {
++        g_free(app.default_font);
++        app.default_font = g_strdup(font_name);
++        g_object_set(gtk_settings_get_default(), "gtk-font-name", font_name, NULL);
++
++        lxappearance_changed();
++    }
++}
++
++void widget_theme_init(GtkBuilder* b)
++{
++    GtkWidget* demo;
++    GdkColor black = {0, 0, 0, 0};
++
++    demo = GTK_WIDGET(gtk_builder_get_object(b, "demo"));
++    app.widget_theme_view = GTK_WIDGET(gtk_builder_get_object(b, "widget_theme_view"));
++
++    gtk_widget_modify_bg(demo, GTK_STATE_NORMAL, &black);
++
++    app.widget_theme_store = gtk_list_store_new(1, G_TYPE_STRING);
++
++    /* load available themes */
++    load_themes();
++
++    app.default_font_btn = GTK_WIDGET(gtk_builder_get_object(b, "default_font"));
++    gtk_font_button_set_font_name(GTK_FONT_BUTTON(app.default_font_btn), app.default_font);
++    g_signal_connect(app.default_font_btn, "font-set", G_CALLBACK(on_font_set), NULL);
++}
+diff --git a/src/widget-theme.h b/src/widget-theme.h
+new file mode 100644
+index 0000000..561ccc1
+--- /dev/null
++++ b/src/widget-theme.h
+@@ -0,0 +1,33 @@
++/*
++ *      widget-theme.h
++ *
++ *      Copyright 2010 PCMan <pcman.tw@gmail.com>
++ *
++ *      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., 51 Franklin Street, Fifth Floor, Boston,
++ *      MA 02110-1301, USA.
++ */
++
++#ifndef _WIDGET_THEME_H_
++#define _WIDGET_THEME_H_
++
++#include <gtk/gtk.h>
++
++G_BEGIN_DECLS
++
++void widget_theme_init(GtkBuilder* b);
++
++G_END_DECLS
++
++#endif
+diff --git a/src/xml-purge.c b/src/xml-purge.c
+new file mode 100644
+index 0000000..9fc8525
+--- /dev/null
++++ b/src/xml-purge.c
+@@ -0,0 +1,102 @@
++#include <stdio.h>
++#include <string.h>
++#include <stdlib.h>
++#include <glib.h>
++
++#define IS_BLANK(ch)  strchr(" \t\n\r", ch)
++
++static void purge_file( const char* file )
++{
++      char* buf, *pbuf;
++      int in_tag = 0, in_quote = 0;
++      FILE* fo;
++
++    if(!g_file_get_contents(file, &buf, NULL, NULL))
++        exit(1);
++
++      fo = fopen( file, "w" );
++      if( ! fo )
++              goto error;
++
++      for( pbuf = buf; *pbuf; ++pbuf )
++      {
++              if( in_tag > 0 )
++              {
++                      if( in_quote )
++                      {
++                              if( *pbuf == '\"' )
++                                      in_quote = 0;
++                      }
++                      else
++                      {
++                              if( *pbuf == '\"' )
++                                      ++in_quote;
++                              if( ! in_quote && IS_BLANK(*pbuf) )     /* skip unnecessary blanks */
++                              {
++                                      do{
++                                              ++pbuf;
++                                      }while( IS_BLANK( *pbuf ) );
++
++                                      if( *pbuf != '>' )
++                                              fputc( ' ', fo );
++                                      --pbuf;
++                                      continue;
++                              }
++                      }
++                      if( *pbuf == '>' )
++                              --in_tag;
++                      fputc( *pbuf, fo );
++              }
++              else
++              {
++                      if( *pbuf == '<' )
++                      {
++                              if( 0 == strncmp( pbuf, "<!--", 4 ) )   /* skip comments */
++                              {
++                                      pbuf = strstr( pbuf, "-->" );
++                                      if( ! pbuf )
++                                              goto error;
++                                      pbuf += 2;
++                                      continue;
++                              }
++                              ++in_tag;
++                              fputc( '<', fo );
++                      }
++                      else
++                      {
++                              char* tmp = pbuf;
++                              while( *tmp && IS_BLANK( *tmp ) && *tmp != '<' )
++                                      ++tmp;
++                              if( *tmp == '<' )       /* all cdata are blank characters */
++                                      pbuf = tmp - 1;
++                              else /* not blank, keep the cdata */
++                              {
++                                      if( tmp == pbuf )
++                                              fputc( *pbuf, fo );
++                                      else
++                                      {
++                                              fwrite( pbuf, 1, tmp - pbuf, fo );
++                                              pbuf = tmp - 1;
++                                      }
++                              }
++                      }
++              }
++      }
++      
++      fclose( fo );
++
++error:
++      free( buf );
++}
++
++int main( int argc, char** argv )
++{
++      int i;
++      if( argc < 2 )
++              return 1;
++
++      for( i = 1; i < argc; ++i )
++              purge_file( argv[ i] );
++
++      return 0;
++}
index e69de29..1ef9763 100644 (file)
@@ -0,0 +1 @@
+lxappearance-0.4.0+git20100807.patch