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

On 04/08/07, Christian Prochaska <[EMAIL PROTECTED]> wrote:
>
> Updated patches for the $client/$theme/$subtheme directory
> structure are attached.

 I updated these against latest svn and added dummy
popup_theme_suggestion_dialog() for other clients so they compile.


 - ML

diff -Nurd -X.diff_ignore freeciv/client/gui-ftwl/dialogs.c freeciv/client/gui-ftwl/dialogs.c
--- freeciv/client/gui-ftwl/dialogs.c	2007-08-06 19:29:10.000000000 +0300
+++ freeciv/client/gui-ftwl/dialogs.c	2007-08-07 17:17:50.000000000 +0300
@@ -376,3 +376,13 @@
 void popup_tileset_suggestion_dialog(void)
 {
 }
+
+/**************************************************************************
+  Tileset (modpack) has suggested loading certain theme. Confirm from
+  user and load.
+**************************************************************************/
+bool popup_theme_suggestion_dialog(const char *theme_name)
+{
+  /* Don't load */
+  return FALSE;
+}
diff -Nurd -X.diff_ignore freeciv/client/gui-gtk-2.0/gui_main.c freeciv/client/gui-gtk-2.0/gui_main.c
--- freeciv/client/gui-gtk-2.0/gui_main.c	2007-08-07 17:31:06.000000000 +0300
+++ freeciv/client/gui-gtk-2.0/gui_main.c	2007-08-07 16:59:21.000000000 +0300
@@ -923,7 +923,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;
@@ -1126,13 +1125,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",
diff -Nurd -X.diff_ignore freeciv/client/gui-gtk-2.0/Makefile.am freeciv/client/gui-gtk-2.0/Makefile.am
--- freeciv/client/gui-gtk-2.0/Makefile.am	2007-08-07 17:31:06.000000000 +0300
+++ freeciv/client/gui-gtk-2.0/Makefile.am	2007-08-07 16:59:21.000000000 +0300
@@ -91,6 +91,7 @@
 	spaceshipdlg.h  \
 	sprite.c	\
 	sprite.h	\
+	theme_dlg.c	\
 	themes.c	\
 	tileset_dlg.c	\
 	wldlg.c		\
diff -Nurd -X.diff_ignore freeciv/client/gui-gtk-2.0/theme_dlg.c freeciv/client/gui-gtk-2.0/theme_dlg.c
--- freeciv/client/gui-gtk-2.0/theme_dlg.c	1970-01-01 02:00:00.000000000 +0200
+++ freeciv/client/gui-gtk-2.0/theme_dlg.c	2007-08-07 16:59:21.000000000 +0300
@@ -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;
+}
diff -Nurd -X.diff_ignore freeciv/client/gui-gtk-2.0/themes.c freeciv/client/gui-gtk-2.0/themes.c
--- freeciv/client/gui-gtk-2.0/themes.c	2007-08-07 17:31:06.000000000 +0300
+++ freeciv/client/gui-gtk-2.0/themes.c	2007-08-07 16:59:21.000000000 +0300
@@ -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];
diff -Nurd -X.diff_ignore freeciv/client/gui-sdl/dialogs.c freeciv/client/gui-sdl/dialogs.c
--- freeciv/client/gui-sdl/dialogs.c	2007-08-06 18:09:20.000000000 +0300
+++ freeciv/client/gui-sdl/dialogs.c	2007-08-07 17:16:52.000000000 +0300
@@ -3089,3 +3089,13 @@
 void popup_tileset_suggestion_dialog(void)
 {
 }
+
+/**************************************************************************
+  Tileset (modpack) has suggested loading certain theme. Confirm from
+  user and load.
+**************************************************************************/
+bool popup_theme_suggestion_dialog(const char *theme_name)
+{
+  /* Don't load */
+  return FALSE;
+}
diff -Nurd -X.diff_ignore freeciv/client/gui-stub/dialogs.c freeciv/client/gui-stub/dialogs.c
--- freeciv/client/gui-stub/dialogs.c	2007-08-06 18:09:20.000000000 +0300
+++ freeciv/client/gui-stub/dialogs.c	2007-08-07 17:18:13.000000000 +0300
@@ -161,6 +161,16 @@
 }
 
 /**************************************************************************
+  Tileset (modpack) has suggested loading certain theme. Confirm from
+  user and load.
+**************************************************************************/
+bool popup_theme_suggestion_dialog(const char *theme_name)
+{
+  /* PORTME */
+  return FALSE;
+}
+
+/**************************************************************************
   This function is called when the client disconnects or the game is
   over.  It should close all dialog windows for that game.
 **************************************************************************/
