2012-02-05 [mir] 3.7.10cvs16.22-new-contacts
authorMichael Rasmussen <mir@datanom.net>
Sun, 5 Feb 2012 22:11:11 +0000 (22:11 +0000)
committerMichael Rasmussen <mir@datanom.net>
Sun, 5 Feb 2012 22:11:11 +0000 (22:11 +0000)
* src/addressbook-dbus.c
* src/addressbook-dbus.h
* src/claws-contacts.xml
* src/compose.c
* src/folder.c
* src/folderview.c
* src/inc.c
* src/jpilot.c
* src/main.c
* src/mainwindow.c
* src/messageview.c
* src/messageview.h
* src/mutt.c
* src/pine.c
* src/prefs_common.c
* src/prefs_common.h
* src/procmime.c
* src/procmsg.c
* src/procmsg.h
* src/send_message.c
* src/summaryview.c
* src/summaryview.h
* src/vcard.c
* src/gtk/gtkutils.c
* src/gtk/progressdialog.c
* src/gtk/progressdialog.h
* src/gtk/sslcertwindow.c
    Applied patch 3.8.0cvs18 to 3.8.0cvs26 from HEAD.

30 files changed:
ChangeLog
PATCHSETS
configure.ac
src/addressbook-dbus.c
src/addressbook-dbus.h
src/claws-contacts.xml
src/compose.c
src/folder.c
src/folderview.c
src/gtk/gtkutils.c
src/gtk/progressdialog.c
src/gtk/progressdialog.h
src/gtk/sslcertwindow.c
src/inc.c
src/jpilot.c
src/main.c
src/mainwindow.c
src/messageview.c
src/messageview.h
src/mutt.c
src/pine.c
src/prefs_common.c
src/prefs_common.h
src/procmime.c
src/procmsg.c
src/procmsg.h
src/send_message.c
src/summaryview.c
src/summaryview.h
src/vcard.c

index ef3190c8922fd558ae03c2595d18d2931f9e684a..2aca2845a7248d75c28648ed182ec6136eb4fcdc 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,34 @@
+2012-02-05 [mir]       3.7.10cvs16.22-new-contacts
+
+       * src/addressbook-dbus.c
+       * src/addressbook-dbus.h
+       * src/claws-contacts.xml
+       * src/compose.c
+       * src/folder.c
+       * src/folderview.c
+       * src/inc.c
+       * src/jpilot.c
+       * src/main.c
+       * src/mainwindow.c
+       * src/messageview.c
+       * src/messageview.h
+       * src/mutt.c
+       * src/pine.c
+       * src/prefs_common.c
+       * src/prefs_common.h
+       * src/procmime.c
+       * src/procmsg.c
+       * src/procmsg.h
+       * src/send_message.c
+       * src/summaryview.c
+       * src/summaryview.h
+       * src/vcard.c
+       * src/gtk/gtkutils.c
+       * src/gtk/progressdialog.c
+       * src/gtk/progressdialog.h
+       * src/gtk/sslcertwindow.c
+           Applied patch 3.8.0cvs18 to 3.8.0cvs26 from HEAD.
+
 2012-01-25 [mir]       3.7.10cvs16.21-new-contacts
 
        * src/addr_compl.c
index c9e2fcca5377298f85ce72780b25ade4ba2ed209..5bf4b6d822042fe39da6a7aca6e8778e767330f4 100644 (file)
--- a/PATCHSETS
+++ b/PATCHSETS
 ( cvs diff -u -r 1.274.2.328.2.3 -r 1.274.2.328.2.4 src/mainwindow.c;  cvs diff -u -r 1.39.2.61.2.1 -r 1.39.2.61.2.2 src/mainwindow.h;  cvs diff -u -r 1.395.2.430.2.3 -r 1.395.2.430.2.4 src/summaryview.c;  cvs diff -u -r 1.43.2.124.2.1 -r 1.43.2.124.2.2 src/toolbar.c;  ) > 3.7.10cvs16.19-new-contacts.patchset
 ( cvs diff -u -r 1.1.2.39.2.1 -r 1.1.2.39.2.2 commitHelper;  cvs diff -u -r 1.22.2.24.2.1 -r 1.22.2.24.2.2 src/addrbook.c;  cvs diff -u -r 1.1.4.22.2.1 -r 1.1.4.22.2.2 src/exportldif.c;  cvs diff -u -r 1.83.2.170.2.3 -r 1.83.2.170.2.4 src/mimeview.c;  ) > 3.7.10cvs16.20-new-contacts.patchset
 ( cvs diff -u -r 1.27.2.53.2.2 -r 1.27.2.53.2.3 src/addr_compl.c;  ) > 3.7.10cvs16.21-new-contacts.patchset
+( cvs diff -u -r 1.1.2.1 -r 1.1.2.2 src/addressbook-dbus.c;  cvs diff -u -r 1.1.2.1 -r 1.1.2.2 src/addressbook-dbus.h;  cvs diff -u -r 1.1.2.1 -r 1.1.2.2 src/claws-contacts.xml;  cvs diff -u -r 1.382.2.580.2.4 -r 1.382.2.580.2.5 src/compose.c;  cvs diff -u -r 1.213.2.202.2.1 -r 1.213.2.202.2.2 src/folder.c;  cvs diff -u -r 1.207.2.220.2.1 -r 1.207.2.220.2.2 src/folderview.c;  cvs diff -u -r 1.149.2.104 -r 1.149.2.105 src/inc.c;  cvs diff -u -r 1.18.2.32.2.1 -r 1.18.2.32.2.2 src/jpilot.c;  cvs diff -u -r 1.115.2.239.2.4 -r 1.115.2.239.2.5 src/main.c;  cvs diff -u -r 1.274.2.328.2.4 -r 1.274.2.328.2.5 src/mainwindow.c;  cvs diff -u -r 1.94.2.218.2.3 -r 1.94.2.218.2.4 src/messageview.c;  cvs diff -u -r 1.19.2.26 -r 1.19.2.27 src/messageview.h;  cvs diff -u -r 1.6.10.18.2.1 -r 1.6.10.18.2.2 src/mutt.c;  cvs diff -u -r 1.6.2.17.2.1 -r 1.6.2.17.2.2 src/pine.c;  cvs diff -u -r 1.204.2.202.2.2 -r 1.204.2.202.2.3 src/prefs_common.c;  cvs diff -u -r 1.103.2.133.2.1 -r 1.103.2.133.2.2 src/prefs_common.h;  cvs diff -u -r 1.49.2.140 -r 1.49.2.141 src/procmime.c;  cvs diff -u -r 1.150.2.117.2.2 -r 1.150.2.117.2.3 src/procmsg.c;  cvs diff -u -r 1.60.2.56.2.1 -r 1.60.2.56.2.2 src/procmsg.h;  cvs diff -u -r 1.17.2.60.2.1 -r 1.17.2.60.2.2 src/send_message.c;  cvs diff -u -r 1.395.2.430.2.4 -r 1.395.2.430.2.5 src/summaryview.c;  cvs diff -u -r 1.68.2.57.2.1 -r 1.68.2.57.2.2 src/summaryview.h;  cvs diff -u -r 1.14.2.20.2.1 -r 1.14.2.20.2.2 src/vcard.c;  cvs diff -u -r 1.5.2.95.2.1 -r 1.5.2.95.2.2 src/gtk/gtkutils.c;  cvs diff -u -r 1.1.4.27.2.1 -r 1.1.4.27.2.2 src/gtk/progressdialog.c;  cvs diff -u -r 1.1.4.16 -r 1.1.4.17 src/gtk/progressdialog.h;  cvs diff -u -r 1.9.2.32 -r 1.9.2.33 src/gtk/sslcertwindow.c;  ) > 3.7.10cvs16.22-new-contacts.patchset
index 5f6f2cffc6121967aa9aa83ccebc1e0a184e683b..edd083bb6fb965be4951a55b5d0bf57fb0503567 100644 (file)
@@ -12,7 +12,7 @@ MINOR_VERSION=7
 MICRO_VERSION=10
 INTERFACE_AGE=0
 BINARY_AGE=0
-EXTRA_VERSION=16.21
+EXTRA_VERSION=16.22
 EXTRA_RELEASE=
 EXTRA_GTK2_VERSION=-new-contacts
 
