[PATCH] Color schemes

Development of XChat itself. Talk about code, patches and other technical stuff. No feature requests!
Formal bug reports should go to http://xchat.org/cvs/#bugs instead.
This forum is for developers writing xchat code, not end-user questions.

[PATCH] Color scheme

Postby erdizz » 12 May 2007 22:27

Hello, here's my take on support for color schemes.

Features:
* creation, deletion of custom color schemes
* automatic scheme switching, guessing a best match for current Gtk+ theme

Schemes are stored in user's directory (~/.xchat2) in separate files. Each file is named colors_SCHEME.conf, where SCHEME is a name of a scheme.

I'm not sure about how to deliver default color schemes (some automake magic?). Leaving this up to you, if you like the patch, of course.

Update As I see, the formatting gets broken after posting. I've put the patch and relevant files here:
http://mync.sourceforge.net/xchat_color_schemes.tar.gz


Best regards,
Dmitry Shatrov

The patch:
Code: Select all
diff -urN xchat2-orig/src/common/cfgfiles.c xchat2/src/common/cfgfiles.c
--- xchat2-orig/src/common/cfgfiles.c   2007-03-26 06:46:05.000000000 +0400
+++ xchat2/src/common/cfgfiles.c   2007-05-12 19:13:45.000000000 +0400
@@ -424,6 +424,7 @@
    {"gui_dialog_left", P_OFFINT (dialog_left), TYPE_INT},
    {"gui_dialog_top", P_OFFINT (dialog_top), TYPE_INT},
    {"gui_dialog_width", P_OFFINT (dialog_width), TYPE_INT},
+   {"gui_guess_theme", P_OFFINT (guess_theme), TYPE_BOOL},
    {"gui_hide_menu", P_OFFINT (hidemenu), TYPE_BOOL},
    {"gui_input_spell", P_OFFINT (gui_input_spell), TYPE_BOOL},
    {"gui_input_style", P_OFFINT (style_inputbox), TYPE_BOOL},
@@ -670,6 +671,7 @@
    prefs.input_flash_priv = prefs.input_flash_hilight = 1;
    prefs.input_tray_priv = prefs.input_tray_hilight = 1;
    prefs.autodccsend = 2;   /* browse mode */
+   prefs.guess_theme = 1;
 #ifdef WIN32
    prefs.identd = 1;
 #endif
diff -urN xchat2-orig/src/common/xchat.h xchat2/src/common/xchat.h
--- xchat2-orig/src/common/xchat.h   2007-03-26 06:46:05.000000000 +0400
+++ xchat2/src/common/xchat.h   2007-05-12 19:14:29.000000000 +0400
@@ -299,6 +299,8 @@
       This is so that we continue using internal defaults (which can
       change in the next release) until the user edits them. */
    unsigned int save_pevents:1;
+
+   unsigned int guess_theme;
 };
 
 /* Session types */
diff -urN xchat2-orig/src/fe-gtk/fe-gtk.c xchat2/src/fe-gtk/fe-gtk.c
--- xchat2-orig/src/fe-gtk/fe-gtk.c   2007-05-05 07:34:30.000000000 +0400
+++ xchat2/src/fe-gtk/fe-gtk.c   2007-05-12 21:23:27.000000000 +0400
@@ -277,7 +277,6 @@
 void
 fe_init (void)
 {
-   palette_load ();
    key_init ();
    pixmaps_init ();
 
diff -urN xchat2-orig/src/fe-gtk/maingui.c xchat2/src/fe-gtk/maingui.c
--- xchat2-orig/src/fe-gtk/maingui.c   2007-05-05 07:34:30.000000000 +0400
+++ xchat2/src/fe-gtk/maingui.c   2007-05-12 20:53:35.000000000 +0400
@@ -65,6 +65,7 @@
 #include "pixmaps.h"
 #include "plugin-tray.h"
 #include "xtext.h"
+#include "setup.h"
 
 #ifdef USE_GTKSPELL
 #include <gtk/gtktextview.h>
@@ -2690,6 +2691,106 @@
                      GTK_EXPAND | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
 }
 