diff -Nurd -X.diff_ignore freeciv/client/gui-win32/dialogs.c freeciv/client/gui-win32/dialogs.c
--- freeciv/client/gui-win32/dialogs.c	2007-08-06 18:09:20.000000000 +0300
+++ freeciv/client/gui-win32/dialogs.c	2007-08-07 17:18:32.000000000 +0300
@@ -1910,3 +1910,13 @@
 void popup_tileset_suggestion_dialog(void)
 {
 }
+
+/**************************************************************************
+  Tileset (modpack) has suggested loading certain theme. Confirm from
+  user and load.
+**************************************************************************/
+bool popup_theme_suggestion_dialog(const char *theme_name)
+{
+  /* Don't load */
+  return FALSE;
+}
diff -Nurd -X.diff_ignore freeciv/client/gui-xaw/dialogs.c freeciv/client/gui-xaw/dialogs.c
--- freeciv/client/gui-xaw/dialogs.c	2007-08-06 18:09:20.000000000 +0300
+++ freeciv/client/gui-xaw/dialogs.c	2007-08-07 17:17:32.000000000 +0300
@@ -1567,6 +1567,16 @@
 {
 }
 
+/**************************************************************************
+  Tileset (modpack) has suggested loading certain theme. Confirm from
+  user and load.
+**************************************************************************/
+bool popup_theme_suggestion_dialog(const char *theme_name)
+{
+  /* Don't load */
+  return FALSE;
+}
+
 /********************************************************************** 
   This function is called when the client disconnects or the game is
   over.  It should close all dialog windows for that game.
diff -Nurd -X.diff_ignore freeciv/client/include/dialogs_g.h freeciv/client/include/dialogs_g.h
--- freeciv/client/include/dialogs_g.h	2007-08-07 17:31:06.000000000 +0300
+++ freeciv/client/include/dialogs_g.h	2007-08-07 16:59:57.000000000 +0300
@@ -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;
 
@@ -48,6 +49,7 @@
                           struct base_type *pbase);
 void popup_upgrade_dialog(struct unit_list *punits);
 void popup_tileset_suggestion_dialog(void);
+bool popup_theme_suggestion_dialog(const char *theme_name);
 
 void popdown_all_game_dialogs(void);
 
diff -Nurd -X.diff_ignore freeciv/client/options.c freeciv/client/options.c
--- freeciv/client/options.c	2007-08-07 17:31:06.000000000 +0300
+++ freeciv/client/options.c	2007-08-07 16:59:21.000000000 +0300
@@ -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 "
diff -Nurd -X.diff_ignore freeciv/client/options.h freeciv/client/options.h
--- freeciv/client/options.h	2007-08-07 17:31:06.000000000 +0300
+++ freeciv/client/options.h	2007-08-07 16:59:21.000000000 +0300
@@ -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 */
-
diff -Nurd -X.diff_ignore freeciv/client/themes_common.c freeciv/client/themes_common.c
--- freeciv/client/themes_common.c	2007-08-07 17:31:06.000000000 +0300
+++ freeciv/client/themes_common.c	2007-08-07 16:59:21.000000000 +0300
@@ -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),
-			  ":;");
-  
-  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]);
     
-    free(directory_tokens[i]);
+  /* get GUI-specific theme directories */
+  char **gui_directories =
+      get_gui_specific_themes_directories(&num_directories);
+  
+  directories = 
+      fc_malloc(sizeof(struct theme_directory) * num_directories);
+          
+  for (i = 0; i < num_directories; i++) {
+    directories[i].path = gui_directories[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);
+}
diff -Nurd -X.diff_ignore freeciv/client/themes_common.h freeciv/client/themes_common.h
--- freeciv/client/themes_common.h	2007-08-07 17:31:06.000000000 +0300
+++ freeciv/client/themes_common.h	2007-08-07 16:59:21.000000000 +0300
@@ -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
diff -Nurd -X.diff_ignore freeciv/client/tilespec.c freeciv/client/tilespec.c
--- freeciv/client/tilespec.c	2007-08-07 17:31:06.000000000 +0300
+++ freeciv/client/tilespec.c	2007-08-07 16:59:21.000000000 +0300
@@ -4996,10 +4996,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 "
diff -Nurd -X.diff_ignore freeciv/common/nation.h freeciv/common/nation.h
--- freeciv/common/nation.h	2007-08-07 17:31:06.000000000 +0300
+++ freeciv/common/nation.h	2007-08-07 16:59:21.000000000 +0300
@@ -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
 