index 630b486dbea23a2b0a11b6433b7bc6d9970b7a91..00c6eaa9fb03ec5c7d08594e090b59d9f6b170fe 100644 (file)
@@ -42,6 +42,7 @@
 #include "addrgather.h"
 #include "folder.h"
 #include "compose.h"
+#include "hooks.h"
 
 #include "addressbook-dbus.h"
 #include "client-bindings.h"
@@ -430,3 +431,57 @@ void addressbook_connect_signals(Compose* compose) {
        }
        dbus_connection_add_filter(bus, contact_add_signal, NULL, NULL);
 }
+
+gchar* addressbook_get_vcard(const gchar* account, GError** error) {
+       gchar* vcard = NULL;
+       
+       g_return_val_if_fail(account != NULL, vcard);
+       
+       if (! init(error)) {
+               return vcard;
+       }
+       
+       if (!org_clawsmail_Contacts_get_vcard(proxy, account, &vcard, error)) {
+               if (! *error)
+                       g_set_error(error, client_object_error_quark(), 1, "Woops remote method failed");
+               g_warning ("Woops remote method failed: %s", (*error)->message);
+               g_free(vcard);
+               vcard = NULL;
+       }
+       
+       return vcard;
+}
+
+gboolean addressbook_add_vcard(const gchar* abook, const gchar* vcard, GError** error) {
+       gboolean result = FALSE;
+       
+       return result;
+}
+
+static gboolean my_compose_create_hook(gpointer source, gpointer user_data) {
+       Compose *compose = (Compose*) source;
+       GError* error = NULL;
+
+       gchar* vcard = addressbook_get_vcard("test", &error);
+       if (error) {
+               g_warning("%s", error->message);
+               g_clear_error(&error);
+       }
+       else {
+               debug_print("test.vcf:\n%s\n", vcard);
+               g_free(vcard);
+       }
+       
+       return FALSE;
+}
+
+void addressbook_install_hooks(GError** error) {
+       if ((guint)-1 == hooks_register_hook(
+                       COMPOSE_CREATED_HOOKLIST, my_compose_create_hook, NULL)) {
+               g_warning("Could not register hook for adding vCards\n");
+               if (error) {
+                       g_set_error(error, client_object_error_quark(), 1,
+                               "Could not register hook for adding vCards");
+               }
+       }
+}
index ee02fbe953a60b053c89c37bfcf1fb0f75c4ff64..128f9aec64418e105e2182c0aa17d8ce08a36ad5 100644 (file)
@@ -51,6 +51,7 @@ typedef struct {
 } ContactData;
 
 gboolean addressbook_start_service(GError** error);
+void addressbook_install_hooks(GError** error);
 int addressbook_dbus_add_contact(ContactData* contact, GError** error);
 gboolean addrindex_dbus_load_completion(gint (*callBackFunc)
                                                                                (const gchar* name,
@@ -66,6 +67,8 @@ void addressbook_harvest(FolderItem *folderItem,
                                                 gboolean sourceInd,
                                                 GList *msgList );
 void addressbook_connect_signals(Compose* compose);
+gchar* addressbook_get_vcard(const gchar* account, GError** error);
+gboolean addressbook_add_vcard(const gchar* abook, const gchar* vcard, GError** error);
 
 G_END_DECLS
 
index 3f758d66e5cfdc1e9bb67c86c5562b893281eb7d..39f91c09dd864366ddb12cd2f3d8ac0b8df77d97 100644 (file)
            <arg type="a(sss)" name="contact_emails" direction="in" />
     </method>
 
-<!--
-    <method name="AddContact1">
+    <method name="AddVCard">
+        <!-- if addressbook is NULL add to default address book -->
         <arg type="s" name="addressbook" direction="in" /> 
-           <arg type="(a{ss}a(sss))" name="contact" direction="in" />
+           <arg type="s" name="vcard" direction="in" />
+    </method>
+
+    <method name="GetVCard">
+        <arg type="s" name="acount" direction="in" /> 
+           <arg type="s" name="vcard" direction="out" />
     </method>
--->
 
     <signal name="ContactMailTo">
                <arg type="s" name="contact_add_to" direction="out" />
index 833d31708da083187b6f2000bac217c094057902..f96a6532e3461551b69e2f21f82cf8dcfcf4dc91 100644 (file)
@@ -5015,7 +5015,7 @@ gint compose_send(Compose *compose)
        compose_allow_user_actions (compose, FALSE);
        compose->sending = TRUE;
 
-       if (compose_check_entries(compose, TRUE) == FALSE) {
+       if ((compose, TRUE) == FALSE) {
                if (compose->batch) {
                        gtk_widget_show_all(compose->window);
                }
index 3887cbbfb582227c679d17d90ee83d480c6943f2..f6f961fe032660844952009aa23398f7f2919649 100644 (file)
@@ -3066,6 +3066,8 @@ static void copy_msginfo_flags(MsgInfo *source, MsgInfo *dest)
 
 static void add_msginfo_to_cache(FolderItem *item, MsgInfo *newmsginfo, MsgInfo *flagsource)
 {
+       MsgInfoUpdate msginfo_update;
+
        /* update folder stats */
        if (MSG_IS_NEW(newmsginfo->flags))
                item->new_msgs++;
@@ -3092,6 +3094,10 @@ static void add_msginfo_to_cache(FolderItem *item, MsgInfo *newmsginfo, MsgInfo
        if (!item->cache)
                folder_item_read_cache(item);
 
+       msginfo_update.msginfo = newmsginfo;
+       msginfo_update.flags = MSGINFO_UPDATE_ADDED;
+       hooks_invoke(MSGINFO_UPDATE_HOOKLIST, &msginfo_update);
+
        msgcache_add_msg(item->cache, newmsginfo);
        copy_msginfo_flags(flagsource, newmsginfo);
        folder_item_update_with_msg(item,  F_ITEM_UPDATE_MSGCNT | F_ITEM_UPDATE_CONTENT | F_ITEM_UPDATE_ADDMSG, newmsginfo);
index 8e0280b7f4c400bb39e5736431fe36754f02eb17..25389143cdaaa95f115080508341942a8df74ace 100644 (file)
@@ -2080,7 +2080,7 @@ void folderview_close_opened(FolderView *folderview)
                olditem = gtk_cmctree_node_get_row_data(GTK_CMCTREE(folderview->ctree), 
                                                      folderview->opened);
                if (olditem) {
-                       gchar *buf = g_strdup_printf(_("Closing Folder %s..."), 
+                       gchar *buf = g_strdup_printf(_("Closing folder %s..."), 
                                olditem->path ? olditem->path:olditem->name);
                        /* will be null if we just moved the previously opened folder */
                        STATUSBAR_PUSH(folderview->mainwin, buf);
@@ -2175,7 +2175,7 @@ static void folderview_selected(GtkCMCTree *ctree, GtkCMCTreeNode *row,
 
        /* Open Folder */
        /* TODO: wwp: avoid displaying (null) in the status bar */
-       buf = g_strdup_printf(_("Opening Folder %s..."), item->path ? 
+       buf = g_strdup_printf(_("Opening folder %s..."), item->path ? 
                                        item->path : "(null)");
        debug_print("%s\n", buf);
        STATUSBAR_PUSH(folderview->mainwin, buf);
index a71fe95eeb05ac353d6fe1a485033dcbb18a7f2c..764d0855381756798731b681a7a5b6b41ce4ab14 100644 (file)
@@ -451,7 +451,7 @@ static gboolean gtkut_text_buffer_find(GtkTextBuffer *buffer, const GtkTextIter
 
        wcs = g_utf8_to_ucs4(str, -1, &items_read, &items_written, &error);
        if (error != NULL) {
-               g_warning("An error occured while converting a string from UTF-8 to UCS-4: %s\n",
+               g_warning("An error occurred while converting a string from UTF-8 to UCS-4: %s\n",
                          error->message);
                g_error_free(error);
        }
@@ -487,7 +487,8 @@ static gboolean gtkut_text_buffer_find_backward(GtkTextBuffer *buffer,
 
        wcs = g_utf8_to_ucs4(str, -1, &items_read, &items_written, &error);
        if (error != NULL) {
-               g_warning("An error occured while converting a string from UTF-8 to UCS-4: %s\n", error->message);
+               g_warning("An error occurred while converting a string from UTF-8 to UCS-4: %s\n",
+                         error->message);
                g_error_free(error);
        }
        if (!wcs || items_written <= 0) return FALSE;
@@ -1147,7 +1148,7 @@ GtkWidget *face_get_from_header(const gchar *o_face)
 
        if ((gdk_pixbuf_get_width(pixbuf) != 48) || (gdk_pixbuf_get_height(pixbuf) != 48)) {
                g_object_unref(pixbuf);
-               g_warning("wrong_size");
+               g_warning("wrong_size\n");
                return NULL;
        }
 
@@ -1253,7 +1254,7 @@ GtkWidget *gtkut_get_link_btn(GtkWidget *window, const gchar *url, const gchar *
                gtk_widget_set_style(btn_label, style);
 #if !GTK_CHECK_VERSION(3, 0, 0)
        } else
-               g_warning("about_create(): color allocation failed.\n");
+               g_warning("color allocation failed\n");
 #endif
 
        g_signal_connect(G_OBJECT(btn), "enter",
index 2d97dce91811375ce4f507ab0150e569ac379b16..db9e74d510dbb7128826ad16a8123425ed03f77f 100644 (file)
@@ -50,6 +50,7 @@ ProgressDialog *progress_dialog_create(void)
        GtkWidget *hbox;
        GtkWidget *vbox;
        GtkWidget *label;
+       GtkWidget *showlog_btn;
        GtkWidget *cancel_btn;
        GtkWidget *progressbar;
        GtkWidget *scrolledwin;
@@ -81,6 +82,9 @@ ProgressDialog *progress_dialog_create(void)
        gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 8);
        gtk_widget_show(label);
 
+       showlog_btn = gtk_dialog_add_button(GTK_DIALOG(dialog),
+                                          _("_View log"),
+                                          GTK_RESPONSE_NONE);
        cancel_btn = gtk_dialog_add_button(GTK_DIALOG(dialog),
                                           GTK_STOCK_CANCEL,
                                           GTK_RESPONSE_NONE);
@@ -100,7 +104,6 @@ ProgressDialog *progress_dialog_create(void)
                                       GTK_POLICY_AUTOMATIC,
                                       GTK_POLICY_AUTOMATIC);
 
-
        store = gtk_list_store_new(N_PROGRESS_COLUMNS, GDK_TYPE_PIXBUF, G_TYPE_STRING,
                                   G_TYPE_STRING, G_TYPE_POINTER);
 
@@ -142,6 +145,7 @@ ProgressDialog *progress_dialog_create(void)
        
        progress->window      = dialog;
        progress->label       = label;
+       progress->showlog_btn  = showlog_btn;
        progress->cancel_btn  = cancel_btn;
        progress->progressbar = progressbar;
        progress->treeview    = treeview;
index f7374f0db1271b015df3f73d7363b32bf7edd276..a9dac94c52d6ace90ed1f6a35a710ef93b1e1c50 100644 (file)
@@ -29,6 +29,7 @@ struct _ProgressDialog
 {
        GtkWidget *window;
        GtkWidget *label;
+       GtkWidget *showlog_btn;
        GtkWidget *cancel_btn;
        GtkWidget *progressbar;
        GtkWidget *treeview;
index 3ed7d54a9a4ae35250495c2f80179dc9673ef65a..fb28591d83de32b3dc3422e14df423e10561376b 100644 (file)
@@ -94,8 +94,8 @@ static GtkWidget *cert_presenter(SSLCertificate *cert)
                tmp = g_malloc(BUFFSIZE);
                if (gnutls_x509_crt_get_issuer_dn_by_oid(cert->x509_cert, 
                        GNUTLS_OID_X520_COUNTRY_NAME, 0, 0, tmp, &n) == 0) {
-                       strncat(issuer_location, ", ", BUFFSIZE-strlen(issuer_location));
-                       strncat(issuer_location, tmp, BUFFSIZE-strlen(issuer_location));
+                       strncat(issuer_location, ", ", BUFFSIZE-strlen(issuer_location)-1);
+                       strncat(issuer_location, tmp, BUFFSIZE-strlen(issuer_location)-1);
                }
                g_free(tmp);
        }
@@ -121,8 +121,8 @@ static GtkWidget *cert_presenter(SSLCertificate *cert)
                tmp = g_malloc(BUFFSIZE);
                if (gnutls_x509_crt_get_dn_by_oid(cert->x509_cert, 
                        GNUTLS_OID_X520_COUNTRY_NAME, 0, 0, tmp, &n) == 0) {
-                       strncat(subject_location, ", ", BUFFSIZE-strlen(subject_location));
-                       strncat(subject_location, tmp, BUFFSIZE-strlen(subject_location));
+                       strncat(subject_location, ", ", BUFFSIZE-strlen(subject_location)-1);
+                       strncat(subject_location, tmp, BUFFSIZE-strlen(subject_location)-1);
                }
                g_free(tmp);
        }
index 8d200b2b61d2b11dcdab719e6d4bf21b1b6703e6..9f14c9b074933768783a04fc3bae9fe59137979f 100644 (file)
--- a/src/inc.c
+++ b/src/inc.c
@@ -57,6 +57,7 @@
 #include "filtering.h"
 #include "log.h"
 #include "hooks.h"
+#include "logwindow.h"
 
 #ifdef MAEMO
 #ifdef CHINOOK
@@ -133,6 +134,8 @@ static gint inc_drop_message                (Pop3Session    *session,
 static void inc_put_error              (IncState        istate,
                                         Pop3Session    *session);
 
+static void inc_showlog_cb             (GtkWidget      *widget,
+                                        gpointer        data);
 static void inc_cancel_cb              (GtkWidget      *widget,
                                         gpointer        data);
 static gint inc_dialog_delete_cb       (GtkWidget      *widget,
@@ -413,6 +416,8 @@ static IncProgressDialog *inc_progress_dialog_create(gboolean autocheck)
        progress = progress_dialog_create();
        gtk_window_set_title(GTK_WINDOW(progress->window),
                             _("Retrieving new messages"));
+       g_signal_connect(G_OBJECT(progress->showlog_btn), "clicked",
+                        G_CALLBACK(inc_showlog_cb), dialog);
        g_signal_connect(G_OBJECT(progress->cancel_btn), "clicked",
                         G_CALLBACK(inc_cancel_cb), dialog);
        g_signal_connect(G_OBJECT(progress->window), "delete_event",
@@ -1260,6 +1265,13 @@ void inc_cancel_all(void)
                inc_cancel((IncProgressDialog *)cur->data);
 }
 
+static void inc_showlog_cb(GtkWidget *widget, gpointer data)
+{
+       MainWindow *mainwin = mainwindow_get_mainwindow();
+
+       log_window_show(mainwin->logwin);
+}
+
 static void inc_cancel_cb(GtkWidget *widget, gpointer data)
 {
        inc_cancel((IncProgressDialog *)data);
index 4e70d292c513b8a4bde4769f8b3fa5ed24dd66d2..7a1902b641491a8b9629588a50c4b870901f1713 100644 (file)
@@ -1595,7 +1595,7 @@ GList *jpilot_get_all_persons( JPilotFile *pilotFile ) {
  */
 gchar *jpilot_find_pilotdb( void ) {
        const gchar *homedir;
-       gchar str[ WORK_BUFLEN ];
+       gchar str[ WORK_BUFLEN + 1 ];
        gint len;
        FILE *fp;
 
@@ -1610,9 +1610,9 @@ gchar *jpilot_find_pilotdb( void ) {
                        str[ ++len ] = '\0';
                }
        }
-       strncat( str, JPILOT_DBHOME_DIR, WORK_BUFLEN );
-       strncat( str, G_DIR_SEPARATOR_S, WORK_BUFLEN );
-       strncat( str, JPILOT_DBHOME_FILE, WORK_BUFLEN );
+       strncat( str, JPILOT_DBHOME_DIR, WORK_BUFLEN - strlen(str) );
+       strncat( str, G_DIR_SEPARATOR_S, WORK_BUFLEN - strlen(str) );
+       strncat( str, JPILOT_DBHOME_FILE, WORK_BUFLEN - strlen(str) );
 
        /* Attempt to open */
        if( ( fp = g_fopen( str, "rb" ) ) != NULL ) {
index 90d768bb0b48d75ba172ab36faea5f16d4d60335..37591813c52ad002ffeea89960c4493ee56c5fbc 100644 (file)
@@ -1327,6 +1327,9 @@ int main(int argc, char *argv[])
                g_warning("%s", error->message);
                g_clear_error(&error);
        }
+       else {
+               addressbook_install_hooks(&error);
+       }
 #endif
        gtkut_widget_init();
        stock_pixbuf_gdk(NULL, STOCK_PIXMAP_CLAWS_MAIL_ICON, &icon);
@@ -2567,7 +2570,7 @@ static void lock_socket_input_cb(gpointer data,
                if (folder_name)
                        folderItem = folder_find_item_from_identifier(folder_name);
                if (folder_name && folderItem == NULL) {
-                       debug_print("Unknow folder item : '%s', searching folder\n",folder_name);
+                       debug_print("Unknown folder item : '%s', searching folder\n",folder_name);
                        Folder* folder = folder_find_from_path(folder_name);
                        if (folder != NULL)
                                folderItem = FOLDER_ITEM(folder->node->data);
index f2c78bce6f29056c76acd8707848ab1b27a0f7e8..6d26837c7e3b3c80fa0021805d59db2138ae31e3 100644 (file)
@@ -310,7 +310,9 @@ static void prev_labeled_cb  (GtkAction     *action,
                                  gpointer       data);
 static void next_labeled_cb     (GtkAction     *action,
                                  gpointer       data);
-static void last_read_cb        (GtkAction     *action,
+static void prev_history_cb     (GtkAction     *action,
+                                 gpointer       data);
+static void next_history_cb     (GtkAction     *action,
                                  gpointer       data);
 static void parent_cb           (GtkAction     *action,
                                  gpointer       data);
@@ -561,7 +563,9 @@ static GtkActionEntry mainwin_entries[] =
        {"View/Goto/PrevLabeled",               NULL, N_("Previous _labeled message"), NULL, NULL, G_CALLBACK(prev_labeled_cb) },
        {"View/Goto/NextLabeled",               NULL, N_("Next la_beled message"), NULL, NULL, G_CALLBACK(next_labeled_cb) },
        /* {"View/Goto/---",                    NULL, "---", NULL, NULL, NULL }, */
-       {"View/Goto/LastRead",                  NULL, N_("Last read message"), NULL, NULL, G_CALLBACK(last_read_cb) },
+       {"View/Goto/PrevHistory",               NULL, N_("Previous opened message"), "<alt>Left", NULL, G_CALLBACK(prev_history_cb) },
+       {"View/Goto/NextHistory",               NULL, N_("Next opened message"), "<alt>Right", NULL, G_CALLBACK(next_history_cb) },
+       /* {"View/Goto/---",                    NULL, "---", NULL, NULL, NULL }, */
        {"View/Goto/ParentMessage",             NULL, N_("Parent message"), "<control>Up", NULL, G_CALLBACK(parent_cb) },
        /* {"View/Goto/---",                    NULL, "---", NULL, NULL, NULL }, */
        {"View/Goto/NextUnreadFolder",          NULL, N_("Next unread _folder"), "<shift>G", NULL, G_CALLBACK(goto_unread_folder_cb) },
@@ -1024,7 +1028,6 @@ static void mainwindow_tags_menu_item_activate_item_cb(GtkMenuItem *menu_item,
        for (; sel != NULL; sel = sel->next) {
                MsgInfo *msginfo;
                GSList *tags = NULL;
-               gint id;
                GtkCheckMenuItem *item;
                msginfo = (MsgInfo *)sel->data;
                sel_len++;
@@ -1035,7 +1038,6 @@ static void mainwindow_tags_menu_item_activate_item_cb(GtkMenuItem *menu_item,
 
                        for (; tags; tags = tags->next) {
                                gint num_checked = GPOINTER_TO_INT(g_hash_table_lookup(menu_allsel_table, tags->data));
-                               id = GPOINTER_TO_INT(tags->data);
                                item = g_hash_table_lookup(menu_table, GINT_TO_POINTER(tags->data));
                                if (item && !gtk_check_menu_item_get_active(item)) {
                                        gtk_check_menu_item_set_active
@@ -1746,9 +1748,11 @@ MainWindow *main_window_create()
        MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/View/Goto", "PrevLabeled", "View/Goto/PrevLabeled", GTK_UI_MANAGER_MENUITEM)
        MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/View/Goto", "NextLabeled", "View/Goto/NextLabeled", GTK_UI_MANAGER_MENUITEM)
        MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/View/Goto", "Separator5", "View/Goto/---", GTK_UI_MANAGER_SEPARATOR)
-       MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/View/Goto", "LastRead", "View/Goto/LastRead", GTK_UI_MANAGER_MENUITEM)
-       MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/View/Goto", "ParentMessage", "View/Goto/ParentMessage", GTK_UI_MANAGER_MENUITEM)
+       MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/View/Goto", "PrevHistory", "View/Goto/PrevHistory", GTK_UI_MANAGER_MENUITEM)
+       MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/View/Goto", "NextHistory", "View/Goto/NextHistory", GTK_UI_MANAGER_MENUITEM)
        MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/View/Goto", "Separator6", "View/Goto/---", GTK_UI_MANAGER_SEPARATOR)
+       MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/View/Goto", "ParentMessage", "View/Goto/ParentMessage", GTK_UI_MANAGER_MENUITEM)
+       MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/View/Goto", "Separator7", "View/Goto/---", GTK_UI_MANAGER_SEPARATOR)
        MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/View/Goto", "NextUnreadFolder", "View/Goto/NextUnreadFolder", GTK_UI_MANAGER_MENUITEM)
        MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/View/Goto", "OtherFolder", "View/Goto/OtherFolder", GTK_UI_MANAGER_MENUITEM)
         MENUITEM_ADDUI_MANAGER(mainwin->ui_manager, "/Menu/View", "Scroll", "View/Scroll", GTK_UI_MANAGER_MENU)
@@ -3242,7 +3246,6 @@ void main_window_set_menu_sensitive(MainWindow *mainwin)
                {"Menu/View/Goto/PrevMarked" , M_MSG_EXIST},
                {"Menu/View/Goto/PrevLabeled", M_MSG_EXIST},
                {"Menu/View/Goto/NextLabeled", M_MSG_EXIST},
-               {"Menu/View/Goto/LastRead"   , M_SINGLE_TARGET_EXIST},
                {"Menu/View/Goto/ParentMessage"      , M_SINGLE_TARGET_EXIST},
                {"Menu/View/OpenNewWindow"        , M_SINGLE_TARGET_EXIST},
                {"Menu/View/MessageSource"            , M_SINGLE_TARGET_EXIST},
@@ -3406,7 +3409,12 @@ void main_window_set_menu_sensitive(MainWindow *mainwin)
                cm_menu_set_sensitive_full(mainwin->ui_manager, "Menu/View/HideReadThreads", FALSE);
        if (mainwin->summaryview->folder_item && mainwin->summaryview->folder_item->hide_read_threads)
                cm_menu_set_sensitive_full(mainwin->ui_manager, "Menu/View/HideReadMessages", FALSE);
-               
+
+       cm_menu_set_sensitive_full(mainwin->ui_manager, "Menu/View/Goto/PrevHistory",
+               messageview_nav_has_prev(mainwin->messageview));
+       cm_menu_set_sensitive_full(mainwin->ui_manager, "Menu/View/Goto/NextHistory",
+               messageview_nav_has_next(mainwin->messageview));
+
        main_window_menu_callback_unblock(mainwin);
 }
 
@@ -3723,8 +3731,8 @@ static void main_window_set_widgets(MainWindow *mainwin, LayoutType layout_mode)
 
                if (messageview_is_visible(mainwin->messageview)) {
                        gtk_paned_add2(GTK_PANED(hpaned), vpaned);
-                       gtk_paned_add1(GTK_PANED(vpaned),
-                                      GTK_WIDGET_PTR(mainwin->summaryview));
+                       gtk_paned_pack1(GTK_PANED(vpaned),
+                                      GTK_WIDGET_PTR(mainwin->summaryview), TRUE, TRUE);
                } else {
                        gtk_paned_add2(GTK_PANED(hpaned),
                                       GTK_WIDGET_PTR(mainwin->summaryview));
@@ -3902,7 +3910,7 @@ void main_window_destroy_all(void)
 {
        while (mainwin_list != NULL) {
                MainWindow *mainwin = (MainWindow*)mainwin_list->data;
-               
+
                /* free toolbar stuff */
                toolbar_clear_list(TOOLBAR_MAIN);
                TOOLBAR_DESTROY_ACTIONS(mainwin->toolbar->action_list);
@@ -4835,10 +4843,33 @@ static void next_labeled_cb(GtkAction *action, gpointer data)
        summary_select_next_labeled(mainwin->summaryview);
 }
 
-static void last_read_cb(GtkAction *action, gpointer data)
+static void prev_history_cb(GtkAction *action, gpointer data)
+{
+       MainWindow *mainwin = (MainWindow *)data;
+       MsgInfo *info = messageview_nav_get_prev(mainwin->messageview);
+       if (info) {
+               if (info->folder != mainwin->summaryview->folder_item)
+                       folderview_select(mainwin->folderview, info->folder);
+               summary_display_by_msgnum(mainwin->summaryview, info->msgnum);
+               summary_display_msg_selected(mainwin->summaryview, FALSE);
+               procmsg_msginfo_free(info);
+               main_window_set_menu_sensitive(mainwindow_get_mainwindow());
+               toolbar_main_set_sensitive(mainwindow_get_mainwindow());
+       }
+}
+
+static void next_history_cb(GtkAction *action, gpointer data)
 {
        MainWindow *mainwin = (MainWindow *)data;
-       summary_select_last_read(mainwin->summaryview);
+       MsgInfo *info = messageview_nav_get_next(mainwin->messageview);
+       if (info) {
+               if (info->folder != mainwin->summaryview->folder_item)
+                       folderview_select(mainwin->folderview, info->folder);
+               summary_display_by_msgnum(mainwin->summaryview, info->msgnum);
+               procmsg_msginfo_free(info);
+               main_window_set_menu_sensitive(mainwindow_get_mainwindow());
+               toolbar_main_set_sensitive(mainwindow_get_mainwindow());
+       }
 }
 
 static void parent_cb(GtkAction *action, gpointer data)
index 67579883b10b5d627efe6c390a67f0345912d935..d8ffcfefe3575172a0982c73cad833d0e0fbf37c 100644 (file)
@@ -130,7 +130,9 @@ static void prev_labeled_cb         (GtkAction      *action,
                                         gpointer        data);
 static void next_labeled_cb            (GtkAction      *action,
                                         gpointer        data);
-static void last_read_cb               (GtkAction      *action,
+static void prev_history_cb            (GtkAction      *action,
+                                        gpointer        data);
+static void next_history_cb            (GtkAction      *action,
                                         gpointer        data);
 static void parent_cb                  (GtkAction      *action,
                                         gpointer        data);
@@ -182,6 +184,7 @@ static void about_cb                        (GtkAction      *action,
 static void messageview_update         (MessageView    *msgview,
                                         MsgInfo        *old_msginfo);
 static gboolean messageview_update_msg (gpointer source, gpointer data);
+static gboolean messageview_msg_moved  (gpointer source, gpointer data);
 
 static void messageview_nothing_cb        (GtkAction *action, gpointer data)
 {
@@ -230,8 +233,10 @@ static GtkActionEntry msgview_entries[] =
        /* {"View/Goto/---",            NULL, "---", NULL, NULL, NULL }, */
        {"View/Goto/PrevLabeled",       NULL, N_("Previous _labeled message"), NULL, NULL, G_CALLBACK(prev_labeled_cb) },
        {"View/Goto/NextLabeled",       NULL, N_("Next la_beled message"), NULL, NULL, G_CALLBACK(next_labeled_cb) },
+       /* {"View/Goto/---",                    NULL, "---", NULL, NULL, NULL }, */
+       {"View/Goto/PrevHistory",       NULL, N_("Previous opened message"), "<alt>Left", NULL, G_CALLBACK(prev_history_cb) },
+       {"View/Goto/NextHistory",       NULL, N_("Next opened message"), "<alt>Right", NULL, G_CALLBACK(next_history_cb) },
        /* {"View/Goto/---",            NULL, "---", NULL, NULL, NULL }, */
-       {"View/Goto/LastRead",          NULL, N_("Last read message"), NULL, NULL, G_CALLBACK(last_read_cb) },
        {"View/Goto/ParentMessage",     NULL, N_("Parent message"), "<control>Up", NULL, G_CALLBACK(parent_cb) },
        /* {"View/Goto/---",            NULL, "---", NULL, NULL, NULL }, */
        {"View/Goto/NextUnreadFolder",  NULL, N_("Next unread _folder"), "<shift>G", NULL, G_CALLBACK(goto_unread_folder_cb) },
@@ -412,6 +417,7 @@ MessageView *messageview_create(MainWindow *mainwin)
 
        messageview->msginfo_update_callback_id =
                hooks_register_hook(MSGINFO_UPDATE_HOOKLIST, messageview_update_msg, (gpointer) messageview);
+       messageview->msginfo_moved_callback_id = 0;
 
        return messageview;
 }
@@ -497,9 +503,11 @@ static void messageview_add_toolbar(MessageView *msgview, GtkWidget *window)
        MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Goto", "PrevLabeled", "View/Goto/PrevLabeled", GTK_UI_MANAGER_MENUITEM)
        MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Goto", "NextLabeled", "View/Goto/NextLabeled", GTK_UI_MANAGER_MENUITEM)
        MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Goto", "Separator5", "View/Goto/---", GTK_UI_MANAGER_SEPARATOR)
-       MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Goto", "LastRead", "View/Goto/LastRead", GTK_UI_MANAGER_MENUITEM)
-       MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Goto", "ParentMessage", "View/Goto/ParentMessage", GTK_UI_MANAGER_MENUITEM)
+       MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Goto", "PrevHistory", "View/Goto/PrevHistory", GTK_UI_MANAGER_MENUITEM)
+       MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Goto", "NextHistory", "View/Goto/NextHistory", GTK_UI_MANAGER_MENUITEM)
        MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Goto", "Separator6", "View/Goto/---", GTK_UI_MANAGER_SEPARATOR)
+       MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Goto", "ParentMessage", "View/Goto/ParentMessage", GTK_UI_MANAGER_MENUITEM)
+       MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Goto", "Separator7", "View/Goto/---", GTK_UI_MANAGER_SEPARATOR)
        MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Goto", "NextUnreadFolder", "View/Goto/NextUnreadFolder", GTK_UI_MANAGER_MENUITEM)
        MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Goto", "OtherFolder", "View/Goto/OtherFolder", GTK_UI_MANAGER_MENUITEM)
 
@@ -714,6 +722,8 @@ static MessageView *messageview_create_with_new_window_visible(MainWindow *mainw
        g_signal_connect(G_OBJECT(window), "key_press_event",
                         G_CALLBACK(key_pressed), msgview);
 #endif
+       msgview->msginfo_moved_callback_id = hooks_register_hook(MSGINFO_UPDATE_HOOKLIST,
+                                       messageview_msg_moved, (gpointer) msgview);
        messageview_add_toolbar(msgview, window);
 
        if (show) {
@@ -1133,6 +1143,118 @@ static MimeInfo *find_broken_part(MimeInfo *rootinfo)
        return brokeninfo;
 }
 
+static void messageview_register_nav(MessageView *messageview)
+{
+       gchar *id;
+       gint pos = -1;
+       GList *existing;
+
+       cm_return_if_fail(messageview);
+       cm_return_if_fail(messageview->msginfo);
+
+       id = procmsg_msginfo_get_identifier(messageview->msginfo);
+       existing = g_list_find_custom(messageview->trail, id, (GCompareFunc)g_strcmp0);
+
+       if (existing != NULL)
+               pos = g_list_position(messageview->trail, existing);
+       else
+               pos = -1;
+
+       if (pos != -1) {
+               messageview->trail_pos = pos;
+               g_free(id);
+       } else {
+               /* Cut the end of the list */
+               GList *end = g_list_nth(messageview->trail, messageview->trail_pos + 1);
+               if (end) {
+                       if (end->prev) {
+                               end->prev->next = NULL;
+                               end->prev = NULL;
+                               list_free_strings(end);
+                               g_list_free(end);
+                       } else {
+                               list_free_strings(messageview->trail);
+                               g_list_free(messageview->trail);
+                               messageview->trail = NULL;
+                       }
+               }
+               messageview->trail = g_list_append(messageview->trail, id);
+               messageview->trail_pos = g_list_length(messageview->trail) - 1;
+               
+               /* Cut the beginning if needed */
+               while (messageview->trail_pos > prefs_common.nav_history_length) {
+                       g_free(messageview->trail->data);
+                       messageview->trail = g_list_delete_link(messageview->trail,
+                                               messageview->trail);
+                       messageview->trail_pos--;
+               }
+       }
+       messageview_set_menu_sensitive(messageview);
+}
+
+gboolean messageview_nav_has_prev(MessageView *messageview) {
+       return messageview->trail != NULL &&  messageview->trail_pos > 0;
+}
+
+gboolean messageview_nav_has_next(MessageView *messageview) {
+       if (!messageview->trail)
+               return FALSE;
+       
+       return sc_g_list_bigger(messageview->trail, messageview->trail_pos + 1);
+}
+
+MsgInfo *messageview_nav_get_prev(MessageView *messageview) {
+       GList *item;
+       MsgInfo *info;
+
+       cm_return_val_if_fail(messageview, NULL);
+       cm_return_val_if_fail(messageview->trail, NULL);
+
+       do {
+               if (!messageview_nav_has_prev(messageview))
+                       return NULL;
+
+               item = g_list_nth(messageview->trail, messageview->trail_pos - 1);
+               cm_return_val_if_fail(item != NULL, NULL);
+
+               info = procmsg_get_msginfo_from_identifier((const gchar *)item->data);
+               if (info != NULL)
+                       break;
+
+               g_free(item->data);
+               messageview->trail = g_list_delete_link(messageview->trail, item);
+               if (messageview->trail_pos > 0)
+                       messageview->trail_pos--;
+       } while (info == NULL);
+
+       return info;
+}
+
+MsgInfo *messageview_nav_get_next(MessageView *messageview) {
+       GList *item;
+       MsgInfo *info;
+
+       cm_return_val_if_fail(messageview, NULL);
+       cm_return_val_if_fail(messageview->trail, NULL);
+
+       do {
+               if (!messageview_nav_has_next(messageview))
+                       return NULL;
+
+               item = g_list_nth(messageview->trail, messageview->trail_pos + 1);
+               cm_return_val_if_fail(item != NULL, NULL);
+
+               info = procmsg_get_msginfo_from_identifier((const gchar *)item->data);
+               if (info != NULL)
+                       break;
+
+               g_free(item->data);
+               messageview->trail = g_list_delete_link(messageview->trail, item);
+       } while (info == NULL);
+       
+       return info;
+}
+
 gint messageview_show(MessageView *messageview, MsgInfo *msginfo,
                      gboolean all_headers)
 {
@@ -1244,6 +1366,7 @@ gint messageview_show(MessageView *messageview, MsgInfo *msginfo,
        }
        headerview_show(messageview->headerview, messageview->msginfo);
 
+       messageview_register_nav(messageview);
        messageview_set_position(messageview, 0);
 
 #ifdef MAEMO
@@ -1458,6 +1581,9 @@ void messageview_destroy(MessageView *messageview)
        if (!messageview->deferred_destroy) {
                hooks_unregister_hook(MSGINFO_UPDATE_HOOKLIST,
                              messageview->msginfo_update_callback_id);
+               if (messageview->new_window)
+                       hooks_unregister_hook(MSGINFO_UPDATE_HOOKLIST,
+                               messageview->msginfo_moved_callback_id);
        }
 
        if (messageview->updating) {
@@ -1486,7 +1612,9 @@ void messageview_destroy(MessageView *messageview)
                toolbar_destroy(messageview->toolbar);
                g_free(messageview->toolbar);
        }
-       
+
+       list_free_strings(messageview->trail);
+       g_list_free(messageview->trail);
        msgview_list = g_list_remove(msgview_list, messageview); 
 
        if (messageview->window)
@@ -2366,28 +2494,39 @@ static void next_labeled_cb(GtkAction *action, gpointer data)
        }
 }
 
-static void last_read_cb(GtkAction *action, gpointer data)
+static void prev_history_cb(GtkAction *action, gpointer data)
 {
        MessageView *messageview = (MessageView *)data;
-       messageview->updating = TRUE;
-       summary_select_last_read(messageview->mainwin->summaryview);
-       messageview->updating = FALSE;
-
-       if (messageview->deferred_destroy) {
-               debug_print("messageview got away!\n");
-               messageview_destroy(messageview);
-               return;
+       MsgInfo *info = messageview_nav_get_prev(messageview);
+       if (info) {
+               messageview->updating = TRUE;
+               messageview_show(messageview, info, 
+                                        messageview->all_headers);
+               messageview->updating = FALSE;
+               procmsg_msginfo_free(info);
+               if (messageview->deferred_destroy) {
+                       debug_print("messageview got away!\n");
+                       messageview_destroy(messageview);
+                       return;
+               }
        }
-       if (messageview->mainwin->summaryview->selected) {
-#ifndef GENERIC_UMPC
-               MsgInfo * msginfo = summary_get_selected_msg(messageview->mainwin->summaryview);
-                      
-               if (msginfo)
-                       messageview_show(messageview, msginfo, 
+}
+
+static void next_history_cb(GtkAction *action, gpointer data)
+{
+       MessageView *messageview = (MessageView *)data;
+       MsgInfo *info = messageview_nav_get_next(messageview);
+       if (info) {
+               messageview->updating = TRUE;
+               messageview_show(messageview, info, 
                                         messageview->all_headers);
-#endif
-       } else {
-               gtk_widget_destroy(messageview->window);
+               messageview->updating = FALSE;
+               procmsg_msginfo_free(info);
+               if (messageview->deferred_destroy) {
+                       debug_print("messageview got away!\n");
+                       messageview_destroy(messageview);
+                       return;
+               }
        }
 }
 
@@ -2761,7 +2900,9 @@ static gboolean messageview_update_msg(gpointer source, gpointer data)
        if (messageview->msginfo != msginfo_update->msginfo)
                return FALSE;
 
-       if (msginfo_update->flags & MSGINFO_UPDATE_DELETED) {
+       if ((msginfo_update->flags & MSGINFO_UPDATE_DELETED) &&
+               !messageview->new_window)
+       {
                MsgInfo *old_msginfo = messageview->msginfo;
                messageview_clear(messageview);
                messageview_update(messageview, old_msginfo);
@@ -2770,6 +2911,29 @@ static gboolean messageview_update_msg(gpointer source, gpointer data)
        return FALSE;
 }
 
+static gboolean messageview_msg_moved(gpointer source, gpointer data)
+{
+       MsgInfoUpdate *msginfo_update = (MsgInfoUpdate *) source;
+       MessageView *messageview = (MessageView *) data;
+       MsgInfo *msg_old = messageview->msginfo;
+       MsgInfo *msg_new = msginfo_update->msginfo;
+
+       if (strcmp2(msg_new->msgid, msg_old->msgid))
+               return FALSE;
+
+       if ((msginfo_update->flags & MSGINFO_UPDATE_ADDED) &&
+           (folder_item_get_msginfo(msg_old->folder, msg_old->msgnum) == NULL))
+       {
+               if (folder_has_parent_of_type(msg_new->folder, F_TRASH))
+                       messageview_destroy(messageview);
+               else
+                       messageview_show(messageview, msg_new,
+                                        messageview->all_headers);
+       }
+       
+       return FALSE;
+}
+
 void messageview_set_menu_sensitive(MessageView *messageview)
 {
        if (!messageview || !messageview->new_window) 
@@ -2780,6 +2944,8 @@ void messageview_set_menu_sensitive(MessageView *messageview)
        cm_toggle_menu_set_active_full(messageview->ui_manager, "Menu/View/Quotes/CollapseAll", (prefs_common.hide_quotes == 1));
        cm_toggle_menu_set_active_full(messageview->ui_manager, "Menu/View/Quotes/Collapse2", (prefs_common.hide_quotes == 2));
        cm_toggle_menu_set_active_full(messageview->ui_manager, "Menu/View/Quotes/Collapse3", (prefs_common.hide_quotes == 3));
+       cm_menu_set_sensitive_full(messageview->ui_manager, "Menu/View/Goto/PrevHistory", messageview_nav_has_prev(messageview));
+       cm_menu_set_sensitive_full(messageview->ui_manager, "Menu/View/Goto/NextHistory", messageview_nav_has_next(messageview));
 }
 
 void messageview_learn (MessageView *msgview, gboolean is_spam)
index 3e593d1b74d552a3a555a8950363e87ef0a28060..d4ae59ac7a6dac73a5c5a31ec9f60e2352fb6486 100644 (file)
@@ -75,12 +75,15 @@ struct _MessageView
        gboolean all_headers;
 
        gint msginfo_update_callback_id;
+       gint msginfo_moved_callback_id;
        gboolean updating;
        gboolean deferred_destroy;
        
        gboolean show_full_text;
        gboolean partial_display_shown;
        GtkUIManager *ui_manager;
+       GList *trail;
+       gint trail_pos;
 };
 
 MessageView *messageview_create                        (MainWindow     *mainwin);
@@ -127,4 +130,9 @@ void messageview_list_urls                  (MessageView    *msgview);
 void messageview_show_partial_display          (MessageView    *msgview, 
                                                 MsgInfo        *msginfo,
                                                 size_t          length);
+gboolean messageview_nav_has_prev(MessageView *messageview);
+gboolean messageview_nav_has_next(MessageView *messageview);
+MsgInfo *messageview_nav_get_prev(MessageView *messageview);
+MsgInfo *messageview_nav_get_next(MessageView *messageview);
+
 #endif /* __MESSAGEVIEW_H__ */
index 6c49fd529cd0e7508e506f38f11cc4bb5246e6f9..58558e360b51118a14956245fb589e9f8c4b9720 100644 (file)
@@ -533,7 +533,7 @@ gint mutt_import_data( MuttFile *muttFile, AddressCache *cache ) {
 */
 gchar *mutt_find_file( void ) {
        const gchar *homedir;
-       gchar str[ WORK_BUFLEN ];
+       gchar str[ WORK_BUFLEN + 1 ];
        gint len;
        FILE *fp;
 
@@ -548,7 +548,7 @@ gchar *mutt_find_file( void ) {
                        str[ ++len ] = '\0';
                }
        }
-       strncat( str, MUTT_HOME_FILE, WORK_BUFLEN );
+       strncat( str, MUTT_HOME_FILE, WORK_BUFLEN - strlen(str) );
 
        /* Attempt to open */
        if( ( fp = g_fopen( str, "rb" ) ) != NULL ) {
index 7a87558009c800816dfaace9a626dcd6efdc535c..a93c97b96ecfea62925e013bf7c2cd48339811e0 100644 (file)
@@ -635,7 +635,7 @@ gint pine_import_data( PineFile *pineFile, AddressCache *cache ) {
  */
 gchar *pine_find_file( void ) {
        const gchar *homedir;
-       gchar str[ WORK_BUFLEN ];
+       gchar str[ WORK_BUFLEN + 1 ];
        gint len;
        FILE *fp;
 
@@ -650,7 +650,7 @@ gchar *pine_find_file( void ) {
                        str[ ++len ] = '\0';
                }
        }
-       strncat( str, PINE_HOME_FILE, WORK_BUFLEN );
+       strncat( str, PINE_HOME_FILE, WORK_BUFLEN - strlen(str) );
 
        /* Attempt to open */
        if( ( fp = g_fopen( str, "rb" ) ) != NULL ) {
index 16ee1b164c9a00f3a228496eaab97d15fc05ada2..0de4e57ca713ee42954fb5b0f06081e9c9d19c9f 100644 (file)
@@ -1167,6 +1167,9 @@ static PrefParam param[] = {
        {"flush_metadata", "TRUE", &prefs_common.flush_metadata, P_BOOL,
         NULL, NULL, NULL},
 
+       {"nav_history_length", "50", &prefs_common.nav_history_length, P_INT,
+        NULL, NULL, NULL},
+
        {NULL, NULL, NULL, P_OTHER, NULL, NULL, NULL}
 };
 
index 03761b57f9310d4d77a6e665427836fe66ffcb39..fb6600b86b4e1f0ce5e90f1a54469bcf8cea6673 100644 (file)
@@ -519,6 +519,7 @@ struct _PrefsCommon
        gboolean inherit_folder_props;
        gboolean flush_metadata;
 
+       gint nav_history_length;
 };
 
 extern PrefsCommon prefs_common;
index e44627eade36ab0182444fb2406268d5714e1eb2..43c151f887279b0b07b979c48465563e5a0228f6 100644 (file)
@@ -1701,15 +1701,15 @@ static void parse_parameters(const gchar *parameters, GHashTable *table)
                        tmp[0] = '\0';
 
                        if ((tmp[1] == '0') && (tmp[2] == '\0') && 
-                           (g_slist_find_custom(concatlist, down_attr, g_str_equal) == NULL))
+                           (g_slist_find_custom(concatlist, down_attr, g_strcmp0) == NULL))
                                concatlist = g_slist_prepend(concatlist, g_strdup(tmpattr));
 
-                       if (convert && (g_slist_find_custom(convlist, down_attr, g_str_equal) == NULL))
+                       if (convert && (g_slist_find_custom(convlist, down_attr, g_strcmp0) == NULL))
                                convlist = g_slist_prepend(convlist, g_strdup(tmpattr));
 
                        g_free(tmpattr);
                } else if (convert) {
-                       if (g_slist_find_custom(convlist, down_attr, g_str_equal) == NULL)
+                       if (g_slist_find_custom(convlist, down_attr, g_strcmp0) == NULL)
                                convlist = g_slist_prepend(convlist, g_strdup(down_attr));
                }
 
index 5979ef705fa104c497ab497dea86486c235f6895..e567237bf2c0f4437214a1746bb479e0e1b48f0b 100644 (file)
@@ -756,6 +756,52 @@ static PrefsAccount *procmsg_get_account_from_file(const gchar *file)
        return mailac;
 }
 
+gchar *procmsg_msginfo_get_identifier(MsgInfo *msginfo)
+{
+       gchar *folder_id;
+       const gchar *msgid;
+       gchar *id;
+
+       cm_return_val_if_fail(msginfo != NULL, NULL);
+       folder_id = folder_item_get_identifier(msginfo->folder);
+       msgid = msginfo->msgid;
+
+       id = g_strconcat(folder_id, G_DIR_SEPARATOR_S, msgid, NULL);
+
+       g_free(folder_id);
+
+       return id;
+}
+
+MsgInfo *procmsg_get_msginfo_from_identifier(const gchar *id)
+{
+       gchar *folder_id = g_strdup(id);
+       gchar *separator = strrchr(folder_id, G_DIR_SEPARATOR);
+       const gchar *msgid;
+       FolderItem *item;
+       MsgInfo *msginfo;
+
+       if (separator == NULL) {
+               g_free(folder_id);
+               return NULL;
+       }
+
+       *separator = '\0';
+       msgid = separator + 1;
+
+       item = folder_find_item_from_identifier(folder_id);
+
+       if (item == NULL) {
+               g_free(folder_id);
+               return NULL;
+       }
+
+       msginfo = folder_item_get_msginfo_by_msgid(item, msgid);
+       g_free(folder_id);
+
+       return msginfo;
+}
+
 static GSList *procmsg_list_sort_by_account(FolderItem *queue, GSList *list)
 {
        GSList *result = NULL;
@@ -1147,7 +1193,8 @@ void procmsg_print_message(MsgInfo *msginfo, const gchar *cmdline)
        g_free(prtmp);
 
        g_strchomp(buf);
-       if (buf[strlen(buf) - 1] != '&') strncat(buf, "&", sizeof(buf));
+       if (buf[strlen(buf) - 1] != '&')
+               strncat(buf, "&", sizeof(buf) - strlen(buf) - 1);
        if (system(buf) == -1)
                g_warning("system(%s) failed.", buf);
 }
index 89fd67f51cee886b37a256c1215b6a9be52cf332..db488ff5032cdba1ad146438c775b7587dfa2e24 100644 (file)
@@ -174,7 +174,8 @@ typedef guint32 MsgTmpFlags;
 
 typedef enum {
        MSGINFO_UPDATE_FLAGS = 1 << 0,
-       MSGINFO_UPDATE_DELETED = 1 << 1
+       MSGINFO_UPDATE_DELETED = 1 << 1,
+       MSGINFO_UPDATE_ADDED = 1 << 2
 } MsgInfoUpdateFlags;
 
 #include "procmime.h"
@@ -400,4 +401,6 @@ gchar *procmsg_msginfo_get_tags_str(MsgInfo *msginfo);
 void procmsg_msginfo_update_tags(MsgInfo *msginfo, gboolean set, gint id);
 void procmsg_msginfo_clear_tags(MsgInfo *msginfo);
 void procmsg_msginfo_commit_tags(GSList *msglist);
+MsgInfo *procmsg_get_msginfo_from_identifier(const gchar *id);
+gchar *procmsg_msginfo_get_identifier(MsgInfo *msginfo);
 #endif /* __PROCMSG_H__ */
index 4b841aae8efe71ef83c33f0756b482a471b5234c..4b309df0591623c2c689fb7f3996ebfa48f5c993 100644 (file)
@@ -47,6 +47,7 @@
 #include "inputdialog.h"
 #include "alertpanel.h"
 #include "manage_window.h"
+#include "logwindow.h"
 #include "socket.h"
 #include "utils.h"
 #include "gtkutils.h"
@@ -76,6 +77,8 @@ static gint send_send_data_finished   (Session                *session,
 static SendProgressDialog *send_progress_dialog_create(void);
 static void send_progress_dialog_destroy(SendProgressDialog *dialog);
 
+static void send_showlog_button_cb     (GtkWidget      *widget,
+                                        gpointer        data);
 static void send_cancel_button_cb      (GtkWidget      *widget,
                                         gpointer        data);
 
@@ -556,6 +559,8 @@ static SendProgressDialog *send_progress_dialog_create(void)
        progress = progress_dialog_create();
        gtk_window_set_title(GTK_WINDOW(progress->window),
                             _("Sending message"));
+       g_signal_connect(G_OBJECT(progress->showlog_btn), "clicked",
+                        G_CALLBACK(send_showlog_button_cb), dialog);
        g_signal_connect(G_OBJECT(progress->cancel_btn), "clicked",
                         G_CALLBACK(send_cancel_button_cb), dialog);
        g_signal_connect(G_OBJECT(progress->window), "delete_event",
@@ -595,6 +600,13 @@ static void send_progress_dialog_destroy(SendProgressDialog *dialog)
        g_free(dialog);
 }
 
+static void send_showlog_button_cb(GtkWidget *widget, gpointer data)
+{
+       MainWindow *mainwin = mainwindow_get_mainwindow();
+
+       log_window_show(mainwin->logwin);
+}
+
 static void send_cancel_button_cb(GtkWidget *widget, gpointer data)
 {
        SendProgressDialog *dialog = (SendProgressDialog *)data;
index c6eb5c46d94f12439ff21f1aa663bf2014cdde87..45aecdb333f892aa5b56bd4948a4b7baa9cdc9e6 100644 (file)
@@ -1139,7 +1139,6 @@ gboolean summary_show(SummaryView *summaryview, FolderItem *item)
        if (!summaryview->mainwin)
                return FALSE;
        START_TIMING("");
-       summaryview->last_displayed = NULL;
        summary_switch_from_to(summaryview, item);
 
        inc_lock();
@@ -1388,7 +1387,6 @@ gboolean summary_show(SummaryView *summaryview, FolderItem *item)
 
        if (is_refresh) {
                if (!quicksearch_is_in_typing(summaryview->quicksearch)) {
-                       summaryview->last_displayed = summaryview->displayed;
                        summaryview->displayed =
                                summary_find_msg_by_msgnum(summaryview,
                                                           displayed_msgnum);
@@ -2049,12 +2047,6 @@ void summary_select_next_labeled(SummaryView *summaryview)
                summary_select_node(summaryview, node, TRUE, FALSE);
 }
 
-void summary_select_last_read(SummaryView *summaryview)
-{
-       if (summaryview->last_displayed)
-               summary_select_node(summaryview, summaryview->last_displayed, TRUE, FALSE);
-}
-
 void summary_select_parent(SummaryView *summaryview)
 {
        GtkCMCTreeNode *node = NULL;
@@ -2073,6 +2065,14 @@ void summary_select_by_msgnum(SummaryView *summaryview, guint msgnum)
        summary_select_node(summaryview, node, FALSE, TRUE);
 }
 
+void summary_display_by_msgnum(SummaryView *summaryview, guint msgnum)
+{
+       GtkCMCTreeNode *node;
+
+       node = summary_find_msg_by_msgnum(summaryview, msgnum);
+       summary_select_node(summaryview, node, TRUE, FALSE);
+}
+
 void summary_select_by_msg_list(SummaryView    *summaryview, GSList *msginfos)
 {
        GtkCMCTree *ctree;
@@ -3507,7 +3507,6 @@ static void summary_display_msg_full(SummaryView *summaryview,
                        else
                                gtkut_window_popup(summaryview->ext_messageview->window);
                        msgview = summaryview->ext_messageview;
-                       summaryview->last_displayed = summaryview->displayed;
                        summaryview->displayed = row;
                        val = messageview_show(msgview, msginfo, all_headers);
                        if (mimeview_tree_is_empty(msgview->mimeview))
@@ -3516,7 +3515,6 @@ static void summary_display_msg_full(SummaryView *summaryview,
                                GTK_CMCLIST(summaryview->ctree)->focus_row);
                } else {
                        msgview = summaryview->messageview;
-                       summaryview->last_displayed = summaryview->displayed;
                        summaryview->displayed = row;
                        if (!messageview_is_visible(msgview) &&
                            gtk_window_is_active(GTK_WINDOW(summaryview->mainwin->window))) {
@@ -6528,7 +6526,6 @@ void summary_set_column_order(SummaryView *summaryview)
 
        summaryview->selected = summary_find_msg_by_msgnum(summaryview, selected_msgnum);
        summaryview->displayed = summary_find_msg_by_msgnum(summaryview, displayed_msgnum);
-       summaryview->last_displayed = summaryview->displayed;
        if (!summaryview->displayed)
                messageview_clear(summaryview->messageview);
        else
index ceabaafec196321e4e8034c105d41b7dcb9fa2ef..6db31e43da8e826b9730f2387d88eb0e7734d648 100644 (file)
@@ -115,7 +115,6 @@ struct _SummaryView
 
        GtkCMCTreeNode *selected;
        GtkCMCTreeNode *displayed;
-       GtkCMCTreeNode *last_displayed;
 
        gboolean display_msg;
 
@@ -204,10 +203,11 @@ void summary_select_prev_marked     (SummaryView          *summaryview);
 void summary_select_next_marked          (SummaryView          *summaryview);
 void summary_select_prev_labeled  (SummaryView         *summaryview);
 void summary_select_next_labeled  (SummaryView         *summaryview);
-void summary_select_last_read     (SummaryView         *summaryview);
 void summary_select_parent        (SummaryView         *summaryview);
 void summary_select_by_msgnum    (SummaryView          *summaryview,
                                   guint                 msgnum);
+void summary_display_by_msgnum   (SummaryView          *summaryview,
+                                  guint                 msgnum);
 void summary_select_by_msg_list   (SummaryView         *summaryview, GSList *msginfos);
 guint summary_get_current_msgnum  (SummaryView         *summaryview);
 void summary_select_node         (SummaryView          *summaryview,
index c61baf93e7d30f3cd82c640c02bc542421c9d311..808d57ebbda65ed5aad6efd1af3f3b4741b79cf2 100644 (file)
@@ -561,7 +561,7 @@ GList *vcard_get_all_persons( VCardFile *cardFile ) {
 gchar *vcard_find_gnomecard( void ) {
        const gchar *homedir;
        gchar buf[ WORK_BUFLEN ];
-       gchar str[ WORK_BUFLEN ];
+       gchar str[ WORK_BUFLEN + 1 ];
        gchar *fileSpec;
        gint len, lenlbl, i;
        FILE *fp;
@@ -577,9 +577,9 @@ gchar *vcard_find_gnomecard( void ) {
                        str[ ++len ] = '\0';
                }
        }
-       strncat( str, GNOMECARD_DIR, WORK_BUFLEN );
-       strncat( str, G_DIR_SEPARATOR_S, WORK_BUFLEN );
-       strncat( str, GNOMECARD_FILE, WORK_BUFLEN );
+       strncat( str, GNOMECARD_DIR, WORK_BUFLEN - strlen(str) );
+       strncat( str, G_DIR_SEPARATOR_S, WORK_BUFLEN - strlen(str) );
+       strncat( str, GNOMECARD_FILE, WORK_BUFLEN - strlen(str) );
 
        fileSpec = NULL;
        if( ( fp = g_fopen( str, "rb" ) ) != NULL ) {