[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
gEDA-user: gschem: Replace recent-file-list by gtk-type
Hello,
attached is a patch, witch will replace the implemented recent-file-list
of gschem by a recent-file-list, which used gtk-default-functions.
Why do I think this patch is useful?
- This patch reduces the code-size of about 200 lines (smaller code,
easier to read & debug).
- No external file to store the list
- There is more documentation and examples available for gtk-functions
than for own functions
It has some differences to the actual version:
- No 'free recent list' option (is this function really needed?)
- Shows just filename (not full path) as menu-label
- Full file-path available as tooltip
- Shows filetype-icons
Potential drawbacks:
- This patch needs GTK 2.10 or newer. I am not sure, which is the actual
minimum gtk-version of gschem
Perhaps, some of you can test this patch and give some feedback (did I
introduce some new bugs?). Thank you :-)!
I am also working at a similar patch for pcb, but I have problems to
migrate it to the menu in a smooth way. And another problem: As far as I
know, pcb's minimum GTK-Version is 2.8. Can anybody tell me, if this is
actually true?
Kind regards,
Felix
From a997981178276b3fd932dd2ade685fce5ccb4090 Mon Sep 17 00:00:00 2001
From: Felix Ruoff <Felix@xxxxxxxxxxxxxxxxxx>
Date: Sat, 9 Oct 2010 21:22:14 +0200
Subject: [PATCH] Replace recent-file-list by gtk_recent_manager
This patch replaces the implemented recent-file - list by the recent-manager provided by GTK since version 2.10.
Known differences to previous version:
* No 'free recent list' option
* Shows just filename (not full path) as menu-label
* Full file-path avaiable as tooltip
* Shows filetype-icons
---
gschem/include/globals.h | 3 +
gschem/include/prototype.h | 3 -
gschem/src/gschem.c | 5 -
gschem/src/x_menus.c | 318 ++++++--------------------------------------
gschem/src/x_window.c | 6 +-
5 files changed, 48 insertions(+), 287 deletions(-)
diff --git a/gschem/include/globals.h b/gschem/include/globals.h
index 8fbeb75..cb1fdb8 100644
--- a/gschem/include/globals.h
+++ b/gschem/include/globals.h
@@ -27,6 +27,9 @@ extern GSCHEM_TOPLEVEL *global_window_current;
/* window list */
extern GList *global_window_list;
+/* Manager for recently used files */
+GtkRecentManager *recent_manager;
+
/* colors */
extern GdkColor white;
extern GdkColor black;
diff --git a/gschem/include/prototype.h b/gschem/include/prototype.h
index 5948c74..d0439a3 100644
--- a/gschem/include/prototype.h
+++ b/gschem/include/prototype.h
@@ -828,9 +828,6 @@ gint do_popup(GSCHEM_TOPLEVEL *w_current, GdkEventButton *event);
void x_menus_sensitivity(GSCHEM_TOPLEVEL *w_current, const char *buf, int flag);
void x_menus_popup_sensitivity(GSCHEM_TOPLEVEL *w_current, const char *buf, int flag);
void x_menu_attach_recent_files_submenu(GSCHEM_TOPLEVEL *w_current);
-void recent_files_load();
-void recent_files_save(gpointer user_data);
-void recent_files_add(const char *filename);
/* x_multiattrib.c */
void x_multiattrib_open (GSCHEM_TOPLEVEL *w_current);
void x_multiattrib_close (GSCHEM_TOPLEVEL *w_current);
diff --git a/gschem/src/gschem.c b/gschem/src/gschem.c
index b47d503..1b96a12 100644
--- a/gschem/src/gschem.c
+++ b/gschem/src/gschem.c
@@ -259,11 +259,6 @@ void main_prog(void *closure, int argc, char *argv[])
free (input_str); /* M'allocated by scm_to_locale_string() */
scm_remember_upto_here_1 (scm_tmp);
- /* Load recent files list. This must be done
- * before calling x_window_setup(). */
- recent_files_load();
- gschem_atexit(recent_files_save, NULL);
-
/* Set default icon */
x_window_set_default_icon();
diff --git a/gschem/src/x_menus.c b/gschem/src/x_menus.c
index 63fe5a6..8b729f5 100644
--- a/gschem/src/x_menus.c
+++ b/gschem/src/x_menus.c
@@ -26,8 +26,6 @@
#include "gschem.h"
-#include <glib/gstdio.h>
-
#ifdef HAVE_LIBDMALLOC
#include <dmalloc.h>
#endif
@@ -359,91 +357,31 @@ void x_menus_popup_sensitivity (GSCHEM_TOPLEVEL *w_current, const char *buf, int
}
}
-/* The list of recently loaded files. */
-static GList *recent_files = NULL;
-#define RECENT_FILES_STORE "gschem-recent-files"
#define MAX_RECENT_FILES 10
-
-struct recent_file_menu_data {
- GSCHEM_TOPLEVEL *w_current;
- gchar *filename;
-};
-
-/*! \brief Make all toplevels reflect changes to the
- * recent files list.
- */
-static void update_recent_files_menus()
-{
- GSCHEM_TOPLEVEL *w_current;
- GtkWidget *submenu, *recent_menu_item;
- GList *iter;
-
- for (iter = global_window_list;
- iter != NULL;
- iter = g_list_next (iter)) {
- w_current = (GSCHEM_TOPLEVEL *)iter->data;
-
- if (w_current->menubar == NULL)
- continue;
-
- recent_menu_item =
- (GtkWidget *) gtk_object_get_data(GTK_OBJECT(w_current->menubar),
- "_File/Open Recen_t");
- if(recent_menu_item == NULL)
- return;
-
- submenu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(recent_menu_item));
- gtk_widget_destroy(submenu);
- x_menu_attach_recent_files_submenu(w_current);
- }
-}
-
-/*! \brief Remove all entries from the recent files
- * list and update all toplevels.
+/*! \brief Callback for recent-chooser.
+ *
+ * Will be proceeded if element of recent-file-list is activated
*/
-static void clear_recent_file_list(gpointer data)
+void
+recent_chooser_item_activated (GtkRecentChooser *chooser, GSCHEM_TOPLEVEL *w_current)
{
- GList *p;
+ PAGE *page;
+ gchar *uri;
+ char *filename;
+ GtkRecentInfo *recentInfo;
- p = recent_files;
- while(p) {
- g_free(p->data);
- p = g_list_next(p);
- }
- g_list_free(recent_files);
- recent_files = NULL;
+ uri = gtk_recent_chooser_get_current_uri (chooser);
+ filename = g_filename_from_uri(uri, NULL, NULL);
- update_recent_files_menus();
-}
+ recentInfo = gtk_recent_chooser_get_current_item(chooser);
+ gtk_recent_manager_add_item(recent_manager, uri);
-static void
-recent_file_free_menu_data (gpointer data, GClosure *closure) {
- g_free (data);
-}
+ page = x_window_open_page(w_current, (char *)filename);
+ x_window_set_current_page(w_current, page);
-static void recent_file_clicked(GtkMenuItem *menuitem, gpointer user_data)
-{
- FILE *fp;
- PAGE *page;
- struct recent_file_menu_data *data =
- (struct recent_file_menu_data *) user_data;
- GSCHEM_TOPLEVEL *w_current = data->w_current;
- gchar *filename = data->filename;
-
- /* Check if the file exists */
- fp = fopen((char *) filename, "r");
- if(fp == NULL) {
- /* Remove this entry from all menus */
- s_log_message(_("Couldn't open file %s\n"), (char *) filename);
- recent_files = g_list_remove(recent_files, filename);
- update_recent_files_menus();
- return;
- }
- fclose(fp);
-
- page = x_window_open_page(w_current, (char *)filename);
- x_window_set_current_page(w_current, page);
+ gtk_recent_info_unref(recentInfo);
+ g_free(uri);
}
/*! \brief Attach a submenu with filenames to the 'Open Recent'
@@ -453,203 +391,31 @@ static void recent_file_clicked(GtkMenuItem *menuitem, gpointer user_data)
*/
void x_menu_attach_recent_files_submenu(GSCHEM_TOPLEVEL *w_current)
{
- gulong id;
- GtkWidget *tmp;
- GtkWidget *recent_menu_item, *recent_submenu;
-
- recent_menu_item = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(
- w_current->menubar), "_File/Open Recen_t");
- if(recent_menu_item == NULL)
- return;
-
- /* disconnect all unblocked signals */
- while(1) {
- id = g_signal_handler_find(recent_menu_item, G_SIGNAL_MATCH_UNBLOCKED,
- 0, 0, NULL, NULL, NULL);
- if(id == 0)
- break;
- gtk_signal_disconnect(recent_menu_item, id);
- }
-
- recent_submenu = gtk_menu_new();
- GList *p = recent_files;
- while(p) {
- struct recent_file_menu_data *menu_data = g_new0 (struct recent_file_menu_data, 1);
- menu_data->filename = p->data;
- menu_data->w_current = w_current;
- tmp = gtk_menu_item_new_with_label((gchar *)p->data);
- g_signal_connect_data (GTK_OBJECT(tmp), "activate",
- (GCallback) recent_file_clicked,
- menu_data,
- (GClosureNotify) recent_file_free_menu_data,
- 0);
- gtk_menu_append(GTK_MENU(recent_submenu), tmp);
- p = g_list_next(p);
- }
-
- if(recent_files != NULL) {
- /* Append the 'Clear' menu item to the submenu */
- GtkWidget *alignment = gtk_alignment_new(0.5, 0, 0, 0);
-
- tmp = gtk_menu_item_new();
- gtk_container_add(GTK_CONTAINER(alignment), gtk_label_new(_("Clear")));
- gtk_container_add(GTK_CONTAINER(tmp), alignment);
-
- gtk_signal_connect_object(GTK_OBJECT(tmp), "activate",
- GTK_SIGNAL_FUNC (clear_recent_file_list), NULL);
-
- gtk_menu_append(GTK_MENU(recent_submenu), gtk_separator_menu_item_new());
- gtk_menu_append(GTK_MENU(recent_submenu), tmp);
- }
-
- gtk_widget_show_all(recent_submenu);
- gtk_menu_item_set_submenu(GTK_MENU_ITEM(recent_menu_item), recent_submenu);
-}
-
-/*! \brief Add a filename to the list of recent files.
- *
- * If filename is already in the list, moves it to the head of the
- * list.
- */
-void recent_files_add(const char *filename)
-{
- gchar *basename;
- gchar *save_fn;
- GError *err = NULL;
- GList *p = recent_files;
-
- basename = g_path_get_basename(filename);
- if(strstr(basename, "untitled_") == basename) {
- g_free(basename);
- return;
- }
-
- g_free(basename);
-
- /* Normalize the filename. */
- save_fn = f_normalize_filename (filename, &err);
- if (err != NULL) {
- save_fn = g_strdup (filename);
- g_error_free (err);
- }
-
- /* Check if the file is already in the list. */
- while (p != NULL) {
- if (strcmp (save_fn, (gchar *) p->data) == 0) {
- break;
- }
- p = g_list_next (p);
- }
-
- if (p != NULL) {
- /* Since we found the filename already in the list, move it to
- * the head of the list. */
- g_free (save_fn);
- save_fn = (gchar *) p->data;
- recent_files = g_list_delete_link (recent_files, p);
- recent_files = g_list_prepend (recent_files, save_fn);
- } else {
- /* Otherwise, just add the new filename to the front of the
- * list. */
- recent_files = g_list_prepend (recent_files, save_fn);
- }
-
- update_recent_files_menus();
-}
+ GtkWidget* menuitem_to_append_to = NULL;
+ GtkRecentFilter *recent_filter;
+ GtkWidget *menuitem_file_recent_items;
-/*! \brief Make RECENT_FILES_STORE contain an empty file list.
- */
-static void recent_files_create_empty()
-{
- gchar *c;
- const gchar * const tmp[] = { NULL };
- GKeyFile *kf = g_key_file_new();
- gchar *file = g_build_filename(s_path_user_config (), RECENT_FILES_STORE, NULL);
-
- g_key_file_set_string_list(kf, "Recent files", "Files", tmp, 0);
- c = g_key_file_to_data(kf, NULL, NULL);
- g_key_file_free(kf);
-
- g_file_set_contents(file, c, -1, NULL);
- g_free(c);
- g_free(file);
-}
-
-/*! \brief Save the list of recent files to RECENT_FILES_STORE.
- *
- * \param [in] user_data unused
- */
-void recent_files_save(gpointer user_data)
-{
- gchar *files[MAX_RECENT_FILES];
- int num = 0;
- gchar *c;
- gchar *file = g_build_filename(s_path_user_config (), RECENT_FILES_STORE, NULL);
-
- GList *p = recent_files;
- if(p == NULL) {
- recent_files_create_empty();
- return;
- }
-
- while((p != NULL) && (num < MAX_RECENT_FILES)) {
- files[num++] = (gchar *)p->data;
- p = g_list_next(p);
- }
-
- GKeyFile *kf = g_key_file_new();
-
- g_key_file_set_string_list(kf, "Recent files", "Files",
- (const gchar **)files, num);
- c = g_key_file_to_data(kf, NULL, NULL);
- g_file_set_contents(file, c, -1, NULL);
-
- g_free(c);
- g_free(file);
- g_key_file_free(kf);
-}
+ recent_manager = gtk_recent_manager_get_default();
+
+ recent_filter = gtk_recent_filter_new();
+ gtk_recent_filter_add_mime_type(recent_filter, "application/x-geda-schematic");
+ gtk_recent_filter_add_mime_type(recent_filter, "application/x-geda-symbol");
+
+ menuitem_file_recent_items = gtk_recent_chooser_menu_new_for_manager(recent_manager);
+
+ gtk_recent_chooser_add_filter(GTK_RECENT_CHOOSER(menuitem_file_recent_items), recent_filter);
+ gtk_recent_chooser_set_show_tips(GTK_RECENT_CHOOSER(menuitem_file_recent_items), TRUE);
+ gtk_recent_chooser_set_sort_type(GTK_RECENT_CHOOSER(menuitem_file_recent_items),
+ GTK_RECENT_SORT_MRU);
+ gtk_recent_chooser_set_limit(GTK_RECENT_CHOOSER(menuitem_file_recent_items), MAX_RECENT_FILES);
+ gtk_recent_chooser_set_local_only(GTK_RECENT_CHOOSER(menuitem_file_recent_items), FALSE);
+ gtk_recent_chooser_menu_set_show_numbers(GTK_RECENT_CHOOSER_MENU(menuitem_file_recent_items), TRUE);
+ g_signal_connect(GTK_OBJECT(menuitem_file_recent_items), "item-activated",
+ G_CALLBACK(recent_chooser_item_activated), w_current);
+
+ menuitem_to_append_to = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(w_current->menubar), "_File/Open Recen_t");
+ if(menuitem_to_append_to == NULL)
+ return;
-/*! \brief Load the recent file list using data from
- * RECENT_FILES_STORE.
- *
- * Must be called before any other recent-files-related
- * functions.
- */
-void recent_files_load()
-{
- GKeyFile *kf = g_key_file_new();
- gchar *file = g_build_filename(s_path_user_config (), RECENT_FILES_STORE, NULL);
-
- if(!g_file_test(file, G_FILE_TEST_EXISTS)) {
- g_mkdir(s_path_user_config (), S_IRWXU | S_IRWXG);
-
- recent_files_create_empty();
- }
-
- if(!g_key_file_load_from_file(kf, file, G_KEY_FILE_NONE, NULL)) {
- /* error opening key file, create an empty one and try again */
- recent_files_create_empty();
- if(!g_key_file_load_from_file(kf, file, G_KEY_FILE_NONE, NULL))
- return;
- }
-
- gsize len;
- gchar **list = g_key_file_get_string_list(kf, "Recent files",
- "Files", &len, NULL);
-
- if(list == NULL) {
- /* error reading key file, don't bother to correct;
- * just overwrite it with an empty one */
- recent_files_create_empty();
- return;
- }
-
- while(len > 0) {
- len--;
- recent_files = g_list_prepend(recent_files, list[len]);
- }
-
- g_free(list);
- g_free(file);
- g_key_file_free(kf);
+ gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem_to_append_to), menuitem_file_recent_items);
}
diff --git a/gschem/src/x_window.c b/gschem/src/x_window.c
index 07beb6e..8e358e7 100644
--- a/gschem/src/x_window.c
+++ b/gschem/src/x_window.c
@@ -743,7 +743,7 @@ x_window_open_page (GSCHEM_TOPLEVEL *w_current, const gchar *filename)
gtk_widget_destroy (dialog);
g_error_free (err);
} else {
- recent_files_add (fn);
+ gtk_recent_manager_add_item (recent_manager, g_filename_to_uri(fn, NULL, NULL));
}
} else {
if (!quiet_mode)
@@ -873,8 +873,8 @@ x_window_save_page (GSCHEM_TOPLEVEL *w_current, PAGE *page, const gchar *filenam
/* reset page CHANGED flag */
page->CHANGED = 0;
- /* update recent file list */
- recent_files_add(filename);
+ /* add to recent file list */
+ gtk_recent_manager_add_item (recent_manager, g_filename_to_uri(filename, NULL, NULL));
}
/* log status of operation */
--
1.7.1
_______________________________________________
geda-user mailing list
geda-user@xxxxxxxxxxxxxx
http://www.seul.org/cgi-bin/mailman/listinfo/geda-user