+struct LoadBestThemeParams {
+   char best_theme [512];
+   int best_match;
+   gboolean default_is_the_best;
+   GtkStyle *style;
+};
+
+void mg_load_best_theme_callback (const char* name, gpointer data)
+{
+   GdkColor color;
+   struct LoadBestThemeParams *params;
+   int match;
+   int inc;
+
+   params = (struct LoadBestThemeParams*) data;
+
+   if (palette_get_bg (name, &color) == FALSE)
+      return;
+
+   match = 0;
+   inc = color.red - params->style->base [GTK_STATE_NORMAL].red;
+   if (inc < 0)
+      inc = -inc;
+   match += inc;
+   inc = color.green - params->style->base [GTK_STATE_NORMAL].green;
+   if (inc < 0)
+      inc = -inc;
+   match += inc;
+   inc = color.blue - params->style->base [GTK_STATE_NORMAL].blue;
+   if (inc < 0)
+      inc = -inc;
+   match += inc;
+
+   if (match < params->best_match) {
+      params->best_match = match;
+      if (name == NULL)
+         params->default_is_the_best = TRUE;
+      else
+         strncpy (params->best_theme, name, sizeof (params->best_theme));
+   }
+}
+
+static void mg_switch_theme (const char *name)
+{
+   GdkColor *color;
+   int i;
+
+   palette_load (name);
+
+   for (i = 0; i < MAX_COL; i++) {
+      color = colors + i;
+      gdk_colormap_alloc_color (gtk_widget_get_default_colormap (), color, TRUE, TRUE);
+   }
+
+   setup_apply_colors ();
+}
+
+static void mg_load_best_theme (GtkStyle *style)
+{
+   struct LoadBestThemeParams params;
+   static GdkColor prv_color;
+   static gboolean local_first_run = TRUE;
+
+   if (!prefs.guess_theme)
+      return;
+
+   if (local_first_run)
+      local_first_run = FALSE;
+   else {
+      if (style->base [GTK_STATE_NORMAL].red == prv_color.red &&
+         style->base [GTK_STATE_NORMAL].green == prv_color.green &&
+         style->base [GTK_STATE_NORMAL].blue == prv_color.blue)
+         return;
+      prv_color.red = style->base [GTK_STATE_NORMAL].red;
+      prv_color.green = style->base [GTK_STATE_NORMAL].green;
+      prv_color.blue = style->base [GTK_STATE_NORMAL].blue;
+   }
+
+   params.style = style;
+   params.best_match = G_MAXINT;
+   params.best_theme [0] = 0;
+   params.default_is_the_best = FALSE;
+
+   setup_scan_for_themes (mg_load_best_theme_callback, (gpointer) &params);
+   mg_load_best_theme_callback (NULL, &params);
+   if (params.default_is_the_best)
+      mg_switch_theme (NULL);
+   else
+   if (params.best_theme [0] != 0)
+      mg_switch_theme (params.best_theme);
+   else
+      mg_switch_theme (NULL);
+}
+
+static void mg_style_set_callback (GtkWidget *widget,
+   GtkStyle *previous_style, gpointer user_data)
+{
+   mg_load_best_theme (widget->style);
+}
+
 static void
 mg_create_topwindow (session *sess)
 {
@@ -3133,6 +3234,14 @@
    if (first_run || (prefs.newtabstofront == FOCUS_NEW_ONLY_ASKED && focus)
          || prefs.newtabstofront == FOCUS_NEW_ALL )
       chan_focus (res->tab);
+
+   if (prefs.guess_theme) {
+      mg_load_best_theme (sess->gui->main_table->style);
+   } else
+      mg_switch_theme (NULL);
+
+   g_signal_connect (G_OBJECT (sess->gui->main_table), "style-set",
+      G_CALLBACK (mg_style_set_callback), NULL);
 }
 
 GtkWidget *
diff -urN xchat2-orig/src/fe-gtk/palette.c xchat2/src/fe-gtk/palette.c
--- xchat2-orig/src/fe-gtk/palette.c   2006-03-13 11:33:45.000000000 +0300
+++ xchat2/src/fe-gtk/palette.c   2007-05-12 21:43:45.000000000 +0400
@@ -81,8 +81,8 @@
    {0, 0xffff, 0x0000, 0x0000}, /* 39 tab New Message (red) */
    {0, 0x9595, 0x9595, 0x9595}, /* 40 away user (grey) */
 };
-#define MAX_COL 40
 
+static const char *str_default_palette_file = "colors.conf";
 
 void
 palette_alloc (GtkWidget * widget)
@@ -114,21 +114,70 @@
    40      /* 23: away */
 };
 
+/* Stripped parsing, reading only the first line */
+gboolean
+palette_get_bg (const char *name, GdkColor *color)
+{
+   int fh, l;
+   char prefname[512];
+   char cfg [512];
+   int red, green, blue;
+
+   if (name != NULL)
+      snprintf (prefname, sizeof (prefname),
+                "%s/colors_%s.conf",
+                get_xdir_fs (), name);
+   else
+      snprintf (prefname, sizeof (prefname),
+                "%s/%s",
+                get_xdir_fs (), str_default_palette_file);
+
+   fh = open (prefname, O_RDONLY | OFLAGS);
+   if (fh == -1)
+      return FALSE;
+
+   cfg[0] = '\0';
+   l = read (fh, cfg, sizeof (cfg) - 1);
+   if (l > 0)
+      cfg[l] = '\0';
+   else {
+      close (fh);
+      return FALSE;
+   }
+
+   snprintf (prefname, sizeof prefname, "color_%d", 256 + COL_BG - 32);
+   cfg_get_color (cfg, prefname, &red, &green, &blue);
+   color->red = red;
+   color->green = green;
+   color->blue = blue;
+
+   close (fh);
+
+   return TRUE;
+}
+
 void
-palette_load (void)
+palette_load (const char *name)
 {
    int i, j, l, fh, res;
-   char prefname[256];
+   char prefname[512];
    struct stat st;
    char *cfg;
    int red, green, blue;
    int upgrade = FALSE;
 
-   fh = xchat_open_file ("colors.conf", O_RDONLY, 0, 0);
-   if (fh == -1)
-   {
-      fh = xchat_open_file ("palette.conf", O_RDONLY, 0, 0);
-      upgrade = TRUE;
+   if (name == NULL) {
+      fh = xchat_open_file ("colors.conf", O_RDONLY, 0, 0);
+      if (fh == -1)
+      {
+         fh = xchat_open_file ("palette.conf", O_RDONLY, 0, 0);
+         upgrade = TRUE;
+      }
+   } else {
+      snprintf (prefname, sizeof (prefname),
+                "%s/colors_%s.conf",
+                get_xdir_fs (), name);
+      fh = open (prefname, O_RDONLY | OFLAGS);
    }
 
    if (fh != -1)
@@ -200,15 +249,32 @@
    }
 }
 
-void
-palette_save (void)
+int
+palette_save (const char *name)
 {
    int i, j, fh;
-   char prefname[256];
+   char prefname[512];
+
+   if (name == NULL) {
+      fh = xchat_open_file ("colors.conf",
+                            O_TRUNC | O_WRONLY | O_CREAT,
+                            0600,
+                            XOF_DOMODE);
+   } else {
+      snprintf (prefname, sizeof (prefname),
+                "%s/colors_%s.conf",
+                get_xdir_fs (), name);
+      fh = open (prefname, O_TRUNC | O_WRONLY | O_CREAT | OFLAGS, 0600);
+   }
 
-   fh = xchat_open_file ("colors.conf", O_TRUNC | O_WRONLY | O_CREAT, 0600, XOF_DOMODE);
    if (fh != -1)
    {
+      /* put bg color first, (index COL_BG),
+       * just to parse files faster if only bg is needed */
+      i = 256 + COL_BG - 32, j = COL_BG;
+      snprintf (prefname, sizeof prefname, "color_%d", i);
+      cfg_put_color (fh, colors[j].red, colors[j].green, colors[j].blue, prefname);
+
       /* mIRC colors 0-31 are here */
       for (i = 0; i < 32; i++)
       {
@@ -219,10 +285,17 @@
       /* our special colors are mapped at 256+ */
       for (i = 256, j = 32; j < MAX_COL+1; i++, j++)
       {
+         if (j == COL_BG)
+            continue;
+
          snprintf (prefname, sizeof prefname, "color_%d", i);
          cfg_put_color (fh, colors[j].red, colors[j].green, colors[j].blue, prefname);
       }
 
       close (fh);
+
+      return 0;
    }
+
+   return -1;
 }
diff -urN xchat2-orig/src/fe-gtk/palette.h xchat2/src/fe-gtk/palette.h
--- xchat2-orig/src/fe-gtk/palette.h   2004-07-07 19:34:40.000000000 +0400
+++ xchat2/src/fe-gtk/palette.h   2007-05-12 21:05:13.000000000 +0400
@@ -10,6 +10,11 @@
 #define COL_NEW_MSG 39
 #define COL_AWAY 40
 
+#define MAX_COL 40
+
 void palette_alloc (GtkWidget * widget);
-void palette_load (void);
-void palette_save (void);
+void palette_load (const char *name);
+int  palette_save (const char *name);
+
+gboolean palette_get_bg (const char *name, GdkColor *color);
+
diff -urN xchat2-orig/src/fe-gtk/setup.c xchat2/src/fe-gtk/setup.c
--- xchat2-orig/src/fe-gtk/setup.c   2007-03-28 08:04:58.000000000 +0400
+++ xchat2/src/fe-gtk/setup.c   2007-05-13 02:05:36.000000000 +0400
@@ -21,7 +21,9 @@
 #include "palette.h"
 #include "pixmaps.h"
 
+#include <glib/gstdio.h>
 #include <gtk/gtkcolorseldialog.h>
+#include <gtk/gtkmessagedialog.h>
 #include <gtk/gtktable.h>
 #include <gtk/gtkentry.h>
 #include <gtk/gtklabel.h>
@@ -41,6 +43,7 @@
 #include <gtk/gtkhseparator.h>
 #include <gtk/gtkradiobutton.h>
 #include <gtk/gtkcombobox.h>
+#include <gtk/gtkcomboboxentry.h>
 #include <gtk/gtkliststore.h>
 #include <gtk/gtktreestore.h>
 #include <gtk/gtktreeselection.h>
@@ -63,10 +66,11 @@
 
 static int last_selected_page = 0;
 static int last_selected_row = 0; /* sound row */
-static gboolean color_change;
-static struct xchatprefs setup_prefs;
 static GtkWidget *cancel_button;
 
+gboolean color_change;
+struct xchatprefs setup_prefs;
+
 enum
 {
    ST_END,
@@ -153,6 +157,9 @@
    {ST_END, 0, 0, 0, 0, 0}
 };
 
+static const setting guess_theme_setting =
+   {ST_TOGGLE, N_("Automatically switch scheme to match system colors"), P_OFFINTNL(guess_theme), 0, 0, 0};
+
 /*static const char *const lagmenutext[] =
 {
    N_("Off"),
@@ -1106,12 +1113,31 @@
 }
 
 static void
+setup_color_ok_internal (GtkWidget *button,
+                         GdkColor  *col,
+                         GdkColor  *old_color)
+{
+   GtkStyle *style;
+
+   color_change = TRUE;
+
+   gdk_colormap_alloc_color (gtk_widget_get_colormap (button), col, TRUE, TRUE);
+
+   style = gtk_style_new ();
+   style->bg[0] = *col;
+   gtk_widget_set_style (button, style);
+   g_object_unref (style);
+
+   /* is this line correct?? */
+   gdk_colormap_free_colors (gtk_widget_get_colormap (button), old_color, 1);
+}
+
+static void
 setup_color_ok_cb (GtkWidget *button, GtkWidget *dialog)
 {
    GtkColorSelectionDialog *cdialog = GTK_COLOR_SELECTION_DIALOG (dialog);
    GdkColor *col;
    GdkColor old_color;
-   GtkStyle *style;
 
    col = g_object_get_data (G_OBJECT (button), "c");
    old_color = *col;
@@ -1124,19 +1150,9 @@
       return;
    }
 
-   color_change = TRUE;
-
    gtk_color_selection_get_current_color (GTK_COLOR_SELECTION (cdialog->colorsel), col);
 
-   gdk_colormap_alloc_color (gtk_widget_get_colormap (button), col, TRUE, TRUE);
-
-   style = gtk_style_new ();
-   style->bg[0] = *col;
-   gtk_widget_set_style (button, style);
-   g_object_unref (style);
-
-   /* is this line correct?? */
-   gdk_colormap_free_colors (gtk_widget_get_colormap (button), &old_color, 1);
+   setup_color_ok_internal (button, col, &old_color);
 
    gtk_widget_destroy (dialog);
 }
@@ -1166,7 +1182,8 @@
 }
 
 static void
-setup_create_color_button (GtkWidget *table, int num, int row, int col)
+setup_create_color_button (GtkWidget *table, int num, int row, int col,
+                           GtkWidget **color_buttons)
 {
    GtkWidget *but;
    GtkStyle *style;
@@ -1178,6 +1195,7 @@
                   /* 12345678901 23456789 01  23456789 */
       sprintf (buf, "<span size=\"x-small\">%d</span>", num);
    but = gtk_button_new_with_label (" ");
+   color_buttons [num] = but;
    gtk_label_set_markup (GTK_LABEL (GTK_BIN (but)->child), buf);
    /* win32 build uses this to turn off themeing */
    g_object_set_data (G_OBJECT (but), "xchat-color", (gpointer)1);
@@ -1192,7 +1210,8 @@
 }
 
 static void
-setup_create_other_colorR (char *text, int num, int row, GtkWidget *tab)
+setup_create_other_colorR (char *text, int num, int row, GtkWidget *tab,
+                           GtkWidget **color_buttons)
 {
    GtkWidget *label;
 
@@ -1200,11 +1219,12 @@
    gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
    gtk_table_attach (GTK_TABLE (tab), label, 5, 9, row, row + 1,
                      GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, LABEL_INDENT, 0);
-   setup_create_color_button (tab, num, row, 9);
+   setup_create_color_button (tab, num, row, 9, color_buttons);
 }
 
 static void
-setup_create_other_color (char *text, int num, int row, GtkWidget *tab)
+setup_create_other_color (char *text, int num, int row, GtkWidget *tab,
+                          GtkWidget **color_buttons)
 {
    GtkWidget *label;
 
@@ -1212,57 +1232,336 @@
    gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
    gtk_table_attach (GTK_TABLE (tab), label, 2, 3, row, row + 1,
                      GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, LABEL_INDENT, 0);
-   setup_create_color_button (tab, num, row, 3);
+   setup_create_color_button (tab, num, row, 3, color_buttons);
+}
+
+static void
+setup_scan_for_themes_cb (const gchar *name, gpointer data)
+{
+   GtkListStore *store;
+   GtkTreeIter tree_iter;
+
+   store = GTK_LIST_STORE (data);
+
+   gtk_list_store_append (store, &tree_iter);
+   gtk_list_store_set (store, &tree_iter, 0, name, -1);
+}
+
+void
+setup_scan_for_themes (void (*callback) (const gchar*, gpointer),
+                       GtkListStore *store)
+{
+   GDir *dir;
+   const gchar *entry;
+   char buf [256];
+   unsigned len;
+
+   dir = g_dir_open (get_xdir_fs (), 0, NULL);
+   if (dir == NULL)
+      return;
+
+   while ((entry = g_dir_read_name (dir)) != NULL) {
+      if (g_str_has_prefix (entry, "colors_") &&
+         g_str_has_suffix (entry, ".conf"))
+      {
+         len = strlen (entry) - 7 - 5;
+         if (len >= 256)
+            len = 255;
+         memcpy (buf, entry + 7, len);
+         buf [len] = 0;
+         callback (buf, store);
+      }
+   }
+
+   g_dir_close (dir);
+}
+
+struct SetupSelectionParams {
+   GtkWidget **color_buttons;
+   GtkWidget  *delete_button;
+   GtkWidget  *save_button;
+};
+
+const char *str_current_scheme = N_("Current scheme");
+
+static void
+setup_color_page_destroy_notify (gpointer data)
+{
+   struct SetupSelectionParams *ssp = (struct SetupSelectionParams*) data;
+
+   g_free (ssp->color_buttons);
+   g_free (ssp);
+}
+
+static void
+setup_theme_changed (
+      GtkComboBox *combo,
+      struct SetupSelectionParams *params)
+{
+   GtkTreeModel *model = gtk_combo_box_get_model (combo);
+   GtkTreeIter iter;
+   gchar *title;
+   GdkColor old_colors [MAX_COL];
+   int i;
+
+   for (i = 0; i < MAX_COL; i++)
+      old_colors [i] = colors [i];
+
+   if (!gtk_combo_box_get_active_iter (combo, &iter)) {
+      gtk_widget_set_sensitive (params->save_button, TRUE);
+      return;
+   }
+
+   gtk_tree_model_get (model, &iter, 0, &title, -1);
+
+   if (strcmp (title, str_current_scheme) == 0) {
+      gtk_widget_set_sensitive (params->save_button, FALSE);
+      gtk_widget_set_sensitive (params->delete_button, FALSE);
+      palette_load (NULL);
+   } else {
+      gtk_widget_set_sensitive (params->save_button, TRUE);
+      gtk_widget_set_sensitive (params->delete_button, TRUE);
+      palette_load (title);
+   }
+
+   for (i = 0; i < MAX_COL; i++)
+      if (params->color_buttons [i] != NULL)
+         setup_color_ok_internal (params->color_buttons [i], colors + i, old_colors + i);
+
+   g_free (title);
+}
+
+struct SearchThemeForeachParams {
+   const gchar *title;
+   gboolean *theme_exists;
+};
+
+static gboolean
+setup_search_theme_foreach (GtkTreeModel *model, GtkTreePath *path,
+   GtkTreeIter *iter, struct SearchThemeForeachParams *params)
+{
+   gboolean ret = FALSE;
+   gchar *title;
+
+   gtk_tree_model_get (model, iter, 0, &title, -1);
+
+   if (strcmp (title, params->title) == 0) {
+      *params->theme_exists = TRUE;
+      ret = TRUE;
+   }
+
+   g_free (title);
+
+   return ret;
+}
+
+static void
+setup_save_theme (GtkButton *button, GtkListStore *store)
+{
+   GtkComboBoxEntry *centry;
+   gchar *title;
+   GtkTreeIter iter;
+   gboolean theme_exists;
+   struct SearchThemeForeachParams search_params;
+
+   centry = g_object_get_data (G_OBJECT (button), "entry");
+   if (centry == NULL)
+      return;
+
+   title = gtk_combo_box_get_active_text (GTK_COMBO_BOX (centry));
+   if (title == NULL)
+      return;
+
+   if (strcmp (title, str_current_scheme) == 0) {
+      palette_save (NULL);
+      goto _return;
+   }
+
+   if (strlen (title) == 0)
+      goto _return;
+
+   if (palette_save (title) != 0)
+      goto _return;
+
+   theme_exists = FALSE;
+   search_params.theme_exists = &theme_exists;
+   search_params.title = title;
+   gtk_tree_model_foreach (GTK_TREE_MODEL (store),
+      (GtkTreeModelForeachFunc) setup_search_theme_foreach, &search_params);
+
+   if (theme_exists)
+      goto _return;
+
+   gtk_list_store_append (store, &iter);
+   gtk_list_store_set (store, &iter, 0, title, -1);
+
+_return:
+   g_free (title);
+}
+
+static void
+setup_delete_theme (GtkButton *button, GtkComboBox *combo)
+{
+   GtkTreeModel *model;
+   GtkTreeIter iter;
+   gchar *title;
+   GString *filename;
+   GtkDialog *dialog;
+
+   model = gtk_combo_box_get_model (combo);
+
+   if (!gtk_combo_box_get_active_iter (combo, &iter))
+      return;
+
+   gtk_tree_model_get (model, &iter, 0, &title, -1);
+
+   if (strcmp (title, str_current_scheme) == 0) {
+      g_free (title);
+      return;
+   }
+
+   filename = g_string_new (get_xdir_fs ());
+   g_string_append (filename, "/colors_");
+   g_string_append (filename, title);
+   g_string_append (filename, ".conf");
+
+   dialog = GTK_DIALOG (gtk_message_dialog_new (
+            GTK_WINDOW (
+                  gtk_widget_get_ancestor (GTK_WIDGET (button),
+                                           GTK_TYPE_WINDOW)),
+            GTK_DIALOG_DESTROY_WITH_PARENT,
+            GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO,
+            _("Are you sure want to delete this theme?\nThe theme will be lost")));
+   if (gtk_dialog_run (dialog) == GTK_RESPONSE_YES) {
+      g_remove (filename->str);
+      gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
+      gtk_combo_box_set_active (combo, -1);
+      gtk_combo_box_set_title (combo, "");
+
+      gtk_entry_set_text (GTK_ENTRY (gtk_bin_get_child (GTK_BIN (combo))), "");
+   }
+
+   gtk_widget_destroy (GTK_WIDGET (dialog));
+
+   g_string_free (filename, TRUE);
+   g_free (title);
 }
 
 static GtkWidget *
 setup_create_color_page (void)
 {
-   GtkWidget *tab, *box, *label;
+   GtkWidget *tab, *box, *label,
+             *theme_entry, *pref_table,
+             *button, *hbox, *vbox;
    int i;
+   GtkWidget **color_buttons;
+   GtkListStore *theme_store;
+   GtkTreeIter tree_iter;
+   struct SetupSelectionParams *selection_params;
+
+   const int tab_offset = 1;
 
    box = gtk_vbox_new (FALSE, 0);
    gtk_container_set_border_width (GTK_CONTAINER (box), 6);
 
+   color_buttons = g_malloc (MAX_COL * sizeof *color_buttons);
+   for (i = 0; i < MAX_COL; i++)
+      color_buttons[i] = NULL;
+
    tab = gtk_table_new (9, 2, FALSE);
+
+   selection_params = g_malloc (sizeof (struct SetupSelectionParams));
+   selection_params->color_buttons = color_buttons;
+
+   g_object_set_data_full (G_OBJECT (tab), "_selection_params",
+                           selection_params,
+                           setup_color_page_destroy_notify);
+
+   pref_table = gtk_table_new (3, 2, FALSE);
+   gtk_container_set_border_width (GTK_CONTAINER (pref_table), 2);
+   gtk_table_set_row_spacings (GTK_TABLE (pref_table), 2);
+   gtk_table_set_col_spacings (GTK_TABLE (pref_table), 3);
+   gtk_box_pack_start (GTK_BOX (box), pref_table, FALSE, FALSE, 0);
+
+   setup_create_header (pref_table, 0, _("Color scheme"));
+   setup_create_toggleL (pref_table, 1, &guess_theme_setting);
+
+   hbox = gtk_hbox_new (FALSE, 5);
+   gtk_table_attach (GTK_TABLE (tab), hbox, 0, 23, 0, 1,
+         GTK_SHRINK | GTK_FILL, GTK_SHRINK, LABEL_INDENT, 0);
+
+   label = gtk_label_new (_("Scheme:"));
+   gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+   gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+
+   theme_store = gtk_list_store_new (1, G_TYPE_STRING);
+   gtk_list_store_append (theme_store, &tree_iter);
+   gtk_list_store_set (theme_store, &tree_iter, 0, str_current_scheme, -1);
+   setup_scan_for_themes (setup_scan_for_themes_cb, theme_store);
+
+   theme_entry = gtk_combo_box_entry_new_with_model (GTK_TREE_MODEL (theme_store), 0);
+   vbox = gtk_vbox_new (FALSE, 0);
+   gtk_box_pack_start (GTK_BOX (vbox), theme_entry, TRUE, FALSE, 0);
+   gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
+   g_signal_connect (G_OBJECT (theme_entry), "changed",
+                     G_CALLBACK (setup_theme_changed),
+                     selection_params);
+
+   button = gtk_button_new_from_stock (GTK_STOCK_SAVE);
+   g_object_set_data (G_OBJECT (button), "entry", theme_entry);
+   g_signal_connect (G_OBJECT (button), "clicked",
+                     G_CALLBACK (setup_save_theme),
+                     theme_store);
+   selection_params->save_button = button;
+   gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
+
+   g_object_unref (theme_store);
+
+   button = gtk_button_new_from_stock (GTK_STOCK_DELETE);
+   gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
+   g_signal_connect (G_OBJECT (button), "clicked",
+                     G_CALLBACK (setup_delete_theme),
+                     GTK_COMBO_BOX (theme_entry));
+   selection_params->delete_button = button;
+
    gtk_container_set_border_width (GTK_CONTAINER (tab), 6);
    gtk_table_set_row_spacings (GTK_TABLE (tab), 2);
    gtk_table_set_col_spacings (GTK_TABLE (tab), 3);
-   gtk_container_add (GTK_CONTAINER (box), tab);
+   gtk_box_pack_start (GTK_BOX (box), tab, FALSE, FALSE, 0);
 
-   setup_create_header (tab, 0, N_("Text Colors"));
+   setup_create_header (tab, tab_offset, N_("Text Colors"));
 
    label = gtk_label_new (_("mIRC colors:"));
    gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
-   gtk_table_attach (GTK_TABLE (tab), label, 2, 3, 1, 2,
+   gtk_table_attach (GTK_TABLE (tab), label, 2, 3, tab_offset + 1, tab_offset + 2,
                      GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, LABEL_INDENT, 0);
 
    for (i = 0; i < 16; i++)
-      setup_create_color_button (tab, i, 1, i+3);
+      setup_create_color_button (tab, i, tab_offset + 1, i+3, color_buttons);
 
    label = gtk_label_new (_("Local colors:"));
    gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
-   gtk_table_attach (GTK_TABLE (tab), label, 2, 3, 2, 3,
+   gtk_table_attach (GTK_TABLE (tab), label, 2, 3, tab_offset + 2, tab_offset + 3,
                      GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, LABEL_INDENT, 0);
 
    for (i = 16; i < 32; i++)
-      setup_create_color_button (tab, i, 2, (i+3) - 16);
+      setup_create_color_button (tab, i, tab_offset + 2, (i+3) - 16, color_buttons);
 
-   setup_create_other_color (_("Foreground:"), COL_FG, 3, tab);
-   setup_create_other_colorR (_("Background:"), COL_BG, 3, tab);
+   setup_create_other_color (_("Foreground:"), COL_FG, tab_offset + 3, tab, color_buttons);
+   setup_create_other_colorR (_("Background:"), COL_BG, tab_offset + 3, tab, color_buttons);
 
-   setup_create_header (tab, 5, N_("Marking Text"));
+   setup_create_header (tab, tab_offset + 5, N_("Marking Text"));
 
-   setup_create_other_color (_("Foreground:"), COL_MARK_FG, 6, tab);
-   setup_create_other_colorR (_("Background:"), COL_MARK_BG, 6, tab);
+   setup_create_other_color (_("Foreground:"), COL_MARK_FG, tab_offset + 6, tab, color_buttons);
+   setup_create_other_colorR (_("Background:"), COL_MARK_BG, tab_offset + 6, tab, color_buttons);
 
-   setup_create_header (tab, 8, N_("Interface Colors"));
+   setup_create_header (tab, tab_offset + 8, N_("Interface Colors"));
 
-   setup_create_other_color (_("New data:"), COL_NEW_DATA, 9, tab);
-   setup_create_other_colorR (_("Marker line:"), COL_MARKER, 9, tab);
-   setup_create_other_color (_("New message:"), COL_NEW_MSG, 10, tab);
-   setup_create_other_colorR (_("Away user:"), COL_AWAY, 10, tab);
-   setup_create_other_color (_("Highlight:"), COL_HILIGHT, 11, tab);
+   setup_create_other_color (_("New data:"), COL_NEW_DATA, tab_offset + 9, tab, color_buttons);
+   setup_create_other_colorR (_("Marker line:"), COL_MARKER, tab_offset + 9, tab, color_buttons);
+   setup_create_other_color (_("New message:"), COL_NEW_MSG, tab_offset + 10, tab, color_buttons);
+   setup_create_other_colorR (_("Away user:"), COL_AWAY, tab_offset + 10, tab, color_buttons);
+   setup_create_other_color (_("Highlight:"), COL_HILIGHT, tab_offset + 11, tab, color_buttons);
 
    return box;
 }
@@ -1966,6 +2265,14 @@
 #endif
 }
 
+void
+setup_apply_colors (void)
+{
+   color_change = TRUE;
+   setup_apply (&prefs);
+   color_change = FALSE;
+}
+
 #if 0
 static void
 setup_apply_cb (GtkWidget *but, GtkWidget *win)
@@ -1982,7 +2289,7 @@
    gtk_widget_destroy (win);
    setup_apply (&setup_prefs);
    save_config ();
-   palette_save ();
+   palette_save (NULL);
 }
 
 static GtkWidget *
diff -urN xchat2-orig/src/fe-gtk/setup.h xchat2/src/fe-gtk/setup.h
--- xchat2-orig/src/fe-gtk/setup.h   1970-01-01 03:00:00.000000000 +0300
+++ xchat2/src/fe-gtk/setup.h   2007-05-12 21:23:11.000000000 +0400
@@ -0,0 +1,5 @@
+void setup_apply_colors (void);
+
+extern void setup_scan_for_themes (void (*callback) (const gchar*, gpointer),
+                                   GtkListStore *store);
+


Dark color scheme (file colors_Dark.conf)
Code: Select all
color_259 = 3434 3434 3434
color_0 = cccc cccc cccc
color_1 = 98c6 98c6 98c6
color_2 = 0059 98c6 98c6
color_3 = 9d7b ffff 9d7b
color_4 = ffff 9b9b 9b9b
color_5 = ffff 9b6f 9b6f
color_6 = ffff 7fef fffe
color_7 = ffff aab2 81d2
color_8 = ffff e499 adcc
color_9 = aa74 ffff aa74
color_10 = 0000 e4ed e4ed
color_11 = 93c8 ffff e46a
color_12 = a108 a108 ffff
color_13 = ffff a2aa ffff
color_14 = 9ad6 9ad6 9ad6
color_15 = cc62 cc62 cc62
color_16 = cccc cccc cccc
color_17 = 9898 9898 9898
color_18 = a108 a108 ffff
color_19 = 9d9d ffff 9d9d
color_20 = ffff 9b9b 9b9b
color_21 = ffff 9b9b 9b9b
color_22 = ffff 7f7f ffff
color_23 = ffff aaaa 8181
color_24 = ffff e4e4 adad
color_25 = 0009 e4e4 adad
color_26 = 0000 e4e4 e4e4
color_27 = 9393 ffff e4e4
color_28 = a1a1 a1a1 ffff
color_29 = ffff a2a2 ffff
color_30 = 9a9a 9a9a 9a9a
color_31 = cccc cccc cccc
color_256 = ffff f113 b49d
color_257 = 5240 8d13 e2ba
color_258 = f18b f18b f18b
color_260 = ffff 824f 824f
color_261 = ffff 9060 9060
color_262 = 7bde 7bde ffff
color_263 = ffff 3fd1 3fd1
color_264 = a529 a529 a529
erdizz
 
Posts: 3
Joined: 12 May 2007 22:13

Update

Postby erdizz » 13 May 2007 10:44

I've updated the patch, you can find it by the same link:
http://mync.sourceforge.net/xchat_color_schemes.tar.gz

Changes:
* UI cleanup
* Use g_strdup_printf instead of snprintf to a limited buffer
* "scheme" instead of "theme" in all UI strings
erdizz
 
Posts: 3
Joined: 12 May 2007 22:13

One more tiny fix

Postby erdizz » 15 May 2007 11:15

After applying the patch, xchat created two tray icons istead of one, I've fixed that. Link to the patch is the same.
erdizz
 
Posts: 3
Joined: 12 May 2007 22:13


Return to Development

Who is online

Users browsing this forum: No registered users and 2 guests