[Thoggen-cvs] SF.net SVN: thoggen: [294] trunk/thoggen
Status: Beta
Brought to you by:
tp-m
From: <tp...@us...> - 2008-01-24 18:47:16
|
Revision: 294 http://thoggen.svn.sourceforge.net/thoggen/?rev=294&view=rev Author: tp-m Date: 2008-01-24 10:42:04 -0800 (Thu, 24 Jan 2008) Log Message: ----------- * src/th-app-window.c: (APPWIN_NUM_RECENT_ITEMS), (appwin_ui_description), (app_window_destroy_cb), (RECENT_FILE_TYPE_ISO_IMAGE), (RECENT_FILE_TYPE_DVD_VIDEO_TS_DIR), (ThAppWindowRecentFileType), (appwin_add_recent), (escape_label_for_menu), (appwin_recent_items_cmp), (appwin_recent_manager_changed_cb), (app_window_setup_recent_manager), (app_window_instance_init), (app_window_finalize), (app_window_add_menubar), (appwin_action_open_vob_folder_cb), (appwin_action_open_iso_file_cb), (appwin_action_edit_prefs_cb), (appwin_action_activate_recent_file_cb): Keep track of recent .iso files and VIDEO_TS directories (code heavily inspired by totem's implementation). Modified Paths: -------------- trunk/thoggen/ChangeLog trunk/thoggen/src/th-app-window.c Modified: trunk/thoggen/ChangeLog =================================================================== --- trunk/thoggen/ChangeLog 2008-01-22 21:13:38 UTC (rev 293) +++ trunk/thoggen/ChangeLog 2008-01-24 18:42:04 UTC (rev 294) @@ -1,3 +1,19 @@ +2008-01-24 Tim-Philipp Müller <tim at centricular dot net> + + * src/th-app-window.c: (APPWIN_NUM_RECENT_ITEMS), + (appwin_ui_description), (app_window_destroy_cb), + (RECENT_FILE_TYPE_ISO_IMAGE), (RECENT_FILE_TYPE_DVD_VIDEO_TS_DIR), + (ThAppWindowRecentFileType), (appwin_add_recent), + (escape_label_for_menu), (appwin_recent_items_cmp), + (appwin_recent_manager_changed_cb), + (app_window_setup_recent_manager), (app_window_instance_init), + (app_window_finalize), (app_window_add_menubar), + (appwin_action_open_vob_folder_cb), (appwin_action_open_iso_file_cb), + (appwin_action_edit_prefs_cb), + (appwin_action_activate_recent_file_cb): + Keep track of recent .iso files and VIDEO_TS directories (code heavily + inspired by totem's implementation). + 2008-01-22 Tim-Philipp Müller <tim at centricular dot net> * src/th-job.c: (job_create_pipeline_setup_queues), Modified: trunk/thoggen/src/th-app-window.c =================================================================== --- trunk/thoggen/src/th-app-window.c 2008-01-22 21:13:38 UTC (rev 293) +++ trunk/thoggen/src/th-app-window.c 2008-01-24 18:42:04 UTC (rev 294) @@ -34,6 +34,9 @@ #include <string.h> #include <unistd.h> +/* How many recent items we want to display in the menu */ +#define APPWIN_NUM_RECENT_ITEMS 5 + enum { PROP_LAST_OUTPUT_DIRECTORY = 1 @@ -41,23 +44,28 @@ struct _ThAppWindowPrivate { - GtkActionGroup *action_group; + GtkUIManager *ui_manager; + GtkActionGroup *action_group; - ThPreferences *prefs; + GtkRecentManager *recent_manager; + GtkActionGroup *recent_action_group; + guint recent_ui_id; - GtkWidget *notebook; - GtkWidget *menubar; - GtkWidget *top_vbox; + ThPreferences *prefs; - GtkWidget *ts; - GtkWidget *jcd; - GtkWidget *jpd; + GtkWidget *notebook; + GtkWidget *menubar; + GtkWidget *top_vbox; - GtkWidget *prefs_dialog; + GtkWidget *ts; + GtkWidget *jcd; + GtkWidget *jpd; - GList *fake_dialogs; + GtkWidget *prefs_dialog; - gchar *last_output_dir; + GList *fake_dialogs; + + gchar *last_output_dir; }; static void app_window_class_init (ThAppWindowClass *klass); @@ -88,6 +96,8 @@ static void appwin_action_open_iso_file_cb (GtkAction *action, ThAppWindow *appwin); +static void appwin_action_activate_recent_file_cb (GtkAction *action, ThAppWindow *appwin); + /* variables */ static GtkWindowClass *appwin_parent_class; /* NULL */ @@ -165,6 +175,8 @@ " <menu action='FileMenu'>" " <menuitem action='OpenVOBFolder'/>" " <menuitem action='OpenISOFile'/>" +" <separator name='recent-separator'/>" +" <placeholder name='recent-placeholder'/>" " <separator />" " <menuitem action='Quit'/>" " </menu>" @@ -366,6 +378,183 @@ th_preferences_save (appwin->priv->prefs); } +typedef enum { + RECENT_FILE_TYPE_ISO_IMAGE = 0, + RECENT_FILE_TYPE_DVD_VIDEO_TS_DIR +} ThAppWindowRecentFileType; + +static void +appwin_add_recent (ThAppWindow * appwin, const gchar * filename, + ThAppWindowRecentFileType type) +{ + GtkRecentData data = { NULL, }; + gchar *groups[] = { "Thoggen", NULL, NULL }; + gchar *fn, *uri; + + if (type == RECENT_FILE_TYPE_ISO_IMAGE) + data.mime_type = "application/x-cd-image"; + else + data.mime_type = "application/x-octet"; + + data.display_name = NULL; + + fn = g_strdup (filename); + + if (type == RECENT_FILE_TYPE_ISO_IMAGE) { + groups[1] = "ThoggenIso"; + if (g_str_has_suffix (fn, ".iso") || g_str_has_suffix (fn, ".ISO")) { + fn[strlen(fn)-strlen(".iso")-1] = '\0'; + } + } else { + groups[1] = "ThoggenVideoTSDir"; + if (g_str_has_suffix (fn, "VIDEO_TS")) { + fn[strlen(fn)-strlen("VIDEO_TS")-1] = '\0'; + } + } + + data.display_name = g_filename_display_basename (fn); + + data.app_name = "Thoggen"; + data.app_exec = "thoggen"; + data.groups = groups; + + uri = g_filename_to_uri (filename, NULL, NULL); + if (uri) { + gtk_recent_manager_add_full (appwin->priv->recent_manager, uri, &data); + th_log ("Added recent file '%s': %s", data.display_name, uri); + } + + g_free (data.display_name); + + g_free (fn); + g_free (uri); +} + +/* Helper function to escape underscores in labels before putting them + * in menu items (since _ is used to indicate the keyboard shortcut) */ +static gchar * +escape_label_for_menu (const gchar * label) +{ + gchar *escaped, **arr; + + arr = g_strsplit (label, "_", -1); + escaped = g_strjoinv ("__", arr); + g_strfreev (arr); + + return escaped; +} + +/* Gah, why is this so painful? */ +static gint +appwin_recent_items_cmp (GtkRecentInfo *a, GtkRecentInfo *b) +{ + gboolean a_is_ours, b_is_ours; + + a_is_ours = gtk_recent_info_has_group (a, "Thoggen"); + b_is_ours = gtk_recent_info_has_group (b, "Thoggen"); + + if (a_is_ours && b_is_ours) + return gtk_recent_info_get_modified (b) - gtk_recent_info_get_modified (a); + else if (a_is_ours) + return -1; + else if (b_is_ours) + return 1; + + return 0; +} + +static void +appwin_recent_manager_changed_cb (ThAppWindow * appwin, GtkRecentManager * rm) +{ + GList *items, *l; + guint counter = 0; + + if (appwin->priv->recent_ui_id != 0) { + gtk_ui_manager_remove_ui (appwin->priv->ui_manager, + appwin->priv->recent_ui_id); + gtk_ui_manager_ensure_update (appwin->priv->ui_manager); + } + + if (appwin->priv->recent_action_group) { + gtk_ui_manager_remove_action_group (appwin->priv->ui_manager, + appwin->priv->recent_action_group); + g_object_unref (appwin->priv->recent_action_group); + } + + appwin->priv->recent_action_group = + gtk_action_group_new ("recent-action-group"); + + gtk_ui_manager_insert_action_group (appwin->priv->ui_manager, + appwin->priv->recent_action_group, -1); + + appwin->priv->recent_ui_id = + gtk_ui_manager_new_merge_id (appwin->priv->ui_manager); + + items = gtk_recent_manager_get_items (appwin->priv->recent_manager); + items = g_list_sort (items, (GCompareFunc) appwin_recent_items_cmp); + + for (l = items; l && l->data; l = l->next) { + const gchar *display_name; + GtkRecentInfo *info; + GtkAction *action; + gchar *action_name; + gchar *label; + gchar *escaped_label; + + info = (GtkRecentInfo *) l->data; + + if (!gtk_recent_info_has_group (info, "Thoggen")) + continue; + + action_name = g_strdup_printf ("OpenRecentFile%u", counter); + + display_name = gtk_recent_info_get_display_name (info); + th_log ("Found recent file: %s\n", display_name); + escaped_label = escape_label_for_menu (display_name); + + label = g_strdup_printf ("_%d. %s", counter + 1, escaped_label); + + action = gtk_action_new (action_name, label, NULL, NULL); + + g_object_set_data_full (G_OBJECT (action), "recent-info", + gtk_recent_info_ref (info), (GDestroyNotify) gtk_recent_info_unref); + + g_signal_connect (action, "activate", + G_CALLBACK (appwin_action_activate_recent_file_cb), appwin); + + gtk_action_group_add_action (appwin->priv->recent_action_group, action); + g_object_unref (action); + + gtk_ui_manager_add_ui (appwin->priv->ui_manager, appwin->priv->recent_ui_id, + "/MainMenu/FileMenu/recent-placeholder", label, action_name, + GTK_UI_MANAGER_MENUITEM, FALSE); + + g_free (escaped_label); + g_free (action_name); + g_free (label); + + ++counter; + if (counter == APPWIN_NUM_RECENT_ITEMS) + break; + } + + g_list_foreach (items, (GFunc) gtk_recent_info_unref, NULL); + g_list_free (items); +} + +static void +app_window_setup_recent_manager (ThAppWindow * appwin) +{ + appwin->priv->recent_manager = gtk_recent_manager_get_default (); + appwin->priv->recent_action_group = NULL; + appwin->priv->recent_ui_id = 0; + + g_signal_connect_swapped (appwin->priv->recent_manager, "changed", + G_CALLBACK (appwin_recent_manager_changed_cb), appwin); + + appwin_recent_manager_changed_cb (appwin, appwin->priv->recent_manager); +} + /*************************************************************************** * * app_window_instance_init @@ -384,6 +573,8 @@ app_window_add_menubar (appwin); + app_window_setup_recent_manager (appwin); + notebook = GTK_NOTEBOOK (gtk_notebook_new ()); appwin->priv->notebook = GTK_WIDGET (notebook); @@ -447,6 +638,9 @@ g_free (appwin->priv->last_output_dir); + if (appwin->priv->recent_action_group) + g_object_unref (appwin->priv->recent_action_group); + memset (appwin->priv, 0xab, sizeof (ThAppWindowPrivate)); g_free (appwin->priv); @@ -532,6 +726,7 @@ appwin->priv->menubar = menubar; appwin->priv->action_group = action_group; + appwin->priv->ui_manager = ui_manager; } /*************************************************************************** @@ -620,6 +815,7 @@ if (looksfine) { th_title_selector_add_vob_folder (TH_TITLE_SELECTOR (appwin->priv->ts), fn); + appwin_add_recent (appwin, fn, RECENT_FILE_TYPE_DVD_VIDEO_TS_DIR); } else { @@ -673,9 +869,10 @@ gtk_widget_destroy (fc); if (fn == NULL) - return; + return; th_title_selector_add_iso_file (TH_TITLE_SELECTOR (appwin->priv->ts), fn); + appwin_add_recent (appwin, fn, RECENT_FILE_TYPE_ISO_IMAGE); g_free (fn); } @@ -832,6 +1029,33 @@ gtk_window_present (GTK_WINDOW (appwin->priv->prefs_dialog)); } +static void +appwin_action_activate_recent_file_cb (GtkAction *action, ThAppWindow *appwin) +{ + GtkRecentInfo *recent_info; + const gchar *uri; + gchar *fn; + + recent_info = g_object_get_data (G_OBJECT (action), "recent-info"); + + uri = gtk_recent_info_get_uri (recent_info); + th_log ("recent file '%s' selected", uri); + + fn = g_filename_from_uri (uri, NULL, NULL); + if (fn == NULL) + return; + + if (gtk_recent_info_has_group (recent_info, "ThoggenVideoTSDir")) { + th_title_selector_add_vob_folder (TH_TITLE_SELECTOR (appwin->priv->ts), fn); + } else if (gtk_recent_info_has_group (recent_info, "ThoggenIso")) { + th_title_selector_add_iso_file (TH_TITLE_SELECTOR (appwin->priv->ts), fn); + } else { + th_log ("recent file item with unknown/unexpected groups"); + } + + g_free (fn); +} + /*************************************************************************** * * app_window_check_free_disk_space This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |