sync with 0.9.10claws57 HEAD
authorPaul Mangan <paul@claws-mail.org>
Mon, 10 May 2004 10:22:28 +0000 (10:22 +0000)
committerPaul Mangan <paul@claws-mail.org>
Mon, 10 May 2004 10:22:28 +0000 (10:22 +0000)
92 files changed:
AUTHORS
ChangeLog
ChangeLog-gtk2.claws
ChangeLog.claws
ChangeLog.jp
configure.ac
intl/.cvsignore
po/.cvsignore
po/POTFILES.in
src/Makefile.am
src/addr_compl.c
src/addressbook.c
src/addrindex.c
src/addrindex.h
src/addrselect.c
src/addrselect.h
src/codeconv.c
src/codeconv.h
src/common/defs.h
src/common/nntp.c
src/common/ssl.c
src/common/utils.c
src/common/utils.h
src/compose.c
src/compose.h
src/filtering.c
src/folder.c
src/folder.h
src/foldersel.c
src/folderutils.c
src/folderutils.h
src/folderview.c
src/folderview.h
src/gtk/Makefile.am
src/gtk/about.c
src/gtk/colorsel.c
src/gtk/description_window.c
src/gtk/filesel.c
src/gtk/foldersort.c
src/gtk/gtkaspell.c
src/gtk/inputdialog.c
src/gtk/menu.c
src/gtk/menu.h
src/gtk/pluginwindow.c
src/gtk/progressdialog.c
src/imap.c
src/import.c
src/inc.c
src/inc.h
src/ldapquery.c
src/ldapquery.h
src/ldapserver.c
src/main.c
src/mainwindow.c
src/matcher.c
src/matcher.h
src/matcher_parser_parse.y
src/mbox.c
src/mbox.h
src/messageview.c
src/messageview.h
src/mh.c
src/mimeview.c
src/msgcache.c
src/news.c
src/plugins/clamav/clamav_plugin.c
src/plugins/dillo_viewer/dillo_prefs.c
src/plugins/image_viewer/viewer.c
src/plugins/image_viewer/viewerprefs.c
src/pop.c
src/pop.h
src/prefs_account.c
src/prefs_actions.c
src/prefs_common.c
src/prefs_common.h
src/prefs_folder_item.c
src/prefs_fonts.c
src/prefs_template.c
src/prefs_themes.c
src/procmime.c
src/quote_fmt.c
src/quote_fmt.h
src/quote_fmt_lex.l
src/quote_fmt_parse.y
src/sgpgme.c
src/stock_pixmap.c
src/stock_pixmap.h
src/summaryview.c
src/summaryview.h
src/textview.c
src/toolbar.c
src/toolbar.h

diff --git a/AUTHORS b/AUTHORS
index 8be22e3..2893b1e 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -38,10 +38,11 @@ sylpheed-claws translation team
        [es]    Ricardo Mones Lastra    <mones@aic.uniovi.es>
        [fr]    Melvin Hadasht          <melvin.hadasht@free.fr>
        [hr]    Dragan                  <drleskov@inet.hr>
-       [it]    Alessandro Maestri      <maestri@cs.tin.it>
+       [it]    Andrea Spadaccini       <lupin85@email.it>
        [ja]    Rui Hirokawa            <rui_hirokawa@ybb.ne.jp>
        [pl]    Emil                    <eminowbl@posejdon.wpk.p.lodz.pl>
        [ru]    Ruslan N. Balkin        <baron@voices.ru>
+       [ru]    Pavlo Bohmat            <bohm@ukr.net>
        [sk]    Andrej Kacian           <andrej@kacian.sk>
        [sr]    Urke MMI                <urke@gmx.net>
        [zh_CN] Hansom Young            <hansom_young@yahoo.com>
@@ -200,3 +201,5 @@ contributors (beside the above; based on Changelog)
        Matthias Förste
        David Chalmers
        Chad Robinson
