Aisleriot: Bug 323818 - Recent Games - Patch



All,

Here's the first cut at the Recently Played Games patch.

It uses a gconf key to store a comma-seperated list of game files
(*.scm) and keeps the most recent 5 games.

Playing a game that is already in the list moves that game to the head
of the list.

I'm attaching the patch here, but what is the official policy regarding 
that - should I post/attach it to Bugzilla?

-D
Index: aisleriot.schemas.in
===================================================================
RCS file: /cvs/gnome/gnome-games/aisleriot/aisleriot.schemas.in,v
retrieving revision 1.9
diff -u -u -r1.9 aisleriot.schemas.in
--- aisleriot.schemas.in	29 Jun 2004 11:47:35 -0000	1.9
+++ aisleriot.schemas.in	6 Aug 2006 02:28:43 -0000
@@ -85,6 +85,18 @@
 	<long>A list of strings that come in the form of a quintuple: name, wins, total games played, best time (in seconds) and worst time (also in seconds). Unplayed games do not need to be represented.</long>
       </locale>
     </schema>
+	
+	<schema>
+      <key>/schemas/apps/aisleriot/recent_games</key>
+      <applyto>/apps/aisleriot/recent_games</applyto>
+      <owner>aisleriot</owner>
+      <type>string</type>
+      <default></default>
+      <locale name="C">
+        <short>Recently Played Games</short>
+        <long>A comma seperated list of recently played games. The filenames are stored here, not the actual game name.</long>
+      </locale>
+     </schema>
 
   </schemalist>
 </gconfschemafile>
Index: menu.c
===================================================================
RCS file: /cvs/gnome/gnome-games/aisleriot/menu.c,v
retrieving revision 1.113
diff -u -u -r1.113 menu.c
--- menu.c	8 Jul 2006 09:01:27 -0000	1.113
+++ menu.c	6 Aug 2006 02:28:43 -0000
@@ -84,6 +84,18 @@
   new_game (NULL, NULL);
 };
 
+
+static void new_recent_game_action (GtkAction *action,
+								  	gpointer   user_data)
+{
+	if (user_data == NULL)
+		new_game (NULL, NULL);
+	else {
+		new_game ((gchar *) user_data, NULL);
+		g_free (user_data);
+	}
+};
+
 void undo_callback ()
 {
   if (waiting_for_mouse_up()) return;
@@ -102,7 +114,7 @@
 
 static void help_about_callback (void)
 {
-  const gchar *authors[] = {
+	const gchar *authors[] = {
 	  _("Main game:"),
 	  "Jonathan Blandford (jrb redhat com)",
 	  "Felix Bellaby (felix pooh u-net com)",
@@ -238,6 +250,7 @@
   { "NewGame", GAMES_STOCK_NEW_GAME, NULL, NULL, N_("Start a new game"), G_CALLBACK (new_game_action) },
   { "RestartGame", GAMES_STOCK_RESTART_GAME, NULL, NULL, N_("Restart the current game"), G_CALLBACK (restart_game) },
   { "Select", GTK_STOCK_INDEX, N_("_Select Game..."), "<Ctrl>o", N_("Play a different game"), G_CALLBACK (show_select_game_dialog) },
+  { "RecentlyPlayed", NULL, N_("Recently Played") },
   { "Statistics", GTK_STOCK_ADD, N_("S_tatistics"), NULL, N_("Show gameplay statistics"), G_CALLBACK (show_statistics_dialog) },
   { "Quit", GTK_STOCK_QUIT, NULL, NULL, NULL, G_CALLBACK (quit_app) },
   { "Fullscreen", GAMES_STOCK_FULLSCREEN, NULL, NULL, NULL, G_CALLBACK (fullscreen_callback) },
@@ -264,6 +277,7 @@
 "      <menuitem action='NewGame'/>"
 "      <menuitem action='RestartGame'/>"
 "      <menuitem action='Select'/>"
+"      <menu action='RecentlyPlayed'/>"
 "      <menuitem action='Statistics'/>"
 "      <separator/>"
 "      <menuitem action='Quit'/>"
@@ -310,6 +324,7 @@
   games_stock_init();
   action_group = gtk_action_group_new ("MenuActions");
   gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
+
   gtk_action_group_add_actions (action_group, actions, G_N_ELEMENTS (actions),
 				NULL); 
   gtk_action_group_add_toggle_actions (action_group, toggles, 
@@ -324,6 +339,9 @@
   accel_group = gtk_ui_manager_get_accel_group (ui_manager);
   gtk_window_add_accel_group (GTK_WINDOW (app), accel_group);
 
+  /* The actions and menus are done. Add the recently played games */
+  install_recently_played_menu ();
+
   undoaction = gtk_action_group_get_action (action_group, "UndoMove");
   redoaction = gtk_action_group_get_action (action_group, "RedoMove");
   restartaction = gtk_action_group_get_action (action_group, "RestartGame");
@@ -580,7 +598,7 @@
 	/* If we encounter an atom, change the mode. What the atom is doesn't
 	   really matter. */
 	if (mode == menu_normal) {
-	  mode = menu_radio;
+	  mode = menu_radio;	
 	  radiogroup = NULL; /* Start a new radio group. */
 	} else {
 	  mode = menu_normal;
@@ -588,4 +606,67 @@
       }
     }
   } 
+}
+
+/*
+ * Set up a sub-menu with the recently played games
+ * We'll keep track of 5 different games
+ */
+void install_recently_played_menu ()
+{
+	char*  game_file_name = NULL;
+	gchar* game_name      = NULL;
+	gchar* callback_data  = NULL;
+	
+	GtkAction *pAction = NULL;
+	GtkWidget *pWidget = NULL;
+	
+ 	/* Show the empty menu if they don't have any recent games yet */
+	GtkAction *action = gtk_action_group_get_action (action_group, "RecentlyPlayed");
+	if (action) {
+		g_object_set (action, "hide_if_empty", FALSE, NULL);
+	}
+
+	/* Get a list of the recent games */
+	GConfClient * gconf_client = gconf_client_get_default ();
+	
+	gchar* recent_games = gconf_client_get_string (gconf_client, RECENT_GAMES_GCONF_KEY, NULL);
+	
+	if (recent_games == NULL)
+		return;
+
+	/* Get the MenuItem that the RecentlyPlayed menu belongs to */
+	GtkWidget *recent_menu = gtk_ui_manager_get_widget (ui_manager, "/MainMenu/GameMenu/RecentlyPlayed");
+
+	if (recent_menu == NULL) return;	
+
+	gtk_menu_item_remove_submenu (GTK_MENU_ITEM (recent_menu));
+	
+	GtkWidget *submenu = gtk_menu_new();
+
+	game_file_name = strtok (recent_games, ",");
+
+	while (game_file_name != NULL) {
+		/* Create actions for the recent games */
+		game_name = game_file_to_name(game_file_name);
+		callback_data = g_strdup (game_file_name);
+
+		pAction = gtk_action_new(game_name, game_name, NULL, NULL);
+		
+		g_signal_connect (G_OBJECT (pAction), "activate",
+								G_CALLBACK (new_recent_game_action),
+								callback_data);
+
+		/* Turn them into widgets */
+		pWidget = gtk_action_create_menu_item(pAction);
+
+		/* Append the recent games to the submenu */
+		gtk_menu_shell_append ( GTK_MENU_SHELL (submenu), pWidget);
+
+		game_file_name = strtok (NULL, ",");
+	}
+
+	gtk_menu_item_set_submenu (GTK_MENU_ITEM (recent_menu), submenu);
+	
+	g_free (recent_games);
 }
Index: menu.h
===================================================================
RCS file: /cvs/gnome/gnome-games/aisleriot/menu.h,v
retrieving revision 1.19
diff -u -u -r1.19 menu.h
--- menu.h	21 Apr 2006 10:22:50 -0000	1.19
+++ menu.h	6 Aug 2006 02:28:43 -0000
@@ -28,6 +28,7 @@
 void option_list_set_sensitive (void);
 void help_update_game_name (gchar * name);
 void install_options_menu (gchar *name);
+void install_recently_played_menu (void);
 
 extern GtkUIManager *ui_manager;
 extern GtkWidget *menubar;
Index: sol.c
===================================================================
RCS file: /cvs/gnome/gnome-games/aisleriot/sol.c,v
retrieving revision 1.139
diff -u -u -r1.139 sol.c
--- sol.c	7 Jul 2006 21:28:12 -0000	1.139
+++ sol.c	6 Aug 2006 02:28:43 -0000
@@ -285,6 +285,8 @@
     game_over = FALSE;
     gtk_window_set_title (GTK_WINDOW (app), _(game_name)); 
   }
+  /* We've just started a new game. Add this to the list of games the user likes */
+  add_recently_played_game (file);
 }
 
 GtkWidget *score_value;
@@ -403,6 +405,55 @@
   }
 
   gtk_main_quit ();
+}
+
+/*
+ * Takes the name of the file that drives the game and
+ * stores it as a recently played game
+ * Recent games are stored at the end of the list.
+ */
+void add_recently_played_game (gchar* game_file)
+{
+	if (game_file == NULL) return;
+	
+	GConfClient * gconf_client = gconf_client_get_default ();
+	
+	gchar* recent_games = gconf_client_get_string (gconf_client, RECENT_GAMES_GCONF_KEY, NULL);
+	gchar* new_games = NULL;
+
+	if (recent_games == NULL)
+		new_games = g_strdup (game_file);		
+	else {		
+		gchar** games_list = g_strsplit (recent_games, (gchar *) ",", 0);
+
+		/* Start off with our latest game at the front */
+		new_games = g_strdup (game_file);
+		int game_count = 1;
+		int index      = 0;
+
+		while ((games_list[index] != NULL) && (game_count < 5)) {			
+			/* If the game is already in the list, don't add it again */
+			if (g_ascii_strcasecmp (game_file, games_list[index]) == 0 ) {
+				++index;
+				continue;
+			}
+			new_games = g_strconcat (new_games, (gchar *) ",", games_list[index], NULL);
+			
+			++game_count;			
+			++index;
+		}
+	
+		new_games = g_strconcat (new_games, NULL);
+		g_strfreev (games_list);
+	}
+	
+	/* Update the gconf key with the new list of games */
+	gconf_client_set_string (gconf_client, RECENT_GAMES_GCONF_KEY, new_games, NULL);
+
+	g_free (recent_games);
+	g_free (new_games);
+
+	install_recently_played_menu ();
 }
 
 static void create_main_window ()
Index: sol.h
===================================================================
RCS file: /cvs/gnome/gnome-games/aisleriot/sol.h,v
retrieving revision 1.32
diff -u -u -r1.32 sol.h
--- sol.h	21 Apr 2006 10:22:50 -0000	1.32
+++ sol.h	6 Aug 2006 02:28:43 -0000
@@ -35,6 +35,7 @@
 #define WIDTH_GCONF_KEY "/apps/aisleriot/width"
 #define HEIGHT_GCONF_KEY "/apps/aisleriot/height"
 #define THEME_GCONF_KEY "/apps/aisleriot/card_style"
+#define RECENT_GAMES_GCONF_KEY "/apps/aisleriot/recent_games"
 
 /* Feature masks */
 #define DROPPABLE_FMASK 1
@@ -79,5 +80,6 @@
 void timer_reset(void);
 guint timer_get(void);
 void eval_installed_file(gchar *file);
+void add_recently_played_game (gchar* game_file);
 
 #endif


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]