<URL: http://bugs.freeciv.org/Ticket/Display.html?id=28301 >

> [EMAIL PROTECTED] - Sa 04. Aug 2007, 11:23:04]:
> 
> On 15/02/07, Christian Prochaska <[EMAIL PROTECTED]>
> wrote:
> >
> > Here's an updated patch that further sets the "Freeciv" theme as
> default
> > in the GTK+ client (until the user chooses another theme either in
> the
> > local options dialog or in the tileset).
> 
>  This means that "Freeciv" theme (#36054) must go in before this
> patch, right?
> 
> 
>  - ML
> 

Before or after. The client would fall back to the system default theme
if the Freeciv theme was not present. But it should go in as well.

Updated patches for the $client/$theme/$subtheme directory
structure are attached.
Index: client/options.h
===================================================================
--- client/options.h	(Revision 13149)
+++ client/options.h	(Arbeitskopie)
@@ -20,6 +20,7 @@
 extern char default_server_host[512];
 extern int default_server_port; 
 extern char default_metaserver[512];
+extern char default_theme_name[512];
 extern char default_tileset_name[512];
 extern char default_sound_set_name[512];
 extern char default_sound_plugin_name[512];
@@ -181,4 +182,3 @@
 void mapview_redraw_callback(struct client_option *option);
 
 #endif  /* FC__OPTIONS_H */
-
Index: client/gui-gtk-2.0/themes.c
===================================================================
--- client/gui-gtk-2.0/themes.c	(Revision 13149)
+++ client/gui-gtk-2.0/themes.c	(Arbeitskopie)
@@ -24,9 +24,13 @@
 #include "mem.h"
 #include "support.h"
 
+#include "gui_main.h"
+
 #include "themes_common.h"
 #include "themes_g.h"
 
+#define FC_GTK_DEFAULT_THEME_NAME "Freeciv"
+
 /* Array of default files. First num_default_files positions
  * are files returned by gtk_rc_get_default_files() on client startup.
  * There are two extra postions allocated in the array - one for
@@ -65,6 +69,7 @@
 *****************************************************************************/
 void gui_load_theme(const char *directory, const char *theme_name)
 {
+  GtkStyle *style;
   char buf[strlen(directory) + strlen(theme_name) + 32];
   
   load_default_files();
@@ -78,6 +83,13 @@
   gtk_rc_set_default_files(default_files);
 
   gtk_rc_reparse_all_for_settings(gtk_settings_get_default(), TRUE);
+    
+  /* the turn done button must have its own style. otherwise when we flash
+     the turn done button other widgets may flash too. */
+  if (!(style = gtk_rc_get_style(turn_done_button))) {
+    style = turn_done_button->style;
+  }
+  gtk_widget_set_style(turn_done_button, gtk_style_copy(style));
 }
 
 /*****************************************************************************
@@ -85,10 +97,34 @@
 *****************************************************************************/
 void gui_clear_theme(void)
 {
-  load_default_files();
-  default_files[num_default_files] = NULL;
-  gtk_rc_set_default_files(default_files);
-  gtk_rc_reparse_all_for_settings(gtk_settings_get_default(), TRUE);
+  GtkStyle *style;
+  bool theme_loaded;
+
+  /* try to load user defined theme */
+  theme_loaded = load_theme(default_theme_name);
+
+  /* no user defined theme loaded -> try to load Freeciv default theme */
+  if (!theme_loaded) {
+    theme_loaded = load_theme(FC_GTK_DEFAULT_THEME_NAME);
+    if (theme_loaded) {
+      sz_strlcpy(default_theme_name, FC_GTK_DEFAULT_THEME_NAME);
+    }
+  }
+    
+  /* still no theme loaded -> load system default theme */
+  if (!theme_loaded) {
+    load_default_files();
+    default_files[num_default_files] = NULL;
+    gtk_rc_set_default_files(default_files);
+    gtk_rc_reparse_all_for_settings(gtk_settings_get_default(), TRUE);
+      
+    /* the turn done button must have its own style. otherwise when we flash
+       the turn done button other widgets may flash too. */
+    if (!(style = gtk_rc_get_style(turn_done_button))) {
+      style = turn_done_button->style;
+    }
+    gtk_widget_set_style(turn_done_button, gtk_style_copy(style));
+  }
 }
 
 /*****************************************************************************
@@ -103,15 +139,28 @@
 {
   gchar *standard_dir;
   char *home_dir;
-  char **directories = fc_malloc(sizeof(char *) * 2);
+  int i;
 
-  *count = 0;
+  const char **data_directories = get_data_dirs(count);
+    
+  char **directories = fc_malloc(sizeof(char *) * (*count + 2));
+    
+  /* Freeciv-specific GTK+ themes directories */
+  for (i = 0; i < *count; i++) {
+    char buf[strlen(data_directories[i]) + strlen("/themes/gui-gtk-2.0") + 1];
+    
+    my_snprintf(buf, sizeof(buf), "%s/themes/gui-gtk-2.0", data_directories[i]);
 
+    directories[i] = mystrdup(buf);
+  }
+    
+  /* standard GTK+ themes directory (e.g. /usr/share/themes) */
   standard_dir = gtk_rc_get_theme_dir();
   directories[*count] = mystrdup(standard_dir);
   (*count)++;
   g_free(standard_dir);
 
+  /* user GTK+ themes directory (~/.themes) */
   home_dir = user_home_dir();
   if (home_dir) {
     char buf[strlen(home_dir) + 16];
Index: client/gui-gtk-2.0/gui_main.c
===================================================================
--- client/gui-gtk-2.0/gui_main.c	(Revision 13149)
+++ client/gui-gtk-2.0/gui_main.c	(Arbeitskopie)
@@ -847,7 +847,6 @@
 {
   GtkWidget *box, *ebox, *hbox, *sbox, *align, *label;
   GtkWidget *frame, *table, *table2, *paned, *sw, *text;
-  GtkStyle *style;
   int i;
   char buf[256];
   struct sprite *sprite;
@@ -1050,13 +1049,6 @@
   /* turn done */
   turn_done_button = gtk_button_new_with_label(_("Turn Done"));
 
-  /* the turn done button must have its own style. otherwise when we flash
-     the turn done button other widgets may flash too. */
-  if (!(style = gtk_rc_get_style(turn_done_button))) {
-    style = turn_done_button->style;
-  }
-  gtk_widget_set_style(turn_done_button, gtk_style_copy(style));
-
   gtk_table_attach_defaults(GTK_TABLE(table), turn_done_button, 0, 10, 2, 3);
 
   g_signal_connect(turn_done_button, "clicked",
Index: client/gui-gtk-2.0/theme_dlg.c
===================================================================
--- client/gui-gtk-2.0/theme_dlg.c	(Revision 0)
+++ client/gui-gtk-2.0/theme_dlg.c	(Revision 0)
@@ -0,0 +1,76 @@
+/********************************************************************** 
+ Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
+   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, 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.
+***********************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gtk/gtk.h>
+
+#include "fcintl.h"
+
+#include "options.h"
+
+#include "dialogs_g.h"
+
+static bool load_theme = FALSE;
+
+static void theme_suggestion_callback(GtkWidget *dlg, gint arg);
+
+/****************************************************************
+  Callback deciding if the theme may be loaded or not
+*****************************************************************/
+static void theme_suggestion_callback(GtkWidget *dlg, gint arg)
+{
+  load_theme = (arg == GTK_RESPONSE_YES);
+}
+
+/****************************************************************
+  Popup dialog asking if tileset suggested theme should be
+  used.
+*****************************************************************/
+bool popup_theme_suggestion_dialog(const char *theme_name)
+{
+  GtkWidget *dialog, *label;
+  char buf[1024];
+
+  dialog = gtk_dialog_new_with_buttons(_("Theme suggested"),
+                                       NULL,
+                                       0,
+                                       _("Load theme"),
+                                       GTK_RESPONSE_YES,
+                                       _("Keep current theme"),
+                                       GTK_RESPONSE_NO,
+                                       NULL);
+  gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_YES);
+  gtk_window_set_destroy_with_parent(GTK_WINDOW(dialog), TRUE);
+
+  my_snprintf(buf, sizeof(buf),
+              _("Tileset suggests using %s theme.\n"
+              "You are currently using %s."),
+              theme_name, default_theme_name);
+
+  label = gtk_label_new(buf);
+  gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), label);
+  gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_CENTER);
+  gtk_widget_show(label);
+
+  g_signal_connect(dialog, "response",
+                   G_CALLBACK(theme_suggestion_callback), NULL);
+
+  gtk_dialog_run(GTK_DIALOG(dialog));
+
+  gtk_widget_destroy(dialog);
+  
+  return load_theme;
+}
Index: client/gui-gtk-2.0/Makefile.am
===================================================================
--- client/gui-gtk-2.0/Makefile.am	(Revision 13149)
+++ client/gui-gtk-2.0/Makefile.am	(Arbeitskopie)
@@ -89,6 +89,7 @@
 	spaceshipdlg.h  \
 	sprite.c	\
 	sprite.h	\