diff -Nurd -X.diff_ignore freeciv/client/gui-ftwl/dialogs.c freeciv/client/gui-ftwl/dialogs.c
--- freeciv/client/gui-ftwl/dialogs.c	2007-08-07 16:49:47.000000000 +0300
+++ freeciv/client/gui-ftwl/dialogs.c	2007-08-07 17:31:20.000000000 +0300
@@ -375,3 +375,13 @@
 void popup_tileset_suggestion_dialog(void)
 {
 }
+
+/**************************************************************************
+  Tileset (modpack) has suggested loading certain theme. Confirm from
+  user and load.
+**************************************************************************/
+bool popup_theme_suggestion_dialog(const char *theme_name)
+{
+  /* Don't load */
+  return FALSE;
+}
diff -Nurd -X.diff_ignore freeciv/client/gui-gtk-2.0/gui_main.c freeciv/client/gui-gtk-2.0/gui_main.c
--- freeciv/client/gui-gtk-2.0/gui_main.c	2007-08-05 20:22:42.000000000 +0300
+++ freeciv/client/gui-gtk-2.0/gui_main.c	2007-08-07 17:19:32.000000000 +0300
@@ -849,7 +849,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;
@@ -1052,13 +1051,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",
diff -Nurd -X.diff_ignore freeciv/client/gui-gtk-2.0/Makefile.am freeciv/client/gui-gtk-2.0/Makefile.am
--- freeciv/client/gui-gtk-2.0/Makefile.am	2007-08-07 16:49:47.000000000 +0300
+++ freeciv/client/gui-gtk-2.0/Makefile.am	2007-08-07 17:19:32.000000000 +0300
@@ -89,6 +89,7 @@
 	spaceshipdlg.h  \
 	sprite.c	\
 	sprite.h	\
+	theme_dlg.c	\
 	themes.c	\
 	tileset_dlg.c	\
 	wldlg.c		\
diff -Nurd -X.diff_ignore freeciv/client/gui-gtk-2.0/theme_dlg.c freeciv/client/gui-gtk-2.0/theme_dlg.c
--- freeciv/client/gui-gtk-2.0/theme_dlg.c	1970-01-01 02:00:00.000000000 +0200
+++ freeciv/client/gui-gtk-2.0/theme_dlg.c	2007-08-07 17:19:32.000000000 +0300
@@ -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;
+}
diff -Nurd -X.diff_ignore freeciv/client/gui-gtk-2.0/themes.c freeciv/client/gui-gtk-2.0/themes.c
--- freeciv/client/gui-gtk-2.0/themes.c	2007-03-05 19:14:30.000000000 +0200
+++ freeciv/client/gui-gtk-2.0/themes.c	2007-08-07 17:19:32.000000000 +0300
@@ -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];
diff -Nurd -X.diff_ignore freeciv/client/gui-sdl/dialogs.c freeciv/client/gui-sdl/dialogs.c
--- freeciv/client/gui-sdl/dialogs.c	2007-08-07 16:49:47.000000000 +0300
+++ freeciv/client/gui-sdl/dialogs.c	2007-08-07 17:31:20.000000000 +0300
@@ -3083,3 +3083,13 @@
 void popup_tileset_suggestion_dialog(void)
 {
 }
+
+/**************************************************************************
+  Tileset (modpack) has suggested loading certain theme. Confirm from
+  user and load.
+**************************************************************************/
+bool popup_theme_suggestion_dialog(const char *theme_name)
+{
+  /* Don't load */
+  return FALSE;
+}
diff -Nurd -X.diff_ignore freeciv/client/gui-stub/dialogs.c freeciv/client/gui-stub/dialogs.c
--- freeciv/client/gui-stub/dialogs.c	2007-08-07 16:49:47.000000000 +0300
+++ freeciv/client/gui-stub/dialogs.c	2007-08-07 17:31:20.000000000 +0300
@@ -160,6 +160,16 @@
 }
 
 /**************************************************************************
+  Tileset (modpack) has suggested loading certain theme. Confirm from
+  user and load.
+**************************************************************************/
+bool popup_theme_suggestion_dialog(const char *theme_name)
+{
+  /* PORTME */
+  return FALSE;
+}
+
+/**************************************************************************
   This function is called when the client disconnects or the game is
   over.  It should close all dialog windows for that game.
 **************************************************************************/
diff -Nurd -X.diff_ignore freeciv/client/gui-win32/dialogs.c freeciv/client/gui-win32/dialogs.c
--- freeciv/client/gui-win32/dialogs.c	2007-08-07 16:49:47.000000000 +0300
+++ freeciv/client/gui-win32/dialogs.c	2007-08-07 17:31:20.000000000 +0300
@@ -1914,3 +1914,13 @@
 void popup_tileset_suggestion_dialog(void)
 {
 }
+
+/**************************************************************************
+  Tileset (modpack) has suggested loading certain theme. Confirm from
+  user and load.
+**************************************************************************/
+bool popup_theme_suggestion_dialog(const char *theme_name)
+{
+  /* Don't load */
+  return FALSE;
+}
diff -Nurd -X.diff_ignore freeciv/client/gui-xaw/dialogs.c freeciv/client/gui-xaw/dialogs.c
--- freeciv/client/gui-xaw/dialogs.c	2007-08-07 16:49:47.000000000 +0300
+++ freeciv/client/gui-xaw/dialogs.c	2007-08-07 17:31:20.000000000 +0300
@@ -1555,6 +1555,16 @@
 {
 }
 
+/**************************************************************************
+  Tileset (modpack) has suggested loading certain theme. Confirm from
+  user and load.
+**************************************************************************/
+bool popup_theme_suggestion_dialog(const char *theme_name)
+{
+  /* Don't load */
+  return FALSE;
+}
+
 /********************************************************************** 
   This function is called when the client disconnects or the game is
   over.  It should close all dialog windows for that game.
diff -Nurd -X.diff_ignore freeciv/client/include/dialogs_g.h freeciv/client/include/dialogs_g.h
--- freeciv/client/include/dialogs_g.h	2007-08-07 16:49:47.000000000 +0300
+++ freeciv/client/include/dialogs_g.h	2007-08-07 17:19:32.000000000 +0300
@@ -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);
 void popup_upgrade_dialog(struct unit_list *punits);
 void popup_tileset_suggestion_dialog(void);
+bool popup_theme_suggestion_dialog(const char *theme_name);
 
 void popdown_all_game_dialogs(void);
 
diff -Nurd -X.diff_ignore freeciv/client/options.c freeciv/client/options.c
--- freeciv/client/options.c	2007-06-28 20:19:41.000000000 +0300
+++ freeciv/client/options.c	2007-08-07 17:19:32.000000000 +0300
@@ -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 "
diff -Nurd -X.diff_ignore freeciv/client/options.h freeciv/client/options.h
--- freeciv/client/options.h	2007-03-05 19:14:36.000000000 +0200
+++ freeciv/client/options.h	2007-08-07 17:19:32.000000000 +0300
@@ -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 */
-
diff -Nurd -X.diff_ignore freeciv/client/themes_common.c freeciv/client/themes_common.c
--- freeciv/client/themes_common.c	2007-03-05 19:14:36.000000000 +0200
+++ freeciv/client/themes_common.c	2007-08-07 17:19:32.000000000 +0300
@@ -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),
-			  ":;");
-  
-  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]);
     
-    free(directory_tokens[i]);
+  /* get GUI-specific theme directories */
+  char **gui_directories =
+      get_gui_specific_themes_directories(&num_directories);
+  
+  directories = 
+      fc_malloc(sizeof(struct theme_directory) * num_directories);
+          
+  for (i = 0; i < num_directories; i++) {
+    directories[i].path = gui_directories[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);
+}
diff -Nurd -X.diff_ignore freeciv/client/themes_common.h freeciv/client/themes_common.h
--- freeciv/client/themes_common.h	2007-03-05 19:14:36.000000000 +0200
+++ freeciv/client/themes_common.h	2007-08-07 17:19:32.000000000 +0300
@@ -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
diff -Nurd -X.diff_ignore freeciv/client/tilespec.c freeciv/client/tilespec.c
--- freeciv/client/tilespec.c	2007-08-04 00:29:09.000000000 +0300
+++ freeciv/client/tilespec.c	2007-08-07 17:19:32.000000000 +0300
@@ -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 "
_______________________________________________
Freeciv-dev mailing list
Freeciv-dev@gna.org
https://mail.gna.org/listinfo/freeciv-dev

Reply via email to