+       Edgar Toernig
+       Fabien Vantard
index 1e9d727..9cf0880 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,162 @@
+2004-03-19
+
+       * src/defs.h
+         src/inc.[ch]: changed the method of updating the progress dialog
+         to reduce the overhead on a fast network.
+
+2004-03-16
+
+       * src/nntp.c: nntp_session_new(): attempt to authenticate at the
+         beginning of a session (thanks to Shiino Yuki and IWAMOTO, Kouichi).
+       * src/news.c
+         src/nntp.c: destroy session when socket error occurred.
+
+2004-03-12
+
+       * src/mainwindow.c
+         src/summaryview.[ch]: added a function to filter selected
+         messages.
+
+2004-03-12
+
+       * src/filter.[ch]
+         src/prefs_filter.c: rewrote the filtering system (the UI is not
+         implemented yet).
+
+2004-03-09
+
+       * src/filter.c: fixed the matching algorithm of "not contain" flag
+         (also match if a header not exist, and handle same multiple
+         headers).
+       * src/imageview.c: get_resized_size(): fixed a typo that caused
+         resizing problem.
+
+2004-03-02
+
+       * src/folder.c
+         src/mh.c: only update FolderItem::last_num when removing the last
+         number of message in MH folders, and don't scan in other case
+         (fixes wrong message count on moving).
+
+2004-03-02
+
+       * src/folderview.c
+         src/summaryview.c: always move messages by default when using DnD
+         (except for News folder). Copy messages if Ctrl-key is pressed.
+       * src/mainwindow.c: main_window_empty_trash()
+         src/summaryview.c: summary_execute(): added missing
+         statusbar_pop_all().
+
+2004-02-29
+
+       * version 0.9.10
+
+2004-02-26
+
+       * src/prefs_common.c: made the default of "inc_local" FALSE.
+
+2004-02-26
+
+       * src/account.c
+         src/folderview.c: toggle online mode when checking IMAP4 accounts.
+         Pop status bar after that.
+       * src/inc.c: code cleanup.
+       * src/mainwindow.[ch]: added main_window_get() and
+         main_window_toggle_online_if_offline().
+       * src/prefs_common.c: prefs_common_read_config(): fixed a bug that
+         made it offline mode on first execution.
+
+2004-02-25
+
+       * src/imageview.c: enabled automatic resize on window resize.
+         restrict the minimum size to 16 pixels to prevent crash.
+         imageview_init(): don't cache images when using imlib.
+         imageview_show_image(): fixed memory leak.
+       * src/mimeview.c: mimeview_init(): call imageview_init().
+
+2004-02-24
+
+       * src/codeconv.[ch]: added ISO-2022-JP-3 encoding.
+
+2004-02-24
+
+       * src/codeconv.c
+         src/mainwindow.c
+         src/messageview.c: added KOI8-U encoding.
+       * src/prefs_common.c: prefs_message_create(): modified the string
+         of resizing image option.
+
+2004-02-19
+
+       * src/addressbook.c: addressbook_list_selected(): corrected its
+         argument.
+       * src/imageview.[ch]: keep original image data in ImageView, and
+         enabled the toggle of resizing.
+       * src/messageview.[ch]
+         src/mimeview.[ch]: handle ImageView in MimeView instead of
+         MessageView.
+
+2004-02-16
+
+       * src/imap.c
+         src/news.c
+         src/summaryview.c: removed statusbar_pop_all() from imap.c and
+         news.c (do it in summaryview.c).
+
+2004-02-12
+
+       * src/inc.[ch]
+         src/pop.[ch]: made inc_drop_message() the virtual function of
+         Pop3Session and removed the dependency of pop.c on inc.h.
+
+2004-02-12
+
+       * src/mainwindow.c
+         src/messageview.[ch]
+         src/textview.c: added statusbar to the message view with new window.
+
+2004-02-10
+
+       * src/inc.[ch]: use hash table for progressive update.
+         changed update interval to 2 sec.
+       * src/folder.[ch]
+         src/mh.c
+         src/procmsg.c
+         src/summaryview.c: added FolderItem::unmarked_num to correct the
+         folder message counting.
+
+2004-02-09
+
+       * src/inc.[ch]: update folderview progressively.
+       * src/foldersel.c: display full id for selected item.
+
+2004-02-06
+
+       * src/folderview.[ch]: code cleanup.
+         folderview_append_item(): new. It appends the folder to the folder
+         view.
+       * src/foldersel.c: foldersel_new_folder(): use
+         folderview_append_item().
+
+2004-02-06
+
+       * src/foldersel.c: implemented 'create new folder' function.
+       * src/folder.[ch]: folder_find_child_item_by_name(): new.
+       * src/utils.h: AUTORELEASE_STR(): convert malloc'd string into
+         auto-release (alloca'd) one.
+
+2004-02-05
+
+       * src/folderview.c: put together folderview_new_imap_folder_cb() into
+         folderview_new_folder_cb().
+
+2004-02-04
+
+       * src/compose.c: compose_write_to_file(): removed redundant strlen()
+         (thanks to Alfons).
+       * src/textview.c: textview_button_pressed(): select correct account
+         when address is clicked.
+
 2004-01-29
 
        * version 0.9.9
 
        * src/alertpanel.c: alertpanel_create(): fixed truncated message.
        * src/rfc2015.c: rfc2015_decrypt_message(): fixed the case problem
-         of content-type (thanks to René Rebe for the patch).
+         of content-type (thanks to Ren?Rebe for the patch).
        * src/codeconv.c: code_get_code_conv_func(): fixed the ISO-8859-1
          detection.
        * src/prefs_common.c: prefs_send_create(): made some more character
index 4cc8314..fb14e00 100644 (file)
@@ -1,3 +1,7 @@
+2004-05-10 [paul]      0.9.10claws57
+
+       * sync with 0.9.10claws57 HEAD
+
 2004-05-05 [paul]      0.9.9.claws1
 
        * ChangeLog-gtk2        ** REMOVED **
index 4c25467..f793b59 100644 (file)
@@ -1,3 +1,834 @@
+2004-05-09 [christoph] 0.9.10claws57
+
+       * src/folderview.c
+               check for folder class functions and not folder type to detect
+               valid drag targets
+
+2004-05-08 [christoph] 0.9.10claws56
+
+       * src/sgpgme.c
+               fix date output for signature expire times
+
+       (Patch by Edgar Toernig <froese@gmx.de>)
+
+2004-05-06 [christoph] 0.9.10claws55
+
+       * src/gtk/prefswindow.c
+               change window type to DIALOG
+
+       * src/folder.[ch]
+       * src/folderview.c
+       * src/news_gtk.c
+               o add folder_remove()
+               o change FolderUpdate hook flag names (NEW -> ADD, DESTROY -> REMOVE)
+               o add new "sort" field to Folder, no longer sort folders by type
+                 higher sort values will be first in the folder list, new folders get 0
+                 and will be added to the end
+
+       * src/mainwindow.c
+       * src/gtk/Makefile.am
+       * src/gtk/foldersort.(c|h|glade)                        ** NEW **
+               add dialog to allow users to change the folder order
+
+2004-05-04 [paul]      0.9.10claws54
+
+       * src/inc.c
+               Display account_name in statusbar when retrieving
+               messages from a pop account
+       * src/prefs_account.c
+               display account name in title of prefs_account
+               window
+       * src/prefs_folder_item.c
+               display folder name in title of prefs_folder window
+
+       all 3 patches submitted by Fabien Vantard
+
+       * AUTHORS
+               add Fabien Vantard
+
+2004-05-04 [paul]      0.9.10claws53
+
+       * src/prefs_actions.c
+         src/prefs_template.c
+               'Esc' Key exits alertpanel
+               Patch submitted by Fabien Vantard <fzz@ifrance.com>
+
+2004-04-26 [christoph] 0.9.10claws52
+
+       * src/gtk/about.c
+       * src/gtk/colorsel.c
+       * src/gtk/description_window.c
+       * src/gtk/filesel.c
+       * src/gtk/gtkaspell.c
+       * src/gtk/inputdialog.c
+       * src/gtk/pluginwindow.c
+       * src/gtk/progressdialog.c
+               o remove gtk_window_set_position(..., GTK_WIN_POS_CENTER) because
+                 it does not work correctly with xinerama
+               o lock incorporation while the plugin window is open
+
+2004-04-23 [paul]      0.9.10claws51
+
+       * po/POTFILES.in
+               update location of inputdialog.c
+               
+       * src/gtk/about.c
+               update Copyright string
+               
+       * src/msgcache.c
+         src/prefs_common.c
+         src/prefs_themes.c
+               improve the english a little
+
+2004-04-22 [christoph] 0.9.10claws50
+
+       * src/folderutils.[ch]
+               add folderutils_mark_all_read()
+
+       * src/folderview.c
+               readd "mark all read" from popup menu, now works
+               in all folders and not only the opened folder
+
+2004-04-21 [christoph] 0.9.10claws49
+
+       * src/Makefile.am
+       * src/inputdialog.[ch]                  ** REMOVED **
+       * src/gtk/Makefile.am
+       * src/gtk/inputdialog.[ch]              ** NEW **
+               move inputdialog.[ch] into gtk directory
+
+       * src/mh_gtk.c
+               remove check for missing IMAP folder account
+
+2004-04-20 [christoph] 0.9.10claws48
+
+       * src/mainwindow.c
+       * src/foldersel.c
+               remove new/rename/delete folder GUI functions because
+               they are always active, even for news folders, and can
+               not be easily made folder class dependent
+
+       * src/gtk/menu.[ch]
+               make menu_translate() public
+
+       * src/Makefile.am
+       * src/folder.[ch]
+       * src/folderview.[ch]
+       * src/imap_gtk.[ch]                     ** NEW **
+       * src/main.c
+       * src/mh_gtk.[ch]                       ** NEW **
+       * src/news_gtk.[ch]                     ** NEW **
+               o dynamically build FolderView popup menus from a folder
+                 specific part, with callbacks to seperated code, and
+                  a common part
+               o remove the folder class specifiy code from folderview.c
+
+2004-04-15 [luke]      0.9.10claws47
+
+       * src/prefs_folder_item.c
+               o remove buttons for applying 'scan for new mail'
+                 and 'process at startup' to sub folders
+               o add 'apply to sub folder' check buttons for all
+                 properties and set folder prefs accordingly
+               o replace multiple gtk_widget_show() with one
+                 gtk_widget_show_all() on container
+
+2004-04-14 [darko]     0.9.10claws46
+
+       * src/gtk/Makefile.am
+       * src/gtk/pluginwindow.c
+               load plugins from to $(prefix)/lib/sylpheed/plugins
+               in file selection dialog
+       * src/plugins/clamav/clamav_plugin.c
+               const correctness
+
+2004-04-14 [christoph] 0.9.10claws45
+
+       * src/folder.c
+       * src/plugins/image_viewer/viewer.c
+               fix g_warnings
+
+2004-04-10 [alfons]    0.9.10claws44
+       
+       * src/compose.c
+               appropriate auto account selection when forwarding
+               (fixes bug #476, "forward as attachment does not listen
+               to account rules")
+
+2004-04-09 [alfons]    0.9.10claws43
+
+       * src/summaryview.c
+               make quick search combo matching case sensitive
+
+2004-04-06 [alfons]    0.9.10claws42
+
+       * src/addr_compl.c
+               use cursor position to prevent clearing the entire entry
+
+2004-04-06 [alfons]    0.9.10claws41
+
+       * src/folderview.c
+               fix bug #472, "filter not updated when renaming folder" 
+
+2004-04-06 [alfons]    0.9.10claws40
+
+       * src/messageview.[ch]
+         src/summaryview.c
+               reflect changes to Show all headers to main view
+               and message view (only affects detached message
+               view). see also bug #473, 'Show All Headers 
+               "problem"'.
+
+2004-04-03 [alfons]    0.9.10claws39
+
+       * src/matcher.c
+               free address list
+
+2004-04-03 [alfons]    0.9.10claws38
+
+       * src/matcher_parser_parse.y
+         src/matcher.[ch]
+               prepare address look up matcher type; marginally
+               tested, and not hooked into the UI yet.
+
+               basically it accepts the result of the left hand
+               side of the matcher (the "criteria"):
+
+                       from all_in_addressbook ""
+                       ~to_or_cc any_in_addressbook ""
+               
+               the first case matches all addresses found in the
+               from header, and the second case matches if any
+               (at least one) of the addresses in to or cc headers 
+               are not in the address book.
+
+               the string argument is not used yet, but is intended
+               to match a group of addresses 
+
+2004-04-02 [luke]      0.9.10claws37
+
+       * src/prefs_folder_item.c
+               Add two buttons to apply 'scan for new mail'
+               and 'process at startup' to sub folders
+
+2004-04-02 [luke]
+       * tools/textviewer.sh
+               better filename extension matching plus some support for
+               MS Excel, MS Powerpoint and HTML
+
+2004-03-29 [christoph] 0.9.10claws36
+
+       * src/folder.h
+       * src/folderutils.[ch]
+       * src/mainwindow.c
+               add delete duplicates for all folders
+
+2004-03-29 [alfons]    0.9.10claws35
+
+       * src/folder.c
+               don't pass NULL to XXXprintf(); fixes Solaris crashes
+               when selecting top-level folder node (thanks to 
+               Alex S. Moore)
+
+2004-03-28 [keith]     0.9.10claws34
+
+       * src/textview.c
+               prepend "http://" to URIs of the form "www.example.com"
+
+2004-03-28 [paul]      0.9.10claws33
+
+       * src/common/nntp.c
+         src/common/smtp.c
+         src/folder.c
+         src/imap.c
+         src/inc.c
+         src/news.c
+         src/pop.c
+               revise 'translatable string' policy:
+               don't translate debug_print() or log_print(),
+               translate log_message() and log_warning()
+       
+       * po/zh_CN.po
+               update submitted by Hansom Young
+
+2004-03-25 [alfons]    0.9.10claws32
+
+       * src/prefs_common.c
+               I mean this one: Return the GList...
+
+2004-03-25 [alfons]    0.9.10claws31
+
+       * src/prefs_common.h
+               add new members at the end of prefs_common, so
+               they get properly initialized
+
+2004-03-24 [christoph] 0.9.10claws30
+
+       * src/imap.c
+               o NULL is a valid GSList
+
+2004-03-24 [alfons]    0.9.10claws29
+
+       * src/prefs_common.[ch]
+         src/summaryview.c
+         src/common/defs.h
+               add history to quick search (patch submitted by 
+               Ivan Francolin Martinez - thanks!)
+
+2004-03-24 [alfons]    0.9.10claws28
+
+       * src/imap.c
+               NULL output pointer parameter
+
+2004-03-21 [alfons]    0.9.10claws27
+
+       * src/addrindex.[ch]
+         src/addr_compl.c
+               complete addresses on nicks and aliases
+
+2004-03-21 [alfons]    0.9.10claws26
+
+       * src/import.c
+         src/inc.c
+         src/mbox.[ch]
+               disable filters on import mbox (patch submitted
+               by Edgar Toernig)
+
+2004-03-21 [darko]     0.9.10claws25
+
+       * src/addr_compl.c
+               select the address when only one match is found while
+               doing address completion with tab key (feature
+               request #914720)
+
+2004-03-21 [alfons]    0.9.10claws24
+
+       * src/messageview.c
+         src/toolbar.c
+               don't `navigate-delete` when a summary view's selection does not 
+               match the accompanying message view's message
+
+2004-03-20 [alfons]    0.9.10claws23
+
+       * src/summaryview.c
+               hide ext search button on initial display (should fix bug #459,
+               "Toggling quick-search at 1st time: minor UI inconsistency")
+
+2004-03-20 [alfons]    0.9.10claws22
+
+       * src/summaryview.[ch]
+               add function to get selected msginfo, if there's
+               only one selected
+
+2004-03-20 [paul]      0.9.10claws21
+
+       * sync with 0.9.10cvs7
+               see ChangeLog 2004-03-19
+
+2004-03-19 [paul]      0.9.10claws20
+
+       * src/common/nntp.c
+         src/common/smtp.c
+         src/common/ssl.c
+         src/folder.c
+         src/imap.c
+         src/inc.c
+         src/news.c
+         src/pop.c
+               don't translate strings in debug_print(), log_print(),
+               log_message(),  and log_warning()
+
+2004-03-19 [alfons]    0.9.10claws19
+
+       better next/previous/delete/focus navigation with separate 
+       message view 
+       
+       * src/toolbar.c
+               call summaryview_delete() instead of messageview_delete()
+       * src/messageview.c
+               disable messageview_delete()
+
+2004-03-18 [paul]      0.9.10claws18
+
+       * sync with 0.9.10cvs6
+               see ChangeLog 2004-03-16
+
+2004-03-17 [alfons]    0.9.10claws17
+
+       * src/gtk/filesel.c
+               remove bogus semicolon after if() (sometimes it pays to
+               read LKML :)
+
+2004-03-15 [darko]     0.9.10claws16
+
+       * src/gtk/filesel.c
+               support full path in place of a filename
+       * src/mimeview.c
+               store directory attachments were saved to and
+               use it when saving attachments
+       * src/prefs_common.[hc]
+               store directory attachments were last saved to
+
+2004-03-15 [paul]      0.9.10claws15
+
+       * src/folderview.c
+               fix bug where unsubscribing a newsgroup would destroy
+               (most of the) filtering rules
+
+2004-03-15 [paul]      0.9.10claws14
+
+       * src/folderview.c
+               fix Bug 458, 'Folder View remaining empty after 
+               removing a NEWS account' (was also true of IMAP
+               accounts)
+
+2004-03-15 [paul]      0.9.10claws13
+
+       * src/folderview.c
+               fix folderview invisibility of newly subscribed
+               newsgroups
+
+2004-03-13 [paul]      0.9.10claws12
+
+       * src/compose.c
+         src/plugins/dillo_viewer/dillo_prefs.c
+         src/plugins/image_viewer/viewerprefs.c
+               gettextise some forgotten parts
+
+2004-03-13 [alfons]    0.9.10claws11
+
+       * src/imap.c
+               make sure the correct type is passed to sscanf()
+
+2004-03-13 [paul]      0.9.10claws10
+
+       * sync with 0.9.10cvs5
+               see ChangeLog 2004-03-02 and 2004-03-12, 
+               specifically:
+               'always move messages by default when using DnD (except 
+               for News folder). Copy messages if Ctrl-key is pressed.'
+               and 'added a function to filter selected messages'
+
+2004-03-12 [christoph] 0.9.10claws9
+
+       * src/codeconv.c
+               add parameter check to conv_unmime_header_overwrite()
+
+       * src/imap.c
+               o fix spelling
+               o fix removing of NEW flag when UNREAD is unset
+
+       * src/procmime.c
+               decode MIME-headers
+
+       (Closes 437 i18n attachment display error.)
+
+2004-03-12 [paul]      0.9.10claws8
+
+       * po/it.po
+               update. submitted by Andrea Spadaccini <lupin85@email.it>
+               
+       * tools/Makefile.am
+               add 'textviewer.sh'
+
+2004-03-12 [alfons]    0.9.10claws7
+
+       * src/imap.c
+               o quiet compiler and typecast Folder * to IMAP Folder *
+               o wake up and fix my previous incompatible type assignment bug
+
+2004-03-12 [alfons]    0.9.10claws6
+
+       * src/imap.c
+               don't mix up pointers to int, guint32 _and_ 
+               unsigned int 
+
+2004-03-12 [christoph] 0.9.10claws5
+
+       * src/folderview.c
+               Add error requester when renaming a folder failed
+
+       * src/imap.c
+               Check new FolderItem name for namespace seperator
+               before renaming
+
+       (Closes Bug 443 Bad named IMAP folders won't be displayed)
+
+2004-03-11 [christoph] 0.9.10claws4
+
+       * src/folder.[ch]
+       * src/imap.c
+       * src/procmsg.h
+               syncronize flags in cache with IMAP folder flags
+
+       Adapted a patch submitted by Simon 'corecode' Schubert
+       <corecode@corecode.ath.cx> 
+
+
+2004-03-11 [alfons]    0.9.10claws3
+
+       * src/textview.[ch]
+               remove dead code that at one time controlled display of
+               URIs in status bar
+
+2004-03-10 [paul]      0.9.10claws2
+
+       * po/it.po
+               updated by Lupino <lupin85@email.it>
+
+2004-03-09 [alfons]    0.9.10claws1
+
+       * src/matcher.c
+               we're not using yywrap, but we may, so close yyin instead
+               of initial FILE *
+
+2004-03-08 [paul]      0.9.10claws
+
+       * 0.9.10claws released
+
+2004-03-08 [paul]      0.9.9claws41
+
+       * po/es.po
+         po/ja.po
+         po/ru.po
+         po/sk.po
+         po/sr.po
+         po/zh_CN.po
+               update translations. submitted by Ricardo Mones Lastra,
+               Rui Hirokawa, Pavlo Bohmat, Andrej Kacian, Urke MMI,
+               Hansom Young
+
+2004-03-06 [paul]      0.9.9claws40
+
+       * src/stock_pixmap.c
+               fix crash: g_strdup(DEFAULT_PIXMAP_THEME)
+               patch submitted by Pawel Pekala
+
+2004-03-06 [alfons]            0.9.9claws39
+
+       * src/addrindex.c
+               allow nick name completion again 
+
+2004-03-02 [match]             0.9.9claws38
+
+       * configure.ac
+               added definition of USE_LDAP_TLS to support TLS.
+       * src/ldapctrl.[ch]
+       * src/ldapquery.c
+       * src/ldapserver.[ch]
+       * src/addressbook.c
+       * src/addrindex.c
+       * src/editldap.c
+               included LDAP TLS support.
+
+2004-03-02 [christoph]         0.9.9claws37
+
+       * src/folder.[ch]
+               o add more documentation for FolderClass
+               o remove usused FolderClass virtual functions
+
+       * src/imap.c
+       * src/mh.c
+       * src/news.c
+               change creation of FolderClass because static initializations
+               for structs suck in C89
+
+2004-03-01 [paul]
+
+       * sync with 0.9.10
+
+2004-02-28 [keith]     0.9.9claws36
+
+       * src/common/utils.c
+               Fix treatment of whitespace in quicksearch bar (leading
+               spaces and >1 space between commands and parameters).
+
+2004-02-27 [alfons]    0.9.9claws35
+
+       * src/compose.[ch]
+               Explicitly remove draft timeout to fix nasty race between 
+               compose_send_cb() (which destroys the compose window) and 
+               compose_defer_auto_save_draft() (which expects compose 
+               window to exist). Should fix Keith's and Fred Marton's
+               bug report (#128, "crash after complaining about character
+               set conversion")
+
+2004-02-27 [luke]      0.9.9claws34
+       
+       * src/folder.c
+               Do folder_item_apply_processing() even if no processing
+               rules for the folder exist (so global processing is applied)
+
+2004-02-26 [thorsten]  0.9.9claws33
+
+       * src/mimeview.c
+               Remove misleading static declaration
+
+2004-02-26 [alfons]    0.9.9claws32
+
+       * src/procmime.[ch]
+         src/compose.c
+         src/mimeview.c
+         src/textview.c
+               use/add procmime_get_content_type_str() as a safe wrapper
+               for returning a Content-Type type string; should fix 
+               bug #444, 0.9.7..0.9.9 crashes with "Content-Type: type= 
+                - attachments."
+
+2004-02-26 [thorsten]  0.9.9claws31
+
+       * src/mimeview.c
+               Restructure save_as/save_all
+
+2004-02-26 [alfons]    0.9.9claws30
+
+       * src/procmime.c
+               clean up (2)
+
+2004-02-26 [alfons]    0.9.9claws29
+
+       * src/procmime.c
+               clean up (1)
+
+2004-02-24 [luke]
+
+       * tools/textviewer.sh
+               tweaks from Johann Koenig, recognition of shell
+               scripts in particular
+
+2004-02-24 [paul]      0.9.9claws28
+
+       * sync with 0.9.9cvs13
+               see ChangeLog 2004-02-24
+
+2004-02-23 [paul]      0.9.9claws27
+
+       * src/inc.c
+               one alertpanel on pop3 authentication error will suffice
+               
+       * src/prefs_fonts.c
+               remove unnecessary printf
+
+2004-02-22 [alfons]    0.9.9claws26
+
+       * src/messageview.c
+               put back a lost check
+
+2004-02-21 [alfons]    0.9.9claws25
+
+       * src/folderview.c
+               don't forget to save folder properties after renaming folder
+
+2004-02-20 [paul]      0.9.9.claws24
+
+       * src/addressbook.c
+               sync with 0.9.9cvs11, see ChangeLog 2004-02-19
+               
+       * src/inc.c
+               complete sync with 0.9.9cvs9's 'update folderview
+               progressively'
+               
+       * configure.ac
+               require gettext >= 0.12.1
+
+2004-02-17 [match]     0.9.9claws23
+
+       * src/compose.c
+               keep the peace - change style.
+
+2004-02-17 [alfons]    0.9.9claws22
+
+       * src/filtering.c
+               make MATCHACTION_STOP cancel filtering / processing;
+               clean up and document it to make it a little bit more clear;
+
+2004-02-17 [alfons]    0.9.9claws21
+
+       %X marks the cursor spot for reply quote format
+
+       * src/quote_fmt_lex.l 
+         src/quote_fmt.c
+               add %X token
+               
+       * src/quote_fmt.h
+         src/quote_fmt_parse.y
+               handle %X token
+               
+       * src/compose.c
+               handle %X token for replies only (for now)
+
+2004-02-17 [paul]      0.9.9claws20
+
+       * po/sk.po
+               updated by Andrej Kacian
+               
+       * src/news.c
+               remove unneeded include
+               
+       * src/prefs_fonts.c
+               be a little more user-friendly with the labels
+               
+       * configure.ac
+               a change forgotten in the last commit: 
+               SYLPHEED_ACLOCAL_INCLUDE(m4)
+
+2004-02-17 [paul]      0.9.9claws19
+
+       * ac/*                          ** REMOVED **
+         ac/                           ** REMOVED **
+         intl/Makefile.in              ** REMOVED **
+         m4/                           ** NEW **
+         m4/missing                    ** NEW **
+         m4/missing/gdk-pixbuf.m4      ** NEW **
+         m4/missing/gettext.m4         ** NEW **
+         m4/missing/gpgme.m4           ** NEW **
+         m4/missing/imlib.m4           ** NEW **
+         m4/.cvsignore                 ** NEW **
+         m4/Makefile.am                ** NEW **
+         m4/README                     ** NEW **
+         m4/aclocal-include.m4         ** NEW **
+         m4/aspell.m4                  ** NEW **
+         m4/check-type.m4              ** NEW **
+         m4/gnupg-check-typedef.m4     ** NEW **
+         m4/openssl.m4                 ** NEW **
+         m4/spamassassin.m4            ** NEW **
+         po/ChangeLog                  ** REMOVED **
+         po/Makefile.in.in             ** REMOVED **
+         po/Rules-quot                 ** REMOVED **
+         po/boldquot.sed               ** REMOVED **
+         po/en@boldquot.header         ** REMOVED **
+         po/en@quot.header             ** REMOVED **
+         po/insert-header.sin          ** REMOVED **
+         po/quot.sed                   ** REMOVED **
+         po/remove-potcdate.sed        ** REMOVED **
+         po/remove-potcdate.sin        ** REMOVED **
+         po/stamp-po                   ** REMOVED **
+         Makefile.am
+         autogen.sh
+         configure.ac
+               enable building with automake 1.8.x
+               add 'autopoint' to autogen.sh and remove all
+               auto-generated files, remove ac/ in favour of
+               m4/
+
+2004-02-17 [alfons]    0.9.9claws18
+       
+       * src/summaryview.c
+               MSG_IS_NEWS() is not stored at all, and is bogus
+
+2004-02-17 [martin]    0.9.9claws17
+
+       * src/prefs_themes.c
+               fix crash when installing wrong theme and output an
+               error message
+
+2004-02-16 [christoph] 0.9.9claws16
+
+       * src/compose.c
+       * src/stock_pixmap.[ch]
+       * src/toolbar.[ch]
+       * src/pixmaps/linewrapcurrent.xpm               ** NEW **
+               add "Wrap current paragraph" to compose toolbar
+
+2004-02-15 [alfons]    0.9.9claws15
+
+       * src/folderview.c
+               refine previous commit to make sure other hook functions
+               get their grab of the pie too
+
+2004-02-15 [alfons]    0.9.9claws14
+
+       * src/folderview.c
+               fix sync breakage so we don't pass invalid pointer types
+
+2004-02-15 [match]     0.9.9claws13
+
+       * src/ldapquery.[ch]
+       * src/ldapserver.h
+       * src/addrindex.[ch]
+               tweak threading calls.
+       * src/addr_compl.[ch]
+               add alias into completion list.
+       * src/addressbook.c
+               fix ldap browse.
+               improve context menu behavior.
+               change menu sequence.
+               add send mail from addressbook.
+       * src/addrselect.[ch]
+       * src/compose.[ch]
+               add send mail from addressbook.
+
+2004-02-15 [christoph] 0.9.9claws12
+
+       * src/folderutils.c
+               skip deleting when duplist is empty
+
+       * src/folderview.[ch]
+       * src/mainwindow.c
+       * src/summaryview.[ch]
+               call folderutils_delete_duplicates() from mainwindow code
+
+2004-02-15 [alfons]    0.9.9claws11
+       
+       * src/common/utils.c
+               add prefix for italian ms o(e) 
+
+2004-02-14 [paul]      0.9.9claws10
+
+       * src/foldersel.c
+               fix updating of the folder view when creating a
+               new folder
+
+2004-02-13 [paul]      0.9.9claws9
+
+       * src/plugins/clamav/clamav_plugin.c
+               remove GUI code
+
+2004-02-13 [paul]      0.9.9claws8
+
+       * sync with 0.9.9cvs9
+               see ChangeLog 2004-02-09, 2004-02-10, 2004-02-12
+
+2004-02-13 [alfons]    0.9.9claws7
+
+       * src/common/utils.c
+               fix wrong type of argument for ctype functions (pass unsigned
+               char instead of signed char)
+
+2004-02-12 [alfons]    0.9.9claws6
+
+       * src/compose.[ch]
+               don't select text in header entry when composing to a 
+               default address, but rather give the header entry a
+               different color / style (same as the folder new color)
+
+2004-02-12 [alfons]    0.9.9claws5
+
+       * src/plugins/clamav/clamav_plugin.c
+               don't exit(2) on libclamav init error - show a warning.
+               (tested by damaging a clamav database file.)
+
+2004-02-12 [paul]      0.9.9claws4
+
+       * sync with 0.9.9cvs4
+               see ChangeLog 2004-02-04, 2004-02-05, and 2004-02-06
+
+2004-02-11 [luke]      0.9.9claws3
+
+       * src/mimeview.c
+               remove redundant check introduced in 0.9.9claws1
+
+2004-02-11 [luke]      0.9.9claws2
+
+       * src/mimeview.c
+               fix compilation of my previous commit without gpg enabled
+
+2004-02-10 [luke]      0.9.9claws1
+
+       * src/mimeview.c
+               add borders to icons to indicate the privacy status for
+               the message part (unknown/bad/good)
+
 2004-02-06 [paul]      0.9.9claws
 
        0.9.9claws released
 
 2004-01-25 [paul]      0.9.8claws48
 
-       src/prefs_ext_prog.c
+       src/prefs_ext_prog.c
                apply Alfons' patch to check for NULL pointers
                fixes bug #424
 
index 4d44e7b..9f5b4e0 100644 (file)
@@ -1,3 +1,162 @@
+2004-03-19
+
+       * src/defs.h
+         src/inc.[ch]: ¿ÊĽ¥À¥¤¥¢¥í¥°¤Î¹¹¿·ÊýË¡¤òÊѹ¹¤·¡¢¹â®¤Ê¥Í¥Ã¥È¥ï¡¼¥¯
+         ¤Ë¤ª¤±¤ë¥ª¡¼¥Ð¡¼¥Ø¥Ã¥É¤ò·Ú¸º¡£
+
+2004-03-16
+
+       * src/nntp.c: nntp_session_new(): ¥»¥Ã¥·¥ç¥ó¤Î³«»Ï»þ¤Ëǧ¾Ú¤ò»î¤ß¤ë
+         ¤è¤¦¤Ë¤·¤¿(Shiino Yuki ¤µ¤ó¡¢ IWAMOTO, Kouichi ¤µ¤ó thanks)¡£
+       * src/news.c
+         src/nntp.c: ¥½¥±¥Ã¥È¥¨¥é¡¼¤¬È¯À¸¤·¤¿¤È¤­¤Ï¥»¥Ã¥·¥ç¥ó¤òÇË´þ¤¹¤ë
+         ¤è¤¦¤Ë¤·¤¿¡£
+
+2004-03-12
+
+       * src/mainwindow.c
+         src/summaryview.[ch]: ÁªÂòÃæ¤Î¥á¥Ã¥»¡¼¥¸¤ò¿¶¤êʬ¤±¤ëµ¡Ç½¤òÄɲá£
+
+2004-03-12
+
+       * src/filter.[ch]
+         src/prefs_filter.c: ¥Õ¥£¥ë¥¿¥·¥¹¥Æ¥à¤òºÆ¼ÂÁõ(UI ¤Ï̤¼ÂÁõ)¡£
+
+2004-03-09
+
+       * src/filter.c: ¡Ö´Þ¤Þ¤Ê¤¤¡×¥Õ¥é¥°¤Î¥Þ¥Ã¥Á¥ó¥°¥¢¥ë¥´¥ê¥º¥à¤ò½¤Àµ
+         (¥Ø¥Ã¥À¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç¤Ç¤â¥Þ¥Ã¥Á¤·¡¢Ê£¿ô¤ÎƱ°ì¥Ø¥Ã¥À¤òÀµ¤·¤¯°·¤¦
+         ¤è¤¦¤Ë¤·¤¿)¡£
+       * src/imageview.c: get_resized_size(): ¥ê¥µ¥¤¥º¤ÎÌäÂê¤òµ¯¤³¤·¤Æ¤¤¤¿
+         typo ¤ò½¤Àµ¡£
+
+2004-03-02
+
+       * src/folder.c
+         src/mh.c: MH ¥Õ¥©¥ë¥À¤ÎºÇ¸å¤ÎÈÖ¹æ¤Î¥á¥Ã¥»¡¼¥¸¤òºï½ü¤·¤¿¤È¤­
+         FolderItem::last_num ¤Î¤ß¤ò¹¹¿·¤·¡¢¤½¤Î¾¤Î¾ì¹ç¤Ï¥¹¥­¥ã¥ó¤·¤Ê¤¤
+         ¤è¤¦¤Ë¤·¤¿(°ÜÆ°»þ¤Ë¥á¥Ã¥»¡¼¥¸¿ô¤Î·×»»¤ò¸í¤ë¥Ð¥°¤ò½¤Àµ)¡£
+
+2004-03-02
+
+       * src/folderview.c
+         src/summaryview.c: DnD »ÈÍÑ»þ¤Ï¾ï¤Ë¥Ç¥Õ¥©¥ë¥È¤Ç¥á¥Ã¥»¡¼¥¸¤ò°ÜÆ°¤¹¤ë
+         ¤è¤¦¤Ë¤·¤¿(¥Ë¥å¡¼¥¹¥Õ¥©¥ë¥À¤ò½ü¤¯)¡£ Ctrl ¥­¡¼¤¬²¡¤µ¤ì¤¿¾ì¹ç¤Ï
+         ¥á¥Ã¥»¡¼¥¸¤ò¥³¥Ô¡¼¤¹¤ë¤è¤¦¤Ë¤·¤¿¡£
+       * src/mainwindow.c: main_window_empty_trash()
+         src/summaryview.c: summary_execute(): ÉÔ­¤·¤Æ¤¤¤¿
+         statusbar_pop_all() ¤òÄɲá£
+
+2004-02-29
+
+       * version 0.9.10
+
+2004-02-26
+
+       * src/prefs_common.c: "inc_local" ¤Î¥Ç¥Õ¥©¥ë¥È¤ò FALSE ¤Ë¤·¤¿¡£
+
+2004-02-26
+
+       * src/account.c
+         src/folderview.c: IMAP4 ¥¢¥«¥¦¥ó¥È¤ò¥Á¥§¥Ã¥¯¤¹¤ë¤È¤­¤Ï¥ª¥ó¥é¥¤¥ó
+         ¥â¡¼¥É¤ËÀÚ¤êÂؤ¨¤ë¤è¤¦¤Ë¤·¤¿¡£¤½¤Î¸å¥¹¥Æ¡¼¥¿¥¹¥Ð¡¼¤ò pop ¤¹¤ë¤è¤¦¤Ë
+         ¤·¤¿¡£
+       * src/inc.c: ¥³¡¼¥É¤ÎÀ°Íý¡£
+       * src/mainwindow.[ch]: main_window_get() ¤È
+         main_window_toggle_online_if_offline() ¤òÄɲá£
+       * src/prefs_common.c: prefs_common_read_config(): ½é²óµ¯Æ°»þ¤Ë
+         ¥ª¥Õ¥é¥¤¥ó¥â¡¼¥É¤Ë¤·¤Æ¤·¤Þ¤Ã¤Æ¤¤¤¿¥Ð¥°¤ò½¤Àµ¡£
+
+2004-02-25
+
+       * src/imageview.c: ¥¦¥£¥ó¥É¥¦¤Î¥ê¥µ¥¤¥º»þ¤Ë¼«Æ°¥ê¥µ¥¤¥º¤¹¤ë¤è¤¦¤Ë¤·¤¿¡£
+         ¥¯¥é¥Ã¥·¥å¤òËɤ°¤¿¤á¤ËºÇ¾®¥µ¥¤¥º¤ò16¥Ô¥¯¥»¥ë¤ËÀ©¸Â¡£
+         imageview_init(): imlib »ÈÍÑ»þ¤Ï²èÁü¤ò¥­¥ã¥Ã¥·¥å¤·¤Ê¤¤¤è¤¦¤Ë¤·¤¿¡£
+         imageview_show_image(): ¥á¥â¥ê¥ê¡¼¥¯¤ò½¤Àµ¡£
+       * src/mimeview.c: mimeview_init(): imageview_init() ¤ò¸Æ¤Ö¤è¤¦¤Ë¤·¤¿¡£
+
+2004-02-24
+
+       * src/codeconv.[ch]: ISO-2022-JP-3 ¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤òÄɲá£
+
+2004-02-24
+
+       * src/codeconv.c
+         src/mainwindow.c
+         src/messageview.c: KOI8-U ¥¨¥ó¥³¡¼¥Ç¥£¥ó¥°¤òÄɲá£
+       * src/prefs_common.c: prefs_message_create(): ²èÁü¥ê¥µ¥¤¥º¥ª¥×¥·¥ç¥ó
+         ¤Îʸ»úÎó¤ò½¤Àµ¡£
+
+2004-02-19
+
+       * src/addressbook.c: addressbook_list_selected(): °ú¿ô¤ò½¤Àµ¡£
+       * src/imageview.[ch]: ¸µ¤Î²èÁü¥Ç¡¼¥¿¤ò ImageView ¤ËÊÝ»ý¤·¡¢
+         ¥ê¥µ¥¤¥º¤ÎÀÚ¤êÂؤ¨¤¬¤Ç¤­¤ë¤è¤¦¤Ë¤·¤¿¡£
+       * src/messageview.[ch]
+         src/mimeview.[ch]: MessageView ¤Ç¤Ê¤¯ MimeView ¤Ç ImageView ¤ò
+         °·¤¦¤è¤¦¤Ë¤·¤¿¡£
+
+2004-02-16
+
+       * src/imap.c
+         src/news.c
+         src/summaryview.c: imap.c ¤È news.c ¤«¤é statusbar_pop_all() ¤ò
+         ½üµî(summaryview.c Æâ¤Ç¼Â¹Ô)¡£
+
+2004-02-12
+
+       * src/inc.[ch]
+         src/pop.[ch]: inc_drop_message() ¤ò Pop3Session ¤Î²¾ÁÛ´Ø¿ô¤Ë¤·¡¢
+         pop3.c ¤Î inc.h ¤Ø¤Î°Í¸¤ò½üµî¡£
+
+2004-02-12
+
+       * src/mainwindow.c
+         src/messageview.[ch]
+         src/textview.c: ¿·µ¬¥¦¥£¥ó¥É¥¦¤Î¥á¥Ã¥»¡¼¥¸¥Ó¥å¡¼¤Ë¥¹¥Æ¡¼¥¿¥¹¥Ð¡¼¤ò
+         Äɲá£
+
+2004-02-10
+
+       * src/inc.[ch]: Ã༡¹¹¿·¤Ë¥Ï¥Ã¥·¥å¥Æ¡¼¥Ö¥ë¤ò»ÈÍÑ¡£
+         ¹¹¿·´Ö³Ö¤ò2ÉäËÊѹ¹¡£
+       * src/folder.[ch]
+         src/mh.c
+         src/procmsg.c
+         src/summaryview.c: ¥Õ¥©¥ë¥À¤Î¥á¥Ã¥»¡¼¥¸¿ô¤Î½¸·×¤òÊäÀµ¤¹¤ë¤¿¤á¤Ë
+         FolderItem::unmarked_num ¤òÄɲá£
+
+2004-02-09
+
+       * src/inc.[ch]: ¥Õ¥©¥ë¥À¥Ó¥å¡¼¤òÃ༡¹¹¿·¤¹¤ë¤è¤¦¤Ë¤·¤¿¡£
+       * src/foldersel.c: ÁªÂò¹àÌܤδ°Á´¤Ê ID ¤òɽ¼¨¡£
+
+2004-02-06
+
+       * src/folderview.[ch]: ¥³¡¼¥É¤ÎÀ°Íý¡£
+         folderview_append_item(): ¿·µ¬¡£¥Õ¥©¥ë¥À¤ò¥Õ¥©¥ë¥À¥Ó¥å¡¼¤ËÄɲ乤롣
+       * src/foldersel.c: foldersel_new_folder(): folderview_append_item()
+         ¤ò»ÈÍÑ¡£
+
+2004-02-06
+
+       * src/foldersel.c: ¡Ö¿·µ¬¥Õ¥©¥ë¥À¤òºîÀ®¡×µ¡Ç½¤ò¼ÂÁõ¡£
+       * src/folder.[ch]: folder_find_child_item_by_name(): ¿·µ¬¡£
+       * src/utils.h: AUTORELEASE_STR(): malloc Ê¸»úÎó¤ò¼«Æ°³«Êü(alloca)
+         Ê¸»úÎó¤ËÊÑ´¹¡£
+
+2004-02-05
+
+       * src/folderview.c: folderview_new_imap_folder_cb() ¤ò
+         folderview_new_folder_cb() ¤Ë¤Þ¤È¤á¤¿¡£
+
+2004-02-04
+
+       * src/compose.c: compose_write_to_file(): ÌµÂ̤ʠstrlen() ¤ò½üµî
+         (Alfons ¤µ¤ó thanks)¡£
+       * src/textview.c: textview_button_pressed(): ¥¢¥É¥ì¥¹¤ò¥¯¥ê¥Ã¥¯¤·¤¿
+         ¤È¤­Àµ¤·¤¤¥¢¥«¥¦¥ó¥È¤òÁªÂò¤¹¤ë¤è¤¦¤Ë¤·¤¿¡£
+
 2004-01-29
 
        * version 0.9.9
index 04c1de5..7dd859d 100644 (file)
@@ -8,10 +8,10 @@ PACKAGE=sylpheed
 dnl version number
 MAJOR_VERSION=0
 MINOR_VERSION=9
-MICRO_VERSION=9
+MICRO_VERSION=10
 INTERFACE_AGE=0
 BINARY_AGE=0
-EXTRA_VERSION=1
+EXTRA_VERSION=57
 if test $EXTRA_VERSION -eq 0; then
     VERSION=${MAJOR_VERSION}.${MINOR_VERSION}.${MICRO_VERSION}claws
 else
index 3b6496f..70845e0 100644 (file)
@@ -1,2 +1 @@
-Makefile
-po2tbl.sed
+Makefile.in
index ca5ebc2..32b7c04 100644 (file)
@@ -1,6 +1,16 @@
-POTFILES
-Makefile.in
 Makefile
+Makefile.in
+Makefile.in.in
+Makevars.template
+POTFILES
+Rules-quot
+boldquot.sed
+en@boldquot.header
+en@quot.header
+insert-header.sin
+quot.sed
+remove-potcdate.sed
+remove-potcdate.sin
 sylpheed.pot
-cat-id-tbl.c
+*.po~
 *.gmo
index 6afa358..919d5ec 100644 (file)
@@ -38,6 +38,7 @@ src/gtk/colorlabel.c
 src/gtk/description_window.c
 src/gtk/gtkaspell.c
 src/gtk/gtkutils.c
+src/gtk/inputdialog.c
 src/gtk/logwindow.c
 src/gtk/pluginwindow.c
 src/gtk/prefswindow.c
@@ -50,7 +51,6 @@ src/importldif.c
 src/importmutt.c
 src/importpine.c
 src/inc.c
-src/inputdialog.c
 src/ldif.c
 src/main.c
 src/mainwindow.c
index 10f9b91..f6ac028 100644 (file)
@@ -61,12 +61,12 @@ sylpheed_SOURCES = \
        headerview.c \
        html.c \
        imap.c \
+       imap_gtk.c \
        import.c \
        importldif.c \
        importmutt.c \
        importpine.c \
        inc.c \
-       inputdialog.c \
        jpilot.c \
        ldapctrl.c \
        ldaplocate.c \
@@ -85,10 +85,12 @@ sylpheed_SOURCES = \
        message_search.c \
        messageview.c \
        mh.c \
+       mh_gtk.c \
        mimeview.c \
        msgcache.c \
        mutt.c \
        news.c \
+       news_gtk.c \
        noticeview.c \
        passphrase.c \
        pgpmime.c \
@@ -187,12 +189,12 @@ sylpheedinclude_HEADERS = \
        headerview.h \
        html.h \
        imap.h \
+       imap_gtk.h \
        import.h \
        importldif.h \
        importmutt.h \
        importpine.h \
        inc.h \
-       inputdialog.h \
        jpilot.h \
        ldapctrl.h \
        ldaplocate.h \
@@ -212,10 +214,12 @@ sylpheedinclude_HEADERS = \
        message_search.h \
        messageview.h \
        mh.h \
+       mh_gtk.h \
        mimeview.h \
        msgcache.h \
        mutt.h \
        news.h \
+       news_gtk.h \
        noticeview.h \
        passphrase.h \
        pgpmime.h \
@@ -304,6 +308,7 @@ EXTRA_DIST = \
        pixmaps/key.xpm \
        pixmaps/ldap.xpm \
        pixmaps/linewrap.xpm \
+       pixmaps/linewrapcurrent.xpm \
        pixmaps/locked.xpm \
        pixmaps/mail_attach.xpm \
        pixmaps/mail_compose.xpm \
index ff14740..4a41bfa 100644 (file)
@@ -179,7 +179,8 @@ static void add_address1(const char *str, address_entry *ae)
  * \return <code>0</code> if entry appended successfully, or <code>-1</code>
  *         if failure.
  */
-static gint add_address(const gchar *name, const gchar *address, const gchar *alias)
+static gint add_address(const gchar *name, const gchar *address, 
+                       const gchar *nick, const gchar *alias)
 {
        address_entry    *ae;
 
@@ -196,7 +197,13 @@ static gint add_address(const gchar *name, const gchar *address, const gchar *al
 
        add_address1(name, ae);
        add_address1(address, ae);
-       add_address1(alias, ae);
+       
+       if (nick != NULL)
+               add_address1(nick, ae);
+       
+       if ( alias != NULL ) {
+               add_address1(alias, ae);
+       }
 
        return 0;
 }
@@ -1073,8 +1080,21 @@ static gboolean address_completion_complete_address_in_entry(GtkEntry *entry,
                g_free( new );
        }
 
+       /* Select the address if there is only one match */
+       if (ncount == 2) {
+               /* Display selected address in entry field */           
+               gchar *addr = get_complete_address(1);
+
+               if (addr) {
+                       replace_address_in_edit(entry, addr, cursor_pos);
+                       g_free(addr);
+               }
+
+               /* Discard the window */
+               clear_completion_cache();
+       }
        /* Make sure that drop-down appears uniform! */
-       if( ncount == 0 ) {
+       else if( ncount == 0 ) {
                addrcompl_add_queue( g_strdup( searchTerm ) );
        }
        g_free( searchTerm );
index 2c64052..619024c 100644 (file)
@@ -176,6 +176,10 @@ static void addressbook_tree_selected              (GtkCTree       *ctree,
                                                 GtkCTreeNode   *node,
                                                 gint            column,
                                                 gpointer        data);
+static void addressbook_select_row_tree                (GtkCTree       *ctree,
+                                                GtkCTreeNode   *node,
+                                                gint            column,
+                                                gpointer        data);
 static void addressbook_list_selected          (GtkCList       *clist,
                                                 gint            row,
                                                 gint            column,
@@ -354,9 +358,9 @@ static void addressbook_treenode_cut_cb             ( void );
 static void addressbook_treenode_copy_cb       ( void );
 static void addressbook_treenode_paste_cb      ( void );
 
-#ifdef USE_LDAP
+static void addressbook_mail_to_cb             ( void );
+
 static void addressbook_browse_entry_cb                ( void );
-#endif
 
 static GtkItemFactoryEntry addressbook_entries[] =
 {
@@ -388,6 +392,8 @@ static GtkItemFactoryEntry addressbook_entries[] =
        {N_("/_Address/---"),           NULL,           NULL, 0, "<Separator>"},
        {N_("/_Address/_Edit"),         "<alt>Return",  addressbook_edit_address_cb,    0, NULL},
        {N_("/_Address/_Delete"),       NULL,           addressbook_delete_address_cb,  0, NULL},
+       {N_("/_Address/---"),           NULL,           NULL, 0, "<Separator>"},
+       {N_("/_Address/_Mail To"),      NULL,           addressbook_mail_to_cb,         0, NULL},
        {N_("/_Tools/---"),             NULL,           NULL, 0, "<Separator>"},
        {N_("/_Tools/Import _LDIF file..."), NULL,      addressbook_import_ldif_cb,     0, NULL},
        {N_("/_Tools/Import M_utt file..."), NULL,      addressbook_import_mutt_cb,     0, NULL},
@@ -401,13 +407,13 @@ static GtkItemFactoryEntry addressbook_entries[] =
 
 static GtkItemFactoryEntry addressbook_tree_popup_entries[] =
 {
-       {N_("/New _Address"),   NULL, addressbook_new_address_cb, 0, NULL},
-       {N_("/New _Group"),     NULL, addressbook_new_group_cb,   0, NULL},
-       {N_("/New _Folder"),    NULL, addressbook_new_folder_cb,  0, NULL},
-       {N_("/---"),            NULL, NULL, 0, "<Separator>"},
        {N_("/_Edit"),          NULL, addressbook_treenode_edit_cb,   0, NULL},
        {N_("/_Delete"),        NULL, addressbook_treenode_delete_cb, 0, NULL},
        {N_("/---"),            NULL, NULL, 0, "<Separator>"},
+       {N_("/New _Address"),   NULL, addressbook_new_address_cb,     0, NULL},
+       {N_("/New _Group"),     NULL, addressbook_new_group_cb,       0, NULL},
+       {N_("/New _Folder"),    NULL, addressbook_new_folder_cb,      0, NULL},
+       {N_("/---"),            NULL, NULL, 0, "<Separator>"},
        {N_("/C_ut"),           NULL, addressbook_treenode_cut_cb,    0, NULL},
        {N_("/_Copy"),          NULL, addressbook_treenode_copy_cb,   0, NULL},
        {N_("/_Paste"),         NULL, addressbook_treenode_paste_cb,  0, NULL}
@@ -415,22 +421,22 @@ static GtkItemFactoryEntry addressbook_tree_popup_entries[] =
 
 static GtkItemFactoryEntry addressbook_list_popup_entries[] =
 {
+       {N_("/_Edit"),          NULL, addressbook_edit_address_cb,   0, NULL},
+       {N_("/_Delete"),        NULL, addressbook_delete_address_cb, 0, NULL},
+       {N_("/---"),            NULL, NULL, 0, "<Separator>"},
        {N_("/New _Address"),   NULL, addressbook_new_address_cb,    0, NULL},
        {N_("/New _Group"),     NULL, addressbook_new_group_cb,      0, NULL},
        {N_("/New _Folder"),    NULL, addressbook_new_folder_cb,     0, NULL},
        {N_("/---"),            NULL, NULL, 0, "<Separator>"},
-       {N_("/_Edit"),          NULL, addressbook_edit_address_cb,   0, NULL},
-       {N_("/_Delete"),        NULL, addressbook_delete_address_cb, 0, NULL},
-       {N_("/---"),            NULL, NULL, 0, "<Separator>"},
        {N_("/C_ut"),           NULL, addressbook_clip_cut_cb,       0, NULL},
        {N_("/_Copy"),          NULL, addressbook_clip_copy_cb,      0, NULL},
        {N_("/_Paste"),         NULL, addressbook_clip_paste_cb,     0, NULL},
        {N_("/---"),            NULL, NULL, 0, "<Separator>"},
-#ifdef USE_LDAP
        {N_("/Pa_ste Address"), NULL, addressbook_clip_paste_address_cb, 0, NULL},
+       {N_("/_Mail To"),       NULL, addressbook_mail_to_cb,            0, NULL}
+#ifdef USE_LDAP
+       ,
        {N_("/_Browse Entry"),  NULL, addressbook_browse_entry_cb,       0, NULL}
-#else
-       {N_("/Pa_ste Address"), NULL, addressbook_clip_paste_address_cb, 0, NULL}
 #endif 
 };
 
@@ -478,6 +484,7 @@ static ErrMsgTableEntry _lutErrorsLDAP_[] = {
        { LDAPRC_CRITERIA,      N_("Error in LDAP search criteria") },
        { LDAPRC_NOENTRIES,     N_("No LDAP entries found for search criteria") },
        { LDAPRC_STOP_FLAG,     N_("LDAP search terminated on request") },
+       { LDAPRC_TLS,           N_("Error starting TLS connection") },
        { 0,                    NULL }
 };
 #endif
@@ -689,6 +696,9 @@ static void addressbook_create(void)
        g_signal_connect(G_OBJECT(ctree), "button_release_event",
                         G_CALLBACK(addressbook_tree_button_released),
                         NULL);
+       /* TEMPORARY */
+       g_signal_connect(G_OBJECT(ctree), "select_row",
+                        G_CALLBACK(addressbook_select_row_tree), NULL);
 
        clist_vbox = gtk_vbox_new(FALSE, 4);
 
@@ -1166,8 +1176,7 @@ static void addressbook_to_clicked(GtkButton *button, gpointer data)
        Compose *compose;
        AddrSelectItem *item;
        AddrItemObject *aio;
-       const gchar *addr;
-       gchar *tmpaddr;
+       gchar *addr;
 
        compose = addrbook.target_compose;
        if( ! compose ) return;
@@ -1188,10 +1197,10 @@ static void addressbook_to_clicked(GtkButton *button, gpointer data)
                aio = item->addressItem;
                if( aio->type == ADDR_ITEM_PERSON ||
                    aio->type == ADDR_ITEM_EMAIL ) {
-                       tmpaddr = addressbook_format_address( aio );
+                       addr = addressbook_format_address( aio );
                        compose_entry_append(
-                               compose, tmpaddr, (ComposeEntryType) data );
-                       g_free( tmpaddr );
+                               compose, addr, (ComposeEntryType) data );
+                       g_free( addr );
                }
                else if( aio->type == ADDR_ITEM_GROUP ) {
                        ItemGroup *group = ( ItemGroup * ) aio;
@@ -1199,11 +1208,11 @@ static void addressbook_to_clicked(GtkButton *button, gpointer data)
                        while( nodeMail ) {
                                ItemEMail *email = nodeMail->data;
 
-                               tmpaddr = addressbook_format_address(
+                               addr = addressbook_format_address(
                                                ( AddrItemObject * ) email );
                                compose_entry_append(
-                                       compose, tmpaddr, (ComposeEntryType) data );
-                               g_free( tmpaddr );
+                                       compose, addr, (ComposeEntryType) data );
+                               g_free( addr );
                                nodeMail = g_list_next( nodeMail );
                        }
                }
@@ -1223,6 +1232,7 @@ static void addressbook_menubar_set_sensitive( gboolean sensitive ) {
        menu_set_sensitive( addrbook.menu_factory, "/Address/New Address", sensitive );
        menu_set_sensitive( addrbook.menu_factory, "/Address/New Group",   sensitive );
        menu_set_sensitive( addrbook.menu_factory, "/Address/New Folder",  sensitive );
+       menu_set_sensitive( addrbook.menu_factory, "/Address/Mail To",     sensitive );
        gtk_widget_set_sensitive( addrbook.reg_btn, sensitive );
        gtk_widget_set_sensitive( addrbook.del_btn, sensitive );
 }
@@ -1454,8 +1464,11 @@ static void addressbook_list_menu_setup( void ) {
 
        canDelete = canEdit;
 
-       /* Disable edit if more than one row selected */
-       if( GTK_CLIST(clist)->selection && GTK_CLIST(clist)->selection->next ) canEdit = FALSE;
+       /* Disable edit or browse if more than one row selected */
+       if( GTK_CLIST(clist)->selection && GTK_CLIST(clist)->selection->next ) {
+               canEdit = FALSE;
+               canBrowse = FALSE;
+       }
 
        /* Now go finalize menu items */
        menu_set_sensitive( addrbook.list_factory, "/Edit",   canEdit );
@@ -1466,22 +1479,25 @@ static void addressbook_list_menu_setup( void ) {
        menu_set_sensitive( addrbook.list_factory, "/Paste",         canPaste );
        menu_set_sensitive( addrbook.list_factory, "/Paste Address", canPaste );
 
+       menu_set_sensitive( addrbook.list_factory, "/Mail To",       canCopy );
+
        menu_set_sensitive( addrbook.menu_factory, "/Edit/Cut",           canCut );
        menu_set_sensitive( addrbook.menu_factory, "/Edit/Copy",          canCopy );
        menu_set_sensitive( addrbook.menu_factory, "/Edit/Paste",         canPaste );
        menu_set_sensitive( addrbook.menu_factory, "/Edit/Paste Address", canPaste );
 
-       menu_set_sensitive( addrbook.tree_factory, "/Cut",           canCut );
-       menu_set_sensitive( addrbook.tree_factory, "/Copy",          canCopy );
-       menu_set_sensitive( addrbook.tree_factory, "/Paste",         canPaste );
+       menu_set_sensitive( addrbook.tree_factory, "/Cut",             canCut );
+       menu_set_sensitive( addrbook.tree_factory, "/Copy",            canCopy );
+       menu_set_sensitive( addrbook.tree_factory, "/Paste",           canPaste );
 
-       menu_set_sensitive( addrbook.menu_factory, "/Address/Edit",   canEdit );
-       menu_set_sensitive( addrbook.menu_factory, "/Address/Delete", canDelete );
+       menu_set_sensitive( addrbook.menu_factory, "/Address/Edit",    canEdit );
+       menu_set_sensitive( addrbook.menu_factory, "/Address/Delete",  canDelete );
+       menu_set_sensitive( addrbook.menu_factory, "/Address/Mail To", canCopy );
 
        gtk_widget_set_sensitive( addrbook.del_btn, canDelete );
 
 #ifdef USE_LDAP
-       menu_set_sensitive( addrbook.list_factory, "/Browse Entry", canBrowse );
+       menu_set_sensitive( addrbook.list_factory, "/Browse Entry",    canBrowse );
 #endif
 }
 
@@ -1492,12 +1508,19 @@ static void addressbook_list_selected(GtkCList *clist, gint row, gint column,
                /* Handle double click */
                if (prefs_common.add_address_by_click &&
                    addrbook.target_compose)
-                       addressbook_to_clicked(NULL, NULL);
+                       addressbook_to_clicked(NULL, GINT_TO_POINTER(COMPOSE_TO));
                else
                        addressbook_edit_address_cb(NULL, 0, NULL);
        }
 }
 
+static void addressbook_select_row_tree        (GtkCTree       *ctree,
+                                        GtkCTreeNode   *node,
+                                        gint            column,
+                                        gpointer        data)
+{
+}
+
 /**
  * Add list of items into tree node below specified tree node.
  * \param treeNode  Tree node.
@@ -1772,6 +1795,11 @@ static void addressbook_list_select_clear( void ) {
        addrselect_list_clear( _addressSelect_ );
 }
 
+/**
+ * Add specified address item to selected address list.
+ * \param aio Address item object.
+ * \param ds  Datasource.
+ */
 static void addressbook_list_select_add( AddrItemObject *aio, AddressDataSource *ds ) {
        gchar *cacheID;
 
@@ -1781,10 +1809,28 @@ static void addressbook_list_select_add( AddrItemObject *aio, AddressDataSource
        g_free( cacheID );
 }
 
+/**
+ * Remove specified address item from selected address list.
+ * \param aio Address item object.
+ */
 static void addressbook_list_select_remove( AddrItemObject *aio ) {
        addrselect_list_remove( _addressSelect_, aio );
 }
 
+/**
+ * Invoke EMail compose window with addresses in selected address list.
+ */
+static void addressbook_mail_to_cb( void ) {
+       GList *listAddress;
+
+       if( ! addrselect_test_empty( _addressSelect_ ) ) {
+               listAddress = addrselect_build_list( _addressSelect_ );
+               compose_new_with_list( NULL, listAddress );
+               mgu_free_dlist( listAddress );
+               listAddress = NULL;
+       }
+}
+
 static void addressbook_list_row_selected( GtkCTree *clist,
                                           GtkCTreeNode *node,
                                           gint column,
@@ -2322,7 +2368,14 @@ static void addressbook_treenode_delete_cb(
                AdapterFolder *adapter = ADAPTER_FOLDER(obj);
                ItemFolder *folder = adapter->itemFolder;
 
+               adapter->itemFolder = NULL;
+               /*
+               printf( "remove folder for ::%s::\n", obj->name );
+               printf( "      folder name ::%s::\n", ADDRITEM_NAME(folder) );
+               printf( "-------------- remove results\n" );
+               */
                addrindex_remove_results( ds, folder );
+               /* printf( "-------------- remove node\n" ); */
                gtk_ctree_remove_node( ctree, node );
                return;
        }
@@ -3537,6 +3590,23 @@ static void addressbook_search_idle( gpointer data ) {
        */
 }
 
+/**
+ * Search completion callback function. This removes the query from the idle
+ * list.
+ *
+ * \param queryID Query ID of search request.
+ */
+void addressbook_clear_idler( gint queryID ) {
+       gpointer ptrQID;
+
+       /* Remove idler function */
+       /* printf( "addressbook_clear_idler::%d::\n", queryID ); */
+       ptrQID = GINT_TO_POINTER( queryID );
+       if( ptrQID ) {
+               gtk_idle_remove_by_data( ptrQID );
+       }
+}
+
 /**
  * Search completion callback function. This removes the query from the idle
  * list.
@@ -3687,6 +3757,7 @@ static void addressbook_lup_clicked( GtkButton *button, gpointer data ) {
                parentNode = node;
        }
        addressbook_perform_search( ds, searchTerm, parentNode );
+       gtk_widget_grab_focus( addrbook.entry );
 
        g_free( searchTerm );
 }
@@ -3694,7 +3765,6 @@ static void addressbook_lup_clicked( GtkButton *button, gpointer data ) {
 /**
  * Browse address entry for highlighted entry.
  */
-#ifdef USE_LDAP
 static void addressbook_browse_entry_cb(void)
 {
        GtkCTree *clist = GTK_CTREE(addrbook.clist);
@@ -3706,19 +3776,19 @@ static void addressbook_browse_entry_cb(void)
 
        if(addrbook.listSelected == NULL)
                return;
-       
+
        obj = gtk_ctree_node_get_row_data(clist, addrbook.listSelected);
        if (obj == NULL)
                return;
-       
+
        ds = addressbook_find_datasource(GTK_CTREE_NODE(addrbook.treeSelected));
        if(ds == NULL)
                return;
-       
+
        iface = ds->interface;
-       if(iface->haveLibrary == NULL)
+       if(! iface->haveLibrary )
                return;
-       
+
        person = NULL;
        if (obj->type == ADDR_ITEM_EMAIL) {
                email = ( ItemEMail * ) obj;
@@ -3741,7 +3811,6 @@ static void addressbook_browse_entry_cb(void)
 #endif
        }
 }
-#endif
 
 
 /* **********************************************************************
index 6527fc2..76f0293 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 2001-2003 Match Grun
+ * Copyright (C) 2001-2004 Match Grun
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -95,6 +95,7 @@
 #define ATTAG_LDAP_MAX_AGE    "max-age"
 #define ATTAG_LDAP_DYN_SEARCH "dyn-search"
 #define ATTAG_LDAP_MATCH_OPT  "match-opt"
+#define ATTAG_LDAP_ENABLE_TLS "enable-tls"
 
 #define ELTAG_LDAP_ATTR_SRCH  "attribute"
 #define ATTAG_LDAP_ATTR_NAME  "name"
@@ -1349,11 +1350,13 @@ static AddressDataSource *addrindex_parse_ldap( XMLFile *file ) {
        gchar *serverName = NULL;
        gchar *criteria = NULL;
        gboolean bDynSearch;
+       gboolean bTLS;
        gint iMatch;
 
        /* printf( "addrindex_parse_ldap\n" ); */
        /* Set up some defaults */
        bDynSearch = FALSE;
+       bTLS = FALSE;
        iMatch = LDAPCTL_MATCH_BEGINWITH;
 
        ds = addrindex_create_datasource( ADDR_IF_LDAP );
@@ -1408,6 +1411,12 @@ static AddressDataSource *addrindex_parse_ldap( XMLFile *file ) {
                                iMatch = LDAPCTL_MATCH_CONTAINS;
                        }
                }
+               else if( strcmp( name, ATTAG_LDAP_ENABLE_TLS ) == 0 ) {
+                       bTLS = FALSE;
+                       if( strcmp( value, ATVAL_BOOLEAN_YES ) == 0 ) {
+                               bTLS = TRUE;
+                       }
+               }
                attr = g_list_next( attr );
        }
 
@@ -1415,6 +1424,7 @@ static AddressDataSource *addrindex_parse_ldap( XMLFile *file ) {
        ldapsvr_set_name( server, serverName );
        ldapsvr_set_search_flag( server, bDynSearch );
        ldapctl_set_matching_option( ctl, iMatch );
+       ldapctl_set_tls( ctl, bTLS );
        g_free( serverName );
        ldapsvr_set_control( server, ctl );
        ds->rawDataSource = server;
@@ -1474,6 +1484,10 @@ static void addrindex_write_ldap( FILE *fp, AddressDataSource *ds, gint lvl ) {
                ( ctl->matchingOption == LDAPCTL_MATCH_CONTAINS ) ?
                ATVAL_LDAP_MATCH_CONTAINS : ATVAL_LDAP_MATCH_BEGIN );
 
+       addrindex_write_attr( fp, ATTAG_LDAP_ENABLE_TLS,
+                       ctl->enableTLS ?
+                       ATVAL_BOOLEAN_YES : ATVAL_BOOLEAN_NO );
+
        fputs(" >\n", fp);
 
        /* Output attributes */
@@ -1487,7 +1501,6 @@ static void addrindex_write_ldap( FILE *fp, AddressDataSource *ds, gint lvl ) {
 
        /* End of element */    
        addrindex_write_elem_e( fp, lvl, TAG_DS_LDAP );
-
 }
 
 #else
@@ -2737,8 +2750,11 @@ void addrindex_remove_results( AddressDataSource *ds, ItemFolder *folder ) {
        AddressCache *cache;
        gint queryID = 0;
 
+       /* printf( "addrindex_remove_results/start\n" ); */
+
        /* Test for folder */
        if( folder->folderType != ADDRFOLDER_QUERY_RESULTS ) return;
+       /* printf( "folder name ::%s::\n", ADDRITEM_NAME(folder) ); */
        adbase = ( AddrBookBase * ) ds->rawDataSource;
        if( adbase == NULL ) return;
        cache = adbase->addressCache;
@@ -2748,13 +2764,26 @@ void addrindex_remove_results( AddressDataSource *ds, ItemFolder *folder ) {
 
        if( ds->type == ADDR_IF_LDAP ) {
 #ifdef USE_LDAP
-               LdapQuery  *qry;
+               LdapQuery *qry;
+               gboolean  delFlag;
 
                qry = ( LdapQuery * ) folder->folderData;
                queryID = ADDRQUERY_ID(qry);
-               ldapquery_remove_results( qry );
+               /* printf( "calling ldapquery_remove_results...queryID=%d\n", queryID ); */
+               delFlag = ldapquery_remove_results( qry );
+               /* printf( "calling ldapquery_remove_results...done\n" ); */
+               /*
+               if( delFlag ) {
+                       printf( "delFlag IS-TRUE\n" );
+               }
+               else {
+                       printf( "delFlag IS-FALSE\n" );
+                       addressbook_clear_idler( queryID );
+               }
+               */
 #endif
        }
+       /* printf( "addrindex_remove_results/end\n" ); */
 
        /* Delete query request */
        if( queryID > 0 ) {
@@ -2776,13 +2805,14 @@ void addrindex_remove_results( AddressDataSource *ds, ItemFolder *folder ) {
  * \return <i>TRUE</i> if data loaded, <i>FALSE</i> if address index not loaded.
  */
 gboolean addrindex_load_completion(
-               gint (*callBackFunc) ( const gchar *, const gchar *, const gchar * ) )
+               gint (*callBackFunc) ( const gchar *, const gchar *, 
+                                      const gchar *, const gchar * ) )
 {
        AddressDataSource *ds;
        GList *nodeIf, *nodeDS;
        GList *listP, *nodeP;
        GList *nodeM;
-       gchar *sName, *sAddress, *sAlias, *sFriendly;
+       gchar *sName;
 
        nodeIf = addrindex_get_interface_list( _addressIndex_ );
        while( nodeIf ) {
@@ -2816,25 +2846,18 @@ gboolean addrindex_load_completion(
                                nodeM = person->listEMail;
 
                                /* Figure out name to use */
-                               sName = person->nickName;
+                               sName = ADDRITEM_NAME(person);
                                if( sName == NULL || *sName == '\0' ) {
-                                       sName = ADDRITEM_NAME(person);
+                                       sName = person->nickName;
                                }
 
                                /* Process each E-Mail address */
                                while( nodeM ) {
                                        ItemEMail *email = nodeM->data;
-                                       /* Have mail */
-                                       sFriendly = sName;
-                                       sAddress = email->address;
-                                       if( sAddress || *sAddress != '\0' ) {
-                                               sAlias = ADDRITEM_NAME(email);
-                                               if( sAlias && *sAlias != '\0' ) {
-                                                       sFriendly = sAlias;
-                                               }
-                                               ( callBackFunc ) ( sFriendly, sAddress, sName );
-                                       }
-
+                                       
+                                       callBackFunc( sName, email->address, person->nickName, 
+                                                     ADDRITEM_NAME(email) );
+                                       
                                        nodeM = g_list_next( nodeM );
                                }
                                nodeP = g_list_next( nodeP );
index 94789c5..d58d42f 100644 (file)
@@ -175,10 +175,8 @@ void addrindex_remove_results              ( AddressDataSource *ds,
 
 gboolean addrindex_load_completion(
                gint (*callBackFunc)
-                       ( const gchar *, const gchar *, const gchar * ) );
-gint addrindex_setup_explicit_search(
-       AddressDataSource *ds, const gchar *searchTerm, ItemFolder *folder,
-       void *callBackEnd, void *callBackEntry );
+                       ( const gchar *, const gchar *, 
+                         const gchar *, const gchar * ) );
 
 #endif /* __ADDRINDEX_H__ */
 
index 319acdc..49ab23d 100644 (file)
 #include "addressitem.h"
 #include "mgutils.h"
 
-/*
-* Create a selection record from an address cache item.
-* Enter: aio Item object.
-*/
+/**
+ * Create a selection record from an address cache item.
+ * \param  aio Item object.
+ * \return Address select item.
+ */
 AddrSelectItem *addrselect_create_item( AddrItemObject *aio ) {
        AddrSelectItem *item = NULL;
 
@@ -45,10 +46,11 @@ AddrSelectItem *addrselect_create_item( AddrItemObject *aio ) {
        return item;
 }
 
-/*
-* Create a selection record from an address object (in tree node).
-* Enter: obj Address object.
-*/
+/**
+ * Create a selection record from an address object (in tree node).
+ * \param obj Address object.
+ * \return Address select item.
+ */
 AddrSelectItem *addrselect_create_node( AddressObject *obj ) {
        AddrSelectItem *item = NULL;
 
@@ -62,10 +64,11 @@ AddrSelectItem *addrselect_create_node( AddressObject *obj ) {
        return item;
 }
 
-/*
-* Create a copy of a selection record.
-* Enter: item Address entry to copy.
-*/
+/**
+ * Create a copy of a selection record.
+ * Enter: item Address entry to copy.
+ * \return Address select item.
+ */
 AddrSelectItem *addrselect_item_copy( AddrSelectItem *item ) {
        AddrSelectItem *copy = NULL;
 
@@ -79,9 +82,10 @@ AddrSelectItem *addrselect_item_copy( AddrSelectItem *item ) {
        return copy;
 }
 
-/*
-* Free selection record.
-*/
+/**
+ * Free selection record.
+ * \return Address select item.
+ */
 void addrselect_item_free( AddrSelectItem *item ) {
        if( item ) {
                g_free( item->uid );
@@ -94,14 +98,21 @@ void addrselect_item_free( AddrSelectItem *item ) {
        g_free( item );
 }
 
-/*
-* Properties.
-*/
+/**
+ * Specify cache ID for specified item.
+ * \param item  Address select item.
+ * \param value Cache ID.
+ */
 void addrselect_set_cache_id( AddrSelectItem *item, const gchar *value ) {
        g_return_if_fail( item != NULL );
        item->cacheID = mgu_replace_string( item->cacheID, value );
 }
 
+/**
+ * Print address selection item.
+ * \param item   Address select item.
+ * \param stream Output stream.
+ */
 void addrselect_item_print( AddrSelectItem *item, FILE *stream ) {
        fprintf( stream, "Select Record\n" );
        fprintf( stream, "obj type: %d\n", item->objectType );
@@ -110,10 +121,10 @@ void addrselect_item_print( AddrSelectItem *item, FILE *stream ) {
        fprintf( stream, "---\n" );
 }
 
-/*
-* Create a new selection.
-* Return: Initialized object.
-*/
+/**
+ * Create a new address selection object.
+ * \return Initialized object.
+ */
 AddrSelectList *addrselect_list_create() {
        AddrSelectList *asl;
 
@@ -122,10 +133,10 @@ AddrSelectList *addrselect_list_create() {
        return asl;
 }
 
-/*
-* Clear list of selection records.
-* Enter: asl List to process.
-*/
+/**
+ * Clear list of selection records.
+ * \param asl  List to process.
+ */
 void addrselect_list_clear( AddrSelectList *asl ) {
        GList *node;
 
@@ -143,10 +154,10 @@ void addrselect_list_clear( AddrSelectList *asl ) {
        asl->listSelect = NULL;
 }
 
-/*
-* Free selection list.
-* Enter: asl List to free.
-*/
+/**
+ * Free selection list.
+ * \param asl  List to free.
+ */
 void addrselect_list_free( AddrSelectList *asl ) {
        g_return_if_fail( asl != NULL );
 
@@ -156,22 +167,23 @@ void addrselect_list_free( AddrSelectList *asl ) {
        g_free( asl );
 }
 
-/*
-* Test whether selection is empty.
-* Enter: asl List to test.
-* Return: TRUE if list is empty.
-*/
+/**
+ * Test whether selection is empty.
+ * \param  asl List to test.
+ * \return <i>TRUE</i> if list is empty.
+ */
 gboolean addrselect_test_empty( AddrSelectList *asl ) {
        g_return_val_if_fail( asl != NULL, TRUE );
        return ( asl->listSelect == NULL );
 }
 
-/*
-* Return list of AddrSelectItem objects.
-* Enter: asl List to process.
-* Return: List of selection items. The list should should be g_list_free()
-* when done. Items contained in the list should not be freed!!!
-*/
+/**
+ * Return list of AddrSelectItem objects.
+ * \param  asl  List to process.
+ * \return List of selection items. The list should should be freed with
+ *         <code>g_list_free()</code> when done. Items contained in the
+ *         list should <b>not</b> be freed!!!
+ */
 GList *addrselect_get_list( AddrSelectList *asl ) {
        GList *node, *list;
 
@@ -185,6 +197,11 @@ GList *addrselect_get_list( AddrSelectList *asl ) {
        return list;
 }
 
+/**
+ * Format address item.
+ * \param  aio Item.
+ * \return Formatted address.
+ */
 static gchar *addrselect_format_address( AddrItemObject * aio ) {
        gchar *buf = NULL;
        gchar *name = NULL;
@@ -232,11 +249,11 @@ static gchar *addrselect_format_address( AddrItemObject * aio ) {
        return buf;
 }
 
-/*
-* Print formatted addresses list to specified stream.
-* Enter: asl    List to process.
-*        stream Stream.
-*/
+/**
+ * Print formatted addresses list to specified stream.
+ * \param asl    List to process.
+ * \param stream Stream.
+ */
 void addrselect_list_print( AddrSelectList *asl, FILE *stream ) {
        GList *node;
 
@@ -282,11 +299,11 @@ void addrselect_list_print( AddrSelectList *asl, FILE *stream ) {
        fprintf( stream, "show selection...<<<\n" );
 }
 
-/*
-* Print address items to specified stream.
-* Enter: asl    List to process.
-*        stream Stream.
-*/
+/**
+ * Print address items to specified stream.
+ * \param asl    List to process.
+ * \param stream Stream.
+ */
 void addrselect_list_show( AddrSelectList *asl, FILE *stream ) {
        GList *node;
 
@@ -303,12 +320,12 @@ void addrselect_list_show( AddrSelectList *asl, FILE *stream ) {
        fprintf( stream, "show selection...<<<\n" );
 }
 
-/*
-* Test whether specified object is in list.
-* Enter: list List to check.
-*        aio  Object to test.
-* Return item found, or NULL if not in list.
-*/
+/**
+ * Test whether specified object is in list.
+ * \param list List to check.
+ * \param aio  Object to test.
+ * \param item found, or <i>NULL</i> if not in list.
+ */
 static AddrSelectItem *addrselect_list_find( GList *list, AddrItemObject *aio ) {
        GList *node;
 
@@ -323,13 +340,12 @@ static AddrSelectItem *addrselect_list_find( GList *list, AddrItemObject *aio )
        return NULL;
 }
 
-/*
-* Add a single object into the list.
-* Enter: asl     Address selection object.
-*        obj     Address object.
-*        cacheID Cache ID. Should be g_free() after calling function.
-* Return: Adjusted list.
-*/
+/**
+ * Add a single object into the list.
+ * \param asl     Address selection object.
+ * \param aio     Address object.
+ * \param cacheID Cache ID. Should be freed after calling function.
+ */
 void addrselect_list_add_obj( AddrSelectList *asl, AddrItemObject *aio, gchar *cacheID ) {
        AddrSelectItem *item;
 
@@ -349,13 +365,12 @@ void addrselect_list_add_obj( AddrSelectList *asl, AddrItemObject *aio, gchar *c
        /* addrselect_list_show( asl, stdout ); */
 }
 
-/*
-* Add a single item into the list.
-* Enter: asl     Address selection object.
-*        item    Address select item.
-*        cacheID Cache ID. Should be g_free() after calling function.
-* Return: Adjusted list.
-*/
+/**
+ * Add a single item into the list.
+ * \param  asl     Address selection object.
+ * \param  item    Address select item.
+ * \param  cacheID Cache ID. Should be g_free() after calling function.
+ */
 void addrselect_list_add( AddrSelectList *asl, AddrSelectItem *item, gchar *cacheID ) {
        g_return_if_fail( asl != NULL );
        if( item == NULL ) return;
@@ -367,11 +382,11 @@ void addrselect_list_add( AddrSelectList *asl, AddrSelectItem *item, gchar *cach
        asl->listSelect = g_list_append( asl->listSelect, item );
 }
 
-/*
-* Remove specified object from list.
-* Enter: asl  Address selection object.
-*        aio  Object to remove.
-*/
+/**
+ * Remove specified object from list.
+ * \param asl  Address selection object.
+ * \param aio  Object to remove.
+ */
 void addrselect_list_remove( AddrSelectList *asl, AddrItemObject *aio ) {
        GList *node;
        AddrSelectItem *item;
@@ -392,6 +407,52 @@ void addrselect_list_remove( AddrSelectList *asl, AddrItemObject *aio ) {
        /* addrselect_list_show( list, stdout ); */
 }
 
+/**
+ * Build list of formatted addresses.
+ * \param  asl List to process.
+ * \return List of addresses, formatted as character strings. List should be
+ *         freed when no longer required.
+ */
+GList *addrselect_build_list( AddrSelectList *asl ) {
+       GList *list;
+       GList *node;
+
+       g_return_val_if_fail(asl != NULL, NULL);
+       list = NULL;
+       node = asl->listSelect;
+       while( node != NULL ) {
+               AddrSelectItem *item;
+               AddrItemObject *aio;
+               gchar *addr;
+
+               item = node->data;
+               aio = ( AddrItemObject * ) item->addressItem;
+               if( aio ) {
+                       if( aio->type == ADDR_ITEM_GROUP ) {
+                               ItemGroup *group = ( ItemGroup * ) aio;
+                               GList *node = group->listEMail;
+                               while( node ) {
+                                       ItemEMail *email = node->data;
+                                       addr = addrselect_format_address(
+                                               ( AddrItemObject * ) email );
+                                       if( addr ) {
+                                               list = g_list_append( list, addr );
+                                       }
+                                       node = g_list_next( node );
+                               }
+                       }
+                       else {
+                               addr = addrselect_format_address( aio );
+                               if( addr ) {
+                                       list = g_list_append( list, addr );
+                               }
+                       }
+               }
+               node = g_list_next( node );
+       }
+       return list;
+}
+
 /*
 * End of Source.
 */
index 78d7e2b..38abe89 100644 (file)
@@ -70,6 +70,7 @@ void addrselect_list_show             ( AddrSelectList *asl,
                                          FILE *stream );
 void addrselect_list_print             ( AddrSelectList *asl,
                                          FILE *stream );
+GList *addrselect_build_list           ( AddrSelectList *asl );
 
 #endif /* __ADDR_SELECT_H__ */
 
index 3d26457..fc0702c 100644 (file)
@@ -869,6 +869,7 @@ CodeConvFunc conv_get_code_conv_func(const gchar *src_charset_str,
        switch (src_charset) {
        case C_ISO_2022_JP:
        case C_ISO_2022_JP_2:
+       case C_ISO_2022_JP_3:
                if (dest_charset == C_AUTO &&
                    conv_get_current_charset() == C_EUC_JP)
                        code_conv = conv_jistodisp;
@@ -909,8 +910,9 @@ CodeConvFunc conv_get_code_conv_func(const gchar *src_charset_str,
                if (dest_charset == C_AUTO &&
                    conv_get_current_charset() == C_EUC_JP)
                        code_conv = conv_euctodisp;
-               else if (dest_charset == C_ISO_2022_JP ||
-                        dest_charset == C_ISO_2022_JP_2)
+               else if (dest_charset == C_ISO_2022_JP   ||
+                        dest_charset == C_ISO_2022_JP_2 ||
+                        dest_charset == C_ISO_2022_JP_3)
                        code_conv = conv_euctojis;
                break;
        default:
@@ -1059,6 +1061,7 @@ static const struct {
        {C_KOI8_U,              CS_KOI8_U},
        {C_ISO_2022_JP,         CS_ISO_2022_JP},
        {C_ISO_2022_JP_2,       CS_ISO_2022_JP_2},
+       {C_ISO_2022_JP_3,       CS_ISO_2022_JP_3},
        {C_EUC_JP,              CS_EUC_JP},
        {C_EUC_JP,              CS_EUCJP},
        {C_SHIFT_JIS,           CS_SHIFT_JIS},
@@ -1108,6 +1111,7 @@ static const struct {
        {"ru_RU"        , C_ISO_8859_5  , C_KOI8_R},
        {"tg_TJ"        , C_KOI8_T      , C_KOI8_T},
        {"ru_UA"        , C_KOI8_U      , C_KOI8_U},
+       {"uk_UA.CP1251" , C_WINDOWS_1251, C_KOI8_U},
        {"uk_UA"        , C_KOI8_U      , C_KOI8_U},
 
        {"be_BY"        , C_WINDOWS_1251, C_WINDOWS_1251},
@@ -1453,6 +1457,7 @@ gboolean conv_is_multibyte_encoding(CharSet encoding)
        case C_EUC_CN:
        case C_ISO_2022_JP:
        case C_ISO_2022_JP_2:
+       case C_ISO_2022_JP_3:
        case C_ISO_2022_KR:
        case C_ISO_2022_CN:
        case C_SHIFT_JIS:
@@ -1488,6 +1493,8 @@ void conv_unmime_header_overwrite(gchar *str)
        CharSet cur_charset;
        const gchar *locale;
 
+       g_return_if_fail(str != NULL);
+       
        cur_charset = conv_get_current_charset();
 
 #warning FIXME_GTK2
index 9bd19d2..1e83876 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2003 Hiroyuki Yamamoto
+ * Copyright (C) 1999-2004 Hiroyuki Yamamoto
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -72,6 +72,7 @@ typedef enum
        C_KOI8_U,
        C_ISO_2022_JP,
        C_ISO_2022_JP_2,
+       C_ISO_2022_JP_3,
        C_EUC_JP,
        C_SHIFT_JIS,
        C_ISO_2022_KR,
@@ -141,6 +142,7 @@ struct _CodeConverter
 #define CS_KOI8_U              "KOI8-U"
 #define CS_ISO_2022_JP         "ISO-2022-JP"
 #define CS_ISO_2022_JP_2       "ISO-2022-JP-2"
+#define CS_ISO_2022_JP_3       "ISO-2022-JP-3"
 #define CS_EUC_JP              "EUC-JP"
 #define CS_EUCJP               "EUCJP"
 #define CS_SHIFT_JIS           "Shift_JIS"
index 922dd4b..8a516af 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2003 Hiroyuki Yamamoto
+ * Copyright (C) 1999-2004 Hiroyuki Yamamoto
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -59,6 +59,7 @@
 #define ACTIONS_RC             "actionsrc"
 #define RENDERER_RC            "rendererrc"
 #define COMMAND_HISTORY                "command_history"
+#define QUICKSEARCH_HISTORY    "quicksearch_history"
 #define TEMPLATE_DIR           "templates"
 #define TMP_DIR                        "tmp"
 #define NEWSGROUP_LIST         ".newsgroup_list"
 #define MAX_ENTRY_LENGTH               8191
 #define COLOR_DIM                      35000
 #define UI_REFRESH_INTERVAL            50000   /* usec */
+#define FOLDER_UPDATE_INTERVAL         1500    /* msec */
+#define PROGRESS_UPDATE_INTERVAL       200     /* msec */
 #define SESSION_TIMEOUT                        60      /* sec */
 #define MAX_HISTORY_SIZE               16
 
index bd0023c..6bcc83e 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2003 Hiroyuki Yamamoto
+ * Copyright (C) 1999-2004 Hiroyuki Yamamoto
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -41,7 +41,7 @@ static void nntp_session_destroy(Session      *session);
 static gint nntp_ok            (SockInfo       *sock,
                                 gchar          *argbuf);
 
-static void nntp_gen_send      (SockInfo       *sock,
+static gint nntp_gen_send      (SockInfo       *sock,
                                 const gchar    *format,
                                 ...);
 static gint nntp_gen_recv      (SockInfo       *sock,
@@ -97,8 +97,32 @@ Session *nntp_session_new(const gchar *server, gushort port, gchar *buf,
        session->group = NULL;
 
        if (userid && passwd) {
+               gint ok;
+
                session->userid = g_strdup(userid);
                session->passwd = g_strdup(passwd);
+
+               ok = nntp_gen_send(sock, "AUTHINFO USER %s", session->userid);
+               if (ok != NN_SUCCESS) {
+                       session_destroy(SESSION(session));
+                       return NULL;
+               }
+               ok = nntp_ok(sock, NULL);
+               if (ok == NN_AUTHCONT) {
+                       ok = nntp_gen_send(sock, "AUTHINFO PASS %s",
+                                          session->passwd);
+                       if (ok != NN_SUCCESS) {
+                               session_destroy(SESSION(session));
+                               return NULL;
+                       }
+                       ok = nntp_ok(sock, NULL);
+                       if (ok != NN_SUCCESS)
+                               session->auth_failed = TRUE;
+               }
+               if (ok == NN_SOCKET) {
+                       session_destroy(SESSION(session));
+                       return NULL;
+               }
        }
 
        return SESSION(session);
@@ -134,7 +158,7 @@ gint nntp_group(NNTPSession *session, const gchar *group,
 
        ok = nntp_gen_command(session, buf, "GROUP %s", group);
 
-       if (ok != NN_SUCCESS) {
+       if (ok != NN_SUCCESS && ok != NN_SOCKET && ok != NN_AUTHREQ) {
                ok = nntp_mode(session, FALSE);
                if (ok == NN_SUCCESS)
                        ok = nntp_gen_command(session, buf, "GROUP %s", group);
@@ -291,9 +315,6 @@ gint nntp_mode(NNTPSession *session, gboolean stream)
 {
        gint ok;
 
-       if (session->auth_failed)
-               return NN_AUTHREQ;
-
        ok = nntp_gen_command(session, NULL, "MODE %s",
                              stream ? "STREAM" : "READER");
 
@@ -327,7 +348,7 @@ static gint nntp_ok(SockInfo *sock, gchar *argbuf)
        return ok;
 }
 
-static void nntp_gen_send(SockInfo *sock, const gchar *format, ...)
+static gint nntp_gen_send(SockInfo *sock, const gchar *format, ...)
 {
        gchar buf[NNTPBUFSIZE];
        va_list args;
@@ -344,7 +365,12 @@ static void nntp_gen_send(SockInfo *sock, const gchar *format, ...)
        }
 
        strcat(buf, "\r\n");
-       sock_write_all(sock, buf, strlen(buf));
+       if (sock_write_all(sock, buf, strlen(buf)) < 0) {
+               log_warning(_("Error occurred while sending command\n"));
+               return NN_SOCKET;
+       }
+
+       return NN_SUCCESS;
 }
 
 static gint nntp_gen_recv(SockInfo *sock, gchar *buf, gint size)
@@ -373,7 +399,9 @@ static gint nntp_gen_command(NNTPSession *session, gchar *argbuf,
        va_end(args);
 
        sock = SESSION(session)->sock;
-       nntp_gen_send(sock, "%s", buf);
+       ok = nntp_gen_send(sock, "%s", buf);
+       if (ok != NN_SUCCESS)
+               return ok;
        ok = nntp_ok(sock, argbuf);
        if (ok == NN_AUTHREQ) {
                if (!session->userid || !session->passwd) {
@@ -381,11 +409,15 @@ static gint nntp_gen_command(NNTPSession *session, gchar *argbuf,
                        return ok;
                }
 
-               nntp_gen_send(sock, "AUTHINFO USER %s", session->userid);
+               ok = nntp_gen_send(sock, "AUTHINFO USER %s", session->userid);
+               if (ok != NN_SUCCESS)
+                       return ok;
                ok = nntp_ok(sock, NULL);
                if (ok == NN_AUTHCONT) {
-                       nntp_gen_send(sock, "AUTHINFO PASS %s",
-                                     session->passwd);
+                       ok = nntp_gen_send(sock, "AUTHINFO PASS %s",
+                                          session->passwd);
+                       if (ok != NN_SUCCESS)
+                               return ok;
                        ok = nntp_ok(sock, NULL);
                }
                if (ok != NN_SUCCESS) {
@@ -393,18 +425,20 @@ static gint nntp_gen_command(NNTPSession *session, gchar *argbuf,
                        return ok;
                }
 
-               nntp_gen_send(sock, "%s", buf);
+               ok = nntp_gen_send(sock, "%s", buf);
+               if (ok != NN_SUCCESS)
+                       return ok;
                ok = nntp_ok(sock, argbuf);
 
        } else if (ok == NN_AUTHCONT) {
-                nntp_gen_send(sock, "AUTHINFO PASS %s", session->passwd);
-                ok = nntp_ok(sock, NULL);
-
-                if (ok != NN_SUCCESS) {
+                ok = nntp_gen_send(sock, "AUTHINFO PASS %s",
+                                  session->passwd);
+               if (ok != NN_SUCCESS)  {
                        session->auth_failed = TRUE;
-                        return ok;
-                }
-        }
+                       return ok;
+               }
+                ok = nntp_ok(sock, NULL);
+       }
 
        return ok;
 }
index 23b672a..a5b1022 100644 (file)
@@ -101,8 +101,7 @@ gboolean ssl_init_socket_with_method(SockInfo *sockinfo, SSLMethod method)
 
        /* Get the cipher */
 
-       debug_print(_("SSL connection using %s\n"),
-                   SSL_get_cipher(ssl));
+       debug_print("SSL connection using %s\n", SSL_get_cipher(ssl));
 
        /* Get server's certificate (note: beware of dynamic allocation) */
        if ((server_cert = SSL_get_peer_certificate(ssl)) == NULL) {
index aef3c96..e969b63 100644 (file)
@@ -3420,6 +3420,7 @@ int subject_get_prefix_length(const gchar *subject)
                "Fw\\:",                        /* "Fw:" Forward */
                "Enc\\:",                       /* "Enc:" Forward (Brazilian Outlook) */
                "Odp\\:",                       /* "Odp:" Re (Polish Outlook) */
+               "Rif\\:"                        /* "Rif:" (Italian Outlook) */
                /* add more */
        };
        const int PREFIXES = sizeof prefixes / sizeof prefixes[0];
@@ -3543,14 +3544,15 @@ gchar *expand_search_string(const gchar *search_string)
                return copy_str;
 
        matcherstr = g_string_sized_new(16);
-       cmd_start = cmd_end = copy_str;
-       while (cmd_end && *cmd_end) {
+       cmd_start = copy_str;
+       while (cmd_start && *cmd_start) {
                /* skip all white spaces */
-               while (*cmd_end && isspace(*cmd_end))
-                       cmd_end++;
+               while (*cmd_start && isspace((guchar)*cmd_start))
+                       cmd_start++;
+        cmd_end = cmd_start;
 
                /* extract a command */
-               while (*cmd_end && !isspace(*cmd_end))
+               while (*cmd_end && !isspace((guchar)*cmd_end))
                        cmd_end++;
 
                /* save character */
@@ -3593,7 +3595,8 @@ gchar *expand_search_string(const gchar *search_string)
                                        break;
 
                                /* extract a parameter, allow quotes */
-                               cmd_end++;
+                while (*cmd_end && isspace((guchar)*cmd_end))
+                             cmd_end++;
                                cmd_start = cmd_end;
                                if (*cmd_start == '"') {
                                        term_char = '"';
@@ -3606,9 +3609,6 @@ gchar *expand_search_string(const gchar *search_string)
                                while ((*cmd_end) && (*cmd_end != term_char))
                                        cmd_end++;
 
-                               if (*cmd_end && (*cmd_end != term_char))
-                                       break;
-
                                if (*cmd_end == '"')
                                        cmd_end++;
 
@@ -3640,10 +3640,9 @@ gchar *expand_search_string(const gchar *search_string)
                        }
                }
 
-               if (*cmd_end) {
+               if (*cmd_end)
                        cmd_end++;
-                       cmd_start = cmd_end;
-               }
+               cmd_start = cmd_end;
        }
 
        g_free(copy_str);
@@ -3658,7 +3657,7 @@ guint g_stricase_hash(gconstpointer gptr)
        const char *str;
 
        for (str = gptr; str && *str; str++) {
-               if (isupper(*str)) hash_result += (*str + ' ');
+               if (isupper((guchar)*str)) hash_result += (*str + ' ');
                else hash_result += *str;
        }
 
@@ -3728,7 +3727,7 @@ gint quote_cmd_argument(gchar * result, guint size,
 
        for(p = path ; * p != '\0' ; p ++) {
 
-               if (isalnum(p) || (* p == '/')) {
+               if (isalnum((guchar)*p) || (* p == '/')) {
                        if (remaining > 0) {
                                * result_p = * p;
                                result_p ++; 
index 434c6f9..9c74c45 100644 (file)
        ptr = __tmp; \
 }
 
+#define AUTORELEASE_STR(str, iffail) \
+{ \
+       gchar *__str; \
+       Xstrdup_a(__str, str, iffail); \
+       g_free(str); \
+       str = __str; \
+}
+
 #define FILE_OP_ERROR(file, func) \
 { \
        fprintf(stderr, "%s: ", file); \
index 6da76b2..c6874a7 100644 (file)
@@ -171,7 +171,8 @@ static GList *compose_list = NULL;
 Compose *compose_generic_new                   (PrefsAccount   *account,
                                                 const gchar    *to,
                                                 FolderItem     *item,
-                                                GPtrArray      *attach_files);
+                                                GPtrArray      *attach_files,
+                                                GList          *listAddress );
 
 static Compose *compose_create                 (PrefsAccount   *account,
                                                 ComposeMode     mode);
@@ -300,6 +301,9 @@ static void compose_create_header_entry     (Compose *compose);
 static void compose_add_header_entry   (Compose *compose, gchar *header, gchar *text);
 static void compose_update_priority_menu_item(Compose * compose);
 
+static void compose_add_field_list     ( Compose *compose,
+                                         GList *listAddress );
+
 /* callback functions */
 
 static gboolean compose_edit_size_alloc (GtkEditable   *widget,
@@ -489,6 +493,7 @@ static void compose_check_forwards_go          (Compose *compose);
 
 static gboolean compose_send_control_enter     (Compose        *compose);
 static gint compose_defer_auto_save_draft      (Compose        *compose);
+static PrefsAccount *compose_guess_forward_account_from_msginfo        (MsgInfo *msginfo);
 
 static GtkItemFactoryEntry compose_popup_entries[] =
 {
@@ -652,7 +657,8 @@ static GtkItemFactoryEntry compose_entries[] =
        {N_("/_Message/---"),           NULL, NULL, 0, "<Separator>"},
        {N_("/_Message/Si_gn"),         NULL, compose_toggle_sign_cb   , 0, "<ToggleItem>"},
        {N_("/_Message/_Encrypt"),      NULL, compose_toggle_encrypt_cb, 0, "<ToggleItem>"},
-       {N_("/_Message/Mode/MIME"),             NULL, compose_set_gnupg_mode_cb,   GNUPG_MODE_DETACH, "<RadioItem>"},   
+       {N_("/_Message/Mode"),          NULL, NULL,   0, "<Branch>"},
+       {N_("/_Message/Mode/MIME"),     NULL, compose_set_gnupg_mode_cb,   GNUPG_MODE_DETACH, "<RadioItem>"},   
        {N_("/_Message/Mode/Inline"),   NULL, compose_set_gnupg_mode_cb,   GNUPG_MODE_INLINE, "/Message/Mode/MIME"},    
 #endif /* USE_GPGME */
        {N_("/_Message/---"),           NULL,           NULL,   0, "<Separator>"},
@@ -682,23 +688,27 @@ static GtkTargetEntry compose_mime_types[] =
 Compose *compose_new(PrefsAccount *account, const gchar *mailto,
                     GPtrArray *attach_files)
 {
-       return compose_generic_new(account, mailto, NULL, attach_files);
+       return compose_generic_new(account, mailto, NULL, attach_files, NULL);
 }
 
 Compose *compose_new_with_folderitem(PrefsAccount *account, FolderItem *item)
 {
-       return compose_generic_new(account, NULL, item, NULL);
+       return compose_generic_new(account, NULL, item, NULL, NULL);
+}
+
+Compose *compose_new_with_list( PrefsAccount *account, GList *listAddress )
+{
+       return compose_generic_new( account, NULL, NULL, NULL, listAddress );
 }
 
 Compose *compose_generic_new(PrefsAccount *account, const gchar *mailto, FolderItem *item,
-                            GPtrArray *attach_files)
+                            GPtrArray *attach_files, GList *listAddress )
 {
        Compose *compose;
        GtkTextView *textview;
        GtkTextBuffer *textbuf;
        GtkTextIter iter;
        GtkItemFactory *ifactory;
-       gboolean grab_focus_on_last = TRUE;
 
        if (item && item->prefs && item->prefs->enable_default_account)
                account = account_find_from_id(item->prefs->default_account);
@@ -733,8 +743,7 @@ Compose *compose_generic_new(PrefsAccount *account, const gchar *mailto, FolderI
 
                } else if (item && item->prefs->enable_default_to) {
                        compose_entry_append(compose, item->prefs->default_to, COMPOSE_TO);
-                       compose_entry_select(compose, item->prefs->default_to);
-                       grab_focus_on_last = FALSE;
+                       compose_entry_mark_default_to(compose, item->prefs->default_to);
                }
                if (item && item->ret_rcpt) {
                        menu_set_toggle(ifactory, "/Message/Request Return Receipt", TRUE);
@@ -749,6 +758,7 @@ Compose *compose_generic_new(PrefsAccount *account, const gchar *mailto, FolderI
                 */
                menu_set_sensitive(ifactory, "/Message/Request Return Receipt", FALSE); 
        }
+       compose_add_field_list( compose, listAddress );
 
        if (attach_files) {
                gint i;
@@ -772,9 +782,7 @@ Compose *compose_generic_new(PrefsAccount *account, const gchar *mailto, FolderI
                g_free(folderidentifier);
        }
        
-       /* Grab focus on last header only if no default_to was set */
-       if (grab_focus_on_last)
-               gtk_widget_grab_focus(compose->header_last->entry);
+       gtk_widget_grab_focus(compose->header_last->entry);
 
        undo_unblock(compose->undostruct);
 
@@ -921,8 +929,10 @@ static void compose_generic_reply(MsgInfo *msginfo, gboolean quote,
        Compose *compose;
        PrefsAccount *account = NULL;
        PrefsAccount *reply_account;
-       GtkTextBuffer *buffer;
+       GtkTextView *textview;
+       GtkTextBuffer *textbuf;
        GtkTextIter iter;
+       int cursor_pos;
 
        g_return_if_fail(msginfo != NULL);
        g_return_if_fail(msginfo->folder != NULL);
@@ -970,6 +980,9 @@ static void compose_generic_reply(MsgInfo *msginfo, gboolean quote,
                                to_sender, followup_and_reply_to);
        compose_show_first_last_header(compose, TRUE);
 
+       textview = (GTK_TEXT_VIEW(compose->text));
+       textbuf = gtk_text_view_get_buffer(textview);
+       
 #ifdef USE_ASPELL
        if (msginfo->folder && msginfo->folder->prefs && 
            msginfo->folder->prefs && 
@@ -998,9 +1011,15 @@ static void compose_generic_reply(MsgInfo *msginfo, gboolean quote,
        if (quote && prefs_common.linewrap_quote)
                compose_wrap_line_all(compose);
 
-       buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(compose->text));
-       gtk_text_buffer_get_start_iter(buffer, &iter);
-       gtk_text_buffer_place_cursor(buffer, &iter);
+       cursor_pos = quote_fmt_get_cursor_pos();
+       gtk_text_buffer_get_start_iter(textbuf, &iter);
+       gtk_text_buffer_get_iter_at_offset(textbuf, &iter, cursor_pos);
+       gtk_text_buffer_place_cursor(textbuf, &iter);
+
+       if (quote && prefs_common.linewrap_quote) {
+               compose_wrap_line_all(compose);
+               gtk_text_view_set_editable(GTK_TEXT_VIEW(compose->text), TRUE);
+       }
 
        gtk_widget_grab_focus(compose->text);
 
@@ -1029,33 +1048,10 @@ Compose *compose_forward(PrefsAccount *account, MsgInfo *msginfo,
        g_return_val_if_fail(msginfo != NULL, NULL);
        g_return_val_if_fail(msginfo->folder != NULL, NULL);
 
-       if (msginfo->folder->prefs->enable_default_account)
-               account = account_find_from_id(msginfo->folder->prefs->default_account);
-       if (!account) 
-               account = msginfo->folder->folder->account;
-       if (!account && msginfo->to && prefs_common.forward_account_autosel) {
-               gchar *to;
-               Xstrdup_a(to, msginfo->to, return NULL);
-               extract_address(to);
-               account = account_find_from_address(to);
-       }
-
-       if (!account && prefs_common.forward_account_autosel) {
-               gchar cc[BUFFSIZE];
-               if (!procheader_get_header_from_msginfo(msginfo,cc,sizeof(cc),"CC:")){ /* Found a CC header */
-                       extract_address(cc);
-                       account = account_find_from_address(cc);
-                }
-       }
-
-       if (account == NULL) {
+       if (!account && 
+           !(account = compose_guess_forward_account_from_msginfo
+                               (msginfo)))
                account = cur_account;
-               /*
-               account = msginfo->folder->folder->account;
-               if (!account) account = cur_account;
-               */
-       }
-       g_return_val_if_fail(account != NULL, NULL);
 
        compose = compose_create(account, COMPOSE_FORWARD);
 
@@ -1158,19 +1154,17 @@ Compose *compose_forward_multiple(PrefsAccount *account, GSList *msginfo_list)
        gchar *msgfile;
 
        g_return_val_if_fail(msginfo_list != NULL, NULL);
-       
-       for (msginfo = msginfo_list; msginfo != NULL; msginfo = msginfo->next) {
-               if ( ((MsgInfo *)msginfo->data)->folder == NULL )
+
+       for (msginfo = msginfo_list; msginfo != NULL; msginfo = msginfo->next)
+               if (((MsgInfo *)msginfo->data)->folder == NULL)
                        return NULL;
-       }
 
-       if (account == NULL) {
+       /* guess account from first selected message */
+       if (!account && 
+           !(account = compose_guess_forward_account_from_msginfo
+                               (msginfo_list->data)))
                account = cur_account;
-               /*
-               account = msginfo->folder->folder->account;
-               if (!account) account = cur_account;
-               */
-       }
+
        g_return_val_if_fail(account != NULL, NULL);
 
        for (msginfo = msginfo_list; msginfo != NULL; msginfo = msginfo->next) {
@@ -1386,7 +1380,8 @@ Compose *compose_redirect(PrefsAccount *account, MsgInfo *msginfo)
        gtk_widget_set_sensitive(compose->toolbar->attach_btn, FALSE);
        gtk_widget_set_sensitive(compose->toolbar->sig_btn, FALSE);
        gtk_widget_set_sensitive(compose->toolbar->exteditor_btn, FALSE);
-       gtk_widget_set_sensitive(compose->toolbar->linewrap_btn, FALSE);
+       gtk_widget_set_sensitive(compose->toolbar->linewrap_current_btn, FALSE);
+       gtk_widget_set_sensitive(compose->toolbar->linewrap_all_btn, FALSE);
 
         return compose;
 }
@@ -1452,16 +1447,36 @@ void compose_entry_append(Compose *compose, const gchar *address,
        compose_add_header_entry(compose, header, (gchar *)address);
 }
 
-void compose_entry_select (Compose *compose, const gchar *mailto)
+void compose_entry_mark_default_to(Compose *compose, const gchar *mailto)
 {
-       GSList *header_list;
+       static GtkStyle *bold_style = NULL;
+       static GdkColor bold_color;
+       GSList *h_list;
+       GtkEntry *entry;
                
-       for (header_list = compose->header_list; header_list != NULL; header_list = header_list->next) {
-               GtkEntry * entry = GTK_ENTRY(((ComposeHeaderEntry *)header_list->data)->entry);
-
-               if (gtk_entry_get_text(entry) && !g_strcasecmp(gtk_entry_get_text(entry), mailto)) {
-                       gtk_entry_select_region(entry, 0, -1);
-                       gtk_widget_grab_focus(GTK_WIDGET(entry));
+       for (h_list = compose->header_list; h_list != NULL; h_list = h_list->next) {
+               entry = GTK_ENTRY(((ComposeHeaderEntry *)h_list->data)->entry);
+               if (gtk_entry_get_text(entry) && 
+                   !g_strcasecmp(gtk_entry_get_text(entry), mailto)) {
+                       gtk_widget_ensure_style(GTK_WIDGET(entry));
+                       if (!bold_style) {
+                               PangoFontDescription *font_desc = NULL;
+                               gtkut_convert_int_to_gdk_color
+                                       (prefs_common.color_new, &bold_color);
+                               bold_style = gtk_style_copy(gtk_widget_get_style
+                                       (GTK_WIDGET(entry)));
+                               if (BOLD_FONT)
+                                       font_desc = pango_font_description_from_string
+                                                       (BOLD_FONT);
+                               if (font_desc) {
+                                       if (bold_style->font_desc)
+                                               pango_font_description_free
+                                                       (bold_style->font_desc);
+                                       bold_style->font_desc = font_desc;
+                               }
+                               bold_style->fg[GTK_STATE_NORMAL] = bold_color;
+                       }
+                       gtk_widget_set_style(GTK_WIDGET(entry), bold_style);
                }
        }
 }
@@ -1495,7 +1510,10 @@ void compose_toolbar_cb(gint action, gpointer data)
        case A_EXTEDITOR:
                compose_ext_editor_cb(compose, 0, NULL);
                break;
-       case A_LINEWRAP:
+       case A_LINEWRAP_CURRENT:
+               compose_wrap_line(compose);
+               break;
+       case A_LINEWRAP_ALL:
                compose_wrap_line_all(compose);
                break;
        case A_ADDRBOOK:
@@ -3621,7 +3639,6 @@ static gint compose_write_to_file(Compose *compose, const gchar *file,
        gtk_text_buffer_get_start_iter(buffer, &start);
        gtk_text_buffer_get_end_iter(buffer, &end);
        chars = gtk_text_buffer_get_text(buffer, &start, &end, FALSE);
-       len = strlen(chars);
        if (is_ascii_str(chars)) {
                buf = chars;
                chars = NULL;
@@ -5378,6 +5395,7 @@ static Compose *compose_create(PrefsAccount *account, ComposeMode mode)
        compose->exteditor_pid     = -1;
        compose->exteditor_readdes = -1;
        compose->exteditor_tag     = -1;
+       compose->draft_timeout_tag = -1;
 
 #if USE_ASPELL
        menu_set_sensitive(ifactory, "/Spelling", FALSE);
@@ -6322,7 +6340,8 @@ static void compose_set_ext_editor_sensitive(Compose *compose,
        gtk_widget_set_sensitive(compose->toolbar->insert_btn,    sensitive);
        gtk_widget_set_sensitive(compose->toolbar->sig_btn,       sensitive);
        gtk_widget_set_sensitive(compose->toolbar->exteditor_btn, sensitive);
-       gtk_widget_set_sensitive(compose->toolbar->linewrap_btn,  sensitive);
+       gtk_widget_set_sensitive(compose->toolbar->linewrap_current_btn,  sensitive);
+       gtk_widget_set_sensitive(compose->toolbar->linewrap_all_btn,  sensitive);
 }
 
 /**
@@ -6532,6 +6551,11 @@ static void compose_send_cb(gpointer data, guint action, GtkWidget *widget)
                               _("Yes"), _("No"), NULL) != G_ALERTDEFAULT)
                        return;
        
+       if (compose->draft_timeout_tag != -1) { /* CLAWS: disable draft timeout */
+               gtk_timeout_remove(compose->draft_timeout_tag);
+               compose->draft_timeout_tag = -1;
+       }
+
        compose_allow_user_actions (compose, FALSE);
        compose->sending = TRUE;
        val = compose_send(compose);
@@ -7640,11 +7664,13 @@ static void text_inserted(GtkTextBuffer *buffer, GtkTextIter *iter,
 
        if (prefs_common.autosave && 
            gtk_text_buffer_get_char_count(buffer) % prefs_common.autosave_length == 0)
-               gtk_timeout_add(500, (GtkFunction) compose_defer_auto_save_draft, compose);
+               compose->draft_timeout_tag = gtk_timeout_add
+                       (500, (GtkFunction) compose_defer_auto_save_draft, compose);
 }
 
 static gint compose_defer_auto_save_draft(Compose *compose)
 {
+       compose->draft_timeout_tag = -1;
        compose_draft_cb((gpointer)compose, 2, NULL);
        return FALSE;
 }
@@ -7726,3 +7752,60 @@ static void compose_check_forwards_go(Compose *compose)
 }
 #endif
 
+/*!
+ *\brief       Guess originating forward account from MsgInfo and several 
+ *             "common preference" settings. Return NULL if no guess. 
+ */
+static PrefsAccount *compose_guess_forward_account_from_msginfo(MsgInfo *msginfo)
+{
+       PrefsAccount *account = NULL;
+       
+       g_return_val_if_fail(msginfo, NULL);
+       g_return_val_if_fail(msginfo->folder, NULL);
+       g_return_val_if_fail(msginfo->folder->prefs, NULL);
+
+       if (msginfo->folder->prefs->enable_default_account)
+               account = account_find_from_id(msginfo->folder->prefs->default_account);
+               
+       if (!account) 
+               account = msginfo->folder->folder->account;
+               
+       if (!account && msginfo->to && prefs_common.forward_account_autosel) {
+               gchar *to;
+               Xstrdup_a(to, msginfo->to, return NULL);
+               extract_address(to);
+               account = account_find_from_address(to);
+       }
+
+       if (!account && prefs_common.forward_account_autosel) {
+               gchar cc[BUFFSIZE];
+               if (!procheader_get_header_from_msginfo
+                       (msginfo, cc,sizeof cc , "CC:")) { /* Found a CC header */
+                       extract_address(cc);
+                       account = account_find_from_address(cc);
+                }
+       }
+       
+       return account;
+}
+
+/**
+ * Add entry field for each address in list.
+ * \param compose     E-Mail composition object.
+ * \param listAddress List of (formatted) E-Mail addresses.
+ */
+static void compose_add_field_list( Compose *compose, GList *listAddress ) {
+       GList *node;
+       gchar *addr;
+       node = listAddress;
+       while( node ) {
+               addr = ( gchar * ) node->data;
+               compose_entry_append( compose, addr, COMPOSE_TO );
+               node = g_list_next( node );
+       }
+}
+
+/*
+ * End of Source.
+ */
+
index 7641e2d..b678658 100644 (file)
@@ -207,6 +207,8 @@ struct _Compose
        gchar *redirect_filename;
        
        gboolean remove_references;
+
+       guint draft_timeout_tag;
 };
 
 struct _AttachInfo
@@ -227,6 +229,9 @@ Compose *compose_new                        (PrefsAccount   *account,
 Compose *compose_new_with_folderitem   (PrefsAccount   *account,
                                         FolderItem     *item);
 
+Compose *compose_new_with_list         (PrefsAccount   *account,
+                                        GList          *listAddress);
+
 void compose_reply_mode                        (ComposeMode     mode, 
                                         GSList         *msginfo_list, 
                                         gchar          *body);
@@ -261,7 +266,7 @@ void compose_entry_append           (Compose          *compose,
                                         const gchar      *address,
                                         ComposeEntryType  type);
 
-void compose_entry_select              (Compose          *compose,
+void compose_entry_mark_default_to     (Compose          *compose,
                                         const gchar      *address);
 
 gint compose_send                      (Compose          *compose);
index fb79d43..7b68fa0 100644 (file)
@@ -284,7 +284,7 @@ static gboolean filteringaction_apply(FilteringAction * action, MsgInfo * info)
                return TRUE;
 
        case MATCHACTION_STOP:
-                return TRUE;
+                return FALSE;
 
        case MATCHACTION_HIDE:
                 info->hidden = TRUE;
@@ -318,6 +318,17 @@ static gboolean filtering_match_condition(FilteringProp *filtering, MsgInfo *inf
        return matcherlist_match(filtering->matchers, info);
 }
 
+/*!
+ *\brief       Apply a rule on message.
+ *
+ *\param       filtering List of filtering rules.
+ *\param       info Message to apply rules on.
+ *\param       final Variable returning TRUE or FALSE if one of the
+ *             encountered actions was final. 
+ *             See also \ref filtering_is_final_action.
+ *
+ *\return      gboolean TRUE to continue applying rules.
+ */
 static gboolean filtering_apply_rule(FilteringProp *filtering, MsgInfo *info,
     gboolean * final)
 {
@@ -332,7 +343,7 @@ static gboolean filtering_apply_rule(FilteringProp *filtering, MsgInfo *info,
                 action = tmp->data;
                 
                 if (FALSE == (result = filteringaction_apply(action, info))) {
-                        g_warning("action %s could not be applied", 
+                        g_warning("No further processing after rule %s\n",
                             filteringaction_to_string(buf, sizeof buf, action));
                 }
                 
@@ -344,6 +355,14 @@ static gboolean filtering_apply_rule(FilteringProp *filtering, MsgInfo *info,
        return result;
 }
 
+/*!
+ *\brief       Check if an action is "final", i.e. should break further
+ *             processing.
+ *
+ *\param       filtering_action Action to check.
+ *
+ *\return      gboolean TRUE if \a filtering_action is final.  
+ */
 static gboolean filtering_is_final_action(FilteringAction *filtering_action)
 {
        switch(filtering_action->type) {
@@ -360,15 +379,15 @@ static gboolean filter_msginfo(GSList * filtering_list, MsgInfo * info)
 {
        GSList  *l;
        gboolean final;
-       gboolean applied;
+       gboolean apply_next;
        
        g_return_val_if_fail(info != NULL, TRUE);
        
-       for (l = filtering_list, final = FALSE, applied = FALSE; l != NULL; l = g_slist_next(l)) {
+       for (l = filtering_list, final = FALSE, apply_next = FALSE; l != NULL; l = g_slist_next(l)) {
                FilteringProp * filtering = (FilteringProp *) l->data;
 
                if (filtering_match_condition(filtering, info)) {
-                       applied = filtering_apply_rule(filtering, info, &final);
+                       apply_next = filtering_apply_rule(filtering, info, &final);
                         if (final)
                                 break;
                }               
@@ -376,13 +395,26 @@ static gboolean filter_msginfo(GSList * filtering_list, MsgInfo * info)
 
        /* put in inbox if a final rule could not be applied, or
         * the last rule was not a final one. */
-       if ((final && !applied) || !final) {
+       if ((final && !apply_next) || !final) {
                return FALSE;
        }
 
        return TRUE;
 }
 
+/*!
+ *\brief       Filter a message against a list of rules.
+ *
+ *\param       flist List of filter rules.
+ *\param       info Message.
+ *
+ *\return      gboolean TRUE if filter rules handled the message.
+ *
+ *\note                Returning FALSE means the message was not handled,
+ *             and that the calling code should do the default
+ *             processing. E.g. \ref inc.c::inc_start moves the 
+ *             message to the inbox.   
+ */
 gboolean filter_message_by_msginfo(GSList *flist, MsgInfo *info)
 {
        return filter_msginfo(flist, info);
index 71f7688..91b6a2f 100644 (file)
@@ -166,6 +166,7 @@ void folder_init(Folder *folder, const gchar *name)
 
        /* Init folder data */
        folder->account = NULL;
+       folder->sort = 0;
        folder->inbox = NULL;
        folder->outbox = NULL;
        folder->draft = NULL;
@@ -175,17 +176,10 @@ void folder_init(Folder *folder, const gchar *name)
 
 void folder_destroy(Folder *folder)
 {
-       FolderUpdateData hookdata;
-
        g_return_if_fail(folder != NULL);
        g_return_if_fail(folder->klass->destroy_folder != NULL);
 
-       folder_list = g_list_remove(folder_list, folder);
-
-       hookdata.folder = folder;
-       hookdata.update_flags = FOLDER_DESTROY_FOLDER;
-       hookdata.item = NULL;
-       hooks_invoke(FOLDER_UPDATE_HOOKLIST, &hookdata);
+       folder_remove(folder);
 
        folder_tree_destroy(folder);
 
@@ -229,6 +223,8 @@ void folder_set_xml(Folder *folder, XMLTag *tag)
                } else if (!strcmp(attr->name, "collapsed")) {
                        if (rootitem != NULL)
                                rootitem->collapsed = *attr->value == '1' ? TRUE : FALSE;
+               } else if (!strcmp(attr->name, "sort")) {
+                       folder->sort = atoi(attr->value);
                }
        }
 }
@@ -248,6 +244,7 @@ XMLTag *folder_get_xml(Folder *folder)
 
                xml_tag_add_attr(tag, "collapsed", g_strdup(rootitem->collapsed ? "1" : "0"));
        }
+       xml_tag_add_attr(tag, "sort", g_strdup_printf("%d", folder->sort));
 
        return tag;
 }
@@ -281,7 +278,7 @@ FolderItem *folder_item_new(Folder *folder, const gchar *name, const gchar *path
        item->threaded  = TRUE;
        item->ret_rcpt  = FALSE;
        item->opened    = FALSE;
-       item->node = NULL;
+       item->node = g_node_new(item);
        item->folder = NULL;
        item->account = NULL;
        item->apply_sub = FALSE;
@@ -301,7 +298,7 @@ void folder_item_append(FolderItem *parent, FolderItem *item)
        g_return_if_fail(item != NULL);
 
        item->folder = parent->folder;
-       item->node = g_node_append_data(parent->node, item);
+       g_node_append(parent->node, item->node);
 }
 
 static gboolean folder_item_remove_func(GNode *node, gpointer data)
@@ -571,6 +568,17 @@ void folder_set_name(Folder *folder, const gchar *name)
        }
 }
 
+void folder_set_sort(Folder *folder, guint sort)
+{
+       g_return_if_fail(folder != NULL);
+
+       if (folder->sort != sort) {
+               folder_remove(folder);
+               folder->sort = sort;
+               folder_add(folder);
+       }
+}
+
 gboolean folder_tree_destroy_func(GNode *node, gpointer data) {
        FolderItem *item = (FolderItem *) node->data;
 
@@ -607,27 +615,28 @@ void folder_add(Folder *folder)
 
        for (i = 0, cur = folder_list; cur != NULL; cur = cur->next, i++) {
                cur_folder = FOLDER(cur->data);
-               if (FOLDER_TYPE(folder) == F_MH) {
-                       if (FOLDER_TYPE(cur_folder) != F_MH) break;
-               } else if (FOLDER_TYPE(folder) == F_MBOX) {
-                       if (FOLDER_TYPE(cur_folder) != F_MH &&
-                           FOLDER_TYPE(cur_folder) != F_MBOX) break;
-               } else if (FOLDER_TYPE(folder) == F_IMAP) {
-                       if (FOLDER_TYPE(cur_folder) != F_MH &&
-                           FOLDER_TYPE(cur_folder) != F_MBOX &&
-                           FOLDER_TYPE(cur_folder) != F_IMAP) break;
-               } else if (FOLDER_TYPE(folder) == F_NEWS) {
-                       if (FOLDER_TYPE(cur_folder) != F_MH &&
-                           FOLDER_TYPE(cur_folder) != F_MBOX &&
-                           FOLDER_TYPE(cur_folder) != F_IMAP &&
-                           FOLDER_TYPE(cur_folder) != F_NEWS) break;
-               }
+               if (cur_folder->sort < folder->sort)
+                       break;
        }
 
        folder_list = g_list_insert(folder_list, folder, i);
 
        hookdata.folder = folder;
-       hookdata.update_flags = FOLDER_NEW_FOLDER;
+       hookdata.update_flags = FOLDER_ADD_FOLDER;
+       hookdata.item = NULL;
+       hooks_invoke(FOLDER_UPDATE_HOOKLIST, &hookdata);
+}
+
+void folder_remove(Folder *folder)
+{
+       FolderUpdateData hookdata;
+
+       g_return_if_fail(folder != NULL);
+
+       folder_list = g_list_remove(folder_list, folder);
+
+       hookdata.folder = folder;
+       hookdata.update_flags = FOLDER_REMOVE_FOLDER;
        hookdata.item = NULL;
        hooks_invoke(FOLDER_UPDATE_HOOKLIST, &hookdata);
 }
@@ -766,14 +775,15 @@ void folder_scan_tree(Folder *folder)
 FolderItem *folder_create_folder(FolderItem *parent, const gchar *name)
 {
        FolderItem *new_item;
-       FolderUpdateData hookdata;
 
        new_item = parent->folder->klass->create_folder(parent->folder, parent, name);
        if (new_item) {
+               FolderUpdateData hookdata;
+
                new_item->cache = msgcache_new();
 
                hookdata.folder = new_item->folder;
-               hookdata.update_flags = FOLDER_TREE_CHANGED | FOLDER_NEW_FOLDERITEM;
+               hookdata.update_flags = FOLDER_TREE_CHANGED | FOLDER_ADD_FOLDERITEM;
                hookdata.item = new_item;
                hooks_invoke(FOLDER_UPDATE_HOOKLIST, &hookdata);
        }
@@ -781,6 +791,26 @@ FolderItem *folder_create_folder(FolderItem *parent, const gchar *name)
        return new_item;
 }
 
+gint folder_item_rename(FolderItem *item, gchar *newname)
+{
+       gint retval;
+
+       g_return_val_if_fail(item != NULL, -1);
+       g_return_val_if_fail(newname != NULL, -1);
+
+       retval = item->folder->klass->rename_folder(item->folder, item, newname);
+
+       if (retval >= 0) {
+               FolderItemUpdateData hookdata;
+
+               hookdata.item = item;
+               hookdata.update_flags = FOLDER_TREE_CHANGED;
+               hooks_invoke(FOLDER_ITEM_UPDATE_HOOKLIST, &hookdata);
+       }
+
+       return retval;
+}
+
 struct TotalMsgCount
 {
        guint new_msgs;
@@ -1022,6 +1052,20 @@ FolderItem *folder_find_item_from_path(const gchar *path)
        return d[1];
 }
 
+FolderItem *folder_find_child_item_by_name(FolderItem *item, const gchar *name)
+{
+       GNode *node;
+       FolderItem *child;
+
+       for (node = item->node->children; node != NULL; node = node->next) {
+               child = FOLDER_ITEM(node->data);
+               if (strcmp2(g_basename(child->path), name) == 0)
+                       return child;
+       }
+
+       return NULL;
+}
+
 FolderClass *folder_get_class_from_string(const gchar *str)
 {
        GSList *classlist;
@@ -1343,22 +1387,21 @@ static gint folder_sort_folder_list(gconstpointer a, gconstpointer b)
 
 gint folder_item_open(FolderItem *item)
 {
+       gchar *buf;
        if((item->folder->klass->scan_required != NULL) && (item->folder->klass->scan_required(item->folder, item))) {
                folder_item_scan_full(item, TRUE);
        }
-
+       folder_item_syncronize_flags(item);
+       
        /* Processing */
-       if(item->prefs->processing != NULL) {
-               gchar *buf;
-               
-               buf = g_strdup_printf(_("Processing (%s)...\n"), item->path);
-               debug_print("%s\n", buf);
-               g_free(buf);
+       buf = g_strdup_printf(_("Processing (%s)...\n"), 
+                             item->path ? item->path : item->name);
+       debug_print("%s\n", buf);
+       g_free(buf);
        
-               folder_item_apply_processing(item);
+       folder_item_apply_processing(item);
 
-               debug_print("done.\n");
-       }
+       debug_print("done.\n");
 
        return 0;
 }
@@ -1655,6 +1698,60 @@ gint folder_item_scan_full(FolderItem *item, gboolean filtering)
        return 0;
 }
 
+gint folder_item_syncronize_flags(FolderItem *item)
+{
+       MsgInfoList *msglist = NULL;
+       GSList *cur;
+       GRelation *relation;
+       gint ret = 0;
+       
+       g_return_val_if_fail(item != NULL, -1);
+       g_return_val_if_fail(item->folder != NULL, -1);
+       g_return_val_if_fail(item->folder->klass != NULL, -1);
+       if(item->folder->klass->get_flags == NULL)
+               return 0;
+       
+       if (item->cache == NULL)
+               folder_item_read_cache(item);
+       
+       msglist = msgcache_get_msg_list(item->cache);
+       
+       relation = g_relation_new(2);
+       g_relation_index(relation, 0, g_direct_hash, g_direct_equal);
+       if ((ret = item->folder->klass->get_flags(
+           item->folder, item, msglist, relation)) == 0) {
+               GTuples *tuples;
+               MsgInfo *msginfo;
+               MsgPermFlags permflags;
+               gboolean skip;
+
+               for (cur = msglist; cur != NULL; cur = g_slist_next(cur)) {
+                       msginfo = (MsgInfo *) cur->data;
+               
+                       tuples = g_relation_select(relation, msginfo, 0);
+                       skip = tuples->len < 1;
+                       if (!skip)
+                               permflags = GPOINTER_TO_INT(g_tuples_index(tuples, 0, 1));
+                       g_tuples_destroy(tuples);
+                       if (skip)
+                               continue;
+                       
+                       if (msginfo->flags.perm_flags != permflags) {
+                               procmsg_msginfo_set_flags(msginfo,
+                                       permflags & ~msginfo->flags.perm_flags, 0);
+                               procmsg_msginfo_unset_flags(msginfo,
+                                       ~permflags & msginfo->flags.perm_flags, 0);
+                       }
+               }
+       }
+       g_relation_destroy(relation);
+       
+       for (cur = msglist; cur != NULL; cur = g_slist_next(cur))
+               procmsg_msginfo_free((MsgInfo *) cur->data);
+       
+       return ret;
+}
+
 gint folder_item_scan(FolderItem *item)
 {
        return folder_item_scan_full(item, TRUE);
@@ -1770,16 +1867,20 @@ void folder_item_read_cache(FolderItem *item)
        
        g_return_if_fail(item != NULL);
 
-       cache_file = folder_item_get_cache_file(item);
-       mark_file = folder_item_get_mark_file(item);
-       item->cache = msgcache_read_cache(item, cache_file);
-       if (!item->cache) {
+       if (item->path != NULL) {
+               cache_file = folder_item_get_cache_file(item);
+               mark_file = folder_item_get_mark_file(item);
+               item->cache = msgcache_read_cache(item, cache_file);
+               if (!item->cache) {
+                       item->cache = msgcache_new();
+                       folder_item_scan_full(item, TRUE);
+               }
+               msgcache_read_mark(item->cache, mark_file);
+               g_free(cache_file);
+               g_free(mark_file);
+       } else {
                item->cache = msgcache_new();
-               folder_item_scan_full(item, TRUE);
        }
-       msgcache_read_mark(item->cache, mark_file);
-       g_free(cache_file);
-       g_free(mark_file);
 
        folder_clean_cache_memory();
 }
@@ -2394,9 +2495,6 @@ static gint do_copy_msgs(FolderItem *dest, GSList *msglist, gboolean remove_sour
                }
        }
 
-       if (folder->klass->finished_copy)
-               folder->klass->finished_copy(folder, dest);
-
        g_relation_destroy(relation);
        return lastnum;
 }
@@ -2530,9 +2628,6 @@ gint folder_item_remove_all_msg(FolderItem *item)
        result = folder->klass->remove_all_msg(folder, item);
 
        if (result == 0) {
-               if (folder->klass->finished_remove)
-                       folder->klass->finished_remove(folder, item);
-
                folder_item_free_cache(item);
                item->cache = msgcache_new();
 
index 0896a62..607a532 100644 (file)
@@ -1,3 +1,5 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+
 /*
  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
  * Copyright (C) 1999-2003 Hiroyuki Yamamoto
@@ -98,10 +100,10 @@ typedef enum
 
 typedef enum
 {
-       FOLDER_NEW_FOLDER               = 1 << 0,
-       FOLDER_DESTROY_FOLDER           = 1 << 1,
+       FOLDER_ADD_FOLDER               = 1 << 0,
+       FOLDER_REMOVE_FOLDER            = 1 << 1,
        FOLDER_TREE_CHANGED             = 1 << 2,
-       FOLDER_NEW_FOLDERITEM           = 1 << 3,
+       FOLDER_ADD_FOLDERITEM           = 1 << 3,
        FOLDER_REMOVE_FOLDERITEM        = 1 << 4,
 } FolderUpdateFlags;
 
@@ -109,6 +111,7 @@ typedef enum
 {
        F_ITEM_UPDATE_MSGCNT = 1 << 0,
        F_ITEM_UPDATE_CONTENT = 1 << 1,
+       F_ITEM_UPDATE_NAME = 1 << 2,
 } FolderItemUpdateFlags;
 
 typedef void (*FolderUIFunc)           (Folder         *folder,
@@ -117,7 +120,7 @@ typedef void (*FolderUIFunc)                (Folder         *folder,
 typedef void (*FolderDestroyNotify)    (Folder         *folder,
                                         FolderItem     *item,
                                         gpointer        data);
-typedef void (*FolderItemFunc)         (FolderItem     *item,
+typedef void (*FolderItemFunc) (FolderItem     *item,
                                         gpointer        data);
 
 
@@ -134,6 +137,7 @@ struct _Folder
 
        gchar *name;
        PrefsAccount *account;
+       guint sort;
 
        FolderItem *inbox;
        FolderItem *outbox;
@@ -153,95 +157,406 @@ struct _Folder
 
 struct _FolderClass
 {
+       /**
+        * A numeric identifier for the FolderClass. Will be removed in the future
+        */
        FolderType  type;
+       /**
+        * A string identifier for the FolderClass. Currently used in folderlist.xml.
+        * Should be lowercase.
+        */
        gchar      *idstr;
+       /**
+        * A string for the User Interface that identifies the FolderClass to the
+        * user. Can be upper and lowercase unlike the idstr.
+        */
        gchar      *uistr;
-
+       
        /* virtual functions */
 
        /* Folder funtions */
+       /**
+        * Create a new \c Folder of this \c FolderClass.
+        *
+        * \param name The name of the new Folder
+        * \param path The path of the new Folder
+        * \return The new \c Folder, or \c NULL when creating the \c Folder 
+        *         failed
+        */
        Folder          *(*new_folder)          (const gchar    *name,
                                                 const gchar    *path);
+       /**
+        * Destroy a \c Folder of this \c FolderClass, frees all resources
+        * allocated by the Folder
+        *
+        * \param folder The \c Folder that should be destroyed.
+        */
        void            (*destroy_folder)       (Folder         *folder);
+       /**
+        * Set the Folder's internal attributes from an \c XMLTag. Also sets the
+        * parameters of the root-FolderItem of the \c Folder. If \c NULL
+        * the default function of the basic \¢ FolderClass is used, so it
+        * must not be \c NULL if one of the parent \c FolderClasses has a \c set_xml
+        * function. In that case the parent \c FolderClass' \c set_xml function
+        * can be used or it has to be called with the \c folder and \c tag by
+        * the implementation.
+        *
+        * \param folder The \c Folder which's attributes should be updated
+        * \param tag The \c XMLTag containing the \c XMLAttrs for the attributes
+        */
        void             (*set_xml)             (Folder         *folder,
                                                 XMLTag         *tag);
+       /**
+        * Get an \c XMLTag for the attributes of the \c Folder and the root-FolderItem
+        * of the \c Folder. If \c NULL the default implementation for the basic
+        * FolderClass will be used, so it must not be \c NULL if one of the
+        * parent \c FolderClasses has it's own implementation for \c get_xml.
+        * In that case the parent FolderClass' \c get_xml function can be
+        * used or the \c XMLTag has to be fetched from the parent's \c get_xml
+        * function and then the \c FolderClass specific attributes can be
+        * added to it.
+        *
+        * \param Folder The \c Folder which's attributes should be set in the
+        *               \c XMLTag's \c XMLAttrs
+        * \return XMLTag An \c XMLTag with \c XMLAttrs containing the \c Folder's
+        *                attributes.
+        */
        XMLTag          *(*get_xml)             (Folder         *folder);
+       /**
+        * Rebuild the folder tree from the folder's data
+        * \todo New implementations of MH and IMAP are actually syncronizing
+        *       the tree with the folder by reusing the old \c FolderItems.
+        *       Claws still destroys the old tree before calling this function.
+        *
+        * \param folder The folder which's tree should be rebuild
+        * \return 0 on success, a negative number otherwise
+        */
        gint            (*scan_tree)            (Folder         *folder);
 
        gint            (*create_tree)          (Folder         *folder);
 
        /* FolderItem functions */
+       /**
+        * Create a new \c FolderItem structure for the \c FolderClass.
+        * \c FolderClasses can have their own \c FolderItem structure with
+        * extra attributes.
+        *
+        * \param folder The \c Folder for that a \c FolderItem should be
+        *               created
+        * \return The new \c FolderItem or NULL in case of an error
+        */
        FolderItem      *(*item_new)            (Folder         *folder);
+       /**
+        * Destroy a \c FolderItem from this \c FolderClass. The \c FolderClass
+        * has to free all private resources used by the \c FolderItem.
+        *
+        * \param folder The \c Folder of the \c FolderItem
+        * \param item The \c FolderItem that should be destroyed
+        */
        void             (*item_destroy)        (Folder         *folder,
                                                 FolderItem     *item);
+       /**
+        * Set the \c FolderItem's internal attributes from an \c XMLTag. If
+        * \c NULL the default function of the basic \c FolderClass is used, so it
+        * must not be \c NULL if one of the parent \c FolderClasses has a \c item_set_xml
+        * function. In that case the parent \c FolderClass' \c item_set_xml function
+        * can be used or it has to be called with the \c folder, \c item and \c tag by
+        * the implementation.
+        *
+        * \param folder The \c Folder of the \c FolderItem
+        * \param item The \c FolderItems which's attributes should be set
+        * \param tag The \c XMLTag with \c XMLAttrs for the \c FolderItem's
+        *            attributes
+        */
        void             (*item_set_xml)        (Folder         *folder,
                                                 FolderItem     *item,
                                                 XMLTag         *tag);
+       /**
+        * Get an \c XMLTag for the attributes of the \c FolderItem If \c NULL
+        * the default implementation for the basic \c FolderClass will be used,
+        * so it must not be \c NULL if one of the parent \c FolderClasses has
+        * it's own implementation for \c item_get_xml. In that case the parent 
+        * FolderClass' \c item_get_xml function can be used or the \c XMLTag
+        * has to be fetched from the parent's \c item_get_xml function and 
+        * then the \c FolderClass specific attributes can be added to it.
+        *
+        * \param folder The \c Folder of the \c FolderItem
+        * \parem item The \c FolderItem which's attributes should be set in
+        *             the \c XMLTag's \c XMLAttrs
+        * \return An \c XMLTag with \c XMLAttrs containing the \c FolderItem's
+        *         attributes.
+        */
        XMLTag          *(*item_get_xml)        (Folder         *folder,
                                                 FolderItem     *item);
+       /**
+        * Get a local path for the \c FolderItem where Sylpheed can save
+        * it's cache data. For local directory based folders this can be the
+        * real path. For other folders it can be the local cache directory.
+        *
+        * \param folder The \c Folder of the \c FolderItem
+        * \param item The \c FolderItem for that a path should be returned
+        * \return A path for the \c FolderItem
+        */
        gchar           *(*item_get_path)       (Folder         *folder,
                                                 FolderItem     *item);
+       /**
+        * Create a new \c FolderItem. The function must use folder_item_append
+        * to add the new \c FolderItem to the folder tree
+        *
+        * \param folder The \c Folder in which a new \c FolderItem should be
+        *               created
+        * \param parent \c The parent \c FolderItem for the new \c FolderItem
+        * \parem name The name for the new \c FolderItem
+        * \return The new \c FolderItem
+        */
        FolderItem      *(*create_folder)       (Folder         *folder,
                                                 FolderItem     *parent,
                                                 const gchar    *name);
+       /**
+        * Rename a \c FolderItem
+        *
+        * \param folder The \c Folder of the \c FolderItem that should be
+        *               renamed
+        * \param item The \c FolderItem that should be renamed
+        * \param name The new name of the \c FolderItem
+        * \return 0 on success, a negative number otherwise
+        */
        gint             (*rename_folder)       (Folder         *folder,
                                                 FolderItem     *item,
                                                 const gchar    *name);
+       /**
+        * Remove a \c FolderItem from the \c Folder
+        *
+        * \param folder The \c Folder that contains the \c FolderItem
+        * \param item The \c FolderItem that should be removed
+        * \return 0 on sucess, a negative number otherwise
+        */
        gint             (*remove_folder)       (Folder         *folder,
                                                 FolderItem     *item);
+       /**
+        * Close a \c FolderItem. Called when the user deselects a
+        * \c FolderItem.
+        * 
+        * \attention In Sylpheed-Main operations can only be done on the
+        *            \c FolderItem that is opened in the SummaryView. This
+        *            \c FolderItem will be closed when you select a new
+        *            \c FolderItem in the FolderView. In Claws operations can
+        *            be done any time on any folder and you should not expect
+        *            that all \c FolderItems get closed after operations
+        *
+        * \param folder The \c Folder that contains the \c FolderItem
+        * \param item The \c FolderItem that should be closed
+        * \return 0 on success, a negative number otherwise
+        */
        gint             (*close)               (Folder         *folder,
                                                 FolderItem     *item);
+       /**
+        * Get the list of message numbers for the messages in the \c FolderItem
+        *
+        * \param folder The \c Folder that contains the \c FolderItem
+        * \param item The \c FolderItem for which the message numbers should
+        *             be fetched
+        * \param list Pointer to a GSList where message numbers have to be
+        *             added. Because of the implementation of the GSList that
+        *             changes the pointer of the GSList itself when the first
+        *             item is added this is a pointer to a pointer to a
+        *             GSList structure. Use *item = g_slist_...(*item, ...)
+        *             operations to modify the list.
+        * \param old_uids_valid In some \c Folders the old UIDs can be invalid.
+        *                       Set this pointer to a gboolean to TRUE if the
+        *                       old UIDs are still valid, otherwise set it to
+        *                       FALSE and the folder system will discard it's
+        *                       cache data of the previously know UIDs
+        * \return The number of message numbers add to the list on success,
+        *         a negative number otherwise.
+        */
        gint             (*get_num_list)        (Folder         *folder,
                                                 FolderItem     *item,
                                                 GSList        **list,
                                                 gboolean       *old_uids_valid);
-       void            (*update_mark)          (Folder         *folder,
-                                                FolderItem     *item);
-       void            (*finished_copy)        (Folder         *folder,
-                                                FolderItem     *item);
-       void            (*finished_remove)      (Folder         *folder,
-                                                FolderItem     *item);
+       /**
+        * Tell the folder system if a \c FolderItem should be scanned
+        * (cache data syncronized with the folder content) when it is required
+        * because the \c FolderItem's content changed. If NULL the folder
+        * system will not do automatic scanning of \c FolderItems
+        *
+        * \param folder The \c Folder that contains the \c FolderItem
+        * \param item The \c FolderItem which's content should be checked
+        * \return TRUE if the \c FolderItem should be scanned, FALSE otherwise
+        */
        gboolean        (*scan_required)        (Folder         *folder,
                                                 FolderItem     *item);
 
        /* Message functions */
+       /**
+        * Get a MsgInfo for a message in a \c FolderItem
+        *
+        * \param folder The \c Folder containing the message
+        * \param item The \c FolderItem containing the message
+        * \param num The message number of the message
+        * \return A pointer to a \c MsgInfo decribing the message or \c 
+        *         NULL in case of an error
+        */
        MsgInfo         *(*get_msginfo)         (Folder         *folder,
                                                 FolderItem     *item,
                                                 gint            num);
-       GSList          *(*get_msginfos)        (Folder         *folder,
+       /**
+        * Get \c MsgInfos for a list of message numbers
+        *
+        * \param folder The \c Folder containing the message
+        * \param item The \c FolderItem containing the message
+        * \param msgnum_list A list of message numbers for which the
+        *                    \c MsgInfos should be fetched
+        * \return A list of \c MsgInfos for the messages in the \c msgnum_list
+        *         that really exist. Messages that are not found can simply
+        *         be left out.
+        */
+       MsgInfoList     *(*get_msginfos)        (Folder         *folder,
                                                 FolderItem     *item,
                                                 MsgNumberList  *msgnum_list);
-       /* return value is locale charset */
-       gchar           *(*fetch_msg)           (Folder         *folder,
+       /**
+        * Get the filename for a message. This can either be the real message
+        * file for local folders or a temporary file for remote folders.
+        *
+        * \param folder The \c Folder containing the message
+        * \param item The \c FolderItem containing the message
+        * \param num The message number of the message
+        * \return A string with the filename of the message file. The returned
+        *         string has to be freed with \c g_free(). If message is not
+        *         available return NULL.
+        */
+       gchar           *(*fetch_msg)           (Folder         *folder,
                                                 FolderItem     *item,
                                                 gint            num);
+       /**
+        * Add a single message file to a folder with the given flags (if
+        * flag handling is supported by the folder)
+        *
+        * \param folder The target \c Folder for the message
+        * \param dest the target \c FolderItem for the message
+        * \param file The file that contains the message
+        * \param flags The flags the new message should have in the folder
+        * \return 0 on success, a negative number otherwise
+        */
        gint            (*add_msg)              (Folder         *folder,
                                                 FolderItem     *dest,
                                                 const gchar    *file,
                                                 MsgFlags       *flags);
+       /**
+        * Add multiple messages to a \c FolderItem. If NULL the folder
+        * system will add messages with \c add_msg one by one
+        *
+        * \param folder The target \c Folder for the messages
+        * \param dest the target \c FolderItem for the messages
+        * \param file_list A list of \c MsgFileInfos which contain the
+        *                  filenames and flags for the new messages
+        * \param relation Insert tuples of (MsgFileInfo, new message number) to
+        *                 provide feedback for the folder system which new
+        *                 message number a \c MsgFileInfo got in dest. Insert
+        *                 0 if the new message number is unknown.
+        */
        gint            (*add_msgs)             (Folder         *folder,
                                                 FolderItem     *dest,
                                                 GSList         *file_list,
                                                 GRelation      *relation);
+       /**
+        * Copy a message to a FolderItem
+        *
+        * \param folder The \c Folder of the destination FolderItem
+        * \param dest The destination \c FolderItem for the message
+        * \param msginfo The message that should be copied
+        * \return The message number the copied message got, 0 if it is
+        *         unknown because message numbers are assigned by an external
+        *         system and not available after copying or a negative number
+        *         if an error occuried
+        */
        gint            (*copy_msg)             (Folder         *folder,
                                                 FolderItem     *dest,
                                                 MsgInfo        *msginfo);
+       /**
+        * Copy multiple messages to a \c FolderItem. If \c NULL the folder
+        * system will use \c copy_msg to copy messages one by one.
+        *
+        * \param folder The \c Folder of the destination FolderItem
+        * \param dest The destination \c FolderItem for the message
+        * \param msglist A list of \c MsgInfos which should be copied to dest
+        * \param relation Insert tuples of (MsgInfo, new message number) to
+        *                 provide feedback for the folder system which new
+        *                 message number a \c MsgInfo got in dest. Insert
+        *                 0 if the new message number is unknown.
+        * \return 0 on success, a negative number otherwise
+        */
        gint            (*copy_msgs)            (Folder         *folder,
                                                 FolderItem     *dest,
                                                 MsgInfoList    *msglist,
                                                 GRelation      *relation);
+       /**
+        * Remove a message from a \c FolderItem.
+        *
+        * \param folder The \c Folder of the message
+        * \param item The \c FolderItem containing the message
+        * \param num The message number of the message
+        * \return 0 on success, a negative number otherwise
+        */
        gint            (*remove_msg)           (Folder         *folder,
                                                 FolderItem     *item,
                                                 gint            num);
+       /**
+        * Remove all messages in a \ c FolderItem
+        *
+        * \param folder The \c Folder of the \c FolderItem
+        * \param item The \FolderItem which's messages should be deleted
+        * \return 0 on succes, a negative number otherwise
+        */
        gint            (*remove_all_msg)       (Folder         *folder,
                                                 FolderItem     *item);
+       /**
+        * Check if a message has been modified by someone else
+        *
+        * \param folder The \c Folder of the message
+        * \param item The \c FolderItem containing the message
+        * \param msginfo The \c MsgInfo for the message that should be checked
+        * \return \c TRUE if the message was modified, \c FALSE otherwise
+        */
        gboolean        (*is_msg_changed)       (Folder         *folder,
                                                 FolderItem     *item,
                                                 MsgInfo        *msginfo);
+       /**
+        * Update a message's flags in the folder data. If NULL only the
+        * internal flag management will be used. The function has to set
+        * \c msginfo->flags.perm_flags. It does not have to set the flags
+        * that it got as \c newflags. If a flag can not be set in this
+        * \c FolderClass the function can refuse to set it. Flags that are not
+        * supported by the \c FolderClass should not be refused. They will be
+        * managed by the internal cache in this case.
+        *
+        * \param folder The \c Folder of the message
+        * \param item The \c FolderItem of the message
+        * \param msginfo The \c MsgInfo for the message which's flags should be
+        *                updated
+        * \param newflags The flags the message should get
+        */
        void            (*change_flags)         (Folder         *folder,
                                                 FolderItem     *item,
                                                 MsgInfo        *msginfo,
                                                 MsgPermFlags    newflags);
+       /**
+        * Get the flags for a list of messages. Flags that are not supported
+        * by the folder should be preserved. They can be copied from
+        * \c msginfo->flags.perm_flags
+        *
+        * \param folder The \c Folder of the messages
+        * \param item The \c FolderItem of the messages
+        * \param msglist The list of \c MsgInfos for which the flags should
+        *                   be returned
+        * \param msgflags A \c GRelation for tuples of (MsgInfo, new permanent
+         *        flags for MsgInfo). Add tuples for the messages in msglist
+        * \return 0 on success, a negative number otherwise
+        */
+       gint            (*get_flags)            (Folder         *folder,
+                                                FolderItem     *item,
+                                                MsgInfoList    *msglist,
+                                                GRelation      *msgflags);
 };
 
 struct _FolderItem
@@ -353,15 +668,19 @@ void        folder_set_ui_func    (Folder         *folder,
                                 gpointer        data);
 void        folder_set_name    (Folder         *folder,
                                 const gchar    *name);
+void       folder_set_sort     (Folder         *folder,
+                                guint           sort);
 void        folder_tree_destroy        (Folder         *folder);
 
 void   folder_add              (Folder         *folder);
+void   folder_remove           (Folder         *folder);
 
 GList *folder_get_list         (void);
 gint   folder_read_list                (void);
 void   folder_write_list       (void);
 void   folder_scan_tree                (Folder *folder);
 FolderItem *folder_create_folder(FolderItem    *parent, const gchar *name);
+gint   folder_item_rename      (FolderItem *item, gchar *newname);
 void   folder_update_op_count          (void);
 void   folder_func_to_all_folders      (FolderItemFunc function,
                                         gpointer data);
@@ -377,6 +696,8 @@ Folder     *folder_find_from_name           (const gchar    *name,
                                                 FolderClass    *klass);
 FolderItem *folder_find_item_from_path         (const gchar    *path);
 FolderClass *folder_get_class_from_string      (const gchar    *str);
+FolderItem *folder_find_child_item_by_name     (FolderItem     *item,
+                                                const gchar    *name);
 gchar      *folder_get_identifier              (Folder         *folder);
 gchar      *folder_item_get_identifier         (FolderItem     *item);
 FolderItem *folder_find_item_from_identifier   (const gchar    *identifier);
index 1e5138c..893a5d7 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2003 Hiroyuki Yamamoto
+ * Copyright (C) 1999-2004 Hiroyuki Yamamoto
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -60,6 +60,7 @@ static GtkWidget *ok_button;
 static GtkWidget *cancel_button;
 
 static FolderItem *folder_item;
+static FolderItem *selected_item;
 
 static gboolean cancelled;
 static gboolean finished;
@@ -97,6 +98,8 @@ FolderItem *foldersel_folder_sel(Folder *cur_folder,
 {
        GtkCTreeNode *node;
 
+       selected_item = NULL;
+
        if (!window) {
                foldersel_create();
                foldersel_init();
@@ -132,9 +135,11 @@ FolderItem *foldersel_folder_sel(Folder *cur_folder,
        gtk_entry_set_text(GTK_ENTRY(entry), "");
        gtk_clist_clear(GTK_CLIST(ctree));
 
-       if (!cancelled && folder_item && folder_item->path)
+       if (!cancelled &&
+           selected_item && selected_item->path) {
+               folder_item = selected_item;
                return folder_item;
-       else
+       else
                return NULL;
 }
 
@@ -146,11 +151,10 @@ static void foldersel_create(void)
 
        window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
        gtk_window_set_title(GTK_WINDOW(window), _("Select folder"));
-       gtk_widget_set_size_request(window, 300, 400);
-       gtk_container_set_border_width(GTK_CONTAINER(window), BORDER_WIDTH);
+       gtk_container_set_border_width(GTK_CONTAINER(window), 4);
        gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
        gtk_window_set_modal(GTK_WINDOW(window), TRUE);
-       gtk_window_set_policy(GTK_WINDOW(window), TRUE, TRUE, TRUE);
+       gtk_window_set_policy(GTK_WINDOW(window), FALSE, TRUE, FALSE);
        gtk_window_set_wmclass
                (GTK_WINDOW(window), "folder_selection", "Sylpheed");
        g_signal_connect(G_OBJECT(window), "delete_event",
@@ -163,6 +167,7 @@ static void foldersel_create(void)
        gtk_container_add(GTK_CONTAINER(window), vbox);
 
        scrolledwin = gtk_scrolled_window_new(NULL, NULL);
+       gtk_widget_set_size_request(window, 300, 360);
        gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwin),
                                       GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
        gtk_box_pack_start(GTK_BOX(vbox), scrolledwin, TRUE, TRUE, 0);
@@ -185,6 +190,7 @@ static void foldersel_create(void)
                         G_CALLBACK(foldersel_selected), NULL);
 
        entry = gtk_entry_new();
+       gtk_entry_set_editable(GTK_ENTRY(entry), FALSE);
        gtk_box_pack_start(GTK_BOX(vbox), entry, FALSE, FALSE, 0);
        g_signal_connect(G_OBJECT(entry), "activate",
                         G_CALLBACK(foldersel_activated), NULL);
@@ -192,7 +198,7 @@ static void foldersel_create(void)
        gtkut_button_set_create(&confirm_area,
                                &ok_button,     _("OK"),
                                &cancel_button, _("Cancel"),
-                               NULL, NULL);
+                               NULL,           NULL);
 
        gtk_box_pack_end(GTK_BOX(vbox), confirm_area, FALSE, FALSE, 0);
        gtk_widget_grab_default(ok_button);
@@ -307,12 +313,16 @@ static void foldersel_set_tree(Folder *cur_folder, FolderSelectionType type)
 static void foldersel_selected(GtkCList *clist, gint row, gint column,
                               GdkEvent *event, gpointer data)
 {
-       FolderItem *item;
        GdkEventButton *ev = (GdkEventButton *)event;
 
-       item = gtk_clist_get_row_data(clist, row);
-       if (item) gtk_entry_set_text(GTK_ENTRY(entry),
-                                    item->path ? item->path : "");
+       selected_item = gtk_clist_get_row_data(clist, row);
+       if (selected_item && selected_item->path) {
+               gchar *id;
+               id = folder_item_get_identifier(selected_item);
+               gtk_entry_set_text(GTK_ENTRY(entry), id);
+               g_free(id);
+       } else
+               gtk_entry_set_text(GTK_ENTRY(entry), "");
 
        if (ev && GDK_2BUTTON_PRESS == ev->type)
                gtk_button_clicked(GTK_BUTTON(ok_button));
@@ -320,13 +330,6 @@ static void foldersel_selected(GtkCList *clist, gint row, gint column,
 
 static void foldersel_ok(GtkButton *button, gpointer data)
 {
-       GList *list;
-
-       list = GTK_CLIST(ctree)->selection;
-       if (list)
-               folder_item = gtk_ctree_node_get_row_data
-                       (GTK_CTREE(ctree), GTK_CTREE_NODE(list->data));
-
        finished = TRUE;
 }
 
index 099631b..0396372 100644 (file)
 #include "prefs_common.h"
 #include "folderutils.h"
 
-void folderutils_delete_duplicates(FolderItem *item)
+gint folderutils_delete_duplicates(FolderItem *item,
+                                  DeleteDuplicatesMode mode)
 {
        GHashTable *table;
        GSList *msglist, *cur, *duplist = NULL;
-
+       guint dups;
+       
+       if (item->folder->klass->remove_msg == NULL)
+               return -1;
+       
        debug_print("Deleting duplicated messages...\n");
 
        msglist = folder_item_get_msg_list(item);
        if (msglist == NULL)
-               return;
+               return 0;
        table = g_hash_table_new(g_str_hash, g_str_equal);
 
        for (cur = msglist; cur != NULL; cur = g_slist_next(cur)) {
@@ -56,22 +61,31 @@ void folderutils_delete_duplicates(FolderItem *item)
                }
        }
 
-       if (prefs_common.immediate_exec) {
-               FolderItem *trash = item->folder->trash;
+       if (duplist) {
+               switch (mode) {
+               case DELETE_DUPLICATES_REMOVE: {
+                       FolderItem *trash = item->folder->trash;
 
-               if (item->stype == F_TRASH || trash == NULL)
-                       folder_item_remove_msgs(item, duplist);
-               else
-                       folder_item_move_msgs(trash, duplist);
-       } else {
-               for (cur = duplist; cur != NULL; cur = g_slist_next(cur)) {
-                       MsgInfo *msginfo = (MsgInfo *) cur->data;
+                       if (item->stype == F_TRASH || trash == NULL)
+                               folder_item_remove_msgs(item, duplist);
+                       else                    
+                               folder_item_move_msgs(trash, duplist);
+                       break;
+               }
+               case DELETE_DUPLICATES_SETFLAG:
+                       for (cur = duplist; cur != NULL; cur = g_slist_next(cur)) {
+                               MsgInfo *msginfo = (MsgInfo *) cur->data;
 
-                       procmsg_msginfo_set_to_folder(msginfo, NULL);
-                       procmsg_msginfo_unset_flags(msginfo, MSG_MARKED, MSG_MOVE | MSG_COPY);
-                       procmsg_msginfo_set_flags(msginfo, MSG_DELETED, 0);
+                               procmsg_msginfo_set_to_folder(msginfo, NULL);
+                               procmsg_msginfo_unset_flags(msginfo, MSG_MARKED, MSG_MOVE | MSG_COPY);
+                               procmsg_msginfo_set_flags(msginfo, MSG_DELETED, 0);
+                       }
+                       break;
+               default:
+                       break;
                }
        }
+       dups = g_slist_length(duplist);
        g_slist_free(duplist);
 
        g_hash_table_destroy(table);
@@ -83,6 +97,30 @@ void folderutils_delete_duplicates(FolderItem *item)
        }
        g_slist_free(msglist);
 
-
        debug_print("done.\n");
+
+       return dups;    
+}
+
+void folderutils_mark_all_read(FolderItem *item)
+{
+       MsgInfoList *msglist, *cur;
+
+       g_return_if_fail(item != NULL);
+
+       msglist = folder_item_get_msg_list(item);
+       if (msglist == NULL)
+               return;
+
+       folder_item_update_freeze();
+       for (cur = msglist; cur != NULL; cur = g_slist_next(cur)) {
+               MsgInfo *msginfo = cur->data;
+
+               if (msginfo->flags.perm_flags & (MSG_NEW | MSG_UNREAD))
+                       procmsg_msginfo_unset_flags(msginfo, MSG_NEW | MSG_UNREAD, 0);
+               procmsg_msginfo_free(msginfo);
+       }
+       folder_item_update_thaw();
+
+       g_slist_free(msglist);
 }
index 2c2d96b..7fdb1e8 100644 (file)
 #ifndef FOLDERUTILS_H
 #define FOLDERUTILS_H 1
 
+typedef enum {
+       DELETE_DUPLICATES_REMOVE,
+       DELETE_DUPLICATES_SETFLAG,
+} DeleteDuplicatesMode;
+
 #include "folder.h"
 
-void folderutils_delete_duplicates(FolderItem *item);
+gint folderutils_delete_duplicates(FolderItem *item,
+                                  DeleteDuplicatesMode mode);
+void folderutils_mark_all_read   (FolderItem *item);
 
 #endif /* FOLDERUTILS_H */
index 71caae3..ba7cbef 100644 (file)
@@ -44,7 +44,6 @@
 #include "summaryview.h"
 #include "summary_search.h"
 #include "inputdialog.h"
-#include "grouplistdialog.h"
 #include "manage_window.h"
 #include "alertpanel.h"
 #include "menu.h"
@@ -62,6 +61,7 @@
 #include "inc.h"
 #include "statusbar.h"
 #include "hooks.h"
+#include "folderutils.h"
 
 typedef enum
 {
@@ -143,15 +143,9 @@ static void folderview_append_folder        (FolderView    *folderview,
 static void folderview_update_node      (FolderView    *folderview,
                                          GtkCTreeNode  *node);
 
-static GtkCTreeNode *folderview_find_by_name   (GtkCTree       *ctree,
-                                                GtkCTreeNode   *node,
-                                                const gchar    *name);
-
 static gint folderview_clist_compare   (GtkCList       *clist,
                                         gconstpointer   ptr1,
                                         gconstpointer   ptr2);
-static gint folderview_compare_name    (gconstpointer   a,
-                                        gconstpointer   b);
 
 /* callback functions */
 static gboolean folderview_button_pressed      (GtkWidget      *ctree,
@@ -180,56 +174,9 @@ static void folderview_col_resized (GtkCList       *clist,
                                         gint            width,
                                         FolderView     *folderview);
 
-static void folderview_download_cb     (FolderView     *folderview,
-                                        guint           action,
-                                        GtkWidget      *widget);
-
-static void folderview_update_tree_cb  (FolderView     *folderview,
-                                        guint           action,
-                                        GtkWidget      *widget);
-
 static void mark_all_read_cb            (FolderView    *folderview,
                                          guint           action,
                                          GtkWidget      *widget);
-static void folderview_new_folder_cb   (FolderView     *folderview,
-                                        guint           action,
-                                        GtkWidget      *widget);
-#if 0
-static void folderview_new_mbox_folder_cb(FolderView *folderview,
-                                         guint action,
-                                         GtkWidget *widget);
-#endif
-static void folderview_rename_folder_cb        (FolderView     *folderview,
-                                        guint           action,
-                                        GtkWidget      *widget);
-#if 0
-static void folderview_rename_mbox_folder_cb(FolderView *folderview,
-                                            guint action,
-                                            GtkWidget *widget);
-#endif
-static void folderview_delete_folder_cb        (FolderView     *folderview,
-                                        guint           action,
-                                        GtkWidget      *widget);
-static void folderview_remove_mailbox_cb(FolderView    *folderview,
-                                        guint           action,
-                                        GtkWidget      *widget);
-
-static void folderview_new_imap_folder_cb(FolderView   *folderview,
-                                         guint          action,
-                                         GtkWidget     *widget);
-static void folderview_rm_imap_server_cb (FolderView   *folderview,
-                                         guint          action,
-                                         GtkWidget     *widget);
-
-static void folderview_new_news_group_cb(FolderView    *folderview,
-                                        guint           action,
-                                        GtkWidget      *widget);
-static void folderview_rm_news_group_cb        (FolderView     *folderview,
-                                        guint           action,
-                                        GtkWidget      *widget);
-static void folderview_rm_news_server_cb(FolderView    *folderview,
-                                        guint           action,
-                                        GtkWidget      *widget);
 
 static void folderview_search_cb       (FolderView     *folderview,
                                         guint           action,
@@ -273,96 +220,84 @@ void folderview_create_folder_node       (FolderView       *folderview,
                                          FolderItem       *item);
 gboolean folderview_update_folder       (gpointer          source,
                                          gpointer          userdata);
-gboolean folderview_update_item                 (gpointer          source,
+gboolean folderview_update_item_claws   (gpointer          source,
                                          gpointer          data);
-
 static void folderview_processing_cb(FolderView *folderview, guint action,
                                     GtkWidget *widget);
-static void folderview_move_to(FolderView *folderview, FolderItem *from_folder,
-                              FolderItem *to_folder);
-static void folderview_move_to_cb(FolderView *folderview);
-
-#if 0
-static GtkItemFactoryEntry folderview_mbox_popup_entries[] =
-{
-       {N_("/Create _new folder..."),  NULL, folderview_new_mbox_folder_cb,    0, NULL},
-       {N_("/_Rename folder..."),      NULL, folderview_rename_mbox_folder_cb, 0, NULL},
-       {N_("/M_ove folder..."),        NULL, folderview_move_to_cb, 0, NULL},
-       {N_("/_Delete folder"),         NULL, folderview_delete_folder_cb, 0, NULL},
-       {N_("/---"),                    NULL, NULL, 0, "<Separator>"},
-       {N_("/Remove _mailbox"),        NULL, folderview_remove_mailbox_cb, 0, NULL},
-       {N_("/---"),                    NULL, NULL, 0, "<Separator>"},
-       {N_("/_Properties..."),         NULL, NULL, 0, NULL},
-       {N_("/_Processing..."),         NULL, folderview_processing_cb, 0, NULL},
-};
-#endif
 
-static GtkItemFactoryEntry folderview_mail_popup_entries[] =
+GHashTable *folderview_popups;
+
+static GtkItemFactoryEntry folderview_common_popup_entries[] =
 {
        {N_("/Mark all _read"),         NULL, mark_all_read_cb, 0, NULL},
-       {N_("/---"),                    NULL, NULL, 0, "<Separator>"},
-       {N_("/Create _new folder..."),  NULL, folderview_new_folder_cb,    0, NULL},
-       {N_("/_Rename folder..."),      NULL, folderview_rename_folder_cb, 0, NULL},
-       {N_("/M_ove folder..."),        NULL, folderview_move_to_cb, 0, NULL},
-       {N_("/_Delete folder"),         NULL, folderview_delete_folder_cb, 0, NULL},
-       {N_("/---"),                    NULL, NULL, 0, "<Separator>"},
-       {N_("/_Check for new messages"),
-                                       NULL, folderview_update_tree_cb, 0, NULL},
-       {N_("/R_ebuild folder tree"),   NULL, folderview_update_tree_cb, 1, NULL},
-       {N_("/---"),                    NULL, NULL, 0, "<Separator>"},
-       {N_("/Remove _mailbox"),        NULL, folderview_remove_mailbox_cb, 0, NULL},
-       {N_("/---"),                    NULL, NULL, 0, "<Separator>"},
        {N_("/_Search folder..."),      NULL, folderview_search_cb, 0, NULL},
        {N_("/_Properties..."),         NULL, folderview_property_cb, 0, NULL},
        {N_("/_Processing..."),         NULL, folderview_processing_cb, 0, NULL},
 };
 
-static GtkItemFactoryEntry folderview_imap_popup_entries[] =
+GtkTargetEntry folderview_drag_types[] =
 {
-       {N_("/Mark all _read"),         NULL, mark_all_read_cb, 0, NULL},
-       {N_("/---"),                    NULL, NULL, 0, "<Separator>"},
-       {N_("/Create _new folder..."),  NULL, folderview_new_imap_folder_cb, 0, NULL},
-       {N_("/_Rename folder..."),      NULL, folderview_rename_folder_cb,   0, NULL},
-       {N_("/M_ove folder..."),        NULL, folderview_move_to_cb, 0, NULL},
-       {N_("/_Delete folder"),         NULL, folderview_delete_folder_cb,   0, NULL},
-       {N_("/---"),                    NULL, NULL, 0, "<Separator>"},
-       {N_("/Down_load"),              NULL, folderview_download_cb, 0, NULL},
-       {N_("/---"),                    NULL, NULL, 0, "<Separator>"},
-       {N_("/_Check for new messages"),
-                                       NULL, folderview_update_tree_cb, 0, NULL},
-       {N_("/R_ebuild folder tree"),   NULL, folderview_update_tree_cb, 1, NULL},
-       {N_("/---"),                    NULL, NULL, 0, "<Separator>"},
-       {N_("/Remove _IMAP4 account"),  NULL, folderview_rm_imap_server_cb, 0, NULL},
-       {N_("/---"),                    NULL, NULL, 0, "<Separator>"},
-       {N_("/_Search folder..."),      NULL, folderview_search_cb, 0, NULL},
-       {N_("/_Properties..."),         NULL, folderview_property_cb, 0, NULL},
-       {N_("/_Processing..."),         NULL, folderview_processing_cb, 0, NULL},
+       {"text/plain", GTK_TARGET_SAME_APP, TARGET_DUMMY}
 };
 
-static GtkItemFactoryEntry folderview_news_popup_entries[] =
+void folderview_initialize(void)
 {
-       {N_("/Mark all _read"),         NULL, mark_all_read_cb, 0, NULL},
-       {N_("/---"),                    NULL, NULL, 0, "<Separator>"},
-       {N_("/_Subscribe to newsgroup..."),
-                                       NULL, folderview_new_news_group_cb, 0, NULL},
-       {N_("/_Remove newsgroup"),      NULL, folderview_rm_news_group_cb, 0, NULL},
-       {N_("/---"),                    NULL, NULL, 0, "<Separator>"},
-       {N_("/Down_load"),              NULL, folderview_download_cb, 0, NULL},
-       {N_("/---"),                    NULL, NULL, 0, "<Separator>"},
-       {N_("/_Check for new messages"),
-                                       NULL, folderview_update_tree_cb, 0, NULL},
-       {N_("/---"),                    NULL, NULL, 0, "<Separator>"},
-       {N_("/Remove _news account"),   NULL, folderview_rm_news_server_cb, 0, NULL},
-       {N_("/---"),                    NULL, NULL, 0, "<Separator>"},
-       {N_("/_Search folder..."),      NULL, folderview_search_cb, 0, NULL},
-       {N_("/_Properties..."),         NULL, folderview_property_cb, 0, NULL},
-       {N_("/_Processing..."),         NULL, folderview_processing_cb, 0, NULL},
-};
+       FolderViewPopup *fpopup;
+       guint i, n_entries;
+       GSList *entries = NULL;
 
-GtkTargetEntry folderview_drag_types[] =
+       fpopup = g_new0(FolderViewPopup, 1);
+
+       n_entries = sizeof(folderview_common_popup_entries) /
+               sizeof(folderview_common_popup_entries[0]);
+       for (i = 0; i < n_entries; i++)
+               entries = g_slist_append(entries, &folderview_common_popup_entries[i]);
+
+       fpopup->klass = "common";
+       fpopup->path = "<CommonFolder>";
+       fpopup->entries = entries;
+       fpopup->set_sensitivity = NULL;
+
+       folderview_popups = g_hash_table_new(g_str_hash, g_str_equal);
+       g_hash_table_insert(folderview_popups, "common", fpopup);
+}
+
+static GtkItemFactory *create_ifactory(FolderView *folderview, FolderViewPopup *fpopup)
 {
-       {"text/plain", GTK_TARGET_SAME_APP, TARGET_DUMMY}
-};
+       GSList *entries;
+       GtkItemFactory *factory;
+       FolderViewPopup *fpopup_common;
+       GtkWidget *popup;
+
+       factory = gtk_item_factory_new(GTK_TYPE_MENU, fpopup->path, NULL);
+       gtk_item_factory_set_translate_func(factory, menu_translate,
+                                           NULL, NULL);
+
+       for (entries = fpopup->entries; entries != NULL; entries = g_slist_next(entries))
+               gtk_item_factory_create_item(factory, entries->data, folderview, 1);
+
+       fpopup_common = g_hash_table_lookup(folderview_popups, "common");
+       if (fpopup_common != fpopup)
+               for (entries = fpopup_common->entries; entries != NULL; entries = g_slist_next(entries))
+                       gtk_item_factory_create_item(factory, entries->data, folderview, 1);
+
+       popup = gtk_item_factory_get_widget(factory, fpopup->path);
+        gtk_signal_connect(GTK_OBJECT(popup), "selection_done",
+                           GTK_SIGNAL_FUNC(folderview_popup_close),
+                           folderview);
+
+       return factory;
+}
+
+static void create_ifactories(gpointer key, gpointer value, gpointer data)
+{
+       FolderView *folderview = data;
+       FolderViewPopup *fpopup = value;
+       GtkItemFactory *factory;
+
+       factory = create_ifactory(folderview, fpopup);
+       g_hash_table_insert(folderview->popups, fpopup->klass, factory);
+}
 
 FolderView *folderview_create(void)
 {
@@ -370,19 +305,6 @@ FolderView *folderview_create(void)
        GtkWidget *scrolledwin;
        GtkWidget *ctree;
        gchar *titles[N_FOLDER_COLS];
-       GtkWidget *mail_popup;
-       GtkWidget *news_popup;
-       GtkWidget *imap_popup;
-#if 0
-       GtkWidget *mbox_popup;
-#endif
-       GtkItemFactory *mail_factory;
-       GtkItemFactory *news_factory;
-       GtkItemFactory *imap_factory;
-#if 0
-       GtkItemFactory *mbox_factory;
-#endif
-       gint n_entries;
        gint i;
 
        debug_print("Creating folder view...\n");
@@ -428,38 +350,15 @@ FolderView *folderview_create(void)
        gtk_ctree_set_indent(GTK_CTREE(ctree), CTREE_INDENT);
        gtk_clist_set_compare_func(GTK_CLIST(ctree), folderview_clist_compare);
 
+       /* create popup factories */
+       folderview->popups = g_hash_table_new(g_str_hash, g_str_equal);
+       g_hash_table_foreach(folderview_popups, create_ifactories, folderview);
+
        /* don't let title buttons take key focus */
        for (i = 0; i < N_FOLDER_COLS; i++)
                GTK_WIDGET_UNSET_FLAGS(GTK_CLIST(ctree)->column[i].button,
                                       GTK_CAN_FOCUS);
 
-       /* popup menu */
-       n_entries = sizeof(folderview_mail_popup_entries) /
-               sizeof(folderview_mail_popup_entries[0]);
-       mail_popup = menu_create_items(folderview_mail_popup_entries,
-                                      n_entries,
-                                      "<MailFolder>", &mail_factory,
-                                      folderview);
-       n_entries = sizeof(folderview_imap_popup_entries) /
-               sizeof(folderview_imap_popup_entries[0]);
-       imap_popup = menu_create_items(folderview_imap_popup_entries,
-                                      n_entries,
-                                      "<IMAPFolder>", &imap_factory,
-                                      folderview);
-       n_entries = sizeof(folderview_news_popup_entries) /
-               sizeof(folderview_news_popup_entries[0]);
-       news_popup = menu_create_items(folderview_news_popup_entries,
-                                      n_entries,
-                                      "<NewsFolder>", &news_factory,
-                                      folderview);
-#if 0
-       n_entries = sizeof(folderview_mbox_popup_entries) /
-               sizeof(folderview_mbox_popup_entries[0]);
-       mbox_popup = menu_create_items(folderview_mbox_popup_entries,
-                                      n_entries,
-                                      "<MboxFolder>", &mbox_factory,
-                                      folderview);
-#endif
 
        g_signal_connect(G_OBJECT(ctree), "key_press_event",
                         G_CALLBACK(folderview_key_pressed),
@@ -489,21 +388,6 @@ FolderView *folderview_create(void)
                         G_CALLBACK(folderview_col_resized),
                         folderview);
 
-       g_signal_connect(G_OBJECT(mail_popup), "selection_done",
-                        G_CALLBACK(folderview_popup_close),
-                        folderview);
-       g_signal_connect(G_OBJECT(imap_popup), "selection_done",
-                        G_CALLBACK(folderview_popup_close),
-                        folderview);
-       g_signal_connect(G_OBJECT(news_popup), "selection_done",
-                        G_CALLBACK(folderview_popup_close),
-                        folderview);
-#if 0
-       g_signal_connect(G_OBJECT(mbox_popup), "selection_done",
-                        G_CALLBACK(folderview_popup_close),
-                        folderview);
-#endif
-
         /* drop callback */
        gtk_drag_dest_set(ctree, GTK_DEST_DEFAULT_ALL & ~GTK_DEST_DEFAULT_HIGHLIGHT,
                          summary_drag_types, 1,
@@ -523,21 +407,11 @@ FolderView *folderview_create(void)
 
        folderview->scrolledwin  = scrolledwin;
        folderview->ctree        = ctree;
-       folderview->mail_popup   = mail_popup;
-       folderview->mail_factory = mail_factory;
-       folderview->imap_popup   = imap_popup;
-       folderview->imap_factory = imap_factory;
-       folderview->news_popup   = news_popup;
-       folderview->news_factory = news_factory;
-#if 0
-       folderview->mbox_popup   = mbox_popup;
-       folderview->mbox_factory = mbox_factory;
-#endif
 
        folderview->folder_update_callback_id =
                hooks_register_hook(FOLDER_UPDATE_HOOKLIST, folderview_update_folder, (gpointer) folderview);
        folderview->folder_item_update_callback_id =
-               hooks_register_hook(FOLDER_ITEM_UPDATE_HOOKLIST, folderview_update_item, (gpointer) folderview);
+               hooks_register_hook(FOLDER_ITEM_UPDATE_HOOKLIST, folderview_update_item_claws, (gpointer) folderview);
 
        gtk_widget_show_all(scrolledwin);
 
@@ -689,8 +563,13 @@ void folderview_select(FolderView *folderview, FolderItem *item)
 static void mark_all_read_cb(FolderView *folderview, guint action,
                              GtkWidget *widget)
 {
-       if (folderview->selected)
-               summary_mark_all_read(folderview->summaryview);
+       FolderItem *item;
+
+       item = folderview_get_selected(folderview);
+       if (item == NULL)
+               return;
+
+       folderutils_mark_all_read(item);
 }
 
 static void folderview_select_node(FolderView *folderview, GtkCTreeNode *node)
@@ -783,6 +662,48 @@ void folderview_update_msg_num(FolderView *folderview, GtkCTreeNode *row)
        folderview_update_node(folderview, row);
 }
 
+void folderview_append_item(FolderItem *item)
+{
+       GList *list;
+
+       g_return_if_fail(item != NULL);
+       g_return_if_fail(item->folder != NULL);
+       if (folder_item_parent(item)) return;
+
+       for (list = folderview_list; list != NULL; list = list->next) {
+               FolderView *folderview = (FolderView *)list->data;
+               GtkCTree *ctree = GTK_CTREE(folderview->ctree);
+               GtkCTreeNode *node, *child;
+
+               node = gtk_ctree_find_by_row_data(ctree, NULL, 
+                                                 folder_item_parent(item));
+               if (node) {
+                       child = gtk_ctree_find_by_row_data(ctree, node, item);
+                       if (!child) {
+                               gchar *text[N_FOLDER_COLS] =
+                                       {NULL, "0", "0", "0"};
+
+                               gtk_clist_freeze(GTK_CLIST(ctree));
+
+                               text[COL_FOLDER] = item->name;
+                               child = gtk_ctree_insert_node
+                                       (ctree, node, NULL, text,
+                                        FOLDER_SPACING,
+                                        folderxpm, folderxpmmask,
+                                        folderopenxpm, folderopenxpmmask,
+                                        FALSE, FALSE);
+                               gtk_ctree_node_set_row_data(ctree, child, item);
+                               gtk_ctree_expand(ctree, node);
+                               folderview_update_node(folderview, child);
+                               folderview_sort_folders(folderview, node,
+                                                       item->folder);
+
+                               gtk_clist_thaw(GTK_CLIST(ctree));
+                       }
+               }
+       }
+}
+
 static void folderview_set_folders(FolderView *folderview)
 {
        GList *list;
@@ -1235,7 +1156,32 @@ static void folderview_update_node(FolderView *folderview, GtkCTreeNode *node)
                folderview_update_node(folderview, node);
 }
 
-gboolean folderview_update_item(gpointer source, gpointer data)
+#if !CLAWS /* keep it here for syncs */
+void folderview_update_item(FolderItem *item, gboolean update_summary)
+{
+       GList *list;
+       FolderView *folderview;
+       GtkCTree *ctree;
+       GtkCTreeNode *node;
+
+       g_return_if_fail(item != NULL);
+
+       for (list = folderview_list; list != NULL; list = list->next) {
+               folderview = (FolderView *)list->data;
+               ctree = GTK_CTREE(folderview->ctree);
+
+               node = gtk_ctree_find_by_row_data(ctree, NULL, item);
+               if (node) {
+                       folderview_update_node(folderview, node);
+                       if (update_summary && folderview->opened == node)
+                               summary_show(folderview->summaryview,
+                                            item, FALSE);
+               }
+       }
+}
+#endif
+
+gboolean folderview_update_item_claws(gpointer source, gpointer data)
 {
        FolderItemUpdateData *update_info = (FolderItemUpdateData *)source;
        FolderView *folderview = (FolderView *)data;
@@ -1250,7 +1196,7 @@ gboolean folderview_update_item(gpointer source, gpointer data)
 
        node = gtk_ctree_find_by_row_data(ctree, NULL, update_info->item);
        if (node) {
-               if (update_info->update_flags & F_ITEM_UPDATE_MSGCNT)
+               if (update_info->update_flags & (F_ITEM_UPDATE_MSGCNT | F_ITEM_UPDATE_NAME))
                        folderview_update_node(folderview, node);
                if ((update_info->update_flags & F_ITEM_UPDATE_CONTENT) && (folderview->opened == node))
                        summary_show(folderview->summaryview, update_info->item);
@@ -1259,6 +1205,26 @@ gboolean folderview_update_item(gpointer source, gpointer data)
        return FALSE;
 }
 
+static void folderview_update_item_foreach_func(gpointer key, gpointer val,
+                                               gpointer data)
+{
+       /* CLAWS: share this joy with other hook functions ... */
+       folder_item_update((FolderItem *)key, 
+                          (FolderItemUpdateFlags)GPOINTER_TO_INT(data));
+}
+
+void folderview_update_item_foreach(GHashTable *table, gboolean update_summary)
+{
+       GList *list;
+       FolderItemUpdateFlags flags;
+       
+       flags = update_summary ?  F_ITEM_UPDATE_CONTENT | F_ITEM_UPDATE_MSGCNT
+               : 0;
+       for (list = folderview_list; list != NULL; list = list->next)
+               g_hash_table_foreach(table, folderview_update_item_foreach_func, 
+                                    GINT_TO_POINTER(flags));
+}
+
 static gboolean folderview_gnode_func(GtkCTree *ctree, guint depth,
                                      GNode *gnode, GtkCTreeNode *cnode,
                                      gpointer data)
@@ -1291,36 +1257,37 @@ static void folderview_expand_func(GtkCTree *ctree, GtkCTreeNode *node,
        }
 }
 
-#define SET_SPECIAL_FOLDER(ctree, item) \
-{ \
-       if (item) { \
-               GtkCTreeNode *node, *parent, *sibling; \
- \
-               node = gtk_ctree_find_by_row_data(ctree, root, item); \
-               if (!node) \
-                       g_warning("%s not found.\n", item->path); \
-               else { \
-                       parent = GTK_CTREE_ROW(node)->parent; \
-                       if (prev && parent == GTK_CTREE_ROW(prev)->parent) \
-                               sibling = GTK_CTREE_ROW(prev)->sibling; \
-                       else \
-                               sibling = GTK_CTREE_ROW(parent)->children; \
-                       while (sibling) { \
-                               FolderItem *tmp; \
- \
-                               tmp = gtk_ctree_node_get_row_data \
-                                       (ctree, sibling); \
-                               if (tmp->stype != F_NORMAL) \
-                                       sibling = GTK_CTREE_ROW(sibling)->sibling; \
-                               else \
-                                       break; \
-                       } \
-                       if (node != sibling) \
-                               gtk_ctree_move(ctree, node, parent, sibling); \
-               } \
- \
-               prev = node; \
-       } \
+static void set_special_folder(GtkCTree *ctree, FolderItem *item,
+                              GtkCTreeNode *root, GtkCTreeNode **prev)
+{
+       if (item) {
+               GtkCTreeNode *node, *parent, *sibling;
+
+               node = gtk_ctree_find_by_row_data(ctree, root, item);
+               if (!node)
+                       g_warning("%s not found.\n", item->path);
+               else {
+                       parent = GTK_CTREE_ROW(node)->parent;
+                       if (*prev && parent == GTK_CTREE_ROW(*prev)->parent)
+                               sibling = GTK_CTREE_ROW(*prev)->sibling;
+                       else
+                               sibling = GTK_CTREE_ROW(parent)->children;
+                       while (sibling) {
+                               FolderItem *tmp;
+
+                               tmp = gtk_ctree_node_get_row_data
+                                       (ctree, sibling);
+                               if (tmp->stype != F_NORMAL)
+                                       sibling = GTK_CTREE_ROW(sibling)->sibling;
+                               else
+                                       break;
+                       }
+                       if (node != sibling)
+                               gtk_ctree_move(ctree, node, parent, sibling);
+               }
+
+               *prev = node;
+       }
 }
 
 static void folderview_sort_folders(FolderView *folderview, GtkCTreeNode *root,
@@ -1333,11 +1300,11 @@ static void folderview_sort_folders(FolderView *folderview, GtkCTreeNode *root,
 
        if (root && GTK_CTREE_ROW(root)->parent) return;
 
-       SET_SPECIAL_FOLDER(ctree, folder->inbox);
-       SET_SPECIAL_FOLDER(ctree, folder->outbox);
-       SET_SPECIAL_FOLDER(ctree, folder->draft);
-       SET_SPECIAL_FOLDER(ctree, folder->queue);
-       SET_SPECIAL_FOLDER(ctree, folder->trash);
+       set_special_folder(ctree, folder->inbox, root, &prev);
+       set_special_folder(ctree, folder->outbox, root, &prev);
+       set_special_folder(ctree, folder->draft, root, &prev);
+       set_special_folder(ctree, folder->queue, root, &prev);
+       set_special_folder(ctree, folder->trash, root, &prev);
 }
 
 static void folderview_append_folder(FolderView *folderview, Folder *folder)
@@ -1354,95 +1321,6 @@ static void folderview_append_folder(FolderView *folderview, Folder *folder)
        folderview_sort_folders(folderview, root, folder);
 }
 
-void folderview_new_folder(FolderView *folderview)
-{
-       GtkCTree *ctree = GTK_CTREE(folderview->ctree);
-       FolderItem *item;
-
-       if (!folderview->selected) return;
-
-       item = gtk_ctree_node_get_row_data(ctree, folderview->selected);
-       g_return_if_fail(item != NULL);
-       g_return_if_fail(item->folder != NULL);
-
-       switch (FOLDER_TYPE(item->folder)) {
-#if 0
-       case F_MBOX:
-               folderview_new_mbox_folder_cb(folderview, 0, NULL);
-               break;
-#endif
-       case F_MH:
-       case F_MAILDIR:
-               folderview_new_folder_cb(folderview, 0, NULL);
-               break;
-       case F_IMAP:
-               folderview_new_imap_folder_cb(folderview, 0, NULL);
-               break;
-       case F_NEWS:
-       default:
-               break;
-       }
-}
-
-void folderview_rename_folder(FolderView *folderview)
-{
-       GtkCTree *ctree = GTK_CTREE(folderview->ctree);
-       FolderItem *item;
-
-       if (!folderview->selected) return;
-
-       item = gtk_ctree_node_get_row_data(ctree, folderview->selected);
-       g_return_if_fail(item != NULL);
-       g_return_if_fail(item->folder != NULL);
-       if (!item->path) return;
-       if (item->stype != F_NORMAL) return;
-
-       switch (FOLDER_TYPE(item->folder)) {
-#if 0
-       case F_MBOX:
-               folderview_rename_mbox_folder_cb(folderview, 0, NULL);
-               break;
-#endif
-       case F_MH:
-       case F_MAILDIR:
-       case F_IMAP:
-               folderview_rename_folder_cb(folderview, 0, NULL);
-               break;
-       case F_NEWS:
-       default:
-               break;
-       }
-}
-
-void folderview_delete_folder(FolderView *folderview)
-{
-       GtkCTree *ctree = GTK_CTREE(folderview->ctree);
-       FolderItem *item;
-
-       if (!folderview->selected) return;
-
-       item = gtk_ctree_node_get_row_data(ctree, folderview->selected);
-       g_return_if_fail(item != NULL);
-       g_return_if_fail(item->folder != NULL);
-       if (!item->path) return;
-       if (item->stype != F_NORMAL) return;
-
-       switch (FOLDER_TYPE(item->folder)) {
-       case F_MH:
-#if 0
-       case F_MBOX:
-#endif
-       case F_MAILDIR:
-       case F_IMAP:
-               folderview_delete_folder_cb(folderview, 0, NULL);
-               break;
-       case F_NEWS:
-       default:
-               break;
-       }
-}
-
-
 /* callback functions */
 
 static gboolean folderview_button_pressed(GtkWidget *ctree, GdkEventButton *event,
@@ -1452,20 +1330,9 @@ static gboolean folderview_button_pressed(GtkWidget *ctree, GdkEventButton *even
        gint prev_row = -1, row = -1, column = -1;
        FolderItem *item;
        Folder *folder;
+       FolderViewPopup *fpopup;
+       GtkItemFactory *fpopup_factory;
        GtkWidget *popup;
-       gboolean mark_all_read   = FALSE;
-       gboolean new_folder      = FALSE;
-       gboolean rename_folder   = FALSE;
-       gboolean move_folder     = FALSE;
-       gboolean delete_folder   = FALSE;
-       gboolean download_msg    = FALSE;
-       gboolean update_tree     = FALSE;
-       gboolean rescan_tree     = FALSE;
-       gboolean remove_tree     = FALSE;
-       gboolean search_folder   = FALSE;
-       gboolean folder_property = FALSE;
-       gboolean folder_processing  = FALSE;
-       gboolean folder_scoring  = FALSE;
 
        if (!event) return FALSE;
 
@@ -1507,106 +1374,28 @@ static gboolean folderview_button_pressed(GtkWidget *ctree, GdkEventButton *even
        g_return_val_if_fail(item->folder != NULL, FALSE);
        folder = item->folder;
 
-       if (folderview->mainwin->lock_count == 0) {
-               new_folder = TRUE;
-               if (folder_item_parent(item) == NULL) {
-                       update_tree = remove_tree = TRUE;
-                       if (folder->account)
-                               folder_property = TRUE;
-               } else
-                       mark_all_read = search_folder = folder_property = TRUE;
-                       
-               if (FOLDER_IS_LOCAL(folder) || FOLDER_TYPE(folder) == F_IMAP /* || FOLDER_TYPE(folder) == F_MBOX */) {
-                       if (folder_item_parent(item) == NULL)
-                               update_tree = rescan_tree = TRUE;
-                       else if (item->stype == F_NORMAL)
-                               move_folder = rename_folder = delete_folder = folder_scoring = folder_processing = TRUE;
-                       else if (item->stype == F_INBOX)
-                               folder_scoring = folder_processing = TRUE;
-                       else if (item->stype == F_TRASH)
-                               folder_processing = TRUE;
-                       else if (item->stype == F_OUTBOX)
-                               folder_processing = TRUE;
-                       if (0 == item->total_msgs)
-                               search_folder = FALSE;
-               } else if (FOLDER_TYPE(folder) == F_NEWS) {
-                       if (folder_item_parent(item) != NULL)
-                               delete_folder = folder_scoring = folder_processing = TRUE;
-               }
-               if (FOLDER_TYPE(folder) == F_IMAP ||
-                   FOLDER_TYPE(folder) == F_NEWS) {
-                       if (folder_item_parent(item) != NULL && 
-                           item->no_select == FALSE &&
-                           !prefs_common.work_offline)
-                               download_msg = TRUE;
-               }
-               if (item->unread_msgs < 1) 
-                       mark_all_read = FALSE;
+       fpopup = g_hash_table_lookup(folderview_popups, folder->klass->idstr);
+       if (fpopup != NULL)
+               fpopup_factory = g_hash_table_lookup(folderview->popups, folder->klass->idstr);
+       else {
+               fpopup = g_hash_table_lookup(folderview_popups, "common");
+               fpopup_factory = g_hash_table_lookup(folderview->popups, "common");
        }
 
-#define SET_SENS(factory, name, sens) \
-       menu_set_sensitive(folderview->factory, name, sens)
-       
-       mark_all_read = mark_all_read && 
-                       (item == folderview->summaryview->folder_item);
-
-       if (FOLDER_IS_LOCAL(folder)) {
-               popup = folderview->mail_popup;
-               menu_set_insensitive_all(GTK_MENU_SHELL(popup));
-               SET_SENS(mail_factory, "/Mark all read", mark_all_read);
-               SET_SENS(mail_factory, "/Create new folder...", new_folder);
-               SET_SENS(mail_factory, "/Rename folder...", rename_folder);
-               SET_SENS(mail_factory, "/Move folder...", move_folder);
-               SET_SENS(mail_factory, "/Delete folder", delete_folder);
-               SET_SENS(mail_factory, "/Check for new messages", update_tree);
-               SET_SENS(mail_factory, "/Rebuild folder tree", rescan_tree);
-               SET_SENS(mail_factory, "/Remove mailbox", remove_tree);
-               SET_SENS(mail_factory, "/Search folder...", search_folder);
-               SET_SENS(mail_factory, "/Properties...", folder_property);
-               SET_SENS(mail_factory, "/Processing...", folder_processing);
-       } else if (FOLDER_TYPE(folder) == F_IMAP) {
-               popup = folderview->imap_popup;
-               menu_set_insensitive_all(GTK_MENU_SHELL(popup));
-               SET_SENS(imap_factory, "/Mark all read", mark_all_read);
-               SET_SENS(imap_factory, "/Create new folder...", new_folder);
-               SET_SENS(imap_factory, "/Rename folder...", rename_folder);
-               SET_SENS(imap_factory, "/Move folder...", move_folder);
-               SET_SENS(imap_factory, "/Delete folder", delete_folder);
-               SET_SENS(imap_factory, "/Download", download_msg);
-               SET_SENS(imap_factory, "/Check for new messages", update_tree);
-               SET_SENS(imap_factory, "/Rebuild folder tree", rescan_tree);
-               SET_SENS(imap_factory, "/Remove IMAP4 account", remove_tree);
-               SET_SENS(imap_factory, "/Search folder...", search_folder);
-               SET_SENS(imap_factory, "/Properties...", folder_property);
-               SET_SENS(imap_factory, "/Processing...", folder_processing);
-       } else if (FOLDER_TYPE(folder) == F_NEWS) {
-               popup = folderview->news_popup;
-               menu_set_insensitive_all(GTK_MENU_SHELL(popup));
-               SET_SENS(news_factory, "/Mark all read", mark_all_read);
-               SET_SENS(news_factory, "/Subscribe to newsgroup...", new_folder);
-               SET_SENS(news_factory, "/Remove newsgroup", delete_folder);
-               SET_SENS(news_factory, "/Download", download_msg);
-               SET_SENS(news_factory, "/Check for new messages", update_tree);
-               SET_SENS(news_factory, "/Remove news account", remove_tree);
-               SET_SENS(news_factory, "/Search folder...", search_folder);
-               SET_SENS(news_factory, "/Properties...", folder_property);
-               SET_SENS(news_factory, "/Processing...", folder_processing);
-#if 0
-       } else if (FOLDER_TYPE(folder) == F_MBOX) {
-               popup = folderview->mbox_popup;
-               menu_set_insensitive_all(GTK_MENU_SHELL(popup));
-               SET_SENS(mbox_factory, "/Create new folder...", new_folder);
-               SET_SENS(mbox_factory, "/Rename folder...", rename_folder);
-               SET_SENS(mbox_factory, "/Move folder...", move_folder);
-               SET_SENS(mbox_factory, "/Delete folder", delete_folder);
-               SET_SENS(news_factory, "/Properties...", folder_property);
-               SET_SENS(mbox_factory, "/Processing...", folder_processing);
-#endif
-       } else
-               return FALSE;
+       if (fpopup->set_sensitivity != NULL)
+               fpopup->set_sensitivity(fpopup_factory, item);
+
+#define SET_SENS(name, sens) \
+       menu_set_sensitive(fpopup_factory, name, sens)
+
+       SET_SENS("/Mark all read", item->unread_msgs >= 1);
+       SET_SENS("/Search folder...", item->total_msgs >= 1);
+       SET_SENS("/Properties...", TRUE);
+       SET_SENS("/Processing...", item->node->parent != NULL);
 
 #undef SET_SENS
 
+       popup = gtk_item_factory_get_widget(fpopup_factory, fpopup->path);
        gtk_menu_popup(GTK_MENU(popup), NULL, NULL, NULL, NULL,
                       event->button, event->time);
 
@@ -1783,7 +1572,7 @@ static void folderview_tree_collapsed(GtkCTree *ctree, GtkCTreeNode *node,
 
        item = gtk_ctree_node_get_row_data(ctree, node);
        g_return_if_fail(item != NULL);
-       item->collapsed= TRUE;
+       item->collapsed = TRUE;
        folderview_update_node(folderview, node);
 }
 
@@ -1818,755 +1607,58 @@ static void folderview_col_resized(GtkCList *clist, gint column, gint width,
        }
 }
 
-static GtkCTreeNode *folderview_find_by_name(GtkCTree *ctree,
-                                            GtkCTreeNode *node,
-                                            const gchar *name)
+void folderview_create_folder_node_recursive(FolderView *folderview, FolderItem *item)
 {
-       FolderItem *item;
-
-       if (!node)
-               node = GTK_CTREE_NODE(GTK_CLIST(ctree)->row_list);
-       if (!node)
-               return NULL;
-
-       node = GTK_CTREE_ROW(node)->children;
+       GNode *srcnode;
 
-       while (node) {
-               item = gtk_ctree_node_get_row_data(ctree, node);
-               if (!folderview_compare_name(item, name))
-                       return node;
-               node = GTK_CTREE_ROW(node)->sibling;
+       folderview_create_folder_node(folderview, item);
+       
+       srcnode = item->folder->node;   
+       srcnode = g_node_find(srcnode, G_PRE_ORDER, G_TRAVERSE_ALL, item);
+       srcnode = srcnode->children;
+       while (srcnode != NULL) {
+               if (srcnode && srcnode->data) {
+                       FolderItem *next_item = (FolderItem*) srcnode->data;
+                       folderview_create_folder_node_recursive(folderview, next_item);
+               }
+               srcnode = srcnode->next;
        }
-
-       return NULL;
 }
 
-static void folderview_download_func(Folder *folder, FolderItem *item,
-                                    gpointer data)
+void folderview_create_folder_node(FolderView *folderview, FolderItem *item)
 {
-       GList *list;
+       GtkCTree *ctree = GTK_CTREE(folderview->ctree);
+       gchar *text[N_FOLDER_COLS] = {NULL, "0", "0", "0"};
+       GtkCTreeNode *node, *parent_node;
+       
+       parent_node = gtk_ctree_find_by_row_data(ctree, NULL, folder_item_parent(item));
+       if (parent_node == NULL)
+               return;
 
-       for (list = folderview_list; list != NULL; list = list->next) {
-               FolderView *folderview = (FolderView *)list->data;
-               MainWindow *mainwin = folderview->mainwin;
-               gchar *str;
+       gtk_clist_freeze(GTK_CLIST(ctree));
 
-               str = g_strdup_printf
-                       (_("Downloading messages in %s ..."), item->path);
-               main_window_progress_set(mainwin,
-                                        GPOINTER_TO_INT(data), item->total_msgs);
-               STATUSBAR_PUSH(mainwin, str);
-               STATUSBAR_POP(mainwin);
-               g_free(str);
-       }
+       text[COL_FOLDER] = item->name;
+       node = gtk_ctree_insert_node(ctree, parent_node, NULL, text,
+                                    FOLDER_SPACING,
+                                    folderxpm, folderxpmmask,
+                                    folderopenxpm, folderopenxpmmask,
+                                    FALSE, FALSE);
+       gtk_ctree_expand(ctree, parent_node);
+       gtk_ctree_node_set_row_data(ctree, node, item);
+       if (normal_style)
+               gtk_ctree_node_set_row_style(ctree, node, normal_style);
+       folderview_sort_folders(folderview, folderview->selected, item->folder);
+
+       gtk_clist_thaw(GTK_CLIST(ctree));
+}
+
+static void folderview_search_cb(FolderView *folderview, guint action,
+                                GtkWidget *widget)
+{
+       summary_search(folderview->summaryview);
 }
 
-static void folderview_download_cb(FolderView *folderview, guint action,
-                                  GtkWidget *widget)
-{
-       GtkCTree *ctree = GTK_CTREE(folderview->ctree);
-       MainWindow *mainwin = folderview->mainwin;
-       FolderItem *item;
-
-       if (!folderview->selected) return;
-
-       item = gtk_ctree_node_get_row_data(ctree, folderview->selected);
-       g_return_if_fail(item != NULL);
-       g_return_if_fail(item->folder != NULL);
-#if 0
-       if (!prefs_common.online_mode) {
-               if (alertpanel(_("Offline"),
-                              _("You are offline. Go online?"),
-                              _("Yes"), _("No"), NULL) == G_ALERTDEFAULT)
-                       main_window_toggle_online(folderview->mainwin, TRUE);
-               else
-                       return;
-       }
-#endif
-       main_window_cursor_wait(mainwin);
-       inc_lock();
-       main_window_lock(mainwin);
-       gtk_widget_set_sensitive(folderview->ctree, FALSE);
-       main_window_progress_on(mainwin);
-       GTK_EVENTS_FLUSH();
-       folder_set_ui_func(item->folder, folderview_download_func, NULL);
-       if (folder_item_fetch_all_msg(item) < 0) {
-               gchar *name;
-
-               name = trim_string(item->name, 32);
-               alertpanel_error(_("Error occurred while downloading messages in `%s'."), name);
-               g_free(name);
-       }
-       folder_set_ui_func(item->folder, NULL, NULL);
-       main_window_progress_off(mainwin);
-       gtk_widget_set_sensitive(folderview->ctree, TRUE);
-       main_window_unlock(mainwin);
-       inc_unlock();
-       main_window_cursor_normal(mainwin);
-}
-
-static void folderview_update_tree_cb(FolderView *folderview, guint action,
-                                     GtkWidget *widget)
-{
-       GtkCTree *ctree = GTK_CTREE(folderview->ctree);
-       FolderItem *item;
-
-       if (!folderview->selected) return;
-
-       summary_show(folderview->summaryview, NULL);
-
-       item = gtk_ctree_node_get_row_data(ctree, folderview->selected);
-       g_return_if_fail(item != NULL);
-       g_return_if_fail(item->folder != NULL);
-
-       if (action == 0)
-               folderview_check_new(item->folder);
-       else
-               folderview_rescan_tree(item->folder);
-}
-
-void folderview_create_folder_node_recursive(FolderView *folderview, FolderItem *item)
-{
-       GNode *srcnode;
-
-       folderview_create_folder_node(folderview, item);
-       
-       srcnode = item->folder->node;   
-       srcnode = g_node_find(srcnode, G_PRE_ORDER, G_TRAVERSE_ALL, item);
-       srcnode = srcnode->children;
-       while (srcnode != NULL) {
-               if (srcnode && srcnode->data) {
-                       FolderItem *next_item = (FolderItem*) srcnode->data;
-                       folderview_create_folder_node_recursive(folderview, next_item);
-               }
-               srcnode = srcnode->next;
-       }
-}
-
-void folderview_create_folder_node(FolderView *folderview, FolderItem *item)
-{
-       GtkCTree *ctree = GTK_CTREE(folderview->ctree);
-       gchar *text[N_FOLDER_COLS] = {NULL, "0", "0", "0"};
-       GtkCTreeNode *node, *parent_node;
-       
-       parent_node = gtk_ctree_find_by_row_data(ctree, NULL, folder_item_parent(item));
-       if (parent_node == NULL)
-               return;
-
-       gtk_clist_freeze(GTK_CLIST(ctree));
-
-       text[COL_FOLDER] = item->name;
-       node = gtk_ctree_insert_node(ctree, parent_node, NULL, text,
-                                    FOLDER_SPACING,
-                                    folderxpm, folderxpmmask,
-                                    folderopenxpm, folderopenxpmmask,
-                                    FALSE, FALSE);
-       gtk_ctree_expand(ctree, parent_node);
-       gtk_ctree_node_set_row_data(ctree, node, item);
-       if (normal_style)
-               gtk_ctree_node_set_row_style(ctree, node, normal_style);
-       folderview_sort_folders(folderview, folderview->selected, item->folder);
-
-       gtk_clist_thaw(GTK_CLIST(ctree));
-}
-
-static void folderview_new_folder_cb(FolderView *folderview, guint action,
-                                    GtkWidget *widget)
-{
-       GtkCTree *ctree = GTK_CTREE(folderview->ctree);
-       FolderItem *item;
-       FolderItem *new_item;
-       gchar *new_folder;
-       gchar *name, *name_;
-
-       if (!folderview->selected) return;
-
-       item = gtk_ctree_node_get_row_data(ctree, folderview->selected);
-       g_return_if_fail(item != NULL);
-       g_return_if_fail(item->folder != NULL);
-
-       new_folder = input_dialog(_("New folder"),
-                                 _("Input the name of new folder:"),
-                                 _("NewFolder"));
-       if (!new_folder) return;
-
-       if (FOLDER_TYPE(item->folder) != F_MBOX) {
-               if (strchr(new_folder, G_DIR_SEPARATOR) != NULL) {
-                       alertpanel_error(_("`%c' can't be included in folder name."),
-                                        G_DIR_SEPARATOR);
-                       g_free(new_folder);
-                       return;
-               }
-       }
-
-       name_ = trim_string(new_folder, 32);
-       Xstrdup_a(name, name_, {g_free(new_folder); return;});
-       g_free(name_);
-
-       /* find whether the directory already exists */
-       if (folderview_find_by_name(ctree, folderview->selected, new_folder)) {
-               alertpanel_error(_("The folder `%s' already exists."), name);
-               g_free(new_folder);
-               return;
-       }
-
-       new_item = folder_create_folder(item, new_folder);
-       if (!new_item) {
-               alertpanel_error(_("Can't create the folder `%s'."), name);
-               g_free(new_folder);
-               return;
-       } 
-       g_free(new_folder);
-
-       folder_write_list();
-}
-
-#if 0
-static void folderview_new_mbox_folder_cb(FolderView *folderview, guint action,
-                                         GtkWidget *widget)
-{
-       GtkCTree *ctree = GTK_CTREE(folderview->ctree);
-       FolderItem *item;
-       FolderItem *new_item;
-       gchar *new_folder;
-
-       if (!folderview->selected) return;
-
-       item = gtk_ctree_node_get_row_data(ctree, folderview->selected);
-       g_return_if_fail(item != NULL);
-       g_return_if_fail(item->folder != NULL);
-
-       new_folder = input_dialog(_("New folder"),
-                                 _("Input the name of new folder:"),
-                                 _("NewFolder"));
-       if (!new_folder) return;
-
-       /* find whether the directory already exists */
-       if (folderview_find_by_name(ctree, folderview->selected, new_folder)) {
-               alertpanel_error(_("The folder `%s' already exists."),
-                                new_folder);
-               g_free(new_folder);
-               return;
-       }
-
-       new_item = folder_create_folder(item, new_folder);
-       g_free(new_folder);
-       if (!new_item) return;
-
-       folder_write_list();
-}
-#endif
-
-static void folderview_rename_folder_cb(FolderView *folderview, guint action,
-                                       GtkWidget *widget)
-{
-       GtkCTree *ctree = GTK_CTREE(folderview->ctree);
-       FolderItem *item;
-       gchar *new_folder;
-       gchar *name, *name_;
-       gchar *message;
-       gchar *old_path;
-       gchar *old_id;
-       gchar *new_id;
-
-       if (!folderview->selected) return;
-
-       item = gtk_ctree_node_get_row_data(ctree, folderview->selected);
-       g_return_if_fail(item != NULL);
-       g_return_if_fail(item->path != NULL);
-       g_return_if_fail(item->folder != NULL);
-
-       name_ = trim_string(item->name, 32);
-       Xstrdup_a(name, name_, return);
-       g_free(name_);
-       message = g_strdup_printf(_("Input new name for `%s':"), name);
-       new_folder = input_dialog(_("Rename folder"), message,
-                                 g_basename(item->path));
-       g_free(message);
-       if (!new_folder) return;
-
-       if (strchr(new_folder, G_DIR_SEPARATOR) != NULL) {
-               alertpanel_error(_("`%c' can't be included in folder name."),
-                                G_DIR_SEPARATOR);
-               g_free(new_folder);
-               return;
-       }
-
-       if (folderview_find_by_name
-               (ctree, GTK_CTREE_ROW(folderview->selected)->parent,
-                new_folder)) {
-               name = trim_string(new_folder, 32);
-               alertpanel_error(_("The folder `%s' already exists."), name);
-               g_free(name);
-               g_free(new_folder);
-               return;
-       }
-
-       Xstrdup_a(old_path, item->path, {g_free(new_folder); return;});
-       old_id = folder_item_get_identifier(item);
-
-       if (item->folder->klass->rename_folder(item->folder, item, new_folder) < 0) {
-               g_free(old_id);
-               g_free(new_folder);
-               return;
-       }
-       g_free(new_folder);
-
-       /* if (FOLDER_TYPE(item->folder) == F_MH)
-               prefs_filtering_rename_path(old_path, item->path); */
-       new_id = folder_item_get_identifier(item);
-       prefs_filtering_rename_path(old_id, new_id);
-
-       g_free(old_id);
-       g_free(new_id);
-
-       gtk_clist_freeze(GTK_CLIST(ctree));
-
-       folderview_update_node(folderview, folderview->selected);
-       folderview_sort_folders(folderview,
-                               GTK_CTREE_ROW(folderview->selected)->parent,
-                               item->folder);
-       if (folderview->opened == folderview->selected ||
-           gtk_ctree_is_ancestor(ctree,
-                                 folderview->selected,
-                                 folderview->opened)) {
-               GtkCTreeNode *node = folderview->opened;
-               folderview_unselect(folderview);
-               folderview_select_node(folderview, node);
-       }
-
-       gtk_clist_thaw(GTK_CLIST(ctree));
-
-       folder_write_list();
-}
-
-#if 0
-static void folderview_rename_mbox_folder_cb(FolderView *folderview,
-                                            guint action,
-                                            GtkWidget *widget)
-{
-       GtkCTree *ctree = GTK_CTREE(folderview->ctree);
-       FolderItem *item;
-       gchar *new_folder;
-       gchar *message;
-
-       if (!folderview->selected) return;
-
-       item = gtk_ctree_node_get_row_data(ctree, folderview->selected);
-       g_return_if_fail(item != NULL);
-       g_return_if_fail(item->path != NULL);
-       g_return_if_fail(item->folder != NULL);
-
-       message = g_strdup_printf(_("Input new name for `%s':"),
-                                 g_basename(item->path));
-       new_folder = input_dialog(_("Rename folder"), message,
-                                 g_basename(item->path));
-       g_free(message);
-       if (!new_folder) return;
-
-       if (folderview_find_by_name
-               (ctree, GTK_CTREE_ROW(folderview->selected)->parent,
-                new_folder)) {
-               alertpanel_error(_("The folder `%s' already exists."),
-                                new_folder);
-               g_free(new_folder);
-               return;
-       }
-
-       if (item->folder->klass->rename_folder(item->folder, item, new_folder) < 0) {
-               g_free(new_folder);
-               return;
-       }
-       g_free(new_folder);
-
-       gtk_clist_freeze(GTK_CLIST(ctree));
-
-       folderview_update_node(folderview, folderview->selected);
-       folderview_sort_folders(folderview,
-                               GTK_CTREE_ROW(folderview->selected)->parent,
-                               item->folder);
-       if (folderview->opened == folderview->selected) {
-               if (!GTK_CTREE_ROW(folderview->opened)->children)
-                       gtk_ctree_expand(ctree, folderview->opened);
-               summary_show(folderview->summaryview, item);
-       }
-
-       gtk_clist_thaw(GTK_CLIST(ctree));
-
-       folder_write_list();
-}
-#endif
-
-static void folderview_delete_folder_cb(FolderView *folderview, guint action,
-                                       GtkWidget *widget)
-{
-       GtkCTree *ctree = GTK_CTREE(folderview->ctree);
-       FolderItem *item;
-       gchar *message, *name, *name_;
-       AlertValue avalue;
-       gchar *old_path;
-       gchar *old_id;
-
-       if (!folderview->selected) return;
-
-       item = gtk_ctree_node_get_row_data(ctree, folderview->selected);
-       g_return_if_fail(item != NULL);
-       g_return_if_fail(item->path != NULL);
-       g_return_if_fail(item->folder != NULL);
-
-       name_ = trim_string(item->name, 32);
-       Xstrdup_a(name, name_, return);
-       g_free(name_);
-       message = g_strdup_printf
-               (_("All folder(s) and message(s) under `%s' will be deleted.\n"
-                  "Do you really want to delete?"), name);
-       avalue = alertpanel(_("Delete folder"), message,
-                           _("Yes"), _("+No"), NULL);
-       g_free(message);
-       if (avalue != G_ALERTDEFAULT) return;
-
-       Xstrdup_a(old_path, item->path, return);
-       old_id = folder_item_get_identifier(item);
-
-       if (folderview->opened == folderview->selected ||
-           gtk_ctree_is_ancestor(ctree,
-                                 folderview->selected,
-                                 folderview->opened)) {
-               summary_clear_all(folderview->summaryview);
-               folderview->opened = NULL;
-       }
-
-       if (item->folder->klass->remove_folder(item->folder, item) < 0) {
-               alertpanel_error(_("Can't remove the folder `%s'."), name);
-               if (folderview->opened == folderview->selected)
-                       summary_show(folderview->summaryview,
-                                    folderview->summaryview->folder_item);
-               g_free(old_id);
-               return;
-       }
-
-       folder_write_list();
-
-       prefs_filtering_delete_path(old_id);
-       g_free(old_id);
-
-}
-
-static void folderview_remove_mailbox_cb(FolderView *folderview, guint action,
-                                        GtkWidget *widget)
-{
-       GtkCTree *ctree = GTK_CTREE(folderview->ctree);
-       GtkCTreeNode *node;
-       FolderItem *item;
-       gchar *name, *name_;
-       gchar *message;
-       AlertValue avalue;
-
-       if (!folderview->selected) return;
-       node = folderview->selected;
-       item = gtk_ctree_node_get_row_data(ctree, node);
-       g_return_if_fail(item != NULL);
-       g_return_if_fail(item->folder != NULL);
-       if (folder_item_parent(item)) return;
-
-       name_ = trim_string(item->folder->name, 32);
-       Xstrdup_a(name, name_, return);
-       g_free(name_);
-       message = g_strdup_printf
-               (_("Really remove the mailbox `%s' ?\n"
-                  "(The messages are NOT deleted from the disk)"), name);
-       avalue = alertpanel(_("Remove mailbox"), message,
-                           _("Yes"), _("+No"), NULL);
-       g_free(message);
-       if (avalue != G_ALERTDEFAULT) return;
-
-       folderview_unselect(folderview);
-       summary_clear_all(folderview->summaryview);
-
-       folder_destroy(item->folder);
-}
-
-static void folderview_new_imap_folder_cb(FolderView *folderview, guint action,
-                                         GtkWidget *widget)
-{
-       GtkCTree *ctree = GTK_CTREE(folderview->ctree);
-       FolderItem *item;
-       FolderItem *new_item;
-       gchar *new_folder;
-       gchar *name, *name_;
-       gchar *p;
-
-       if (!folderview->selected) return;
-
-       item = gtk_ctree_node_get_row_data(ctree, folderview->selected);
-       g_return_if_fail(item != NULL);
-       g_return_if_fail(item->folder != NULL);
-       g_return_if_fail(FOLDER_TYPE(item->folder) == F_IMAP);
-       g_return_if_fail(item->folder->account != NULL);
-
-       new_folder = input_dialog
-               (_("New folder"),
-                _("Input the name of new folder:\n"
-                  "(if you want to create a folder to store subfolders,\n"
-                  " append `/' at the end of the name)"),
-                _("NewFolder"));
-       if (!new_folder) return;
-
-       if ((p = strchr(new_folder, G_DIR_SEPARATOR)) != NULL &&
-           *(p + 1) != '\0') {
-               alertpanel_error(_("`%c' can't be included in folder name."),
-                                G_DIR_SEPARATOR);
-               g_free(new_folder);
-               return;
-       }
-
-       name_ = trim_string(new_folder, 32);
-       Xstrdup_a(name, name_, return);
-       g_free(name_);
-
-       /* find whether the directory already exists */
-       if (folderview_find_by_name(ctree, folderview->selected, new_folder)) {
-               alertpanel_error(_("The folder `%s' already exists."), name);
-               g_free(new_folder);
-               return;
-       }
-
-       new_item = folder_create_folder(item, new_folder);
-       if (!new_item) {
-               alertpanel_error(_("Can't create the folder `%s'."), name);
-               g_free(new_folder);
-               return;
-       }
-       g_free(new_folder);
-
-       folder_write_list();
-}
-
-static void folderview_rm_imap_server_cb(FolderView *folderview, guint action,
-                                        GtkWidget *widget)
-{
-       GtkCTree *ctree = GTK_CTREE(folderview->ctree);
-       FolderItem *item;
-       PrefsAccount *account;
-       gchar *name, *name_;
-       gchar *message;
-       AlertValue avalue;
-
-       if (!folderview->selected) return;
-
-       item = gtk_ctree_node_get_row_data(ctree, folderview->selected);
-       g_return_if_fail(item != NULL);
-       g_return_if_fail(item->folder != NULL);
-       g_return_if_fail(FOLDER_TYPE(item->folder) == F_IMAP);
-       g_return_if_fail(item->folder->account != NULL);
-
-       name_ = trim_string(item->folder->name, 32);
-       Xstrdup_a(name, name_, return);
-       g_free(name_);
-       message = g_strdup_printf(_("Really delete IMAP4 account `%s'?"), name);
-       avalue = alertpanel(_("Delete IMAP4 account"), message,
-                           _("Yes"), _("+No"), NULL);
-       g_free(message);
-
-       if (avalue != G_ALERTDEFAULT) return;
-
-       if (folderview->opened == folderview->selected ||
-           gtk_ctree_is_ancestor(ctree,
-                                 folderview->selected,
-                                 folderview->opened)) {
-               summary_clear_all(folderview->summaryview);
-               folderview->opened = NULL;
-       }
-
-       account = item->folder->account;
-       folder_destroy(item->folder);
-       account_destroy(account);
-       gtk_ctree_remove_node(ctree, folderview->selected);
-       account_set_menu();
-       main_window_reflect_prefs_all();
-       folder_write_list();
-}
-
-static void folderview_new_news_group_cb(FolderView *folderview, guint action,
-                                        GtkWidget *widget)
-{
-       GtkCTree *ctree = GTK_CTREE(folderview->ctree);
-       gchar *text[N_FOLDER_COLS] = {NULL, "0", "0", "0"};
-       GtkCTreeNode *servernode, *node;
-       Folder *folder;
-       FolderItem *item;
-       FolderItem *rootitem;
-       FolderItem *newitem;
-       GSList *new_subscr;
-       GSList *cur;
-       GNode *gnode;
-
-       if (!folderview->selected) return;
-
-       item = gtk_ctree_node_get_row_data(ctree, folderview->selected);
-       g_return_if_fail(item != NULL);
-       folder = item->folder;
-       g_return_if_fail(folder != NULL);
-       g_return_if_fail(FOLDER_TYPE(folder) == F_NEWS);
-       g_return_if_fail(folder->account != NULL);
-
-       if (GTK_CTREE_ROW(folderview->selected)->parent != NULL)
-               servernode = GTK_CTREE_ROW(folderview->selected)->parent;
-       else
-               servernode = folderview->selected;
-
-       rootitem = gtk_ctree_node_get_row_data(ctree, servernode);
-
-       new_subscr = grouplist_dialog(folder);
-
-       /* remove unsubscribed newsgroups */
-       for (gnode = folder->node->children; gnode != NULL; ) {
-               GNode *next = gnode->next;
-
-               item = FOLDER_ITEM(gnode->data);
-               if (g_slist_find_custom(new_subscr, item->path,
-                                       (GCompareFunc)g_strcasecmp) != NULL) {
-                       gnode = next;
-                       continue;
-               }
-
-               node = gtk_ctree_find_by_row_data(ctree, servernode, item);
-               if (!node) {
-                       gnode = next;
-                       continue;
-               }
-
-               if (folderview->opened == node) {
-                       summary_clear_all(folderview->summaryview);
-                       folderview->opened = NULL;
-               }
-
-               gtk_ctree_remove_node(ctree, node);
-               folder_item_remove(item);
-
-               gnode = next;
-       }
-
-       gtk_clist_freeze(GTK_CLIST(ctree));
-
-       /* add subscribed newsgroups */
-       for (cur = new_subscr; cur != NULL; cur = cur->next) {
-               gchar *name = (gchar *)cur->data;
-
-               if (folderview_find_by_name(ctree, servernode, name) != NULL)
-                       continue;
-
-               text[COL_FOLDER] = name;
-               node = gtk_ctree_insert_node(ctree, servernode, NULL, text,
-                                            FOLDER_SPACING,
-                                            folderxpm, folderxpmmask,
-                                            folderopenxpm, folderopenxpmmask,
-                                            FALSE, FALSE);
-               gtk_ctree_expand(ctree, servernode);
-
-               newitem = folder_item_new(folder, name, name);
-               folder_item_append(rootitem, newitem);
-               gtk_ctree_node_set_row_data(ctree, node, newitem);
-       }
-
-       folderview_sort_folders(folderview, servernode, folder);
-       gtk_clist_thaw(GTK_CLIST(ctree));
-
-       slist_free_strings(new_subscr);
-       g_slist_free(new_subscr);
-
-       folder_write_list();
-}
-
-static void folderview_rm_news_group_cb(FolderView *folderview, guint action,
-                                       GtkWidget *widget)
-{
-       GtkCTree *ctree = GTK_CTREE(folderview->ctree);
-       FolderItem *item;
-       gchar *name, *name_;
-       gchar *message;
-       AlertValue avalue;
-
-       if (!folderview->selected) return;
-
-       item = gtk_ctree_node_get_row_data(ctree, folderview->selected);
-       g_return_if_fail(item != NULL);
-       g_return_if_fail(item->folder != NULL);
-       g_return_if_fail(FOLDER_TYPE(item->folder) == F_NEWS);
-       g_return_if_fail(item->folder->account != NULL);
-
-       name_ = trim_string(item->path, 32);
-       Xstrdup_a(name, name_, return);
-       g_free(name_);
-       message = g_strdup_printf(_("Really delete newsgroup `%s'?"), name);
-       avalue = alertpanel(_("Delete newsgroup"), message,
-                           _("Yes"), _("+No"), NULL);
-       g_free(message);
-       if (avalue != G_ALERTDEFAULT) return;
-
-       if (folderview->opened == folderview->selected) {
-               summary_clear_all(folderview->summaryview);
-               folderview->opened = NULL;
-       }
-
-       folder_item_remove(item);
-       folder_write_list();
-       
-       prefs_filtering_delete_path(name);
-}
-
-static void folderview_rm_news_server_cb(FolderView *folderview, guint action,
-                                        GtkWidget *widget)
-{
-       GtkCTree *ctree = GTK_CTREE(folderview->ctree);
-       FolderItem *item;
-       PrefsAccount *account;
-       gchar *name, *name_;
-       gchar *message;
-       AlertValue avalue;
-
-       if (!folderview->selected) return;
-
-       item = gtk_ctree_node_get_row_data(ctree, folderview->selected);
-       g_return_if_fail(item != NULL);
-       g_return_if_fail(item->folder != NULL);
-       g_return_if_fail(FOLDER_TYPE(item->folder) == F_NEWS);
-       g_return_if_fail(item->folder->account != NULL);
-
-       name_ = trim_string(item->folder->name, 32);
-       Xstrdup_a(name, name_, return);
-       g_free(name_);
-       message = g_strdup_printf(_("Really delete news account `%s'?"), name);
-       avalue = alertpanel(_("Delete news account"), message,
-                           _("Yes"), _("+No"), NULL);
-       g_free(message);
-
-       if (avalue != G_ALERTDEFAULT) return;
-
-       if (folderview->opened == folderview->selected ||
-           gtk_ctree_is_ancestor(ctree,
-                                 folderview->selected,
-                                 folderview->opened)) {
-               summary_clear_all(folderview->summaryview);
-               folderview->opened = NULL;
-       }
-
-       account = item->folder->account;
-       folder_destroy(item->folder);
-       account_destroy(account);
-       gtk_ctree_remove_node(ctree, folderview->selected);
-       account_set_menu();
-       main_window_reflect_prefs_all();
-       folder_write_list();
-}
-
-static void folderview_search_cb(FolderView *folderview, guint action,
-                                GtkWidget *widget)
-{
-       summary_search(folderview->summaryview);
-}
-
-static void folderview_property_cb(FolderView *folderview, guint action,
+static void folderview_property_cb(FolderView *folderview, guint action,
                                   GtkWidget *widget)
 {
        GtkCTree *ctree = GTK_CTREE(folderview->ctree);
@@ -2605,25 +1697,8 @@ static void folderview_recollapse_nodes(FolderView *folderview, GtkCTreeNode *no
        g_slist_free(done);
 }
 
-static void folderview_move_to_cb(FolderView *folderview) 
-{
-       FolderItem *from_folder = NULL, *to_folder = NULL;
-
-       if (folderview->selected)
-               from_folder = gtk_ctree_node_get_row_data(GTK_CTREE(folderview->ctree), folderview->selected);
-       if (!from_folder || FOLDER_TYPE(from_folder->folder) == F_NEWS)
-               return;
-
-       to_folder = foldersel_folder_sel(from_folder->folder, FOLDER_SEL_MOVE, NULL);
-       
-       if (!to_folder || FOLDER_TYPE(to_folder->folder) == F_NEWS)
-               return;
-
-       folderview_move_to(folderview, from_folder, to_folder);
-}
-
-static void folderview_move_to(FolderView *folderview, FolderItem *from_folder,
-                              FolderItem *to_folder)
+void folderview_move_folder(FolderView *folderview, FolderItem *from_folder,
+                           FolderItem *to_folder)
 {
        FolderItem *from_parent = NULL;
        FolderItem *new_folder = NULL;
@@ -2631,6 +1706,10 @@ static void folderview_move_to(FolderView *folderview, FolderItem *from_folder,
        gchar *buf;
        gint status;
 
+       g_return_if_fail(folderview != NULL);
+       g_return_if_fail(from_folder != NULL);
+       g_return_if_fail(to_folder != NULL);
+
        src_node = gtk_ctree_find_by_row_data(GTK_CTREE(folderview->ctree), NULL, from_folder);
        from_parent = folder_item_parent(from_folder);
        buf = g_strdup_printf(_("Moving %s to %s..."), from_folder->name, to_folder->name);
@@ -2693,15 +1772,6 @@ static gint folderview_clist_compare(GtkCList *clist,
        return g_strcasecmp(item1->name, item2->name);
 }
 
-static gint folderview_compare_name(gconstpointer a, gconstpointer b)
-{
-       const FolderItem *item = a;
-       const gchar *name = b;
-
-       if (!item->path) return -1;
-       return strcmp2(g_basename(item->path), name);
-}
-
 static void folderview_processing_cb(FolderView *folderview, guint action,
                                     GtkWidget *widget)
 {
@@ -2804,8 +1874,8 @@ static void folderview_drag_data_get(GtkWidget        *widget,
 {
        FolderItem *item;
        GList *cur;
-       gchar *source=NULL;
-       
+       gchar *source = NULL;
+
        for (cur = GTK_CLIST(folderview->ctree)->selection;
             cur != NULL; cur = cur->next) {
                item = gtk_ctree_node_get_row_data
@@ -2836,7 +1906,7 @@ gboolean folderview_update_folder(gpointer source, gpointer userdata)
        ctree = folderview->ctree;
        g_return_val_if_fail(ctree != NULL, FALSE);
 
-       if (hookdata->update_flags & FOLDER_NEW_FOLDERITEM)
+       if (hookdata->update_flags & FOLDER_ADD_FOLDERITEM)
                folderview_create_folder_node(folderview, hookdata->item);
        else if (hookdata->update_flags & FOLDER_REMOVE_FOLDERITEM) {
                GtkCTreeNode *node;
@@ -2844,7 +1914,7 @@ gboolean folderview_update_folder(gpointer source, gpointer userdata)
                node = gtk_ctree_find_by_row_data(GTK_CTREE(ctree), NULL, hookdata->item);
                if (node != NULL)
                        gtk_ctree_remove_node(GTK_CTREE(ctree), node);
-       } else if (hookdata->update_flags & (FOLDER_TREE_CHANGED | FOLDER_NEW_FOLDER | FOLDER_DESTROY_FOLDER))
+       } else if (hookdata->update_flags & (FOLDER_TREE_CHANGED | FOLDER_ADD_FOLDER | FOLDER_REMOVE_FOLDER))
                folderview_set(folderview);
 
        return FALSE;
@@ -2869,6 +1939,8 @@ static gboolean folderview_drag_motion_cb(GtkWidget      *widget,
 
        if (gtk_clist_get_selection_info
                (GTK_CLIST(widget), x - 24, y - 24, &row, &column)) {
+               GtkWidget *srcwidget;
+
                if (y > height - 24 && height + vpos < total_height)
                        gtk_adjustment_set_value(pos, (vpos+5 > height ? height : vpos+5));
 
@@ -2879,26 +1951,23 @@ static gboolean folderview_drag_motion_cb(GtkWidget      *widget,
                item = gtk_ctree_node_get_row_data(GTK_CTREE(widget), node);
                src_item = folderview->summaryview->folder_item;
 
-               if (item && item->folder && item->path &&
-                   src_item && src_item != item) {
-                       switch (FOLDER_TYPE(item->folder)) {
-                       case F_MH:
-#if 0
-                       case F_MBOX:
-#endif
-                       case F_IMAP:
+               srcwidget = gtk_drag_get_source_widget(context);
+               if (srcwidget == folderview->summaryview->ctree) {
+                       /* comes from summaryview */
+                       /* we are copying messages, so only accept folder items that are not
+                          the source item, are no root items and can copy messages */
+                       if (item && item->folder && folder_item_parent(item) != NULL && src_item &&
+                           src_item != item && FOLDER_CLASS(item->folder)->copy_msg != NULL)
                                acceptable = TRUE;
-                               break;
-                       default:
-                               break;
-                       }
-               } else if (item && item->folder && folder_item_get_path(item) &&
-                          src_item && src_item != item) {
-                       /* a root folder - acceptable only from folderview */
-                       if (FOLDER_TYPE(item->folder) == F_MH || FOLDER_TYPE(item->folder) == F_IMAP)
+               } else if (srcwidget == folderview->ctree) {
+                       /* comes from folderview */
+                       /* we are moving folder items, only accept folders that are not
+                           the source items and can copy messages and create folder items */
+                       if (item && item->folder && src_item && src_item != item &&
+                           FOLDER_CLASS(item->folder)->copy_msg != NULL &&
+                           FOLDER_CLASS(item->folder)->create_folder != NULL)
                                acceptable = TRUE;
                }
-                       
        }
 
        if (acceptable || (src_item && src_item == item))
@@ -2958,26 +2027,23 @@ static void folderview_drag_received_cb(GtkWidget        *widget,
                
                /* re-check (due to acceptable possibly set for folder moves */
                if (!(item && item->folder && item->path &&
-                     src_item && src_item != item && 
-                     (FOLDER_TYPE(item->folder) == F_MH || FOLDER_TYPE(item->folder) == F_IMAP))) {
+                     src_item && src_item != item && FOLDER_CLASS(item->folder)->copy_msg != NULL)) {
                        return;
                }
                if (item && src_item) {
                        switch (drag_context->action) {
-                               case GDK_ACTION_COPY:
-                                       summary_copy_selected_to(folderview->summaryview, item);
-                                       gtk_drag_finish(drag_context, TRUE, FALSE, time);
-                                       break;
-                               case GDK_ACTION_MOVE:
-                               case GDK_ACTION_DEFAULT:
-                               default:
-                       if (FOLDER_TYPE(src_item->folder) != FOLDER_TYPE(item->folder) ||
-                           (FOLDER_TYPE(item->folder) == F_IMAP &&
-                            src_item->folder != item->folder))
+                       case GDK_ACTION_COPY:
                                summary_copy_selected_to(folderview->summaryview, item);
-                       else
-                               summary_move_selected_to(folderview->summaryview, item);
-                       gtk_drag_finish(drag_context, TRUE, TRUE, time);
+                               gtk_drag_finish(drag_context, TRUE, FALSE, time);
+                               break;
+                       case GDK_ACTION_MOVE:
+                       case GDK_ACTION_DEFAULT:
+                       default:
+                               if (FOLDER_CLASS(src_item->folder)->remove_msg == NULL)
+                                       summary_copy_selected_to(folderview->summaryview, item);
+                               else
+                                       summary_move_selected_to(folderview->summaryview, item);
+                               gtk_drag_finish(drag_context, TRUE, TRUE, time);
                        }
                } else
                        gtk_drag_finish(drag_context, FALSE, FALSE, time);
@@ -3001,7 +2067,7 @@ static void folderview_drag_received_cb(GtkWidget        *widget,
                        return;
                }
 
-               folderview_move_to(folderview, src_item, item);
+               folderview_move_folder(folderview, src_item, item);
                gtk_drag_finish(drag_context, TRUE, TRUE, time);
        }
        folderview->nodes_to_recollapse = NULL;
@@ -3015,3 +2081,35 @@ static void folderview_drag_end_cb(GtkWidget         *widget,
        g_slist_free(folderview->nodes_to_recollapse);
        folderview->nodes_to_recollapse = NULL;
 }
+
+FolderItem *folderview_get_selected(FolderView *folderview)
+{
+       return (FolderItem *) gtk_ctree_node_get_row_data(
+               GTK_CTREE(folderview->ctree), folderview->selected);
+}
+
+void folderview_register_popup(FolderViewPopup *fpopup)
+{
+       GList *folderviews;
+
+       for (folderviews = folderview_list; folderviews != NULL; folderviews = g_list_next(folderviews)) {
+               FolderView *folderview = folderviews->data;
+               GtkItemFactory *factory;
+
+               factory = create_ifactory(folderview, fpopup);
+               g_hash_table_insert(folderview->popups, fpopup->klass, factory);
+       }       
+       g_hash_table_insert(folderview_popups, fpopup->klass, fpopup);
+}
+
+void folderview_unregister_popup(FolderViewPopup *fpopup)
+{
+       GList *folderviews;
+
+       for (folderviews = folderview_list; folderviews != NULL; folderviews = g_list_next(folderviews)) {
+               FolderView *folderview = folderviews->data;
+
+               g_hash_table_remove(folderview->popups, fpopup->klass);
+       }       
+       g_hash_table_remove(folderview_popups, fpopup->klass);
+}
index b93a49f..f589a76 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2002 Hiroyuki Yamamoto
+ * Copyright (C) 1999-2004 Hiroyuki Yamamoto
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -21,6 +21,7 @@
 #define __FOLDERVIEW_H__
 
 typedef struct _FolderView     FolderView;
+typedef struct _FolderViewPopup        FolderViewPopup;
 
 #include <glib.h>
 #include <gtk/gtkwidget.h>
@@ -34,19 +35,8 @@ struct _FolderView
 {
        GtkWidget *scrolledwin;
        GtkWidget *ctree;
-       GtkWidget *mail_popup;
-       GtkWidget *imap_popup;
-       GtkWidget *news_popup;
-#if 0
-       GtkWidget *mbox_popup;
-#endif
-
-       GtkItemFactory *mail_factory;
-       GtkItemFactory *imap_factory;
-       GtkItemFactory *news_factory;
-#if 0
-       GtkItemFactory *mbox_factory;
-#endif
+
+       GHashTable *popups;
 
        GtkCTreeNode *selected;
        GtkCTreeNode *opened;
@@ -71,6 +61,15 @@ struct _FolderView
        GtkTargetList *target_list; /* DnD */
 };
 
+struct _FolderViewPopup
+{
+       gchar            *klass;
+       gchar            *path;
+       GSList           *entries;
+       void            (*set_sensitivity)      (GtkItemFactory *menu, FolderItem *item);
+};
+
+void folderview_initialize             (void);
 FolderView *folderview_create          (void);
 void folderview_init                   (FolderView     *folderview);
 void folderview_set                    (FolderView     *folderview);
@@ -78,20 +77,31 @@ void folderview_set_all                     (void);
 void folderview_select                 (FolderView     *folderview,
                                         FolderItem     *item);
 void folderview_unselect               (FolderView     *folderview);
+FolderItem *folderview_get_selected    (FolderView     *folderview);
 void folderview_select_next_unread     (FolderView     *folderview);
 void folderview_update_msg_num         (FolderView     *folderview,
                                         GtkCTreeNode   *row);
+
+void folderview_append_item            (FolderItem     *item);
+
 void folderview_rescan_tree            (Folder         *folder);
 void folderview_rescan_all             (void);
 gint folderview_check_new              (Folder         *folder);
 void folderview_check_new_all          (void);
 
-void folderview_new_folder             (FolderView     *folderview);
-void folderview_rename_folder          (FolderView     *folderview);
-void folderview_delete_folder          (FolderView     *folderview);
+void folderview_update_item_foreach    (GHashTable     *table,
+                                        gboolean        update_summary);
+void folderview_update_all_updated     (gboolean        update_summary);
+
+void folderview_move_folder            (FolderView     *folderview,
+                                        FolderItem     *from_folder,
+                                        FolderItem     *to_folder);
 
 void folderview_set_target_folder_color (gint          color_op);
 
 void folderview_reflect_prefs_pixmap_theme     (FolderView *folderview);
 
+void folderview_register_popup         (FolderViewPopup        *fpopup);
+void folderview_unregister_popup       (FolderViewPopup        *fpopup);
+
 #endif /* __FOLDERVIEW_H__ */
index a841b87..a54ab8a 100644 (file)
@@ -1,3 +1,5 @@
+PLUGINDIR = $(pkglibdir)/plugins/
+
 noinst_LTLIBRARIES = libsylpheedgtk.la
 
 EXTRA_DIST = \
@@ -9,6 +11,7 @@ libsylpheedgtk_la_SOURCES = \
        colorsel.c \
        description_window.c \
        filesel.c \
+       foldersort.c \
        gtkaspell.c \
        gtksctree.c \
        gtkshruler.c \
@@ -16,6 +19,7 @@ libsylpheedgtk_la_SOURCES = \
        gtkutils.c \
        gtkvscrollbutton.c \
        logwindow.c \
+       inputdialog.c \
        manage_window.c \
        menu.c \
        pluginwindow.c \
@@ -31,12 +35,14 @@ sylpheedgtkinclude_HEADERS = \
        colorsel.h \
        description_window.h \
        filesel.h \
+       foldersort.h \
        gtkaspell.h \
        gtksctree.h \
        gtkshruler.h \
        gtksctree.h \
        gtkutils.h \
        gtkvscrollbutton.h \
+       inputdialog.h \
        logwindow.h \
        manage_window.h \
        menu.h \
@@ -52,7 +58,8 @@ AM_CPPFLAGS = \
        -I.. \
        $(GTK_CFLAGS) \
        $(OPENSSL_CFLAGS) \
-       $(ASPELL_CFLAGS)
+       $(ASPELL_CFLAGS) \
+       -DPLUGINDIR=\"$(PLUGINDIR)\"
 
 libsylpheedgtk_la_LIBADD = \
        ../common/libsylpheedcommon.la \
index 063c446..fe1ef6b 100644 (file)
@@ -91,7 +91,6 @@ static void about_create(void)
        gtk_window_set_title(GTK_WINDOW(window), _("About"));
        gtk_container_set_border_width(GTK_CONTAINER(window), 8);
        gtk_widget_set_size_request(window, 518, 358);
-       gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
        g_signal_connect(G_OBJECT(window), "delete_event",
                         G_CALLBACK(gtk_widget_hide_on_delete), NULL);
        g_signal_connect(G_OBJECT(window), "key_press_event",
@@ -165,7 +164,7 @@ static void about_create(void)
        gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
 
        label = gtk_label_new
-               ("Copyright (C) 1999-2003 Hiroyuki Yamamoto <hiro-y@kcn.ne.jp>");
+               ("Copyright (C) 1999-2004 Hiroyuki Yamamoto <hiro-y@kcn.ne.jp>");
        gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
 
        hbox = gtk_hbox_new(FALSE, 0);
index 60bdf82..1920307 100644 (file)
@@ -49,7 +49,6 @@ gint colorsel_select_color_rgb(gchar *title, gint rgbvalue)
        gint result;
 
        color_dialog = GTK_COLOR_SELECTION_DIALOG(gtk_color_selection_dialog_new(title));
-       gtk_window_set_position(GTK_WINDOW(color_dialog), GTK_WIN_POS_CENTER);
        gtk_window_set_modal(GTK_WINDOW(color_dialog), TRUE);
        gtk_window_set_policy(GTK_WINDOW(color_dialog), FALSE, FALSE, FALSE);
        manage_window_set_transient(GTK_WINDOW(color_dialog));
index e463318..5482de8 100644 (file)
@@ -64,7 +64,6 @@ static void description_create(DescriptionWindow * dwindow)
        gtk_window_set_title(GTK_WINDOW(dwindow->window),
                             gettext(dwindow->title));
        gtk_container_set_border_width(GTK_CONTAINER(dwindow->window), 8);
-       gtk_window_set_position(GTK_WINDOW(dwindow->window), GTK_WIN_POS_CENTER);
        gtk_window_set_modal(GTK_WINDOW(dwindow->window), TRUE);
        gtk_window_set_policy(GTK_WINDOW(dwindow->window), FALSE, TRUE, FALSE);
 
index 4305b0c..e74cb2b 100644 (file)
@@ -59,6 +59,8 @@ gchar *filesel_select_file(const gchar *title, const gchar *file)
 {
        static gchar *filename = NULL;
        static gchar *cwd = NULL;
+       gchar *startdir = NULL;
+       gchar *realfile = NULL;
 
        filesel_create(title, FALSE);
 
@@ -69,15 +71,27 @@ gchar *filesel_select_file(const gchar *title, const gchar *file)
                filename = NULL;
        }
 
-       if (!cwd)
+       /* try to extract the directory and filename from file */
+       if (file) {
+               startdir = g_dirname(file);
+               realfile = g_basename(file);
+       } else {
+               realfile = file;
+       }
+
+       /* use sylpheed's startup directory if we can't find anything useful */
+       if (!startdir || !strcmp(startdir, ".")) {
                cwd = g_strconcat(sylpheed_get_startup_dir(), G_DIR_SEPARATOR_S, NULL);
+       } else {
+               cwd = g_strconcat(startdir, G_DIR_SEPARATOR_S, NULL);
+       }
 
        gtk_file_selection_set_filename(GTK_FILE_SELECTION(filesel), cwd);
 
-       if (file) {
+       if (realfile) {
                gtk_file_selection_set_filename(GTK_FILE_SELECTION(filesel),
-                                               file);
-               filesel_oldfilename = g_strdup(file);
+                                               realfile);
+               filesel_oldfilename = g_strdup(realfile);
        } else {
                filesel_oldfilename = NULL;
        }
@@ -108,6 +122,9 @@ gchar *filesel_select_file(const gchar *title, const gchar *file)
        if (filesel_oldfilename) 
                g_free(filesel_oldfilename);
 
+       if (startdir)
+               g_free(startdir);
+
        manage_window_focus_out(filesel, NULL, NULL);
        gtk_widget_destroy(filesel);
        GTK_EVENTS_FLUSH();
@@ -177,7 +194,6 @@ GList *filesel_select_multiple_files(const gchar *title, const gchar *file)
 static void filesel_create(const gchar *title, gboolean multiple_files)
 {
        filesel = gtk_file_selection_new(title);
-       gtk_window_set_position(GTK_WINDOW(filesel), GTK_WIN_POS_CENTER);
        gtk_window_set_modal(GTK_WINDOW(filesel), TRUE);
        gtk_window_set_wmclass
                (GTK_WINDOW(filesel), "file_selection", "Sylpheed");
index aaca22f..c06597a 100644 (file)
@@ -132,7 +132,7 @@ void foldersort_open()
        GtkWidget *folderlist;
        GtkWidget *label2;
 
-       window = gtk_window_new(GTK_WINDOW_DIALOG);
+       window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
        gtk_object_set_data(GTK_OBJECT(window), "window", window);
        gtk_container_set_border_width(GTK_CONTAINER(window), 4);
        gtk_window_set_title(GTK_WINDOW(window),
index 7e34088..89299d9 100644 (file)
@@ -2406,7 +2406,7 @@ static void gtkaspell_alert_dialog(gchar *message)
 
        dialog = gtk_dialog_new();
        gtk_window_set_policy(GTK_WINDOW(dialog), FALSE, FALSE, FALSE);
-       gtk_window_set_position(GTK_WINDOW(dialog),GTK_WIN_POS_MOUSE);
+       gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_MOUSE);
        gtk_signal_connect_object(GTK_OBJECT(dialog), "destroy",
                                   GTK_SIGNAL_FUNC(gtk_widget_destroy), 
                                   GTK_OBJECT(dialog));
index 3111c70..2eb11f9 100644 (file)
@@ -77,7 +77,7 @@ static void cancel_clicked    (GtkWidget      *widget,
 static gint delete_event       (GtkWidget      *widget,
                                 GdkEventAny    *event,
                                 gpointer        data);
-static void key_pressed                (GtkWidget      *widget,
+static gboolean key_pressed    (GtkWidget      *widget,
                                 GdkEventKey    *event,
                                 gpointer        data);
 static void entry_activated    (GtkEditable    *editable);
@@ -166,13 +166,13 @@ static void input_dialog_create(void)
 
        dialog = gtk_dialog_new();
        gtk_window_set_policy(GTK_WINDOW(dialog), FALSE, FALSE, FALSE);
-       gtk_widget_set_usize(dialog, INPUT_DIALOG_WIDTH, -1);
+       gtk_widget_set_size_request(dialog, INPUT_DIALOG_WIDTH, -1);
        gtk_container_set_border_width
                (GTK_CONTAINER(GTK_DIALOG(dialog)->action_area), 5);
-       gtk_signal_connect(GTK_OBJECT(dialog), "delete_event",
-                          GTK_SIGNAL_FUNC(delete_event), NULL);
-       gtk_signal_connect(GTK_OBJECT(dialog), "key_press_event",
-                          GTK_SIGNAL_FUNC(key_pressed), NULL);
+       g_signal_connect(G_OBJECT(dialog), "delete_event",
+                        G_CALLBACK(delete_event), NULL);
+       g_signal_connect(G_OBJECT(dialog), "key_press_event",
+                        G_CALLBACK(key_pressed), NULL);
        MANAGE_WINDOW_SIGNALS_CONNECT(dialog);
 
        gtk_widget_realize(dialog);
@@ -190,13 +190,13 @@ static void input_dialog_create(void)
 
        entry = gtk_entry_new();
        gtk_box_pack_start(GTK_BOX(vbox), entry, FALSE, FALSE, 0);
-       gtk_signal_connect(GTK_OBJECT(entry), "activate",
-                          GTK_SIGNAL_FUNC(entry_activated), NULL);
+       g_signal_connect(G_OBJECT(entry), "activate",
+                        G_CALLBACK(entry_activated), NULL);
 
        combo = gtk_combo_new();
        gtk_box_pack_start(GTK_BOX(vbox), combo, FALSE, FALSE, 0);
-       gtk_signal_connect(GTK_OBJECT(GTK_COMBO(combo)->entry), "activate",
-                          GTK_SIGNAL_FUNC(combo_activated), NULL);
+       g_signal_connect(G_OBJECT(GTK_COMBO(combo)->entry), "activate",
+                        G_CALLBACK(combo_activated), NULL);
 
        gtkut_button_set_create(&confirm_area,
                                &ok_button,     _("OK"),
@@ -206,10 +206,10 @@ static void input_dialog_create(void)
                          confirm_area);
        gtk_widget_grab_default(ok_button);
 
-       gtk_signal_connect(GTK_OBJECT(ok_button), "clicked",
-                          GTK_SIGNAL_FUNC(ok_clicked), NULL);
-       gtk_signal_connect(GTK_OBJECT(cancel_button), "clicked",
-                          GTK_SIGNAL_FUNC(cancel_clicked), NULL);
+       g_signal_connect(G_OBJECT(ok_button), "clicked",
+                        G_CALLBACK(ok_clicked), NULL);
+       g_signal_connect(G_OBJECT(cancel_button), "clicked",
+                        G_CALLBACK(cancel_clicked), NULL);
 
 
        gtk_widget_show_all(GTK_DIALOG(dialog)->vbox);
@@ -274,8 +274,8 @@ static void input_dialog_set(const gchar *title, const gchar *message,
        gtk_label_set_text(GTK_LABEL(msg_label), message);
        if (default_string && *default_string) {
                gtk_entry_set_text(GTK_ENTRY(entry_), default_string);
-               gtk_entry_set_position(GTK_ENTRY(entry_), 0);
-               gtk_entry_select_region(GTK_ENTRY(entry_), 0, -1);
+               gtk_editable_set_position(GTK_EDITABLE(entry_), 0);
+               gtk_editable_select_region(GTK_EDITABLE(entry_), 0, -1);
        } else
                gtk_entry_set_text(GTK_ENTRY(entry_), "");
 
@@ -303,12 +303,14 @@ static gint delete_event(GtkWidget *widget, GdkEventAny *event, gpointer data)
        return TRUE;
 }
 
-static void key_pressed(GtkWidget *widget, GdkEventKey *event, gpointer data)
+static gboolean key_pressed(GtkWidget *widget, GdkEventKey *event, gpointer data)
 {
        if (event && event->keyval == GDK_Escape) {
                ack = FALSE;
                fin = TRUE;
        }
+
+       return FALSE;
 }
 
 static void entry_activated(GtkEditable *editable)
index d844410..08cfb52 100644 (file)
@@ -35,8 +35,6 @@
 #include "menu.h"
 #include "utils.h"
 
-static gchar *menu_translate(const gchar *path, gpointer data);
-
 static void menu_item_add_accel( GtkWidget *widget, guint accel_signal_id, GtkAccelGroup *accel_group,
                                 guint accel_key, GdkModifierType accel_mods, GtkAccelFlags accel_flags,
                                 gpointer user_data);
@@ -90,7 +88,7 @@ GtkWidget *popupmenu_create(GtkWidget *window, GtkItemFactoryEntry *entries,
        return gtk_item_factory_get_widget(factory, path);
 }
 
-static gchar *menu_translate(const gchar *path, gpointer data)
+gchar *menu_translate(const gchar *path, gpointer data)
 {
        gchar *retval;
 
index d8fdf83..8e31703 100644 (file)
@@ -53,11 +53,12 @@ GtkWidget *menu_create_items        (GtkItemFactoryEntry    *entries,
                                 const gchar            *path,
                                 GtkItemFactory        **factory,
                                 gpointer                data);
-GtkWidget *popupmenu_create(GtkWidget *window,
+GtkWidget *popupmenu_create    (GtkWidget *window,
                                 GtkItemFactoryEntry *entries,
-                            guint n_entries,
+                                guint n_entries,
                                 const gchar *path,
                                 gpointer data);
+gchar *menu_translate          (const gchar *path, gpointer data);
 
 GString *menu_factory_get_rc   (const gchar            *path);
 void menu_factory_clear_rc     (const gchar            *rc_str);
index 044f64a..99a2ec9 100644 (file)
@@ -46,6 +46,7 @@ static void close_cb(GtkButton *button, PluginWindow *pluginwindow)
        gtk_widget_destroy(pluginwindow->window);
        g_free(pluginwindow);
        plugin_save_list();
+       inc_unlock();
 }
 
 static void set_plugin_list(PluginWindow *pluginwindow)
@@ -119,7 +120,7 @@ static void load_cb(GtkButton *button, PluginWindow *pluginwindow)
 {
        gchar *file, *error = NULL;
 
-       file = filesel_select_file(_("Select Plugin to load"), "");
+       file = filesel_select_file(_("Select Plugin to load"), PLUGINDIR);
        if (file == NULL)
                return;
 
@@ -156,8 +157,6 @@ void pluginwindow_create()
        gtk_container_set_border_width(GTK_CONTAINER(window), 8);
        gtk_window_set_default_size(GTK_WINDOW(window), 480, 300);
        gtk_window_set_title(GTK_WINDOW(window), _("Plugins"));
-       gtk_window_set_position(GTK_WINDOW(window),
-                               GTK_WIN_POS_CENTER);
        gtk_window_set_modal(GTK_WINDOW(window), TRUE);
 
        vbox1 = gtk_vbox_new(FALSE, 4);
@@ -259,5 +258,6 @@ void pluginwindow_create()
 
        set_plugin_list(pluginwindow);
 
+       inc_lock();
        gtk_widget_show(window);
 }
index f9672d8..e7b4a07 100644 (file)
@@ -58,7 +58,6 @@ ProgressDialog *progress_dialog_create(void)
        window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
        gtk_widget_set_usize(window, 460, -1);
        gtk_container_set_border_width(GTK_CONTAINER(window), 8);
-       gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
        gtk_window_set_policy(GTK_WINDOW(window), FALSE, TRUE, TRUE);
        gtk_widget_realize(window);
 
index 9e3abfc..fe78554 100644 (file)
@@ -435,57 +435,56 @@ static gboolean imap_scan_required                (Folder         *folder,
 static void imap_change_flags                  (Folder         *folder,
                                                 FolderItem     *item,
                                                 MsgInfo        *msginfo,
-                                                MsgPermFlags   newflags);
+                                                MsgPermFlags    newflags);
+static gint imap_get_flags                     (Folder         *folder,
+                                                FolderItem     *item,
+                                                MsgInfoList    *msglist,
+                                                GRelation      *msgflags);
 static gchar *imap_folder_get_path             (Folder         *folder);
 static gchar *imap_item_get_path               (Folder         *folder,
                                                 FolderItem     *item);
 
-static FolderClass imap_class =
-{
-       F_IMAP,
-       "imap",
-       "IMAP4",
-
-       /* Folder functions */
-       imap_folder_new,
-       imap_folder_destroy,
-       NULL,
-       NULL,
-       imap_scan_tree,
-       imap_create_tree,
-
-       /* FolderItem functions */
-       imap_folder_item_new,
-       imap_folder_item_destroy,
-       NULL,
-       NULL,
-       imap_item_get_path,
-       imap_create_folder,
-       imap_rename_folder,
-       imap_remove_folder,
-       imap_close,
-       imap_get_num_list,
-       NULL,
-       NULL,
-       NULL,
-       imap_scan_required,
-
-       /* Message functions */
-       imap_get_msginfo,
-       imap_get_msginfos,
-       imap_fetch_msg,
-       imap_add_msg,
-       imap_add_msgs,
-       imap_copy_msg,
-       imap_copy_msgs,
-       imap_remove_msg,
-       imap_remove_all_msg,
-       imap_is_msg_changed,
-       imap_change_flags,
-};
+static FolderClass imap_class;
 
 FolderClass *imap_get_class(void)
 {
+       if (imap_class.idstr == NULL) {
+               imap_class.type = F_IMAP;
+               imap_class.idstr = "imap";
+               imap_class.uistr = "IMAP4";
+
+               /* Folder functions */
+               imap_class.new_folder = imap_folder_new;
+               imap_class.destroy_folder = imap_folder_destroy;
+               imap_class.scan_tree = imap_scan_tree;
+               imap_class.create_tree = imap_create_tree;
+
+               /* FolderItem functions */
+               imap_class.item_new = imap_folder_item_new;
+               imap_class.item_destroy = imap_folder_item_destroy;
+               imap_class.item_get_path = imap_item_get_path;
+               imap_class.create_folder = imap_create_folder;
+               imap_class.rename_folder = imap_rename_folder;
+               imap_class.remove_folder = imap_remove_folder;
+               imap_class.close = imap_close;
+               imap_class.get_num_list = imap_get_num_list;
+               imap_class.scan_required = imap_scan_required;
+
+               /* Message functions */
+               imap_class.get_msginfo = imap_get_msginfo;
+               imap_class.get_msginfos = imap_get_msginfos;
+               imap_class.fetch_msg = imap_fetch_msg;
+               imap_class.add_msg = imap_add_msg;
+               imap_class.add_msgs = imap_add_msgs;
+               imap_class.copy_msg = imap_copy_msg;
+               imap_class.copy_msgs = imap_copy_msgs;
+               imap_class.remove_msg = imap_remove_msg;
+               imap_class.remove_all_msg = imap_remove_all_msg;
+               imap_class.is_msg_changed = imap_is_msg_changed;
+               imap_class.change_flags = imap_change_flags;
+               imap_class.get_flags = imap_get_flags;
+       }
+       
        return &imap_class;
 }
 
@@ -666,13 +665,13 @@ static IMAPSession *imap_session_get(Folder *folder)
                        /* Check if this is the first try to establish a
                           connection, if yes we don't try to reconnect */
                        if (rfolder->session == NULL) {
-                               log_warning(_("Connecting %s failed"),
+                               log_warning(_("Connecting to %s failed"),
                                            folder->account->recv_server);
             &nbs