+	theme_dlg.c	\
 	themes.c	\
 	wldlg.c		\
 	wldlg.h	
Index: client/include/dialogs_g.h
===================================================================
--- client/include/dialogs_g.h	(Revision 13149)
+++ client/include/dialogs_g.h	(Arbeitskopie)
@@ -18,6 +18,7 @@
 #include "fc_types.h"
 #include "nation.h"		/* Nation_type_id */
 #include "terrain.h"		/* enum tile_special_type */
+#include "unitlist.h"           /* struct unit_list */
 
 struct packet_nations_selected_info;
 
@@ -46,6 +47,7 @@
 void popup_sabotage_dialog(struct city *pcity);
 void popup_pillage_dialog(struct unit *punit, bv_special may_pillage);
 void popup_upgrade_dialog(struct unit_list *punits);
+bool popup_theme_suggestion_dialog(const char *theme_name);
 
 void popdown_all_game_dialogs(void);
 
Index: client/themes_common.c
===================================================================
--- client/themes_common.c	(Revision 13149)
+++ client/themes_common.c	(Arbeitskopie)
@@ -62,81 +62,23 @@
 ****************************************************************************/
 void init_themes(void)
 {
-  char **directories_paths = fc_malloc(sizeof(char *) * 2);
-  /* length of the directories_paths array */
-  int count = 0;
-  /* allocated size of the directories_paths array */
-  int t_size = 2;
-
-
   int i;
-
-  struct stat stat_result;
-  int gui_directories_count;
-  char **gui_directories;
-
-  char *directory_tokens[strlen(DEFAULT_DATA_PATH)];
-  int num_tokens;
-
-  /* Directories are separated with : or ; */
-  num_tokens = get_tokens(DEFAULT_DATA_PATH,
-                          directory_tokens,
-			  strlen(DEFAULT_DATA_PATH),
-			  ":;");
+    
+  /* get GUI-specific theme directories */
+  char **gui_directories =
+      get_gui_specific_themes_directories(&num_directories);
   
-  for (i = 0; i < num_tokens; i++) {
-    char buf[strlen(DEFAULT_DATA_PATH) + 16];
-
-    /* Check if there's 'themes' subdirectory */
-    my_snprintf(buf, sizeof(buf), "%s/themes", directory_tokens[i]);
+  directories = 
+      fc_malloc(sizeof(struct theme_directory) * num_directories);
+          
+  for (i = 0; i < num_directories; i++) {
+    directories[i].path = gui_directories[i];
     
-    free(directory_tokens[i]);
-    
-    if (stat(buf, &stat_result) != 0) {
-      continue;
-    }
-    if (!S_ISDIR(stat_result.st_mode)) {
-      continue;
-    }
-
-    /* Increase array size if needed */
-    if (t_size == count) {
-      directories_paths =
-	  fc_realloc(directories_paths, t_size * 2 * sizeof(char *));
-      t_size *= 2;
-    }
-
-    directories_paths[count] = mystrdup(buf);
-    count++;
-  }
-
-  /* Add gui specific directories */
-  gui_directories =
-      get_gui_specific_themes_directories(&gui_directories_count);
-
-  for (i = 0; i < gui_directories_count; i++) {
-    if (t_size == count) {
-      directories_paths =
-	  fc_realloc(directories_paths, t_size * 2 * sizeof(char *));
-      t_size *= 2;
-    }
-    /* We are responsible for freeing the memory, so we don't need to copy */
-    directories_paths[count++] = gui_directories[i];
-  }
-  free(gui_directories);
-
-  /* Load useable themes in those directories */
-  directories = fc_malloc(sizeof(struct theme_directory) * count);
-  for (i = 0; i < count; i++) {
-    directories[i].path = directories_paths[i];
-
-    /* Gui specific function must search for themes */
+    /* get useable themes in this directory */
     directories[i].themes =
-	get_useable_themes_in_directory(directories_paths[i],
+	get_useable_themes_in_directory(directories[i].path,
 					&(directories[i].num_themes));
   }
-  num_directories = count;
-  free(directories_paths);
 }
 
 /****************************************************************************
@@ -190,3 +132,12 @@
   }
   return FALSE;
 }
+
+/****************************************************************************
+  Wrapper for load_theme. It's is used by local options dialog
+****************************************************************************/
+void theme_reread_callback(struct client_option *option)
+{
+  assert(option->p_string_value && *option->p_string_value != '\0');
+  load_theme(option->p_string_value);
+}
Index: client/themes_common.h
===================================================================
--- client/themes_common.h	(Revision 13149)
+++ client/themes_common.h	(Arbeitskopie)
@@ -17,4 +17,5 @@
 void init_themes(void);
 const char** get_themes_list(void);
 bool load_theme(const char* theme_name);
+void theme_reread_callback(struct client_option *option);
 #endif
Index: client/tilespec.c
===================================================================
--- client/tilespec.c	(Revision 13149)
+++ client/tilespec.c	(Arbeitskopie)
@@ -4779,10 +4779,14 @@
 void tileset_use_prefered_theme(const struct tileset *t)
 {
   int i;
+    
   for (i = 0; i < t->num_prefered_themes; i++) {
-    freelog(LOG_DEBUG, "trying theme \"%s\".", t->prefered_themes[i]);
-    if (load_theme(t->prefered_themes[i])) {
-      return;
+    if (popup_theme_suggestion_dialog(t->prefered_themes[i])) {
+      freelog(LOG_DEBUG, "trying theme \"%s\".", t->prefered_themes[i]);
+      if (load_theme(t->prefered_themes[i])) {
+        sz_strlcpy(default_theme_name, t->prefered_themes[i]);
+        return;
+      }
     }
   }
   freelog(LOG_VERBOSE, "The tileset doesn't specify prefered themes or "
Index: client/options.c
===================================================================
--- client/options.c	(Revision 13149)
+++ client/options.c	(Arbeitskopie)
@@ -40,6 +40,7 @@
 #include "overview_common.h"
 #include "plrdlg_common.h"
 #include "servers.h"
+#include "themes_common.h"
 #include "tilespec.h"
 
 /** Defaults for options normally on command line **/
@@ -48,6 +49,7 @@
 char default_server_host[512] = "localhost";
 int  default_server_port = DEFAULT_SOCK_PORT;
 char default_metaserver[512] = METALIST_ADDR;
+char default_theme_name[512] = "\0";
 char default_tileset_name[512] = "\0";
 char default_sound_set_name[512] = "stdsounds";
 char default_sound_plugin_name[512] = "\0";
@@ -130,6 +132,10 @@
 		    "you restart Freeciv.  Changing this is the same as "
 		    "using the -P command-line option."),
 		 COC_SOUND, get_soundplugin_list, NULL),
+  GEN_STR_OPTION(default_theme_name, N_("Theme"),
+		 N_("By changing this option you change the active theme."),
+		 COC_GRAPHICS,
+		 get_themes_list, theme_reread_callback),
   GEN_STR_OPTION(default_tileset_name, N_("Tileset"),
 		 N_("By changing this option you change the active tileset. "
 		    "This is the same as using the -t command-line "
Index: common/nation.h
===================================================================
--- common/nation.h	(Revision 13145)
+++ common/nation.h	(Arbeitskopie)
@@ -16,6 +16,7 @@
 #include "shared.h"		/* MAX_LEN_NAME */
 
 #include "fc_types.h"
+#include "terrain.h"            /* MAX_NUM_TERRAINS */
 
 #define MAX_NUM_TECH_GOALS 10
 
Index: client/options.h
===================================================================
--- client/options.h	(Revision 13145)
+++ client/options.h	(Arbeitskopie)
@@ -20,6 +20,7 @@
 extern char default_server_host[512];
 extern int default_server_port; 
 extern char default_metaserver[512];
+extern char default_theme_name[512];
 extern char default_tileset_name[512];
 extern char default_sound_set_name[512];
 extern char default_sound_plugin_name[512];
@@ -199,4 +200,3 @@
 void mapview_redraw_callback(struct client_option *option);
 
 #endif  /* FC__OPTIONS_H */
-
Index: client/gui-gtk-2.0/themes.c
===================================================================
--- client/gui-gtk-2.0/themes.c	(Revision 13145)
+++ client/gui-gtk-2.0/themes.c	(Arbeitskopie)
@@ -24,9 +24,13 @@
 #include "mem.h"
 #include "support.h"
 
+#include "gui_main.h"
+
 #include "themes_common.h"
 #include "themes_g.h"
 
+#define FC_GTK_DEFAULT_THEME_NAME "Freeciv"
+
 /* Array of default files. First num_default_files positions
  * are files returned by gtk_rc_get_default_files() on client startup.
  * There are two extra postions allocated in the array - one for
@@ -65,6 +69,7 @@
 *****************************************************************************/
 void gui_load_theme(const char *directory, const char *theme_name)
 {
+  GtkStyle *style;
   char buf[strlen(directory) + strlen(theme_name) + 32];
   
   load_default_files();
@@ -78,6 +83,13 @@
   gtk_rc_set_default_files(default_files);
 
   gtk_rc_reparse_all_for_settings(gtk_settings_get_default(), TRUE);
+    
+  /* the turn done button must have its own style. otherwise when we flash
+     the turn done button other widgets may flash too. */
+  if (!(style = gtk_rc_get_style(turn_done_button))) {
+    style = turn_done_button->style;
+  }
+  gtk_widget_set_style(turn_done_button, gtk_style_copy(style));
 }
 
 /*****************************************************************************
@@ -85,10 +97,34 @@
 *****************************************************************************/
 void gui_clear_theme(void)
 {
-  load_default_files();
-  default_files[num_default_files] = NULL;
-  gtk_rc_set_default_files(default_files);
-  gtk_rc_reparse_all_for_settings(gtk_settings_get_default(), TRUE);
+  GtkStyle *style;
+  bool theme_loaded;
+
+  /* try to load user defined theme */
+  theme_loaded = load_theme(default_theme_name);
+
+  /* no user defined theme loaded -> try to load Freeciv default theme */
+  if (!theme_loaded) {
+    theme_loaded = load_theme(FC_GTK_DEFAULT_THEME_NAME);
+    if (theme_loaded) {
+      sz_strlcpy(default_theme_name, FC_GTK_DEFAULT_THEME_NAME);
+    }
+  }
+    
+  /* still no theme loaded -> load system default theme */
+  if (!theme_loaded) {
+    load_default_files();
+    default_files[num_default_files] = NULL;
+    gtk_rc_set_default_files(default_files);
+    gtk_rc_reparse_all_for_settings(gtk_settings_get_default(), TRUE);
+      
+    /* the turn done button must have its own style. otherwise when we flash
+       the turn done button other widgets may flash too. */
+    if (!(style = gtk_rc_get_style(turn_done_button))) {
+      style = turn_done_button->style;
+    }
+    gtk_widget_set_style(turn_done_button, gtk_style_copy(style));
+  }
 }
 
 /*****************************************************************************
@@ -103,15 +139,28 @@
 {
   gchar *standard_dir;
   char *home_dir;
-  char **directories = fc_malloc(sizeof(char *) * 2);
+  int i;
 
-  *count = 0;
+  const char **data_directories = get_data_dirs(count);
+    
+  char **directories = fc_malloc(sizeof(char *) * (*count + 2));
+    
+  /* Freeciv-specific GTK+ themes directories */
+  for (i = 0; i < *count; i++) {
+    char buf[strlen(data_directories[i]) + strlen("/themes/gui-gtk-2.0") + 1];
+    
+    my_snprintf(buf, sizeof(buf), "%s/themes/gui-gtk-2.0", data_directories[i]);
 
+    directories[i] = mystrdup(buf);
+  }
+    
+  /* standard GTK+ themes directory (e.g. /usr/share/themes) */
   standard_dir = gtk_rc_get_theme_dir();
   directories[*count] = mystrdup(standard_dir);
   (*count)++;
   g_free(standard_dir);
 
+  /* user GTK+ themes directory (~/.themes) */
   home_dir = user_home_dir();
   if (home_dir) {
     char buf[strlen(home_dir) + 16];
Index: client/gui-gtk-2.0/gui_main.c
===================================================================
--- client/gui-gtk-2.0/gui_main.c	(Revision 13145)
+++ client/gui-gtk-2.0/gui_main.c	(Arbeitskopie)
@@ -921,7 +921,6 @@
 {
   GtkWidget *box, *ebox, *hbox, *sbox, *align, *label;
   GtkWidget *frame, *table, *table2, *paned, *sw, *text;
-  GtkStyle *style;
   int i;
   char buf[256];
   struct sprite *sprite;
@@ -1124,13 +1123,6 @@
   /* turn done */
   turn_done_button = gtk_button_new_with_label(_("Turn Done"));
 
-  /* the turn done button must have its own style. otherwise when we flash
-     the turn done button other widgets may flash too. */
-  if (!(style = gtk_rc_get_style(turn_done_button))) {
-    style = turn_done_button->style;
-  }
-  gtk_widget_set_style(turn_done_button, gtk_style_copy(style));
-
   gtk_table_attach_defaults(GTK_TABLE(table), turn_done_button, 0, 10, 2, 3);
 
   g_signal_connect(turn_done_button, "clicked",
Index: client/gui-gtk-2.0/theme_dlg.c
===================================================================
--- client/gui-gtk-2.0/theme_dlg.c	(Revision 0)
+++ client/gui-gtk-2.0/theme_dlg.c	(Revision 0)
@@ -0,0 +1,76 @@
+/********************************************************************** 
+ Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
+   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, 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.
+***********************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gtk/gtk.h>
+
+#include "fcintl.h"
+
+#include "options.h"
+
+#include "dialogs_g.h"
+
+static bool load_theme = FALSE;
+
+static void theme_suggestion_callback(GtkWidget *dlg, gint arg);
+
+/****************************************************************
+  Callback deciding if the theme may be loaded or not
+*****************************************************************/
+static void theme_suggestion_callback(GtkWidget *dlg, gint arg)
+{
+  load_theme = (arg == GTK_RESPONSE_YES);
+}
+
+/****************************************************************
+  Popup dialog asking if tileset suggested theme should be
+  used.
+*****************************************************************/
+bool popup_theme_suggestion_dialog(const char *theme_name)
+{
+  GtkWidget *dialog, *label;
+  char buf[1024];
+
+  dialog = gtk_dialog_new_with_buttons(_("Theme suggested"),
+                                       NULL,
+                                       0,
+                                       _("Load theme"),
+                                       GTK_RESPONSE_YES,
+                                       _("Keep current theme"),
+                                       GTK_RESPONSE_NO,
+                                       NULL);
+  gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_YES);
+  gtk_window_set_destroy_with_parent(GTK_WINDOW(dialog), TRUE);
+
+  my_snprintf(buf, sizeof(buf),
+              _("Tileset suggests using %s theme.\n"
+              "You are currently using %s."),
+              theme_name, default_theme_name);
+
+  label = gtk_label_new(buf);
+  gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), label);
+  gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_CENTER);
+  gtk_widget_show(label);
+
+  g_signal_connect(dialog, "response",
+                   G_CALLBACK(theme_suggestion_callback), NULL);
+
+  gtk_dialog_run(GTK_DIALOG(dialog));
+
+  gtk_widget_destroy(dialog);
+  
+  return load_theme;
+}
Index: client/gui-gtk-2.0/Makefile.am
===================================================================
--- client/gui-gtk-2.0/Makefile.am	(Revision 13145)
+++ client/gui-gtk-2.0/Makefile.am	(Arbeitskopie)
@@ -91,6 +91,7 @@
 	spaceshipdlg.h  \
 	sprite.c	\
 	sprite.h	\
+	theme_dlg.c	\
 	themes.c	\
 	wldlg.c		\
 	wldlg.h	
Index: client/include/dialogs_g.h
===================================================================
--- client/include/dialogs_g.h	(Revision 13145)
+++ client/include/dialogs_g.h	(Arbeitskopie)
@@ -18,6 +18,7 @@
 #include "fc_types.h"
 #include "nation.h"		/* Nation_type_id */
 #include "terrain.h"		/* enum tile_special_type */
+#include "unitlist.h"           /* struct unit_list */
 
 struct packet_nations_selected_info;
 
@@ -47,6 +48,7 @@
 void popup_pillage_dialog(struct unit *punit, bv_special may_pillage,
                           struct base_type *pbase);
 void popup_upgrade_dialog(struct unit_list *punits);
+bool popup_theme_suggestion_dialog(const char *theme_name);
 
 void popdown_all_game_dialogs(void);
 
Index: client/themes_common.c
===================================================================
--- client/themes_common.c	(Revision 13145)
+++ client/themes_common.c	(Arbeitskopie)
@@ -62,81 +62,23 @@
 ****************************************************************************/
 void init_themes(void)
 {
-  char **directories_paths = fc_malloc(sizeof(char *) * 2);
-  /* length of the directories_paths array */
-  int count = 0;
-  /* allocated size of the directories_paths array */
-  int t_size = 2;
-
-
   int i;
-
-  struct stat stat_result;
-  int gui_directories_count;
-  char **gui_directories;
-
-  char *directory_tokens[strlen(DEFAULT_DATA_PATH)];
-  int num_tokens;
-
-  /* Directories are separated with : or ; */
-  num_tokens = get_tokens(DEFAULT_DATA_PATH,
-                          directory_tokens,
-			  strlen(DEFAULT_DATA_PATH),
-			  ":;");
+    
+  /* get GUI-specific theme directories */
+  char **gui_directories =
+      get_gui_specific_themes_directories(&num_directories);
   
-  for (i = 0; i < num_tokens; i++) {
-    char buf[strlen(DEFAULT_DATA_PATH) + 16];
-
-    /* Check if there's 'themes' subdirectory */
-    my_snprintf(buf, sizeof(buf), "%s/themes", directory_tokens[i]);
+  directories = 
+      fc_malloc(sizeof(struct theme_directory) * num_directories);
+          
+  for (i = 0; i < num_directories; i++) {
+    directories[i].path = gui_directories[i];
     
-    free(directory_tokens[i]);
-    
-    if (stat(buf, &stat_result) != 0) {
-      continue;
-    }
-    if (!S_ISDIR(stat_result.st_mode)) {
-      continue;
-    }
-
-    /* Increase array size if needed */
-    if (t_size == count) {
-      directories_paths =
-	  fc_realloc(directories_paths, t_size * 2 * sizeof(char *));
-      t_size *= 2;
-    }
-
-    directories_paths[count] = mystrdup(buf);
-    count++;
-  }
-
-  /* Add gui specific directories */
-  gui_directories =
-      get_gui_specific_themes_directories(&gui_directories_count);
-
-  for (i = 0; i < gui_directories_count; i++) {
-    if (t_size == count) {
-      directories_paths =
-	  fc_realloc(directories_paths, t_size * 2 * sizeof(char *));
-      t_size *= 2;
-    }
-    /* We are responsible for freeing the memory, so we don't need to copy */
-    directories_paths[count++] = gui_directories[i];
-  }
-  free(gui_directories);
-
-  /* Load useable themes in those directories */
-  directories = fc_malloc(sizeof(struct theme_directory) * count);
-  for (i = 0; i < count; i++) {
-    directories[i].path = directories_paths[i];
-
-    /* Gui specific function must search for themes */
+    /* get useable themes in this directory */
     directories[i].themes =
-	get_useable_themes_in_directory(directories_paths[i],
+	get_useable_themes_in_directory(directories[i].path,
 					&(directories[i].num_themes));
   }
-  num_directories = count;
-  free(directories_paths);
 }
 
 /****************************************************************************
@@ -190,3 +132,12 @@
   }
   return FALSE;
 }
+
+/****************************************************************************
+  Wrapper for load_theme. It's is used by local options dialog
+****************************************************************************/
+void theme_reread_callback(struct client_option *option)
+{
+  assert(option->p_string_value && *option->p_string_value != '\0');
+  load_theme(option->p_string_value);
+}
Index: client/themes_common.h
===================================================================
--- client/themes_common.h	(Revision 13145)
+++ client/themes_common.h	(Arbeitskopie)
@@ -17,4 +17,5 @@
 void init_themes(void);
 const char** get_themes_list(void);
 bool load_theme(const char* theme_name);
+void theme_reread_callback(struct client_option *option);
 #endif
Index: client/tilespec.c
===================================================================
--- client/tilespec.c	(Revision 13145)
+++ client/tilespec.c	(Arbeitskopie)
@@ -4993,10 +4993,14 @@
 void tileset_use_prefered_theme(const struct tileset *t)
 {
   int i;
+    
   for (i = 0; i < t->num_prefered_themes; i++) {
-    freelog(LOG_DEBUG, "trying theme \"%s\".", t->prefered_themes[i]);
-    if (load_theme(t->prefered_themes[i])) {
-      return;
+    if (popup_theme_suggestion_dialog(t->prefered_themes[i])) {
+      freelog(LOG_DEBUG, "trying theme \"%s\".", t->prefered_themes[i]);
+      if (load_theme(t->prefered_themes[i])) {
+        sz_strlcpy(default_theme_name, t->prefered_themes[i]);
+        return;
+      }
     }
   }
   freelog(LOG_VERBOSE, "The tileset doesn't specify prefered themes or "
Index: client/options.c
===================================================================
--- client/options.c	(Revision 13145)
+++ client/options.c	(Arbeitskopie)
@@ -41,6 +41,7 @@
 #include "overview_common.h"
 #include "plrdlg_common.h"
 #include "servers.h"
+#include "themes_common.h"
 #include "tilespec.h"
 
 /** Defaults for options normally on command line **/
@@ -49,6 +50,7 @@
 char default_server_host[512] = "localhost";
 int  default_server_port = DEFAULT_SOCK_PORT;
 char default_metaserver[512] = METALIST_ADDR;
+char default_theme_name[512] = "\0";
 char default_tileset_name[512] = "\0";
 char default_sound_set_name[512] = "stdsounds";
 char default_sound_plugin_name[512] = "\0";
@@ -132,6 +134,10 @@
 		    "you restart Freeciv.  Changing this is the same as "
 		    "using the -P command-line option."),
 		 COC_SOUND, get_soundplugin_list, NULL),
+  GEN_STR_OPTION(default_theme_name, N_("Theme"),
+		 N_("By changing this option you change the active theme."),
+		 COC_GRAPHICS,
+		 get_themes_list, theme_reread_callback),
   GEN_STR_OPTION(default_tileset_name, N_("Tileset"),
 		 N_("By changing this option you change the active tileset. "
 		    "This is the same as using the -t command-line "
_______________________________________________
Freeciv-dev mailing list
Freeciv-dev@gna.org
https://mail.gna.org/listinfo/freeciv-dev

Reply via email to