Finish color scheme support.
authorHong Jen Yee (PCMan) <pcman.tw@gmail.com>
Thu, 5 Aug 2010 11:29:23 +0000 (19:29 +0800)
committerHong Jen Yee (PCMan) <pcman.tw@gmail.com>
Thu, 5 Aug 2010 11:29:23 +0000 (19:29 +0800)
Fix some English strings.

data/lxappearance2.desktop.in
data/ui/about.glade.in
data/ui/lxappearance.glade
src/color-scheme.c
src/color-scheme.h
src/icon-theme.c
src/lxappearance2.c
src/lxappearance2.h

index 7e4c9df..e17bf61 100644 (file)
@@ -1,9 +1,9 @@
 [Desktop Entry]
 Type=Application
-_Name=Desktop Look and Feels
-_GenericName=Desktop Look and Feels
-_Comment=Configures look and feels of your desktop and applications
+_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=lxappearance2
 StartupNotify=true
-Categories=Settings;DesktopSettings;GTK;
+Categories=Settings;DesktopSettings;GTK;X-LXDE-Settings;
index f5b7bf8..0227724 100644 (file)
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="UTF-8"?>
+<?xml version="1.0"?>
 <interface>
   <!-- interface-requires gtk+ 2.12 -->
   <!-- interface-naming-policy toplevel-contextual -->
@@ -10,7 +10,7 @@
     <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">Configures look and feels of your desktop</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
 
@@ -27,7 +27,7 @@ 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">洪任諭 Hong Jen Yee (PCMan) &lt;pcman.tw@gmail.com&gt;</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>
index 7ca6841..41b6103 100644 (file)
@@ -95,7 +95,7 @@
   </object>
   <object class="GtkDialog" id="dlg">
     <property name="border_width">5</property>
-    <property name="title" translatable="yes">Desktop Look and Feels</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="border_width">12</property>
                 <property name="spacing">6</property>
                 <child>
-                  <object class="GtkTable" id="table1">
+                  <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>
                   </object>
                   <packing>
                     <property name="expand">False</property>
-                    <property name="position">0</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkHBox" id="hbox9">
-                    <property name="visible">True</property>
-                    <child>
-                      <placeholder/>
-                    </child>
-                    <child>
-                      <object class="GtkButton" id="default_color_scheme">
-                        <property name="label" translatable="yes">Restore default color scheme</property>
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="receives_default">True</property>
-                      </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="pack_type">end</property>
-                        <property name="position">1</property>
-                      </packing>
-                    </child>
-                  </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="position">1</property>
+                    <property name="position">2</property>
                   </packing>
                 </child>
               </object>
               </packing>
             </child>
             <child>
-              <object class="GtkButton" id="apply">
-                <property name="label">gtk-apply</property>
+              <object class="GtkButton" id="close">
+                <property name="label">gtk-close</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>
               </packing>
             </child>
             <child>
-              <object class="GtkButton" id="close">
-                <property name="label">gtk-close</property>
+              <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>
     </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-widget response="-10">apply</action-widget>
     </action-widgets>
   </object>
   <object class="GtkImage" id="image2">
index 27ada9e..3f05cf4 100644 (file)
@@ -21,6 +21,9 @@
 #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. */
@@ -33,7 +36,7 @@ static const char* gnome_color_names[] = {
     "tooltip_fg_color", /* Text color for text in tooltips. */
 };
 
-static char* hash_to_color_scheme_str(GHashTable* hash)
+char* color_scheme_hash_to_str(GHashTable* hash)
 {
     GHashTableIter it;
     char* key, *val;
@@ -44,6 +47,26 @@ static char* hash_to_color_scheme_str(GHashTable* hash)
     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;
@@ -53,23 +76,84 @@ static void on_color_set(GtkColorButton* btn, const char* color_name)
 
     g_hash_table_replace(app.color_scheme_hash, g_strdup(color_name), color_str);
     g_free(app.color_scheme);
-    app.color_scheme = hash_to_color_scheme_str(app.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);
 
     lxappearance_changed();
 }
 
-static void on_reset_color_schemes()
+static void update_color_buttons()
 {
-    /* FIXME: How to correctly do this? */
+    int i;
+    /* set the color to buttons */
+    GHashTable* hash;
 
-    /* this resets gtk color schemes to default. */
-    g_free(app.color_scheme);
-    app.color_scheme = NULL;
+    /* 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;
 
-    g_object_set(gtk_settings_get_default(), "gtk-color-scheme", "", NULL);
-    color_scheme_update();
+    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(app.color_scheme_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, color_name);
+                gtk_color_button_set_color(GTK_COLOR_BUTTON(btn), &clr);
+                g_signal_handlers_unblock_by_func(btn, on_color_set, 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(app.default_color_scheme_hash)
+            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();
 }
@@ -77,109 +161,125 @@ static void on_reset_color_schemes()
 void color_scheme_init(GtkBuilder* b)
 {
     int i;
-    GtkWidget* btn = GTK_WIDGET(gtk_builder_get_object(b, "default_color_scheme"));
-    g_signal_connect(btn, "clicked", G_CALLBACK(on_reset_color_schemes), NULL);
-    /* FIXME: there is no good way to restore default colors yet. */
-    gtk_widget_hide(btn);
+    /* regular expressions used to parse gtkrc files */
+    gtkrc_include_reg = g_regex_new(
+        "[\\s]*include[\\s]+(\"([^\"]+)\"|'([^']+)')",
+        G_REGEX_MULTILINE|G_REGEX_OPTIMIZE, 0, NULL);
 
-    app.color_page = GTK_WIDGET(gtk_builder_get_object(b, "color_page"));
+    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_scheme_hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
+    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), gnome_color_names[i]);
 }
 
-static gboolean gtkrc_supports_colors(const char* gtkrc_file, gboolean* support)
+/* return FALSE when the gtkrc file does not exists. */
+gboolean gtkrc_file_get_color_scheme(const char* gtkrc_file, GHashTable* hash)
 {
     char* content;
-    gboolean support_colors = FALSE;
-    g_debug("check: %s", gtkrc_file);
+    /* g_debug("check: %s", gtkrc_file); */
     if(g_file_get_contents(gtkrc_file, &content, NULL, NULL))
     {
-        /* FIXME: check included gtkrc files, too. */
-        if(strstr(content, "gtk-color-scheme"))
-            support_colors = TRUE;
+        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;
-    *support = support_colors;
     return TRUE;
 }
 
-/* check if current gtk+ widget theme supports color schemes */
+/* update the color scheme page for currently selected gtk theme.
+ * called when currently selected gtk theme gets changed. */
 void color_scheme_update()
 {
-    gboolean supported = FALSE;
+    /* 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);
-        file_found = gtkrc_supports_colors(gtkrc, &supported);
+        /* 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_supports_colors(gtkrc, &supported);
+            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;
 
-    g_free(app.color_scheme);
-    if(supported)
+    if(app.color_scheme_supported)
     {
-        char** pairs, **pair;
-        int i;
-
-        g_object_get(gtk_settings_get_default(), "gtk-color-scheme", &app.color_scheme, NULL);
-        g_debug("color-scheme: %s", app.color_scheme);
-        gtk_widget_set_sensitive(app.color_page, TRUE);
-
-        g_hash_table_remove_all(app.color_scheme_hash);
-
-        /* split color scheme string into key/value pairs */
-        pairs = g_strsplit_set(app.color_scheme, "\n;", -1);
-        for(pair = pairs; *pair; ++pair)
-        {
-            char* name = strtok(*pair, ": \t");
-            if(name)
-            {
-                char* val = strtok(NULL, " \t");
-                if(val)
-                    g_hash_table_replace(app.color_scheme_hash, g_strdup(name), g_strdup(val));
-            }
-        }
-        g_strfreev(pairs);
-
-        /* set the color to buttons */
-        for(i = 0; i < 8; ++i)
-        {
-            GtkWidget* btn = app.color_btns[i];
-            const char* color_str = (const char*)g_hash_table_lookup(app.color_scheme_hash, gnome_color_names[i]);
-            g_debug("%s ='%s'", gnome_color_names[i], color_str);
-            if(color_str)
-            {
-                GdkColor clr;
-                if(gdk_color_parse(color_str, &clr))
-                    gtk_color_button_set_color(GTK_COLOR_BUTTON(btn), &clr);
-                gtk_widget_set_sensitive(btn, TRUE);
-            }
-            else
-                gtk_widget_set_sensitive(btn, FALSE);
-        }
+        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);
     }
     else
     {
-        app.color_scheme = NULL;
-        gtk_widget_set_sensitive(app.color_page, FALSE);
-        g_debug("color-scheme is not supported by this theme");
+        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();
 }
 
index 08b2df0..7397143 100644 (file)
 
 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__ */
index f3b9ebd..82225b6 100644 (file)
@@ -123,7 +123,7 @@ static void load_icon_themes()
     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_debug("icon_theme_dirs[%d] = %s", i, icon_theme_dirs[i]); */
     }
     g_key_file_free(kf);
 }
index db86013..f036917 100644 (file)
@@ -143,7 +143,8 @@ static void lxappearance_save_gtkrc()
     };
 
     char* file_path = g_build_filename(g_get_home_dir(), ".gtkrc-2.0", NULL);
-    char* content = g_strdup_printf(
+    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"
@@ -155,9 +156,8 @@ static void lxappearance_save_gtkrc()
         "gtk-cursor-theme-size=%d\n"
 #if GTK_CHECK_VERSION(2, 14, 0)
         "gtk-enable-event-sounds=%s\n"
-        "gtk-enable-input-feedback-sounds=%s\n"
+        "gtk-enable-input-feedback-sounds=%s\n",
 #endif
-        "include \"%s/.gtkrc-2.0.mine\"\n",
         app.widget_theme,
         app.icon_theme,
         app.default_font,
@@ -167,12 +167,25 @@ static void lxappearance_save_gtkrc()
         app.cursor_theme_size,
 #if GTK_CHECK_VERSION(2, 14, 0)
         bool2str(app.enable_event_sound),
-        bool2str(app.enable_input_feedback),
+        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, -1, NULL);
-    g_free(content);
+    g_file_set_contents(file_path, content->str, content->len, NULL);
+    g_string_free(content, TRUE);
     g_free(file_path);
 }
 
@@ -201,8 +214,7 @@ static void lxappearance_save_lxsession()
     g_key_file_set_string( kf, "GTK", "sNet/ThemeName", app.widget_theme );
     g_key_file_set_string( kf, "GTK", "sGtk/FontName", app.default_font );
 
-    if(app.color_scheme)
-        g_key_file_set_string( kf, "GTK", "sGtk/ColorScheme", app.color_scheme );
+    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 );
 
@@ -299,6 +311,41 @@ static void settings_init()
         }
         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, 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)
index 2e26964..541b4b3 100644 (file)
@@ -30,26 +30,36 @@ struct _LXAppearance
     GtkWidget* dlg;
     GtkWidget* notebook;
 
+    /* gtk theme */
     GtkWidget* widget_theme_view;
     GtkListStore* widget_theme_store;
     GtkWidget* default_font_btn;
 
-    GtkWidget* color_page;
-    GHashTable* color_scheme_hash;
+    /* 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 */
+    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;