[balsa/remember-mailbox-positions: 2/4] Preserve tab order of open mailboxes
- From: Peter Bloomfield <peterb src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [balsa/remember-mailbox-positions: 2/4] Preserve tab order of open mailboxes
- Date: Sun, 24 Feb 2019 01:26:30 +0000 (UTC)
commit 4403340f41abc717c03bca8da1f992410b2136c9
Author: Peter Bloomfield <PeterBloomfield bellsouth net>
Date: Thu Feb 7 21:37:38 2019 -0500
Preserve tab order of open mailboxes
Preserve tab order of open mailboxes across instances (#12)
* libbalsa/mailbox.c (libbalsa_mailbox_set_position),
(libbalsa_mailbox_get_position): manage the mailbox's position
in the notebook;
(libbalsa_mailbox_set_open): unset the position when the
mailbox is closed;
* libbalsa/mailbox.h: new member 'position';
* libbalsa/mailbox_local.c (lbml_set_threading): guard against
NULL msg_tree;
* src/balsa-app.c (position_compare_func),
(balsa_add_open_mailbox_urls): sort the mailboxes to be opened
by their position in the last instance;
* src/balsa-app.h: new member 'gboolean in_destruction';
* src/balsa-index.c (bndx_destroy), (bndx_selection_changed),
(balsa_index_load_mailbox_node): take a strong ref on the
BalsaMailboxNode instead of a weak ref;
* src/mailbox-node.c (balsa_mailbox_node_dispose): do not bother
to close the mbnode;
* src/main-window.c (bw_notebook_page_notify_cb): callback for
the "child-notify::position" signal;
(bw_real_open_mbnode_idle_cb): connect to it;
(balsa_window_destroy): set 'in_destruction';
* src/save-restore.c (config_load_mailbox_view),
(config_save_mailbox_view): save and restore positions;
(config_mailbox_get_int_property),
(config_mailbox_get_position): new functions to get position;
* src/save-restore.h: new API.
ChangeLog | 31 ++++++++++++++++++++++++++++++
libbalsa/mailbox.c | 32 +++++++++++++++++++++++++++++--
libbalsa/mailbox.h | 3 +++
libbalsa/mailbox_local.c | 3 +++
src/balsa-app.c | 12 ++++++++++++
src/balsa-app.h | 2 ++
src/balsa-index.c | 50 ++++++++++++++++++++++--------------------------
src/main-window.c | 31 ++++++++++++++++++++++++++++--
src/save-restore.c | 41 ++++++++++++++++++++++++++++++++++++---
src/save-restore.h | 1 +
10 files changed, 172 insertions(+), 34 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 572d6ecc0..5c11c3064 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -218,6 +218,37 @@
* libbalsa/mailbox_pop3.c: Do not leak the filter-cmd
* libbalsa/address-book-rubrica.c: Do not leak the completion
+2019-02-07 Peter Bloomfield <pbloomfield bellsouth net>
+
+ Preserve tab order of open mailboxes across instances (#12)
+
+ * libbalsa/mailbox.c (libbalsa_mailbox_set_position),
+ (libbalsa_mailbox_get_position): manage the mailbox's position
+ in the notebook;
+ (libbalsa_mailbox_set_open): unset the position when the
+ mailbox is closed;
+ * libbalsa/mailbox.h: new member 'position';
+ * libbalsa/mailbox_local.c (lbml_set_threading): guard against
+ NULL msg_tree;
+ * src/balsa-app.c (position_compare_func),
+ (balsa_add_open_mailbox_urls): sort the mailboxes to be opened
+ by their position in the last instance;
+ * src/balsa-app.h: new member 'gboolean in_destruction';
+ * src/balsa-index.c (bndx_destroy), (bndx_selection_changed),
+ (balsa_index_load_mailbox_node): take a strong ref on the
+ BalsaMailboxNode instead of a weak ref;
+ * src/mailbox-node.c (balsa_mailbox_node_dispose): do not bother
+ to close the mbnode;
+ * src/main-window.c (bw_notebook_page_notify_cb): callback for
+ the "child-notify::position" signal;
+ (bw_real_open_mbnode_idle_cb): connect to it;
+ (balsa_window_destroy): set 'in_destruction';
+ * src/save-restore.c (config_load_mailbox_view),
+ (config_save_mailbox_view): save and restore positions;
+ (config_mailbox_get_int_property),
+ (config_mailbox_get_position): new functions to get position;
+ * src/save-restore.h: new API.
+
2019-02-04 Peter Bloomfield <pbloomfield bellsouth net>
* meson_options.txt: make 'autocrypt' a boolean option, default
diff --git a/libbalsa/mailbox.c b/libbalsa/mailbox.c
index 7c10b3371..8df9536eb 100644
--- a/libbalsa/mailbox.c
+++ b/libbalsa/mailbox.c
@@ -2304,7 +2304,8 @@ static LibBalsaMailboxView libbalsa_mailbox_view_default = {
#endif
-1, /* total messages */
-1, /* unread messages */
- 0 /* mod time */
+ 0, /* mod time */
+ -1 /* position */
};
LibBalsaMailboxView *
@@ -2465,8 +2466,11 @@ libbalsa_mailbox_set_open(LibBalsaMailbox * mailbox, gboolean open)
if (view->open != open) {
view->open = open ? 1 : 0;
- if (mailbox)
+ if (mailbox != NULL) {
+ if (!open)
+ view->position = -1;
view->in_sync = 0;
+ }
}
}
@@ -2549,6 +2553,23 @@ libbalsa_mailbox_set_mtime(LibBalsaMailbox * mailbox, time_t mtime)
}
}
+void
+libbalsa_mailbox_set_position(LibBalsaMailbox * mailbox, gint position)
+{
+ LibBalsaMailboxView *view;
+
+ /* Changing the default is not allowed. */
+ g_return_if_fail(mailbox != NULL);
+
+ view = lbm_get_view(mailbox);
+ view->used = 1;
+
+ if (view->position != position) {
+ view->position = position;
+ view->in_sync = 0;
+ }
+}
+
/* End of set methods. */
/* Get methods; NULL mailbox is valid, and returns the default value. */
@@ -2663,6 +2684,13 @@ libbalsa_mailbox_get_mtime(LibBalsaMailbox * mailbox)
mailbox->view->mtime : libbalsa_mailbox_view_default.mtime;
}
+gint
+libbalsa_mailbox_get_position(LibBalsaMailbox * mailbox)
+{
+ return (mailbox && mailbox->view) ?
+ mailbox->view->position : libbalsa_mailbox_view_default.position;
+}
+
/* End of get methods. */
/* =================================================================== *
diff --git a/libbalsa/mailbox.h b/libbalsa/mailbox.h
index 96c76231f..4d57a669a 100644
--- a/libbalsa/mailbox.h
+++ b/libbalsa/mailbox.h
@@ -184,6 +184,7 @@ struct _LibBalsaMailboxView {
int unread;
int total;
time_t mtime; /* Mailbox mtime when counts were cached. */
+ gint position; /* Position in the notebook */
};
struct _LibBalsaMailbox {
@@ -555,6 +556,7 @@ gboolean libbalsa_mailbox_set_crypto_mode(LibBalsaMailbox * mailbox,
void libbalsa_mailbox_set_unread(LibBalsaMailbox * mailbox, gint unread);
void libbalsa_mailbox_set_total (LibBalsaMailbox * mailbox, gint total);
void libbalsa_mailbox_set_mtime (LibBalsaMailbox * mailbox, time_t mtime);
+void libbalsa_mailbox_set_position(LibBalsaMailbox * mailbox, gint position);
const gchar *libbalsa_mailbox_get_identity_name(LibBalsaMailbox * mailbox);
LibBalsaMailboxThreadingType
@@ -576,6 +578,7 @@ LibBalsaChkCryptoMode libbalsa_mailbox_get_crypto_mode(LibBalsaMailbox * mailbox
gint libbalsa_mailbox_get_unread(LibBalsaMailbox * mailbox);
gint libbalsa_mailbox_get_total (LibBalsaMailbox * mailbox);
time_t libbalsa_mailbox_get_mtime(LibBalsaMailbox * mailbox);
+gint libbalsa_mailbox_get_position(LibBalsaMailbox * mailbox);
/** force update of given msgno */
void libbalsa_mailbox_msgno_changed(LibBalsaMailbox *mailbox, guint seqno);
diff --git a/libbalsa/mailbox_local.c b/libbalsa/mailbox_local.c
index d2a6bad4f..f32fdfbf4 100644
--- a/libbalsa/mailbox_local.c
+++ b/libbalsa/mailbox_local.c
@@ -1109,6 +1109,9 @@ static void
lbml_set_threading(LibBalsaMailbox * mailbox,
LibBalsaMailboxThreadingType thread_type)
{
+ if (mailbox->msg_tree == NULL)
+ return;
+
switch (thread_type) {
case LB_MAILBOX_THREADING_JWZ:
lbml_thread_messages(mailbox, TRUE);
diff --git a/src/balsa-app.c b/src/balsa-app.c
index 6bc80f15d..1ecb18dc0 100644
--- a/src/balsa-app.c
+++ b/src/balsa-app.c
@@ -557,12 +557,24 @@ balsa_open_mailbox_list(gchar ** urls)
g_strfreev(urls);
}
+static gint
+position_compare_func(gconstpointer a,
+ gconstpointer b)
+{
+ const gchar *url_a = *(const gchar **) a;
+ const gchar *url_b = *(const gchar **) b;
+
+ return config_mailbox_get_position(url_a) - config_mailbox_get_position(url_b);
+}
+
void
balsa_add_open_mailbox_urls(GPtrArray * url_array)
{
libbalsa_conf_foreach_group(VIEW_BY_URL_SECTION_PREFIX,
(LibBalsaConfForeachFunc)
append_url_if_open, url_array);
+
+ g_ptr_array_sort(url_array, position_compare_func);
}
/*
diff --git a/src/balsa-app.h b/src/balsa-app.h
index 9ec45c0f9..58159de8c 100644
--- a/src/balsa-app.h
+++ b/src/balsa-app.h
@@ -371,6 +371,8 @@ extern struct BalsaApplication {
/* use as default email client for GNOME */
int default_client;
+
+ gboolean in_destruction;
} balsa_app;
#define BALSA_IS_MAILBOX_SPECIAL(a) ((a)==balsa_app.inbox || (a)==balsa_app.trash ||
(a)==balsa_app.outbox||(a)==balsa_app.draftbox || (a)==balsa_app.sentbox)
diff --git a/src/balsa-index.c b/src/balsa-index.c
index ee52f5dae..5e072e447 100644
--- a/src/balsa-index.c
+++ b/src/balsa-index.c
@@ -199,13 +199,6 @@ bndx_class_init(BalsaIndexClass * klass)
}
/* Object class destroy method. */
-static void
-bndx_mbnode_weak_notify(gpointer data, GObject *where_the_object_was)
-{
- BalsaIndex *bindex = data;
- bindex->mailbox_node = NULL;
- gtk_widget_destroy(GTK_WIDGET(bindex));
-}
static void
bndx_destroy(GObject * obj)
@@ -215,22 +208,23 @@ bndx_destroy(GObject * obj)
g_return_if_fail(obj != NULL);
index = BALSA_INDEX(obj);
- if (index->mailbox_node) {
- LibBalsaMailbox* mailbox;
+ if (index->mailbox_node != NULL) {
+ LibBalsaMailbox *mailbox;
- if ((mailbox = index->mailbox_node->mailbox)) {
- g_signal_handlers_disconnect_matched(mailbox,
- G_SIGNAL_MATCH_DATA,
- 0, 0, NULL, NULL, index);
- gtk_tree_view_set_model(GTK_TREE_VIEW(index), NULL);
- libbalsa_mailbox_close(mailbox, balsa_app.expunge_on_close);
- }
+ mailbox = index->mailbox_node->mailbox;
+ if (mailbox != NULL)
+ g_object_ref(mailbox);
- if (index->mailbox_node) {
- g_object_weak_unref(G_OBJECT(index->mailbox_node),
- (GWeakNotify) bndx_mbnode_weak_notify,
- index);
- index->mailbox_node = NULL;
+ g_object_unref(index->mailbox_node);
+ index->mailbox_node = NULL;
+
+ if (mailbox != NULL) {
+ g_signal_handlers_disconnect_matched(mailbox,
+ G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, NULL, index);
+ gtk_tree_view_set_model(GTK_TREE_VIEW(index), NULL);
+ libbalsa_mailbox_close(mailbox, balsa_app.expunge_on_close);
+ g_object_unref(mailbox);
}
}
@@ -244,10 +238,10 @@ bndx_destroy(GObject * obj)
index->popup_menu = NULL;
}
- g_free(index->filter_string); index->filter_string = NULL;
+ g_free(index->filter_string);
+ index->filter_string = NULL;
- if (G_OBJECT_CLASS(parent_class)->dispose)
- (*G_OBJECT_CLASS(parent_class)->dispose) (obj);
+ G_OBJECT_CLASS(parent_class)->dispose(obj);
}
/* Widget class popup menu method. */
@@ -561,6 +555,9 @@ bndx_selection_changed_func(GtkTreeModel * model, GtkTreePath * path,
static void
bndx_selection_changed(GtkTreeSelection * selection, BalsaIndex * index)
{
+ if (index->mailbox_node == NULL)
+ return;
+
index->next_msgno = 0;
gtk_tree_selection_selected_foreach(selection,
(GtkTreeSelectionForeachFunc)
@@ -966,9 +963,8 @@ balsa_index_load_mailbox_node(BalsaIndex * index,
/*
* set the new mailbox
*/
- index->mailbox_node = mbnode;
- g_object_weak_ref(G_OBJECT(mbnode),
- (GWeakNotify) bndx_mbnode_weak_notify, index);
+ index->mailbox_node = g_object_ref(mbnode);
+
/*
* rename "from" column to "to" for outgoing mail
*/
diff --git a/src/main-window.c b/src/main-window.c
index 5a7707de4..a1d72726f 100644
--- a/src/main-window.c
+++ b/src/main-window.c
@@ -171,6 +171,9 @@ static gboolean bw_notebook_drag_motion_cb(GtkWidget* widget,
GdkDragContext* context,
gint x, gint y, guint time,
gpointer user_data);
+static void bw_notebook_page_notify_cb(GtkWidget *child,
+ GParamSpec *child_property,
+ gpointer user_data);
static GtkWidget *bw_notebook_label_new (BalsaMailboxNode* mbnode);
@@ -2820,6 +2823,8 @@ bw_real_open_mbnode_idle_cb(BalsaWindowRealOpenMbnodeInfo * info)
GTK_POLICY_AUTOMATIC);
gtk_container_add(GTK_CONTAINER(scroll), GTK_WIDGET(index));
gtk_widget_show(scroll);
+ g_signal_connect(scroll, "child-notify::position",
+ G_CALLBACK(bw_notebook_page_notify_cb), window->notebook);
page_num = gtk_notebook_append_page(GTK_NOTEBOOK(window->notebook),
scroll, label);
gtk_notebook_set_tab_reorderable(GTK_NOTEBOOK(window->notebook),
@@ -3088,8 +3093,8 @@ balsa_window_destroy(GObject * object)
window->network_changed_source_id = 0;
}
- if (G_OBJECT_CLASS(balsa_window_parent_class)->dispose != NULL)
- G_OBJECT_CLASS(balsa_window_parent_class)->dispose(object);
+ balsa_app.in_destruction = TRUE;
+ G_OBJECT_CLASS(balsa_window_parent_class)->dispose(object);
balsa_unregister_pixmaps();
}
@@ -4350,6 +4355,28 @@ static gboolean bw_notebook_drag_motion_cb(GtkWidget * widget,
return FALSE;
}
+static void
+bw_notebook_page_notify_cb(GtkWidget *widget,
+ GParamSpec *child_property,
+ gpointer notebook)
+{
+ GtkWidget *child;
+
+ if (balsa_app.in_destruction)
+ return;
+
+ child = gtk_bin_get_child(GTK_BIN(widget));
+
+ if (child != NULL) {
+ LibBalsaMailbox *mailbox;
+ gint page_num;
+
+ mailbox = BALSA_INDEX(child)->mailbox_node->mailbox;
+ page_num = gtk_notebook_page_num(notebook, widget);
+ libbalsa_mailbox_set_position(mailbox, page_num);
+ }
+}
+
/* bw_progress_timeout
*
* This function is called at a preset interval to cause the progress
diff --git a/src/save-restore.c b/src/save-restore.c
index 23313fb9c..75fc19ac7 100644
--- a/src/save-restore.c
+++ b/src/save-restore.c
@@ -1783,6 +1783,9 @@ config_load_mailbox_view(const gchar * url)
if (libbalsa_conf_has_key("Open"))
view->open = libbalsa_conf_get_bool("Open");
+ if (libbalsa_conf_has_key("Position"))
+ view->position = libbalsa_conf_get_int("Position");
+
#ifdef HAVE_GPGME
if (libbalsa_conf_has_key("CryptoMode"))
view->gpg_chk_mode = libbalsa_conf_get_int("CryptoMode");
@@ -1836,9 +1839,12 @@ config_save_mailbox_view(const gchar * url, LibBalsaMailboxView * view)
libbalsa_conf_set_int("Subscribe", view->subscribe);
if (view->exposed != libbalsa_mailbox_get_exposed(NULL))
libbalsa_conf_set_bool("Exposed", view->exposed);
- if (balsa_app.remember_open_mboxes &&
- view->open != libbalsa_mailbox_get_open(NULL))
- libbalsa_conf_set_bool("Open", view->open);
+ if (balsa_app.remember_open_mboxes) {
+ if (view->open != libbalsa_mailbox_get_open(NULL))
+ libbalsa_conf_set_bool("Open", view->open);
+ if (view->position != libbalsa_mailbox_get_position(NULL))
+ libbalsa_conf_set_int("Position", view->position);
+ }
#ifdef HAVE_GPGME
if (view->gpg_chk_mode != libbalsa_mailbox_get_crypto_mode(NULL))
libbalsa_conf_set_int("CryptoMode", view->gpg_chk_mode);
@@ -2111,3 +2117,32 @@ config_mailbox_was_exposed(const gchar * url)
{
return config_mailbox_had_property(url, "Exposed");
}
+
+static gint
+config_mailbox_get_int_property(const gchar * url, const gchar * key)
+{
+ gchar *prefix;
+ gint retval = -1;
+
+ prefix = view_by_url_prefix(url);
+ if (!libbalsa_conf_has_group(prefix)) {
+ g_free(prefix);
+ return retval;
+ }
+
+ libbalsa_conf_push_group(prefix);
+
+ if (libbalsa_conf_has_key(key))
+ retval = libbalsa_conf_get_int(key);
+
+ libbalsa_conf_pop_group();
+ g_free(prefix);
+
+ return retval;
+}
+
+gint
+config_mailbox_get_position(const gchar * url)
+{
+ return config_mailbox_get_int_property(url, "Position");
+}
diff --git a/src/save-restore.h b/src/save-restore.h
index adc2c9222..f6bb24587 100644
--- a/src/save-restore.h
+++ b/src/save-restore.h
@@ -65,6 +65,7 @@ void config_save_mailbox_view(const gchar * url, LibBalsaMailboxView * view);
gboolean config_mailbox_was_open(const gchar * url);
gboolean config_mailbox_was_exposed(const gchar * url);
+gint config_mailbox_get_position(const gchar * url);
void config_filters_save(void);
void config_mailbox_filters_save(LibBalsaMailbox * mbox);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]