diff options
Diffstat (limited to 'mail')
66 files changed, 0 insertions, 31837 deletions
diff --git a/mail/.cvsignore b/mail/.cvsignore deleted file mode 100644 index 63d45eccce..0000000000 --- a/mail/.cvsignore +++ /dev/null @@ -1,14 +0,0 @@ -.deps -.libs -.pure -Makefile -Makefile.in -Mail-stubs.c -Mail-skels.c -Mail-common.c -Mail.h -evolution-mail -evolution-mail.pure -test-mail -test-sources -test-thread
\ No newline at end of file diff --git a/mail/ChangeLog b/mail/ChangeLog deleted file mode 100644 index 6340d44bfa..0000000000 --- a/mail/ChangeLog +++ /dev/null @@ -1,6070 +0,0 @@ -2000-11-06 Kjartan Maraas <kmaraas@gnome.org> - - * mail-autofilter.c: Fix up #include <config.h> - * mail-crypto.c: Same here. - * mail-search-dialog.c: Here too. - * main.c: Fix indentation of #ifdef - * message-thread.c: Fix include. - -2000-11-06 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-callbacks.c (delete_msg): Don't invert the flag. - (undelete_msg): Same (when multiple messages are selected). - -2000-11-06 Jeffrey Stedfast <fejj@helixcode.com> - - * folder-browser-factory.c: Updated to have the same menu items as - the new right-click menu - eventually these 2 menus should be the - same. - - * folder-browser.c (on_right_click): Now correctly handles the - case of multiple selection. - - * mail-callbacks.c (enumerate_msg): Make public so it can be used - in other source files (it's a useful function!) - -2000-11-05 Jeffrey Stedfast <fejj@helixcode.com> - - * folder-browser.c (on_right_click): Added an "Undelete" option to - the right-click menu and also set a mask so it was only selectable - if the message is marked as deleted. Also set a mask for "Mark as - Read" and "Mark as Unread". - - * mail-callbacks.c (undelete_msg): New callback to undelete - messages. - -2000-11-03 Dan Winship <danw@helixcode.com> - - * message-list.c (cleanup_regenerate_messagelist): don't free the - MessageList search when it's being reused - -2000-11-03 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-local.c (mail_local_map_uri): Don't show the passwd in the - url string. - (mail_tool_local_uri_to_folder): Same. - (do_reconfigure_folder): Same. - -2000-11-03 Jeffrey Stedfast <fejj@helixcode.com> - - * Makefile.am: Added new header files. - - * component-factory.c (owner_set_cb): - s/session_init/mail_session_init - - * session.c: Renamed public functions to mail_session_*. - FIXME: Rename session.c to mail-session.c - - * folder-browser-factory.c: #include "mail-callbacks.h", #include - "mail-session.h" and replace forget_passwords with - mail_session_forget_passwords - - * mail.h: Move session prototypes to mail-session.h, Move - mail-crypto prototypes to mail-crypto.h, Move mail-callback - prototypes to mail-callbacks.h - - * mail-session.h: New header file containing public prototypes - for session.c - - * mail-format.c: #include "mail-crypto.h" - - * mail-view.c: - * folder-browser.c: #include "mail-callbacks.h" - - * mail-crypto.h: New header file containing public prototypes - for mail-crypto.c - - * mail-callbacks.h: New header file containing public prototypes - for mail-callbacks.c - - * message-list.c (message_list_get_layout): Set useful defaults. - (message_list_setup_etable): Don't set the Outbox defaults on a - folder just because it doesn't have a corresponding saved file. - -2000-11-03 Dan Winship <danw@helixcode.com> - - * mail-config-gui.c (service_page_item_new): url_flags are now on - CamelProvider, not CamelService - - * main.c: - * subscribe-dialog.c: - * mail-threads.c: Kill warnings - -2000-11-03 Federico Mena Quintero <federico@helixcode.com> - - * Makefile.am: Clean the idl-generated files properly. - -2000-11-03 Not Zed <NotZed@HelixCode.com> - - * mail-view.c: Added mail-display.h. - - * mail-autofilter.c: Removed unecessary headers. Who ran indent - over this code? Sigh. - - * mail-ops.c (display_message_input_s): Added messagedisplay. - (mail_do_display_message): Added messagedisplay arg. - (mail_do_display_message): Dont bother doing another thread when - we know we dont have a uid. - (): Added folder-browser.h to headers. Sigh. - - * folder-browser-factory.c (control_activate): Setup the - viewthreaded callback to the folder_browser function. - - * folder-browser.c (my_folder_browser_init): Connect to - right_click of etable of the messagelist here. - (on_right_click): Changed for argument changes. - (folder_browser_toggle_threads): Changed to take a fb, and to set - threaded mode on the messagelist. - (my_folder_browser_init): Connect also to the double_click signal. - (my_folder_browser_init): Connect to the message_selected signal - of the message_list. - (on_message_selected): Signal handler for message selected. - (my_folder_browser_init): Fix for change to message_list_new(). - - * message-list.h: Dont include folder-browser.h. - (message_list_toggle_threads): Moved into folder-browser.h. - (struct _MessageList): Removed folderbrowser. - - * mail.h: Dont include folder-browser.h here either, but - mail-types.h instead. - Moved prototypes moved into folder-browser.c into - folder-browser.h. (vfolder_*, filter_*). - - * mail-display.h: Dont include folder-browser.h here, but - mail-types.h and specific camel headers. - - * message-thread.c (sort_node): Invert the sort order logic so the - list is sorted in mailbox order, not reverse mailbox order. - - * message-list.c (free_tree_ids): Fix a merge foo. - (remove_node_diff): Removed unused row argument. Fixed - callers/prototype. - (clear_tree): pre_change on the removal of the root node. - (build_flat): Only perform pre_change if we are rebuilding the - whole lot. For incremental change let etable do its thing. - (build_tree): Likewise for building the tree view. If making - incremental updates, do them as we build it. - (vfolder_subject): - (vfolder_sender): - (vfolder_recipient): - (filter_subject): - (filter_sender): - (filter_recipient): - (filter_mlist): - (on_right_click): Moved to folder-browser.c, where they belong. - (message_list_init): Dont connect to right_click anymore. - (message_list_toggle_threads): Moved to folder-browser.c, renamed. - (on_double_click): Moved to folder-browser.c - (on_click): Set the flags directly, rather than in anothre thread, - which is just not necessary. - (message_list_class_init): Added a new signal 'message_selected', - to indicate when a message was selected. - (on_cursor_change_idle): Emit a signal, rather than directly - triggering the display update. - (select_row): Removed, no longer used. - (idle_select_row): And this too. - (select_msg): Removed as well. - (message_list_select): Emit a signal, rather - thandisplaying/clearing the mail-display directly. - (mark_msg_seen): Moved to folder-browser.c - (message_list_new): Removed folderbrowser argument. - -2000-11-02 Jeffrey Stedfast <fejj@helixcode.com> - - * message-list.c (on_right_click): Sync with message - menu. Addresses bugzilla bug #778. - -2000-11-02 Christopher James Lahey <clahey@helixcode.com> - - * message-list.c: Turn on draw grid for the main ETable (this may - not be working in ETable itself.) - -2000-11-01 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-threads.c (mail_op_set_message): fmt argument should be - const. - -2000-11-01 Dan Winship <danw@helixcode.com> - - Make "Get Mail" even more functional on IMAP (scans all folders), - and do a first cut at folder tree highlighting (for IMAP/news - only). - - * mail-ops.c (do_fetch_mail): For imap (sigh, we *still* shouldn't - be hardcoding that), rescan the store's folder tree, rescan each - changed folder for new messages, and update the shell folder tree. - (do_scan_subfolders): Update for component-factory.c changes, and - set folder display names and highlights appropriately when - building the storage. - - * component-factory.c (add_storage): Make this static (was - mail_add_new_storage). Use camel_service_get_name for the name - rather than url->host. (Among other things, this lets you use a - single machine as both an IMAP server and a news server.) - (mail_lookup_storage): Hash storages based on their CamelStore - rather than the URL. - (factory_destroy): Disconnect each of the CamelStores in the - storages_hash. - - * subscribe-dialog.c (cleanup_subscribe_folder): - * mail-vfolder.c (vfolder_refresh): Pass "highlighted" flag to - evolution_storage_new_folder - -2000-11-01 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-ops.c (mail_op_report_status): Don't call the default - logging function. - (do_fetch_mail): Set the logfile and don't pass the logfile to - filter_driver_set_status_func - it's purpose has been altered. - (do_filter_ondemand): Same. - -2000-11-02 Not Zed <NotZed@HelixCode.com> - - ** Merged in camel-incremental-branch. - - * mail-format.c (mail_get_message_body): Jeff! Sigh. - We should definetly not be strduping the - content, it has already been copied and duplicated. Look at - get_data_wrapper_text. - -2000-11-01 Chris Toshok <toshok@helixcode.com> - - * subscribe-dialog.h: add fields search_entry and search_top. - - * subscribe-dialog.c: add mail-ops.c style async operations for - getting the store (to remove deadlock in the case where a auth - dialog is dismissed at startup and then the subscribe dialog is - brought up), and subscribing/unsubscribing to folders. One case - remains, that is getting the list of all folders. - (subscribe_search): flesh out this function - (build_tree): use the search_top field so we can search for - groups/folders. - (subscribe_dialog_destroy): free search_top. - (subscribe_dialog_construct): init search_top. - -2000-10-30 Iain Holmes <iain@helixcode.com> - - * mail-summary.c (generate_folder_summaries): Fix spelling :) - Set folder->uri to NULL for the Inbox. - -2000-10-26 Iain Holmes <iain@helixcode.com> - - * mail-summary.c (generate_html_summary): Add view:// uris to - switch the display to that folder. - -2000-11-01 Jeffrey Stedfast <fejj@helixcode.com> - - * folder-browser-factory.c: Hmmm, someone can't spell Filder, - er...I mean Filter ;-) - -2000-11-01 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-autofilter.c (rule_from_message): If the name is NULL or - empty, then set the title to "Mail from <address>". Closes - bugzilla bug #777. Also when filtering on Subject, set the file - name to "Subject is <subject>" rather than just "<subject>" - I - think this is a bit more user-friendly. - (strip_re): Use unsigned char when passing to is<type>() - functions from ctype.h. - (rule_add_subject): Use the "is" rule instead of "contains". - -2000-11-01 Jesse Pavel <jpavel@helixcode.com> - - * mail-display.c: added property bag support for Bonobo - controls, support which helps only the iTip control, currently. - -2000-11-01 Dan Winship <danw@helixcode.com> - - * mail-display.c (pixbuf_gen_idle): Lots of fixes and - simplifications. Should get rid of the "missing icon" problem. - There is still a problem with some images failing to get - thumbnails, even though they display correctly. - (pixbuf_for_mime_type): New function to try really hard to get the - right icon for a MIME type, including looking in mc and nautilus's - pixmap directories. - (on_object_requested): Always use pixbuf_gen_idle, even for - non-image types, to prevent code duplication. - -2000-10-31 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-format.c (mail_get_message_body): Shouldn't we be - strdup'ing the content? This seems to fix the memory corruption - problems. - (mail_generate_reply): Make sure that the last char in the - generated reply text is '\0' (when body text doesn't end with a - \n, a random char will appear otherwise). - -2000-10-31 Dan Winship <danw@helixcode.com> - - * mail-config-gui.c (do_test_service): Update for - camel_service_disconnect change. - -2000-10-31 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-autofilter.c (filter_gui_add_for_mailing_list): Match "is" - rather than "contains" now that we have the "is"-rule. - -2000-10-30 Dan Winship <danw@helixcode.com> - - * mail-config-gui.c (config_do_query_authtypes): Redo this so that - it works for all pages, not just the first page. (Now that this is - finally working again, I expect Anna to finish her redesign in the - next 15 minutes.) - (service_page_item_new): Fix up the sizing of the Auth line to - look more like everything else. - -2000-10-29 Dan Winship <danw@helixcode.com> - - * mail-tools.c (mail_tool_uri_to_folder): Simplify this a lot by - making IMAP and NNTP use the same code, now that the IMAP - namespace doesn't need special magic handling. - - * message-list.c (mail_do_regenerate_messagelist): Don't try to - regenerate the message list if there is no folder. (The Bonobo UI - code will call this as the callback for the "Threaded View" - command.) - - * mail-ops.c (do_fetch_mail): Sync the folder before refreshing so - we don't lose flag settings. - -2000-10-27 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-callbacks.c (composer_send_cb): Check to make sure that the - recipient list is neither NULL nor a 0-length list of addresses - and pop up a dialog letting the user know why we are not allowing - him/her to send the message. - -2000-10-26 Dan Winship <danw@helixcode.com> - - * mail-display.c (write_data_to_file): Don't destroy a dialog - after run_and_close'ing it. - -2000-10-26 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-callbacks.c (composer_send_cb): Check for the TO recipient - list being NULL and don't send. - -2000-10-25 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-ops.c (do_send_mail): Don't forget to unref the - FilterDriver. - - * mail-callbacks.c (apply_filters): New callback for applying - on-demand filters. (removed the old on-demand filters callback). - - * mail-ops.c (do_filter_ondemand): Rewrote to apply "incoming" - filters to all selected messages. - (mail_do_filter_ondemand): No longer takes a FilterContext - argument or a destination folder argument (why did we ever need - this last one??) but now takes a uids argument. - - * folder-browser-factory.c: Add a MessageApplyFilters menu item. - -2000-10-25 Iain Holmes <iain@helixcode.com> - - * mail-summary.[ch]: Updated for the new ExecutiveSummary code. - - * Makefile.am: Added the summary files and the evolution-services CFLAGS - and LIB stuff. - - * component-factory.c: Re-enabled the summary stuff. - -2000-10-25 Dan Winship <danw@helixcode.com> - - * main.c (main): Pass send/postpone signal handler functions to - evolution_composer_factory_init. - -2000-10-25 Jeffrey Stedfast <fejj@helixcode.com> - - * subscribe-dialog.c (subscribe_select_all): Implemented. - (subscribe_invert_selection): (was unselect_all) Implemented. - -2000-10-25 Dan Winship <danw@helixcode.com> - - * message-list.c: Add a "flagged" column, based on the Camel - "flagged" flag, for assigning an arbitrary "hey, I care about - this" flag to a message. - (ml_tree_set_value_at): Remove - (ml_tree_is_cell_editable): No, it's not. - (on_click): Handle the read/unread and flagged fields via the - click handler. Among other things, this makes it not select - a message when you change its read status. - -2000-10-24 Dan Winship <danw@helixcode.com> - - * subscribe-dialog.c (folder_info_subscribed, - subscribe_folder_info, unsubscribe_folder_info): Don't prepend "/" - to the folder's full_name. Deal with hierarchy in the - EvolutionStorage tree better. - (storage_tree_path): Helper function to build a storage path from - a CamelFolderInfo. - -2000-10-23 Dan Winship <danw@helixcode.com> - - * *: Add some missing _()s and N_()s. - -2000-10-23 Dan Winship <danw@helixcode.com> - - * Makefile.am (INCLUDES): Update EVOLUTION_LOCALEDIR. - -2000-10-23 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-ops.c (do_send_mail): Apply outgoing filters to the - message. - -2000-10-23 Christopher James Lahey <clahey@helixcode.com> - - * message-list.c: Fixed a possible error in row numberings. This - needs to be changed quite a bit anyway, but this should make - things slightly nicer in some cases. - -2000-10-23 Christopher James Lahey <clahey@helixcode.com> - - * folder-browser.c: Made the top of the folder browser a little - prettier. - - * mail-display.c, mail-vfolder.c: Made more dialogs resizable. - -2000-10-23 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-autofilter.c (filter_gui_add_from_message): Don't forget to - set the rule source! (eg "incoming", "demand", or "outgoing") - -2000-10-22 Ettore Perazzoli <ettore@helixcode.com> - - * message-list.c (message_list_init): Always display the vertical - scrollbar. - - * mail-display.c (mail_display_new): Always display the vertical - scrollbar. - -2000-10-20 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-config.h: #include <camel/camel-folder.h> - -2000-10-20 Michael Meeks <michael@helixcode.com> - - * mail.h: s/BonoboUIHandler/BonoboUIComponent/ - - * mail-callbacks.c (run_filter_ondemand): ditto. - - * session.c (forget_passwords): ditto. - -2000-10-20 Dan Winship <danw@helixcode.com> - - * evolution-mail.oafinfo: Declare composer factory. - - * main.c (main): Initialize it - -2000-10-19 Chris Toshok <toshok@helixcode.com> - - * message-list.c (nuke_uids): e-tree-model is now opaque. use the - accessor to get the root node. - -2000-10-19 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-callbacks.c: #include "mail-vfolder.h" - (vfolder_edit_vfolders): Don't call the dummy vfolder_edit - function. - - * folder-browser-factory.c: s/VFolderEdit/SetVFolder - -2000-10-19 Dan Winship <danw@helixcode.com> - - * mail-ops.c: (do_fetch_mail): For an imap store, just refresh the - INBOX. - - * folder-browser-factory.c (control_deactivate): Don't sync - non-existent folders. - * message-list.c (nuke_uids): Don't traverse non-existent trees. - -2000-10-19 Ettore Perazzoli <ettore@helixcode.com> - - * Makefile.am (glade_messages): New. - (EXTRA_DIST): Add `$(glade_messages)'. - -2000-10-19 Dan Winship <danw@helixcode.com> - - * mail-ops.c: Clean up some old #if 0 code. - -2000-10-19 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-format.c (mail_generate_reply): Get the MailConfigIdentity - *before* we create a new composer object so that we can set the - signature file. - -2000-10-18 Michael Meeks <michael@helixcode.com> - - * folder-browser-factory.c (register_ondemand): kill. - (create_ondemand_hooks): die. - (control_activate): remove hook. - - * test-mail.c (create_container): kill old UI handler. - -2000-10-18 Christopher James Lahey <clahey@helixcode.com> - - * message-list.c: Fixed some column widths. - -2000-11-02 Not Zed <NotZed@HelixCode.com> - - * message-list.c (get_message_info): Call get_message_uid to get - the uid, save some duplicated code. - (folder_changed): Handle the case of a NULL changes input. - - * message-thread.c (thread_messages): Removed pointless - variable/assignment 'container'. - (thread_messages): Try and cope with duplicate message id's. - -2000-11-01 Not Zed <NotZed@HelixCode.com> - - * mail-callbacks.c (main_select_first_unread): Changed to use 0 as - the first row to select a message. - - * mail-ops.h (mail_do_regenerate_messagelist): Removed from - header. This function is no longer public since it is really an - internal message-list function. - - * folder-browser.c (search_full_clicked): Call the set_search() - function, rather than messagelist_rebuild, which is going private. - (search_set): Same here. - (folder_browser_clear_search): And here. - (etable_key): Call message_list_select() instead of - message_list_home and message_list_end. Removing some odd code - duplication. - - * message-thread.c (do_thread_messages): Moved the mail lock to - here, rather than locking for each message lookup (which is - useless anyway). This is still not correct either, as the tree - references folder data ... but a bit better than it was. - (thread_messages): Removed the mail tool lock stuff, lock in - higher functions. - - * message-list.h: Added a threaded indicator to the message list - itself. - (threaded_view): removed a mystery variable. - - * message-list.c (do_regenerate_messagelist): Made the code a - little more readable. - (build_tree): Fixed argument to be a thread_messages struct, not a - container. - (cleanup_regenerate_messagelist): Free changeinfo. - (mail_do_regenerate_messagelist): If we are adding changes to a - flat view, we dont need to goto the other thread at all, so - process immediately. - (message_list_toggle_threads): Clear the tree if we're changing - the view mode. - (message_list_toggle_threads): And reset the rowmap, since it is no - longer valid. - (build_tree): If we are building into an already empty tree, just - build into that (probably irrelevant optimisation). - (build_subtree): Build hte subtree in the same order as we got it, - not inverted order. - (message_list_set_threaded): New function to select the threaded - view/flat view. - (mail_do_regenerate_messagelist): Removed references to - mail_config, get it from the ml->threaded var instead. - (message_list_destroy): No longer free the key data for the - uid_rowmap. - (new_id_from_uid): Convert a uid string into an id string. - (new_id_from_subject): Likewise for subject strings. - 'id' strings replace the 'uid:' and 'subject:' stuff with - accessors and macros and use less memory and is more readable. - (id_is_uid): macro to check if an id string is a uid. - (id_uid): Returns the uid part of a uid id string. - (id_subject): Returns the uid part of a subject id string. - (build_subtree): Use the new id functions, and dont duplicate the - uid in the uid rowmap, but just reference it from the tree node. - (node_equal): Use new id functions. - (add_node_diff): And here too. - (remove_node_diff): And here. Also remove the uid from the - rowmap, and dont free it anymore. - (get_message_info): And here. - (get_message_uid): And here. - (subtree_unread): And here. - (ml_tree_value_at): " - (ml_tree_set_value_at): Noted a memory leak. do_flag_messages() - doesn't free the contents of the uid array, just the uid array - (well that i can tell, teh code has more problems anyway). - (ml_tree_set_value_at): And fix the id accessors. - (save_node_state): " - (build_flat): Use id macros/functions. Dont alloc memory for hash - key. - (build_flat_diff): Use id macros. - (build_flat_diff): Remove the hash table entry before freeing its - key data (in the node). - (free_key): Removed. Keys are no longer alloc'd. - (clear_tree): When we clear the tree, also clear the uid_rowmap, - as it is no longer valid (or contains allocated keys!). - (free_tree_ids): Renamed from nuke_uids. - (free_ids_cb): Renamed from nuke_uids_cb. - (free_tree_ids): Changed arg to be a ETreeModel directly. - (ml_tree_value_at): Map id to subject using the right macro. - (free_tree_ids): Check we have any nodes to traverse first. - (build_flat): Insert to row -1 to append the nodes (faster). - (remove_node_diff): Only remove the uid rowmap entry if it is - referencing this node (i.e. the key string is the same key string, - not just a matching key string). - (add_node_diff): Remove the uid rowmap entry before inserting a - new one to force the key to be replaced. This is required as the - tree may temporarily contain duplicate messages during the - rebuilding phase. - (message_list_set_search): New function, set the search string. - Only redo the search if it has changed, etc. - (mail_do_regenerate_messagelist): Made static. There is no need - for external code to call this. - (message_list_set_folder): NOP if the new folder is the same. - (message_list_set_folder): Clear the tree before rebuilding it. - (message_list_select): Ok, this wins the award for 'most bizarre - interface'. Changed the start row to mean the end of the list if - we supply -1, rather than the start of the list. Also fixed the - endpoints (it would never select message 0 if searching - backwards). - (idle_select_row): Changed start row to 0 from -1. - (message_list_end): Removed. - (message_list_home): Removed. - (go_to_message): Removed. message_list_select can do this. - (message_list_select): Check that direction is one of the valid - ones, otherwise we could be thrown for loops. - -2000-10-31 Not Zed <NotZed@HelixCode.com> - - * message-list.c (node_equal): Compares an etree node with a - message-thread node to see if they point to the same object. - (add_node_diff): Adds a new thread node to the etree. - (remove_node_diff): Removed an etree node, freeing any additional - data. - (build_subtree_diff): Takes an existing etree definition, and a - new thread definition and makes the etree match, using as few - operations as possible. - (do_regenerate_messagelist): No longer free/clear the uid/rowmap - here. - (regenerate_messagelist_input_t): Added a tree field - are we - building a tree view? - (regnerate_messagelist_data_t): Added a tree field, if we built a - tree result. Added a changes parameter, for building diff's after - search/etc. - (mail_do_regenerate_messagelist): Setup the tree indicator. - (build_flat_diff): Apply a changeset to a message list. - (build_flat): Added a changes argument, if present, use - build_flat_diff() to build the list. - (do_regenerate_messagelist): If we are generating a threaded view, - build the threaded list here, rather in another separate - invocation. - (cleanup_regenerate_messagelist): Call build_tree directly on the - threaded list. - (message_list_init): Init the uid_rowmap hash table here instead - of somewhere odd. - (message_list_destroy): Assume uid_rowmap exists. - (do_regenerate_messagelist): Remove the code here that is messing - with the message list data (search/uid_rowmap). We're in a - different thread boys ... - -2000-10-26 Not Zed <NotZed@HelixCode.com> - - * message-list.c (cleanup_regenerate_messagelist): Fixed some - logic to make more sense (gboolean)!pointer replaced with - (pointer != NULL). - (build_tree): Put the tree pre/post change stuff in here, where it - should be. - (build_flat): Same here. - (cleanup_regenerate_messagelist): Remove model_changed stuff here. - (setup_regenerate_messagelist): Remove pre_change stuff here. - -2000-10-20 Not Zed <NotZed@HelixCode.com> - - * message-list.c (main_folder_changed): Perform incremental update - of the display for flat view. - (ml_tree_value_at): Spit out a mroe meaningful warning when we - can't find the uid in our tree, in the folder. - - * message-thread.c (thread_messages): Made public. - (thread_messages_free): Made public. - (thread_messages): Now we also return a struct _thread_messages, - which is passed to other functions. - (container_free): Renamed from thread_messages_free. - (thread_messages_free): Take a thread_messages argument. - (thread_messages_add): New function to add a list of uid's to the - thread list. - (thread_messages_remove): Likewise, for removing them. - (cleanup_thread_messages): Change for struct changes. - (do_thread_messages): Likewise. - -2000-10-19 Not Zed <NotZed@HelixCode.com> - - * mail-tools.c (mail_tool_do_movemail): removed unused var - - * folder-browser.c (search_full_clicked): Fix for api changes, - such as it can be called an api, its mroe an utter mess infact. - (search_set): Same. - (search_set): And here. - (folder_browser_clear_search): And here. - - * message-list.c (folder_changed): Copy and forward the changeinfo - list to the mian thread. - (main_folder_changed): Free the changeinfo. Todo: something smart - with this information. - (struct regenerate_messagelist_input_s): Added a changes field. - (mail_do_regenerate_messagelist): Added a change list argument. - (message_list_set_folder): Fix for mail_do_regenreate_messagelist - api. - (message_list_toggle_threads): Same. - -2000-10-18 Iain Holmes <iain@helixcode.com> - - * mail-config-gui.c (mail_config): Make all the CLists have passive - titles. - (identity_dialog): Make the default button the "OK" button, and set - the dialog to close on pressing return on the entryboxes. - -2000-10-17 Iain Holmes <iain@helixcode.com> - - * mail-config-gui.c (service_page_item_new): Disable the optionmenu - because it is empty. - (service_page_item_auth_fill): Enable the optionmenu as there's stuff - in it now. - - * mail-callbacks.c (reply_to_sender): Call check_send_configuration - when we have the FolderBrowser because if it is done in mail_reply - (with passing NULL) it will only be able to continue if the mailer - has already been configured. - (reply_to_all): Same. - -2000-10-18 Not Zed <NotZed@HelixCode.com> - - * folder-browser.c (folder_browser_gui_init): No, we REALLY dont - want to perform an immediate search as the keys are pressed. - - * mail-display.c (on_object_requested): Kill a minor warning with - a cast. - - * mail-config.c: Include mising ctype.h to kill a warning. - - * message-thread.c (main): Fixed the test case for api changes. - - * message-list.c (message_list_drag_data_get): Set some flags to - get_folder(). I dont even think this will work because - mail_tool_get_folder doesn't handle file url's. - - * mail-vfolder.c (vfolder_uri_to_folder): Pass appropriate flags. - - * mail-ops.c (do_setup_folder): Pass appropriate flags. Hmm, - whats the difference between setup and create. *shrug* - (do_create_folder): Pass appropriate flags to get_folder. Needs a - way to specify the index flag. - - * mail-tools.c (mail_tool_get_folder_from_urlname): Changed create - to flags argument. - (mail_tool_get_local_inbox_url): Add an index argument. - (mail_tool_get_local_inbox): honour index flag. - (mail_tool_get_inbox): Changed for api change. - (mail_tool_uri_to_folder): Fixed calls to store_get_folder(); - - * mail-local.c (load_metainfo): Added an indexed field to the metainfo. - (save_metainfo): And save it too. - (do_reconfigure_folder): Honour index flag when creating the new - folder. Do not open the old folder with an index at all. - (mail_local_map_uri): Add an index argument - tells if the mbox is - indexed. - (mail_tool_local_uri_to_folder): Create & pass flags properly. - (#include gnome.h): Dont include all of gnome, just what we use, - and explicity include xml-memory, so we get xmlFree(). - -2000-10-16 Jeffrey Stedfast <fejj@helixcode.com> - - * folder-browser.c (search_full_clicked): Un #if 0'd out - (search_full): Same. - (folder_browser_gui_init): Connect search_full and search_activate. - (search_set): Uncomment search_full() - - * Makefile.am: Re-add `mail-search-dialogue.h' and - `mail-search-dialogue.c'. - -2000-10-16 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-format.c (mail_generate_reply): Decode recipient names so - that they display nicely in the To and Cc fields. - (write_field_to_stream): Now takes another argument - 'value_is_encoded' so that we know if we should decode that string - before proceding onward. Since the message subject is already - decoded before it's passed in, we don't want to decode it again - (wasted cpu time and/or any 8bit chars will be assumed to be - latin1 encoded and thus the decoded value will be corrupt). - -2000-10-16 Chris Toshok <toshok@helixcode.com> - - * mail-config-gui.c (service_page_get_url): only set the url->user - field if the user string is non-NULL and not empty. - -2000-10-16 Not Zed <NotZed@HelixCode.com> - - * message-list.c (message_list_setup_etable): Uh, fixed jeff's - wrong fix for setting the speficiation (the function changed to - set_state(), as can be seen in the e_table-scrolled_load_state() - call only 2 lines above). - -2000-10-13 Not Zed <NotZed@HelixCode.com> - - * message-list.c (message_list_setup_etable): oops, chose the - wrong thing to cut out after a merge conflict. - -2000-10-15 Chris Toshok <toshok@helixcode.com> - - * message-list.c (subtree_unread): ETreePath != GNode now, use - accessors. - (ml_tree_value_at): same. - (save_node_state): same. - (save_tree_state): same. - (nuke_uids_cb): convert to e_tree_model_node_traverse required - type. - (nuke_uids): g_node_traverse -> e_tree_model_node_traverse. - -2000-10-14 Ettore Perazzoli <ettore@helixcode.com> - - * evolution-mail.oafinfo: Add "evolution:shell-component-icon" - attribute. - -2000-10-13 Jeffrey Stedfast <fejj@helixcode.com> - - * message-list.c (message_list_setup_etable): Don't free the - service name. - -2000-10-12 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-ops.c (do_fetch_mail): sync & expunge the source folder - after filtering. - -2000-10-12 Jeffrey Stedfast <fejj@helixcode.com> - - * message-list.c (message_list_setup_etable): Create the 'spec' - and 'extras' arguments and call e_table_scrolled_new() rather than - set_specification as that function no longer (?) exists. - - Also started to add drag & drop functionality to something like - Nautilus (but #if 0'd it out until I had time to finish it and - till after 0.6). - -2000-10-12 Not Zed <NotZed@HelixCode.com> - - * message-list.c (message_list_setup_etable): Duh, fix the test - for the folder name, strstr != strcmp is it. - -2000-10-10 Not Zed <NotZed@HelixCode.com> - - * message-list.c (folder_to_cachename): Removed, changed callers - to use mail_config_folder_to_cachename instead. - - * mail-config.c (mail_config_folder_to_cachename): New utility - function to get a cache name for a folder. - - * mail-tools.c (mail_tool_do_movemail): Changed to return the path - to the mbox, rather than opening a folder of it. - - * mail-ops.c (mail_incorporate_messages): Dont bother making the - pseudo messageinfo, filder_driver_filter_message will do it for - us. - (report_status): Callback to report status of filtering operation. - (do_fetch_mail): Changed significantly - for the api changes to - the filtering system. Also now incorporates a mailbox file - directly, without having to import it into a camel folder first. - (mail_incorporate_messages): Removed entirely, no longer needed. - - * mail-vfolder.c (vfolder_refresh): Fix for context api changes. - (vfolder_uri_to_folder): Likewise. - - * folder-browser-factory.c (create_ondemand_hooks): Changed for - api changes. Also only adds demand filters to the menu (fixed a - small logic bug). - -2000-10-11 Chris Toshok <toshok@helixcode.com> - - * subscribe-dialog.c (folder_etree_value_at): special case for - folders with NULL urls (which aren't selected/subscribeable). - (unsubscribe_folder_info): can't (un)subscribe from folders with - non-NULL urls. - (subscribe_folder_info): same. - -2000-10-12 Christopher James Lahey <clahey@helixcode.com> - - * message-list.c: Replace To with From except in Drafts, Outbox, - or Sent boxes. Make Subject column pay attention to text - attributes like bold and strikethrough. - -2000-10-12 Iain Holmes <iain@helixcode.com> - - * component-factory.c: Disable the executive summary. - -2000-10-11 Chris Toshok <toshok@helixcode.com> - - * subscribe-dialog.c (FOLDER_ETABLE_SPEC): set expansion to 0.0, - minimum-width to 16, and resizable to false for the subscribed - column. - (folder_info_subscribed): new function so we can do the correct - path munging. - (subscribe_folder_info): only add the folder to the storage if - there wasn't an exception subscribing it. - (unsubscribe_folder_info): same, but unsubscribing. - (folder_etree_value_at): use folder_info_subscribed. - (folder_toggle_cb): same. - (unsubscribe_folder_foreach): same. - (subscribe_folder_foreach): same. - (subscribe_dialog_gui_init): set the bold column on the text cell, - and add the subscribed pixbuf. - -2000-10-11 Anna Marie Dirks <anna@helixcode.com> - * mail-threads.c: Changed the password-getting dialog so that the - text entry has focus. - -2000-10-11 Chris Toshok <toshok@helixcode.com> - - * subscribe-dialog.c (STORE_ETABLE_SPEC): change cell type to - "string" since we're not including it in the extras. - -2000-10-11 Christopher James Lahey <clahey@helixcode.com> - - * message-list.c, message-list.h, subscribe-dialog.c: Changed - these to use the proper form for the column element. - -2000-10-11 Christopher James Lahey <clahey@helixcode.com> - - * message-list.c, message-list.h, subscribe-dialog.c: Updated - these to the new ETable style of specifications. - -2000-10-11 Chris Toshok <toshok@helixcode.com> - - * subscribe-dialog.c (subscribe_dialog_gui_init): convert to the - new gal e-table stuff. - (html_size_req): - (html_new): - (put_html): #if 0 out the html functions since description stuff - isn't used and we don't want the warnings. - -2000-10-11 Chris Toshok <toshok@helixcode.com> - - * subscribe-dialog.c (subscribe_dialog_gui_init): remove the html - description stuff for now. - -2000-10-10 Chris Toshok <toshok@helixcode.com> - - * subscribe-dialog.c (folder_toggle_cb): umm.. duh :) only - subscribe if it's not subscribed, and vice versa. - (subscribe_folder_foreach): make sure to call - e_tree_model_node_changed. - (unsubscribe_folder_foreach): make sure to call - e_tree_model_node_changed. - -2000-10-10 Chris Toshok <toshok@helixcode.com> - - * mail-ops.c (setup_scan_subfolders): add a ref to input->storage - here so that the ref/unref pattern more closely matches other - mail-ops. also, this keeps the storage from being freed when we - hit the unref in cleanup_scan_subfolders, which is important - because we maintain a reference to it in the storage_hash in - component-factory.c - - * subscribe-dialog.h: add storage field. - - * subscribe-dialog.c (subscribe_folder_info): new function, - subscribe to a folder given it's CamelFolderInfo, and add it to - the shell - we're generating a path from the name of the folder - which is bad. - (unsubscribe_folder_info): same (except we unsubscribe and remove - from the shell). - (storage_selected_cb): unref the currently selected storage. - (subscribe_dialog_destroy): unref the currently selected storage. - (subscribe_dialog_construct): sc->storage = NULL. - - * component-factory.c (mail_lookup_storage): new function, to look - up a EvolutionStorage corresponding to a CamelService. we ref the - EvolutionStorage before passing it back. - (mail_add_new_storage): insert the storage into storages_hash if - result is EVOLUTION_STORAGE_OK. - - * mail.h: add prototype for mail_lookup_storage. - -2000-10-10 Larry Ewing <lewing@helixcode.com> - - * mail-format.c (mail_generate_reply): make sure we dup the return - value of get_reply_to or get_from when building the recipient list. - -2000-10-10 Iain Holmes <iain@helixcode.com> - - * mail-summary.c (generate_html_summary): Removed the <li> from the - HTML. - -2000-10-10 Cody Russell <bratsche@gnome.org> - - * mail-threads.c: Added #include <errno.h> - -2000-10-09 Iain Holmes <iain@helixcode.com> - - * mail-summary.c: Removed the extra arguments to rule_context_load. - -2000-10-09 Chris Toshok <toshok@helixcode.com> - - * subscribe-dialog.c, subscribe-dialog.h: use our own etable to - display the stores, and get them from the mail-config api. put - #if 0'ed code in place to add/remove the folders from the shell - when they're subscribed/unsusbcribed. also, react to double - clicks in the folder etable by toggling subscription status. - -2000-10-08 Iain Holmes <iain@helixcode.com> - - * mail-summary.c (create_summary_view): Updated to use new icon code. - -2000-10-08 Iain Holmes <iain@helixcode.com> - - * mail-summary.c (generate_html_summary): Generic function to - recreate the HTML of the summary. Checks all the folder summaries. - (generate_folder_summarys): Create a summary of all the vfolders - and the Inbox. - (create_summary_view): Generate the folder summarys before the - HTML. - -2000-10-09 Ettore Perazzoli <ettore@helixcode.com> - - * folder-browser.c: Don't #include "mail-search-dialogue.h" as - it's missing from the repository. - (search_full_clicked): Temporarily `#if 0'ed out. - (search_full): Likewise. - (folder_browser_gui_init): Don't connect `search_full'. - (create_option_menu): Don't connect `search_menu_deactivate'. - (folder_browser_gui_init): Don't connect `search_activate'. - (search_set): Don't do `search_full()'. - (folder_browser_gui_init): Likewise. - - * Makefile.am (evolution_mail_SOURCES): Remove - `mail-search-dialogue.h' and `mail-search-dialogue.c' as NotZed - forgot to put them into CVS. - -2000-10-06 Not Zed <NotZed@HelixCode.com> - - * mail-search-dialogue.c: New widget, full search dialogue for - mail. - - * folder-browser.c (search_set): If we click on custom search, run - the full search dialogue. - (folder_browser_gui_init): Add a button to perform a full search. - (search_full): Bring up the mail search dialogue asynchronously. - (search_full_clicked): Handle search options. - (folder_browser_destroy): Free the saved rule if there is one - there. - (search_options[]): Added a custom option option - brings up the - full search dialogue. - (search_set): Disable the search entry if we are doing a full - search. - - * mail-vfolder.c (vfolder_create_storage): Yay, finally - depeterised this stuff. - (vfolder_uri_to_folder): Removed an irrelevant comment. - - * mail-callbacks.c (filter_edit): And here. - - * mail-ops.c (do_fetch_mail): And here too. - - * mail-autofilter.c (filter_gui_add_from_message): Fixed call to - context_load. - (filter_gui_add_for_mailing_list): And here too. - - * folder-browser-factory.c (create_ondemand_hooks): Remove that - ondemand callback snot. - -2000-10-05 Not Zed <NotZed@HelixCode.com> - - * message-list.c (message_list_init_etable): Build the etable once - we know what folder we are going to use. - (save_header_state): Save the header spec to a cache file. - (message_list_destroy): Save the header spec. - (message_list_setup_etable): Setup the etable spec for this - folder, from a saved version if one exists, or to suit the folder - type (sent/received). - (message_list_set_folder): Setup the etable here once we have a folder. - -2000-10-09 Michael Meeks <michael@helixcode.com> - - * message-list.c (message_list_toggle_threads): re-write. - - * folder-browser-factory.c (control_activate): update paths, need - CVS HEAD bonobo, use a listener not a verb. - -2000-10-08 Miguel de Icaza <miguel@helixcode.com> - - * mail-ops.c (mail_incorporate_messages): Tag string for translation - (do_flag_messages): ditto. - - * mail-threads.c (pipe_write): Repeates writes on EINTRS. - (pipe_read): Repeats reads on EINTRS. - (mail_operation_queue): Use pipe_write - (mail_op_set_percentage): ditto. - (mail_op_hide_progressbar): ditto. - (mail_op_show_progressbar): ditto. - (mail_op_set_message): ditto. - (mail_op_get_password): ditto. - (mail_op_error): ditto. - (mail_op_forward_event): ditto. - (mail_operations_terminate): ditto. - (dispatch): use pipe_read. - (dispatch): use pipe_write - (dispatch): ditto. - - * mail-ops.c (mail_incorporate_messages): Only show message being - incorporated every 2 seconds, to avoid a bunch of CORBA round trips. - (do_transfer_messages): ditto. - (do_forward_messages): ditto. - -2000-10-07 Miguel de Icaza <miguel@helixcode.com> - - * mail-ops.c (do_fetch_mail): Move the functionality to - incorporate messages into mail_incorporate_messages. - (mail_load_evolution_rule_context): New function. Move the - functionality for loading the context rules to its own function. - -2000-10-06 Iain Holmes <iain@helixcode.com> - - * mail-summary.c: Fix the locking up of the mail by only calling - camel functions from the camel thread, and ORBit functions from - the GTK thread. Watch for the message-changed signal again. - - * component-factory.c (summary_fn, component_factory_init): - Re-enabled it, cos I think it works again. - - * mail-display.h: Remove the pb_cache. - - * Makefile.am: Readd the mail-summary.[ch] files and add the - evolution-services library to the link. - -2000-10-06 Chris Toshok <toshok@helixcode.com> - - * mail-ops.c (do_scan_subfolders): set the @subscribed_only - parameter to TRUE, since the subscribe UI is the only interface - that should show unsubscribed groups. - -2000-10-06 Ettore Perazzoli <ettore@helixcode.com> - - * mail-ops.c (do_scan_subfolders): Add missing @subscribed_only - parameter in the call to `camel_store_get_folder_info()'. [FALSE, - I hope that's right.] - -2000-10-05 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-format.c (write_field_to_stream): Decode the header before - writing it to the header box. - - * mail-callbacks.c (send_receieve_mail): fetch mail before - sending, this is a temp fix for POP-before-SMTP authentication. - -2000-10-05 Michael Meeks <michael@helixcode.com> - - * component-factory.c (summary_fn, component_factory_init): - Disable summary stuff, it appears to be badly broken. - - * Makefile.am (evolution_mail_SOURCES): add mail-summary.[ch] - - * subscribe-dialog.c (update_pixmaps): upd. - (set_pixmap): upd. - (subscribe_dialog_gui_init): upd. - remove redundant and annoying forward definitions. - - * folder-browser-factory.c (control_deactivate): upd. - (control_activate_cb): upd. - (control_activate): upd. - (set_pixmap): upd. - (update_pixmaps): upd. - (register_ondemand): upd. - (create_ondemand_hooks): upd. - -2000-10-04 Jeffrey Stedfast <fejj@helixcode.com> - - * message-list.c (address_compare): Use CamelInternetAddress - instead of my quick hack (aka InternetAddress). - -2000-10-05 Iain Holmes <iain@helixcode.com> - - * mail-summary.c: Don't watch for the message-changed signal. - -2000-10-05 Iain Holmes <iain@helixcode.com> - - * component-factory.c (component_factory_init): Setup the summary - factory as well. - (summary_fn): New function to create the ExecutiveSummaryComponent. - - * mail-summary.c: Create the view, and update it when something - changes. - -2000-10-04 Iain Holmes <iain@helixcode.com> - - * mail-display.c (on_object_requested): Removed the pixbuf cache - as it would return the pixbufs in the reverse order every so often - and generally get all confused. - -2000-10-04 Dan Winship <danw@helixcode.com> - - * folder-browser-factory.c (control_deactivate): Add back the - "sync folder on leave" hack that got lost in the UIHandler merge. - -2000-10-04 Jeffrey Stedfast <fejj@helixcode.com> - - * folder-browser-factory.c: Instead of UnSelectAll, we want - InvertSelection. - - * mail-callbacks.c (select_all): Finished this function. - (invert_selection): Finished. (was unselect_all - but that's not - what we really wanted as it'd be pointless. invert_selection is a - much more useful callback :-) - -2000-10-04 Chris Toshok <toshok@helixcode.com> - - * mail-tools.c (mail_tool_get_root_of_store): remove news specific - check. - (mail_tool_uri_to_folder): news: -> nntp: - -2000-10-04 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-ops.c (do_filter_ondemand): Don't expunge the source - mailbox on completion. - -2000-10-04 Dan Winship <danw@helixcode.com> - - * mail-ops.c (do_scan_subfolders): Don't try to add_folders if - get_folder_info returned NULL. - -2000-10-04 Not Zed <NotZed@HelixCode.com> - - * message-list.c (message_list_init_header): Fix the attachment - icon width. - (content_is_attachment): Perform some simple tests to see if the - message contains an attachment. - (build_subtree): Kill a pointless warning. - -2000-10-04 Miguel de Icaza <miguel@helixcode.com> - - * mail-callbacks.c (delete_msg): Added a comment to a piece of - code that I was trying to "fix" just to find that the strange - behaviour here that was about to be fixed, was actually a fix to - the problem I was trying to fix. - - So put the original comments from Dan, and will hope that someone - with more knowledge about this can figure why the delete key wont - delete messages and select the next unread message. - -2000-10-02 Chris Toshok <toshok@helixcode.com> - - * subscribe-dialog.c (subscribe_dialog_destroy): destroy our - tree_model and remove the root node. also, release_unref our - control and view, and unref the listener. - - * mail-tools.c (mail_tool_uri_to_folder): news url's contain host - names too, now. - -2000-10-02 Chris Toshok <toshok@helixcode.com> - - * subscribe-dialog.c, subscribe-dialog.h: add a - storage-set-view-listener, and add a little printf saying what - storage was selected. - -2000-10-02 Chris Toshok <toshok@helixcode.com> - - * subscribe-dialog.c (subscribe_dialog_gui_init): get - Evolution::StorageSetView interface on our storage set view - control, and set "show_folders" to FALSE. - -2000-10-02 Chris Toshok <toshok@helixcode.com> - - * Makefile.am (INCLUDES): add -I$(top_srcdir)/widgets/misc - - * subscribe-dialog.c (subscribe_dialog_gui_init): change the - window title to Manage Subscriptions, bold subscribed folders, and - add a title bar ala the evolution shell (but without the close - button). - -2000-10-02 Chris Toshok <toshok@helixcode.com> - - * subscribe-dialog.h: add fields for the storage set - Bonobo_Control and Evolution_StorageSetView interfaces. - - * subscribe-dialog.c (subscribe_dialog_gui_init): create the uih - as early as possible, and add the storage set view to the left - side of the hpaned. - -2000-09-22 Michael Meeks <michael@helixcode.com> - - * folder-browser-factory.c (set_pixmap): upd. - (control_activate): upd. - -2000-10-02 Dan Winship <danw@helixcode.com> - - * mail-config-gui.c: Remove "Port" entry from source dialog. We'll - use "host:port" like Netscape and other programs do. - (service_page_get_url): If host ends in ":###", use that as port. - (service_page_set_url): If URL contains a port, append it to the - hostname, separated by a colon. - -2000-10-02 Chris Toshok <toshok@helixcode.com> - - * Makefile.am (evolution_mail_SOURCES): subscribe-control.[ch] -> - subscribe_dialog.[ch] - - * mail-callbacks.c (manage_subscriptions): subscribe_control -> - subscribe_dialog. Also, pass the shell to subscribe_dialog_new. - - * mail-types.h: SubscribeControl -> SubscribeDialog. - - * subscribe-dialog.c, subscribe-dialog.h: rename from - subscribe-control.[ch]. - - * subscribe-dialog.c (subscribe_dialog_construct): pass - Evolution_Shell in. - (subscribe_dialog_new): takes Evolution_Shell argument now. - -2000-10-02 Chris Toshok <toshok@helixcode.com> - - * message-list.c (message_list_init_renderers): remove the 2 tree - pixbufs, so adjust the offsets to the score pixbufs. also, pass - NULL for the open/closed pixbufs to the tree cell renderer. - -2000-10-02 Dan Winship <danw@helixcode.com> - - * mail-ops.c (mail_do_scan_subfolders, etc): Update for - CamelFolderInfo changes. - - * message-list.c (message_list_destroy): Don't save_tree_state if - there's no folder associated with the MessageList. - - * folder-browser.c (folder_browser_set_uri): Only call - mail_do_load_folder if the URI is not "". - -2000-10-02 Iain Holmes <iain@helixcode.com> - - * mail-display.[ch]: Add a cache for the pixbufs, hashed on CID, - so that we only have to make a thumbnail once. - -2000-10-01 Iain Holmes <iain@helixcode.com> - - * mail-display.c: Generate the thumbnails on an idle function so - that the user interface isn't locked. Checks in case the widget it - will use to display the image isn't destroyed. - -2000-10-01 Iain Holmes <iain@helixcode.com> - - * mail-display.c (on_object_requested): If the attachment is an - image display a thumbnail of it, instead of the generic image - icon. - -2000-09-29 Miguel de Icaza <miguel@helixcode.com> - - * folder-browser-factory.c: Add print preview verb here. - - * mail-callbacks.c (do_mail_print): Handle printing here, the - complete engine. - (mail_print_preview_msg): new. does print previewing. - (mail_print_msg): does printing of the message. - -2000-09-29 Chris Toshok <toshok@helixcode.com> - - * subscribe-control-factory.c, subscribe-control-factory.h: nuked. - - * subscribe-control.c, subscribe-control.h: lots of changes. we - now pop up a dialog, and will have a storage set view on our left - side, like the shell does. - - * mail.h: add prototype for manage_subscriptions. - - * mail-callbacks.c (manage_subscriptions): new function, pops up - the subscribe dialog. - - * folder-browser-factory.c: add the verb for managing - subscriptions. - - * Makefile.am (evolution_mail_SOURCES): add subscribe-control.[ch] - again. - -2000-09-28 Chris Toshok <toshok@helixcode.com> - - * subscribe-control.h (subscribe_search): added prototype. - - * subscribe-control.c (subscribe_search): new function. - - * subscribe-control-factory.c (make_folder_search_widget): new - function, to add search widget to toolbar. - (control_activate): create the search widget and add it to the - toolbar. - -2000-09-28 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-ops.c (do_send_queue): Messages should be appended to Sent - as Seen. - (do_send_mail): Same. - -2000-09-28 Ettore Perazzoli <ettore@helixcode.com> - - * Makefile.am: Don't compile `subscribe-control' for now. It - needs to be converted to the new UI handler code in Bonobo; it - doesn't compile right now. - -2000-09-27 Chris Toshok <toshok@helixcode.com> - - * subscribe-control.c (subscribe_refresh_list): new function. - - * subscribe-control.h (subscribe_refresh_list): new prototype. - - * subscribe-control-factory.c (update_pixmaps): add RefreshList - pixmap. also, add it to the verbs list. - -2000-09-27 Chris Toshok <toshok@helixcode.com> - - * mail-types.h: add SubscribeControl typedef. - - * Makefile.am (evolution_mail_SOURCES): add the subscribe stuff. - - * subscribe-control-factory.h * subscribe-control-factory.c * - subscribe-control.c: * subscribe-control.h: Mostly mocked up - subscribe ui. - -2000-09-27 Jeffrey Stedfast <fejj@helixcode.com> - Note: We need a configuration option to specify whether to log - filtering actions or not. - - * mail-ops.c (do_filter_ondemand): Updated to pass a log file - pointer to filter_driver_run. - (do_fetch_mail): Same. - (mail_do_fetch_mail): Fixed a compiler warning. - -2000-09-27 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-callbacks.c (composer_postpone_cb): Fix it so that "send - later" will still mark a message as being replied, forwarded, - whatever. Closes bug #568 on bugzilla. - -2000-09-27 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-ops.c (do_filter_ondemand): If the message has been - deleted, don't try filtering it - skip to the next message. Fixes - bugzilla bug #639. - -2000-09-25 Jeffrey Stedfast <fejj@helixcode.com> - - * folder-browser-factory.c: Shuffling (un)select all menu items to - the Edit menu. - -2000-09-25 Jeffrey Stedfast <fejj@helixcode.com> - - * folder-browser-factory.c: Added new menu items - - * mail-callbacks.c (mark_as_seen): New callback to mark all - selected messages as Seen. - (mark_as_unseen): New callback to mark all selected messages as - Unseen. - (select_all): New callback to select all messages (not yet - finished) - (unselect_all): New callback to unselect all messages (not yet - finished) - -2000-09-25 Not Zed <NotZed@HelixCode.com> - - * message-list.c (folder_to_cachename): Function to convert a - folder name/path to a filename for per-folder data. - (save_tree_state): - (load_tree_state): - (free_tree_state): For loading/saving the state of the expansion - of nodes in the tree. - (message_list_destroy): Save the tree state when done. - (save_node_state): Changed logic, we save when the node should be - closed on startup. i.e. any new nodes with children automatically - default to being open. - (subtree_unread): Check for unread messages in a subtree. So - false messages (for tree roots) are properly displayed. - -2000-09-25 Jeffrey Stedfast <fejj@helixcode.com> - - * message-list.c (address_compare): Updated to use Nat's - ENameWestern parser. - - * Makefile.am: link against e-util/ename/libename.la - -2000-09-25 Dan Winship <danw@helixcode.com> - - * mail-ops.c: CamelException is not for compile-time errors. - Replace lots of argument checks in setup_ functions with - g_return_if_fails in the public functions. Also remove some - prototypes that weren't needed because they were for static - functions that are defined before they're used. - -2000-09-23 Michael Meeks <michael@helixcode.com> - - * folder-browser-factory.c (set_pixmap): upd. - (control_activate): upd. - -2000-09-23 Ettore Perazzoli <ettore@helixcode.com> - - * message-list.c (internet_address_new_from_string): Skip spaces - at the beginning of the string first before doing anything else. - The code that follows doesn't like the first character of the - string to be a space. - -2000-09-22 Jeffrey Stedfast <fejj@helixcode.com> - - * message-list.c (address_compare): New comparison function for - email addresses. - (subject_compare): New comparison function for message subjects. - (message_list_init_header): Updated to use the new compare funcs. - -2000-09-21 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-format.c (mail_generate_reply): Fixed some memory - leakage. Call free_recipients() so we don't leak memory. - -2000-09-19 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-ops.c (do_scan_subfolders): Use the folder's full_name so - recursive directory structures display correctly ;-) - -2000-09-19 Dan Winship <danw@helixcode.com> - - * mail-ops.c (do_scan_subfolders): Update for CamelFolder changes - (subfolder_names -> subfolder_info). - -2000-09-19 Dan Winship <danw@helixcode.com> - - * mail-callbacks.c (create_msg_composer, compose_msg, send_to_url, - mail_reply, forward_msg): * mail-format.c (mail_generate_reply): * - mail-ops.c (cleanup_edit_messages): - - * mail-view.c (view_forward_msg): Deal with NULL composer. - -2000-09-18 Dan Winship <danw@helixcode.com> - - * main.c (main): Call gnome_vfs_init() since the composer now does - file operations (to get the MIME type of attachments). - -2000-09-18 Jeffrey Stedfast <fejj@helixcode.com> - - * message-list.c: Removed COL_ONLINE_STATUS because we don't want - that. Renamed COL_PRIORITY to COL_SCORE and set it up to sort-of - work, I'm not really sure which renderer I should use. - -2000-09-18 Christopher James Lahey <clahey@helixcode.com> - - * Makefile.am: Added $(EXTRA_GNOME_CFLAGS) and - $(EXTRA_GNOME_LIBS). Removed unneeded libraries. - - * component-factory.c, folder-browser-factory.c, folder-browser.c, - mail-callbacks.c, mail-config-gui.c, mail-display.c, - mail-display.h, main.c, message-list.c, message-list.h: Fixed the - #include lines to deal properly with gal. - -2000-09-16 Michael Meeks <michael@helixcode.com> - - * Makefile.am (INCLUDES): add datadir - - * folder-browser-factory.c (control_activate): use it. - -2000-09-15 Dan Winship <danw@helixcode.com> - - * mail-callbacks.c (transfer_msg): Revert **Temp fix** from below - since the relevant shell bug has been fixed now. - - * mail-ops.c (do_fetch_mail): Fix the sense of the "keep on - server" check so we're not doing this backwards. Don't - get_message_flags, because POP doesn't support it and it's - pointless anyway since we're setting deleted, not toggling it. - call camel_folder_sync with expunge=TRUE so that the deletions are - actually recorded. - -2000-09-15 Dan Winship <danw@helixcode.com> - - This bug was so much fun to fix the first time that I decided to - fix it again. - - 2000-07-11 Dan Winship <danw@helixcode.com> - - * mail-ops.c (real_send_mail): Set the post_send_data flag - rather than toggling it. (Maybe we'll need more control - over it later, but for now, the only flag we set is - "replied", and we want that set, not toggled.) - -2000-09-14 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-callbacks.c (transfer_msg): **Temp fix** Send "" as the - default folder to select as anything else seems to cause a - segfault in shell's user_get_folder(). - (check_configured): A spoon full of 'line wrapping' makes the - medicine go down, the medicine go dowwwwn... - -2000-09-14 Iain Holmes <terrorist@gegl.org> - - * mail-callbacks.c (check_configured): Ask if you want to - configure the mail client if it isn't configured already. - (check_send_configuration): Remove the error box if mail isn't - configured. - (send_queued_mail): Same. - -2000-09-14 Dan Winship <danw@helixcode.com> - - * mail-ops.c (setup_append_mail): camel_folder_append is perfectly - happy to take a NULL info. - -2000-09-14 Michael Meeks <michael@helixcode.com> - - * folder-browser-factory.c: move fn to bonobo. - (set_pixmap): update. - (control_deactivate): add bonobo_ui_handler_unset_container - -2000-09-14 Christopher James Lahey <clahey@helixcode.com> - - * mail-config-gui.h: Changed the include here because it caused - make distcheck to fail for me. I changed it from <Evolution.h> to - "shell/Evolution.h". This seems to have fixed things. - -2000-09-14 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-ops.c (do_fetch_mail): Only use the cache if the user plans - to keep_on_server. - -2000-09-14 Michael Meeks <michael@helixcode.com> - - * folder-browser-factory.c (control_deactivate): kill - warning. (control_activate): set threaded toggle state, - add freeze / thaw. - (set_pixmap, fill_toolbar, update_pixmaps): update. - -2000-09-13 Christopher James Lahey <clahey@helixcode.com> - - * folder-browser-factory.c: Fixed a warning (Missing include - file.) - -2000-09-12 Ettore Perazzoli <ettore@helixcode.com> - - ($(EVOLUTION_MAIL_CORBA_GENERATED)): Add space after `-I'. - -2000-09-12 Ettore Perazzoli <ettore@helixcode.com> - - * Makefile.am: Remove `ui.xml' stuff. - -2000-09-12 Dan Winship <danw@helixcode.com> - - * mail-local-storage.c (mail_local_storage_startup): set - folder_tree before adding the listener, since that will eventually - invoke callbacks that will look at it. - - * folder-browser-factory.c (control_deactivate): sync the folder - on deactivate. - -2000-09-12 Ettore Perazzoli <ettore@helixcode.com> - - * message-list.c (on_right_click): Also display the name of the - mailing list in the "Filter on Mailing List" item for additional - Coolness factor. - - * mail-autofilter.c (filter_gui_add_for_mailing_list): Create the - rule with `filter_filter_new()' so that it also has an action - part. - - * mail-mlist-magic.c (get_header): Use the right header name to - retrieve the header. - -2000-09-12 Ettore Perazzoli <ettore@helixcode.com> - - * message-list.c (on_right_click): Grey out the mailing list - filter item if `mail_mlist_magic_detect_list()' returns NULL on - this message [i.e., if we cannot figure out a mailing list for - this message]. - (filter_mlist): Good boys don't use F words. - - * mail-mlist-magic.c (check_sender): Work safely if - `header_name_return' or `header_value_return' are NULL. - (check_x_been_there): Likewise. - (check_delivered_to): Likewise. - (check_x_mailing_list): Likewise. - (check_x_loop): Likewise. - (get_header): Use the right header name to retrieve the header. - - * message-list.c (on_right_click): Mark strings for translation. - -2000-09-12 Ettore Perazzoli <ettore@helixcode.com> - - * folder-browser-factory.c: Use the latest, shiny, amazing TigerT - art for the toolbar. - - * component-factory.c: #include "mail-local-storage.h". - (owner_set_cb): Removed unused variable. - - * message-list.c (filter_sender): Made static. - (filter_recipient): Likewise. - (filter_subject): Likewise. - (vfolder_recipient): Likewise. - (vfolder_sender): Likewise. - (vfolder_subject): Likewise. - - * mail.h (vfolder_subject): Removed prototype [WTF was this doing - here?!?!]. - (vfolder_sender): Likewise. - (vfolder_recipient): Likewise. - (filter_subject): Likewise. - (filter_sender): Likewise. - (filter_recipient): Likewise. - - * message-list.c: Added a new "Filter on mailing list" menu item. - (filter_mlist): Callback for this menu item. Use - `filter_gui_add_for_mailing_list' to pop up the filter dialog with - the appropriate rule. - - * mail-autofilter.c (filter_gui_add_for_mailing_list): New. - - * message-thread.c (dump_tree): Removed unused variable. - - * mail-mlist-magic.c: New. - * mail-mlist-magic.h: New. - - * mail-autofilter.c (rule_match_recipients): Mark strings for - translation. - (rule_from_message): Likewise. - (filter_gui_add_from_message): Likewise. - -2000-09-12 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-ops.c (do_fetch_mail): Was trying to unhook an event from - the wrong folder - oops. - -2000-09-12 Not Zed <NotZed@HelixCode.com> - - * message-thread.c: Reverted to version 1.15. - (remove_node): Ok, if a node has a parent, remove it from the - parent list, otherwise remove it from the (supplied) root list. - (group_root_set): When we merge children, free the lost node. - (thread_messages_free): Remove the return, run as is. - (prune_empty): Plugged another small leak. - -2000-09-11 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-callbacks.c (run_filter_ondemand): Updated to use the new - mail_do_filter_ondemand. - - * mail-ops.c (do_fetch_mail): Update to use the new - filter_driver_run args. - (do_filter_ondemand): Updated to use the new filter_driver_run - args. - (mail_do_filter_ondemand): Take a FilterContext as a argument - instead of a driver as we need to destroy the filter inside the - do_filter_ondemand function and things'd get messy. - -2000-09-11 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-ops.c (do_fetch_mail): Don't have the filter driver - self_destruct. - -2000-09-11 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-ops.c (do_fetch_mail): If we're fetching from an mbox - formatted file then we need to do some special-casing. - -2000-09-11 Ettore Perazzoli <ettore@helixcode.com> - - * component-factory.c (owner_set_cb): Call - `mail_local_storage_startup()' to set up handling of the local - storage. - - * mail-local-storage.c: New. - * mail-local-storage.h: New. - -2000-09-11 Christopher James Lahey <clahey@helixcode.com> - - * mail-display.c: Fixed some warnings. - -2000-09-11 Dan Winship <danw@helixcode.com> - - * mail-display.c, mail-format.c: Another big rewrite of this - stuff. Now all (well, most) attachments get a small icon with a - description and a (non-obvious) right-click pop-up menu with - options to save, open in an external program, or show/hide inline. - - TODO: antialias the icon, add more options to the pop-up for - certain MIME types, add an icon to the headers, fix PGP to work - like everything else, fix message/external-body to work again, - add some icon caching action, etc, etc. - -2000-09-09 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-ops.c (do_fetch_mail): Use the CamelUIDCache so that we - only retrieve *new* messages and also send notes to the status bar - telling it which message we're downloading so that Ettore can - sleep at night ;-) - -2000-09-09 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-ops.c (do_fetch_mail): Updated to not send hook/unhook data - to filter_driver_run as it no longer takes those args. - (do_filter_ondemand): Same. Also wrap filtering in freeze/thaw to - prevent signals from being queued up - -2000-09-09 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-ops.c (do_fetch_mail): Freeze the default folder before - filtering and thaw it afterward to prevent a ton of - "folder_changed" signals from being queued. - -2000-09-08 Christopher James Lahey <clahey@helixcode.com> - - * folder-browser.c, mail-config-gui.c, mail-ops.c: Fixed some - warnings. - - * message-list.c: Added base ETableModel functions. - -2000-09-08 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-ops.c (do_fetch_mail): Updated to pass a CamelMessageInfo - to filter_driver_run - (do_filter_ondemand): Same. - -2000-09-07 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-ops.c (do_filter_ondemand): Updated to check the boolean - return code from filter_driver_run to find out whether or not the - message was filtered so that it can decide whether or not to - delete the message from the source folder or not. - -2000-09-07 Jesse Pavel <jpavel@helixcode.com> - - * mail-format.c (mail_generate_reply) Changed the behavior of - Reply-to-All so that the sender's address does not appear in - the cc: list. - -2000-09-07 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-ops.c (do_fetch_mail): Updated to pass an exception to - filter_driver_run and also check the exception before deleting the - message from the source folder. - (do_filter_ondemand): Updated to pass an exception to - filter_driver_run - -2000-09-07 Dan Winship <danw@helixcode.com> - - * session.c (session_init): Pass a storage dir to - camel_session_new now. - - * main.c (main): Can't call session_init here now, because it - requires evolution_dir to be set. - - * component-factory.c (owner_set_cb): call session_init here. - - * mail-ops.c (do_fetch_mail): Fix previous fix. (Free the uids, - just do it correctly.) - -2000-09-07 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-ops.c (do_fetch_mail): Don't free uids, let the camel - folder do that when it gets finalized - -2000-09-06 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-ops.c (mail_do_filter_ondemand): New async function to - filter messages on demand. - (do_fetch_mail): Updated to filter 1 message at a time using the - new filter-driver code - - * mail-callbacks.c (composer_postpone_cb): Send NULL as the - message info. - (run_filter_ondemand): Use mail_do_filter_ondemand instead of - filter_driver_run - - * mail-tools.c: Removed mail_tool_filter_contents_into and - mail_tool_fetch_mail_into_searchable as they have now been - deprecated. - -2000-09-06 Dan Winship <danw@helixcode.com> - - * message-list.c (clear_tree): set the data to NULL for the tree - root, so nuke_uids won't try to free anything. - -2000-09-06 Ettore Perazzoli <ettore@helixcode.com> - - * folder-browser.c (folder_browser_new): @shell made const. - `CORBA_Object_duplicate()' it before storing it. - (folder_browser_destroy): Free the shell object with - `CORBA_Object_release()', not `CORBA_free()'. - - * folder-browser-factory.c (folder_browser_factory_new_control): - @shell made const. - -2000-09-05 Dan Winship <danw@helixcode.com> - - * mail-display.c (make_safe_filename): - * mail-format.c (handle_mystery): - * mail-identify.c (mail_identify_mime_part): - camel_mime_part_get_filename now deals with both - Content-Disposition and Content-Type. - -2000-09-05 Peter Williams <peterw@helixcode.com> - - * mail-ops.c (cleanup_load_folder): Check for NULL folder. - (mail_do_setup_folder): Copy the 'name' parameter so that - we can free it. - - * message-list.c (nuke_uids): Depth '-1' means "unlimited", not 0. - -2000-09-05 Dan Winship <danw@helixcode.com> - - * component-factory.c (owner_set_cb): Re-rename "Sent". - - * folder-browser.c (fb_resize_cb): Remove the "+ 90" here since it - seems to break things for me, and it's not commented anyway and - there's no excuse for adding 90 to a number with no explanation. - -2000-09-05 Peter Williams <peterw@helixcode.com> - - * folder-browser.c (folder_browser_destroy): Don't free the shell; - it's not ours. - -2000-09-05 Dan Winship <danw@helixcode.com> - - * mail-tools.c (mail_tool_move_folder_contents): only call - camel_folder_get_message_info if the folder has - summary_capability. Don't hack up a fake CamelMessageInfo: - append_message will take NULL. - - * mail-ops.c: Replace mail_do_setup_draftbox, - mail_do_setup_outbox, and mail_do_setup_sentbox with - mail_do_setup_folder. - (do_send_mail, do_send_queue): s/sentbox_folder/sent_folder/ - - * component-factory.c (owner_set_cb): Use mail_do_setup_folder, - rename sentbox_folder to sent_folder, and call - mail_operation_wait_for_finish after the setup_folder calls in - case anything needs to use the _folder variables. - -2000-09-04 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-format.c (mail_generate_reply): Applied Jesse's patch that - will append a signature to the replied message text - - * folder-browser-factory.c: Changed "Send & Receieve" back to "Get - Mail" temporarily so that the toolbar buttons don't all get - stretched to some weird proportion - -2000-09-03 JP Rosevear <jpr@helixcode.com> - - * mail-config.c (mail_config_add_news): Copy the passed in item - before adding - (mail_config_add_source): ditto - (mail_config_add_identity): ditto - - * mail-config-gui.c (mail_config): We don't actually need a notebook - pointer. - (identities_edit_clicked): Don't explicitly destroy, we are using - gtk_clist_set_data_full now - (sources_edit_clicked): ditto - (news_edit_clicked): ditto - (mail_config): Use gtk_clist_set_row_data_full to kill leaks - -2000-09-03 Jeffrey Stedfast <fejj@helixcode.com> - - * folder-browser-factory.c: Change the "Get Mail" toolbar button - to become "Send & Receieve" - - * mail-callbacks.c (send_queued_mail): New callback function for - sending queued mail - (send_receieve_mail): New callback for Send & Receieve that - basically just calls send_queued_mail and then fetch_mail - - * mail-ops.c (cleanup_send_mail): Mod to be able to handle a NULL - composer window - (setup_send_mail): Modified to handle a NULL composer widget - (mail_do_send_queue): New convenience async function to send all - messages in a folder (aka all messages in a queue) - -2000-09-02 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-tools.c (mail_tool_move_folder_contents): Since POP3 - doesn't implement get_message_info, we need to check for info to - be NULL. In this case, we need to make our own info structure to - pass to append_message and then remember to free it - afterward. Should we even bother with get_message_info? And if so, - should we then implement get_message_info for POP3? - -2000-09-02 Ettore Perazzoli <ettore@helixcode.com> - - * folder-browser.c (etable_key): Make the `Home' key to move to - the beginning of the list and `End' to the end of it, using - `message_list_home()' and `message_list_end()'. - - * message-list.c (message_list_home): New. - (message_list_end): New. - - * folder-browser.c (folder_browser_new): Don't ref the shell here. - (folder_browser_destroy): Don't unref the shell. Instead, - `CORBA_free()' the object reference. - - * folder-browser-factory.c (control_activate): Bind "Open in New - Window" to `Ctrl-O'. - -2000-09-02 Lauris Kaplinski <lauris@helixcode.com> - - * mail-config-gui.c: Use e_utf8 wrappers - - * main.c (main): Do e_unicode_init, so we are not confusing - libunicode - -2000-09-01 Christopher James Lahey <clahey@helixcode.com> - - * folder-browser.c: Removed a warning. - -2000-09-01 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-callbacks.c (compose_msg): Attach a callback to the - postpone signal - (send_to_url): Same - (mail_reply): Same - (forward_msg): Same - (composer_postpone_cb): Callback function for the postpone signal - - * mail-ops.c (mail_do_setup_outbox): New convenience function to - load the Outbox folder - (mail_do_setup_sentbox): Same, but for Sentbox. - (do_send_mail): Now saves messages in Sentbox if sent successfully - (mail_do_append_mail): New convenience async function for - appending messages to a folder - - * component-factory.c: Added outbox_folder and sent_folder - (owner_set_cb): Call our new convenience functions to load Outbox - and Sentbox - -2000-09-01 Ettore Perazzoli <ettore@helixcode.com> - - * mail-ops.c (cleanup_scan_subfolders): Update for the extra arg - needed by `evolution_storage_new_folder()'. - * mail-vfolder.c (vfolder_refresh): Likewise. - -2000-08-31 Peter Williams <peterw@helixcode.com> - - * folder-browser.c (folder_browser_new): Don't ref the shell: - causes a race upon exit. - (folder_browser_destroy): Don't unref it. - - * mail-config-gui.c (service_page_item_new): Add a checkbutton - "use default port" to make life simple. - (service_page_get_url): Honor use_default_port. - (service_page_set_url): Set use_default_port based on the input - URL. - (toggle_port): New function, sets the sensitivity of the - port entry based on "use default port" - - (config_do_query_authtypes): Make this asynchronous, as it - may involve connecting to a server. - (service_page_detect): Call the async auth querier. - (service_page_item_new): Put the authentication stuff in if - the url_flags have URL_ALLOW_AUTH. Call the async auth querier - to get the info. - -2000-08-30 Ettore Perazzoli <ettore@helixcode.com> - - * mail-view.c (mail_view_create): Make the HTML widget grab the - focus. - -2000-08-30 Peter Williams <peterw@helixcode.com> - - * mail-config-gui.c (do_test_service): Explicitly connect to - the service again. - - * component-factory.c (mail_load_storages): Now that - camel_service_get_provider exists, use it to make this function - much simpler. - -2000-08-29 Peter Williams <peterw@helixcode.com> - - * folder-browser.c (folder_browser_new): Ref the Evolution_Shell. - Is this correct, or is it a circular reference? - -2000-08-29 Dan Winship <danw@helixcode.com> - - * mail-ops.c (mail_do_send_mail): Update this and related - functions to no longer take a From address. (The composer deals - with it itself now.) - (do_send_mail): Add the Evolution version back to the X-Mailer - header (this change got lost in the thread migration). - - * mail-callbacks.c (composer_send_cb): Don't re-fetch the From - address. It's set by the composer now. Don't free the - post_send_data from here. - (mail_reply): Attach to the composer's destroy signal to free the - psd. (The current code would free it more than once if an error - occurred while trying to send the first time.) - -2000-08-28 Peter Williams <peterw@helixcode.com> - - * mail-config-gui.c (mail_config_apply_clicked): Add new news sources, - not only stores. - -2000-08-28 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-callbacks.c (composer_send_cb): Free the from address when - we're done with it. Also, e_msg_composer_hdrs_get_from returns - alloc'd memory so don't strdup it. - -2000-08-28 Peter Williams <peterw@helixcode.com> - - * mail-ops.c (do_transfer_messages): Add status messages. - (do_flag_messages): Same. - (do_scan_subfolders): Same. - (do_forward_messages): Same. - (do_view_messages): Same. - -2000-08-28 Ettore Perazzoli <ettore@helixcode.com> - - * mail-view.c (mail_view_create): Use `gnome_app_set_toolbar()' - the easy way instead of doing things manually with `GnomeDock' and - `gnome_app_add_toolbar()'. - (MINIMUM_WIDTH): New #define. - (MINIMUM_HEIGHT): New #define. - (view_size_allocate_cb): New, callback for the "size_allocate" - signal of the mail view. It saves the last allocation in a static - `last_allocation' variable. - (mail_view_create): Connect it. - (set_default_size): New function. Set the default width/height to - the last allocation width/height; if the width/height is less than - the `MINIUM_WIDTH' or `MINIMUM_HEIGHT', use that value instead. - - * mail-tools.c (mail_tool_move_folder_contents): Show `i + 1', not - `i', so that we correctlly start counting from one instead of zero. - -2000-08-28 Peter Williams <peterw@helixcode.com> - - * *.c: s,mail_dialog_run,gnome_dialog_run,g. - - * main.c (main): Since only the main thread is dealing with GTK+, - free the GDK threads mutex and never worry about locking again. - -2000-08-28 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-crypto.c (mail_crypto_openpgp_encrypt): Fix to prevent - possible buffer overflows and a logic fix. - -2000-08-27 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-crypto.c (mail_crypto_openpgp_clearsign): New crypto - function to clearsign plaintext - -2000-08-27 Ariel Rios <ariel@arcavia.com> - - * folder-browser-factory.c (control_activate): Added bonobo menu - handler for mark_all_deleted function. - - * mail.h: (mark_all_deleted): Added prototype. - - * mail-callbacks.c (mark_all_deleted): Added callback for marking - all displayed messages in a folder as deleted. - -2000-08-26 Ettore Perazzoli <ettore@helixcode.com> - - * mail-view.c (mail_view_create): Use - `gtk_window_set_default_size' on the toplevel instead of - `gtk_widget_set_usize()', and make the default size smaller. - -2000-08-25 Christopher James Lahey <clahey@helixcode.com> - - * mail-crypto.c: Fixed an uninitialized variable. - -2000-08-26 JP Rosevear <jpr@helixcode.com> - - * evolution-mail.gnorba: Kill - - * Makefile.am: Remove gnorba related stuff - -2000-08-25 Peter Williams <peterw@helixcode.com> - - * mail-config-gui.c (service_page_item_new): If the service wants - a host, also let the user specify a port. - (MailDialogServicePageItem): Add members for the port GtkEntry and - the default port. - (service_page_get_url): Translate the port in the entry back into - the CamelURL. - (service_page_set_url): Read in the port from the URL or use - the default. - -2000-08-25 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-crypto.c (mail_crypto_openpgp_encrypt): Implemented PGP 2.x - encryption. We only need to get the passphrase if we plan to sign - the text, otherwise we don't need to worry about getting the - passphrase. - -2000-08-24 Lauris Kaplinski <lauris@helixcode.com> - - * folder-browser.c: Use e_utf8 wrappers - - * mail-config-gui.c: Use e_utf8 wrappers - -2000-08-24 Peter Williams <peterw@helixcode.com> - - * folder-browser-factory.c (control_activate): Add all the - functions from message-list.c's popup menu to the main - menu as well - - * message-list.c (vfolder_subject): These functions become - public. - - * mail-callbacks.c (mark_all_seen): Don't call camel_folder_get_uids - here. IMAP, for example, will try to communicate with the IMAP - server during that call. - - * mail-ops.c (cleanup_fetch_mail): Tell the user - which URL has no new mail, as they may be checking - more than one source. - (mail_do_flag_all_messages): New function. Flags all of - the messages in a folder. Something of a hack. This merely - extends the flag_messages operation; it doesn't implement - a new one. - (do_flag_messages et al): Fetch the uids if we need to; - use camel_folder_free_uids if necessary, etc. - - * mail-tools.c (mail_tool_move_folder_contents): Add - messages to tell the user what's going on. - -2000-08-24 Christopher James Lahey <clahey@helixcode.com> - - * folder-browser-factory.c: Fixed some warnings in the uihandler - code. - -2000-08-24 Peter Williams <peterw@helixcode.com> - - * component-factory.c (mail_load_storages): New function. - Loads a list of URI's as mail storages, and inserts them - into the shell's folder tree if appropriate (really, only - puts them into the folder tree.) - (mail_add_new_storage): Insert a storage into the folder - tree. Not always appropriate (eg, /var/spool/mail/user is - a storage that shouldn't be in the folder tree.) - (create_view): Generate the Evolution_Shell and pass it - to folder_browser_factor_new_control so that its member - 'shell' can be set. - (owner_set_cb): Instead of create_news_storage and - creating the imap storages, load the news storages and - mail storages via mail_load_storages(). - - * folder-browser-factory.c (control_activate): Change to - use providers_config again instead of mail_config. Pass - the folderbrowser so that the config code knows where - to insert the new storages if any are created. Pass - forget_passwords the folderbriwser, too, for good luck. - (folder_browser_factory_new_control): Take a new parameter, - the Evolution_Shell that we belong to. The field in - FolderBrowser has been there but was never getting set by - anything, and we need this to be able to insert new storages - into the shell's folder list. - - * folder-browser.c (folder_browser_new): Accept the - new Evolution_Shell parameter. Set it. (Should we - ref it or something?) - - * mail-config-gui.c (struct MailDruidDialog): Store an - Evolution_Shell. With this we can insert the stores into - the shell's folder list. - (struct MailDialog): Same. - (service_page_item_changed): Close a leak. - (identity_dialog): Unswitch the Add/Edit identity titles. - (news_dialog): Analogous to above. - (mail_druid_finish): Add the new mail source to the shell - view. - (mail_config_druid): Take a new Evolution_Shell parameter - for later use. - (mail_config_apply_clicked): Add all the mail sources to - the shell view. - (mail_config): Take a new Evolution_Shell parameter. - - * mail-callbacks.c (check_configured): Accept a FolderBrowser - so that we know where to put the new storages if any are - created. Almost all the callbacks are passed a FB * anyway - so this isn't a big deal. - (check_send_configuration): Make sure that we're configured - enough to be able to send mail. composer_send_cb() used to - do this, but it would need a FolderBrowser *, and there are - too many entry points to composer_send_cb to make this - feasible. - (fetch_mail): Pass the extra parm to check_configured(). - (free_psd): Move so that composer_send_cb can call this - directly. - (composer_send_cb): Don't check for proper configuration - here -- it is the caller's responsiblity to call - check_send_configuration(). Call free_psd() directly. - (compose_msg): Call check_send_configuration(). - (send_to_url): Same. This is called from mail-display.c, - though, and cannot reasonably be passed a FB. So: we can't - start up the config dialog directly; the user must do it - manually. Oh well. - (mail_reply): Same as above. - (forward_msg): Same as compose_msg(). - (edit_msg): Same as above. - (providers_config): Reenable so that we can pass mail_config - its FolderBrowser. - - * mail-display.c (write_data_to_file): Use the much more - straightforward run_and_close to retrieve the user's answer, - instead of the reply callback stuff. - - * mail-threads.c (mail_dialog_run): New wrapper for - gnome_dialog_run that will take care of the GDK lock correctly. - Far far more complicated than it should be. - (mail_dialog_run_and_close): Analogous to above. - (read_msg): Set inside_read_msg and unset it for the benefit - of the two above functions. Don't bracket ourselves in - GDK_THREADS_ENTER/_LEAVE anymore. - (mail_operation_queue): Use mail_dialog_run_and_close. - (show_error): As above. - (get_password): As above. - - * mail-display.c (write_data_to_file): This has the only - exception to the rule that "use mail_dialog_run(_and_close) - instead of the gnome equivalent always." Not quite sure why - it doesn't work here (the file selection window?). - - * mail-config-gui.c (identity_dialog): Change to - mail_dialog_run_and_close. - (source_dialog): Same as above. - (news_dialog): Same as above. - (cleanup_test_service): Same as above. - (mail_config): Change to mail_dialog_run(). - - * session.c (mail_request_dialog): Change to - mail_dialog_run_and_close. - - * mail-tools.c (mail_tool_uri_to_folder_noex): As above. - - * mail-ops.c (cleanup_fetch_mail): As above. - - * mail-local.c (local_reconfigure_folder): As above. - - * mail-callbacks.c (check_send_configuration): As above. - (ask_confirm_for_empty_subject): As above. - (edit_msg): As above. - (filter_edit): As above. - -2000-08-23 Dan Winship <danw@helixcode.com> - - * folder-browser-factory.c (control_activate): Reformat a bit, - make "Folder" appear before "Message", fill in the Message menu - more. - -2000-08-23 Peter Williams <peterw@helixcode.com> - - * mail-ops.c (describe_fetch_mail): Don't use the camel calls - to describe the operation. - -2000-08-22 Peter Williams <peterw@helixcode.com> - - * mail-tools.c (mail_tool_get_folder_from_urlname): Don't connect - to the service explicitly. - (mail_tool_send_via_transport): Don't connect to the transport - explicitly. - (mail_tool_get_root_of_store): Same. - - * mail-config-gui.c (do_test_service): Just try camel_session_get_service, - which will now connect for us. - - * message-thread.h: Add a note about *next being the first member - of struct _container... if it isn't, everything goes Very Wrong. - - * message-thread.c (free_container): Extra debug print. - (remove_node): Handle the case of empty containers holding the child - that we're interested in. - (thread_messages_free): Extra debug print. - -2000-08-20 Jeremy Wise <jwise@pathwaynet.com> - * folder-browser.c: (fb_resize_cb) Added function to monitor resize - of the e_paned in the main view. - -2000-08-18 Peter Williams <peterw@helixcode.com> - - * mail-tools.c (mail_tool_filter_contents_into): Fix a race. filter_driver_run is an - async operation so it won't even be started by the time we sync the folders and check - for the movemailbox to be emtpy. Thus the empty check for the movemail would fail - 99% of the time. - - * mail-callbacks.c (run_filter_ondemand): Pass he new argument to the ever-mushrooming - filter_driver_run. - -2000-08-17 Peter Williams <peterw@helixcode.com> - - * folder-browser-factory.c (control_activate): Fix menu item names. - (register_ondemand): Put the ondemand hooks into the new folder menu. - -2000-08-17 Ettore Perazzoli <ettore@helixcode.com> - - * mail-vfolder.c (vfolder_gui_add_rule): Use stock OK/Cancel - buttons and add i18n support. - - * folder-browser-factory.c (control_activate): Changed menu item - label from "Mark all messages seen" to "Mark All Messages as - Read". Changed capitalization of some other menu items. - (control_activate): Put the message- and folder- related menu - items in new "Message" and "Folder" subtrees which are created in - the `<Component Placeholder>' item created by the shell. - (control_deactivate): Updated accordingly. - (control_activate): Put the filter and vfolder editors, the mail - configuration and the "forget password" command into the - "settings" menu. - (control_deactivate): Updated accordingly. - - * mail-config-gui.c (transport_page_new): Add translation mark. - (service_page_new): Show the menu items before appending them. - (service_page_item_new): Use `GTK_FILL' for the "Detect supported - types..." button. - - * local-config.glade: Change the apply button into an ok button. - -2000-08-17 Peter Williams <peterw@helixcode.com> - - Implement filtering on demand. - - * folder-browser-factory.c (register_ondemand): New function. Callback - to put the filter-on-demand filters into the bonobo UIH; - (create_ondemand_hooks): New function. Read in our on-demand filters - and hook them into the UI. - (remove_ondemand_hooks): New function. Remove the hooks when done with - them. - (control_activate): Call create_ondemand_hooks() - (control_deactivate): Call remove_ondemand_hooks(); - - * mail-callbacks.c (run_filter_ondemand): New function. Callback - for running a filter on demand. - (filter_edit): Pass NULLs as the new arguments to rule_context_load. - - * mail.h: Prototype run_filter_ondemand(); - - * folder-browser.c (oc_destroy): New function. Iterator to destroy - an fb_ondemand_closure. - (folder_browser_destroy): Free the data associated with the ondemand - menu items. - (my_folder_browser_init): Clear the filter_ variables. - - * folder-browser.h: Two new members of FolderBrowser: filter_menu_paths, - a list of fb_ondemand_closures so that the menu items can be freed and - removed; and filter_context, a permanently loaded FilterContext for - running the ondemand filters. Prototype the new fb_ondemand_closure - structure. - - * mail-autofilter.c (filter_gui_add_from_message): Pass NULLs as the - new parameters to rule_context_load (we don't need to hook up ondemand - menu items...) - - * mail-tools.c (mail_tool_filter_get_folder_func): Rename from - get_folder_func() and make public so mail-callbacks.c:run_filter_ondemand() - can use it too. - (mail_tool_filter_contents_into): Use the new name of get_folder_func. - Pass NULLs as the extra arguments to rule_context_load. Pass the - extra source type to filter_driver_run (only use INCOMING). - - * mail-tools.h: Publicly prototype mail_tool_filter_get_folder_func() - - * mail-vfolder.c (vfolder_create_storage): Pass NULLs as the extra - arguments to rule_context_load. - - * message-list.c (message_list_init): Free our strdup'd uids when - the table model gets destroyed. - (nuke_uids): New function. Walk the tree nodes to free the uids. - (nuke_uids_cb): New callback for nuke_uids(); - - -2000-08-16 Richard Hult <rhult@hem.passagen.se> - - * mail-ops.c (cleanup_display_message): Use a configurable timeout. - - * mail-config.c (mail_config_set_mark_as_seen_timeout): New function - for the settable mark-as-seen timeout. - (mail_config_mark_as_seen_timeout): Likewise. - (mail_config_write): Write the timeout setting. - (config_read): Read timeout setting. - - * mail-config-gui.c (mail_config): Add option for the settable - mark-as-seen timeout. - (mail_config_apply_clicked): Likewise. - (timeout_changed): New function for the timeout setting. - -2000-08-16 Peter Williams <peterw@helixcode.com> - - * message-thread.c (walk_containers): More (default disabled) - mem debugging here. Fix the big leaks. - - * mail-format.c (get_url_for_icon): Copy the url_path so that - it can't get freed under us. - - * mail-threads.c (mail_operation_queue): Fix a leak. - - * mail-ops.c (mail_do_display_message): Fix another leak. - - * message-list.c (message_list_destroy): Remove the seen_id timeout - if necessary. - - * mail-local.c (mail_tool_local_uri_to_folder): Fix a leak. - - * session.c (auth_callback): Fix a leak. Almost seems as if - I've been using Purify... - - -2000-08-15 Peter Williams <peterw@helixcode.com> - - * message-thread.c (alloc_container): Add support for debugging - container allocations -- currently disabled. Make sure that - the g_strfreev works. - - * message-list.c (main_message_changed): Address bug #496 -- - possible race when forwading a message_changed event. - - * mail-threads.c (dispatch): Close the dispatch thread's half of - pipes when about to exit. - (mail_operations_terminate): Close the main thread's half of the - pipes when about to exit. - (all): Add i18n support. - - * mail-tools.c (all): Add i18n support. - - * mail-ops.c (transfer_messages): Generalize move_messages into - transfer_messages so that we can copy too. - (all): Add i18n supprt where appropriate. - - * mail-ops.h: Prototype the new mail_do_transfer_messages. - - * folder-browser-factory.c: Add a UI hook for copy_msg. - - * mail-callbacks.c (transfer_msg): Generalize move so that it supports - copy as well, and add a callback 'copy_msg'. - - * message-list.c (on_right_click): Add a right-click hook for Copy Message. - - * session.c (mail_request_dialog): Don't deadlock when in main thread. - -2000-08-14 Peter Williams <peterw@helixcode.com> - - * mail-threads.c (show_error): Fix the error dialogs. - (read_msg): Re-enable them. - - * mail-ops.c (do_scan_subfolders): Silence a compile warning. - -2000-08-13 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-crypto.c (mail_crypto_openpgp_encrypt): Added support for - encrypting via PGP 5.0 - -2000-08-13 Ettore Perazzoli <ettore@helixcode.com> - - * mail-ops.c (cleanup_create_folder): Release the listener object - with `CORBA_Object_release()', not `CORBA_free()'. - -2000-08-13 Ettore Perazzoli <ettore@helixcode.com> - - * main.c (main): Set the signal handlers for `SIGSEGV' and - `SIGBUS' to the default ones. - -2000-08-13 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-config.c (mail_config_write): Set config->configured to - TRUE - -2000-08-13 Ettore Perazzoli <ettore@helixcode.com> - - * mail-config-gui.c (mail_config_druid): Don't - `GDK_THREADS_ENTER()'/`GDK_THREADS_LEAVE()'. - -2000-08-13 Ettore Perazzoli <ettore@helixcode.com> - - * mail-threads.c (update_active_views): Just iterate through all - the controls, not just the active ones. - - * folder-browser-factory.c: Don't keep track of active controls. - Rather, keep track of all of them. - (folder_browser_factory_get_active_control_list): Removed. - (folder_browser_factory_get_control_list): New. - -2000-08-13 Dan Winship <danw@helixcode.com> - - * Makefile.am (evolution_mail_SOURCES): add mail-local.h - -2000-08-13 Ettore Perazzoli <ettore@helixcode.com> - - * mail-threads.c (read_msg): For now, don't do anything about - errors. - -2000-08-13 Dan Winship <danw@helixcode.com> - - * mail-format.c (add_url): Fix some freed-memory references - - * mail-threads.c (get_password): Don't free the prompt. It - doesn't belong to you. - -2000-08-13 Ettore Perazzoli <ettore@helixcode.com> - - * mail-ops.c (mail_do_create_folder): Duplicate the listener - object. - (cleanup_create_folder): Free the listener. - -2000-08-13 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-threads.c (get_password): Don't wrap the gnome_dialog_run - in GDK_THREADS_ENTER/LEAVE - -2000-08-13 Ettore Perazzoli <ettore@helixcode.com> - - * folder-browser-factory.c (control_destroy_cb): Remove the - control from the active control list, if it's there. - - * mail.h (folder_browser_factory_new_control): Removed prototype. - (folder_browser_factory_init): Removed prototype. - - * folder-browser-factory.h: New. - - * folder-browser-factory.c: New static variable `active_controls', - list of the currently active controls. - (control_activate): Add the control to it. - (control_deactivate): Remove the control from it. - (folder_browser_factory_get_active_control_list): New. - - * mail-threads.c (mail_operations_get_status): New function. - - * folder-browser.c (folder_browser_gui_init): Add i18n support for - the labels. - - [The following is actually from a patch by Peter Williams - <peterw@helixcode.com>.] - - * Removed types `PERCENTAGE', `HIDE_PBAR', `SHOW_PBAR'. New - struct `block_info_s'. Removed all the code to create and destroy - the progress window. - -2000-08-13 Jeffrey Stedfast <fejj@helixcode.com> - - * component-factory.c (create_news_storage): Updated to reflect - changes to mail_do_scan_subfolders - (create_imap_storage): Same. - - * mail-ops.c (mail_do_scan_subfolders): No longer takes an - add_INBOX argument - -2000-08-13 Dan Winship <danw@helixcode.com> - - * mail-ops.c (do_scan_subfolders): Lose a reference to the store - on purpose. To be fixed later. - -2000-08-12 Dan Winship <danw@helixcode.com> - - * component-factory.c (create_imap_storage): Take the source as a - command-line argument rather than fetching it from mail-config. - (owner_set_cb): Call create_imap_storage on each configured IMAP - store. - - * mail-format.c (decode_pgp): Redo this so that the lock icon - remains active after a failed decryption so you can click on it - and try again. - (try_inline_pgp, handle_multipart_encrypted): Put a border around - the decrypted data. - - * message-list.c (cleanup_regenerate_messagelist): Don't clear the - tree here. If two "folder_changed"s arrive in close succession, - then one possible ordering of events is - cleanup_regenerate_messagelist, cleanup_regenerate_messagelist, - cleanup_thread_messages, cleanup_thread_messages. Which would - result in the message list being filled in twice without being - cleared in between. So don't clear it until the rebuilding - function itself is called. - (clear_tree): New function to empty out the ETreeModel in the - message list. - (build_tree): Change to simpler interface. Call clear_tree. - (build_subtree): Does most of the work of the old build_tree - (build_flat): Remove unused arg. Call clear_tree. - - * message-thread.c (cleanup_thread_messages): Update for - build_tree interface change. - - * mail-ops.c (do_send_mail): Don't leak the transport. - - * mail-tools.c (mail_tool_get_folder_from_urlname): Don't ref the - store returned from camel_session_get_store. It's already reffed. - (mail_tool_get_root_of_store): Ditto. - (mail_tool_send_via_transport): Remove some commented-out code and - fix it to not leave the transport connected if sending fails. - - * mail-callbacks.c (delete_msg): Toggling a flag is an - "instantaneous" operation, so if we're only doing one, just do it - and return, rather than queueing it for the other thread. This - makes the "Delete" key work correctly (move to the next message) - again. - - * mail-identify.c: Remove workaround for gnome-vfs 0.2 bug. - - * mail-format.c (lookup_handler): Remove workaround for function - introduced between gnome-vfs 0.2 and 0.3, since we depend on 0.3 - now. - -2000-08-12 Michael Meeks <michael@helixcode.com> - - * main.c (main): kill using_oaf assertion. - -2000-08-11 Peter Williams <peterw@helixcode.com> - - * Makefile.am: Make it so that test-mail links - -2000-08-11 JP Rosevear <jpr@helixcode.com> - - * folder-browser-factory.c (control_activate): Move menu items - that affect a single message together, ditto with ones that - affect multiple messages, put a separator in. - -2000-08-11 Christopher James Lahey <clahey@helixcode.com> - - * mail-format.c, mail-tools.h, message-list.c: Fixed a warning. - -2000-08-11 Dan Winship <danw@helixcode.com> - - * mail-display.c, mail-format.c: Redo this again. Get rid of - struct mail_format_data and move most of that info into - MailDisplay itself, and pass the MailDisplay around. Add a GData** - to MailDisplay, and put the urls hash table into that. Also add - the ability to redisplay the currently-displayed message (with the - same GData**), and add a "show_pgp" datum to it that controls - whether or not to decrypt PGP messages, and redo the PGP stuff - (again) to take that into account. Now you don't get the annoying - PGP password dialog box without any warning. - -2000-08-11 Peter Williams <peterw@helixcode.com> - - * mail-config-gui.c (service_acceptable): Make verify-service - an asynchronous operation. - - * Makefile.am (noinst_PROGRAMS): Don't build test-thread - while mail-threads.c is in flux. - - * mail-threads.c (mail_operation_queue): Make the error - and query dialogs modal. - - * mail-local.c (update_progress): Don't use the - temporarily-disabled mail_op_set_percentage(). - -2000-08-11 Chris Toshok <toshok@helixcode.com> - - * mail-config.c (mail_config_get_default_news): use config->news - instead of config->sources. - -2000-08-11 Dan Winship <danw@helixcode.com> - - * mail-format.c (destroy_part): Update this for CamelObject - (try_inline_pgp): Deal with decrypting here rather than trying to - pawn the data off to handle_multipart_encrypted, since it most - likely won't be correct (won't have the proper MIME headers inside - the encrypted part). - (handle_multipart_encrypted): Add code from Nathan Thompson-Amato - to re-MIME-parse the decrypted data after decrypting. - - * mail-crypto.c (mail_crypto_openpgp_{de,en}crypt): Get the - password here rather than having it passed in. Remove some dead - code. - - * session.c (mail_request_dialog): Allow this to work in either a - sync or an async context. - -2000-08-11 Peter Williams <peterw@helixcode.com> - - * mail-tools.c (mail_tool_fetch_mail_into_searchable): Don't - do the imap check here... it's a silly place. - - * mail-ops.c (do_fetch_mail): Do the imap check here. - -2000-08-11 JP Rosevear <jpr@helixcode.com> - - * mail-config-gui.c (service_page_new): Work around - gtk option menu bug. - (service_page_item_auth_fill): ditto - -2000-08-11 Peter Williams <peterw@helixcode.com> - - * mail-threads.c (read_msg): Fix the new FORWARD_EVENT handler - (didn't free msg, didn't write newline in the debug) - - * mail-local.c (local_reconfigure_folder): Make the dialog - modal. - - * mail-callbacks.c (select_first_unread): Fix some warnings. - - * mail-threads.c (mail_op_forward_event): New function that - writes a FORWARD_EVENT signal to the compipe, to allow Camel - events to be handled in the main thread. - (read_msg): Handle a FORWARD_EVENT. - - * mail-callbacks.c (select_first_unread): Forward the - event into the main thread to prevent the GTK calls in the - dispatcher thread. - (main_select_first_unread): New name of old select_first_unread. - - * message-list.c (folder_changed): Same as above. - (main_folder_changed): Same as above. - (message_changed): Same as above. - (main_message_changed): Same as above. - - * mail-format.c (free_byte_array): Note about using - mail_op_forward_event. (cmm_destroyed): Same. - -2000-08-11 Dan Winship <danw@helixcode.com> - - * message-list.c (message_list_select): If the caller passes "-1" - for the model row, translate that to view row 0. - - * message-list.c (idle_select_row): - * mail-callbacks.c (select_first_unread): Use new - message_list_select kludge^H^H^H^H^H^Hfeature - -2000-08-11 JP Rosevear <jpr@helixcode.com> - - * mail-config-gui.c (source_dialog): Allow the window - to be growable - - * mail-config.c: use void in empty declarations - -2000-08-11 Peter Williams <peterw@helixcode.com> - - * mail-config.c (mail_config_get_news): Change () to (void) - if a function takes no arguments. - - * mail-config.h: Prototype mail_config_get_{sources,news}x - -2000-08-11 JP Rosevear <jpr@helixcode.com> - - * mail-config-gui.c (identity_dialog): iddialog, not sdialog - (news_edit_clicked): Kill leftover c-p crud - -2000-08-11 JP Rosevear <jpr@helixcode.com> - - * mail-config-gui.c (news_edit_clicked): Check nrow, not srow. - -2000-08-11 JP Rosevear <jpr@helixcode.com> - - * mail-config-gui.c (service_acceptable): Use camel_object_unref - instead of gtk_object_unref - (mail_druid_finish): Use new config accessors - (mail_config_druid): No need to call config functions - (news_add_clicked): Increments maxnrow, not maxsrow - (mail_config_apply_clicked): Use new config accessors - (mail_config): ditto - - * component-factory.c (create_imap_storage): Use new - config accessors - (create_news_storage): ditto - - * mail-config.glade: Set news clist name correctly - - * mail-config.c (config_read): Rename from mail_config_read and - made private - no one should need to do a read manually. - (mail_config_set_send_html): New accessor - (mail_config_add_identity): ditto - (mail_config_get_sources): ditto - (mail_config_add_source): ditto - (mail_config_get_default_news): ditto - (mail_config_get_news): ditto - (mail_config_add_news): ditto - - * mail-config.h: Prototype new accessors. Config struct is now - in mail-config.c and hidden from the world. - -2000-08-11 Dan Winship <danw@helixcode.com> - - * mail-ops.c (describe_fetch_mail): Use camel_service_get_name - rather than showing the URL to the user. - -2000-08-11 Peter Williams <peterw@helixcode.com> - - * mail-ops.c (do_refile_messages): Freeze the folders while moving. - (do_flag_messages): Same. - - * mail-threads.c (get_password_clicked): Fix the case when the - user /doesn't/ use escape to cancel the dialog :-/ - (show_error_clicked): Same. - -2000-08-11 Dan Winship <danw@helixcode.com> - - * mail-tools.c (mail_tool_get_folder_name): Add a function to - return a useful name for a folder (not just "mbox" or "mh" for - any local folder.) - - * mail-ops.c: Use mail_tool_get_folder_name rather than - folder->full_name when printing folder names. - -2000-08-11 Not Zed <NotZed@HelixCode.com> - - * mail-tools.c (mail_tool_get_local_inbox_url): Properly handle - different local file formats. The folder isn't always mbox. - (mail_tool_do_movemail): Movemail always uses an mbox format - however. - (mail_tool_get_local_movemail_url): What is the mbox url, it is - always the same type, mbox. - (mail_tool_fetch_mail_into_searchable): Same here. - - * mail-local.c (mail_local_map_uri): Map a local uri to the real uri. - -2000-08-10 Christopher James Lahey <clahey@helixcode.com> - - * folder-browser-factory.c, message-list.c, message-thread.c, - session.c: Fixed some warnings. - -2000-08-10 Dan Winship <danw@helixcode.com> - - * session.c (session_init): Don't call e_setup_base_dir. It was - wrong and it doesn't exist any more. - - * component-factory.c (owner_set_cb): Update for changed - prototype, and record the evolution_homedir. Move call to - mail_config_init here from session.c so it happens after - evolution_dir is initialized. - - * mail.h: define "extern char *evolution_dir;" (formerly in - e-util/e-setup.h) - - * component-factory.c, mail-callbacks.c, mail-config-gui.c, - mail-config.c, mail-display.c, mail-format.c, mail-ops.c, - mail-tools.c, session.c: Remove "e-util/e-setup.h" include. - -2000-08-10 Peter Williams <peterw@helixcode.com> - - * test-thread.c (queue_ops): Use mail_operations_terminate() to - close the other thread nicely. - - * mail-threads.c (get_password_deleted): Handle the "close" event - as a cancel. - (show_error): Same. - -2000-08-10 Dan Winship <danw@helixcode.com> - - * mail-tools.c (mail_tool_get_folder_from_urlname): Add a - "gboolean create" argument to pass to camel_store_get_folder. - - * mail-ops.c (do_create_folder, do_setup_draftbox): - * mail-local.c (mail_tool_local_uri_to_folder): - * mail-vfolder.c (vfolder_uri_to_folder): Add create flag to - mail_tool_get_folder_from_urlname calls. - -2000-08-10 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-callbacks.c (composer_send_cb): Fix compile warning by - casting the object to a CamelObject - -2000-08-10 Peter Williams <peterw@helixcode.com> - - * mail-tools.c (mail_tool_filter_contents_into): Delete the source - folder if told to and if it's empty - (mail_tool_get_local_movemail_path): New function. - -2000-08-10 Dan Winship <danw@helixcode.com> - - * mail-callbacks.c (reply_to_all): Fix a bug in the async changes. - (This was identical to reply_to_sender.) - -2000-08-10 Not Zed <NotZed@HelixCode.com> - - * mail-local.c (do_local_reconfigure_folder): Update for - append_message api change. - - * message-list.c (message_list_regenerate): Change for search api - change. - (ml_tree_value_at): Add a colour column, based on the colour - assigned in the summary. - (message_list_init_renderers): Init colour column. - -2000-08-09 Peter Williams <peterw@helixcode.com> - - * mail-display.c (part_for_url): Remove a gtk_object_get_data - -2000-08-09 Cody Russell <bratsche@gnome.org> - - * folder-browser-factory.c, mail-view.c: Make the toolbars - honor the user's gnomecc settings for detachable toolbars. - -2000-08-09 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-ops.c (composer_send_cb): Get the from address set in the - composer, if that fails ONLY THEN get the default from mail config - - * mail-config.c (mail_config_get_identities): New convenience - function for getting a list of the configured identities - -2000-08-09 Dan Winship <danw@helixcode.com> - - * mail-display.c (on_object_requested): Support controls as well - as embeddables. - -2000-08-09 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-view.c (mail_view_create): Changed to only take a - FolderBrowser argument - - * mail-ops.c (real_view_msg): Create a new FolderBrowser for each - message being opened in a new window. Also set the - message_list->cursor_uid and mail_display->current_message to the - appropriate values. - (real_view_msg): Updated to reflect changes in the mail_view_create - - * message-list.c (on_right_click): Nicify a little, add in a menu - separator between VFolder and Filter stuff. - - * mail-ops.c (real_view_msg): Set the UID of the message that is - being displayed - -2000-08-09 Ettore Perazzoli <ettore@helixcode.com> - - * folder-browser-factory.c (control_activate): Use - `GNOME_STOCK_MENU_*' things instead of `GNOME_STOCK_PIXMAP_*' - things, that are too big and look bad. - -2000-08-09 Peter Williams <peterw@helixcode.com> - - * mail-view.c (mail_view_create): Save the top window so that on_close - can find it [with set_data]. - (on_close): Recover the top window. - - * mail-threads.c (read_msg): Destroy the window instead of hiding it. - -2000-08-09 Not Zed <NotZed@HelixCode.com> - - * mail-autofilter.c (filter_gui_add_from_message): Helper function - to add with confirm. - (rule_match_recipients): Dont set real name if its empty for the - filter name. - (rule_match_subject): was cutting ] off mailing list names. - - * message-list.c (on_right_click): Added menu to install - vfolders/filters from message. - -2000-08-09 Not Zed <NotZed@HelixCode.com> - - * mail-autofilter.c: New file to hold auto filter/vfolder stuff. - -2000-08-09 Christopher James Lahey <clahey@helixcode.com> - - * mail-display.c, mail-format.c, mail-ops.c: Fixed some warnings. - - * message-list.c: Fix the call to e_popup_menu_run to match the - new signature. - -2000-08-09 Ettore Perazzoli <ettore@helixcode.com> - - * folder-browser-factory.c (control_activate): Create a "print - message" menu item. - -2000-08-09 Jeffrey Stedfast <fejj@helixcode.com> - - * message-list.c (message_list_init): Attached a double_click - signal handler - (on_double_click): Our lovely new double_click callback. Will - display the current selected message in a new window - -2000-08-08 Jeremy Wise <jwise@pathwaynet.com> - * mail-config.[ch], folder-browser.c: Added configuration work to - save the size of the vpaned widget. It will be functional when the - e_paned widget emits a "resized" signal - -2000-08-08 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-config.h: Added void as an argument to functions not - needing any parameters to avoid compile warnings. - -2000-08-08 Jeremy Wise <jwise@pathwaynet.com> - * mail-config.[ch], main.c, folder-browser-factory.c: State of the - threaded list toggle is now saved via gnome_config - -2000-08-08 Dan Winship <danw@helixcode.com> - - * mail-config-gui.c (service_page_item_new): Attach a signal - handler to call the "changed" function when the user clicks the - "keep on server" checkbox. - -2000-08-08 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-ops.c (view_msg): New convenience function with params of a - normal Gtk callback function. We also now create a new - FolderBrowser object so that the message-view window isn't tied to - the display in the main window - (view_message): Now calls view_msg (this function is a bonobo - callback and can't be used with gtk widgets) - (edit_msg): Same idea as view_msg() - (edit_message): Again, same as view_message() - - * message-list.c (on_right_click): Callback for creating an - e-popup-menu - (message_list_init): Added a right_click event to trigger a pop-up - menu to be displayed - -2000-08-08 Dan Winship <danw@helixcode.com> - - * mail-config-gui.c: Add "Don't delete messages from server" - button to remote SOURCEs that aren't STORAGEs (ie, POP). - (provider_list): Only list SOURCEs. (ie, not mh) - - * mail-config.c: Save/load "keep_on_server" flag. - - * mail-ops.c (fetch_remote_mail): New function, split out of - real_fetch_mail. Deals with copying mail from a remote server into - a temporary mbox, possibly using a CamelUIDCache to leave the - messages on the server. - - * mail-crypto.c, mail-format.c, message-thread.c: Fix some - compiler warnings. - - * mail-format.c (mail_generate_reply): Fix up format of addresses. - (write_headers): Use CamelAddress functions to simplify this. - -2000-08-08 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-view.c: Lets get rid of the last separator in the toolbar - until we add n/p - -2000-08-08 Ettore Perazzoli <ettore@helixcode.com> - - * mail-threads.c (queue_window_delete_event_cb): Callback for - "delete_event", just doing nothing. - (create_queue_window): Connect it to the "delete_event" signal of - the progress dialog. - -2000-08-08 Peter Williams <peterw@helixcode.com> - - * mail-threads.c (remove_next_pending): Sanity check for - job queue, which seems to have some issues. - (read_msg): Make sure that the next operation isn't started - before the last one is cleaned up. - - * mail-callbacks.c (fetch_mail): Fix erroneous free. - - * mail-config-gui.c (mail_config_druid): Wrap the gtk_main call. - - * mail-ops.c (do_flag_messages): Allow specification of whether - to set the flags unconditionally or toggle their current state. - - * message-list.c (ml_tree_set_value_at): Toggle the seen status; - don't set it unconditionally. - - * mail-callbacks.c (delete_msg): Toggle the deletion status; - don't set it unconditionally. - - * mail-tools.c (mail_tool_do_movemail): Fix for undeclared tmpfd. - - * mail-local.c (local_reconfigure_folder): Big rewrite; make into - an asynchronous operation. Use some mail tools to make life easy. - -2000-08-08 Dan Winship <danw@helixcode.com> - - * main.c (main): Move mail_config_init after session_init, since - it depends on evolution_dir being set. - -2000-08-08 JP Rosevear <jpr@helixcode.com> - - * mail-ops.c (check_configured): Use config accessors - (fetch_mail): ditto - (composer_send_cb): ditto - (create_msg_composer): ditto - - * mail-config-gui.h: Update API - - * mail-config.h: Update API - - * mail-config.c: Add accessor functions - (mail_config_is_configured): accessor function - (mail_config_get_default_identity): ditto - (mail_config_get_default_source): ditto - (mail_config_get_transport): ditto - (mail_config_send_html): ditto - (identity_copy): Make public - (identity_destroy): ditto - (identity_destroy_each): ditto - (service_copy): ditto - (service_destroy): ditto - (service_destroy_each): ditto - (mail_config_init): Rename from init_config and make public - (mail_config_clear): Rename from clear_config and make public - (mail_config_read): Rename from read_config and make public - (mail_config_write): Reanme from write_config and make public - - * main.c (main): Call mail_config_init. - - * mail.h: Include mail-config-gui.h - - * mail-config-gui.c: Move config gui stuff here. - (source_dialog): Kill memory leak from debug leftovers. - Make sure returned source is NULL by default - -2000-08-07 Not Zed <NotZed@HelixCode.com> - - * mail-local.c (local_reconfigure_folder): Redone to show a - dialogue first, and show progress of whats happening as its done. - - * Makefile.am (glade_DATA): Added local-config.glade, for mailbox - reconfig dialogue. - -2000-08-04 Not Zed <NotZed@HelixCode.com> - - * folder-browser.c (mail_uri_to_folder): Use local_uri_to_folder() - for local uri's (file://). - - * mail-local.c (local_uri_to_folder): Handle looking up folder - storage type before opening the store/folder. - (local_reconfigure_folder): Function to reconfigure the format of - a local mailbox into another storage format. - - * Makefile.am (evolution_mail_SOURCES): Added mail-local.c and - missing mail-vfolder.h. - -2000-08-07 Jeffrey Stedfast <fejj@helixcode.com> - - * Makefile.am: Added mail-view.c - - * folder-browser-factory.c (control_activate): Adda menu item for - viewing the message - - * mail-view.c: New file containing methods for viewing messages in - separate windows - - * mail-ops.c (view_message): New callback for viewing messages in - a new window. - -2000-08-07 Jeffrey Stedfast <fejj@helixcode.com> - - * component-factory.c (real_create_generic_storage): New function - to replace real_create_imap_storage and real_create_news_storage - (create_imap_storage): Updated. - (create_news_storage): Updated. - -2000-08-07 Peter Williams <peterw@helixcode.com> - - * mail-ops.c (cleanup_edit_messages): New operation: edit_messages - For continuing draft messages. - (attach_messages): Fix accidental 0 datasize. - (do_setup_draftbox): New operation: setup_draftbox. Soooo hacky. - - * mail-callbacks.c: Move fejj's edit message to the async home. - - * component-factory.c (owner_set_cb): Use mail_do_setup_draftbox. - - -2000-08-07 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-display.c: - * component-factory.c: s/strncasecmp/g_strncasecmp - - * mail-format.c (write_headers): Get rid of kludge around subject - beginning with spaces. - (mail_generate_reply): Get rid of kludge around subject beginning - with spaces and also use g_strncasecmp instead of strncasecmp for - portability - - * mail-ops.c (forward_msg): Get rid of kludges around subject - beginning with spaces. - -2000-08-07 Dan Winship <danw@helixcode.com> - - * message-list.c (message_list_select): Clarify that the input row - is a model row, and swap it to a view row when finding the - next/previous row. - (idle_select_row): Select view row 0, not model row 0. - - * mail-ops.c (select_first_unread): Start from view row 0, not - model row 0. - -2000-08-07 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-format.c (mail_get_message_body): Renamed from reply_body() - so other functions can use it - (mail_generate_reply): Updated to reflect function name changes - - * mail-ops.c (real_edit_msg): Attach a callback to the send signal - -2000-08-07 Jeffrey Stedfast <fejj@helixcode.com> - - * folder-browser-factory.c (control_activate): New menu item under - Actions to allow editing of messages. - - * mail-ops.c (edit_message): New function for editing messages. - - * component-factory.c (owner_set_cb): Create a global reference to - the Drafts mbox folder for the Composer to use - -2000-08-06 JP Rosevear <jpr@helixcode.com> - - * mail-config.c (ndialog_page_undone): Desensitize ok button - (sdialog_page_undone): ditto - (iddialog_page_undone): ditto - (news_page_new): Typo - news, not mail - (transport_page_new): Typo - transport, not source - (identity_dialog): Set undone callback - (source_dialog): ditto - (news_dialog): ditto - (mail_druid_identity_undone): Desensitize next button and - mark done flag as false - (mail_druid_source_undone): ditto - (mail_druid_transport_undone): ditto - (mail_druid_identity_done): Mark done flag as true - (mail_druid_source_done): ditto - (mail_druid_transport_done): ditto - (mail_druid_prepare): Use done flag to set next button - sensitivity, fixes #467 - -2000-08-06 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-crypto.c (mail_crypto_openpgp_encrypt): Added support for - encrypting with GnuPG. Support for PGP5 and PGP2 are still in - progress. - -2000-08-05 Dan Winship <danw@helixcode.com> - - * folder-browser-factory.c (control_activate): Remove bonobo 0.15 - vs 0.15-and-a-half ifdef, since we require post-0.16 now. - -2000-08-04 Dan Winship <danw@helixcode.com> - - * mail-threads.c (mail_operation_wait_for_finish): Don't use - "while (gtk_events_pending ()) gtk_main_iteration ();" inside - another tight loop, because it makes the thread spin rather than - blocking and waiting like it should. - -2000-08-04 Peter Williams <peterw@helixcode.com> - - * message-thread.c (do_thread_messages): Uninitialized variable - fix. - - * mail-threads.c (read_msg): Small leak fix. - - * component-factory.c (owner_unset_cb): Use mail_operations_ - terminate() instead of wait_for_finish(). - - * mail-threads.c (mail_operation_queue): Centralize the clur - handling functions; fix a race condition where the dispatcher - would overwrite the closure before the main thread could - free the old one. - (mail_operations_terminate): New function, wait for ops to - finished and kill the other thread. - (dispatch): changes to die when terminate is called (abort - on NULL spec). - - * mail-ops.c (cleanup_display_message): Fix improper handling - of displaying a NULL message (which means clear the message - display). - -2000-08-04 Ettore Perazzoli <ettore@helixcode.com> - - * message-list.c (message_list_regenerate): Free the GPtrArray - correctly instead of using `g_strfreev()'. - -2000-08-04 Michael Meeks <michael@helixcode.com> - - * folder-browser-factory.c (control_activate): release the ui_handler - after set_container. - -2000-08-03 Michael Meeks <michael@helixcode.com> - - * mail-config.c (identity_page_new): only whack the sig in if the - file exists. - - * component-factory.c (factory_fn): count running instances, - attach destroy signal (factory_destroy): add. - - * main.c (main): pass orb around. - -2000-08-03 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-ops.c (composer_send_cb): Yay, no more compiler warnings - - * mail-config.c: set config = NULL - (provider_list) Eek! Initialize news to NULL! Also, use - g_slist_prepend() for "performance" gains ;-) - (init_config): Set the config member data to NULL just to be on - the safe side - (clear_config): Don't bother freeing slist data if the slist is - NULL - -2000-08-03 Peter Williams <peterw@helixcode.com> - - * mail-ops.c (op_forward_messages): Use the new dynamic - operation naming. - - * message-thread.c (describe_thread_messages): Ditto. - - * message-list.c (describe_regenerate_messagelist): Ditto. - - * mail-threads.c (get_password_clicked): Dynamic generation - of descriptive text for mail operations. "Opening a folder" -> - "Opening INBOX". Supported only so far, will be implemented - quickly. - g_strdup() the old_message when changing the queue_window_label's - text. - - * main.c (main): One more gconf reference to take out... - - * mail-ops.c (composer_send_cb): Check for an identity before - sending. - -2000-08-03 JP Rosevear <jpr@helixcode.com> - - * mail-config.glade: Increase window size slightly, rename - "Transport" to "Mail Transport" - - * mail-config.c (init_config): Remove gconf references - (clear_config): ditto - (read_config): ditto - (write_config): ditto - (mail_config): Null provider lists before filling them - (mail_config_druid): ditto - (identity_page_new): Increase spacing of vbox - (service_page_new): ditto - - * Makefile.am: Remove gconf references. - -2000-08-02 Dan Winship <danw@helixcode.com> - - * mail-config.c (service_page_item_new): Make the "test settings" - button FILL rather than SHRINK so it doesn't end up oddly-placed. - - * mail-config-druid.glade: Make the icon background dark blue - like the surrounding area. - -2000-08-02 Peter Williams <peterw@helixcode.com> - - * component-factory.c (owner_unset_cb): Wait for async operations - to finish before exiting. - -2000-08-02 Christopher James Lahey <clahey@helixcode.com> - - * mail-ops.c, message-list.c: Emit "model_pre_change" where - appropriate. - -2000-08-02 Peter Williams <peterw@helixcode.com> - - * mail-config.h: #ifdef _MAIL_CONFIG_H protect the header. - -2000-08-01 Peter Williams <peterw@helixcode.com> - - * mail-threads.c: Implement Solaris threads. Attempt - to join to the thread upon exit -- hopefully prevents - all those nasty zombie processes from popping up :-( - -2000-08-01 Dan Winship <danw@helixcode.com> - - * mail-crypto.c: New code to spawn off GPG/PGP to do stuff. - Currently only deals with decryption. From Nathan Thompson-Amato - <ndt@jps.net>, with bunches of changes from me. - - * session.c (mail_request_dialog): Expose the password dialog to - the rest of the app (for use by the GPG/PGP code). - - * mail-format.c (handle_text_plain): Handle special inline data - types. (Currently uuencoding, BinHex, and PGP encryption.) This is - not the best way to deal with it, but it works for now. - (try_inline_pgp): Convert an inline PGP-encrypted message into a - multipart/encrypted part. - (try_inline_binhex): Convert an inline BinHex attachment into an - application/mac-binhex40 part (which we currently don't deal - with...) - (try_uudecoding): Convert a uuencoded attachment to an - application/octet-stream part. - (handle_multipart_encrypted): Deal with RFC2015 MIME-encoded PGP - encrypted messages. (From ndt.) - - * mail-display.c (mail_text_write, mail_error_write): New utility - functions. - - * Makefile.am (evolution_mail_SOURCES): add mail-crypto.c - -2000-07-31 Christopher James Lahey <clahey@helixcode.com> - - * component-factory.c, folder-browser.c: Fixed some warnings. - - * message-list.c: Made the icon column non sortable. - -2000-07-31 Dan Winship <danw@helixcode.com> - - * mail-config.c (service_page_set_url): Fix a NULL-pointer strcmp - noticed by peterw. - -2000-07-31 Not Zed <NotZed@HelixCode.com> - - * mail-vfolder.h: Header for vfolder functions. - - * folder-browser.c (mail_uri_to_folder): Use new scheme to open - vfolders. - (search_save): New button/function to save a search as a vfolder. - - * mail-vfolder.c (vfolder_edit): Made asynchronous. - (vfolder_uri_to_folder): New function for loading vfolders and - setting up their source folders. - (vfolder_refresh): Change shell vfolder uri's to indirect - references rather than the real vfolder uri. - (vfolder_gui_add_rule): Add a rule with user confirmation. - (vfolder_create_part): Get a new part by name, for creating rules - in code. - - * message-thread.c (thread_messages): Check for uid lookup - failure, which indicates an error in the folder or calling code. - -2000-07-29 Not Zed <NotZed@HelixCode.com> - - * component-factory.c (create_view): Remove hack to pass the - storage around. - - * folder-browser-factory.c (control_activate): Changed to call - renamed vfolder editor. - - * mail-ops.c (vfolder_edit_vfolders): renamed from vfolder_edit, - call new edit function. - (vfolder_editor_clicked): Removed. - (filter_druid_clicked): - (filter_edit): Updated for api change. - (real_fetch_mail): Fixed up for api change and fucked up indent. - (filter_get_folder): callback for filter driver. - - * mail-vfolder.c: New file to manage virtual folders. - -2000-07-29 JP Rosevear <jpr@helixcode.com> - - * mail-format.c (mail_generate_reply): Use new mail config stuff - - * component-factory.c (create_imap_storage): Use new mail config - stuff - (create_news_storage): ditto - - * evolution-mail.schemas: Gconf schema for evolution mail - - * mail-config-druid.glade: Gladification of config druid - - * mail-config.h: New header with config structs. - - * mail-config.c: Rewrite of GUI configuration tools to use - new config structs. Stores multiple identities and sources now. - Still only uses the first one found. - (mail_config_fetch): Returns MailConfig struct to caller - for configuration queries. - (mail_config): Renamed function to show mail config dialog. - (mail_config_druid): Renamed function to show mail config druid. - - * mail-ops.c (create_msg_composer): Use - e_msg_composer_new_with_sig_file and new config stuff - (check_configured): Use new config stuff - (fetch_mail): ditto - (composer_send_cb): ditto - -2000-07-28 Cody Russell <bratsche@gnome.org> - * mail-ops.c, mail.h: Added mark_all_seen(), to mark every - message in the list with CAMEL_MESSAGE_SEEN. - - * folder-browser-factory.c: Added "Actions/Mark all seen". - -2000-07-27 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-config.c: Lets fix Dan's kludge the Right Way (tm) - (set_service_url): Only strip off the leading "/" from the - url->path if url->host is NULL - (get_service_url): Only prepend a leading "/" to the path if the - host is NULL - -2000-07-27 Dan Winship <danw@helixcode.com> - - * mail-config.c (get_service_url): toss in a kludge to deal with - the IMAP vs mbox path problem for now. - -2000-07-26 Christopher James Lahey <clahey@helixcode.com> - - * message-list.c, message-list.h: Removed counting of selected - messages. - -2000-07-26 Dan Winship <danw@helixcode.com> - - * mail-ops.c (real_fetch_mail): Don't create the tmp_mbox before - calling movemail, because the external movemail requires it to not - exist. Contrariwise, delete it in the cleanup code if it's empty. - Update for camel_movemail interface change. Do the "No new - messages" dialog in the mbox case as well as the remote mail - issue. - -2000-07-26 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-ops.c: s/struct refile_data/struct move_data - (real_move_msg): Renamed from real_refile_msg() - (move_msg): Renamed from refile_msg() - - * folder-browser-factory.c: Changed Refile to Move. - -2000-07-26 Dan Winship <danw@helixcode.com> - - * mail-format.c (lookup_handler): Update for OAF and for external - apps as well as components. - (handle_via_external): Handler to set up for data that can be - displayed by an external application. - - * mail-display.c (on_link_clicked, etc): Refactor the save_data() - code and add launch_external() as a handler for - x-evolution-external URLs. - (embeddable_destroy_cb): Remove this, since it seems like it's all - wrong. - (on_object_requested): Update for OAF, and fix some bugs. - -2000-07-25 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-config.c (get_service_url): Always prepend a leading "/" to - the url->path. - (set_service_url): Added more error checking and also strip the - leading '/' from the url->path - (create_identity_page): Set the signature file to the one specified in - the identity record, else set the default path to ~/.sugnature - -2000-07-25 Michael Meeks <michael@helixcode.com> - - * mail-config.c (create_identity_page): set default signature to - ~/.signature - -2000-07-25 Peter Williams <peterw@helixcode.com> - - * mail-ops.c (reply): Check for the case of fb->mail_display-> - current_message = NULL, which shouldn't happen, but has happened - to me. - -2000-07-25 Dan Winship <danw@helixcode.com> - - * message-thread.c (group_root_set): Don't group together messages - with the same non-Re: subject and no References/In-Reply-To. More - often than not, they're unrelated. (eg, "[No subject]".) - (thread_messages): Handle messages with no Message-Id. "This - shouldn't happen", but it does sometimes, and it's not much code - to make it just work. - -2000-07-25 Ettore Perazzoli <ettore@helixcode.com> - - * mail-config.c (create_service_page): Call - `gtk_option_menu_set_menu()' as the last thing, as `GtkOptionMenu' - is fscking broken. Also, `gtk_widget_show()' the individual menu - items. - -2000-07-24 Dan Winship <danw@helixcode.com> - - * message-list.c (mark_msg_seen, ml_tree_set_value_at, - message_list_regenerate): Update for CamelFolder API changes. - (Certain functions no longer take a CamelException.) - - * mail-ops.c (real_fetch_mail, real_send_mail, real_delete_msg): - ditto - - * component-factory.c (real_create_imap_storage, - real_create_news_storage): ditto - -2000-07-24 Dan Winship <danw@helixcode.com> - - * component-factory.c, folder-browser-factory.c, test-mail.c: - Remove GOAD support. - - * main.c: Remove GOAD support. - (main): More "guess the build mistake" fun, this time for the - failure to initialize Bonobo case. - -2000-07-24 Peter Williams <peterw@helixcode.com> - - * mail-tools.c (mail_tool_set_uid_flags): Change - function to faithfully pass parameters to - camel_folder_set_message_flags; this function is - somewhat useless now. Other files synced with - API change. - - * mail-ops.c (op_display_message): Change "display - a message" into "retrieve a messsage" in the - description of mail_op_display_message. - - * mail-threads.c (display_timeout): New function. - Only display the progress dialog if the operation - takes more than a second to perform. - (hide_queue_window): New function. Hide the queue - window as an idle function... I'm thinking maybe - the problem with hiding it was due to us not - being in a GTK event sequence? Perhaps it's only - the timeout, which was not being cancelled, which - is now. - - * message-list.c (get_message_uid): New function, - copy of get_message_info, except gets only the - UID, as that's all that most functions want, and - we avoid a Camel call. - -2000-07-23 Ettore Perazzoli <ettore@helixcode.com> - - * mail-ops.c (create_message_composer): New. - (compose_msg): Use it. - (send_to_url): Likewise. - (forward_msg): Likewise. - - * folder-browser-factory.c (control_activate): Use `_()' instead - of `N_()'. - -2000-07-21 Peter Williams <peterw@helixcode.com> - - * message-thread.c (setup_thread_messages): New - operation: thread_messages, simple wrapper around - thread_messages () and thread_messages_free(); - - * message-list.c (cleanup_regenerate_messagelist): - Use new thread_messages operation instead of just - calling ... thread_messages :-) - - * folder-browser.c (folder_browser_destroy): Use new - sync_folder operation instead of calling camel_folder_sync - directly. - - * component-factory.c (create_folder): Changed to use - new create_folder operation. - - * mail-ops.c (mail_do_create_folder): New operation: create - folder. New operation: sync folder. - - * mail-format.c (cmm_destroyed): Remove the url hashtable from - the larger hashtable when it gets destroyed. - - * mail-callbacks.c (fetch_mail): Pass a hook function and data - down the chain to pick up the folder_changed and change the view. - - * mail-ops.c: Rename from mail-ops-new.c now that it's a little more - solid. - (fetch_mail): Add new options to hook and unhook an event while the - filter driver runs. A hack, but all of the operations are to some - extent. - (cleanup_fetch_mail): Unref the destination folder if not NULL. - * mail-tools.c (mail_tool_filter_contents_into): Intermediate the - event hook/unhook hack here. - -2000-07-20 Peter Williams <peterw@helixcode.com> - - * mail-ops-new.c (setup_send_mail): Fix silly forgetting-to-ref - problem on some sends (when not replying). Note the early exit - path with a big comment. - - * message-list.c (message_list_set_folder): Don't call - folder_changed, call mail_do_regenerate_messagelist, as - the GDK_THREADS_ENTER in the former can deadlock us! - - * folder-browser.c (folder_browser_set_uri): Ah, screw it. - Make 'load folder' asynchronous and pretend that it always - succeeds. - - * mail-ops-new.c (mail_do_load_folder): New operation, loads - a folder into a FolderBrowser. - - * mail-threads.c (read_msg): Check if the exception is - a user cancel; don't complain if it is. - (mail_operation_queue): Same. - (dispatch_func): Same. - -2000-07-20 Peter Williams <peterw@helixcode.com> - - * mail-ops-new.c (cleanup_send_mail): Fix evil mistaken - unref. - - * test-thread.c: Fit the new mail_operation_spec prototype. - - * mail-callbacks.c (composer_send_cb): Hide the composer upon - start of send operation. - - * folder-browser.c: #include "mail-ops-new.h" - - * mail-threads.h: Change text fields of mail_operation_spec to - provide two forms of the name. - - * mail-threads.c: Use appropriate new string fields. - (dispatch_func): Hide the progressbar by default. - - * message-list.c (op_regenerate_messagelist): Fix the datasize from - 0 -> sizeof (regenerate_messagelist_data_t). Add the new gerund and - infinitive strings. - (do_regenerate_messagelist): Include some code that fell between the - cracks. - - * mail-ops-new.c (op_scan_subfolders): Same datasize fix for - scan_subfolders. - (op_forward_message): Same. - (all): Add new gerund and inifinitive strings for mail_operation_spec. - (cleanup_send_mail): Destroy the composer on success; re-show it on - error. I'm so clever! - -2000-07-20 Ettore Perazzoli <ettore@helixcode.com> - - * component-factory.c (factory_fn): Updated for the new - `evolution_shell_component_new()' arg. - -2000-07-19 Jeffrey Stedfast <fejj@helixcode.com> - - * message-thread.c (thread_messages): What if message info is NULL? - -2000-07-17 Peter Williams <peterw@helixcode.com> - - * component-factory.c (real_create_{imap,news}_storage): Instead of - directly calling evolution_storage_new_folder, queue up a list of - folders to register so that we don't do our CORBA in The Other Thread. - (create_{imap,news}_storage): Changes ancillary to the above. - (add_new_mailbox): New function to queue up a folder - (cleanup_create_info): New function to dequeue the folders and free mem. - - * test-thread.c: s,ENABLE_BROKEN_THREADS,USE_BROKEN_THREADS -- oops - - * mail-format.c: (mail_lookup_url_table): New function to get the url - table associated with a CamelMimeMessage because we can no longer - gtk_object_get_data on it. - - * mail-display.c: replace 'gtk_object_get_data( message, "urls" )' - with 'mail_lookup_url_table( message )' - -2000-07-16 Jeffrey Stedfast <fejj@helixcode.com> - - * folder-browser.c, component-factory.c: Initial code to support - IMAP folders that don't use "/" as a directory separator. - -2000-07-15 Ettore Perazzoli <ettore@helixcode.com> - - * mail-ops.c (set_x_mailer_header): New helper function to set the - `X-Mailer:' header to to `Evolution <version> [Developer - Preview]". - (real_send_mail): Call it. - -2000-07-14 Peter Williams <peterw@curious-george.helixcode.com> - - * message-list.c (message_list_set_folder): Ported to CamelObject: - GTK_OBJECT->CAMEL_OBJECT; gtk_signal_connect->camel_object_hook_event; - GDK_THREADS_ENTER/LEAVE around "changed" event hooks. - - * folder-browser.c (folder_browser_destroy): likewise. - (mail_uri_to_folder): likewise. - (folder_browser_load_folder): likewise. - -2000-07-14 Ettore Perazzoli <ettore@helixcode.com> - - * Makefile.am (evolution_mail_LDADD): Add `GCONF_LIBS'. - -2000-07-14 Dan Winship <danw@helixcode.com> - - * mail-format.c (write_headers): put a <p> at the end of the - header table. (I think there used to be whitespace after it, but - then some gtkhtml change got rid of it...) - (handle_text_plain): Don't do this <PRE>. Instead, CONVERT_NL and - CONVERT_SPACES and wrap it in <TT>. Now if the sender didn't - include any newlines, it will be wrapped to the width of the - window instead of extending off into infinity. - -2000-07-13 Dan Winship <danw@helixcode.com> - - * message-list.c (message_list_destroy): Only unref the folder if - it's been set. - - * folder-browser.c (folder_browser_destroy): Only sync the folder - if it's been set. - -2000-07-13 Jonathan Blandford <jrb@redhat.com> - - * mail-config.c (create_transport): - s/CAMEL_SERVICE_NEED_HOST/CAMEL_SERVICE_URL_NEED_HOST. - -2000-07-13 Dan Winship <danw@helixcode.com> - - * mail-config.c (add_row): Add a "gboolean required" argument, and - set its value on the entry. - (create_source, create_transport): Create rows for URL elements if - the URL ALLOWs them. Mark them required if it NEEDs them. - (service_note_doneness): Only require the required fields to be - filled in. - - Now the IMAP config page allows the user to enter a path, but - doesn't require it. - -2000-07-13 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-ops.c (real_fetch_mail): Back to the old way to avoid - g_warnings, yay. Also fix append to send a flags argument (0) - -2000-07-12 Chris Toshok <toshok@helixcode.com> - - * mail-config.c (providers_config_new): fix some cut & paste bung. - -2000-07-12 Chris Toshok <toshok@helixcode.com> - - * mail-format.c (setup_function_table): add "message/news" to the - mime_function_table using the same handler as message/rfc822. - -2000-07-12 Chris Toshok <toshok@helixcode.com> - - * mail-config.glade*: add news server tab to dialog. - - * mail-config.c (on_NewsServerConfigDialogButton_clicked): new function. - (on_clistNewsServers_select_row): new function. - (on_cmdNewsServersAdd_clicked): new function. - (on_cmdNewsServersEdit_clicked): new function. - (on_cmdNewsServersDelete_clicked): new function. - (providers_config_new): mirror the source tab's code to fill in - the news server tab. - (write_config): save out the news server. - (create_news_server_config_dialog): new function. - (create_news_server_page): new function. - -2000-07-12 Peter Williams <peterw@helixcode.com> - - * mail-display.c (save_data): Change from evolution_dir to - g_get_home_dir() for default location of save file. - -2000-07-11 Dan Winship <danw@helixcode.com> - - * Update for CamelFolder API changes - -2000-07-11 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-ops.c (real_fetch_mail): Changed to use - camel_folder_move_message_to () rather than get_message () and then - append_message (). This also makes it so we don't have to worry about - fetching message flags to pass to the new append_message () method. - - * folder-browser.c (folder_browser_load_folder): Disable - Search capability menu/entry if folder doesn't support it. - - * message-list.c (message_list_regenerate): Don't perform - a search if the folder doesn't support it. - -2000-07-11 Dan Winship <danw@helixcode.com> - - * mail-ops.c (real_send_mail): Set the post_send_data flag rather - than toggling it. (Maybe we'll need more control over it later, - but for now, the only flag we set is "replied", and we want - that set, not toggled.) - -2000-07-10 Dan Winship <danw@helixcode.com> - - * folder-browser-factory.c (control_activate): Work with both - current and 0.15 bonobo - - * kill more debugging messages - - * mail-ops.c (real_fetch_mail): Don't multiply free dest_url. - - * message-list.c (message_list_select): Update - message_list_select_next to do either next or previous. - - * folder-browser.c (etable_key): Make 'n' and 'p' do next and - previous unread message. - - * mail-ops.c (select_first_unread): Update. - (real_fetch_mail): clean up a bit. - -2000-07-10 Ettore Perazzoli <ettore@helixcode.com> - - * mail-ops.c (forward_msg): Initialize `fwd_subj' to NULL if - `from' is NULL. - -2000-07-10 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-ops.c (real_fetch_mail): Fixed broken POP fetching - -2000-07-10 Ettore Perazzoli <ettore@helixcode.com> - - * component-factory.c: Removed variable `browsers'. - (create_view): Don't update it. - (owner_unset_cb): Don't sync the folders here anymore, because at - this point the folder browser is dead already so we cannot get a - valid list of folders from it anymore. - - * folder-browser.c (folder_browser_destroy): Sync the associated - mailbox first. - -2000-07-10 Christopher James Lahey <clahey@helixcode.com> - - * message-list.c, message-list.h: Switched from ETable to - ETableScrolled. - -2000-07-10 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-ops.c (real_fetch_mail): Fixed movemail so that it too would - deliver to Inbox. - -2000-07-09 Dan Winship <danw@helixcode.com> - - * message-list.c (get_message_info): Don't g_warn if the user - selects a fake tree parent. - (message_list_select_next): Ignore fake rows - (build_tree): Store the "root_subject" for fake rows - (ml_tree_value_at): Display the correct subject for fake rows. - (on_cursor_change_cmd): Update for the other changes and set - cursor_uid to NULL when the cursor is on a fake row. - - * mail-ops.c (reply): Don't try to reply when no (real) message is - selected. - (forward_msg): Ditto. - -2000-07-09 Christopher James Lahey <clahey@helixcode.com> - - * message-list.c: Remove setting of dnd_code since that's handled - internally to ETable. - -2000-07-08 Dan Winship <danw@helixcode.com> - - * folder-browser.c (etable_key): Fix up the pageup/pagedown - increment a bit. - - * folder-browser-factory.c (control_activate): Add a "Threaded - Message List" item to the "View" menu. - - * message-list.c (message_list_toggle_threads): Handler for that. - (build_flat): New function to build a "flat" message list using - the tree model. - (message_list_regenerate): Build tree or flat message list - depending on the global setting. - - * message-thread.c (get_root_subject): fix a "Re:" parsing bug - -2000-07-08 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-ops.c (real_fetch_mail): Always dump incoming messages to - Inbox (assuming not filtered to another location). - -2000-07-08 Ettore Perazzoli <ettore@helixcode.com> - - * folder-browser-factory.c (control_activate): Move the - "Expunge" item to the "Action" menu. - (control_deactivate): Accordingly. - -2000-07-08 Dan Winship <danw@helixcode.com> - - * mail-ops.c (forward_msg): Deal with having multiple selected - messages. - - * mail-format.c (mail_generate_forward): Removed. (Integrated into - forward_msg) - -2000-07-08 Jeffrey Stedfast <fejj@helixcode.com> - - * message-list.c (build_tree): Small fix to stop uid data from - being set on a message-list tree node when it didn't correspond - to an actual message. - -2000-07-08 Dan Winship <danw@helixcode.com> - - * message-list.c (get_message_info): Fix Jeff's FIXME: This does - get called with out-of-range data sometimes, so we do need the - check. Use e_table_model_row_count to get the actual right answer. - -2000-07-07 Jeffrey Stedfast <fejj@helixcode.com> - - * message-list.c (get_message_info): This wasn't quite right, it - will now work but still isn't perfect. See FIXME comment. - -2000-07-07 Dan Winship <danw@helixcode.com> - - * message-thread.c (remove_node): Add another argument "clast" - pointing to the container before the current one in the list, - which it can update if that turns out to be the one that it - removed. - (group_root_set): Update for remove_node change, and remove both - nodes in the "subjects are common" case. Fixes a bug that would - cause the message list to be truncated if this rule was invoked. - - (sort_node): sort the tree by the original order of the messages - in the folder rather than by date. - -2000-07-07 Dan Winship <danw@helixcode.com> - - * message-list.c: Lots of changes. Store uids as node data on the - tree nodes and use those rather than rows where possible. (The - concept of "row" is just getting too complicated.) Get rid of the - summary_table, because given a uid we can call - camel_folder_get_message_info, which makes more sense than keeping - a separate uid->row hash table ourselves. - - (get_message_info): update - (get_message_row): removed - (ml_col_cound, ml_row_count, ml_value_at, ml_set_value_at, - ml_cell_is_editable, ml_duplicate_value, ml_free_value, - ml_initialize_value, ml_value_is_empty, ml_value_to_string): - Removed. We always use the tree model now. - (message_list_init): Remove the non-tree code. - (build_tree): store uids in the tree rather than row numbers, - and build the message_list->uid_rowmap to map from uids to rows - when needed. - (message_list_regenerate): Renamed from _set_search, since it's - used to redraw in non-search cases too. - (message_changed): Use the uid_rowmap to get a model row number. - - * message-thread.c (thread_messages): Change the interface on this - to work with the new MessageList. - - * folder-browser.c (search_set, folder_browser_clear_search): - s/message_list_set_search/message_list_regenerate/ - -2000-07-07 Christopher James Lahey <clahey@helixcode.com> - - * message-list.c (get_message_info): Handle a row number of -1 - properly. - -2000-07-06 Dan Winship <danw@helixcode.com> - - * message-list.c (get_message_info): Map tree model row numbers to - summary row numbers. - (ml_tree_value_at, ml_tree_set_value_at, - ml_tree_is_cell_editable): So don't do that here. - -2000-07-06 JP Rosevear <jpr@arcavia.com> - - * mail-config.glade*: Glade files for the configuration dialog. - - * mail-config.c (providers_config_new): Build the dialog with - glade. - -2000-07-06 Dan Winship <danw@helixcode.com> - - * folder-browser-factory.c, folder-browser.c, mail-ops.c, - message-list.c: fix warnings. - - * main.c (main): gtkhtmllib_init is no more. Call gconf_init - directly instead. - - * message-list.c (message_list_select_next): New function to - select the first message on or after the given row that meets - certain flag criteria. - - * mail-ops.c (real_fetch_mail): call message_list_select_next to - select first unread message in current folder if it changes. - (real_delete_msg): Remove the code to move the etable cursor. It - only makes sense really if you deleted the message with the - keyboard, so do it from etable_key. - - * folder-browser.c (etable_key): call message_list_select_next to - select next non-deleted message after Delete. - - * mail-identify.c: Add a workaround for a small gnome-vfs 0.2 bug - so we don't need to require CVS gnome-vfs. - -2000-07-06 Not Zed <NotZed@HelixCode.com> - - * message-thread.c (sort_thread): sort messages based on date for - the initial sort order. - (thread_messages_free): Implement. - - * message-list.c (message_list_init_header): Setup the subject - renderer to a tree in tree mode. - (on_cursor_change_cmd): For a tree model, map the view row to the - data row. - (build_tree): Builds the tree data structure of all messages. - (message_list_set_search): For a tree model, build the tree here. - (ml_tree_icon_at): Icon callback, returns nothing. - (ml_tree_value_at): - (ml_tree_set_value_at): - (ml_tree_is_cell_editable): Maps tree node to data row, and calls - the equivalent table callback - (message_list_init_renderers): Setup the tree renderer if needed. - (message_list_init): set the root node invisible afterall. - (message_list_set_search): Clear the old tree before putting in a - new one. - - * message-list.h: Add a tree renderer to render list, and - tree_view indicator. - - * message-thread.[ch]: Code for message threading. - -2000-07-05 Dan Winship <danw@helixcode.com> - - * mail-identify.c (mail_identify_mime_part): Oops. My gnome-vfs - was out-of-date. Update for changed function name. - -2000-07-05 Dan Winship <danw@helixcode.com> - - * mail-identify.c (mail_identify_mime_part): Use the gnomevfs - sniff buffer interface to try to identify the MIME type when - everything else fails. - - * mail-display.c (on_object_requested): - * mail-format.c (lookup_handler, handle_undisplayable, - handle_audio): s/gnome_mime/gnome_vfs_mime/ - - * Makefile.am: Add gnomevfs stuff - -2000-07-03 Ettore Perazzoli <ettore@helixcode.com> - - * component-factory.c (create_folder): Get rid of a compiler - warning by making sure `folder' is always initialized to some - value for any code path. - -2000-07-03 Dan Winship <danw@helixcode.com> - - * message-list.c (select_msg): call mail_display_set_message with - NULL if the message we tried to select doesn't exist (probably - meaning we tried to selecte the first message and the folder is - empty.) - - * mail-display.c (mail_display_set_message): deal with NULL as an - input (meaning "undisplay previous message and display nothing"). - -2000-07-02 Dan Winship <danw@helixcode.com> - - * mail-ops.c (real_fetch_mail): Remove hack to redisplay the - inbox, since folder_changed signals will now be emitted - appropriately. - - * component-factory.c (create_vfolder_storage): Fix - filter_driver_new invocation. - - * Makefile.am (bin_PROGRAMS): test-mail and test-thread should be - noinst. - - * mail-ops.c (real_fetch_mail): - (vfolder_editor_clicked): - * component-factory.c (create_vfolder_storage): - Pass mail_uri_to_folder and rules to filter_driver_new. - -2000-07-02 Ettore Perazzoli <ettore@helixcode.com> - - * folder-browser.c (mail_uri_to_folder): Fix double freeing of the - local exception `ex'. - -2000-07-01 Ettore Perazzoli <ettore@helixcode.com> - - * mail-ops.c (refile_msg): Only allow type "mail" in the folder - selection dialog. - -2000-07-01 Dan Winship <danw@helixcode.com> - - * pixmaps.h, pixmaps/*.xpm: Removed. These aren't being used any - more. (The real pixmaps are in ../art.) - -2000-07-01 Jeffrey Stedfast <fejj@helixcode.com> - - * message-list.c (get_message_info): - (select_msg): Updated to reflect camel-folder changes. - - * mail-ops.c (real_fetch_mail): Modified to reflect camel-folder - changes. - -2000-06-30 Dan Winship <danw@helixcode.com> - - * mail-ops.c (print_msg): Use gnome-print to do a print preview. - - * folder-browser-factory.c: Hook up "Print" button. - - * message-list.c (message_list_foreach): New function, a wrapper - around e_table_selected_row_foreach, which calls the callback - function with UIDs rather than row numbers. - - * folder-browser-factory.c: Remove never-used "Find" button from - the toolbar and replace it with "Refile". (We need a better icon - for this...). Hook up "Refile" to "refile_msg". - - * mail-ops.c (refile_msg): Call the shell's user_select_folder - routine, and then use message_list_foreach and real_refile_msg to - do the work. - (delete_msg): Update to use message_list_foreach. - - * folder-browser.c (mail_uri_to_folder): new function, extracted - from folder_browser_load_folder, to turn a URI into a folder. - (folder_browser_load_folder): Use it. - -2000-06-30 Peter Williams <peterw@curious-george.helixcode.com> - - * component-factory.c (create_news_storage, create_imap_storage): - Fixed to use new EvolutionShellClient proxy thingamajiggie. - -2000-06-30 Dan Winship <danw@helixcode.com> - - * message-list.c (on_row_selection): use the ETable row_selection - signal to track how many rows are selected. Eventually we will use - this info to disable toolbar buttons when you have too few/too - many messages selected, but the current toolbar widget doesn't - allow that. - - * message-list.h, message-list.c, mail-ops.c: Change selected_row - and selected_uid fields of MessageList to cursor_row and - cursor_uid to be more correct according to the new ETable - interfaces. - -2000-06-30 Ettore Perazzoli <ettore@helixcode.com> - - * component-factory.c: Eeek. Fix typo: add missing star in the - declaration of `global_shell_client'. - -2000-06-29 Ettore Perazzoli <ettore@helixcode.com> - - * component-factory.c: Replace `global_shell_interface' with - `global_shell_client'. - -2000-06-29 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-ops.c (delete_msg): Clean up compile warnings - (real_fetch_mail): Fetching from IMAP should do nothing - -2000-06-29 Christopher James Lahey <clahey@helixcode.com> - - * mail-ops.c: Handle multiple deletes (change by Peter Williams.) - -2000-06-29 Jeffrey Stedfast <fejj@helixcode.com> - - * folder-browser-factory.c: Changed "Send" to "Compose" to - avoid user confusion. Compose is a little more intuitive. - Also changed the pixmap to MAIL_NEW instead of MAIL_SND - - * mail-ops.c (compose_msg): Renamed to avoid confusion - -2000-06-29 Dan Winship <danw@helixcode.com> - - * component-factory.c (create_imap_storage, create_news_storage): - remove some code incorrectly copied and pasted from - create_vfolder_storage which caused vfolder creation to stop - working. - -2000-06-29 Christopher James Lahey <clahey@helixcode.com> - - * message-list.c, mail-ops.c: Changed the name of - e_table_select_row to e_table_set_cursor_row. - -2000-06-29 Peter Williams <peterw@helixcode.com> - - * message-list.c (message_list_init): Set the dnd_code of the - ETableHeader to something so that Solaris sprintf doesn't die - on a NULL string. - - * mail-config.c (providers_config_new): Check for a null "transport" - string (not all OS' handle NULL strings well *cough* Solaris) - -2000-06-28 Dan Winship <danw@helixcode.com> - - * mail-format.c (mail_generate_forward): add default subjects - - * component-factory.c (create_folder): Refuse to create folders - not of type "mail", and correctly create an empty "mbox" folder - for new folders in /local. - - * main.c (init_corba): Call od_assert_using_oaf() or - od_assert_using_goad() as appropriate to make sure people didn't - somehow trick the build system. - -2000-06-28 Jeffrey Stedfast <fejj@helixcode.com> - - * message-list.c: Added prototype for filter_date to make - it build cleanly - -2000-06-27 Christopher James Lahey <clahey@helixcode.com> - - * message-list.c: Made dates display grouping information - properly. - -2000-06-27 Peter Williams <peterw@curious-george.helixcode.com> - - * message-list.c (mark_msg_seen): Need to return a value - on error. - - * main.c (main): Don't start threads or enter threads if - there's no threading! Sigh. - - * test-thread.c: Don't compile if no threads. - - * session.c: Work without broken threads. - - * message-list.c (filter_date): Solve the ctime_r problem the - correct way, with the magic of autoconf. - -2000-06-27 Christopher James Lahey <clahey@helixcode.com> - - * message-list.c: Work around mismatched ctime_r functions. This - will be fixed. - -2000-06-27 Peter Williams <peterw@curious-george.helixcode.com> - - * mail-threads.c: Don't compile this if we don't have - threads enabled. This should maybe be on the Makefile.am - level. - -2000-06-27 Michael Zucchi <zucchi@zedzone.mmc.com.au> - - * component-factory.c (owner_set_cb): Put in a gross hack to - export the shell reference elsewhere. - -2000-06-26 Christopher James Lahey <clahey@helixcode.com> - - * message-list.c: Added a value_to_string handler. - -2000-06-26 Peter Williams <peterw@helixcode.com> - - * component-factory.c, mail-ops.c: #ifdef the threads stuff so - that if USE_BROKEN_THREADS is not defined we just call the functions - in the main thread. - - * mail-threads.h: Don't declare funcs if USE_BROKEN_THREADS not - defined. - - * mail-threads.c: Put the query and message boxes on top so that - you can see them. - -2000-06-26 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-config.c (error_dialog): va_start() returns void, don't - assign it's retval to a variable. - -2000-06-26 Ettore Perazzoli <ettore@helixcode.com> - - * main.c (main): Call `GDK_THREADS_ENTER()' and - `GDK_THREADS_LEAVE()' around the main loop as in the examples from - the GTK+ FAQ. - - * mail-threads.c (DEBUG): New macro for debugging. - (read_msg): Use it. - -2000-06-25 Peter Williams <peterw@helixcode.com> - - * Makefile.am: Clean up the various _LIBS and _CFLAGS - to work with simpler THREADS_LIBS and THREADS_CFLAGS scheme. - -2000-06-23 Jeffrey Stedfast <fejj@helixcode.com> - - * folder-browser.c (folder_browser_load_folder): Improved the - code to separate the imap namespace from the folder name. - -2000-06-23 Peter Williams <peterw@curious-george.helixcode.com> - - * component-factory.c: Include e-util/e-setup.h for the - prototype of evolution_dir; prototype create_news_storage. - (real_create_imap_storage, real_create_news_storage): New - functions moving the camel stuff into the async callback. - (create_imap_storage, create_news_storage): Chopped in - half to move camel stuff as above. - - * mail-ops.c: Include "mail-threads.h" for threading protos. - (real_fetch_mail, real_send_mail, real_expunge_folder): - New functions moving the camel stuff into the async callback. - (async_mail_exception_dialog): A version of mail_exception_dialog - to be called from the async handlers (just calls mail_op_error()) - (fetch_mail, expunge_folder, composer_send_cb): Cut in half to - move camel stuff as above. - (cleanup_send_mail): Clean up after the async real_send_mail - with the gtk_object_destroys et al. - - * mail-threads.c: Instead of hiding the progress bar, make it - zip back and forth constantly. - (progress_timeout): New func. Timeout called to make the pbar - shimmy. - (timeout_toggle): New func. Turn on and off the shimmy effect. - (check_cond): New func. Make sure that the GCond for modal - operation is initialized before mail_op_{error,get_password}. - (show_error_clicked, read_msg, get_password_clicked): Move - over to timeout_toggle. - (mail_op_error,mail_op_get_password): Add check_cond() call. - - * main.c: (main) Call g_thread_init. - - * session.c: Change auth_callback stuff over to assume that it's - being called async. Note: no real good way to tell if this is - the case or not. - (request_callback): ifdef'ed out - (evolution_auth_callback): Use mail_op_get_password. - -2000-06-22 Jeffrey Stedfast <fejj@helixcode.com> - - * folder-browser.c (folder_browser_load_folder): Now should - correctly get the selected folder from the given URL. - -2000-06-22 Chris Toshok <toshok@helixcode.com> - - * folder-browser.c (folder_browser_load_folder): add handling for - loading "news:" folders. - - * component-factory.c (create_news_storage): add a root for news - source. - (owner_set_cb): call create_news_storage. - -2000-06-22 Jeffrey Stedfast <fejj@helixcode.com> - - * folder-browser.c (folder_browser_load_folder): Updated to - prepend url-> path if it exists for that imap store. - - * component-factory.c (create_imap_storage): Modified to not - prepend a hard-coded namespace. - -2000-06-22 Chris Toshok <toshok@helixcode.com> - - * mail-ops.c (fetch_mail_cleanup): new function, passed as arg to - mail_operation_try. - (fetch_mail): add cleanup func arg. - -2000-06-22 Christopher James Lahey <clahey@helixcode.com> - - * message-list.c: Changed ml_value_at to return "" instead of NULL - in some cases. - -2000-06-22 Peter Williams <peterw@curious-george.helixcode.com> - * Makefile.am: Add GNOME_EXTRA_LIBS so that we get libgthread - in our LIBS for evolution-mail. - - * mail-threads.c: Make the dialog boxes for error and - question non-modal. They're modal relative to the dispatch - thread, but before they would also eg lock up the toolbar - buttons (while the menus, managed by another process, were - active -- a weird effect). - -2000-06-22 Peter Williams <peterw@curious-george.helixcode.com> - - * mail-threads.[ch]: Extra argument to mail_operation_try: - 'cleanup', a function to be called in the main thread after - the dispatcher thread exits. gtk_object_destroy's et al may - attempt to unmap windows so we can't do them in the dispatcher - thread :-( - - * test-thread.c: Updated with demo of new argument working. - -2000-06-22 Peter Williams <peterw@helixcode.com> - - * test-thread.c (op_5): New tests for the get_password - hook. - - * mail-threads.[ch]: New hook, mail_op_get_password, for - getting a user response from an async operation. The operation - blocks while waiting for the response. A big whole mutex - condition threading blocking dealie to make sure that it - works. - - Also the error hook creates a dialog again, which also needs - to block its caller while we wait for the user to press ok. - -2000-06-22 Peter Williams <peterw@helixcode.com> - - * mail-threads.c (various functions): Prettify the UI - so that the progress bar doesn't become all huge 'n stuff. - (mail_operation_try): Now save the operation's description, - so that we can display it later as the default message. - (read_msg): When the operation starts set the label to its - UI-friendly name. - (dispatch_func): Free the saved prettyname. - -2000-06-21 Christopher James Lahey <clahey@helixcode.com> - - * message-list.c: Removed an erroneous comment. - -2000-06-21 Dan Winship <danw@helixcode.com> - - * mail-config.c (create_transport_page): Make this not crash if - you don't have a transport configured. - - * message-list.c: Update received date to work like sent date. - -2000-06-21 Peter Williams <peterw@helixcode.com> - - * mail-thread.{c,h}: New files -- a simple API for executing - the major mail ops (fetch_mail etc) asynchronously, allowing - the operations to send messages and update a progress bar. - - * test-thread.{c,h}: Tests the mail-thread API. - - * Makefile.am: add mail-thread.[ch] to evolution_mail_SOURCES - and declare the test_thread noinst_PROGRAM. - -2000-06-21 Peter Williams <peterw@helixcode.com> - - * mail-format.c (mail_generate_reply): Include "e-setup.h" to - get the prototype for evolution_dir. - -2000-06-20 Jeffrey Stedfast <fejj@helixcode.com> - - * component-factory.c (create_imap_storage): Oops. Should - have checked for a NULL sources. - -2000-06-20 Dan Winship <danw@helixcode.com> - - * message-list.c (mark_msg_seen): Quick hack to prevent a NULL - pointer dereference. Things need to be cleaned up a bit more here - though. - - * mail-sources.c: Oops. This should have been removed a long time - ago. - -2000-06-20 Jeffrey Stedfast <fejj@helixcode.com> - - * folder-browser.c (folder_browser_load_folder): Working on getting - this to work :) - - * component-factory.c (create_imap_storage): Should now correctly - construct the folder path allowing the selection of a folder. - -2000-06-20 Ettore Perazzoli <ettore@helixcode.com> - - * mail-format.c (mail_generate_reply): Declare `evolution_dir'. - Ugly, ugly, ugly, but I am not sure where it should go instead. - -2000-06-19 Ettore Perazzoli <ettore@helixcode.com> - - * mail-ops.c (ask_confirm_for_empty_subject): New function to ask - confirmation for an empty subject line. - (composer_send_cb): Use it if the subject is empty and only send - the message if the user confirms. - -2000-06-20 Jeffrey Stedfast <fejj@helixcode.com> - - * component-factory.c (create_imap_storage): Now creates the IMAP - storage (listing subfolders and such) - -2000-06-19 Dan Winship <danw@helixcode.com> - - * mail-format.c (find_preferred_alternative): add an option to - prefer text/plain. - (reply_body): add an option to prefer text/plain - (mail_generate_reply): Check the mail sending preferences, and - generate a text/plain reply if the user prefers to send plain text - (and we have a text/plain part to generate a reply from). - -2000-06-19 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-config.c (providers_config_new): Should now correctly display - the Transport page (made it set the optionmenu correctly, before it - would only set SMTP). - (create_transport_page): Updated to set the page info to sendmail/smtp - based on the url. - (create_service_page): Had to add some code to set data on some objects - so I could grab the objects I needed to modify in the above function. - -2000-06-18 Jeffrey Stedfast <fejj@helixcode.com> - - * folder-browser.c (folder_browser_load_folder): started to add - code to load an IMAP folder. - - * component-factory.c: Started to add a create_imap_storage - method so that we can eventually have our IMAP store displayed - in the tree view. - (create_vfolder_storage): Renamed from - create_test_storage(). - (owner_set_cb): Updated. - -2000-06-17 Dan Winship <danw@helixcode.com> - - * message-list.c (message_list_set_folder): Prevent double-freeing - action on summary_table and uid_rowmap. - -2000-06-16 Dan Winship <danw@helixcode.com> - - * message-list.c (ml_set_value_at): Implement clicking on the - envelope icon to set read/unread. Based on a patch by clahey. - (select_msg): keep the timeout id for the "seen" flagging in the - message_list structure, so ml_set_value_at can clear it so it - doesn't re-mark a message seen after you click it unseen. - -2000-06-16 Dan Winship <danw@helixcode.com> - - * message-list.c (get_message_row): new function to do a uid to - row mapping. - (mark_msg_seen, select_msg, message_changed, - message_list_set_folder): Update for Camel flag changes. - (on_cursor_change_cmd): Rename "row_to_select" to "selected_row", - and keep a "selected_uid" as well. - - * mail-ops.c (composer_send_cb): Update for Camel flag changes, - and fix some memory-handling bugs. (Free the post_send_data when - the composer is destroyed, not when the user clicks "send", which - could happen never, or more than once.) - (delete_msg): Update for Camel flag changes, and fix the "holding - down the delete key skips some messages" bug. - -2000-06-15 Dan Winship <danw@helixcode.com> - - * mail-ops.c (fetch_mail): - * component-factory.c (owner_unset_cb): - * message-list.c (message_list_set_folder): Update for CamelFolder - changes. - - * folder-browser.c (folder_browser_clear_search): New function to - revert back to non-searching mode. - - * mail-ops.c (fetch_mail): Use folder_browser_clear_search. - - * mail-display.c (on_url_requested): if the document requests an - unknown URL, it's not an error; just ignore the URL. - - * mail-ops.c (fetch_mail): If there's no new mail, tell the user. - -2000-06-14 Radek Doulik <rodo@helixcode.com> - - * main.c (main): call gtkhtmllib_init here - -2000-06-13 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-config.c (on_SourceConfigDialogButton_clicked): Make sure source - is always pointing to something, so a blank is not written to the config file - on close. - -2000-06-13 Ettore Perazzoli <ettore@helixcode.com> - - * Makefile.am (SHELL_OBJS): Removed. - (evolution_mail_LDADD): Use `libeshell.a'. Also use - `top_builddir' consistently. - -2000-06-12 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-config.c: Got rid of sources_max_row and identities_max_row - as they are not really needed (just use clist->rows) - (on_cmdSourcesEdit_clicked): Modified to make 'source' - point to the data being edited. - (on_cmdSourcesAdd_clicked): Adds a new clist item and selects it so the - editor knows where to stick the data when it's done. - -2000-06-12 Federico Mena Quintero <federico@helixcode.com> - - * message-list.c: Removed the ETableModel thaw handler. - -2000-06-12 Dan Winship <danw@helixcode.com> - - * folder-browser.c (folder_browser_set_uri): Return the result of - folder_browser_load_folder. - (get_prop, set_prop, folder_browser_properties_init): Remove. No - longer needed. - - * folder-browser-factory.c (folder_browser_factory_new_control): - Add a "uri" argument, return NULL if setting it fails. - (folder_browser_factory_new_control): Remove property bag stuff. - (folder_browser_factory_init, folder_browser_factory): Remove - this, since we're using the component factory now. - - * component-factory.c (create_view): Update for - folder_browser_factory_new_control change and return NOTFOUND as - appropriate. - - * main.c (main): Don't call folder_browser_factory_init. - - * mail-format.c (mail_generate_reply): Fix the subject generation - so we don't get "Re: Re:". This is working around something that - may later be declared a misfeature in Camel. - -2000-06-10 Ettore Perazzoli <ettore@helixcode.com> - - * component-factory.c (create_folder): New stub implementation for - the folder creation function in the EvolutionShellComponent we - expose [it simply returns success all the time]. - (factory_fn): Pass this function to `evolution_shell_component_new'. - -2000-06-09 Dan Winship <danw@helixcode.com> - - * folder-browser.c (folder_browser_new): Add a serial number to - FolderBrowser. - - * folder-browser-factory.c (control_activate, control_deactivate): - Include fb serial number in the name of the Bonobo toolbar to - prevent problems with disappearing toolbars. This is a kludge and - should go away. - - - * mail-ops.c (expunge_folder): display error from - camel_folder_expunge if there is one. - - * message-list.c (select_row): install an idle function to - select the row rather than doing it directly. Ugh. What a - kludge, but at least it works now. - - * session.c (evolution_auth_callback): Update for - CamelAuthCallback changes. (Uncache passwords when asked to.) - - * mail-ops.c (fetch_mail): close and expunge the source folder - after copying it to a local folder. - -2000-06-09 Ettore Perazzoli <ettore@helixcode.com> - - * component-factory.c (create_view): Updated to match the changes - to the definition of `EvolutionShellComponentCreateFn'. If @type - is not "mail", return an "unsupported type" error. - (factory_fn): Pass NULL for the `remove_folder' and - `create_folder' functions. - -2000-06-09 Dan Winship <danw@helixcode.com> - - * mail-format.c: Redo things a bit so that whitespace-only - text parts aren't displayed. (In particular, so that - whitespace-only subparts of multipart/mixed aren't displayed as - separate (empty) parts.) - -2000-06-06 Dan Winship <danw@helixcode.com> - - * mail-ops.c (fetch_mail): - * folder-browser.c (folder_browser_load_folder): Update for folder - creation/existence changes. - - * message-list.c (message_list_set_folder): Remove the code to - create the folder if it doesn't exist, since we don't want to do - that. - -2000-06-05 Dan Winship <danw@helixcode.com> - - * mail-ops.c (composer_send_cb): Leave the composer window around - if the message doesn't get sent. - -2000-06-05 Matt Loper <matt@helixcode.com> - - * folder-browser.c (etable_key): Allow "GDK_KP_Delete", a keypad - delete key, to delete a message. - -2000-06-05 Dan Winship <danw@helixcode.com> - - * session.c (evolution_auth_callback): Remember passwords between - calls. - (forget_passwords): Callback for "Forget Passwords" menu item. - - * folder-browser-factory.c (control_activate): - (control_deactivate): Add "Forget Passwords" menu item. - - * mail.h, mail-ops.c: fix some function prototypes - - * folder-browser.c (etable_key): Add "Delete" = delete message. - - * mail-format.c (mail_generate_forward): Update for new composer - attachment interface. - -2000-06-02 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-config.c (providers_config_new): Added a new notebook - page that allowed for mail format (text/plain or - multipart/alternative) - -2000-06-02 Dan Winship <danw@helixcode.com> - - * message-list.c (filter_date): If the date in the summary is 0, - output "?". - - * component-factory.c (create_view): keep a GList of folder - browsers created - (owner_unset_cb): Go through the list and close each folder before - exiting so they sync their summary state, etc to disk. - - * mail-ops.c (fetch_mail): Use camel_service_connect, not - connect_with_url, since we already passed the URL into - camel_session_get_store. - -2000-06-02 Christopher James Lahey <clahey@helixcode.com> - - * message-list.c: Use camel_folder_free_summary instead of - g_ptr_array_free. Unref the folder when we're done with it. - -2000-06-02 Christopher James Lahey <clahey@helixcode.com> - - * session.c: Revert removal of e_setup_base_dir. - -2000-06-02 Dan Winship <danw@helixcode.com> - - * folder-browser.c (my_folder_browser_init): Connect to ETable's - key_press signal. - (etable_key): scroll mail on space/backspace. - -2000-06-02 Christopher James Lahey <clahey@helixcode.com> - - * message-list.c: Made sent column as wide as from column. - -2000-06-02 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-config.c (on_cmdSourcesAdd_clicked): Changed identity_row - to source_row as this is a Sources clist we are dealing with and - not an identity clist - (on_cmdSourcesEdit_clicked): same - (on_cmdSourcesDelete_clicked): again, same - (on_cmdSourcesEdit_clicked): Source editor now fills in data from - the clist - -2000-06-01 Dan Winship <danw@helixcode.com> - - * message-list.c: Add a date column. - (COL_SENT_WIDTH_MIN): Make this wider. - (ml_value_at): return the sent date (as a time_t) for COL_SENT. - (Fix COL_TO too while I'm here.) - (ml_duplicate_value, ml_free_value, ml_initialize_value, - ml_value_is_empty): COL_SENT is numeric now. - (message_list_init_renderers): Create a date renderer (using - text_filter to translate the time_t into a string). - (message_list_init_header): Use render_date for COL_SENT. - -2000-06-01 Christopher James Lahey <clahey@helixcode.com> - - * session.c: Don't call e_setup_base_dir. - -2000-06-01 Dan Winship <danw@helixcode.com> - - * mail-format.c (mail_generate_forward): Fix forwarding to work - for people other than me. :) [Although apparently it doesn't - really.] - - * mail-ops.c (delete_msg): Add a quick hack to move the selection - down a row when you delete a message. - - * mail-format.c (handle_message_rfc822): use <blockquote> rather - than <center><table border=1 width=95%> to frame the embedded - message. If <pre> text in the subtable won't fit in the 95% width, - GtkHTML will write past the border of the table (and - <blockquote><table border=1> causes creeping updates so it's not - usable for now). - -2000-06-01 Christopher James Lahey <clahey@helixcode.com> - - * message-list.c (message_list_init): Turn off the grid in our - ETable. - -2000-06-01 Dan Winship <danw@helixcode.com> - - * mail-format.c (write_headers): Oops. This needs to take a - message argument because we might be writing headers for an - embedded message/rfc822 subpart rather than the root document. - -2000-06-01 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-config.c: Config dialogs are completed. - (service_acceptable): Fixed a segfault caused by duplicate - camel_exception_free() - (providers_config_new): Identity and Source clists are now filled in - when the dialog is created as well as the Transport page - - * folder-browser-factory.c: Renamed Tool/ menu items - Vfolder was changed to Virtual Folder and - Configure Camel Providers was changed to Mail Configuration - -2000-06-01 Ettore Perazzoli <ettore@helixcode.com> - - * Makefile.am (evolution_mail_LDADD): Link with - `libemiscwidgets.a'. - - * mail-display.c (mail_display_new): Use an EScrollFrame instead - of a GtkScrolledWindow. - (mail_display_set_message): Likewise. - - * mail-display.h: Replace the GtkScrolledWindow with an - EScrollFrame. - -2000-06-01 Dan Winship <danw@helixcode.com> - - * component-factory.c (owner_unset_cb): Quit when the shell exits. - This is a kludge, but a pretty necessary one until the refcounting - bugs that keep the component from exiting properly are fixed. - -2000-05-31 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-config.c: Partially implemented the source - configuration, seems to segfault due to a destroyed - gnome dialog being destroyed again in the method - on_SourceConfigDialogButton_clicked() - -2000-05-31 Dan Winship <danw@helixcode.com> - - * mail-format.c (free_url, handle_text_enriched, - get_url_for_icon): Fix up memory management of x-evolution-data - URLs so the URLs and/or their data don't get freed while there are - still references to them. - - * message-list.c (message_list_init_header): redo the (unused) - online status column to no longer refer to pixmaps that no longer - exist. - -2000-06-01 Ettore Perazzoli <ettore@helixcode.com> - - * folder-browser-factory.c (control_activate): Put the toolbar - into a frame to make it look like standard GNOME toolbars. Also, - set `GNOME_DOCK_ITEM_BEH_NEVER_VERTICAL' so that it does not do - evil things when its moved to the left or the right of the window. - -2000-05-31 Jeffrey Stedfast <fejj@helixcode.com> - - * mail-config.c: Configuration dialog now allows - adding/editing/deleting of Identities (which leaves - adding/editing/deleting of sources left to implement). - The data is also saved when the dialog is exited via - the OK button. - -2000-05-31 Dan Winship <danw@helixcode.com> - - * mail-format.c (mail_format_mime_message): Initialize the "urls" - hash table stored on the message and store cid and other URLs - there rather than as object data on the message. - (get_cid): rewrite this a bunch - (handle_text_enriched): move the code from write_iframe_string() - into here, since it's the only place that actually needs it. - (handle_text_html): simplify this a lot. We can use a cid: URL - here rather than x-evolution-data. - (get_url_for_icon): New routine to return URLs for icons, and - cache the results, so we don't have to keep re-reading the icon - files (and so we can't be spoofed into reading non-icon files). - (handle_mystery, handle_audio): use get_url_for_icon. - - * mail-display.c (save_data): move the CamelMimePart filename - extracting code from get_cid to here. - (on_link_clicked, on_object_requested): Update for cid: changes. - (on_url_requested): Kill off the kludgy, exploitable x-gnome-icon - URL schema, update cid and x-evolution-data to match - mail-format.c. - - It should now be easier to implement RFC 2557 (Content-Location, - etc), but that RFC still pretty much sucks. - -2000-05-30 Dan Winship <danw@helixcode.com> - - * mail-format.c: Redo this back to the old way: a single GtkHTML - with various things inline in it. (Gets rid of flicker, simplifies - some scrolling, selecting, and printing issues.) - (handle_text_enriched, handle_text_html): Use <iframe>s for these, - to protect the rest of the document from their possibily invalid - HTML. - (handle_via_bonobo): Use (new-and-improved) <object> tags for - this, moving most of the work back into mail-display.c - - * mail-display.c (on_object_requested): Move the Bonobo embedding - code back here again (reorganized a bit). - (on_url_requested): add x-evolution-data handler, for iframe - bodies. - (mail_html_new, mail_html_end): removed - (mail_display_set_message, mail_display_new): Update for NWO. - -2000-05-30 Not Zed <NotZed@HelixCode.com> - - * folder-browser.c (search_set): Properly encode the search string. - -2000-05-30 Jeffrey Stedfast <fejj@helixcode.com> - - * mail.h: Added a prototype for providers_config_new() which - is the constructor for the configuration dialog window - - * mail-config.c: Added set_service_url() which is basically - the reverse of get_service_url(). - Implemented on_cmdCamelServicesOK_clicked() - The configuration - window will now remember the Sendmail/SMTP data that the user - had entered in the previous session. - Removed on_cmdCamelServicesApply_clicked() - No need for this. - -2000-05-30 Dan Winship <danw@helixcode.com> - - * message-list.c (message_changed): call - e_table_model_row_changed, not e_table_model_changed so we do less - work, and don't lose the current selection. - (select_msg): Set up a timer to mark the displayed message as - "seen" if it's selected for longer than 1.5 seconds (a number - pulled out of Matt's butt). - (ml_value_at): Use the MESSAGE_STATUS column for read/unread as - well as deleted. - - * message-list.c: use the "new" tigert pixmaps rather than the - older ones. Includes a "replied to" icon (which is used now), but - no "deleted" icon (although we have the strikeout renderer for - that now). - -2000-05-30 Christopher James Lahey <clahey@helixcode.com> - - * message-list.c, message-list.h: Added bold for unread messages. - -2000-05-30 Jeffrey Stedfast <fejj@helixcode.com> - - * mail.h: Added a prototype for providers_config() - which is the callback for a new menu item that - will construct a configuration dialog for the camel - providers and identities and display it - - * mail-config.c: Added some code to construct the - new providers dialog and a bunch of callbacks (most - of which are not yet useful) - - * mail-ops.c: Added the code for the providers_confi() - callback - - * folder-browser-factory.c: Added the - "Tools/Camel Providers Configuration ..." menu item - -2000-05-30 Christopher James Lahey <clahey@helixcode.com> - - * message-list.c: Switched to using "cursor_change" signal instead - of "row_selection" for switching messages. Select the first row - (still doesn't work because of ETable.) Adapt to some small - ETable changes. Set drawfocus to FALSE. - -2000-05-29 Not Zed <NotZed@HelixCode.com> - - * folder-browser.c (folder_browser_load_folder): Hardcode the - vfolder source to just the inbox (so at least it returns - something). - - * component-factory.c (create_test_storage): Create a vfolder dir - first, and put the folders in that. - (create_test_storage): Create the storage as VFolders, not - "storage_name" :) - -2000-05-28 Dan Winship <danw@helixcode.com> - - * mail-config.c (error_dialog): helper function since we need to - set "modal" on the dialogs returned by gnome_error_dialog to make - them work when popped up from the modal Druid. - (service_acceptable): New function to check if the info entered on - a store/transport page actually checks out. - (mail_config_druid): Connect to the "next" signal on the store and - transport pages and don't let the user continue if the data is - bad and "check this before continuing" is checked. Also, only - display sources/transports in the "mail" domain. (Ie, not - "vfolder".) - - * mail-format.c (write_recipients_to_stream): Use `foo@bar' rather - than `<foo@bar>' for recipient with no name. - - * mail-ops.c (fetch_mail): don't put up an error message if the - user cancels the password dialog. - -2000-05-27 Not Zed <NotZed@HelixCode.com> - - * Makefile.am (SHELL_OBJS): Include mail storage so we can - initialise folders. - - * component-factory.c (create_test_storage): Parses vfolder - defintions and adds them to the storage. Definetly needs more - work. - - * folder-browser-factory.c (control_activate): Add the VFolder - druid menu item. - (control_deactivate): And remove it. - - * mail-ops.c (vfolder_editor_clicked): For editing vfolder - definitions (rather like filters, oddly enough :). Tries to - update the shell but it doesn't seem to work properly - requires a - mail component restart to take effect. - - * folder-browser.c (folder_browser_load_folder): Handle vfolder: - urls' appropriately and map to camel. Still needs a way to tell - the vfolder what folders to search! (all vfolders come up empty!). - -2000-05-28 Christopher James Lahey <clahey@helixcode.com> - - * message-list.c, message-list.h: Added a COL_DELETED and made it - the strikeout column for both text renderers. - -2000-05-27 Dan Winship <danw@helixcode.com> - - * mail-format.c: Various improvements: - - (call_handler_function, etc): Add a "mime_type" argument to the - handlers, so that if a part is tagged as - "application/octet-stream", and we figure out that it's really - something else, the handler we call can know what that something - else is. - - (handle_text_enriched): Small fixes to make this not do - text/enriched-specific syntax in text/richtext or vice versa. - - (handle_mystery): Allow for mystery data that can't even be saved - to disk. (ie, unrecognized external-body). Let the caller specify - the URL to use. - - (handle_message_external_body): New function to deal with - message/external-body parts. Generates URLs for anon-ftp, - local-file, and URL access-types, and a more-useful-than-before - descriptive message for other types. - - (handle_audio, handle_undisplayable): Use gnome_mime_get_value to - try to get a description of the MIME type to display to the user - rather than the raw form. (This will only work if the user has - recent gnome-vfs installed. [If they don't, it works just like - it used to.]) - -2000-05-26 Dan Winship <danw@helixcode.com> - - * mail-format.c (handle_text_html): Fix a bug (security/stability) - in its usage of mail_html_write. - - * mail-ops.c (composer_send_cb, reply): set CAMEL_MESSAGE_ANSWERED - on a message after a successful reply. - - * message-list.c (folder_changed): free the summary with - camel_folder_free_summary rather than g_ptr_array_free. - - * mail-format.c (handle_via_bonobo): Update for PersistStream - changes - -2000-05-25 Ettore Perazzoli <ettore@helixcode.com> - - * main.c (main): Initialize the component factory. - - * Makefile.am (evolution_mail_LDADD): Link with - `evolution-shell-component.o' from the shell directory. - - * evolution-mail.oafinfo: Updated with the - Evolution::ShellComponent OAFIID. - - * evolution-mail.gnorba: Updated with the - Evolution::ShellComponent GOAD ID. - - * folder-browser-factory.c (folder_browser_factory_new_control): - New function; code moved out from `folder_browser_factory'. - (folder_browser_factory): Use it. - - * component-factory.c: New. - * component-factory.h: New. - -2000-05-24 Dan Winship <danw@helixcode.com> - - * mail-ops.c (composer_send_cb): connect to and disconnect from - the transport. - -2000-05-24 Christopher James Lahey <clahey@helixcode.com> - - * Makefile.am: Added libepaned.a. - - * folder-browser.c: Switched from GtkPaned to EPaned. - -2000-05-23 Ettore Perazzoli <ettore@helixcode.com> - - * Makefile.am: Don't link to `evolution-service-repository.o' - anymore. - - * folder-browser-factory.c: Don't use crufty service-repository - anymore. - -2000-05-21 Ettore Perazzoli <ettore@helixcode.com> - - * message-list.c (get_message_info): Made static. - (ml_initialize_value): Return NULL to placate compiler. - - * folder-browser.c (folder_browser_gui_init): Add cast. - - * mail-display.c (mail_html_new): Don't pass an empty URL to - `gtk_html_begin()' anymore. - - * mail-config.c (put_html): Don't pass an empty URL to - `gtk_html_begin()' anymore. - - * mail-display.h: Updated for the new GtkHTML API that uses - `GtkHTMLStream *' instead of `GtkHTMLStreamHandle'. - * mail-display.c: Likewise. - * mail-config.c: Likewise. - * mail-format.c: Likewise. - -2000-05-19 NotZed <NotZed@HelixCode.com> - - * mail-format.c: Fixes for stream stuff. - - * mail-display.c (save_data_cb): Remove exception stuff on streams. - -2000-05-19 Christopher James Lahey <clahey@helixcode.com> - - * message-list.c: Added initialize_value and value_is_empty - callbacks. - -2000-05-18 Dan Winship <danw@helixcode.com> - - * folder-browser-factory.c (folder_browser_factory): Remove - development_warning (moved to shell) - - * message-list.c (select_msg): Update for camel_folder_get_uids - (folder_changed, message_list_set_folder): Update for - camel_folder_get_summary - - * mail-ops.c (fetch_mail): Update for camel_folder_get_uids - -2000-05-17 Dan Winship <danw@helixcode.com> - - * mail-component.c: This seems to be cruft. Nuke it. - - * mail-display.c (save_data_cb, save_data, on_url_requested): - * mail-format.c (handle_text_plain_flowed, handle_text_html): - Use camel_data_wrapper_write_to_stream rather than - camel_data_wrapper_get_output_stream. - -2000-05-16 NotZed <NotZed@HelixCode.com> - - * mail-ops.c (filter_edit): Function to bring up the filter editor. - (filter_druid_clicked): Save/close dialogue. - (fetch_mail): Apply filters to incoming mail ... *hold breath* - If we are coming from a non-indexed/searchable/etc source, then - copy it to an mbox first. When copying mail from an mbox source, - dont remove it aftewards, open it for append, so partially - filtered mail isn't lost. - - * Makefile.am (evolution_mail_LDADD): Added libfilter. - (INCLUDES): Add EVOLUTION_DATADIR, and fix matt's brokeneditor(tm) - for putting spaces instead of tabs in. - -2000-05-16 Christopher James Lahey <clahey@helixcode.com> - - * mail-format.c: Removed usage of bonobo_object_destroy. - -2000-05-14 Christopher James Lahey <clahey@helixcode.com> - - * message-list.c: Updated to work with new ETable resizing. - -2000-05-12 NotZed <NotZed@HelixCode.com> - - * mail-ops.c (fetch_mail): Use 6 X's to mkstemp, as required by - the man page, just a temp fix, this should probably change to a - known filename. - -2000-05-11 Dan Winship <danw@helixcode.com> - - * folder-browser-factory.c (control_activate): Now that we depend - on current gnome-libs we can make the toolbar detachable again. - -2000-05-11 Federico Mena Quintero <federico@helixcode.com> - - * folder-browser-factory.c (development_warning): Left-justify the - message. - -2000-05-10 Christopher James Lahey <clahey@helixcode.com> - - * folder-browser-factory.c (development_warning): Made this dialog - have fewer buttons. - -2000-05-10 Christopher James Lahey <clahey@helixcode.com> - - * folder-browser-factory.c (development_warning): New development - warning text from Nat. - -2000-05-10 Larry Ewing <lewing@helixcode.com> - - * mail-config.c (html_new): only set the default background color - if style is not NULL. - -2000-05-09 Christopher James Lahey <clahey@helixcode.com> - - * Makefile.am: Removed folder-browser-factory.h since it doesn't - exist. Added mail-display.h, mail-types.h, pixmaps.h. - -2000-05-09 Matt Loper <matt@helixcode.com> - - * folder-browser-factory.c (control_activate): Remove "File->mail" - menuitem. - - * mail-config.c (mail_config_druid): Fill in "blah blah blah". - -2000-05-09 Dan Winship <danw@helixcode.com> - - * folder-browser.c (folder_browser_load_folder): make this a - little less kludgy. Use gnome_error_dialog rather than printf on - errors. - - * mail-ops.c (fetch_mail): Fix to work with the new shell stuff... - sorta. Will need more fixing later when the new shell framework is - more done. - - * mail-config.c (finish): Call gnome_config_sync so the data - actually gets written. - -2000-05-08 Dan Winship <danw@helixcode.com> - - * mail-display.c (save_data_cb): - (on_url_requested): Update for CamelStream CamelException changes. - - * mail-format.c: Pass NULL for a CamelException in a bunch of - places... the user will see that the data is not being displayed, - and there's not a lot we can do, and none of these things should - be failing anyway. Maybe fix this later. - -2000-05-07 NotZed <NotZed@HelixCode.com> - - * message-list.c (ml_value_at): Size moved to message info, rather - than content info structure. - -2000-05-07 Dan Winship <danw@helixcode.com> - - * message-list.c (select_msg): unref the message after displaying - it. - - * mail-format.c (get_data_wrapper_text): - (handle_text_plain_flowed): - (handle_via_bonobo): Replace camel_stream_close calls. - -2000-05-07 Matt Loper <matt@helixcode.com> - - * folder-browser-factory.c: Changed a toolbar button from saying - "New mail" (which suggests you might be composing new mail) to - "Get mail". - -2000-05-06 Dan Winship <danw@helixcode.com> - - * folder-browser-factory.c (folder_browser_factory): Don't - hardcode "inbox" here. - - * folder-browser.c (folder_browser_set_uri): Don't hardcode - "inbox" here either. - (folder_browser_load_folder): Create a new store according to the - folder browser's URI, and load the mbox file from that store. - Parts of this are temporary. - - * session.c, mail.h: There is no longer a global store, just a - global session. - - * mail-config.c, mail-ops.c: Update for default_session -> session - change. fetch_mail is currently broken. - -2000-05-06 Dan Winship <danw@helixcode.com> - - * mail-config.c: New code to configure identity, mail source, and - mail transport. - (mail_config_druid): A druid using the config widgets. (Only - allows configuration of a single identity, source, and transport.) - - * mail-ops.c (check_configured): New function to make sure the - user has configured stuff, and call the druid if not. - (fetch_mail, send_msg, send_to_url, reply, forward_msg): Call - check_configured - (composer_send_cb): Make this pass the message to a CamelTransport - rather than just printing it to stdout. - - * folder-browser-factory.c (development_warning): Add a warning - about sending mail, since you can do that now. - -2000-05-06 Chris Toshok <toshok@HelixCode.com> - - * .cvsignore: ignore evolution-mail.pure - - * Makefile.am: add support for building evolution-mail.pure - -2000-05-06 Dan Winship <danw@helixcode.com> - - * mail.h: consolidate mail-format.h, mail-identify.h, mail-ops.h, - main.h and session.h into this new file. There's no reason to have - a .h for every .c. - -2000-05-05 Anders Carlsson <andersca@gnu.org> - - * test-mail.c (create_container): Use the OAFIID when using an - OAF-enabled build of bonobo. - -2000-05-04 NotZed <NotZed@HelixCode.com> - - * message-list.c (message_list_set_folder): Get the whole message - summary right away. - (folder_changed): And if we change too. - (ml_row_count): Use the match count or summary table length as the - row count. - (get_message_info): Use array references to lookup message summary - info. For the search result list, use the summary_search_cache to - cache the info lookup. - (message_list_init): Allocate the summary search cache. - (message_list_destroy): Free the summary search cache and the - summary table, if there is one to free. - (message_list_set_search): Save the match count, and clear the - summary search cache for reuse. - (folder_changed): Re-retrieve the summary list if the folder has - changed. - (message_list_set_folder): Retrieve the summary list when opening - the folder. - -2000-05-03 Jason Leach <leach@wam.umd.edu> - - * Makefile.am (evolution_mail_LDADD): s/-lunicode/$(UNICODE_LIBS)/ - in the LDADD section. - -2000-05-03 Dan Winship <danw@helixcode.com> - - * mail-format.c (write_recipients_to_stream, write_headers): Make - the "Cc:" field optional again. (Before, we could check if - camel_mime_message_get_recipients returned NULL, but now we need - to actually look into the returned CamelInternetAddress object.) - -2000-05-03 Larry Ewing <lewing@helixcode.com> - - * folder-browser.c (folder_browser_gui_init): comment out the - changed signal for now. - -2000-05-02 Matt Loper <matt@helixcode.com> - - * Makefile.am: set G_LOG_DOMAIN. - -2000-05-02 Larry Ewing <lewing@helixcode.com> - - * message-list.c (message_list_set_search): only free search if it - is not NULL. - -2000-05-02 NotZed <NotZed@HelixCode.com> - - * folder-browser.c (folder_browser_gui_init): Connect the changed - signal to search, so it searched immediately? - -2000-05-01 NotZed <NotZed@HelixCode.com> - - * pixmaps.h: Added envelope-deleted state. - - * folder-browser-factory.c: Setup callback for actual delete op. - (control_activate): Setup a tool menu item to expnge deleted - messages. - - * mail-ops.c (delete_msg): Toggle the delete flag on a message. - (expunge_folder): New function to expunge deleted messages from - the current folder. - - * folder-browser.c (folder_browser_gui_init): A hackish little - quick-search entry. - (search_activate): Perform a quick-search on the folder subject - only. - (folder_browser_gui_init): Add an option meny to the search line. - (create_option_menu): Build the option menu from a table. - (search_set): Build a search from another string whent he option - menu or text item is changed. 5 search options are defined so - far. - - * message-list.c (get_message_info): If there is an active search, - then get the data from that ... use this instead of - _get_message_info(). - (ml_row_count): If we have an active search, get the info from its - result. - (select_msg): Changed to use get_message_info, so searches work. - (ml_value_at): And same here. - (message_list_init_renderers): Added a 3rd state to message_status - = deleted. - (ml_value_at): Show the message state as deleted, if it is marked - for deletion. - (folder_changed): When the folder changes, update the display. - (message_list_set_folder): Connect to the folder_changed event - here. - (message_changed): Callback to update the display when the message - changes. - (select_msg): And connect to the message_changed signal so we know - when it cahgnes. - (message_list_set_search): Save the search string. - (folder_changed): If the folder changes, re-run the search, - otherwise we may end up with invalid entries in the display. - - * mail-display.c: Include missing errno.h. - -2000-04-30 Dan Winship <danw@helixcode.com> - - * session.c (session_providers_init): This is no longer necessary. - - * mail-ops.c (fetch_mail): Remove kludge to load remote provider, - as camel can do it by itself now. - -2000-04-29 Dan Winship <danw@helixcode.com> - - * mail-display.c (on_link_clicked): Handle clicks on "cid" URLs by - popping up a "Save Attachment" dialog. - - * mail-format.c (get_cid): if the part has a Content-Disposition - with a filename specified, record (a sanitized version of) that on - the wrapper when creating the cid reference, so the "save - attachment" code can use it later. - (handle_mystery): fix a bug in the cid generation here. - -2000-04-29 Dan Winship <danw@helixcode.com> - - * mail-format.c (lookup_handler, etc): Improve the builtin vs - bonobo selection code. - (handle_mystery): Include name and Content-Description in the - "mystery data" info, when available - (handle_unknown_type): Call mail_identify_mime_part before - giving up. - (handle_undisplayable): Split out of handle_unknown_type now - that handle_unknown_type can try alternate viewers. - (handle_via_bonobo): Fall back to handle_undisplayable if the - bonobo control fails. - - * mail-identify.c (mail_identify_mime_part): New function to - attempt to identify a MIME part that we can't identify based on - Content-Type alone. - - * mail-display.c (on_url_requested): redo the mystery data icon - display stuff less kludgily. - -2000-04-28 Dan Winship <danw@helixcode.com> - - * mail-format.c (write_recipients_to_stream, write_headers, - mail_generate_reply): Update (minimally) for Camel recipient - changes. - -2000-04-28 Ettore Perazzoli <ettore@helixcode.com> - - * main.c (init_bonobo): Don't call `init_corba()' and don't get - any args. - (init_corba) [!USING_OAF]: Fix args. - -2000-04-27 Ettore Perazzoli <ettore@helixcode.com> - - * folder-browser-factory.c: New macro `CONTROL_FACTORY_ID', which - is #defined to a different value according to whether we are - `USING_OAF' or not. - (folder_browser_factory_init): Use `CONTROL_FACTORY_ID'. - - * test-mail.c - (init_corba): New helper function, implemented differently - according to `USING_OAF'. - (main): Use `init_corba()'. - - * main.c - (init_corba): New helper function, implemented differently - according to `USING_OAF'. - (init_bonobo): Use `init_corba()'. - - * Makefile.am: Install OAF stuff if `USING_OAF'. Add - `-I$(datadir)/idl' to the `orbit-idl' command-line so that we can - use Bonobo IDL files installed under our prefix as well. Also, - use `$(ORBIT_IDL)' instead of hardcoded `orbit-idl'. - - * evolution-mail.oafinfo: New file. - -2000-04-27 Dan Winship <danw@helixcode.com> - - * mail-format.c: Move text_to_html to e-util. - - * mail-ops.c (send_to_url): New routine. Thin wrapper for - e_msg_composer_new_from_url. - - * mail-display.c (on_link_clicked): print a warning for news or - nntp URLs (which we'll deal with some day), and call send_to_url - for mailto URLs. - - * mail-format.c (text_to_html): Improve URL conversion code. - Recognize https, recognize "www\..*" without a prefixed "http://". - Properly escape &, <, >, etc in URL strings. Don't be fooled by - "mailto:", "http://", etc with no following data. - -2000-04-26 Dan Winship <danw@helixcode.com> - - * mail-format.c (text_to_html): Reorganize a bit and add a new - flag, TEXT_TO_HTML_CONVERT_URLS to recognize and wrap URLs - in text. - - * mail-display.c (mail_html_new): Add link_clicked signal handler. - (on_link_clicked): Use gnome_url_show to launch a browser. - - * mail-format.c: update for CamelStream changes. Update for - CamelMimeBodyPart -> CamelMimePart - -2000-04-25 Dan Winship <danw@helixcode.com> - - * mail-display.c, mail-format.c: Redo large chunks of this. The - mail display now consists of a vbox in a scrolled window, in which - we put multiple GtkHTML objects. This means broken HTML in one - part can't corrupt other parts. The headers now scroll with the - body. Unrecognized attachments look prettier, but still don't do - anything, and will probably be changed later. We can also now - display nested message/rfc822 parts and multipart/alternatives - with multipart subparts. Oh, and text/{richtext,enriched}, since - we had all these ancient sample messages that use it and the lack - of support annoyed me. :) - - Bonobo embeddables are broken right now, but I don't think that's - my fault. - - * mail-format.c (reply_body): Fix some bugs that crept into reply - generation. This needs a lot more work to deal correctly with - complicated bodies. - (setup_function_table): pass unknown text subtypes to - handle_text_plain. - (handle_multipart_appledouble): new handler. Just ignores the - first (application/applefile) part and tries to display the - second part. Since the second part is usually - application/octet-stream, this doesn't work very well still - usually. - (reply_body): Make this deal better with multiparts. - - * mail-format.c, mail-display.c: Now that we're not limited to - a single GtkHTML for the display, there's no reason to embed - Bonobo objects for unrecognized content-types in GtkHTML rather - than embedded them into the vbox directly. So do that. - - Meanwhile, fix up the handler-selection code so that we can - declare which built-in handlers are more desirable than external - handlers and which are less. (Of course, eventually we'll want - this to be customizable.) Add some cleverness to - handle_multipart_alternative as well so it doesn't accept an - alternative which we can display generically over one we can - display specifically. - - * mail-format.c (text_to_html): add a convert_space_hack flag, - which turns N spaces into N-1 s and a space. - (handle_text_plain): Check for "format=flowed" in the - Content-Type. - (handle_text_plain_flowed): Spinoff of handle_text_plain to deal - with RFC 2646 flowed text. (All the examples I can find of it - are generated by Eudora, but it's a pretty cool idea that ought - to be used more widely.) - -2000-04-23 Dan Winship <danw@helixcode.com> - - * folder-browser-factory.c: rename "send" to "send_msg", to avoid - name clash with the tcp function. Connect the "forward" button. - - * mail-ops.c: rename "send" to "send_msg", to avoid name clash - with the tcp function. Add forward_msg function. - - * mail-format.c (mail_generate_forward): support function for - forward_msg. Pretty much a big kludge right now, pending the - attachment/attachment-bar changes. - -2000-04-22 Dan Winship <danw@helixcode.com> - - * mail-display.c (on_url_requested): Change cid expectations to - match current camel reality. - - * main.c (main): call glade_gnome_init, for composer. - - * folder-browser-factory.c: move msg_composer_cb and - msg_composer_send_cb to mail-ops. Attach send, reply, and "reply - to all" buttons. - - * mail-ops.c (composer_send_cb, send): moved from - folder-browser-factory.c. - (reply_to_sender, reply_to_all): new functions to do replies. - - * mail-format.c (text_to_html): Add an "add_pre" flag, to make - it wrap the output in <pre></pre>. - (mail_generate_reply): New function to create a composer and build - a reply in it. - -2000-04-21 Dan Winship <danw@helixcode.com> - - * mail-display.c (on_url_requested): deal with cid: URLs. - (find_cid): helper routine for above. (This could be much better.) - (mail_display_init): connect url_requested signal - - * mail-format.c (handle_multipart_related): Make this work. - - * mail-display.c (mail_display_set_message): ref the message we - display, since we're going to unref it when we remove it. Fixes a - bug that showed up with the new camel code, but it's not obvious - if it's due to a bug or a feature in the new code. - -2000-04-20 NotZed <NotZed@HelixCode.com> - - * Makefile.am (evolution_mail_LDADD): Add libibex.la to link. - - * message-list.h: Removed folder summary. - - * message-list.c: Dont include folder-summary anymore. - (select_msg): Changed to use folder, not summary in - summary_get_message_info(). God this code is grotty. - (ml_value_at): Ditto. - (ml_value_at): Changed to use new interface. Hmm, this returns a - static variable, that seems wrong. - (message_list_set_folder): Remove folder summary. - (ml_row_count): Oops, remove some debug i put there. - -2000-04-20 Dan Winship <danw@helixcode.com> - - * mail-display.c: update for bonobo change, and remove a - now-unused variable. - -2000-04-17 Chris Toshok <toshok@helixcode.com> - - * message-list.c (on_row_selection_idle): new function, actually - calls select_msg. - (on_row_selection_cmd): register an idle instead of calling - select_msg directly. this fixes the lag before the row is - selected - selection is instantaneous now, with message loading - happening afterward. - - * message-list.h: add row_to_select and an idle_id to the message - list to make the select_msg call happen in an idle func. - - * message-list.c (message_list_init_renderers): no more - e_cell_set_editable. this info always comes from the model. - -2000-04-14 Dan Winship <danw@helixcode.com> - - * mail-format.[ch]: Moved from camel/camel-formatter, and changed - slightly. (More to come.) - - * html-stream.[ch]: No longer necessary. mail-format uses - GtkHTMLStreamHandles directly. - - * mail-display.[ch]: update for new message formatting code. - -2000-04-14 Chris Toshok <toshok@helixcode.com> - - * folder-browser-factory.c (control_activate): use - gnome_app_fill_toolbar_with_data, so we get the beautiful gnome - toolbar. - -2000-04-14 Dan Winship <danw@helixcode.com> - - * folder-browser-factory.c (development_warning): Fix up the - warning message a bit. - (folder_browser_factory): Make the warning bypassable. - -2000-04-12 Miguel de Icaza <miguel@gnu.org> - - * main.c (main): Call e_cursors_init. - -2000-04-10 Dan Winship <danw@helixcode.com> - - * mail-ops.c (fetch_mail): use camel_movemail when fetching mail - from an mbox store. This leaves behind temp files for now, - because CamelMboxFolder::delete is too confused to use, and NotZed - is rewriting CamelMboxFolder, so I'm not going to bother to try to - fix it. - - * mail-ops.c: Add some #includes for the non-HAVE_MKSTEMP case - -2000-04-09 Matt Loper <matt@helixcode.com> - - * folder-browser.c (folder_browser_new): set folder_browser->uri - to NULL, so that we know when to free it. - -2000-04-07 Miguel de Icaza <miguel@gnu.org> - - * message-list.c (states_pixmaps): Add more beautiful art from - Miggue, the Diego Rivera of the next millenium. - (message_list_init_header): Use the beautiful art. - - * pixmaps: Miguel rediscovers the "transparent" concept. - -2000-04-07 Matt Loper <matt@helixcode.com> - - * folder-browser.c (folder_browser_destroy): Unref the shell - interface that we have a handle to. - - * folder-browser-factory.c (control_destroy_cb): New function; - destroys a folder-browser when its control is destroyed. - (folder_browser_factory): Hook up to the above. - -2000-04-07 Dan Winship <danw@helixcode.com> - - * mail-ops.c: new file, for toolbar/menu callbacks - (fetch_mail): fetch mail. Doesn't do mbox locking. Many kludges. - - * folder-browser-factory.c (control_activate): use new fetch_mail - function as the callback for the "New mail" icon. Rename check_cb - to random_cb. - - * Makefile.am: don't build test-sources since the version in - CVS doesn't do much and once I've fixed it it won't be a separate - program. Add mail-ops.[ch]. - -2000-04-06 Miguel de Icaza <miguel@gnu.org> - - * message-list.c: Stick pixmaps here. - - * mail-display.c (embeddable_destroy_cb): Replaced C++ comments - with C comments. - - * message-list.c (load_internal_images): New function, loads images. - (message_list_init_renderers): Load images, fix previous attempt - at loading images. - - * Makefile.am (dist-hook): Added distribution of pixmaps. - - * pixmaps: New directory, used to hold the XPMs we ship with. - - * pixmaps/envelope-closed.xpm, pixmaps/envelope-open.xpm: Tigert's - envelopes incorporated. - -2000-03-31 Miguel de Icaza <miguel@gnu.org> - - * message-list.c (ml_value_at): Fix miss-used variable. - -2000-04-01 Michael Meeks <michael@helixcode.com> - - * folder-browser.c (folder_browser_properties_init): update to - new property (folder_browser_property_changed): kill. - (get_prop, set_prop): do the donkey work + make properly RW. - -2000-03-31 Dan Winship <danw@helixcode.com> - - * folder-browser-factory.c (folder_browser_set_shell): - * folder-browser.c (folder_browser_new): - * message-list.c (on_row_selection_cmd, select_msg, - message_list_init, message_list_set_folder): - - remove debugging printf()s that no longer seem useful - -2000-03-29 Dan Winship <danw@helixcode.com> - - * folder-browser-factory.c (control_activate): build a toolbar. - (control_deactivate): and hide it. - -2000-03-27 Chris Toshok <toshok@helixcode.com> - * mail-display.c: quiet warnings when building in ../po - -2000-03-26 Miguel de Icaza <miguel@gnu.org> - - * folder-browser-factory.c (folder_browser_set_shell): Memory leak - fix. - -2000-03-25 Dan Winship <danw@helixcode.com> - - * message-list.c (select_msg, ml_value_at): update for summary - changes. Hey, neat, it really does make it more efficient. - -2000-03-22 Christopher James Lahey <clahey@helixcode.com> - - * .cvsignore: Updated .cvsignore. - -2000-03-21 Matt Loper <matt@helixcode.com> - - * mail-display.c: Minor cleanup & commenting. - - * folder-browser-factory.c: Minor cleanup & warning elimination. - -2000-03-21 bertrand <bertrand@helixcode.com> - - * message-list.c (ml_value_at): display message size - -2000-03-20 Christopher James Lahey <clahey@helixcode.com> - - * message-list.c: Properly ref & sink the table and header models. - -2000-03-14 Dan Winship <danw@helixcode.com> - - * mail-sources.c: First cut at a mail source selection wizard. - Basically a rigged demo at this point. Doesn't use camel to get - its information, and is not yet complete or integrated with the - mail component. Did I mention that the code is ugly? - -2000-03-13 bertrand <bertrand@helixcode.com> - - * folder-browser-factory.c (folder_browser_set_shell): - for testing and demonstration purpose, immediately - register a fake service. - -2000-03-12 bertrand <bertrand@helixcode.com> - - * folder-browser-factory.c (folder_browser_factory_init): - name change. - (control_activate_cb): when the control is activated, - it merges its own UI with the remote UIHandler. - (control_add_menu): sample menu merging. - (folder_browser_factory): connect the control "activate" signal. - - * evolution-mail.gnorba: - name changes - - * folder-browser.h: added a reference to an - Evolution::Shell object. - - * folder-browser-factory.c (folder_browser_set_shell): - (folder_browser_control_add_service_repository_interface): - (folder_browser_factory): the folder-browser control now - implements the Evolution/ServiceRepository interface. - -2000-03-07 bertrand <bertrand@helixcode.com> - - * folder-browser-factory.c (development_warning): - added a warning so that the user knows that this - version may crash his mails. - -2000-03-05 bertrand <bertrand@helixcode.com> - - * message-list.h: include a referrence to the parent - folder browser. - - * message-list.c (ml_value_at): use the message summary - from the - - * html-stream.c (html_stream_close): when the stream - is closed, set the html stream to NULL - (html_stream_write): don't write anything if the - html handle does not exist. - (html_stream_reset): implemented. close the current - html handle and begins a new html parser. - - * session.c (session_store_new): use static exception - here. - -2000-03-05 Christopher James Lahey <clahey@helixcode.com> - - * message-list.c: Added a prototype message listing. - -2000-03-04 Christopher James Lahey <clahey@helixcode.com> - - * message-list.c: Set up the column headers properly. - - * folder-browser.c: Show the folder_browser widget. - -2000-03-04 Christopher James Lahey <clahey@helixcode.com> - - * message-list.c: Define ml_duplicate_value and ml_free_value - correctly. - -2000-03-04 Christopher James Lahey <clahey@helixcode.com> - - * message-list.c: Use g_int_compare and g_str_compare as we should - be instead of g_int_equal and g_str_equal. - -2000-03-04 bertrand <bertrand@helixcode.com> - - * test-mail.c (main): replace the bonobo-active/gtk-main - by bonobo-main. - Include Gnorba headers. - (main): don't call the container creation routine - before we entered the main loop. Use idle for that. - -2000-03-04 Christopher James Lahey <clahey@helixcode.com> - - * message-list.c: Change this to use the ETable widget itself - instead of building it from all the parts. - -2000-03-03 Christopher James Lahey <clahey@helixcode.com> - - * message-list.c: Ref the table columns since we unref them at the - end. - -2000-03-01 Ettore Perazzoli <ettore@helixcode.com> - - * Makefile.am (INCLUDES): Add `$(top_srcdir)'. Also, the - `top_srcdir' includes must come first everything else to avoid - including installed headers instead of our fresh ones. - -2000-02-28 NotZed <NotZed@HelixCode.com> - - * Makefile.am (evolution_mail_LDADD): Fixed references to eutil. - -2000-02-24 Christopher James Lahey <clahey@helixcode.com> - - * message-list.c: Changed to match new e_table_simple interface. - -2000-02-24 Dan Winship <danw@helixcode.com> - - * message-list.c (message_list_set_folder): update for CamelFolder - changes - -2000-02-24 Christopher James Lahey <clahey@helixcode.com> - - * message-list.c: Changed this to not use the "x" and "y" - arguments to e-table-item. - -2000-02-23 Matt Loper <matt@helixcode.com> - - * message-list.c (message_list_set_folder): Check 'desc'riptions - of exceptions. - -2000-02-22 bertrand <Bertrand.Guiheneuf@aful.org> - - * message-list.c (message_list_set_folder): - fix to show a sample correct implementation. - -2000-02-21 Matt Loper <matt@helixcode.com> - - * Makefile.am: added -lunicode to evolution_mail_LDADD. - -2000-02-21 Dan Winship <danw@helixcode.com> - - * session.c (session_store_new): Pass a CamelAuthCallback - (evolution_auth_callback) to camel_session_new. - -2000-02-21 Dan Winship <danw@helixcode.com> - - * session.c (session_store_new): Update session_store_new to - deal with the fact that camel_session_get_store takes a - CamelException now. Doesn't actually do anything with the - exception yet, because nothing else does yet either. - -2000-02-19 Matt Loper <matt@helixcode.com> - - * .cvsignore: added test-mail. - -2000-02-14 Miguel de Icaza <miguel@gnu.org> - - * folder-browser.c (folder_browser_load_folder): New routine, - loads a camel folder. - (folder_browser_set_uri): redo. - - * session.c: new file. Implements SessionStores to keep track of - a Session/Store tuple. - -2000-02-13 Matt Loper <matt@helixcode.com> - - * html-stream.c (html_stream_new): Second param of gtk_html_begin - should be "", not NULL. - (html_stream_new): gtk_html_parse() is deprecated, so the call was - removed. - - * html-stream.h: HTMLStreamClass's parent changed to - CamelStreamClass, not CamelStream. - -2000-02-11 Christopher James Lahey <clahey@helixcode.com> - - * Makefile.am: Add the e-text directory to the includes list. - - * message-list.c: Change the call to e_cell_text_new, since - there's an added argument. - -2000-02-09 Christopher James Lahey <clahey@helixcode.com> - - * Makefile.am: Added libetext as libetable depends on it. - -2000-02-08 Iain Holmes <ih@csd.abdn.ac.uk> - - * Makefile.am: Changed the order of the compilation so the CORBA stuff - was made before it was needed. - -2000-01-19 Miguel de Icaza <miguel@gnu.org> - - * Started work on the mail display engine. - - * html-stream.c, html-stream.h: New files, they are CamelStreams - used to write to the GtkHTML widget. - diff --git a/mail/GNOME_Evolution_Mail.oaf.in b/mail/GNOME_Evolution_Mail.oaf.in deleted file mode 100644 index 81edb07292..0000000000 --- a/mail/GNOME_Evolution_Mail.oaf.in +++ /dev/null @@ -1,105 +0,0 @@ -<oaf_info> - -<oaf_server iid="OAFIID:control-factory:evolution-mail:25902062-543b-4f44-8702-d90145fcdbf2" - type="exe" - location="evolution-mail"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME/GenericFactory:1.0"/> - </oaf_attribute> - - <oaf_attribute name="description" type="string" - value="Evolution mail folder factory component."/> -</oaf_server> - -<oaf_server iid="OAFIID:control:evolution-mail:833d5a71-a201-4a0e-b7e6-5475c5c4cb45" - type="factory" - location="OAFIID:control-factory:evolution-mail:25902062-543b-4f44-8702-d90145fcdbf2"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:BonoboControl/evolution-mail:1.0"/> - <item value="IDL:GNOME/Control:1.0"/> - </oaf_attribute> - - <oaf_attribute name="description" type="string" - value="Evolution mail folder display component."/> -</oaf_server> - -<oaf_server iid="OAFIID:evolution-shell-component-factory:evolution-mail:0ea887d5-622b-4b8c-b525-18aa1cbe18a6" - type="exe" - location="evolution-mail"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME/GenericFactory:1.0"/> - </oaf_attribute> - - <oaf_attribute name="description" type="string" - value="Factory for the Evolution mail component."/> - -</oaf_server> - -<oaf_server iid="OAFIID:evolution-shell-component:evolution-mail:d3cb3ed6-a654-4337-8aa0-f443751d6d1b" - type="factory" - location="OAFIID:evolution-shell-component-factory:evolution-mail:0ea887d5-622b-4b8c-b525-18aa1cbe18a6"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:Evolution/ShellComponent:1.0"/> - </oaf_attribute> - - <oaf_attribute name="description" type="string" - value="Evolution component for handling mail."/> - - <oaf_attribute name="evolution:shell-component-icon" type="string" - value="evolution-inbox.png"/> -</oaf_server> - -<oaf_server iid="OAFIID:evolution-executive-summary-component-factory:evolution-mail:be210cba-0eee-4def-84fa-643d50321217" - type="exe" - location="evolution-mail"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME:GenericFactory:1.0"/> - </oaf_attribute> - - <oaf_attribute name="description" type="string" - value="Factory for the Mail Summary component."/> -</oaf_server> - -<oaf_server iid="OAFIID:evolution-executive-summary-component:evolution-mail:157f86b4-ff6a-4618-86b8-4789024c4043" - type="factory" - location="OAFIID:evolution-executive-summary-component-factory:evolution-mail:be210cba-0eee-4def-84fa-643d50321217"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:Evolution:SummaryComponent:1.0"/> - </oaf_attribute> - - <oaf_attribute name="description" type="string" - value="Evolution mail executive summary component."/> -</oaf_server> - -<oaf_server iid="OAFIID:evolution-composer-factory:evolution-mail:fcfda393-60ee-485f-b782-e9323434bff3" - type="exe" - location="evolution-mail"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME:GenericFactory:1.0"/> - </oaf_attribute> - - <oaf_attribute name="description" type="string" - value="Factory for the Evolution composer."/> -</oaf_server> - -<oaf_server iid="OAFIID:evolution-composer:evolution-mail:cd8618ea-53e1-4b9e-88cf-ec578bdb903b" - type="factory" - location="OAFIID:evolution-composer-factory:evolution-mail:fcfda393-60ee-485f-b782-e9323434bff3"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:Evolution:Composer:1.0"/> - </oaf_attribute> - - <oaf_attribute name="description" type="string" - value="Evolution mail composer."/> -</oaf_server> - - -</oaf_info> diff --git a/mail/GNOME_Evolution_Mail.oafinfo b/mail/GNOME_Evolution_Mail.oafinfo deleted file mode 100644 index 81edb07292..0000000000 --- a/mail/GNOME_Evolution_Mail.oafinfo +++ /dev/null @@ -1,105 +0,0 @@ -<oaf_info> - -<oaf_server iid="OAFIID:control-factory:evolution-mail:25902062-543b-4f44-8702-d90145fcdbf2" - type="exe" - location="evolution-mail"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME/GenericFactory:1.0"/> - </oaf_attribute> - - <oaf_attribute name="description" type="string" - value="Evolution mail folder factory component."/> -</oaf_server> - -<oaf_server iid="OAFIID:control:evolution-mail:833d5a71-a201-4a0e-b7e6-5475c5c4cb45" - type="factory" - location="OAFIID:control-factory:evolution-mail:25902062-543b-4f44-8702-d90145fcdbf2"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:BonoboControl/evolution-mail:1.0"/> - <item value="IDL:GNOME/Control:1.0"/> - </oaf_attribute> - - <oaf_attribute name="description" type="string" - value="Evolution mail folder display component."/> -</oaf_server> - -<oaf_server iid="OAFIID:evolution-shell-component-factory:evolution-mail:0ea887d5-622b-4b8c-b525-18aa1cbe18a6" - type="exe" - location="evolution-mail"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME/GenericFactory:1.0"/> - </oaf_attribute> - - <oaf_attribute name="description" type="string" - value="Factory for the Evolution mail component."/> - -</oaf_server> - -<oaf_server iid="OAFIID:evolution-shell-component:evolution-mail:d3cb3ed6-a654-4337-8aa0-f443751d6d1b" - type="factory" - location="OAFIID:evolution-shell-component-factory:evolution-mail:0ea887d5-622b-4b8c-b525-18aa1cbe18a6"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:Evolution/ShellComponent:1.0"/> - </oaf_attribute> - - <oaf_attribute name="description" type="string" - value="Evolution component for handling mail."/> - - <oaf_attribute name="evolution:shell-component-icon" type="string" - value="evolution-inbox.png"/> -</oaf_server> - -<oaf_server iid="OAFIID:evolution-executive-summary-component-factory:evolution-mail:be210cba-0eee-4def-84fa-643d50321217" - type="exe" - location="evolution-mail"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME:GenericFactory:1.0"/> - </oaf_attribute> - - <oaf_attribute name="description" type="string" - value="Factory for the Mail Summary component."/> -</oaf_server> - -<oaf_server iid="OAFIID:evolution-executive-summary-component:evolution-mail:157f86b4-ff6a-4618-86b8-4789024c4043" - type="factory" - location="OAFIID:evolution-executive-summary-component-factory:evolution-mail:be210cba-0eee-4def-84fa-643d50321217"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:Evolution:SummaryComponent:1.0"/> - </oaf_attribute> - - <oaf_attribute name="description" type="string" - value="Evolution mail executive summary component."/> -</oaf_server> - -<oaf_server iid="OAFIID:evolution-composer-factory:evolution-mail:fcfda393-60ee-485f-b782-e9323434bff3" - type="exe" - location="evolution-mail"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME:GenericFactory:1.0"/> - </oaf_attribute> - - <oaf_attribute name="description" type="string" - value="Factory for the Evolution composer."/> -</oaf_server> - -<oaf_server iid="OAFIID:evolution-composer:evolution-mail:cd8618ea-53e1-4b9e-88cf-ec578bdb903b" - type="factory" - location="OAFIID:evolution-composer-factory:evolution-mail:fcfda393-60ee-485f-b782-e9323434bff3"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:Evolution:Composer:1.0"/> - </oaf_attribute> - - <oaf_attribute name="description" type="string" - value="Evolution mail composer."/> -</oaf_server> - - -</oaf_info> diff --git a/mail/Mail.idl b/mail/Mail.idl deleted file mode 100644 index 1d12a39c5c..0000000000 --- a/mail/Mail.idl +++ /dev/null @@ -1,30 +0,0 @@ -/* - * mail.idl: Mail interfaces for Evolution - * - * Author: - * Miguel de Icaza (miguel@helixcode.com) - * - * (C) 2000 Helix Code, Inc. - */ - -#include <Bonobo.idl> - -module Evolution { - - interface MessageList : Bonobo::Unknown { - - void select_message (in long message_number); - void open_message (in long message_number); - }; - - /* - * FolderBrowser object. - * - * configuration of this widget is done trough - * Bonobo Properties - */ - interface FolderBrowser : Bonobo::Unknown { - MessageList get_message_list (); - }; -}; - diff --git a/mail/Makefile.am b/mail/Makefile.am deleted file mode 100644 index 4f8a9e3dfa..0000000000 --- a/mail/Makefile.am +++ /dev/null @@ -1,162 +0,0 @@ -bin_PROGRAMS = evolution-mail - -noinst_PROGRAMS = test-mail #test-thread - -providerdir = $(libdir)/evolution/camel-providers/$(VERSION) - -INCLUDES = \ - -I$(top_srcdir)/widgets \ - -I$(top_srcdir)/widgets/e-text \ - -I$(top_srcdir)/widgets/misc \ - -I$(top_srcdir) \ - -I$(top_srcdir)/camel \ - -I$(top_builddir)/shell \ - -I$(top_srcdir)/shell \ - -I$(top_builddir)/executive-summary \ - -I$(top_srcdir)/executive-summary \ - $(EXTRA_GNOME_CFLAGS) \ - $(BONOBO_HTML_GNOME_CFLAGS) \ - $(GNOME_VFS_CFLAGS) \ - $(UNICODE_CFLAGS) \ - $(GTKHTML_CFLAGS) \ - -DEVOLUTION_VERSION=\""$(VERSION)"\" \ - -DEVOLUTION_DATADIR=\""$(datadir)"\" \ - -DEVOLUTION_GLADEDIR=\""$(gladedir)"\" \ - -DEVOLUTION_ICONSDIR=\""$(iconsdir)"\" \ - -DEVOLUTION_LOCALEDIR=\""$(localedir)"\" \ - -DEVOLUTION_DATADIR=\""$(datadir)"\" \ - -DCAMEL_PROVIDERDIR=\""$(providerdir)"\" \ - -DG_LOG_DOMAIN=\"evolution-mail\" \ - $(THREADS_CFLAGS) - -EVOLUTION_MAIL_CORBA_GENERATED = \ - Mail.h \ - Mail-common.c \ - Mail-skels.c \ - Mail-stubs.c - -# FIXME Is there any way around having to do this? -CAMEL_OBJS_EXTRA = \ - $(top_builddir)/camel/providers/vee/libcamelvee.la - -evolution_mail_SOURCES = \ - $(EVOLUTION_MAIL_CORBA_GENERATED) \ - component-factory.c \ - component-factory.h \ - folder-browser.c \ - folder-browser.h \ - folder-browser-factory.c \ - folder-browser-factory.h \ - mail-autofilter.c \ - mail-autofilter.h \ - mail-callbacks.c \ - mail-callbacks.h \ - mail-config.c \ - mail-config.h \ - mail-config-gui.c \ - mail-config-gui.h \ - mail-crypto.c \ - mail-crypto.h \ - mail-display.c \ - mail-display.h \ - mail-format.c \ - mail-identify.c \ - mail-local.c \ - mail-local.h \ - mail-local-storage.c \ - mail-local-storage.h \ - mail-mlist-magic.c \ - mail-mlist-magic.h \ - mail-ops.c \ - mail-ops.h \ - mail-search-dialogue.c \ - mail-search-dialogue.h \ - mail-summary.c \ - mail-summary.h \ - mail-threads.c \ - mail-threads.h \ - mail-tools.c \ - mail-tools.h \ - mail-types.h \ - mail-vfolder.c \ - mail-vfolder.h \ - mail-view.c \ - main.c \ - message-list.c \ - message-list.h \ - message-thread.c \ - message-thread.h \ - session.c \ - mail-session.h \ - subscribe-dialog.c \ - subscribe-dialog.h \ - mail.h - -evolution_mail_LDADD = \ - $(top_builddir)/shell/libeshell.a \ - $(top_builddir)/composer/libcomposer.la \ - $(top_builddir)/widgets/misc/libemiscwidgets.a \ - $(CAMEL_OBJS_EXTRA) \ - $(top_builddir)/camel/libcamel.la \ - $(top_builddir)/e-util/libeutil.la \ - $(top_builddir)/e-util/ename/libename.la \ - $(top_builddir)/libibex/libibex.la \ - $(top_builddir)/filter/libfilter.la \ - $(top_builddir)/executive-summary/evolution-services/libevolution-services.la \ - $(BONOBO_VFS_GNOME_LIBS) \ - $(EXTRA_GNOME_LIBS) \ - $(GTKHTML_LIBS) \ - $(THREADS_LIBS) \ - $(UNICODE_LIBS) - -test_mail_SOURCES = \ - test-mail.c - -test_mail_LDADD = \ - $(BONOBO_HTML_GNOME_LIBS) - -#test_thread_SOURCES = \ -# mail-threads.c \ -# mail-threads.h \ -# test-thread.c -# -#test_thread_LDADD = \ -# $(top_builddir)/camel/libcamel.la \ -# $(top_builddir)/e-util/libeutil.la \ -# $(top_builddir)/libibex/libibex.la \ -# $(BONOBO_HTML_GNOME_LIBS) \ -# $(UNICODE_LIBS) \ -# $(THREADS_LIBS) -# -#test_thread_CFLAGS = -g $(THREADS_CFLAGS) - -oafdir = $(datadir)/oaf -oaf_DATA = evolution-mail.oafinfo - -gladedir = $(datadir)/evolution/glade -glade_DATA = mail-config.glade mail-config-druid.glade local-config.glade - -glade_messages = \ - mail-config-druid.glade.h \ - mail-config.glade.h - -iconsdir = $(datadir)/images/evolution - -$(EVOLUTION_MAIL_CORBA_GENERATED): Mail.idl - $(ORBIT_IDL) -I $(datadir)/idl -I `$(GNOME_CONFIG) --cflags idl` -I `$(GNOME_CONFIG) --datadir`/idl -I $(srcdir) $(srcdir)/Mail.idl - -EXTRA_DIST = Mail.idl $(glade_DATA) $(oaf_DATA) $(glade_messages) - -if ENABLE_PURIFY -PLINK = $(LIBTOOL) --mode=link $(PURIFY) $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ - -all-local: evolution-mail.pure - -evolution-mail.pure: evolution-mail - @rm -f evolution-mail.pure - $(PLINK) $(evolution_mail_LDFLAGS) $(evolution_mail_OBJECTS) $(evolution_mail_LDADD) $(LIBS) - -endif - -BUILT_SOURCES = $(EVOLUTION_MAIL_CORBA_GENERATED) -CLEANFILES += $(BUILT_SOURCES) diff --git a/mail/README.async b/mail/README.async deleted file mode 100644 index 238fafcedb..0000000000 --- a/mail/README.async +++ /dev/null @@ -1,360 +0,0 @@ -Asynchronous Mailer Information -Peter Williams <peterw@helixcode.com> -8/4/2000 - -1. INTRODUCTION - -It's pretty clear that the Evolution mailer needs to be asynchronous in -some manner. Blocking the UI completely on IMAP calls or large disk reads -is unnacceptable, and it's really nice to be able to thread the message -view in the background, or do other things while a mailbox is downloading. - -The problem in making Evolution asynchronous is Camel. Camel is not -asynchronous for a few reasons. All of its interfaces are synchronous -- -calls like camel_store_get_folder, camel_folder_get_message, etc. can -take a very long time if they're being performed over a network or with -a large mbox mailbox file. However, these functions have no mechanism -for specifying that the operation is in progress but not complete, and -no mechanism for signaling when to operation does complete. - -2. WHY I DIDN'T MAKE CAMEL ASYNCHRONOUS - -It seems like it would be a good idea, then, to rewrite Camel to be -asynchonous. This presents several problems: - - * Many interfaces must be rewritten to support "completed" - callbacks, etc. Some of these interfaces are connected to - synchronous CORBA calls. - * Everything must be rewritten to be asynchonous. This includes - the CamelStore, CamelFolder, CamelMimeMessage, CamelProvider, - every subclass thereof, and all the code that touches these. - These include the files in camel/, mail/, filter/, and - composer/. The change would be a complete redesign for any - provider implementation. - * All the work on providers (IMAP, mh, mbox, nntp) up to this - point would be wasted. While they were being rewritten - evolution-mail would be useless. - -However, it is worth noting that the solution I chose is not optimal, -and I think that it would be worthwhile to write a libcamel2 or some -such thing that was designed from the ground up to work asynchronously. -Starting fresh from such a design would work, but trying to move the -existing code over would be more trouble than it's worth. - -3. WHY I MADE CAMEL THREADED - -If Camel was not going to be made asynchronous, really the only other -choice was to make it multithreaded. [1] No one has been particularly -excited by this plan, as debugging and writing MT-safe code is hard. -But there wasn't much of a choice, and I believed that a simple thread -wrapper could be written around Camel. - -The important thing to know is that while Camel is multithreaded, we -DO NOT and CANNOT share objects between threads. Instead, -evolution-mail sends a request to a dispatching thread, which performs -the action or queues it to be performed. (See section 4 for details) - -The goal that I was working towards is that there should be no calls -to camel made, ever, in the main thread. I didn't expect to and -didn't do this, but that was the intent. - -[1]. Well, we could fork off another process, but they share so much -data that this would be pretty impractical. - -4. IMPLEMENTATION - -a. CamelObject - -Threading presented a major problem regarding Camel. Camel is based -on the GTK Object system, and uses signals to communicate events. This -is okay in a nonthreaded application, but the GTK Object system is -not thread-safe. - -Particularly, signals and object allocations use static data. Using -either one inside Camel would guarantee that we'd be stuck with -random crashes forevermore. That's Bad (TM). - -There were two choices: make sure to limit our usage of GTK, or stop -using the GTK Object system. I decided to do the latter, as the -former would lead to a mess of "what GTK calls can we make" and -GDK_THREADS_ENTER and accidentally calling UI functions and upgrades -to GTK breaking everything. - -So I wrote a very very simple CamelObject system. It had three goals: - - * Be really straightforward, just encapsulate the type - heirarchy without all that GtkArg silliness or anything. - * Be as compatible as possible with the GTK Object system - to make porting easy - * Be threadsafe - -It supports: - - * Type inheritance - * Events (signals) - * Type checking - * Normal refcounting - * No unref/destroy messiness - * Threadsafety - * Class functions - -The entire code to the object system is in camel/camel-object.c. It's -a naive implementation and not full of features, but intentionally that -way. The main differences between GTK Objects and Camel Objects are: - - * s,gtk,camel,i of course - * Finalize is no longer a GtkObjectClass function. You specify - a finalize function along with an init function when declaring - a type, and it is called automatically and chained automatically. - * Declaring a type is a slightly different API - * The signal system is replaced with a not-so-clever event system. - Every event is equivalent to a NONE__POINTER signal. The syntax - is slightly different: a class "declares" an event and specifies - a name and a "prep func", that is called before the event is - triggered and can cancel it. - * There is only one CamelXXXClass in existence for every type. - All objects share it. - -There is a shell script, tools/make-camel-object.sh that will do all of -the common substitutions to make a file CamelObject-compatible. Usually -all that needs to be done is move the implementation of the finalize -event out of the class init, modify the get_type function, and replace -signals with events. - -Pitfalls in the transition that I ran into were: - - * gtk_object_ref -> camel_object_ref or you coredump - * some files return 'guint' instead of GtkType and must be changed - * Remove the #include <gtk/gtk.h> - * gtk_object_set_datas must be changed (This happened once; I - added a static hashtable) - * signals have to be fudged a bit to match the gpointer input - * the BAST_CASTARD option is on, meaning failed typecasts will - return NULL, almost guaranteeing a segfault -- gets those - bugs fixed double-quick! - -b. API -- mail_operation_spec - -I worked by creating a very specific definition of a "mail operation" -and wrote an engine to queue and dispatch them. - -A mail operation is defined by a structure mail_operation_spec -prototyped in mail-threads.h. It comes in three logical parts -- a -"setup" phase, executed in the main thread; a "do" phase, executed -in the dispatch thread; and a "cleanup" phase, executed in the main -thread. These three phases are guaranteed to be performed in order -and atomically with respect to other mail operations. - -Each of these phases is represented by a function pointer in the -mail_operation_spec structure. The function mail_operation_queue() is -called and passed a pointer to a mail_operation_spec and a user_data-style -pointer that fills in the operation's parameters. The "setup" callback -is called immediately, though that may change. - -Each callback is passed three parameters: a pointer to the user_data, -a pointer to the "operation data", and a pointer to a CamelException. -The "operation data" is allocated automatically and freed when the operation -completes. Internal data that needs to be shared between phases should -be stored here. The size allocated is specified in the mail_operation_spec -structure. - -Because all of the callbacks use Camel calls at some point, the -CamelException is provided as utility. The dispatcher will catch exceptions -and display error dialogs, unlike the synchronous code which lets -exceptions fall through the cracks fairly easily. - -I tried to implement all the operations following this convention. Basically -I used this skeleton code for all the operations, just filling in the -specifics: - -=================================== - -typedef struct operation_name_input_s { - parameters to operation -} operation_name_input_t; - -typedef struct operation_name_data_s { - internal data to operation, if any - (if none, omit the structure and set opdata_size to 0) -} operation_name_data_t; - -static gchar *describe_operation_name (gpointer in_data, gboolean gerund); -static void setup_operation_name (gpointer in_data, gpointer op_data, CamelException *ex); -static void do_operation_name (gpointer in_data, gpointer op_data, CamelException *ex); -static void cleanup_operation_name (gpointer in_data, gpointer op_data, CamelException *ex); - -static gchar *describe_operation_name (gpointer in_data, gboolean gerund) -{ - operation_name_input_t *input = (operation_name_input_t *) in_data; - - if (gerund) { - return a g_strdup'ed string describing what we're doing - } else { - return a g_strdup'ed string describing what we're about to do - } -} - -static void setup_operation_name (gpointer in_data, gpointer op_data, CamelException *ex) -{ - operation_name_input_t *input = (operation_name_input_t *) in_data; - operation_name_data_t *data = (operation_name_data_t *) op_data; - - verify that parameters are valid - - initialize op_data - - reference objects -} - -static void do_operation_name (gpointer in_data, gpointer op_data, CamelException *ex) -{ - operation_name_input_t *input = (operation_name_input_t *) in_data; - operation_name_data_t *data = (operation_name_data_t *) op_data; - - perform camel operations -} - -static void cleanup_operation_name (gpointer in_data, gpointer op_data, CamelException *ex) -{ - operation_name_input_t *input = (operation_name_input_t *) in_data; - operation_name_data_t *data = (operation_name_data_t *) op_data; - - perform UI updates - - free allocations - - dereference objects -} - -static const mail_operation_spec op_operation_name = { - describe_operation_name, - sizeof (operation_name_data_t), - setup_operation_name, - do_operation_name, - cleanup_operation_name -}; - -void -mail_do_operation_name (parameters) -{ - operation_name_input_t *input; - - input = g_new (operation_name_input_t, 1); - - store parameters in input - - mail_operation_queue (&op_operation_name, input, TRUE); -} - -=========================================== - -c. mail-ops.c - -Has been drawn and quartered. It has been split into: - - * mail-callbacks.c: the UI callbacks - * mail-tools.c: useful sequences wrapping common Camel operations - * mail-ops.c: implementations of all the mail_operation_specs - -An important part of mail-ops.c are the global functions -mail_tool_camel_lock_{up,down}. These simulate a recursize mutex around -camel. There are an extreme few, supposedly safe, calls to Camel made in -the main thread. These functions should go around evey call to Camel or -group thereof. I don't think they're necessary but it's nice to know -they're there. - -If you look at mail-tools.c, you'll notice that all the Camel calls are -protected with these functions. Remember that a mail tool is really -just another Camel call, so don't use them in the main thread either. - -All the mail operations are implemented in mail-ops.c EXCEPT: - - * filter-driver.c: the filter_mail operation - * message-list.c: the regenerate_messagelist operation - * message-thread.c: the thread_messages operation - -d. Using the operations - -The mail operations as implemented are very specific to evolution-mail. I -was thinking about leaving them mostly generic and then allowing extra -callbacks to be added to perform the more specific UI touches, but this -seemed kind of pointless. - -I basically looked through the code, found references to Camel, and split -the code into three parts -- the bit before the Camel calls, the bit after, -and the Camel calls. These were mapped onto the template, given a name, -and added to mail-ops.c. Additionally, I simplified the common tasks that -were taken care of in mail-tools.c, making some functions much simpler. - -Ninety-nine percent of the time, whatever operation is being done is being -done in a callback, so all that has to be done is this: - -================== - -void my_callback (GtkObject *obj, gchar *uid) -{ - camel_do_something (uid); -} - -==== becomes ==== - -void my_callback (GtkObject *obj, gchar *uid) -{ - mail_do_do_something (uid); -} - -================= - -There are, however, a few belligerents. Particularly, the function -mail_uri_to_folder returns a CamelFolder and yet should really be -asynchronous. This is called in a CORBA call that is sychronous, and -additionally is used in the filter code. - -I changed the first usage to return the folder immediately but -still fetch the CamelFolder asyncrhonously, and in the second case, -made filtering asynchronous, so the fact that the call is synchronous -doesn't matter. - -The function was renamed to mail_tool_uri_to_folder to emphasize that -it's a synchronous Camel call. - -e. The dispatcher - -mail_operation_queue () takes its parameters and assembles them in a -closure_t structure, which I abbreviate clur. It sets a timeout to -display a progress window if an operation is still running one second -later (we're not smart enough to check if it's the same operation, -but the issue is not a big deal). The other thread and some communication -pipes are created. - -The dispatcher thread sits in a loop reading from a pipe. Every time -the main thread queues an operation, it writes the closure_t into the pipe. -The dispatcher reads the closure, sends a STARTING message to the main -thread (see below for explanation), calls the callback specified in the -closure, and sends a FINISHED message. It then goes back to reading -from its pipe; it will either block until another operation comes along, -or find one right away and start it. This the pipe takes care of queueing -operations. - -The dispatch thread communicates with the main thread with another pipe; -however, the main thread has other things to do than read from the pipe, -so it adds registers a GIOReader that checks for messages in the glib -main loop. In addition to starting and finishing messages, the other -thread can communicate to the user using messages and a progress bar. -(This is currently implemented but unused.) - -5. ISSUES - - * Operations are queued and dequeued stupidly. Like if you click - on one message then click on another, the first will be retrieved - and displayed then overwritten by the second. Operations that could - be performed at the same time safely aren't. - * The CamelObject system is workable, but it'd be nice to work with - something established like the GtkObject - * The whole threading idea is not great. Concensus is that an - asynchronous interface is the Right Thing, eventually. - * Care still needs to be taken when designing evolution-mail code to - work with the asynchronous mail_do_ functions - * Some of the operations are extremely hacky. - * IMAP's timeout to send a NOOP had to be removed because we can't - use GTK. We need an alternative for this.
\ No newline at end of file diff --git a/mail/component-factory.c b/mail/component-factory.c deleted file mode 100644 index acd635e5c6..0000000000 --- a/mail/component-factory.c +++ /dev/null @@ -1,354 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* component-factory.c - * - * Authors: Ettore Perazzoli <ettore@helixcode.com> - * - * Copyright (C) 2000 Helix Code, Inc. - * - * 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 the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <bonobo.h> - -#include "camel.h" - -#include "Evolution.h" -#include "evolution-storage.h" - -#include "folder-browser-factory.h" -#include "evolution-shell-component.h" -#include "folder-browser.h" -#include "mail.h" /* YUCK FIXME */ -#include "mail-tools.h" -#include "mail-ops.h" -#include "mail-session.h" -#include <gal/widgets/e-gui-utils.h> -#include "mail-local-storage.h" - -#include "component-factory.h" - -#include <executive-summary/evolution-services/executive-summary-component.h> -#include "mail-summary.h" - -CamelFolder *drafts_folder = NULL; -CamelFolder *outbox_folder = NULL; -CamelFolder *sent_folder = NULL; /* this one should be configurable? */ -char *evolution_dir; - -static void create_vfolder_storage (EvolutionShellComponent *shell_component); - -#define COMPONENT_FACTORY_ID "OAFIID:evolution-shell-component-factory:evolution-mail:0ea887d5-622b-4b8c-b525-18aa1cbe18a6" -#define SUMMARY_FACTORY_ID "OAFIID:evolution-executive-summary-component-factory:evolution-mail:be210cba-0eee-4def-84fa-643d50321217" - -static BonoboGenericFactory *factory = NULL; -static BonoboGenericFactory *summary_factory = NULL; -static gint running_objects = 0; -static GHashTable *storages_hash; - -static const EvolutionShellComponentFolderType folder_types[] = { - { "mail", "evolution-inbox.png" }, - { NULL, NULL } -}; - -/* EvolutionShellComponent methods and signals. */ - -static EvolutionShellComponentResult -create_view (EvolutionShellComponent *shell_component, - const char *physical_uri, - const char *folder_type, - BonoboControl **control_return, - void *closure) -{ - EvolutionShellClient *shell_client; - Evolution_Shell corba_shell; - BonoboControl *control; - GtkWidget *folder_browser_widget; - - if (g_strcasecmp (folder_type, "mail") != 0) - return EVOLUTION_SHELL_COMPONENT_UNSUPPORTEDTYPE; - - shell_client = evolution_shell_component_get_owner (shell_component); - corba_shell = bonobo_object_corba_objref (BONOBO_OBJECT (shell_client)); - - control = folder_browser_factory_new_control (physical_uri, corba_shell); - if (!control) - return EVOLUTION_SHELL_COMPONENT_NOTFOUND; - - folder_browser_widget = bonobo_control_get_widget (control); - - g_assert (folder_browser_widget != NULL); - g_assert (IS_FOLDER_BROWSER (folder_browser_widget)); - - *control_return = control; - - return EVOLUTION_SHELL_COMPONENT_OK; -} - -static void -create_folder (EvolutionShellComponent *shell_component, - const char *physical_uri, - const char *type, - const Evolution_ShellComponentListener listener, - void *closure) -{ - mail_do_create_folder (listener, physical_uri, type); -} - -static void -owner_set_cb (EvolutionShellComponent *shell_component, - EvolutionShellClient *shell_client, - const char *evolution_homedir, - gpointer user_data) -{ - GSList *sources; - Evolution_Shell corba_shell; - - g_print ("evolution-mail: Yeeeh! We have an owner!\n"); /* FIXME */ - - evolution_dir = g_strdup (evolution_homedir); - mail_session_init (); - - mail_config_init (); - mail_do_setup_folder ("Drafts", &drafts_folder); - mail_do_setup_folder ("Outbox", &outbox_folder); - mail_do_setup_folder ("Sent", &sent_folder); - /* Don't proceed until those _folder variables are valid. */ - mail_operation_wait_for_finish (); - - create_vfolder_storage (shell_component); - - corba_shell = bonobo_object_corba_objref (BONOBO_OBJECT (shell_client)); - - sources = mail_config_get_sources (); - mail_load_storages (corba_shell, sources); - sources = mail_config_get_news (); - mail_load_storages (corba_shell, sources); - - mail_local_storage_startup (shell_client); -} - -static void -owner_unset_cb (EvolutionShellComponent *shell_component, gpointer user_data) -{ - mail_operations_terminate (); - gtk_main_quit (); -} - -static void -free_storage (gpointer service, gpointer storage, gpointer data) -{ - camel_service_disconnect (service, TRUE, NULL); - camel_object_unref (service); - gtk_object_unref (storage); -} - -static void -factory_destroy (BonoboEmbeddable *embeddable, - gpointer dummy) -{ - running_objects--; - if (running_objects > 0) - return; - - if (factory) - bonobo_object_unref (BONOBO_OBJECT (factory)); - else - g_warning ("Serious ref counting error"); - factory = NULL; - - g_hash_table_foreach (storages_hash, free_storage, NULL); - g_hash_table_destroy (storages_hash); - storages_hash = NULL; - - gtk_main_quit (); -} - -static BonoboObject * -summary_fn (BonoboGenericFactory *factory, void *closure) -{ - ExecutiveSummaryComponent *summary_component; - - summary_component = executive_summary_component_new (create_summary_view, - NULL, NULL); - return BONOBO_OBJECT (summary_component); -} - -static BonoboObject * -factory_fn (BonoboGenericFactory *factory, void *closure) -{ - EvolutionShellComponent *shell_component; - - running_objects++; - - shell_component = evolution_shell_component_new (folder_types, - create_view, - create_folder, - NULL, - NULL, - NULL); - - gtk_signal_connect (GTK_OBJECT (shell_component), "destroy", - GTK_SIGNAL_FUNC (factory_destroy), NULL); - gtk_signal_connect (GTK_OBJECT (shell_component), "owner_set", - GTK_SIGNAL_FUNC (owner_set_cb), NULL); - gtk_signal_connect (GTK_OBJECT (shell_component), "owner_unset", - GTK_SIGNAL_FUNC (owner_unset_cb), NULL); - - return BONOBO_OBJECT (shell_component); -} - -void -component_factory_init (void) -{ - if (factory != NULL) - return; - - factory = bonobo_generic_factory_new (COMPONENT_FACTORY_ID, factory_fn, NULL); - summary_factory = bonobo_generic_factory_new (SUMMARY_FACTORY_ID, summary_fn, NULL); - - storages_hash = g_hash_table_new (NULL, NULL); - - if (factory == NULL) { - e_notice (NULL, GNOME_MESSAGE_BOX_ERROR, - _("Cannot initialize Evolution's mail component.")); - exit (1); - } - - if (summary_factory == NULL) { - e_notice (NULL, GNOME_MESSAGE_BOX_ERROR, - _("Cannot initialize Evolution's mail summary component.")); - } - - if (storages_hash == NULL) { - e_notice (NULL, GNOME_MESSAGE_BOX_ERROR, - _("Cannot initialize Evolution's mail storage hash.")); - } -} - -/* FIXME: remove */ -static void -create_vfolder_storage (EvolutionShellComponent *shell_component) -{ - void vfolder_create_storage(EvolutionShellComponent *shell_component); - - vfolder_create_storage(shell_component); -} - -static void -add_storage (const char *uri, CamelService *store, - Evolution_Shell corba_shell, CamelException *ex) -{ - EvolutionStorage *storage; - EvolutionStorageResult res; - char *name; - - name = camel_service_get_name (store, TRUE); - storage = evolution_storage_new (name); - g_free (name); - - res = evolution_storage_register_on_shell (storage, corba_shell); - - switch (res) { - case EVOLUTION_STORAGE_OK: - g_hash_table_insert (storages_hash, store, storage); - camel_object_ref (CAMEL_OBJECT (store)); - mail_do_scan_subfolders (CAMEL_STORE (store), storage); - /* falllll */ - case EVOLUTION_STORAGE_ERROR_ALREADYREGISTERED: - case EVOLUTION_STORAGE_ERROR_EXISTS: - return; - default: - camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, - _("Cannot register storage with shell")); - break; - } -} - -void -mail_load_storages (Evolution_Shell corba_shell, GSList *sources) -{ - CamelException ex; - MailConfigService *svc; - GSList *iter; - - camel_exception_init (&ex); - - /* Load each service (don't connect!). Check its provider and - * see if this belongs in the shell's folder list. If so, add - * it. - */ - - for (iter = sources; iter; iter = iter->next) { - CamelService *store; - CamelProvider *prov; - - svc = (MailConfigService *) iter->data; - if (svc->url == NULL || svc->url[0] == '\0') - continue; - - store = camel_session_get_service (session, svc->url, - CAMEL_PROVIDER_STORE, &ex); - if (store == NULL) { - /* FIXME: real error dialog */ - g_warning ("couldn't get service %s: %s\n", svc->url, - camel_exception_get_description (&ex)); - camel_exception_clear (&ex); - continue; - } - - prov = camel_service_get_provider (store); - - /* FIXME: this case is ambiguous for things like the - * mbox provider, which can really be a spool - * (/var/spool/mail/user) or a storage (~/mail/, eg). - * That issue can't be resolved on the provider level - * -- it's a per-URL problem. - */ - if (prov->flags & CAMEL_PROVIDER_IS_STORAGE && - prov->flags & CAMEL_PROVIDER_IS_REMOTE) { - add_storage (svc->url, store, corba_shell, &ex); - if (camel_exception_is_set (&ex)) { - /* FIXME: real error dialog */ - g_warning ("Cannot load storage: %s", - camel_exception_get_description (&ex)); - camel_exception_clear (&ex); - } - camel_object_unref (CAMEL_OBJECT (store)); - } - } -} - -EvolutionStorage* -mail_lookup_storage (CamelStore *store) -{ - EvolutionStorage *storage; - - /* Because the storages_hash holds a reference to each store - * used as a key in it, none of them will ever be gc'ed, meaning - * any call to camel_session_get_{service,store} with the same - * URL will always return the same object. So this works. - */ - - storage = g_hash_table_lookup (storages_hash, store); - if (storage) - gtk_object_ref (GTK_OBJECT (storage)); - - return storage; -} diff --git a/mail/component-factory.h b/mail/component-factory.h deleted file mode 100644 index 1f5a33f407..0000000000 --- a/mail/component-factory.h +++ /dev/null @@ -1,29 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* component-factory.h - * - * Copyright (C) 2000 Helix Code, Inc. - * - * 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 the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: Ettore Perazzoli - */ - -#ifndef COMPONENT_FACTORY_H -#define COMPONENT_FACTORY_H - -void component_factory_init (void); - -#endif diff --git a/mail/e-attchmt.png b/mail/e-attchmt.png Binary files differdeleted file mode 100644 index b4bac8db67..0000000000 --- a/mail/e-attchmt.png +++ /dev/null diff --git a/mail/evolution-mail.oafinfo b/mail/evolution-mail.oafinfo deleted file mode 100644 index 81edb07292..0000000000 --- a/mail/evolution-mail.oafinfo +++ /dev/null @@ -1,105 +0,0 @@ -<oaf_info> - -<oaf_server iid="OAFIID:control-factory:evolution-mail:25902062-543b-4f44-8702-d90145fcdbf2" - type="exe" - location="evolution-mail"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME/GenericFactory:1.0"/> - </oaf_attribute> - - <oaf_attribute name="description" type="string" - value="Evolution mail folder factory component."/> -</oaf_server> - -<oaf_server iid="OAFIID:control:evolution-mail:833d5a71-a201-4a0e-b7e6-5475c5c4cb45" - type="factory" - location="OAFIID:control-factory:evolution-mail:25902062-543b-4f44-8702-d90145fcdbf2"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:BonoboControl/evolution-mail:1.0"/> - <item value="IDL:GNOME/Control:1.0"/> - </oaf_attribute> - - <oaf_attribute name="description" type="string" - value="Evolution mail folder display component."/> -</oaf_server> - -<oaf_server iid="OAFIID:evolution-shell-component-factory:evolution-mail:0ea887d5-622b-4b8c-b525-18aa1cbe18a6" - type="exe" - location="evolution-mail"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME/GenericFactory:1.0"/> - </oaf_attribute> - - <oaf_attribute name="description" type="string" - value="Factory for the Evolution mail component."/> - -</oaf_server> - -<oaf_server iid="OAFIID:evolution-shell-component:evolution-mail:d3cb3ed6-a654-4337-8aa0-f443751d6d1b" - type="factory" - location="OAFIID:evolution-shell-component-factory:evolution-mail:0ea887d5-622b-4b8c-b525-18aa1cbe18a6"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:Evolution/ShellComponent:1.0"/> - </oaf_attribute> - - <oaf_attribute name="description" type="string" - value="Evolution component for handling mail."/> - - <oaf_attribute name="evolution:shell-component-icon" type="string" - value="evolution-inbox.png"/> -</oaf_server> - -<oaf_server iid="OAFIID:evolution-executive-summary-component-factory:evolution-mail:be210cba-0eee-4def-84fa-643d50321217" - type="exe" - location="evolution-mail"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME:GenericFactory:1.0"/> - </oaf_attribute> - - <oaf_attribute name="description" type="string" - value="Factory for the Mail Summary component."/> -</oaf_server> - -<oaf_server iid="OAFIID:evolution-executive-summary-component:evolution-mail:157f86b4-ff6a-4618-86b8-4789024c4043" - type="factory" - location="OAFIID:evolution-executive-summary-component-factory:evolution-mail:be210cba-0eee-4def-84fa-643d50321217"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:Evolution:SummaryComponent:1.0"/> - </oaf_attribute> - - <oaf_attribute name="description" type="string" - value="Evolution mail executive summary component."/> -</oaf_server> - -<oaf_server iid="OAFIID:evolution-composer-factory:evolution-mail:fcfda393-60ee-485f-b782-e9323434bff3" - type="exe" - location="evolution-mail"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME:GenericFactory:1.0"/> - </oaf_attribute> - - <oaf_attribute name="description" type="string" - value="Factory for the Evolution composer."/> -</oaf_server> - -<oaf_server iid="OAFIID:evolution-composer:evolution-mail:cd8618ea-53e1-4b9e-88cf-ec578bdb903b" - type="factory" - location="OAFIID:evolution-composer-factory:evolution-mail:fcfda393-60ee-485f-b782-e9323434bff3"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:Evolution:Composer:1.0"/> - </oaf_attribute> - - <oaf_attribute name="description" type="string" - value="Evolution mail composer."/> -</oaf_server> - - -</oaf_info> diff --git a/mail/folder-browser-factory.c b/mail/folder-browser-factory.c deleted file mode 100644 index ea0bde946d..0000000000 --- a/mail/folder-browser-factory.c +++ /dev/null @@ -1,247 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * folder-browser-factory.c: A Bonobo Control factory for Folder Browsers - * - * Author: - * Miguel de Icaza (miguel@helixcode.com) - * - * (C) 2000 Helix Code, Inc. - */ - -#include <config.h> - -#include <gnome.h> -#include <bonobo/bonobo-main.h> -#include <bonobo/bonobo-object.h> -#include <bonobo/bonobo-generic-factory.h> -#include <bonobo/bonobo-control.h> -#include <bonobo/bonobo-ui-component.h> - -#include <gal/util/e-util.h> -#include <gal/widgets/e-gui-utils.h> - -#include "folder-browser-factory.h" - -#include "folder-browser.h" -#include "mail.h" -#include "mail-callbacks.h" -#include "shell/Evolution.h" -#include "mail-config.h" -#include "mail-ops.h" -#include "mail-session.h" - -/* The FolderBrowser BonoboControls we have. */ -static GList *control_list = NULL; - -/* - * Add with 'folder_browser' - */ -BonoboUIVerb verbs [] = { - BONOBO_UI_UNSAFE_VERB ("PrintMessage", print_msg), - BONOBO_UI_UNSAFE_VERB ("PrintPreviewMessage", print_preview_msg), - - /* Edit Menu */ - BONOBO_UI_UNSAFE_VERB ("EditSelectAll", select_all), - BONOBO_UI_UNSAFE_VERB ("EditInvertSelection", invert_selection), - - /* Settings Menu */ - BONOBO_UI_UNSAFE_VERB ("SetMailFilter", filter_edit), - BONOBO_UI_UNSAFE_VERB ("SetVFolder", vfolder_edit_vfolders), - BONOBO_UI_UNSAFE_VERB ("SetMailConfig", providers_config), - BONOBO_UI_UNSAFE_VERB ("SetSubscribe", manage_subscriptions), - BONOBO_UI_UNSAFE_VERB ("SetForgetPwd", mail_session_forget_passwords), - - /* Message Menu */ - BONOBO_UI_UNSAFE_VERB ("MessageOpenNewWnd", view_message), - BONOBO_UI_UNSAFE_VERB ("MessageEdit", edit_message), - BONOBO_UI_UNSAFE_VERB ("MessagePrint", print_msg), - BONOBO_UI_UNSAFE_VERB ("MessageReplySndr", reply_to_sender), - BONOBO_UI_UNSAFE_VERB ("MessageReplyAll", reply_to_all), - BONOBO_UI_UNSAFE_VERB ("MessageForward", forward_msg), - /*BONOBO_UI_UNSAFE_VERB ("MessageForwardAttach", forward_msg),*/ - - BONOBO_UI_UNSAFE_VERB ("MessageMarkAsRead", mark_as_seen), - BONOBO_UI_UNSAFE_VERB ("MessageMarkAsUnRead", mark_as_unseen), - - BONOBO_UI_UNSAFE_VERB ("MessageMove", move_msg), - BONOBO_UI_UNSAFE_VERB ("MessageCopy", copy_msg), - BONOBO_UI_UNSAFE_VERB ("MessageDelete", delete_msg), - BONOBO_UI_UNSAFE_VERB ("MessageUndelete", undelete_msg), - - /*BONOBO_UI_UNSAFE_VERB ("MessageAddSenderToAddressBook", addrbook_sender),*/ - - BONOBO_UI_UNSAFE_VERB ("MessageApplyFilters", apply_filters), - - BONOBO_UI_UNSAFE_VERB ("MessageVFolderSubj", vfolder_subject), - BONOBO_UI_UNSAFE_VERB ("MessageVFolderSndr", vfolder_sender), - BONOBO_UI_UNSAFE_VERB ("MessageVFolderRecip", vfolder_recipient), - - BONOBO_UI_UNSAFE_VERB ("MessageFilterSubj", filter_subject), - BONOBO_UI_UNSAFE_VERB ("MessageFilterSndr", filter_sender), - BONOBO_UI_UNSAFE_VERB ("MessageFilterRecip", filter_recipient), - - /* Folder Menu */ - BONOBO_UI_UNSAFE_VERB ("FolderExpunge", expunge_folder), - BONOBO_UI_UNSAFE_VERB ("FolderConfig", configure_folder), - - /* Toolbar specific */ - BONOBO_UI_UNSAFE_VERB ("MailGet", send_receieve_mail), - BONOBO_UI_UNSAFE_VERB ("MailCompose", compose_msg), - - BONOBO_UI_VERB_END -}; - -static void -set_pixmap (BonoboUIComponent *uic, - const char *xml_path, - const char *icon) -{ - char *path; - GdkPixbuf *pixbuf; - - path = g_concat_dir_and_file (EVOLUTION_DATADIR "/images/evolution/buttons", icon); - - pixbuf = gdk_pixbuf_new_from_file (path); - g_return_if_fail (pixbuf != NULL); - - bonobo_ui_util_set_pixbuf (uic, xml_path, pixbuf); - - gdk_pixbuf_unref (pixbuf); - - g_free (path); -} - -static void -update_pixmaps (BonoboUIComponent *uic) -{ - set_pixmap (uic, "/Toolbar/MailGet", "fetch-mail.png"); - set_pixmap (uic, "/Toolbar/MailCompose", "compose-message.png"); - set_pixmap (uic, "/Toolbar/Reply", "reply.png"); - set_pixmap (uic, "/Toolbar/ReplyAll", "reply-to-all.png"); - set_pixmap (uic, "/Toolbar/Forward", "forward.png"); - set_pixmap (uic, "/Toolbar/Move", "move-message.png"); - set_pixmap (uic, "/Toolbar/Copy", "copy-message.png"); -} - -static void -control_activate (BonoboControl *control, - BonoboUIComponent *uic, - FolderBrowser *fb) -{ - GtkWidget *folder_browser; - Bonobo_UIContainer container; - - container = bonobo_control_get_remote_ui_container (control); - bonobo_ui_component_set_container (uic, container); - bonobo_object_release_unref (container, NULL); - - g_assert (container == bonobo_ui_component_get_container (uic)); - g_return_if_fail (container != CORBA_OBJECT_NIL); - - folder_browser = bonobo_control_get_widget (control); - - bonobo_ui_component_add_verb_list_with_data ( - uic, verbs, folder_browser); - - bonobo_ui_component_freeze (uic, NULL); - - bonobo_ui_util_set_ui ( - uic, EVOLUTION_DATADIR, - "evolution-mail.xml", "evolution-mail"); - - if (mail_config_thread_list ()) - bonobo_ui_component_set_prop ( - uic, "/commands/ViewThreaded", "state", "1", NULL); - else - bonobo_ui_component_set_prop ( - uic, "/commands/ViewThreaded", "state", "0", NULL); - - bonobo_ui_component_add_listener ( - uic, "ViewThreaded", - folder_browser_toggle_threads, folder_browser); - - update_pixmaps (uic); - - bonobo_ui_component_thaw (uic, NULL); -} - -static void -control_deactivate (BonoboControl *control, - BonoboUIComponent *uic, - FolderBrowser *fb) -{ - bonobo_ui_component_rm (uic, "/", NULL); - bonobo_ui_component_unset_container (uic); - - if (fb->folder) - mail_do_sync_folder (fb->folder); -} - -static void -control_activate_cb (BonoboControl *control, - gboolean activate, - gpointer user_data) -{ - BonoboUIComponent *uic; - - uic = bonobo_control_get_ui_component (control); - g_assert (uic != NULL); - - if (activate) - control_activate (control, uic, user_data); - else - control_deactivate (control, uic, user_data); -} - -static void -control_destroy_cb (BonoboControl *control, - gpointer user_data) -{ - GtkWidget *folder_browser = user_data; - - control_list = g_list_remove (control_list, control); - - gtk_object_destroy (GTK_OBJECT (folder_browser)); -} - -BonoboControl * -folder_browser_factory_new_control (const char *uri, - const Evolution_Shell shell) -{ - BonoboControl *control; - GtkWidget *folder_browser; - - folder_browser = folder_browser_new (shell); - if (folder_browser == NULL) - return NULL; - - if (!folder_browser_set_uri (FOLDER_BROWSER (folder_browser), uri)) { - gtk_object_sink (GTK_OBJECT (folder_browser)); - return NULL; - } - - gtk_widget_show (folder_browser); - - control = bonobo_control_new (folder_browser); - - if (control == NULL) { - gtk_object_destroy (GTK_OBJECT (folder_browser)); - return NULL; - } - - gtk_signal_connect (GTK_OBJECT (control), "activate", - control_activate_cb, folder_browser); - - gtk_signal_connect (GTK_OBJECT (control), "destroy", - control_destroy_cb, folder_browser); - - control_list = g_list_prepend (control_list, control); - - return control; -} - -GList * -folder_browser_factory_get_control_list (void) -{ - return control_list; -} diff --git a/mail/folder-browser-factory.h b/mail/folder-browser-factory.h deleted file mode 100644 index b47913a66a..0000000000 --- a/mail/folder-browser-factory.h +++ /dev/null @@ -1,21 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * folder-browser-factory.c: A Bonobo Control factory for Folder Browsers - * - * Author: - * Miguel de Icaza (miguel@helixcode.com) - * - * (C) 2000 Helix Code, Inc. - */ - -#ifndef _FOLDER_BROWSER_FACTORY_H -#define _FOLDER_BROWSER_FACTORY_H - -#include <bonobo.h> -#include "Evolution.h" - -BonoboControl *folder_browser_factory_new_control (const char *uri, - const Evolution_Shell shell); -GList *folder_browser_factory_get_control_list (void); - -#endif /* _FOLDER_BROWSER_FACTORY_H */ diff --git a/mail/folder-browser.c b/mail/folder-browser.c deleted file mode 100644 index 8727591cb6..0000000000 --- a/mail/folder-browser.c +++ /dev/null @@ -1,826 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * folder-browser.c: Folder browser top level component - * - * Author: - * Miguel de Icaza (miguel@kernel.org) - * - * (C) 2000 Helix Code, Inc. - */ -#include <config.h> -#include <ctype.h> -#include <gnome.h> -#include "e-util/e-sexp.h" -#include "folder-browser.h" -#include "mail.h" -#include "mail-callbacks.h" -#include "mail-tools.h" -#include "message-list.h" -#include "mail-threads.h" -#include "mail-ops.h" -#include "mail-vfolder.h" -#include "mail-autofilter.h" -#include "mail-mlist-magic.h" - -#include <gal/util/e-util.h> -#include <gal/widgets/e-unicode.h> -#include <gal/e-paned/e-vpaned.h> - -#include "filter/vfolder-rule.h" -#include "filter/vfolder-context.h" -#include "filter/filter-option.h" -#include "filter/filter-input.h" - -#include "mail-search-dialogue.h" - -#include "mail-local.h" -#include "mail-config.h" - -#include <gal/widgets/e-popup-menu.h> - -#define PARENT_TYPE (gtk_table_get_type ()) - -static void fb_resize_cb (GtkWidget *w, GtkAllocation *a); - -static GtkObjectClass *folder_browser_parent_class; - -static void oc_destroy (gpointer obj, gpointer user) -{ - struct fb_ondemand_closure *oc = (struct fb_ondemand_closure *) obj; - - g_free (oc->path); - g_free (oc); -} - -static void -folder_browser_destroy (GtkObject *object) -{ - FolderBrowser *folder_browser; - CORBA_Environment ev; - - folder_browser = FOLDER_BROWSER (object); - - CORBA_exception_init (&ev); - - if (folder_browser->search_full) - gtk_object_unref((GtkObject *)folder_browser->search_full); - - if (folder_browser->shell != CORBA_OBJECT_NIL) - CORBA_Object_release (folder_browser->shell, &ev); - - g_free (folder_browser->uri); - - if (folder_browser->folder) { - mail_do_sync_folder (folder_browser->folder); - camel_object_unref (CAMEL_OBJECT (folder_browser->folder)); - } - - if (folder_browser->message_list) - bonobo_object_unref (BONOBO_OBJECT (folder_browser->message_list)); - - if (folder_browser->mail_display) - gtk_widget_destroy (GTK_WIDGET (folder_browser->mail_display)); - - if (folder_browser->filter_context) - gtk_object_unref (GTK_OBJECT (folder_browser->filter_context)); - - if (folder_browser->filter_menu_paths) { - g_slist_foreach (folder_browser->filter_menu_paths, oc_destroy, NULL); - g_slist_free (folder_browser->filter_menu_paths); - } - - CORBA_exception_free (&ev); - - folder_browser_parent_class->destroy (object); -} - -static void -folder_browser_class_init (GtkObjectClass *object_class) -{ - object_class->destroy = folder_browser_destroy; - - folder_browser_parent_class = gtk_type_class (PARENT_TYPE); -} - -/* - * static gboolean - * folder_browser_load_folder (FolderBrowser *fb, const char *name) - * { - * CamelFolder *new_folder; - * - * new_folder = mail_tool_uri_to_folder_noex (name); - * - * if (!new_folder) - * return FALSE; - * - * if (fb->folder) - * camel_object_unref (CAMEL_OBJECT (fb->folder)); - * fb->folder = new_folder; - * message_list_set_folder (fb->message_list, new_folder); - * return TRUE; - * } - */ - -#define EQUAL(a,b) (strcmp (a,b) == 0) - -gboolean folder_browser_set_uri (FolderBrowser *folder_browser, const char *uri) -{ - if (*uri) - mail_do_load_folder (folder_browser, uri); - return TRUE; -} - -void -folder_browser_set_message_preview (FolderBrowser *folder_browser, gboolean show_message_preview) -{ - if (folder_browser->preview_shown == show_message_preview) - return; - - g_warning ("FIXME: implement me"); -} - -static char * search_options[] = { - N_("Body or subject contains"), - N_("Body contains"), - N_("Subject contains"), - N_("Body does not contain"), - N_("Subject does not contain"), - N_("Custom search"), - NULL -}; - -/* NOTE: If this is changed, then change the search_save() function to match! */ -/* %s is replaced by the whole search string in quotes ... - possibly could split the search string into words as well ? */ -static char * search_string[] = { - "(or (body-contains %s) (match-all (header-contains \"Subject\" %s)))", - "(body-contains %s)", - "(match-all (header-contains \"Subject\" %s)", - "(match-all (not (body-contains %s)))", - "(match-all (not (header-contains \"Subject\" %s)))", - "%s", -}; -#define CUSTOM_SEARCH_ID (5) - -static void -search_full_clicked(MailSearchDialogue *msd, guint button, FolderBrowser *fb) -{ - char *query; - - switch (button) { - case 0: /* 'ok' */ - case 1: /* 'search' */ - query = mail_search_dialogue_get_query(msd); - message_list_set_search(fb->message_list, query); - g_free(query); - /* save the search as well */ - if (fb->search_full) - gtk_object_unref((GtkObject *)fb->search_full); - fb->search_full = msd->rule; - gtk_object_ref((GtkObject *)fb->search_full); - if (button == 0) - gnome_dialog_close((GnomeDialog *)msd); - break; - case 2: /* 'cancel' */ - gnome_dialog_close((GnomeDialog *)msd); - case -1: /* dialogue closed */ - message_list_set_search(fb->message_list, 0); - /* reset the search buttons state */ - gtk_menu_set_active(GTK_MENU(GTK_OPTION_MENU(fb->search_menu)->menu), 0); - gtk_widget_set_sensitive(fb->search_entry, TRUE); - break; - } -} - -/* bring up the 'full search' dialogue and let the user use that to search with */ -static void -search_full(GtkWidget *w, FolderBrowser *fb) -{ - MailSearchDialogue *msd; - - /* make search dialogue thingy match */ - gtk_menu_set_active(GTK_MENU(GTK_OPTION_MENU(fb->search_menu)->menu), CUSTOM_SEARCH_ID); - gtk_widget_set_sensitive(fb->search_entry, FALSE); - - msd = mail_search_dialogue_new_with_rule(fb->search_full); - gtk_signal_connect((GtkObject *)msd, "clicked", search_full_clicked, fb); - gtk_widget_show((GtkWidget*)msd); -} - -static void -search_set(FolderBrowser *fb) -{ - GtkWidget *widget; - GString *out; - char *str; - int index; - char *text; - - widget = gtk_menu_get_active (GTK_MENU(GTK_OPTION_MENU(fb->search_menu)->menu)); - index = (int)gtk_object_get_data((GtkObject *)widget, "search_option"); - if (index == CUSTOM_SEARCH_ID) { - search_full(NULL, fb); - return; - } - gtk_widget_set_sensitive(fb->search_entry, TRUE); - - text = e_utf8_gtk_entry_get_text((GtkEntry *)fb->search_entry); - - if (text == NULL || text[0] == 0) { - if (text) - g_free(text); - message_list_set_search(fb->message_list, NULL); - return; - } - - if (index > sizeof(search_string)/sizeof(search_string[0])) - index = 0; - str = search_string[index]; - - out = g_string_new(""); - while (*str) { - if (str[0] == '%' && str[1]=='s') { - str+=2; - e_sexp_encode_string(out, text); - } else { - g_string_append_c(out, *str); - str++; - } - } - message_list_set_search(fb->message_list, out->str); - g_string_free(out, TRUE); - - g_free (text); -} - -static void -search_menu_deactivate(GtkWidget *menu, FolderBrowser *fb) -{ - search_set(fb); -} - -static GtkWidget * -create_option_menu (char **menu_list, int item, void *data) -{ - GtkWidget *omenu; - GtkWidget *menu; - int i = 0; - - omenu = gtk_option_menu_new (); - menu = gtk_menu_new (); - while (*menu_list){ - GtkWidget *entry; - - /* We don't use e_utf8_gtk_menu_item_new_with_label here - * because the string comes from gettext and so is localized, - * not UTF-8. - */ - entry = gtk_menu_item_new_with_label (_(*menu_list)); - gtk_widget_show (entry); - gtk_object_set_data((GtkObject *)entry, "search_option", (void *)i); - gtk_menu_append (GTK_MENU (menu), entry); - menu_list++; - i++; - } - gtk_option_menu_set_menu (GTK_OPTION_MENU (omenu), menu); - gtk_option_menu_set_history (GTK_OPTION_MENU (omenu), item); - gtk_widget_show (omenu); - - gtk_signal_connect (GTK_OBJECT (menu), - "deactivate", - GTK_SIGNAL_FUNC (search_menu_deactivate), data); - - return omenu; -} - -static void -search_activate(GtkEntry *entry, FolderBrowser *fb) -{ - search_set(fb); -} - -static void -search_save(GtkWidget *w, FolderBrowser *fb) -{ - GtkWidget *widget; - int index; - char *text; - FilterElement *element; - VfolderRule *rule; - FilterPart *part; - - text = e_utf8_gtk_entry_get_text((GtkEntry *)fb->search_entry); - - widget = gtk_menu_get_active (GTK_MENU(GTK_OPTION_MENU(fb->search_menu)->menu)); - index = (int)gtk_object_get_data((GtkObject *)widget, "search_option"); - - /* some special case code for the custom search position */ - if (index == CUSTOM_SEARCH_ID) { - g_free(text); - text = g_strdup(_("Custom")); - } else { - if (text == NULL || text[0] == 0) { - g_free (text); - return; - } - } - - rule = vfolder_rule_new(); - ((FilterRule *)rule)->grouping = FILTER_GROUP_ANY; - vfolder_rule_add_source(rule, fb->uri); - filter_rule_set_name((FilterRule *)rule, text); - switch(index) { - case 5: /* custom search */ - if (fb->search_full) { - GList *partl; - - /* copy the parts from the search rule to the vfolder rule */ - partl = fb->search_full->parts; - while (partl) { - FilterPart *old = partl->data; - part = filter_part_clone(old); - filter_rule_add_part((FilterRule *)rule, part); - partl = g_list_next(partl); - } - break; - } - default: /* header or body contains */ - index = 0; - case 1: case 2: - if (index == 0 || index == 1) { /* body-contains */ - part = vfolder_create_part("body"); - filter_rule_add_part((FilterRule *)rule, part); - element = filter_part_find_element(part, "body-type"); - filter_option_set_current((FilterOption *)element, "contains"); - element = filter_part_find_element(part, "word"); - filter_input_set_value((FilterInput *)element, text); - } - if (index == 0 || index == 2) { /* subject contains */ - part = vfolder_create_part("subject"); - filter_rule_add_part((FilterRule *)rule, part); - element = filter_part_find_element(part, "subject-type"); - filter_option_set_current((FilterOption *)element, "contains"); - element = filter_part_find_element(part, "subject"); - filter_input_set_value((FilterInput *)element, text); - } - break; - case 3: /* not body contains */ - part = vfolder_create_part("body"); - filter_rule_add_part((FilterRule *)rule, part); - element = filter_part_find_element(part, "body-type"); - filter_option_set_current((FilterOption *)element, "not contains"); - element = filter_part_find_element(part, "word"); - filter_input_set_value((FilterInput *)element, text); - break; - case 4: /* not header contains */ - part = vfolder_create_part("subject"); - filter_rule_add_part((FilterRule *)rule, part); - element = filter_part_find_element(part, "subject-type"); - filter_option_set_current((FilterOption *)element, "not contains"); - element = filter_part_find_element(part, "subject"); - filter_input_set_value((FilterInput *)element, text); - break; - - } - - vfolder_gui_add_rule(rule); - - g_free (text); -} - -void -folder_browser_clear_search (FolderBrowser *fb) -{ - gtk_entry_set_text (GTK_ENTRY (fb->search_entry), ""); - gtk_option_menu_set_history (GTK_OPTION_MENU (fb->search_menu), 0); - message_list_set_search(fb->message_list, NULL); -} - -void -folder_browser_toggle_threads (BonoboUIComponent *component, - const char *path, - Bonobo_UIComponent_EventType type, - const char *state, - gpointer user_data) -{ - FolderBrowser *fb = user_data; - - if (type != Bonobo_UIComponent_STATE_CHANGED) - return; - - mail_config_set_thread_list(atoi(state)); - message_list_set_threaded(fb->message_list, atoi(state)); -} - -void -vfolder_subject(GtkWidget *w, FolderBrowser *fb) -{ - vfolder_gui_add_from_message(fb->mail_display->current_message, AUTO_SUBJECT, - fb->uri); -} - -void -vfolder_sender(GtkWidget *w, FolderBrowser *fb) -{ - vfolder_gui_add_from_message(fb->mail_display->current_message, AUTO_FROM, - fb->uri); -} - -void -vfolder_recipient(GtkWidget *w, FolderBrowser *fb) -{ - vfolder_gui_add_from_message(fb->mail_display->current_message, AUTO_TO, - fb->uri); -} - -void -filter_subject(GtkWidget *w, FolderBrowser *fb) -{ - filter_gui_add_from_message(fb->mail_display->current_message, AUTO_SUBJECT); -} - -void -filter_sender(GtkWidget *w, FolderBrowser *fb) -{ - filter_gui_add_from_message(fb->mail_display->current_message, AUTO_FROM); -} - -void -filter_recipient(GtkWidget *w, FolderBrowser *fb) -{ - filter_gui_add_from_message(fb->mail_display->current_message, AUTO_TO); -} - -void -filter_mlist (GtkWidget *w, FolderBrowser *fb) -{ - char *name; - char *header_value; - const char *header_name; - - name = mail_mlist_magic_detect_list (fb->mail_display->current_message, &header_name, &header_value); - if (name == NULL) - return; - - filter_gui_add_for_mailing_list (fb->mail_display->current_message, name, header_name, header_value); - - g_free (name); - g_free (header_value); -} - -/* handle context menu over message-list */ -static gint -on_right_click (ETableScrolled *table, gint row, gint col, GdkEvent *event, FolderBrowser *fb) -{ - extern CamelFolder *drafts_folder; - const CamelMessageInfo *info; - GPtrArray *uids; - int enable_mask = 0; - int last_item, i; - char *mailing_list_name; - EPopupMenu menu[] = { - { _("Open"), NULL, GTK_SIGNAL_FUNC (view_msg), 0 }, - { _("Edit"), NULL, GTK_SIGNAL_FUNC (edit_msg), 1 }, - { _("Print"), NULL, GTK_SIGNAL_FUNC (print_msg), 0 }, - { "", NULL, GTK_SIGNAL_FUNC (NULL), 0 }, - { _("Reply to Sender"), NULL, GTK_SIGNAL_FUNC (reply_to_sender), 0 }, - { _("Reply to All"), NULL, GTK_SIGNAL_FUNC (reply_to_all), 0 }, - { _("Forward"), NULL, GTK_SIGNAL_FUNC (forward_msg), 0 }, - /*{ _("Forward as Attachment"), NULL, GTK_SIGNAL_FUNC (forward_msg), 0 },*/ - { "", NULL, GTK_SIGNAL_FUNC (NULL), 0 }, - { _("Mark as Read"), NULL, GTK_SIGNAL_FUNC (mark_as_seen), 4 }, - { _("Mark as Unread"), NULL, GTK_SIGNAL_FUNC (mark_as_unseen), 8 }, - { "", NULL, GTK_SIGNAL_FUNC (NULL), 0 }, - { _("Move to Folder..."), NULL, GTK_SIGNAL_FUNC (move_msg), 0 }, - { _("Copy to Folder..."), NULL, GTK_SIGNAL_FUNC (copy_msg), 0 }, - { _("Delete"), NULL, GTK_SIGNAL_FUNC (delete_msg), 16 }, - { _("Undelete"), NULL, GTK_SIGNAL_FUNC (undelete_msg), 32 }, - { "", NULL, GTK_SIGNAL_FUNC (NULL), 0 }, - /*{ _("Add Sender to Address Book"), NULL, GTK_SIGNAL_FUNC (addrbook_sender), 0 }, - { "", NULL, GTK_SIGNAL_FUNC (NULL), 0 },*/ - { _("Apply Filters"), NULL, GTK_SIGNAL_FUNC (apply_filters), 0 }, - { "", NULL, GTK_SIGNAL_FUNC (NULL), 0 }, - { _("VFolder on Subject"), NULL, GTK_SIGNAL_FUNC (vfolder_subject), 2 }, - { _("VFolder on Sender"), NULL, GTK_SIGNAL_FUNC (vfolder_sender), 2 }, - { _("VFolder on Recipients"), NULL, GTK_SIGNAL_FUNC (vfolder_recipient), 2 }, - { "", NULL, GTK_SIGNAL_FUNC (NULL), 0 }, - { _("Filter on Subject"), NULL, GTK_SIGNAL_FUNC (filter_subject), 2 }, - { _("Filter on Sender"), NULL, GTK_SIGNAL_FUNC (filter_sender), 2 }, - { _("Filter on Recipients"), NULL, GTK_SIGNAL_FUNC (filter_recipient), 2 }, - { _("Filter on Mailing List"), NULL, GTK_SIGNAL_FUNC (filter_mlist), 66 }, - { NULL, NULL, NULL, 0 } - }; - - /* Evil Hack. */ - - last_item = (sizeof (menu) / sizeof (*menu)) - 2; - - if (fb->folder != drafts_folder) - enable_mask |= 1; - - if (fb->mail_display->current_message == NULL) { - enable_mask |= 2; - mailing_list_name = NULL; - } else { - mailing_list_name = mail_mlist_magic_detect_list (fb->mail_display->current_message, - NULL, NULL); - } - - /* get a list of uids */ - uids = g_ptr_array_new (); - message_list_foreach (fb->message_list, enumerate_msg, uids); - if (uids->len >= 1) { - /* gray-out any items we don't need */ - gboolean have_deleted = FALSE; - gboolean have_undeleted = FALSE; - gboolean have_seen = FALSE; - gboolean have_unseen = FALSE; - - for (i = 0; i < uids->len; i++) { - info = camel_folder_get_message_info (fb->folder, uids->pdata[i]); - if (info->flags & CAMEL_MESSAGE_SEEN) - have_seen = TRUE; - else - have_unseen = TRUE; - - if (info->flags & CAMEL_MESSAGE_DELETED) - have_deleted = TRUE; - else - have_undeleted = TRUE; - - if (have_seen && have_unseen && have_deleted && have_undeleted) - break; - } - - if (!have_unseen) - enable_mask |= 4; - if (!have_seen) - enable_mask |= 8; - - if (!have_undeleted) - enable_mask |= 16; - if (!have_deleted) - enable_mask |= 32; - } - - if (mailing_list_name == NULL) { - enable_mask |= 64; - menu[last_item].name = g_strdup (_("Filter on Mailing List")); - } else { - menu[last_item].name = g_strdup_printf (_("Filter on Mailing List (%s)"), - mailing_list_name); - } - - /* free uids */ - for (i = 0; i < uids->len; i++) - g_free (uids->pdata[i]); - g_ptr_array_free (uids, TRUE); - - e_popup_menu_run (menu, (GdkEventButton *)event, enable_mask, 0, fb); - - g_free (menu[last_item].name); - - return TRUE; -} - -static int -etable_key (ETable *table, int row, int col, GdkEvent *ev, FolderBrowser *fb) -{ - if ((ev->key.state & !(GDK_SHIFT_MASK | GDK_LOCK_MASK)) != 0) - return FALSE; - - switch (ev->key.keyval) { - case GDK_space: - case GDK_BackSpace: - { - GtkAdjustment *vadj; - gfloat page_size; - - vadj = e_scroll_frame_get_vadjustment (fb->mail_display->scroll); - page_size = vadj->page_size - vadj->step_increment; - - if (ev->key.keyval == GDK_BackSpace) { - if (vadj->value > vadj->lower + page_size) - vadj->value -= page_size; - else - vadj->value = vadj->lower; - } else { - if (vadj->value < vadj->upper - vadj->page_size - page_size) - vadj->value += page_size; - else - vadj->value = vadj->upper - vadj->page_size; - } - - gtk_adjustment_value_changed (vadj); - return TRUE; - } - - case GDK_Delete: - case GDK_KP_Delete: - delete_msg (NULL, fb); - message_list_select (fb->message_list, row, - MESSAGE_LIST_SELECT_NEXT, - 0, CAMEL_MESSAGE_DELETED); - return TRUE; - - case GDK_Home: - case GDK_KP_Home: - message_list_select(fb->message_list, 0, MESSAGE_LIST_SELECT_NEXT, 0, 0); - return TRUE; - - case GDK_End: - case GDK_KP_End: - message_list_select(fb->message_list, -1, MESSAGE_LIST_SELECT_PREVIOUS, 0, 0); - return TRUE; - - case 'n': - case 'N': - message_list_select (fb->message_list, row, - MESSAGE_LIST_SELECT_NEXT, - 0, CAMEL_MESSAGE_SEEN); - return TRUE; - - case 'p': - case 'P': - message_list_select (fb->message_list, row, - MESSAGE_LIST_SELECT_PREVIOUS, - 0, CAMEL_MESSAGE_SEEN); - return TRUE; - - default: - return FALSE; - } - - return FALSE; -} - -static void -on_double_click (ETableScrolled *table, gint row, FolderBrowser *fb) -{ - view_msg (NULL, fb); -} - -static void -folder_browser_gui_init (FolderBrowser *fb) -{ - GtkWidget *hbox, *label; - GtkButton *button, *searchbutton; - GtkWidget *search_alignment, *save_alignment; - - /* - * The panned container - */ - fb->vpaned = e_vpaned_new (); - gtk_widget_show (fb->vpaned); - - gtk_table_attach ( - GTK_TABLE (fb), fb->vpaned, - 0, 1, 1, 3, - GTK_FILL | GTK_EXPAND, - GTK_FILL | GTK_EXPAND, - 0, 0); - - /* quick-search entry */ - hbox = gtk_hbox_new(FALSE, 3); - gtk_widget_show(hbox); - fb->search_entry = gtk_entry_new(); - gtk_widget_show(fb->search_entry); - gtk_signal_connect(GTK_OBJECT (fb->search_entry), "activate", search_activate, fb); - search_alignment = gtk_alignment_new(.5, .5, 0, 0); - gtk_widget_show(search_alignment); - searchbutton = (GtkButton *)gtk_button_new_with_label(_("Full Search")); - gtk_widget_show((GtkWidget *)searchbutton); - label = gtk_label_new(_("Search")); - gtk_widget_show(label); - fb->search_menu = create_option_menu(search_options, 0, fb); - button = (GtkButton *)gtk_button_new_with_label(_("Save")); - gtk_widget_show((GtkWidget *)button); - save_alignment = gtk_alignment_new(.5, .5, 0, 0); - gtk_widget_show(save_alignment); - gtk_signal_connect((GtkObject *)button, "clicked", search_save, fb); - gtk_signal_connect((GtkObject *)searchbutton, "clicked", search_full, fb); - gtk_container_add(GTK_CONTAINER(save_alignment), GTK_WIDGET(button)); - gtk_box_pack_end((GtkBox *)hbox, save_alignment, FALSE, FALSE, 3); - gtk_box_pack_end((GtkBox *)hbox, fb->search_entry, FALSE, FALSE, 3); - gtk_box_pack_end((GtkBox *)hbox, fb->search_menu, FALSE, FALSE, 3); - gtk_box_pack_end((GtkBox *)hbox, label, FALSE, FALSE, 3); - gtk_container_add(GTK_CONTAINER(search_alignment), GTK_WIDGET(searchbutton)); - gtk_box_pack_end((GtkBox *)hbox, search_alignment, FALSE, FALSE, 3); - gtk_table_attach ( - GTK_TABLE (fb), hbox, - 0, 1, 0, 1, - GTK_FILL | GTK_EXPAND, - 0, - 0, 0); - - fb->message_list_w = message_list_get_widget (fb->message_list); - e_paned_add1 (E_PANED (fb->vpaned), fb->message_list_w); - gtk_widget_show (fb->message_list_w); - - gtk_signal_connect (GTK_OBJECT (fb->message_list_w), "size_allocate", - GTK_SIGNAL_FUNC (fb_resize_cb), NULL); - - e_paned_add2 (E_PANED (fb->vpaned), GTK_WIDGET (fb->mail_display)); - e_paned_set_position (E_PANED (fb->vpaned), mail_config_paned_size()); - gtk_widget_show (GTK_WIDGET (fb->mail_display)); - gtk_widget_show (GTK_WIDGET (fb)); -} - -static gint -mark_msg_seen (gpointer data) -{ - MessageList *ml = data; - GPtrArray *uids; - - if (!ml->cursor_uid) - return FALSE; - - uids = g_ptr_array_new (); - g_ptr_array_add (uids, g_strdup (ml->cursor_uid)); - mail_do_flag_messages (ml->folder, uids, FALSE, - CAMEL_MESSAGE_SEEN, CAMEL_MESSAGE_SEEN); - return FALSE; -} - -static void -on_message_selected(MessageList *ml, const char *uid, FolderBrowser *fb) -{ - printf("selecting uid %s\n", uid); - mail_do_display_message(ml, fb->mail_display, uid, mark_msg_seen); -} - -static void -folder_browser_init (GtkObject *object) -{ -} - -static void -my_folder_browser_init (GtkObject *object) -{ - FolderBrowser *fb = FOLDER_BROWSER (object); - - /* - * Setup parent class fields. - */ - GTK_TABLE (fb)->homogeneous = FALSE; - gtk_table_resize (GTK_TABLE (fb), 1, 2); - - /* - * Our instance data - */ - fb->message_list = (MessageList *)message_list_new (); - fb->mail_display = (MailDisplay *)mail_display_new (); - - gtk_signal_connect (GTK_OBJECT (fb->message_list->etable), - "key_press", GTK_SIGNAL_FUNC (etable_key), fb); - - gtk_signal_connect (GTK_OBJECT (fb->message_list->etable), "right_click", - GTK_SIGNAL_FUNC (on_right_click), fb); - - gtk_signal_connect (GTK_OBJECT (fb->message_list->etable), "double_click", - GTK_SIGNAL_FUNC (on_double_click), fb); - - gtk_signal_connect (GTK_OBJECT(fb->message_list), "message_selected", - on_message_selected, fb); - - fb->filter_menu_paths = NULL; - fb->filter_context = NULL; - - folder_browser_gui_init (fb); -} - -GtkWidget * -folder_browser_new (const Evolution_Shell shell) -{ - static int serial = 0; - CORBA_Environment ev; - FolderBrowser *folder_browser; - - CORBA_exception_init (&ev); - - folder_browser = gtk_type_new (folder_browser_get_type ()); - - my_folder_browser_init (GTK_OBJECT (folder_browser)); - folder_browser->uri = NULL; - folder_browser->serial = serial++; - - folder_browser->shell = CORBA_Object_duplicate (shell, &ev); - if (ev._major != CORBA_NO_EXCEPTION) { - folder_browser->shell = CORBA_OBJECT_NIL; - gtk_widget_destroy (GTK_WIDGET (folder_browser)); - CORBA_exception_free (&ev); - return NULL; - } - - CORBA_exception_free (&ev); - - return GTK_WIDGET (folder_browser); -} - - -E_MAKE_TYPE (folder_browser, "FolderBrowser", FolderBrowser, folder_browser_class_init, folder_browser_init, PARENT_TYPE); - -static void fb_resize_cb (GtkWidget *w, GtkAllocation *a) -{ - mail_config_set_paned_size (a->height); -} diff --git a/mail/folder-browser.h b/mail/folder-browser.h deleted file mode 100644 index 6bddba18c5..0000000000 --- a/mail/folder-browser.h +++ /dev/null @@ -1,92 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - - -#ifndef _FOLDER_BROWSER_H_ -#define _FOLDER_BROWSER_H_ - -#include "mail-types.h" -#include <gtk/gtktable.h> -#include "camel/camel-stream.h" -#include <bonobo/bonobo-property-bag.h> -#include "filter/filter-rule.h" -#include "filter/filter-context.h" /*eek*/ -#include "message-list.h" -#include "mail-display.h" -#include "shell/Evolution.h" - - -#define FOLDER_BROWSER_TYPE (folder_browser_get_type ()) -#define FOLDER_BROWSER(o) (GTK_CHECK_CAST ((o), FOLDER_BROWSER_TYPE, FolderBrowser)) -#define FOLDER_BROWSER_CLASS(k) (GTK_CHECK_CLASS_CAST((k), FOLDER_BROWSER_TYPE, FolderBrowserClass)) -#define IS_FOLDER_BROWSER(o) (GTK_CHECK_TYPE ((o), FOLDER_BROWSER_TYPE)) -#define IS_FOLDER_BROWSER_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), FOLDER_BROWSER_TYPE)) - -struct _FolderBrowser { - GtkTable parent; - - BonoboPropertyBag *properties; - - Evolution_Shell shell; - - /* This is a kludge for the toolbar problem. */ - int serial; - - /* - * The current URI being displayed by the FolderBrowser - */ - char *uri; - CamelFolder *folder; - - MessageList *message_list; - GtkWidget *message_list_w; - MailDisplay *mail_display; - GtkWidget *vpaned; - GtkWidget *search_menu; - GtkWidget *search_entry; - FilterRule *search_full; /* if we have a full search active */ - - gboolean preview_shown; - - /* Stuff to allow on-demand filtering */ - GSList *filter_menu_paths; - FilterContext *filter_context; -}; - - -typedef struct { - GtkTableClass parent_class; -} FolderBrowserClass; - -struct fb_ondemand_closure { - FilterRule *rule; - FolderBrowser *fb; - gchar *path; -}; - -GtkType folder_browser_get_type (void); -GtkWidget *folder_browser_new (const Evolution_Shell shell); - -gboolean folder_browser_set_uri (FolderBrowser *folder_browser, - const char *uri); - -void folder_browser_set_message_preview (FolderBrowser *folder_browser, - gboolean show_message_preview); -void folder_browser_clear_search (FolderBrowser *fb); - -/* callbacks for functions on the folder-browser */ -void vfolder_subject (GtkWidget *w, FolderBrowser *fb); -void vfolder_sender (GtkWidget *w, FolderBrowser *fb); -void vfolder_recipient (GtkWidget *w, FolderBrowser *fb); - -void filter_subject (GtkWidget *w, FolderBrowser *fb); -void filter_sender (GtkWidget *w, FolderBrowser *fb); -void filter_recipient (GtkWidget *w, FolderBrowser *fb); -void filter_mlist (GtkWidget *w, FolderBrowser *fb); - -void folder_browser_toggle_threads (BonoboUIComponent *component, - const char *path, - Bonobo_UIComponent_EventType type, - const char *state, - gpointer user_data); - -#endif /* _FOLDER_BROWSER_H_ */ diff --git a/mail/local-config.glade b/mail/local-config.glade deleted file mode 100644 index 8f3a1a4cda..0000000000 --- a/mail/local-config.glade +++ /dev/null @@ -1,220 +0,0 @@ -<?xml version="1.0"?> -<GTK-Interface> - -<project> - <name>Mail</name> - <program_name>mail</program_name> - <directory></directory> - <source_directory>src</source_directory> - <pixmaps_directory>pixmaps</pixmaps_directory> - <language>C</language> - <gnome_support>True</gnome_support> - <gettext_support>True</gettext_support> -</project> - -<widget> - <class>GnomeDialog</class> - <name>dialog_format</name> - <type>GTK_WINDOW_TOPLEVEL</type> - <position>GTK_WIN_POS_NONE</position> - <modal>False</modal> - <allow_shrink>False</allow_shrink> - <allow_grow>False</allow_grow> - <auto_shrink>False</auto_shrink> - <auto_close>False</auto_close> - <hide_on_close>False</hide_on_close> - - <widget> - <class>GtkVBox</class> - <child_name>GnomeDialog:vbox</child_name> - <name>dialog-vbox1</name> - <homogeneous>False</homogeneous> - <spacing>8</spacing> - <child> - <padding>4</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkHButtonBox</class> - <child_name>GnomeDialog:action_area</child_name> - <name>dialog-action_area1</name> - <layout_style>GTK_BUTTONBOX_END</layout_style> - <spacing>8</spacing> - <child_min_width>85</child_min_width> - <child_min_height>27</child_min_height> - <child_ipad_x>7</child_ipad_x> - <child_ipad_y>0</child_ipad_y> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>True</fill> - <pack>GTK_PACK_END</pack> - </child> - - <widget> - <class>GtkButton</class> - <name>apply_format</name> - <can_default>True</can_default> - <can_focus>True</can_focus> - <stock_button>GNOME_STOCK_BUTTON_OK</stock_button> - </widget> - - <widget> - <class>GtkButton</class> - <name>cancel_format</name> - <can_default>True</can_default> - <can_focus>True</can_focus> - <stock_button>GNOME_STOCK_BUTTON_CANCEL</stock_button> - </widget> - </widget> - - <widget> - <class>GtkFrame</class> - <name>frame_format</name> - <label>Mailbox Format</label> - <label_xalign>0</label_xalign> - <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkTable</class> - <name>table1</name> - <border_width>2</border_width> - <rows>2</rows> - <columns>2</columns> - <homogeneous>False</homogeneous> - <row_spacing>0</row_spacing> - <column_spacing>2</column_spacing> - - <widget> - <class>GtkLabel</class> - <name>label2</name> - <label>New store format:</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>1</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>1</top_attach> - <bottom_attach>2</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>label1</name> - <label>Current store format:</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>1</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>0</top_attach> - <bottom_attach>1</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>label_format</name> - <label>mbox</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>7.45058e-09</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>0</top_attach> - <bottom_attach>1</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkOptionMenu</class> - <name>option_format</name> - <can_focus>True</can_focus> - <items>mh -mbox -</items> - <initial_choice>0</initial_choice> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>1</top_attach> - <bottom_attach>2</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - </widget> - </widget> - - <widget> - <class>GtkLabel</class> - <name>label4</name> - <label>Note: When converting between mailbox formats, a failure -(such as lack of disk space) may not be automatically -recoverable. Please use this feature with care.</label> - <justify>GTK_JUSTIFY_LEFT</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - </widget> -</widget> - -</GTK-Interface> diff --git a/mail/mail-autofilter.c b/mail/mail-autofilter.c deleted file mode 100644 index d4b537ab31..0000000000 --- a/mail/mail-autofilter.c +++ /dev/null @@ -1,343 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* mail-autofilter.c - * - * Copyright (C) 2000 Helix Code, Inc. - * - * 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 the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Authors: - * Michael Zucchi <notzed@helixcode.com> - * Ettore Perazzoli <ettore@helixcode.com> - */ - -/* Code for autogenerating rules or filters from a message. */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <ctype.h> - -#include <bonobo.h> - -#include <libgnomeui/gnome-app.h> -#include <libgnomeui/gnome-app-helper.h> -#include <libgnomeui/gnome-popup-menu.h> - -#include "mail-vfolder.h" -#include "mail-autofilter.h" - -#include "camel/camel.h" - -#include "filter/vfolder-context.h" -#include "filter/vfolder-rule.h" -#include "filter/vfolder-editor.h" - -#include "filter/filter-context.h" -#include "filter/filter-filter.h" -#include "filter/filter-editor.h" -#include "filter/filter-option.h" - -static void -rule_match_recipients (RuleContext *context, FilterRule *rule, CamelInternetAddress *iaddr) -{ - FilterPart *part; - FilterElement *element; - int i; - const char *real, *addr; - char *namestr; - - /* address types etc should handle multiple values */ - for (i = 0; camel_internet_address_get (iaddr, i, &real, &addr); i++) { - part = rule_context_create_part (context, "to"); - filter_rule_add_part ((FilterRule *)rule, part); - element = filter_part_find_element (part, "recipient-type"); - filter_option_set_current ((FilterOption *)element, "contains"); - element = filter_part_find_element (part, "recipient"); - filter_input_set_value ((FilterInput *)element, addr); - - namestr = g_strdup_printf (_("Mail to %s"), real && real[0] ? real : addr); - filter_rule_set_name (rule, namestr); - g_free (namestr); - } -} - - -/* remove 're' part of a subject */ -static const char * -strip_re (const char *subject) -{ - const unsigned char *s, *p; - - s = (unsigned char *) subject; - - while (*s) { - while (isspace (*s)) - s++; - if (s[0] == 0) - break; - if ((s[0] == 'r' || s[0] == 'R') - && (s[1] == 'e' || s[1] == 'E')) { - p = s+2; - while (isdigit (*p) || (ispunct (*p) && (*p != ':'))) - p++; - if (*p == ':') { - s = p + 1; - } else - break; - } else - break; - } - return (char *) s; -} - -#if 0 -int -reg_match (char *str, char *regstr) -{ - regex_t reg; - int error; - int ret; - - error = regcomp(®, regstr, REG_EXTENDED|REG_ICASE|REG_NOSUB); - if (error != 0) { - return 0; - } - error = regexec(®, str, 0, NULL, 0); - regfree(®); - return (error == 0); -} -#endif - -static void -rule_add_subject (RuleContext *context, FilterRule *rule, const char *text) -{ - FilterPart *part; - FilterElement *element; - - /* dont match on empty strings ever */ - if (*text == 0) - return; - part = rule_context_create_part (context, "subject"); - filter_rule_add_part ((FilterRule *)rule, part); - element = filter_part_find_element (part, "subject-type"); - filter_option_set_current ((FilterOption *)element, "is"); - element = filter_part_find_element (part, "subject"); - filter_input_set_value ((FilterInput *)element, text); -} - -static void -rule_add_sender (RuleContext *context, FilterRule *rule, const char *text) -{ - FilterPart *part; - FilterElement *element; - - /* dont match on empty strings ever */ - if (*text == 0) - return; - part = rule_context_create_part (context, "sender"); - filter_rule_add_part ((FilterRule *)rule, part); - element = filter_part_find_element (part, "sender-type"); - filter_option_set_current ((FilterOption *)element, "contains"); - element = filter_part_find_element (part, "sender"); - filter_input_set_value ((FilterInput *)element, text); -} - -/* do a bunch of things on the subject to try and detect mailing lists, remove - unneeded stuff, etc */ -static void -rule_match_subject (RuleContext *context, FilterRule *rule, const char *subject) -{ - const char *s; - const char *s1, *s2; - char *tmp; - - s = strip_re (subject); - /* dont match on empty subject */ - if (*s == 0) - return; - - /* [blahblah] is probably a mailing list, match on it separately */ - s1 = strchr (s, '['); - s2 = strchr (s, ']'); - if (s1 && s2 && s1 < s2) { - /* probably a mailing list, match on the mailing list name */ - tmp = alloca (s2 - s1 + 2); - memcpy (tmp, s1, s2 - s1 + 1); - tmp[s2 - s1 + 1] = 0; - g_strstrip (tmp); - rule_add_subject (context, rule, tmp); - s = s2 + 1; - } - /* Froblah: at the start is probably something important (e.g. bug number) */ - s1 = strchr (s, ':'); - if (s1) { - tmp = alloca (s1 - s + 1); - memcpy (tmp, s, s1-s); - tmp[s1 - s] = 0; - g_strstrip (tmp); - rule_add_subject (context, rule, tmp); - s = s1+1; - } - - /* just lump the rest together */ - tmp = alloca (strlen (s) + 1); - strcpy (tmp, s); - g_strstrip (tmp); - rule_add_subject (context, rule, tmp); -} - -static void -rule_from_message (FilterRule *rule, RuleContext *context, CamelMimeMessage *msg, int flags) -{ - CamelInternetAddress *addr; - - rule->grouping = FILTER_GROUP_ANY; - - if (flags & AUTO_SUBJECT) { - char *namestr; - - rule_match_subject (context, rule, msg->subject); - - namestr = g_strdup_printf (_("Subject is %s"), strip_re (msg->subject)); - filter_rule_set_name (rule, namestr); - g_free (namestr); - } - /* should parse the from address into an internet address? */ - if (flags & AUTO_FROM) { - struct _header_address *haddr, *scan; - char *name, *namestr; - - haddr = header_address_decode (msg->from); - scan = haddr; - while (scan) { - if (scan->type == HEADER_ADDRESS_NAME) { - rule_add_sender (context, rule, scan->v.addr); - if (scan->name && scan->name[0]) - name = scan->name; - else - name = scan->v.addr; - namestr = g_strdup_printf (_("Mail from %s"), name); - filter_rule_set_name (rule, namestr); - g_free (namestr); - } - scan = scan->next; - } - header_address_unref (haddr); - } - if (flags & AUTO_TO) { - addr = (CamelInternetAddress *)camel_mime_message_get_recipients (msg, CAMEL_RECIPIENT_TYPE_TO); - rule_match_recipients (context, rule, addr); - addr = (CamelInternetAddress *)camel_mime_message_get_recipients (msg, CAMEL_RECIPIENT_TYPE_CC); - rule_match_recipients (context, rule, addr); - } -} - -FilterRule * -vfolder_rule_from_message (VfolderContext *context, CamelMimeMessage *msg, int flags, const char *source) -{ - VfolderRule *rule; - - rule = vfolder_rule_new (); - vfolder_rule_add_source (rule, source); - rule_from_message ((FilterRule *)rule, (RuleContext *)context, msg, flags); - - return (FilterRule *)rule; -} - -FilterRule * -filter_rule_from_message(FilterContext *context, CamelMimeMessage *msg, int flags) -{ - FilterFilter *rule; - - rule = filter_filter_new (); - rule_from_message ((FilterRule *)rule, (RuleContext *)context, msg, flags); - - /* should we define the default action? */ - - return (FilterRule *)rule; -} - -void -filter_gui_add_from_message (CamelMimeMessage *msg, int flags) -{ - FilterContext *fc; - char *userrules, *systemrules; - FilterRule *rule; - extern char *evolution_dir; - - fc = filter_context_new (); - userrules = g_strdup_printf ("%s/filters.xml", evolution_dir); - systemrules = g_strdup_printf ("%s/evolution/filtertypes.xml", EVOLUTION_DATADIR); - rule_context_load ((RuleContext *)fc, systemrules, userrules); - rule = filter_rule_from_message (fc, msg, flags); - - filter_rule_set_source (rule, FILTER_SOURCE_INCOMING); - - rule_context_add_rule_gui ((RuleContext *)fc, rule, _("Add Filter Rule"), userrules); - g_free (userrules); - g_free (systemrules); - gtk_object_unref (GTK_OBJECT (fc)); -} - -void -filter_gui_add_for_mailing_list (CamelMimeMessage *msg, - const char *list_name, - const char *header_name, - const char *header_value) -{ - FilterContext *fc; - FilterRule *rule; - FilterPart *part; - FilterElement *element; - char *userrules, *systemrules; - char *rule_name; - extern char *evolution_dir; - - g_return_if_fail (msg != NULL); - g_return_if_fail (CAMEL_IS_MIME_MESSAGE (msg)); - g_return_if_fail (list_name != NULL); - g_return_if_fail (header_name != NULL); - g_return_if_fail (header_value != NULL); - - fc = filter_context_new (); - userrules = g_strdup_printf ("%s/filters.xml", evolution_dir); - systemrules = g_strdup_printf ("%s/evolution/filtertypes.xml", EVOLUTION_DATADIR); - rule_context_load ((RuleContext *)fc, systemrules, userrules); - - rule = (FilterRule *) filter_filter_new (); - - part = rule_context_create_part ((RuleContext *)fc, "header"); - filter_rule_add_part ((FilterRule *)rule, part); - - element = filter_part_find_element (part, "header-field"); - filter_input_set_value ((FilterInput *)element, header_name); - - element = filter_part_find_element (part, "header-type"); - filter_option_set_current ((FilterOption *)element, "is"); - - element = filter_part_find_element (part, "word"); - filter_input_set_value ((FilterInput *)element, header_value); - - rule_name = g_strdup_printf (_("%s mailing list"), list_name); - filter_rule_set_name ((FilterRule *) rule, rule_name); - g_free (rule_name); - - rule_context_add_rule_gui ((RuleContext *)fc, rule, _("Add Filter Rule"), userrules); - - g_free (userrules); - g_free (systemrules); - gtk_object_unref (GTK_OBJECT (fc)); -} diff --git a/mail/mail-autofilter.h b/mail/mail-autofilter.h deleted file mode 100644 index 5787b74c7c..0000000000 --- a/mail/mail-autofilter.h +++ /dev/null @@ -1,53 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* mail-autofilter.h - * - * Copyright (C) 2000 Helix Code, Inc. - * - * 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 the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Authors: - * Michael Zucchi <notzed@helixcode.com> - * Ettore Perazzoli <ettore@helixcode.com> - */ - -#ifndef _MAIL_AUTOFILTER_H -#define _MAIL_AUTOFILTER_H - -#include "filter/filter-rule.h" -#include "filter/filter-context.h" -#include "filter/vfolder-context.h" -#include "camel/camel-mime-message.h" - -enum { - AUTO_SUBJECT = 1, - AUTO_FROM = 2, - AUTO_TO = 4 -}; - -FilterRule *vfolder_rule_from_message(VfolderContext *context, CamelMimeMessage *msg, int flags, const char *source); -FilterRule *filter_rule_from_message(FilterContext *context, CamelMimeMessage *msg, int flags); - -/* easiest place to put this */ - -void filter_gui_add_from_message (CamelMimeMessage *msg, - int flags); - -void filter_gui_add_for_mailing_list (CamelMimeMessage *msg, - const char *list_name, - const char *header_name, - const char *header_value); - -#endif diff --git a/mail/mail-callbacks.c b/mail/mail-callbacks.c deleted file mode 100644 index b6a9f9bcea..0000000000 --- a/mail/mail-callbacks.c +++ /dev/null @@ -1,946 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* mail-ops.c: callbacks for the mail toolbar/menus */ - -/* - * Authors: - * Dan Winship <danw@helixcode.com> - * Peter Williams <peterw@helixcode.com> - * Jeffrey Stedfast <fejj@helixcode.com> - * - * Copyright 2000 Helix Code, Inc. (http://www.helixcode.com) - * - * 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 the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#include <config.h> -#include <errno.h> -#include <gnome.h> -#include <libgnomeprint/gnome-print-master.h> -#include <libgnomeprint/gnome-print-master-preview.h> -#include "mail.h" -#include "mail-callbacks.h" -#include "mail-config.h" -#include "mail-threads.h" -#include "mail-tools.h" -#include "mail-ops.h" -#include "mail-local.h" -#include "mail-vfolder.h" -#include "folder-browser.h" -#include "subscribe-dialog.h" -#include "filter/filter-editor.h" -#include "filter/filter-driver.h" -#include <gal/e-table/e-table.h> -#include <gal/widgets/e-gui-utils.h> - -/* FIXME: is there another way to do this? */ -#include "Evolution.h" -#include "evolution-storage.h" - -#include "evolution-shell-client.h" - -#ifndef HAVE_MKSTEMP -#include <fcntl.h> -#include <sys/stat.h> -#endif - -struct post_send_data { - CamelFolder *folder; - gchar *uid; - guint32 flags; -}; - -static gboolean -check_configured (FolderBrowser *fb) -{ - if (mail_config_is_configured ()) - return TRUE; - - if (fb) { - GtkWidget *dialog; - - dialog = gnome_message_box_new (_("You have not configured the mail client.\n" - "You need to do this before you can send,\n" - "receive or compose mail.\n" - "Would you like to configure it now?"), - GNOME_MESSAGE_BOX_QUESTION, - GNOME_STOCK_BUTTON_YES, - GNOME_STOCK_BUTTON_NO, NULL); - gnome_dialog_set_parent (GNOME_DIALOG (dialog), - GTK_WINDOW (gtk_widget_get_ancestor (GTK_WIDGET(fb), GTK_TYPE_WINDOW))); - - switch (gnome_dialog_run_and_close (GNOME_DIALOG (dialog))) { - case 0: - mail_config_druid (fb->shell); - break; - case 1: - default: - break; - } - - return mail_config_is_configured (); - } else - return FALSE; -} - -static gboolean -check_send_configuration (FolderBrowser *fb) -{ - MailConfigService *xport = NULL; - - /* Check general */ - - if (!check_configured (fb)) { - return FALSE; - } - - /* Check for an identity */ - - if (!mail_config_get_default_identity ()) { - GtkWidget *message; - - message = gnome_warning_dialog_parented (_("You need to configure an identity\n" - "before you can compose mail."), - GTK_WINDOW (gtk_widget_get_ancestor (GTK_WIDGET (fb), - GTK_TYPE_WINDOW))); - gnome_dialog_run_and_close (GNOME_DIALOG (message)); - return FALSE; - } - - /* Check for a transport */ - - xport = mail_config_get_transport (); - if (!xport || !xport->url) { - GtkWidget *message; - - message = gnome_warning_dialog_parented (_("You need to configure a mail transport\n" - "before you can compose mail."), - GTK_WINDOW (gtk_widget_get_ancestor (GTK_WIDGET (fb), - GTK_TYPE_WINDOW))); - gnome_dialog_run_and_close (GNOME_DIALOG (message)); - return FALSE; - } - - return TRUE; -} - -static void -main_select_first_unread (CamelObject *object, gpointer event_data, gpointer data) -{ - FolderBrowser *fb = FOLDER_BROWSER (data); - /*ETable *table = E_TABLE_SCROLLED (fb->message_list->etable)->table;*/ - - message_list_select (fb->message_list, 0, MESSAGE_LIST_SELECT_NEXT, - 0, CAMEL_MESSAGE_SEEN); -} - -static void -select_first_unread (CamelObject *object, gpointer event_data, gpointer data) -{ - mail_op_forward_event (main_select_first_unread, object, event_data, data); -} - -void -fetch_mail (GtkWidget *widget, gpointer user_data) -{ - GSList *sources; - - if (!check_configured (FOLDER_BROWSER (user_data))) { - GtkWidget *win = gtk_widget_get_ancestor (GTK_WIDGET (user_data), - GTK_TYPE_WINDOW); - - gnome_error_dialog_parented (_("You have no mail sources " - "configured"), - GTK_WINDOW (win)); - return; - } - - sources = mail_config_get_sources (); - - if (!sources || !sources->data) { - GtkWidget *win = gtk_widget_get_ancestor (GTK_WIDGET (user_data), - GTK_TYPE_WINDOW); - - gnome_error_dialog_parented (_("You have no mail sources " - "configured"), - GTK_WINDOW (win)); - return; - } - - while (sources) { - MailConfigService *source; - - source = (MailConfigService *) sources->data; - sources = sources->next; - - if (!source || !source->url) { - g_warning ("Bad source in fetch_mail??"); - continue; - } - - mail_do_fetch_mail (source->url, source->keep_on_server, - NULL, select_first_unread, user_data); - } -} - -void -send_queued_mail (GtkWidget *widget, gpointer user_data) -{ - extern CamelFolder *outbox_folder; - MailConfigService *transport; - - if (!mail_config_is_configured ()) { - return; - } - - transport = mail_config_get_transport (); - if (!transport) { - GtkWidget *win = gtk_widget_get_ancestor (GTK_WIDGET (user_data), - GTK_TYPE_WINDOW); - - gnome_error_dialog_parented (_("You have not set a mail transport method"), - GTK_WINDOW (win)); - return; - } - - if (!outbox_folder) { - GtkWidget *win = gtk_widget_get_ancestor (GTK_WIDGET (user_data), - GTK_TYPE_WINDOW); - - gnome_error_dialog_parented (_("You have no Outbox configured"), - GTK_WINDOW (win)); - return; - } - - mail_do_send_queue (outbox_folder, transport->url); - - mail_do_expunge_folder (outbox_folder); -} - -void -send_receieve_mail (GtkWidget *widget, gpointer user_data) -{ - /* receive first then send, this is a temp fix for POP-before-SMTP */ - fetch_mail (widget, user_data); - send_queued_mail (widget, user_data); -} - -static gboolean -ask_confirm_for_empty_subject (EMsgComposer *composer) -{ - GtkWidget *message_box; - int button; - - message_box = gnome_message_box_new (_("This message has no subject.\nReally send?"), - GNOME_MESSAGE_BOX_QUESTION, - GNOME_STOCK_BUTTON_YES, GNOME_STOCK_BUTTON_NO, - NULL); - - button = gnome_dialog_run_and_close (GNOME_DIALOG (message_box)); - - if (button == 0) - return TRUE; - else - return FALSE; -} - -static void -free_psd (GtkWidget *composer, gpointer user_data) -{ - struct post_send_data *psd = user_data; - - if (psd->folder) - camel_object_unref (CAMEL_OBJECT (psd->folder)); - if (psd->uid) - g_free (psd->uid); - g_free (psd); -} - -void -composer_send_cb (EMsgComposer *composer, gpointer data) -{ - MailConfigService *xport = NULL; - CamelMimeMessage *message; - const CamelInternetAddress *iaddr; - const char *subject; - struct post_send_data *psd = data; - - /* Config info */ - xport = mail_config_get_transport (); - - /* Get the message */ - message = e_msg_composer_get_message (composer); - - /* Check for no recipients */ - iaddr = camel_mime_message_get_recipients (message, CAMEL_RECIPIENT_TYPE_TO); - if (!iaddr || CAMEL_ADDRESS (iaddr)->addresses->len == 0) { - GtkWidget *message_box; - - message_box = gnome_message_box_new (_("You must specify recipients in order to send this message."), - GNOME_MESSAGE_BOX_WARNING, - GNOME_STOCK_BUTTON_OK, - NULL); - - gnome_dialog_run_and_close (GNOME_DIALOG (message_box)); - - camel_object_unref (CAMEL_OBJECT (message)); - return; - } - - /* Check for no subject */ - subject = camel_mime_message_get_subject (message); - if (subject == NULL || subject[0] == '\0') { - if (!ask_confirm_for_empty_subject (composer)) { - camel_object_unref (CAMEL_OBJECT (message)); - return; - } - } - - if (psd) { - mail_do_send_mail (xport->url, message, - psd->folder, psd->uid, psd->flags, - GTK_WIDGET (composer)); - } else { - mail_do_send_mail (xport->url, message, NULL, NULL, 0, - GTK_WIDGET (composer)); - } -} - -void -composer_postpone_cb (EMsgComposer *composer, gpointer data) -{ - extern CamelFolder *outbox_folder; - CamelMimeMessage *message; - struct post_send_data *psd = data; - const char *subject; - - /* Get the message */ - message = e_msg_composer_get_message (composer); - - /* Check for no subject */ - subject = camel_mime_message_get_subject (message); - if (subject == NULL || subject[0] == '\0') { - if (!ask_confirm_for_empty_subject (composer)) { - camel_object_unref (CAMEL_OBJECT (message)); - return; - } - } - - /* Save the message in Outbox */ - mail_do_append_mail (outbox_folder, message, NULL); - - if (psd) { - guint32 set; - - set = camel_folder_get_message_flags (psd->folder, psd->uid); - camel_folder_set_message_flags (psd->folder, psd->uid, - psd->flags, psd->flags); - } - - gtk_widget_destroy (GTK_WIDGET (composer)); -} - -static GtkWidget * -create_msg_composer (const char *url) -{ - MailConfigIdentity *id; - gboolean send_html; - gchar *sig_file = NULL; - EMsgComposer *composer; - - id = mail_config_get_default_identity (); - send_html = mail_config_send_html (); - - if (id) - sig_file = id->sig; - - if (url != NULL) - composer = e_msg_composer_new_from_url (url); - else - composer = e_msg_composer_new_with_sig_file (sig_file); - if (composer) - e_msg_composer_set_send_html (composer, send_html); - - return (GtkWidget *)composer; -} - -void -compose_msg (GtkWidget *widget, gpointer user_data) -{ - GtkWidget *composer; - - if (!check_send_configuration (FOLDER_BROWSER (user_data))) - return; - - composer = create_msg_composer (NULL); - if (!composer) - return; - - gtk_signal_connect (GTK_OBJECT (composer), "send", - GTK_SIGNAL_FUNC (composer_send_cb), NULL); - gtk_signal_connect (GTK_OBJECT (composer), "postpone", - GTK_SIGNAL_FUNC (composer_postpone_cb), NULL); - - gtk_widget_show (composer); -} - -/* Send according to a mailto (RFC 2368) URL. */ -void -send_to_url (const char *url) -{ - GtkWidget *composer; - - /* FIXME: no way to get folder browser? Not without - * big pain in the ass, as far as I can tell */ - if (!check_send_configuration (NULL)) - return; - - composer = create_msg_composer (url); - if (!composer) - return; - - gtk_signal_connect (GTK_OBJECT (composer), "send", - GTK_SIGNAL_FUNC (composer_send_cb), NULL); - gtk_signal_connect (GTK_OBJECT (composer), "postpone", - GTK_SIGNAL_FUNC (composer_postpone_cb), NULL); - - gtk_widget_show (composer); -} - -void -mail_reply (CamelFolder *folder, CamelMimeMessage *msg, const char *uid, gboolean to_all) -{ - EMsgComposer *composer; - struct post_send_data *psd; - - /* FIXME: I just don't feel like implementing the folder-browser-passing - * garbage. */ - /* FIXME: We really need some way to get the folder_browser into this - function */ - if (!check_send_configuration (NULL) || !folder || - !msg || !uid) - return; - - psd = g_new (struct post_send_data, 1); - psd->folder = folder; - camel_object_ref (CAMEL_OBJECT (psd->folder)); - psd->uid = g_strdup (uid); - psd->flags = CAMEL_MESSAGE_ANSWERED; - - composer = mail_generate_reply (msg, to_all); - if (!composer) - return; - - gtk_signal_connect (GTK_OBJECT (composer), "send", - GTK_SIGNAL_FUNC (composer_send_cb), psd); - gtk_signal_connect (GTK_OBJECT (composer), "postpone", - GTK_SIGNAL_FUNC (composer_postpone_cb), psd); - gtk_signal_connect (GTK_OBJECT (composer), "destroy", - GTK_SIGNAL_FUNC (free_psd), psd); - - gtk_widget_show (GTK_WIDGET (composer)); -} - -void -reply_to_sender (GtkWidget *widget, gpointer user_data) -{ - FolderBrowser *fb = FOLDER_BROWSER (user_data); - - if (!check_send_configuration (fb)) - return; - - mail_reply (fb->folder, fb->mail_display->current_message, - fb->message_list->cursor_uid, FALSE); -} - -void -reply_to_all (GtkWidget *widget, gpointer user_data) -{ - FolderBrowser *fb = FOLDER_BROWSER (user_data); - - if (!check_send_configuration (fb)) - return; - - mail_reply (fb->folder, fb->mail_display->current_message, - fb->message_list->cursor_uid, TRUE); -} - -void -enumerate_msg (MessageList *ml, const char *uid, gpointer data) -{ - g_ptr_array_add ((GPtrArray *) data, g_strdup (uid)); -} - - -void -forward_msg (GtkWidget *widget, gpointer user_data) -{ - FolderBrowser *fb = FOLDER_BROWSER (user_data); - EMsgComposer *composer; - CamelMimeMessage *cursor_msg; - GPtrArray *uids; - - cursor_msg = fb->mail_display->current_message; - if (!check_send_configuration (fb) || !cursor_msg) - return; - - composer = e_msg_composer_new (); - if (!composer) - return; - - uids = g_ptr_array_new(); - message_list_foreach (fb->message_list, enumerate_msg, uids); - - gtk_signal_connect (GTK_OBJECT (composer), "send", - GTK_SIGNAL_FUNC (composer_send_cb), NULL); - gtk_signal_connect (GTK_OBJECT (composer), "postpone", - GTK_SIGNAL_FUNC (composer_postpone_cb), NULL); - - mail_do_forward_message (cursor_msg, - fb->message_list->folder, - uids, - composer); -} - -static void -transfer_msg (GtkWidget *widget, gpointer user_data, gboolean delete_from_source) -{ - FolderBrowser *fb = user_data; - MessageList *ml = fb->message_list; - GPtrArray *uids; - char *uri, *physical, *path; - char *desc; - const char *allowed_types[] = { "mail", NULL }; - extern EvolutionShellClient *global_shell_client; - static char *last = NULL; - - if (last == NULL) - last = g_strdup (""); - - if (delete_from_source) - desc = _("Move message(s) to"); - else - desc = _("Copy message(s) to"); - - evolution_shell_client_user_select_folder (global_shell_client, - desc, - last, allowed_types, &uri, &physical); - if (!uri) - return; - - path = strchr (uri, '/'); - if (path && strcmp (last, path) != 0) { - g_free (last); - last = g_strdup (path); - } - g_free (uri); - - uids = g_ptr_array_new (); - message_list_foreach (ml, enumerate_msg, uids); - mail_do_transfer_messages (ml->folder, uids, delete_from_source, physical); -} - -void -move_msg (GtkWidget *widget, gpointer user_data) -{ - transfer_msg (widget, user_data, TRUE); -} - -void -copy_msg (GtkWidget *widget, gpointer user_data) -{ - transfer_msg (widget, user_data, FALSE); -} - -void -apply_filters (GtkWidget *widget, gpointer user_data) -{ - FolderBrowser *fb = FOLDER_BROWSER (user_data); - MessageList *ml = fb->message_list; - GPtrArray *uids; - - uids = g_ptr_array_new (); - message_list_foreach (ml, enumerate_msg, uids); - - mail_do_filter_ondemand (fb->folder, uids); -} - -void -select_all (BonoboUIComponent *uih, void *user_data, const char *path) -{ - FolderBrowser *fb = FOLDER_BROWSER (user_data); - MessageList *ml = fb->message_list; - ETableScrolled *scrolled; - - if (ml->folder == NULL) - return; - - scrolled = E_TABLE_SCROLLED (ml->etable); - e_table_select_all (scrolled->table); -} - -void -invert_selection (BonoboUIComponent *uih, void *user_data, const char *path) -{ - FolderBrowser *fb = FOLDER_BROWSER (user_data); - MessageList *ml = fb->message_list; - ETableScrolled *scrolled; - - if (ml->folder == NULL) - return; - - scrolled = E_TABLE_SCROLLED (ml->etable); - e_table_invert_selection (scrolled->table); -} - -void -mark_as_seen (BonoboUIComponent *uih, void *user_data, const char *path) -{ - FolderBrowser *fb = FOLDER_BROWSER(user_data); - MessageList *ml = fb->message_list; - GPtrArray *uids; - - if (ml->folder == NULL) - return; - - uids = g_ptr_array_new (); - message_list_foreach (ml, enumerate_msg, uids); - mail_do_flag_messages (ml->folder, uids, FALSE, - CAMEL_MESSAGE_SEEN, CAMEL_MESSAGE_SEEN); -} - -void -mark_as_unseen (BonoboUIComponent *uih, void *user_data, const char *path) -{ - FolderBrowser *fb = FOLDER_BROWSER(user_data); - MessageList *ml = fb->message_list; - GPtrArray *uids; - - if (ml->folder == NULL) - return; - - uids = g_ptr_array_new (); - message_list_foreach (ml, enumerate_msg, uids); - mail_do_flag_messages (ml->folder, uids, FALSE, - CAMEL_MESSAGE_SEEN, 0); -} - -void -edit_msg (GtkWidget *widget, gpointer user_data) -{ - FolderBrowser *fb = FOLDER_BROWSER (user_data); - GPtrArray *uids; - extern CamelFolder *drafts_folder; - - if (fb->folder != drafts_folder) { - GtkWidget *message; - - message = gnome_warning_dialog (_("You may only edit messages saved\n" - "in the Drafts folder.")); - gnome_dialog_run_and_close (GNOME_DIALOG (message)); - return; - } - - if (!check_send_configuration (fb)) - return; - - uids = g_ptr_array_new (); - message_list_foreach (fb->message_list, enumerate_msg, uids); - - /* FIXME: do we need to pass the postpone callback too? */ - mail_do_edit_messages (fb->folder, uids, (GtkSignalFunc) composer_send_cb); -} - -void -delete_msg (GtkWidget *button, gpointer user_data) -{ - FolderBrowser *fb = user_data; - MessageList *ml = fb->message_list; - GPtrArray *uids; - - uids = g_ptr_array_new (); - message_list_foreach (ml, enumerate_msg, uids); - - /* - * Toggling a flag is an "instantaneous" operation, so if - * we're only doing one, just do it and return, rather than - * queueing it for the other thread. This makes the "Delete" - * key work correctly (move to the next message) again. - * - Dan - */ - if (uids->len == 1) { - char *uid = uids->pdata[0]; - - mail_tool_camel_lock_up (); - camel_folder_set_message_flags (ml->folder, uid, - CAMEL_MESSAGE_DELETED, - CAMEL_MESSAGE_DELETED); - mail_tool_camel_lock_down (); - } else { - mail_do_flag_messages (ml->folder, uids, FALSE, - CAMEL_MESSAGE_DELETED, - CAMEL_MESSAGE_DELETED); - } -} - -void -undelete_msg (GtkWidget *button, gpointer user_data) -{ - FolderBrowser *fb = user_data; - MessageList *ml = fb->message_list; - GPtrArray *uids; - - uids = g_ptr_array_new (); - message_list_foreach (ml, enumerate_msg, uids); - - /* - * Toggling a flag is an "instantaneous" operation, so if - * we're only doing one, just do it and return, rather than - * queueing it for the other thread. This makes the "Delete" - * key work correctly (move to the next message) again. - * - Dan - */ - if (uids->len == 1) { - char *uid = uids->pdata[0]; - - mail_tool_camel_lock_up (); - camel_folder_set_message_flags (ml->folder, uid, - CAMEL_MESSAGE_DELETED, - 0); - mail_tool_camel_lock_down (); - } else { - mail_do_flag_messages (ml->folder, uids, FALSE, - CAMEL_MESSAGE_DELETED, - 0); - } -} - -void -expunge_folder (BonoboUIComponent *uih, void *user_data, const char *path) -{ - FolderBrowser *fb = FOLDER_BROWSER(user_data); - - e_table_model_pre_change (fb->message_list->table_model); - - if (fb->message_list->folder) - mail_do_expunge_folder (fb->message_list->folder); -} - -static void -filter_druid_clicked (GtkWidget *w, int button, FolderBrowser *fb) -{ - FilterContext *fc; - - if (button == 0) { - char *user; - - fc = gtk_object_get_data (GTK_OBJECT (w), "context"); - user = g_strdup_printf ("%s/filters.xml", evolution_dir); - rule_context_save ((RuleContext *)fc, user); - g_free (user); - } - - if (button != -1) { - gnome_dialog_close (GNOME_DIALOG (w)); - } -} - -void -filter_edit (BonoboUIComponent *uih, void *user_data, const char *path) -{ - FolderBrowser *fb = FOLDER_BROWSER (user_data); - FilterContext *fc; - char *user, *system; - GtkWidget *w; - - fc = filter_context_new (); - user = g_strdup_printf ("%s/filters.xml", evolution_dir); - system = g_strdup_printf ("%s/evolution/filtertypes.xml", EVOLUTION_DATADIR); - rule_context_load ((RuleContext *)fc, system, user); - g_free (user); - g_free (system); - - if (((RuleContext *)fc)->error) { - GtkWidget *dialog; - gchar *err; - - err = g_strdup_printf (_("Error loading filter information:\n%s"), - ((RuleContext *)fc)->error); - dialog = gnome_warning_dialog (err); - g_free (err); - - gnome_dialog_run_and_close (GNOME_DIALOG (dialog)); - return; - } - - w = filter_editor_construct (fc); - gtk_object_set_data_full (GTK_OBJECT (w), "context", fc, (GtkDestroyNotify)gtk_object_unref); - gtk_signal_connect (GTK_OBJECT (w), "clicked", filter_druid_clicked, fb); - gtk_widget_show (GTK_WIDGET (w)); -} - -void -vfolder_edit_vfolders (BonoboUIComponent *uih, void *user_data, const char *path) -{ - vfolder_edit (); -} - -void -providers_config (BonoboUIComponent *uih, void *user_data, const char *path) -{ - mail_config ((FOLDER_BROWSER (user_data))->shell); -} - -/* - * FIXME: This routine could be made generic, by having a closure - * function plus data, and having the whole process be taken care - * of for you - */ -static void -do_mail_print (MailDisplay *md, gboolean preview) -{ - GnomePrintContext *print_context; - GnomePrintMaster *print_master; - GnomePrintDialog *gpd; - GnomePrinter *printer = NULL; - int copies = 1; - int collate = FALSE; - - if (!preview){ - - gpd = GNOME_PRINT_DIALOG ( - gnome_print_dialog_new (_("Print Message"), GNOME_PRINT_DIALOG_COPIES)); - gnome_dialog_set_default (GNOME_DIALOG (gpd), GNOME_PRINT_PRINT); - - switch (gnome_dialog_run (GNOME_DIALOG (gpd))){ - case GNOME_PRINT_PRINT: - break; - - case GNOME_PRINT_PREVIEW: - preview = TRUE; - break; - - case -1: - return; - - default: - gnome_dialog_close (GNOME_DIALOG (gpd)); - return; - } - - gnome_print_dialog_get_copies (gpd, &copies, &collate); - printer = gnome_print_dialog_get_printer (gpd); - gnome_dialog_close (GNOME_DIALOG (gpd)); - } - - print_master = gnome_print_master_new (); - -/* FIXME: set paper size gnome_print_master_set_paper (print_master, */ - - if (printer) - gnome_print_master_set_printer (print_master, printer); - gnome_print_master_set_copies (print_master, copies, collate); - print_context = gnome_print_master_get_context (print_master); - gtk_html_print (md->html, print_context); - gnome_print_master_close (print_master); - - if (preview){ - gboolean landscape = FALSE; - GnomePrintMasterPreview *preview; - - preview = gnome_print_master_preview_new_with_orientation ( - print_master, _("Print Preview"), landscape); - gtk_widget_show (GTK_WIDGET (preview)); - } else { - int result = gnome_print_master_print (print_master); - - if (result == -1){ - e_notice (NULL, GNOME_MESSAGE_BOX_ERROR, - _("Printing of message failed")); - } - } - gtk_object_unref (GTK_OBJECT (print_master)); -} - -void -mail_print_preview_msg (MailDisplay *md) -{ - do_mail_print (md, TRUE); -} - -void -mail_print_msg (MailDisplay *md) -{ - do_mail_print (md, FALSE); -} - -void -print_msg (GtkWidget *button, gpointer user_data) -{ - FolderBrowser *fb = user_data; - - mail_print_msg (fb->mail_display); -} - -void -print_preview_msg (GtkWidget *button, gpointer user_data) -{ - FolderBrowser *fb = user_data; - - mail_print_preview_msg (fb->mail_display); -} - -void -manage_subscriptions (BonoboUIComponent *uih, void *user_data, const char *path) -{ - /* XXX pass in the selected storage */ - GtkWidget *subscribe = subscribe_dialog_new ((FOLDER_BROWSER (user_data))->shell); - - gtk_widget_show (subscribe); -} - -void -configure_folder(BonoboUIComponent *uih, void *user_data, const char *path) -{ - FolderBrowser *fb = FOLDER_BROWSER(user_data); - - local_reconfigure_folder(fb); -} - -void -view_msg (GtkWidget *widget, gpointer user_data) -{ - FolderBrowser *fb = user_data; - GPtrArray *uids; - - if (!fb->folder) - return; - - uids = g_ptr_array_new (); - message_list_foreach (fb->message_list, enumerate_msg, uids); - mail_do_view_messages (fb->folder, uids, fb); -} - -void -view_message (BonoboUIComponent *uih, void *user_data, const char *path) -{ - view_msg (NULL, user_data); -} - -void -edit_message (BonoboUIComponent *uih, void *user_data, const char *path) -{ - edit_msg (NULL, user_data); -} diff --git a/mail/mail-callbacks.h b/mail/mail-callbacks.h deleted file mode 100644 index 7995581be2..0000000000 --- a/mail/mail-callbacks.h +++ /dev/null @@ -1,82 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Authors: Jeffrey Stedfast <fejj@helixcode.com> - * - * Copyright 2000 Helix Code, Inc. (www.helixcode.com) - * - * 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 - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA. - * - */ - -#ifndef MAIL_CALLBACKS_H -#define MAIL_CALLBACKS_H - -#include <gnome.h> -#include <camel/camel.h> -#include "composer/e-msg-composer.h" -#include "mail-types.h" - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus }*/ - -void enumerate_msg (MessageList *ml, const char *uid, gpointer data); - -void fetch_mail (GtkWidget *widget, gpointer user_data); -void send_queued_mail (GtkWidget *widget, gpointer user_data); -void send_receieve_mail (GtkWidget *widget, gpointer user_data); - -void compose_msg (GtkWidget *widget, gpointer user_data); -void send_to_url (const char *url); -void forward_msg (GtkWidget *widget, gpointer user_data); -void reply_to_sender (GtkWidget *widget, gpointer user_data); -void reply_to_all (GtkWidget *widget, gpointer user_data); -void delete_msg (GtkWidget *widget, gpointer user_data); -void undelete_msg (GtkWidget *widget, gpointer user_data); -void move_msg (GtkWidget *widget, gpointer user_data); -void copy_msg (GtkWidget *widget, gpointer user_data); -void apply_filters (GtkWidget *widget, gpointer user_data); -void print_msg (GtkWidget *widget, gpointer user_data); -void print_preview_msg (GtkWidget *widget, gpointer user_data); -void edit_msg (GtkWidget *widget, gpointer user_data); -void view_msg (GtkWidget *widget, gpointer user_data); - -void select_all (BonoboUIComponent *uih, void *user_data, const char *path); -void invert_selection (BonoboUIComponent *uih, void *user_data, const char *path); -void mark_as_seen (BonoboUIComponent *uih, void *user_data, const char *path); -void mark_as_unseen (BonoboUIComponent *uih, void *user_data, const char *path); -void edit_message (BonoboUIComponent *uih, void *user_data, const char *path); -void view_message (BonoboUIComponent *uih, void *user_data, const char *path); -void expunge_folder (BonoboUIComponent *uih, void *user_data, const char *path); -void filter_edit (BonoboUIComponent *uih, void *user_data, const char *path); -void vfolder_edit_vfolders (BonoboUIComponent *uih, void *user_data, const char *path); -void providers_config (BonoboUIComponent *uih, void *user_data, const char *path); -void manage_subscriptions (BonoboUIComponent *uih, void *user_data, const char *path); - -void configure_folder (BonoboUIComponent *uih, void *user_data, const char *path); - -void mail_reply (CamelFolder *folder, CamelMimeMessage *msg, const char *uid, gboolean to_all); -void composer_send_cb (EMsgComposer *composer, gpointer data); -void composer_postpone_cb (EMsgComposer *composer, gpointer data); - -void mail_print_preview_msg (MailDisplay *md); -void mail_print_msg (MailDisplay *md); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* ! MAIL_CALLBACKS_H */ diff --git a/mail/mail-config-druid.glade b/mail/mail-config-druid.glade deleted file mode 100644 index 92f3a72912..0000000000 --- a/mail/mail-config-druid.glade +++ /dev/null @@ -1,2876 +0,0 @@ -<?xml version="1.0"?> -<GTK-Interface> - -<project> - <name>config</name> - <program_name>config</program_name> - <directory></directory> - <source_directory>src</source_directory> - <pixmaps_directory>pixmaps</pixmaps_directory> - <language>C</language> - <gnome_support>True</gnome_support> - <gettext_support>True</gettext_support> - <output_main_file>False</output_main_file> - <output_support_files>False</output_support_files> - <output_build_files>False</output_build_files> - <output_translatable_strings>True</output_translatable_strings> - <translatable_strings_file>mail-config.glade.h</translatable_strings_file> -</project> - -<widget> - <class>GtkWindow</class> - <name>mail-config-window</name> - <title>Mail Configuration Druid</title> - <type>GTK_WINDOW_TOPLEVEL</type> - <position>GTK_WIN_POS_NONE</position> - <modal>False</modal> - <default_width>450</default_width> - <default_height>350</default_height> - <allow_shrink>True</allow_shrink> - <allow_grow>False</allow_grow> - <auto_shrink>True</auto_shrink> - - <widget> - <class>GnomeDruid</class> - <name>mail-config-druid</name> - - <widget> - <class>GnomeDruidPageStart</class> - <name>druidpagestart1</name> - <title>Mail Configuration</title> - <text>Welcome to the Evolution Mail Configuration Druid! - -By filling in some information about your email settings, -you can start sending and receiving email right away. - -Click "Next" to begin. </text> - <title_color>255,255,255</title_color> - <text_color>0,0,0</text_color> - <background_color>25,25,112</background_color> - <logo_background_color>25,25,112</logo_background_color> - <textbox_color>255,255,255</textbox_color> - <logo_image>fetch-mail.png</logo_image> - </widget> - - <widget> - <class>GnomeDruidPageStandard</class> - <name>druidpagestandard1</name> - <title>Identity</title> - <title_color>255,255,255</title_color> - <background_color>25,25,112</background_color> - <logo_background_color>25,25,112</logo_background_color> - <logo_image>malehead.png</logo_image> - - <widget> - <class>GtkVBox</class> - <child_name>GnomeDruidPageStandard:vbox</child_name> - <name>druid-vbox1</name> - <border_width>5</border_width> - <homogeneous>False</homogeneous> - <spacing>0</spacing> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkVBox</class> - <name>vbox4</name> - <homogeneous>False</homogeneous> - <spacing>0</spacing> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkLabel</class> - <name>identity-help</name> - <label>Please enter your name and email address below. The "optional" fields below do not -need to be filled in, unless you wish to include this information in email you send. </label> - <justify>GTK_JUSTIFY_FILL</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - </widget> - - <widget> - <class>GtkFrame</class> - <name>frame2</name> - <border_width>3</border_width> - <height>76</height> - <label>Required</label> - <label_xalign>0</label_xalign> - <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type> - <child> - <padding>5</padding> - <expand>False</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkTable</class> - <name>table1</name> - <border_width>4</border_width> - <rows>2</rows> - <columns>2</columns> - <homogeneous>False</homogeneous> - <row_spacing>4</row_spacing> - <column_spacing>4</column_spacing> - - <widget> - <class>GtkEntry</class> - <name>name-entry</name> - <width>80</width> - <height>20</height> - <can_focus>True</can_focus> - <has_focus>True</has_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>50</text_max_length> - <text></text> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>0</top_attach> - <bottom_attach>1</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkEntry</class> - <name>email-entry</name> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>50</text_max_length> - <text></text> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>1</top_attach> - <bottom_attach>2</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>name-label</name> - <label>Full Name:</label> - <justify>GTK_JUSTIFY_RIGHT</justify> - <wrap>False</wrap> - <xalign>1</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>0</top_attach> - <bottom_attach>1</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>email-address-label</name> - <label>Email Address:</label> - <justify>GTK_JUSTIFY_RIGHT</justify> - <wrap>False</wrap> - <xalign>1</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>1</top_attach> - <bottom_attach>2</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - </widget> - </widget> - - <widget> - <class>GtkVBox</class> - <name>vbox5</name> - <homogeneous>False</homogeneous> - <spacing>0</spacing> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkFrame</class> - <name>optional-frame</name> - <border_width>3</border_width> - <height>102</height> - <label>Optional</label> - <label_xalign>0</label_xalign> - <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkTable</class> - <name>table2</name> - <border_width>4</border_width> - <rows>3</rows> - <columns>2</columns> - <homogeneous>False</homogeneous> - <row_spacing>4</row_spacing> - <column_spacing>4</column_spacing> - - <widget> - <class>GtkLabel</class> - <name>label41</name> - <label>Organization:</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>1</top_attach> - <bottom_attach>2</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>False</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>label42</name> - <label>Signature file:</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>2</top_attach> - <bottom_attach>3</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>False</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkEntry</class> - <name>organization-entry</name> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>1</top_attach> - <bottom_attach>2</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkHBox</class> - <name>hbox8</name> - <homogeneous>False</homogeneous> - <spacing>4</spacing> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>2</top_attach> - <bottom_attach>3</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - - <widget> - <class>GtkCombo</class> - <name>sig-combo</name> - <value_in_list>False</value_in_list> - <ok_if_empty>True</ok_if_empty> - <case_sensitive>False</case_sensitive> - <use_arrows>True</use_arrows> - <use_arrows_always>False</use_arrows_always> - <items></items> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkEntry</class> - <child_name>GtkCombo:entry</child_name> - <name>combo-entry1</name> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - </widget> - </widget> - - <widget> - <class>GtkButton</class> - <name>button1</name> - <can_focus>True</can_focus> - <label>Browse...</label> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - </widget> - - <widget> - <class>GtkLabel</class> - <name>reply-label</name> - <label>Reply-to:</label> - <justify>GTK_JUSTIFY_RIGHT</justify> - <wrap>True</wrap> - <xalign>1</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>0</top_attach> - <bottom_attach>1</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkEntry</class> - <name>reply-to-entry</name> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>0</top_attach> - <bottom_attach>1</bottom_attach> - <xpad>1</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - </widget> - </widget> - </widget> - </widget> - </widget> - </widget> - - <widget> - <class>GnomeDruidPageStandard</class> - <name>druidpagestandard2</name> - <title>Receiving Email</title> - <title_color>255,255,255</title_color> - <background_color>25,25,112</background_color> - <logo_background_color>25,25,112</logo_background_color> - <logo_image>evolution-inbox.png</logo_image> - - <widget> - <class>GtkVBox</class> - <child_name>GnomeDruidPageStandard:vbox</child_name> - <name>druid-vbox2</name> - <homogeneous>False</homogeneous> - <spacing>0</spacing> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkVBox</class> - <name>vbox6</name> - <border_width>5</border_width> - <homogeneous>False</homogeneous> - <spacing>0</spacing> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkLabel</class> - <name>label45</name> - <label>Please enter information about your incoming mail server below. If you don't know what - kind of server you use, contact your system administrator or Internet Service Provider. </label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkTable</class> - <name>table3</name> - <border_width>4</border_width> - <rows>1</rows> - <columns>2</columns> - <homogeneous>False</homogeneous> - <row_spacing>4</row_spacing> - <column_spacing>2</column_spacing> - <child> - <padding>4</padding> - <expand>False</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkOptionMenu</class> - <name>server-types-option-menu</name> - <can_focus>True</can_focus> - <items>POP -IMAP -Unix mbox -</items> - <initial_choice>0</initial_choice> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>0</top_attach> - <bottom_attach>1</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>False</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>server-type-label</name> - <label>Server Type: </label> - <justify>GTK_JUSTIFY_RIGHT</justify> - <wrap>False</wrap> - <xalign>1</xalign> - <yalign>0.5</yalign> - <xpad>2</xpad> - <ypad>0</ypad> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>0</top_attach> - <bottom_attach>1</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - </widget> - - <widget> - <class>GtkFrame</class> - <name>server-info-frame</name> - <label>Server Configuration</label> - <label_xalign>0</label_xalign> - <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkVBox</class> - <name>vbox7</name> - <homogeneous>False</homogeneous> - <spacing>0</spacing> - - <widget> - <class>GtkTable</class> - <name>table4</name> - <border_width>4</border_width> - <rows>4</rows> - <columns>2</columns> - <homogeneous>False</homogeneous> - <row_spacing>4</row_spacing> - <column_spacing>4</column_spacing> - <child> - <padding>4</padding> - <expand>False</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkLabel</class> - <name>server-label</name> - <label>Server:</label> - <justify>GTK_JUSTIFY_RIGHT</justify> - <wrap>False</wrap> - <xalign>1</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>0</top_attach> - <bottom_attach>1</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>username-label</name> - <label>Username:</label> - <justify>GTK_JUSTIFY_LEFT</justify> - <wrap>False</wrap> - <xalign>1</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>1</top_attach> - <bottom_attach>2</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>path-label</name> - <label></label> - <justify>GTK_JUSTIFY_RIGHT</justify> - <wrap>False</wrap> - <xalign>1</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>2</top_attach> - <bottom_attach>3</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkEntry</class> - <name>entry5</name> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>0</top_attach> - <bottom_attach>1</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkEntry</class> - <name>entry6</name> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>1</top_attach> - <bottom_attach>2</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkEntry</class> - <name>entry7</name> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>2</top_attach> - <bottom_attach>3</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkEntry</class> - <name>entry18</name> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>3</top_attach> - <bottom_attach>4</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>password-entry</name> - <label>Password:</label> - <justify>GTK_JUSTIFY_RIGHT</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>2</top_attach> - <bottom_attach>3</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>False</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>path-entry</name> - <label>Path:</label> - <justify>GTK_JUSTIFY_RIGHT</justify> - <wrap>False</wrap> - <xalign>1</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>3</top_attach> - <bottom_attach>4</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - </widget> - - <widget> - <class>GtkHBox</class> - <name>hbox9</name> - <homogeneous>False</homogeneous> - <spacing>0</spacing> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkCheckButton</class> - <name>checkbutton1</name> - <border_width>3</border_width> - <can_focus>True</can_focus> - <label>Don't delete messages from server</label> - <active>False</active> - <draw_indicator>True</draw_indicator> - <child> - <padding>2</padding> - <expand>False</expand> - <fill>True</fill> - </child> - </widget> - - <widget> - <class>GtkHButtonBox</class> - <name>hbuttonbox1</name> - <layout_style>GTK_BUTTONBOX_END</layout_style> - <spacing>30</spacing> - <child_min_width>85</child_min_width> - <child_min_height>27</child_min_height> - <child_ipad_x>7</child_ipad_x> - <child_ipad_y>0</child_ipad_y> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkButton</class> - <name>test-settings-button</name> - <can_default>True</can_default> - <can_focus>True</can_focus> - <label>Test Settings</label> - </widget> - </widget> - </widget> - </widget> - </widget> - </widget> - </widget> - </widget> - - <widget> - <class>GnomeDruidPageStandard</class> - <name>druidpagestandard3</name> - <title>Authentication</title> - <title_color>255,255,255</title_color> - <background_color>25,25,112</background_color> - <logo_background_color>25,25,112</logo_background_color> - <logo_image>registration.png</logo_image> - - <widget> - <class>GtkVBox</class> - <child_name>GnomeDruidPageStandard:vbox</child_name> - <name>druid-vbox3</name> - <homogeneous>False</homogeneous> - <spacing>0</spacing> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkVBox</class> - <name>vbox8</name> - <border_width>6</border_width> - <homogeneous>False</homogeneous> - <spacing>0</spacing> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkLabel</class> - <name>security-info-label</name> - <label>Your mail server supports the following types of authentication. Please -select the type you want Evolution to use. -</label> - <justify>GTK_JUSTIFY_FILL</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkFrame</class> - <name>frame3</name> - <label>Authentication</label> - <label_xalign>0</label_xalign> - <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkVBox</class> - <name>vbox9</name> - <homogeneous>False</homogeneous> - <spacing>0</spacing> - - <widget> - <class>GtkHBox</class> - <name>hbox10</name> - <border_width>2</border_width> - <homogeneous>False</homogeneous> - <spacing>2</spacing> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkLabel</class> - <name>authentification-label</name> - <label>Preferred type: </label> - <justify>GTK_JUSTIFY_FILL</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <padding>3</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkOptionMenu</class> - <name>optionmenu1</name> - <can_focus>True</can_focus> - <items>Kerberos -</items> - <initial_choice>0</initial_choice> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkCheckButton</class> - <name>checkbutton2</name> - <can_focus>True</can_focus> - <label>Remember my password</label> - <active>False</active> - <draw_indicator>True</draw_indicator> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - <pack>GTK_PACK_END</pack> - </child> - </widget> - </widget> - </widget> - </widget> - </widget> - </widget> - </widget> - - <widget> - <class>GnomeDruidPageStandard</class> - <name>druidpagestandard4</name> - <title>Sending Email</title> - <title_color>255,255,255</title_color> - <background_color>25,25,112</background_color> - <logo_background_color>25,25,112</logo_background_color> - <logo_image>send.png</logo_image> - - <widget> - <class>GtkVBox</class> - <child_name>GnomeDruidPageStandard:vbox</child_name> - <name>druid-vbox4</name> - <homogeneous>False</homogeneous> - <spacing>0</spacing> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkVBox</class> - <name>vbox10</name> - <homogeneous>False</homogeneous> - <spacing>0</spacing> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkVBox</class> - <name>vbox11</name> - <border_width>5</border_width> - <homogeneous>False</homogeneous> - <spacing>0</spacing> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkLabel</class> - <name>label51</name> - <label>Please enter information about your outgoing mail protocol below. If you don't know -which protocol you use, contact your system administrator or Internet Service Provider. </label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkTable</class> - <name>table5</name> - <border_width>4</border_width> - <rows>1</rows> - <columns>2</columns> - <homogeneous>False</homogeneous> - <row_spacing>4</row_spacing> - <column_spacing>2</column_spacing> - <child> - <padding>4</padding> - <expand>False</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkOptionMenu</class> - <name>optionmenu2</name> - <can_focus>True</can_focus> - <items>Sendmail -SMTP -</items> - <initial_choice>1</initial_choice> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>0</top_attach> - <bottom_attach>1</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>False</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>label52</name> - <label>Server Type: </label> - <justify>GTK_JUSTIFY_RIGHT</justify> - <wrap>False</wrap> - <xalign>1</xalign> - <yalign>0.5</yalign> - <xpad>2</xpad> - <ypad>0</ypad> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>0</top_attach> - <bottom_attach>1</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - </widget> - - <widget> - <class>GtkFrame</class> - <name>frame4</name> - <label>Server Configuration</label> - <label_xalign>0</label_xalign> - <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkVBox</class> - <name>vbox12</name> - <homogeneous>False</homogeneous> - <spacing>0</spacing> - - <widget> - <class>GtkTable</class> - <name>table6</name> - <border_width>4</border_width> - <rows>1</rows> - <columns>2</columns> - <homogeneous>False</homogeneous> - <row_spacing>4</row_spacing> - <column_spacing>4</column_spacing> - <child> - <padding>4</padding> - <expand>False</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkLabel</class> - <name>label53</name> - <label>Server:</label> - <justify>GTK_JUSTIFY_RIGHT</justify> - <wrap>False</wrap> - <xalign>1</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>0</top_attach> - <bottom_attach>1</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkEntry</class> - <name>entry8</name> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>0</top_attach> - <bottom_attach>1</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - </widget> - - <widget> - <class>GtkHBox</class> - <name>hbox11</name> - <homogeneous>False</homogeneous> - <spacing>0</spacing> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkCheckButton</class> - <name>smtp-authentication-checkbox</name> - <border_width>3</border_width> - <can_focus>True</can_focus> - <label>SMTP server requires authentication</label> - <active>False</active> - <draw_indicator>True</draw_indicator> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkHButtonBox</class> - <name>hbuttonbox2</name> - <layout_style>GTK_BUTTONBOX_END</layout_style> - <spacing>30</spacing> - <child_min_width>85</child_min_width> - <child_min_height>27</child_min_height> - <child_ipad_x>7</child_ipad_x> - <child_ipad_y>0</child_ipad_y> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkButton</class> - <name>button2</name> - <can_default>True</can_default> - <can_focus>True</can_focus> - <label>Test Settings</label> - </widget> - </widget> - </widget> - </widget> - </widget> - </widget> - </widget> - </widget> - </widget> - - <widget> - <class>GnomeDruidPageStandard</class> - <name>druidpagestandard5</name> - <title>Account Management</title> - <title_color>255,255,255</title_color> - <background_color>25,25,112</background_color> - <logo_background_color>25,25,112</logo_background_color> - <logo_image>evolution-tasks.png</logo_image> - - <widget> - <class>GtkVBox</class> - <child_name>GnomeDruidPageStandard:vbox</child_name> - <name>druid-vbox5</name> - <homogeneous>False</homogeneous> - <spacing>0</spacing> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkVBox</class> - <name>vbox29</name> - <border_width>5</border_width> - <homogeneous>False</homogeneous> - <spacing>0</spacing> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkLabel</class> - <name>almost-done-label</name> - <label>You are almost done with the mail configuration process. The identity, incoming -mail server and outgoing mail transport method which you provided will be grouped -together to make an Evolution mail account. Please enter a name for this account -in the space below. This name will be used for display purposes only. -</label> - <justify>GTK_JUSTIFY_FILL</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkFrame</class> - <name>frame20</name> - <label>Account Information</label> - <label_xalign>0</label_xalign> - <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkVBox</class> - <name>vbox31</name> - <homogeneous>False</homogeneous> - <spacing>0</spacing> - - <widget> - <class>GtkHBox</class> - <name>hbox24</name> - <border_width>3</border_width> - <homogeneous>False</homogeneous> - <spacing>5</spacing> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkLabel</class> - <name>name-label</name> - <label>Name:</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkEntry</class> - <name>entry30</name> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - </widget> - - <widget> - <class>GtkCheckButton</class> - <name>default-checkbox</name> - <can_focus>True</can_focus> - <label>Make this my default account</label> - <active>False</active> - <draw_indicator>True</draw_indicator> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - </widget> - - <widget> - <class>GtkLabel</class> - <name></name> - <label></label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - </widget> - </widget> - </widget> - </widget> - </widget> - - <widget> - <class>GnomeDruidPageFinish</class> - <name>druidpagefinish1</name> - <title>Done</title> - <text>Congratulations, your mail configuration is complete. - -You are now ready to send and receive email -using Evolution. - -Click "Finish" to save your settings.</text> - <background_color>25,25,112</background_color> - <logo_background_color>25,25,112</logo_background_color> - <textbox_color>255,255,255</textbox_color> - <text_color>0,0,0</text_color> - <title_color>255,255,255</title_color> - <logo_image>house.png</logo_image> - </widget> - </widget> -</widget> - -<widget> - <class>GnomeDialog</class> - <name>edit-settings</name> - <title>Edit Mail Configuration Settings</title> - <type>GTK_WINDOW_TOPLEVEL</type> - <position>GTK_WIN_POS_NONE</position> - <modal>False</modal> - <allow_shrink>False</allow_shrink> - <allow_grow>True</allow_grow> - <auto_shrink>False</auto_shrink> - <auto_close>False</auto_close> - <hide_on_close>False</hide_on_close> - - <widget> - <class>GtkVBox</class> - <child_name>GnomeDialog:vbox</child_name> - <name>dialog-vbox1</name> - <homogeneous>False</homogeneous> - <spacing>8</spacing> - <child> - <padding>4</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkHButtonBox</class> - <child_name>GnomeDialog:action_area</child_name> - <name>dialog-action_area1</name> - <layout_style>GTK_BUTTONBOX_END</layout_style> - <spacing>8</spacing> - <child_min_width>85</child_min_width> - <child_min_height>27</child_min_height> - <child_ipad_x>7</child_ipad_x> - <child_ipad_y>0</child_ipad_y> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>True</fill> - <pack>GTK_PACK_END</pack> - </child> - - <widget> - <class>GtkButton</class> - <name>button3</name> - <can_default>True</can_default> - <can_focus>True</can_focus> - <stock_button>GNOME_STOCK_BUTTON_OK</stock_button> - </widget> - - <widget> - <class>GtkButton</class> - <name>button4</name> - <can_default>True</can_default> - <can_focus>True</can_focus> - <stock_button>GNOME_STOCK_BUTTON_APPLY</stock_button> - </widget> - - <widget> - <class>GtkButton</class> - <name>button5</name> - <can_default>True</can_default> - <can_focus>True</can_focus> - <stock_button>GNOME_STOCK_BUTTON_CANCEL</stock_button> - </widget> - </widget> - - <widget> - <class>GtkVBox</class> - <name>vbox25</name> - <homogeneous>False</homogeneous> - <spacing>0</spacing> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkFrame</class> - <name>identity-frame</name> - <label>Identity</label> - <label_xalign>0</label_xalign> - <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkVBox</class> - <name>vbox28</name> - <homogeneous>False</homogeneous> - <spacing>0</spacing> - - <widget> - <class>GtkTable</class> - <name>table14</name> - <border_width>4</border_width> - <rows>2</rows> - <columns>2</columns> - <homogeneous>False</homogeneous> - <row_spacing>4</row_spacing> - <column_spacing>4</column_spacing> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkEntry</class> - <name>full-name-entry</name> - <width>80</width> - <height>20</height> - <can_focus>True</can_focus> - <has_focus>True</has_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>50</text_max_length> - <text></text> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>0</top_attach> - <bottom_attach>1</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkEntry</class> - <name>email-address-entry</name> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>50</text_max_length> - <text></text> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>1</top_attach> - <bottom_attach>2</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>full-name-label</name> - <label>Full Name:</label> - <justify>GTK_JUSTIFY_RIGHT</justify> - <wrap>False</wrap> - <xalign>1</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>0</top_attach> - <bottom_attach>1</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>email-address-label</name> - <label>Email Address:</label> - <justify>GTK_JUSTIFY_RIGHT</justify> - <wrap>False</wrap> - <xalign>1</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>1</top_attach> - <bottom_attach>2</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - </widget> - - <widget> - <class>GtkHButtonBox</class> - <name>hbuttonbox6</name> - <layout_style>GTK_BUTTONBOX_END</layout_style> - <spacing>30</spacing> - <child_min_width>85</child_min_width> - <child_min_height>27</child_min_height> - <child_ipad_x>7</child_ipad_x> - <child_ipad_y>0</child_ipad_y> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkButton</class> - <name>add-fields-button</name> - <can_default>True</can_default> - <can_focus>True</can_focus> - <label>Add Optional Fields...</label> - </widget> - </widget> - </widget> - </widget> - - <widget> - <class>GtkFrame</class> - <name>receiving-frame</name> - <label>Receiving Mail</label> - <label_xalign>0</label_xalign> - <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkVBox</class> - <name>vbox26</name> - <homogeneous>False</homogeneous> - <spacing>0</spacing> - - <widget> - <class>GtkTable</class> - <name>table12</name> - <border_width>4</border_width> - <rows>6</rows> - <columns>2</columns> - <homogeneous>False</homogeneous> - <row_spacing>2</row_spacing> - <column_spacing>4</column_spacing> - <child> - <padding>4</padding> - <expand>False</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkLabel</class> - <name>server-type</name> - <label>IMAP</label> - <justify>GTK_JUSTIFY_LEFT</justify> - <wrap>False</wrap> - <xalign>7.45058e-09</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>0</top_attach> - <bottom_attach>1</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkEntry</class> - <name>path-entry</name> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>4</top_attach> - <bottom_attach>5</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkEntry</class> - <name>password-entry</name> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>3</top_attach> - <bottom_attach>4</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkEntry</class> - <name>username-entry</name> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>2</top_attach> - <bottom_attach>3</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkEntry</class> - <name>incoming-server-entry</name> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>1</top_attach> - <bottom_attach>2</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>type-label</name> - <label>Type:</label> - <justify>GTK_JUSTIFY_RIGHT</justify> - <wrap>False</wrap> - <xalign>1</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>0</top_attach> - <bottom_attach>1</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>server-label</name> - <label>Server:</label> - <justify>GTK_JUSTIFY_RIGHT</justify> - <wrap>False</wrap> - <xalign>1</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>1</top_attach> - <bottom_attach>2</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>username-label</name> - <label>Username:</label> - <justify>GTK_JUSTIFY_RIGHT</justify> - <wrap>False</wrap> - <xalign>1</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>2</top_attach> - <bottom_attach>3</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>path-label</name> - <label>Path:</label> - <justify>GTK_JUSTIFY_RIGHT</justify> - <wrap>False</wrap> - <xalign>1</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>4</top_attach> - <bottom_attach>5</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>auth-label</name> - <label>Authentication:</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>5</top_attach> - <bottom_attach>6</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>False</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>label93</name> - <label>Password:</label> - <justify>GTK_JUSTIFY_RIGHT</justify> - <wrap>False</wrap> - <xalign>1</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>3</top_attach> - <bottom_attach>4</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkOptionMenu</class> - <name>optionmenu5</name> - <can_focus>True</can_focus> - <items>Kerberos -Plain-text Password -</items> - <initial_choice>0</initial_choice> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>5</top_attach> - <bottom_attach>6</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - </widget> - - <widget> - <class>GtkHBox</class> - <name>hbox21</name> - <homogeneous>False</homogeneous> - <spacing>0</spacing> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkCheckButton</class> - <name>checkbutton10</name> - <border_width>3</border_width> - <can_focus>True</can_focus> - <label>Don't delete messages from server</label> - <active>False</active> - <draw_indicator>True</draw_indicator> - <child> - <padding>2</padding> - <expand>False</expand> - <fill>True</fill> - </child> - </widget> - - <widget> - <class>GtkHButtonBox</class> - <name>hbuttonbox4</name> - <layout_style>GTK_BUTTONBOX_END</layout_style> - <spacing>30</spacing> - <child_min_width>85</child_min_width> - <child_min_height>27</child_min_height> - <child_ipad_x>7</child_ipad_x> - <child_ipad_y>0</child_ipad_y> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - </widget> - </widget> - </widget> - </widget> - - <widget> - <class>GtkFrame</class> - <name>sending-frame</name> - <label>Sending Mail</label> - <label_xalign>0</label_xalign> - <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkVBox</class> - <name>vbox27</name> - <homogeneous>False</homogeneous> - <spacing>0</spacing> - - <widget> - <class>GtkTable</class> - <name>table13</name> - <border_width>4</border_width> - <rows>3</rows> - <columns>2</columns> - <homogeneous>False</homogeneous> - <row_spacing>4</row_spacing> - <column_spacing>4</column_spacing> - <child> - <padding>4</padding> - <expand>False</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkLabel</class> - <name>label95</name> - <label>Server:</label> - <justify>GTK_JUSTIFY_RIGHT</justify> - <wrap>False</wrap> - <xalign>1</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>1</top_attach> - <bottom_attach>2</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkEntry</class> - <name>outgoing-server-entry</name> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>1</top_attach> - <bottom_attach>2</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>label100</name> - <label>Type:</label> - <justify>GTK_JUSTIFY_RIGHT</justify> - <wrap>False</wrap> - <xalign>1</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>0</top_attach> - <bottom_attach>1</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>label101</name> - <label>SMTP</label> - <justify>GTK_JUSTIFY_LEFT</justify> - <wrap>False</wrap> - <xalign>0</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>0</top_attach> - <bottom_attach>1</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>label103</name> - <label>Authentication:</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>2</top_attach> - <bottom_attach>3</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>False</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkOptionMenu</class> - <name>optionmenu6</name> - <can_focus>True</can_focus> - <items>Kerberos -Plain-text Password -</items> - <initial_choice>0</initial_choice> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>2</top_attach> - <bottom_attach>3</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - </widget> - - <widget> - <class>GtkHBox</class> - <name>hbox22</name> - <homogeneous>False</homogeneous> - <spacing>0</spacing> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkHButtonBox</class> - <name>hbuttonbox5</name> - <layout_style>GTK_BUTTONBOX_END</layout_style> - <spacing>30</spacing> - <child_min_width>85</child_min_width> - <child_min_height>27</child_min_height> - <child_ipad_x>7</child_ipad_x> - <child_ipad_y>0</child_ipad_y> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - </widget> - </widget> - </widget> - </widget> - </widget> - </widget> -</widget> - -<widget> - <class>GnomeDialog</class> - <name>mail-accounts-list</name> - <title>Evolution Mail Configuration</title> - <type>GTK_WINDOW_TOPLEVEL</type> - <position>GTK_WIN_POS_NONE</position> - <modal>False</modal> - <default_width>350</default_width> - <default_height>240</default_height> - <allow_shrink>False</allow_shrink> - <allow_grow>True</allow_grow> - <auto_shrink>False</auto_shrink> - <auto_close>False</auto_close> - <hide_on_close>False</hide_on_close> - - <widget> - <class>GtkVBox</class> - <child_name>GnomeDialog:vbox</child_name> - <name>dialog-vbox2</name> - <homogeneous>False</homogeneous> - <spacing>8</spacing> - <child> - <padding>4</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkHButtonBox</class> - <child_name>GnomeDialog:action_area</child_name> - <name>dialog-action_area2</name> - <layout_style>GTK_BUTTONBOX_END</layout_style> - <spacing>8</spacing> - <child_min_width>85</child_min_width> - <child_min_height>27</child_min_height> - <child_ipad_x>7</child_ipad_x> - <child_ipad_y>0</child_ipad_y> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>True</fill> - <pack>GTK_PACK_END</pack> - </child> - - <widget> - <class>GtkButton</class> - <name>button9</name> - <can_default>True</can_default> - <can_focus>True</can_focus> - <stock_button>GNOME_STOCK_BUTTON_OK</stock_button> - </widget> - - <widget> - <class>GtkButton</class> - <name>button11</name> - <can_default>True</can_default> - <can_focus>True</can_focus> - <stock_button>GNOME_STOCK_BUTTON_CANCEL</stock_button> - </widget> - </widget> - - <widget> - <class>GtkNotebook</class> - <name>notebook2</name> - <can_focus>True</can_focus> - <show_tabs>True</show_tabs> - <show_border>True</show_border> - <tab_pos>GTK_POS_TOP</tab_pos> - <scrollable>False</scrollable> - <tab_hborder>2</tab_hborder> - <tab_vborder>2</tab_vborder> - <popup_enable>False</popup_enable> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkHBox</class> - <name>hbox18</name> - <homogeneous>False</homogeneous> - <spacing>0</spacing> - - <widget> - <class>GtkScrolledWindow</class> - <name>scrolledwindow7</name> - <hscrollbar_policy>GTK_POLICY_AUTOMATIC</hscrollbar_policy> - <vscrollbar_policy>GTK_POLICY_AUTOMATIC</vscrollbar_policy> - <hupdate_policy>GTK_UPDATE_CONTINUOUS</hupdate_policy> - <vupdate_policy>GTK_UPDATE_CONTINUOUS</vupdate_policy> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkCList</class> - <name>clist3</name> - <can_focus>True</can_focus> - <columns>2</columns> - <column_widths>47,80</column_widths> - <selection_mode>GTK_SELECTION_SINGLE</selection_mode> - <show_titles>True</show_titles> - <shadow_type>GTK_SHADOW_IN</shadow_type> - - <widget> - <class>GtkLabel</class> - <child_name>CList:title</child_name> - <name>default-label</name> - <label>Default</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - </widget> - - <widget> - <class>GtkLabel</class> - <child_name>CList:title</child_name> - <name>accounts-label</name> - <label>Accounts</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - </widget> - </widget> - </widget> - - <widget> - <class>GtkVButtonBox</class> - <name>vbuttonbox7</name> - <layout_style>GTK_BUTTONBOX_START</layout_style> - <spacing>0</spacing> - <child_min_width>85</child_min_width> - <child_min_height>27</child_min_height> - <child_ipad_x>7</child_ipad_x> - <child_ipad_y>0</child_ipad_y> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - - <widget> - <class>GtkButton</class> - <name>add-mail-button</name> - <can_default>True</can_default> - <can_focus>True</can_focus> - <label>Add</label> - </widget> - - <widget> - <class>GtkButton</class> - <name>edit-mail-button</name> - <can_default>True</can_default> - <can_focus>True</can_focus> - <label>Edit</label> - </widget> - - <widget> - <class>GtkButton</class> - <name>delet-mail-button</name> - <can_default>True</can_default> - <can_focus>True</can_focus> - <label>Delete</label> - </widget> - </widget> - </widget> - - <widget> - <class>GtkLabel</class> - <child_name>Notebook:tab</child_name> - <name>mail-tab</name> - <label>Mail</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - </widget> - - <widget> - <class>GtkHBox</class> - <name>hbox19</name> - <homogeneous>False</homogeneous> - <spacing>0</spacing> - - <widget> - <class>GtkScrolledWindow</class> - <name>scrolledwindow8</name> - <hscrollbar_policy>GTK_POLICY_AUTOMATIC</hscrollbar_policy> - <vscrollbar_policy>GTK_POLICY_AUTOMATIC</vscrollbar_policy> - <hupdate_policy>GTK_UPDATE_CONTINUOUS</hupdate_policy> - <vupdate_policy>GTK_UPDATE_CONTINUOUS</vupdate_policy> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkCList</class> - <name>clist2</name> - <can_focus>True</can_focus> - <columns>1</columns> - <column_widths>80</column_widths> - <selection_mode>GTK_SELECTION_SINGLE</selection_mode> - <show_titles>True</show_titles> - <shadow_type>GTK_SHADOW_IN</shadow_type> - - <widget> - <class>GtkLabel</class> - <child_name>CList:title</child_name> - <name>news-sources-label</name> - <label>Sources</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - </widget> - </widget> - </widget> - - <widget> - <class>GtkVButtonBox</class> - <name>vbuttonbox8</name> - <layout_style>GTK_BUTTONBOX_START</layout_style> - <spacing>0</spacing> - <child_min_width>85</child_min_width> - <child_min_height>27</child_min_height> - <child_ipad_x>7</child_ipad_x> - <child_ipad_y>0</child_ipad_y> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - - <widget> - <class>GtkButton</class> - <name>add-news-button</name> - <can_default>True</can_default> - <can_focus>True</can_focus> - <label>Add</label> - </widget> - - <widget> - <class>GtkButton</class> - <name>edit-news-button</name> - <can_default>True</can_default> - <can_focus>True</can_focus> - <label>Edit</label> - </widget> - - <widget> - <class>GtkButton</class> - <name>delete-news-button</name> - <can_default>True</can_default> - <can_focus>True</can_focus> - <label>Delete</label> - </widget> - </widget> - </widget> - - <widget> - <class>GtkLabel</class> - <child_name>Notebook:tab</child_name> - <name>news-tab</name> - <label>News</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - </widget> - </widget> - </widget> -</widget> - -<widget> - <class>GnomeDialog</class> - <name>optional-identity-info</name> - <title>Additional Identity Fields</title> - <type>GTK_WINDOW_TOPLEVEL</type> - <position>GTK_WIN_POS_NONE</position> - <modal>False</modal> - <allow_shrink>False</allow_shrink> - <allow_grow>False</allow_grow> - <auto_shrink>False</auto_shrink> - <auto_close>False</auto_close> - <hide_on_close>False</hide_on_close> - - <widget> - <class>GtkVBox</class> - <child_name>GnomeDialog:vbox</child_name> - <name>dialog-vbox3</name> - <homogeneous>False</homogeneous> - <spacing>8</spacing> - <child> - <padding>4</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkHButtonBox</class> - <child_name>GnomeDialog:action_area</child_name> - <name>dialog-action_area3</name> - <layout_style>GTK_BUTTONBOX_END</layout_style> - <spacing>8</spacing> - <child_min_width>85</child_min_width> - <child_min_height>27</child_min_height> - <child_ipad_x>7</child_ipad_x> - <child_ipad_y>0</child_ipad_y> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>True</fill> - <pack>GTK_PACK_END</pack> - </child> - - <widget> - <class>GtkButton</class> - <name>button21</name> - <can_default>True</can_default> - <can_focus>True</can_focus> - <stock_button>GNOME_STOCK_BUTTON_OK</stock_button> - </widget> - - <widget> - <class>GtkButton</class> - <name>button23</name> - <can_default>True</can_default> - <can_focus>True</can_focus> - <stock_button>GNOME_STOCK_BUTTON_CANCEL</stock_button> - </widget> - </widget> - - <widget> - <class>GtkFrame</class> - <name>frame19</name> - <border_width>3</border_width> - <height>102</height> - <label>Optional Information</label> - <label_xalign>0</label_xalign> - <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkTable</class> - <name>table15</name> - <border_width>4</border_width> - <rows>3</rows> - <columns>2</columns> - <homogeneous>False</homogeneous> - <row_spacing>4</row_spacing> - <column_spacing>4</column_spacing> - - <widget> - <class>GtkLabel</class> - <name>label106</name> - <label>Organization:</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>1</top_attach> - <bottom_attach>2</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>False</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>label107</name> - <label>Signature file:</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>2</top_attach> - <bottom_attach>3</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>False</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkEntry</class> - <name>entry27</name> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>1</top_attach> - <bottom_attach>2</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkHBox</class> - <name>hbox23</name> - <homogeneous>False</homogeneous> - <spacing>4</spacing> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>2</top_attach> - <bottom_attach>3</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - - <widget> - <class>GtkCombo</class> - <name>combo1</name> - <value_in_list>False</value_in_list> - <ok_if_empty>True</ok_if_empty> - <case_sensitive>False</case_sensitive> - <use_arrows>True</use_arrows> - <use_arrows_always>False</use_arrows_always> - <items></items> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkEntry</class> - <child_name>GtkCombo:entry</child_name> - <name>entry28</name> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - </widget> - </widget> - - <widget> - <class>GtkButton</class> - <name>button26</name> - <can_focus>True</can_focus> - <label>Browse...</label> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - </widget> - - <widget> - <class>GtkLabel</class> - <name>label108</name> - <label>Reply-to:</label> - <justify>GTK_JUSTIFY_RIGHT</justify> - <wrap>True</wrap> - <xalign>1</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>0</top_attach> - <bottom_attach>1</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkEntry</class> - <name>entry29</name> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>0</top_attach> - <bottom_attach>1</bottom_attach> - <xpad>1</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - </widget> - </widget> - </widget> -</widget> - -</GTK-Interface> diff --git a/mail/mail-config-druid.glade.h b/mail/mail-config-druid.glade.h deleted file mode 100644 index 7c48ce6ea1..0000000000 --- a/mail/mail-config-druid.glade.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Translatable strings file generated by Glade. - * Add this file to your project's POTFILES.in. - * DO NOT compile it as part of your application. - */ - -gchar *s = N_("Mail Configuration"); -gchar *s = N_("Mail Configuration"); -gchar *s = N_("Welcome to the Evolution Mail configuration wizard!\n" - "By filling in some information about your email\n" - "settings, you can start sending and receiving email\n" - "right away. Click Next to continue."); -gchar *s = N_("Identity"); -gchar *s = N_("Mail Source"); -gchar *s = N_("Mail Transport"); -gchar *s = N_("Mail Configuration"); -gchar *s = N_("Your email configuration is now complete.\n" - "Click \"Finish\" to save your new settings"); diff --git a/mail/mail-config-gui.c b/mail/mail-config-gui.c deleted file mode 100644 index 15099d8332..0000000000 --- a/mail/mail-config-gui.c +++ /dev/null @@ -1,2388 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* mail-config.c: Mail configuration dialogs/wizard. */ - -/* - * Authors: - * Dan Winship <danw@helixcode.com> - * Jeffrey Stedfast <fejj@helixcode.com> - * JP Rosevear <jpr@helixcode.com> - * - * Copyright 2000 Helix Code, Inc. (http://www.helixcode.com) - * - * 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 the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#include <config.h> -#include <pwd.h> - -#include <gnome.h> -#include <gtkhtml/gtkhtml.h> -#include <glade/glade.h> - -#include "e-util/e-html-utils.h" -#include <gal/widgets/e-unicode.h> -#include "mail.h" -#include "mail-threads.h" -#include "mail-tools.h" -#include "mail-config.h" -#include "mail-config-gui.h" - -typedef struct _MailDialogIdentityPage MailDialogIdentityPage; -typedef struct _MailDialogServicePage MailDialogServicePage; - -typedef void (*IdentityPageCallback) (MailDialogIdentityPage *, gpointer); -typedef void (*ServicePageCallback) (MailDialogServicePage *, gpointer); - -typedef struct -{ - CamelProvider *provider; - CamelService *service; - CamelProviderType type; -} MailService; - -struct _MailDialogIdentityPage -{ - GtkWidget *vbox; - GtkWidget *name; - GtkWidget *address; - GtkWidget *org; - GtkWidget *sig; - IdentityPageCallback undonecb; - gpointer undonedata; - IdentityPageCallback donecb; - gpointer donedata; -}; - -typedef struct -{ - GtkWidget *item; - GtkWidget *vbox; - CamelProviderType type; - gchar *protocol; - GtkWidget *user; - gboolean userneed; - GtkWidget *host; - gboolean hostneed; - GtkWidget *path; - gboolean pathneed; - GtkWidget *auth_optionmenu; - GList *auth_items; - GtkWidget *auth_html; - GtkWidget *auth_detect; - GtkWidget *keep_on_server; - gint pnum; -} MailDialogServicePageItem; - -struct _MailDialogServicePage -{ - GtkWidget *vbox; - GtkWidget *optionmenu; - GList *items; - GtkWidget *notebook; - MailDialogServicePageItem *spitem; - ServicePageCallback changedcb; - gpointer changeddata; - ServicePageCallback undonecb; - gpointer undonedata; - ServicePageCallback donecb; - gpointer donedata; -}; - -typedef struct -{ - GtkWidget *vbox; - MailDialogServicePage *page; -} MailDialogSourcePage; - -typedef struct -{ - GtkWidget *vbox; - MailDialogServicePage *page; -} MailDialogNewsPage; - -typedef struct -{ - GtkWidget *vbox; - MailDialogServicePage *page; -} MailDialogTransportPage; - -typedef struct -{ - GtkWidget *dialog; - MailDialogIdentityPage *page; - MailConfigIdentity *id; -} MailDialogIdentity; - -typedef struct -{ - GtkWidget *dialog; - MailDialogSourcePage *page; - MailConfigService *source; -} MailDialogSource; - -typedef struct -{ - GtkWidget *dialog; - MailDialogNewsPage *page; - MailConfigService *source; -} MailDialogNews; - -typedef struct -{ - Evolution_Shell shell; - GladeXML *gui; - GtkWidget *dialog; - GtkWidget *druid; - MailDialogIdentityPage *idpage; - gboolean iddone; - MailDialogSourcePage *spage; - gboolean sdone; - MailDialogTransportPage *tpage; - gboolean tdone; -} MailDruidDialog; - -typedef struct -{ - Evolution_Shell shell; - GladeXML *gui; - GtkWidget *dialog; - GtkWidget *clistIdentities; - gint idrow; - gint maxidrow; - GtkWidget *clistSources; - gint srow; - gint maxsrow; - GtkWidget *clistNews; - gint nrow; - gint maxnrow; - MailDialogTransportPage *page; - gboolean tpagedone; - GtkWidget *chkFormat; - GtkWidget *spinTimeout; -} MailDialog; - -/* private prototypes - these are ugly, rename some of them? */ -static void config_do_test_service (const char *url, CamelProviderType type); -static void config_do_query_authtypes (MailDialogServicePage *page, const char *url, MailDialogServicePageItem *item); - -static void html_size_req (GtkWidget *widget, GtkRequisition *requisition); -static GtkWidget *html_new (gboolean white); -static void put_html (GtkHTML *html, char *text); -#if 0 -static void error_dialog (GtkWidget *parent_finder, const char *fmt, ...); -#endif -static GdkImlibImage *load_image (const char *name); -static void service_page_menuitem_activate (GtkWidget *item, - MailDialogServicePage *page); -static void service_page_item_changed (GtkWidget *item, - MailDialogServicePage *page); -static void service_page_item_auth_activate (GtkWidget *menuitem, - MailDialogServicePageItem *spitem); - - -/* HTML Helpers */ -static void -html_size_req (GtkWidget *widget, GtkRequisition *requisition) -{ - requisition->height = GTK_LAYOUT (widget)->height; -} - -/* Returns a GtkHTML which is already inside a GtkScrolledWindow. If - * @white is TRUE, the GtkScrolledWindow will be inside a GtkFrame. - */ -static GtkWidget * -html_new (gboolean white) -{ - GtkWidget *html, *scrolled, *frame; - GtkStyle *style; - - html = gtk_html_new (); - GTK_LAYOUT (html)->height = 0; - gtk_signal_connect (GTK_OBJECT (html), "size_request", - GTK_SIGNAL_FUNC (html_size_req), NULL); - gtk_html_set_editable (GTK_HTML (html), FALSE); - style = gtk_rc_get_style (html); - if (style) { - gtk_html_set_default_background_color (GTK_HTML (html), - white ? &style->white : - &style->bg[0]); - } - gtk_widget_set_sensitive (html, FALSE); - scrolled = gtk_scrolled_window_new (NULL, NULL); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled), - GTK_POLICY_NEVER, - GTK_POLICY_NEVER); - gtk_container_add (GTK_CONTAINER (scrolled), html); - - if (white) { - frame = gtk_frame_new (NULL); - gtk_frame_set_shadow_type (GTK_FRAME (frame), - GTK_SHADOW_ETCHED_IN); - gtk_container_add (GTK_CONTAINER (frame), scrolled); - gtk_widget_show_all (frame); - } else - gtk_widget_show_all (scrolled); - - return html; -} - -static void -put_html (GtkHTML *html, char *text) -{ - GtkHTMLStream *handle; - - text = e_text_to_html (text, E_TEXT_TO_HTML_CONVERT_NL); - handle = gtk_html_begin (html); - gtk_html_write (html, handle, "<HTML><BODY>", 12); - gtk_html_write (html, handle, text, strlen (text)); - gtk_html_write (html, handle, "</BODY></HTML>", 14); - g_free (text); - gtk_html_end (html, handle, GTK_HTML_STREAM_OK); -} - - -#if 0 -/* Standard Dialog Helpers */ -static void -error_dialog (GtkWidget *parent_finder, const char *fmt, ...) -{ - GtkWidget *parent, *dialog; - char *msg; - va_list ap; - - parent = gtk_widget_get_ancestor (parent_finder, GTK_TYPE_WINDOW); - - va_start (ap, fmt); - msg = g_strdup_vprintf (fmt, ap); - va_end (ap); - - dialog = gnome_error_dialog_parented (msg, GTK_WINDOW (parent)); - gtk_window_set_modal (GTK_WINDOW (dialog), TRUE); - g_free (msg); -} - -static void -info_dialog (GtkWidget *parent_finder, const char *fmt, ...) -{ - GtkWidget *parent, *dialog; - char *msg; - va_list ap; - - parent = gtk_widget_get_ancestor (parent_finder, GTK_TYPE_WINDOW); - - va_start (ap, fmt); - msg = g_strdup_vprintf (fmt, ap); - va_end (ap); - - dialog = gnome_ok_dialog_parented (msg, GTK_WINDOW (parent)); - gtk_window_set_modal (GTK_WINDOW (dialog), TRUE); - g_free (msg); -} -#endif - -/* Provider List */ -static GSList * -provider_list_add (GSList *services, CamelProviderType type, - CamelProvider *prov) -{ - MailService *mcs; - CamelService *service; - CamelException *ex; - char *url; - - ex = camel_exception_new (); - - url = g_strdup_printf ("%s:", prov->protocol); - service = camel_session_get_service (session, url, type, ex); - camel_exception_free (ex); - g_free (url); - if (!service) - return services; - - mcs = g_new (MailService, 1); - mcs->provider = prov; - mcs->service = service; - mcs->type = type; - - return g_slist_prepend (services, mcs); -} - -static void -provider_list (GSList **sources, GSList **news, GSList **transports) -{ - GList *providers, *p; - - /* Fetch list of all providers. */ - providers = camel_session_list_providers (session, TRUE); - *sources = *transports = *news = NULL; - for (p = providers; p; p = p->next) { - CamelProvider *prov = p->data; - - if (!strcmp (prov->domain, "news")) { - if (prov->object_types[CAMEL_PROVIDER_STORE]) { - *news = provider_list_add (*news, - CAMEL_PROVIDER_STORE, - prov); - } - } - - if (strcmp (prov->domain, "mail")) - continue; - - if (prov->object_types[CAMEL_PROVIDER_STORE] && - prov->flags & CAMEL_PROVIDER_IS_SOURCE) { - *sources = provider_list_add (*sources, - CAMEL_PROVIDER_STORE, - prov); - } else if (prov->object_types[CAMEL_PROVIDER_TRANSPORT]) { - *transports = provider_list_add (*transports, - CAMEL_PROVIDER_TRANSPORT, - prov); - } - } -} - -/* Utility routines */ -static GdkImlibImage * -load_image (const char *name) -{ - char *path; - GdkImlibImage *image; - - path = g_strdup_printf (EVOLUTION_ICONSDIR "/%s", name); - image = gdk_imlib_load_image (path); - g_free (path); - - return image; -} - -/* Identity Page */ -static void -identity_page_changed (GtkWidget *widget, MailDialogIdentityPage *page) -{ - gchar *name, *addr; - - name = e_utf8_gtk_editable_get_chars (GTK_EDITABLE (page->name), 0, -1); - addr = e_utf8_gtk_editable_get_chars (GTK_EDITABLE (page->address), 0, -1); - - if (addr && *addr && name && *name && page->donecb) - page->donecb (page, page->donedata); - else if (page->undonecb) - page->undonecb (page, page->undonedata); - - g_free (name); - g_free (addr); -} - -static MailConfigIdentity * -identity_page_extract (MailDialogIdentityPage *page) -{ - MailConfigIdentity *id = g_new0 (MailConfigIdentity, 1); - - id->name = e_utf8_gtk_editable_get_chars (GTK_EDITABLE (page->name), 0, -1); - id->address = e_utf8_gtk_editable_get_chars (GTK_EDITABLE (page->address), 0, -1); - id->org = e_utf8_gtk_editable_get_chars (GTK_EDITABLE (page->org), 0, -1); - id->sig = e_utf8_gtk_editable_get_chars (GTK_EDITABLE (page->sig), 0, -1); - - return id; -} - -static void -identity_page_set_undone_cb (MailDialogIdentityPage *page, - IdentityPageCallback cb, gpointer data) -{ - page->undonecb = cb; - page->undonedata = data; -} - -static void -identity_page_set_done_cb (MailDialogIdentityPage *page, - IdentityPageCallback cb, gpointer data) -{ - page->donecb = cb; - page->donedata = data; -} - -static MailDialogIdentityPage * -identity_page_new (const MailConfigIdentity *id) -{ - MailDialogIdentityPage *page = g_new0 (MailDialogIdentityPage, 1); - GtkWidget *html, *table; - GtkWidget *label, *fentry, *hsep; - gchar *user = NULL; - gboolean new = !id; - - page->vbox = gtk_vbox_new (FALSE, 5); - - html = html_new (FALSE); - put_html (GTK_HTML (html), - _("Enter your name and email address to be used in " - "outgoing mail. You may also, optionally, enter the " - "name of your organization, and the name of a file " - "to read your signature from.")); - gtk_box_pack_start (GTK_BOX (page->vbox), html->parent, - FALSE, TRUE, 0); - - table = gtk_table_new (5, 2, FALSE); - gtk_table_set_row_spacings (GTK_TABLE (table), 10); - gtk_table_set_col_spacings (GTK_TABLE (table), 6); - gtk_container_set_border_width (GTK_CONTAINER (table), 8); - gtk_box_pack_start (GTK_BOX (page->vbox), table, FALSE, FALSE, 0); - - label = gtk_label_new (_("Full name:")); - gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1, - GTK_FILL, 0, 0, 0); - gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5); - - page->name = gtk_entry_new (); - gtk_table_attach (GTK_TABLE (table), page->name, 1, 2, 0, 1, - GTK_EXPAND | GTK_FILL, 0, 0, 0); - - if (!id || !id->name) - user = g_get_real_name (); - - if ((id && id->name) || user) { - char *name; - - if (id && id->name) - name = g_strdup (id->name); - else - name = g_strdup (user); - - e_utf8_gtk_entry_set_text (GTK_ENTRY (page->name), name); - g_free (name); - } - - label = gtk_label_new (_("Email address:")); - gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2, - GTK_FILL, 0, 0, 0); - gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5); - - page->address = gtk_entry_new (); - if (id && id->address) - e_utf8_gtk_entry_set_text (GTK_ENTRY (page->address), id->address); - gtk_table_attach (GTK_TABLE (table), page->address, 1, 2, 1, 2, - GTK_EXPAND | GTK_FILL, 0, 0, 0); - - hsep = gtk_hseparator_new (); - gtk_table_attach (GTK_TABLE (table), hsep, 0, 2, 2, 3, - GTK_FILL, 0, 0, 8); - - label = gtk_label_new (_("Organization:")); - gtk_table_attach (GTK_TABLE (table), label, 0, 1, 3, 4, - GTK_FILL, 0, 0, 0); - gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5); - - page->org = gtk_entry_new (); - if (id && id->org) - e_utf8_gtk_entry_set_text (GTK_ENTRY (page->org), id->org); - gtk_table_attach (GTK_TABLE (table), page->org, 1, 2, 3, 4, - GTK_EXPAND | GTK_FILL, 0, 0, 0); - - label = gtk_label_new (_("Signature file:")); - gtk_table_attach (GTK_TABLE (table), label, 0, 1, 4, 5, - GTK_FILL, GTK_FILL, 0, 0); - gtk_misc_set_alignment (GTK_MISC (label), 1, 0); - - fentry = gnome_file_entry_new (NULL, _("Signature File")); - page->sig = gnome_file_entry_gtk_entry (GNOME_FILE_ENTRY (fentry)); - if (id && id->sig) { - e_utf8_gtk_entry_set_text (GTK_ENTRY (page->sig), id->sig); - } else { - gchar *default_sig; - - default_sig = g_strconcat (g_get_home_dir (), - G_DIR_SEPARATOR_S, - ".signature", NULL); - if (g_file_exists (default_sig)) - e_utf8_gtk_entry_set_text (GTK_ENTRY (page->sig), default_sig); - g_free (default_sig); - } - - gtk_table_attach (GTK_TABLE (table), fentry, 1, 2, 4, 5, - GTK_FILL, 0, 0, 0); - gnome_file_entry_set_default_path (GNOME_FILE_ENTRY (fentry), - g_get_home_dir ()); - - gtk_signal_connect (GTK_OBJECT (page->name), "changed", - GTK_SIGNAL_FUNC (identity_page_changed), page); - gtk_signal_connect (GTK_OBJECT (page->address), "changed", - GTK_SIGNAL_FUNC (identity_page_changed), page); - if (!new) { - gtk_signal_connect (GTK_OBJECT (page->org), "changed", - GTK_SIGNAL_FUNC (identity_page_changed), - page); - gtk_signal_connect (GTK_OBJECT (page->sig), "changed", - GTK_SIGNAL_FUNC (identity_page_changed), - page); - } - - gtk_widget_show_all (table); - - return page; -} - -/* Service page */ -static MailDialogServicePageItem * -service_page_item_by_protocol (MailDialogServicePage *page, gchar *protocol) -{ - MailDialogServicePageItem *spitem; - gint len, i; - - len = g_list_length (page->items); - for (i = 0; i < len; i++) { - spitem = (MailDialogServicePageItem *) - g_list_nth_data (page->items, i); - if (!g_strcasecmp (spitem->protocol, protocol)) - return spitem; - } - - return NULL; -} - -static MailDialogServicePageItem * -service_page_item_by_menuitem (MailDialogServicePage *page, - GtkWidget *menuitem) -{ - MailDialogServicePageItem *spitem; - gint len, i; - - len = g_list_length (page->items); - for (i = 0; i < len; i++) { - spitem = (MailDialogServicePageItem *) - g_list_nth_data (page->items, i); - if (spitem->item == menuitem) - return spitem; - } - - return NULL; -} - -static char * -service_page_get_url (MailDialogServicePage *page) -{ - MailDialogServicePageItem *spitem; - CamelURL *url; - char *url_str; - - spitem = page->spitem; - - url = g_new0 (CamelURL, 1); - url->protocol = g_strdup (spitem->protocol); - - if (spitem->user) { - char *user = e_utf8_gtk_editable_get_chars (GTK_EDITABLE (spitem->user), 0, -1); - if (user && *user) { - url->user = user; - } - else { - url->user = NULL; - g_free (user); - } - } - if (spitem->host) { - char *p; - - url->host = e_utf8_gtk_editable_get_chars (GTK_EDITABLE (spitem->host), 0, -1); - p = strchr (url->host, ':'); - if (p) { - *p++ = '\0'; - url->port = atoi (p); - } - } - - if (spitem->path) { - gchar *path; - path = e_utf8_gtk_editable_get_chars (GTK_EDITABLE (spitem->path), - 0, -1); - url->path = g_strdup_printf ("%s%s", url->host ? "/" : "", - path); - g_free (path); - } - - if (spitem->auth_optionmenu) { - GtkWidget *menu, *item; - CamelServiceAuthType *authtype; - - menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (spitem->auth_optionmenu)); - if (menu) { - item = gtk_menu_get_active (GTK_MENU (menu)); - authtype = gtk_object_get_data (GTK_OBJECT (item), - "authtype"); - if (*authtype->authproto) - url->authmech = g_strdup (authtype->authproto); - } - } - - url_str = camel_url_to_string (url, FALSE); - camel_url_free (url); - - return url_str; -} - -static void -service_page_set_url (MailDialogServicePage *page, MailConfigService *service) -{ - CamelURL *url; - CamelException *ex; - MailDialogServicePageItem *spitem = NULL; - - if (!service || !service->url) - return; - - ex = camel_exception_new (); - - url = camel_url_new (service->url, ex); - if (camel_exception_get_id (ex) != CAMEL_EXCEPTION_NONE) { - camel_exception_free (ex); - return; - } - - /* Find the right protocol */ - spitem = service_page_item_by_protocol (page, url->protocol); - service_page_menuitem_activate (spitem->item, page); - gtk_option_menu_set_history (GTK_OPTION_MENU (page->optionmenu), - spitem->pnum); - - if (spitem->user && url && url->user) - e_utf8_gtk_entry_set_text (GTK_ENTRY (spitem->user), url->user); - - if (spitem->host && url && url->host) { - if (url->port) { - char *hostport; - hostport = g_strdup_printf ("%s:%d", url->host, - url->port); - e_utf8_gtk_entry_set_text (GTK_ENTRY (spitem->host), - hostport); - } else { - e_utf8_gtk_entry_set_text (GTK_ENTRY (spitem->host), - url->host); - } - } - - if (spitem->path && url && url->path) { - if (url->host && *url->path) - e_utf8_gtk_entry_set_text (GTK_ENTRY (spitem->path), - url->path + 1); - else - e_utf8_gtk_entry_set_text (GTK_ENTRY (spitem->path), - url->path); - } - - /* Set the auth menu */ - if (spitem->auth_optionmenu) { - GtkWidget *menu, *item; - CamelServiceAuthType *authtype; - gint len, i; - - menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (spitem->auth_optionmenu)); - len = g_list_length (spitem->auth_items); - for (i = 0; i < len; i++) { - item = g_list_nth_data (spitem->auth_items, i); - authtype = gtk_object_get_data (GTK_OBJECT (item), - "authtype"); - - if ((!url->authmech && !*authtype->authproto) || - (url->authmech && - !strcmp (authtype->authproto, url->authmech))) { - - service_page_item_auth_activate (item, spitem); - gtk_option_menu_set_history (GTK_OPTION_MENU (spitem->auth_optionmenu), i); - } - } - } - - if (spitem->keep_on_server) - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (spitem->keep_on_server), service->keep_on_server); - - camel_exception_free (ex); - camel_url_free (url); -} - -static void -service_page_item_auth_activate (GtkWidget *menuitem, - MailDialogServicePageItem *spitem) -{ - CamelServiceAuthType *authtype; - - authtype = gtk_object_get_data (GTK_OBJECT (menuitem), "authtype"); - put_html (GTK_HTML (spitem->auth_html), - _(authtype->description)); -} - -static void -service_page_item_auth_fill (MailDialogServicePage *page, - MailDialogServicePageItem *spitem, - GList *authtypes) -{ - CamelServiceAuthType *authtype; - GtkWidget *menu, *item, *firstitem = NULL; - - menu = gtk_menu_new (); - for (; authtypes; authtypes = authtypes->next) { - authtype = authtypes->data; - - item = gtk_menu_item_new_with_label (_(authtype->name)); - if (!firstitem) - firstitem = item; - spitem->auth_items = g_list_append (spitem->auth_items, item); - - gtk_menu_append (GTK_MENU (menu), item); - gtk_object_set_data (GTK_OBJECT (item), "authtype", authtype); - - gtk_signal_connect (GTK_OBJECT (item), "activate", - GTK_SIGNAL_FUNC (service_page_item_auth_activate), - spitem); - gtk_signal_connect (GTK_OBJECT (item), "activate", - GTK_SIGNAL_FUNC (service_page_item_changed), - page); - } - gtk_widget_show_all (menu); - - gtk_option_menu_set_menu (GTK_OPTION_MENU (spitem->auth_optionmenu), - menu); - gtk_option_menu_set_history (GTK_OPTION_MENU (spitem->auth_optionmenu), 0); - gtk_widget_set_sensitive (spitem->auth_optionmenu, TRUE); - if (firstitem) - service_page_item_auth_activate (firstitem, spitem); -} - -static void -service_acceptable (MailDialogServicePage *page) -{ - char *url; - - url = service_page_get_url (page); - config_do_test_service (url, page->spitem->type); - g_free (url); -} - -static MailConfigService * -service_page_extract (MailDialogServicePage *page) -{ - MailConfigService *source = g_new0 (MailConfigService, 1); - MailDialogServicePageItem *spitem = page->spitem; - - source->url = service_page_get_url (page); - if (spitem->keep_on_server) { - source->keep_on_server = gtk_toggle_button_get_active ( - GTK_TOGGLE_BUTTON (spitem->keep_on_server)); - } - - return source; -} - -static void -service_page_item_changed (GtkWidget *item, MailDialogServicePage *page) -{ - MailDialogServicePageItem *spitem; - char *data; - gboolean complete = TRUE; - - spitem = page->spitem; - - if (complete && page->changedcb) { - page->changedcb (page, page->changeddata); - } - - if (spitem->host && spitem->hostneed) { - data = e_utf8_gtk_editable_get_chars (GTK_EDITABLE (spitem->host), 0, -1); - if (!data || !*data) - complete = FALSE; - g_free (data); - } - - if (complete) { - if (spitem->user && spitem->userneed) { - data = e_utf8_gtk_editable_get_chars (GTK_EDITABLE (spitem->user), 0, -1); - if (!data || !*data) - complete = FALSE; - g_free (data); - } - } - - if (complete) { - if (spitem->path && spitem->pathneed) { - data = e_utf8_gtk_editable_get_chars (GTK_EDITABLE (spitem->path), 0, -1); - if (!data || !*data) - complete = FALSE; - g_free (data); - } - } - - if (spitem->auth_detect) - gtk_widget_set_sensitive (spitem->auth_detect, complete); - - if (complete && page->donecb) { - page->donecb (page, page->donedata); - } else if (!complete && page->undonecb) { - page->undonecb (page, page->undonedata); - } -} - -static void -service_page_detect (GtkWidget *button, MailDialogServicePage *page) -{ - MailDialogServicePageItem *spitem; - char *url = NULL; - - spitem = page->spitem; - url = service_page_get_url (page); - - config_do_query_authtypes (page, url, spitem); -} - -static void -service_page_item_test (GtkWidget *button, MailDialogServicePage *page) -{ - service_acceptable (page); -} - -static GtkWidget * -service_page_add_elem (MailDialogServicePage *page, GtkWidget *table, - int row, const char *label_text) -{ - GtkWidget *label, *entry; - - label = gtk_label_new (label_text); - gtk_table_attach (GTK_TABLE (table), label, 0, 1, - row, row + 1, GTK_FILL, 0, 0, 0); - gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5); - - entry = gtk_entry_new (); - gtk_table_attach (GTK_TABLE (table), entry, 1, 3, row, row + 1, - GTK_EXPAND | GTK_FILL, 0, 0, 0); - - gtk_signal_connect (GTK_OBJECT (entry), "changed", - GTK_SIGNAL_FUNC (service_page_item_changed), page); - - return entry; -} - -static MailDialogServicePageItem * -service_page_item_new (MailDialogServicePage *page, MailService *mcs) -{ - MailDialogServicePageItem *item; - GtkWidget *table, *description; - int row, service_flags; - - item = g_new0 (MailDialogServicePageItem, 1); - - item->vbox = gtk_vbox_new (FALSE, 0); - - /* Description */ - description = html_new (TRUE); - put_html (GTK_HTML (description), _(mcs->provider->description)); - gtk_box_pack_start (GTK_BOX (item->vbox), - description->parent->parent, - TRUE, TRUE, 0); - - table = gtk_table_new (6, 3, FALSE); - gtk_table_set_row_spacings (GTK_TABLE (table), 2); - gtk_table_set_col_spacings (GTK_TABLE (table), 10); - gtk_container_set_border_width (GTK_CONTAINER (table), 8); - gtk_box_pack_start (GTK_BOX (item->vbox), table, TRUE, TRUE, 0); - - item->protocol = g_strdup (mcs->provider->protocol); - item->type = mcs->type; - - row = 0; - service_flags = mcs->service->provider->url_flags & ~CAMEL_URL_NEED_AUTH; - - if (service_flags & CAMEL_URL_ALLOW_HOST) { - item->host = service_page_add_elem (page, table, row++, _("Server:")); - item->hostneed = ((service_flags & CAMEL_URL_NEED_HOST) - == CAMEL_URL_NEED_HOST); - } - - if (service_flags & CAMEL_URL_ALLOW_USER) { - item->user = service_page_add_elem (page, table, row++, _("Username:")); - item->userneed = ((service_flags & CAMEL_URL_NEED_USER) - == CAMEL_URL_NEED_USER); - } - - if (service_flags & CAMEL_URL_ALLOW_PATH) { - item->path = service_page_add_elem (page, table, row++, _("Path:")); - item->pathneed = ((service_flags & CAMEL_URL_NEED_PATH) - == CAMEL_URL_NEED_PATH); - } - - if (mcs->service->provider->url_flags & CAMEL_URL_ALLOW_AUTH) { - GtkWidget *label; - gchar *url; - - label = gtk_label_new (_("Authentication:")); - gtk_table_attach (GTK_TABLE (table), label, 0, 1, - row, row + 1, GTK_FILL, 0, 0, 0); - gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5); - - item->auth_optionmenu = gtk_option_menu_new (); - - gtk_table_attach (GTK_TABLE (table), - item->auth_optionmenu, - 1, 2, row, row + 1, - GTK_EXPAND | GTK_FILL, 0, - 0, 0); - - item->auth_detect = gtk_button_new_with_label (_("Detect supported types...")); - gtk_table_attach (GTK_TABLE (table), item->auth_detect, - 2, 3, row, row + 1, - GTK_FILL | GTK_EXPAND, 0, - 0, 0); - gtk_widget_set_sensitive (item->auth_detect, FALSE); - gtk_signal_connect (GTK_OBJECT (item->auth_detect), - "clicked", - GTK_SIGNAL_FUNC (service_page_detect), - page); - - item->auth_html = html_new (TRUE); - gtk_table_attach (GTK_TABLE (table), - item->auth_html->parent->parent, - 0, 3, row + 1, row + 2, - GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); - - /* this is done async */ - url = camel_url_to_string (mcs->service->url, FALSE); - config_do_query_authtypes (page, url, item); - g_free (url); - row += 2; - } - - if ((mcs->provider->flags & CAMEL_PROVIDER_IS_REMOTE) && - !(mcs->provider->flags & CAMEL_PROVIDER_IS_STORAGE)) { - item->keep_on_server = gtk_check_button_new_with_label ( - _("Don't delete messages from server")); - gtk_signal_connect (GTK_OBJECT (item->keep_on_server), "toggled", - GTK_SIGNAL_FUNC (service_page_item_changed), - page); - gtk_table_attach (GTK_TABLE (table), item->keep_on_server, - 0, 3, row, row + 1, GTK_FILL, 0, 0, 0); - row++; - } - - if (row != 0) { - GtkWidget *btn; - - btn = gtk_button_new_with_label (_("Test Settings")); - - gtk_table_attach (GTK_TABLE (table), btn, 2, 3, - row, row + 1, GTK_FILL, GTK_FILL, 0, 0); - - gtk_signal_connect (GTK_OBJECT (btn), "clicked", - GTK_SIGNAL_FUNC (service_page_item_test), - page); - row += 1; - } - - gtk_table_resize (GTK_TABLE (table), row, 3); - gtk_widget_show_all (table); - - return item; -} - -static void -service_page_menuitem_activate (GtkWidget *item, MailDialogServicePage *page) -{ - MailDialogServicePageItem *spitem; - - spitem = service_page_item_by_menuitem (page, item); - - g_return_if_fail (spitem); - - gtk_notebook_set_page (GTK_NOTEBOOK (page->notebook), spitem->pnum); - page->spitem = spitem; - - service_page_item_changed (item, page); -} - -static void -service_page_set_changed_cb (MailDialogServicePage *page, - ServicePageCallback cb, gpointer data) -{ - page->changedcb = cb; - page->changeddata = data; -} - -static void -service_page_set_undone_cb (MailDialogServicePage *page, - ServicePageCallback cb, gpointer data) -{ - page->undonecb = cb; - page->undonedata = data; -} - -static void -service_page_set_done_cb (MailDialogServicePage *page, - ServicePageCallback cb, gpointer data) -{ - page->donecb = cb; - page->donedata = data; -} - -static MailDialogServicePage * -service_page_new (const char *label_text, GSList *services) -{ - MailDialogServicePage *page; - GtkWidget *hbox, *label, *menu; - GtkWidget *first_item = NULL; - int pnum; - GSList *s; - - page = g_new0 (MailDialogServicePage, 1); - - page->vbox = gtk_vbox_new (FALSE, 5); - - hbox = gtk_hbox_new (FALSE, 8); - gtk_box_pack_start (GTK_BOX (page->vbox), hbox, FALSE, TRUE, 0); - - label = gtk_label_new (label_text); - gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); - gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5); - - page->optionmenu = gtk_option_menu_new (); - menu = gtk_menu_new (); - gtk_box_pack_start (GTK_BOX (hbox), page->optionmenu, TRUE, TRUE, 0); - - /* Notebook */ - page->notebook = gtk_notebook_new (); - gtk_notebook_set_show_tabs (GTK_NOTEBOOK (page->notebook), FALSE); - gtk_box_pack_start (GTK_BOX (page->vbox), page->notebook, - TRUE, TRUE, 0); - - /* Build the list of services and the service item pages */ - for (s = services, pnum = 0; s; s = s->next, pnum++) { - MailService *mcs = s->data; - MailDialogServicePageItem *spitem; - - spitem = service_page_item_new (page, mcs); - spitem->pnum = pnum; - - gtk_notebook_append_page (GTK_NOTEBOOK (page->notebook), - spitem->vbox, NULL); - - spitem->item = gtk_menu_item_new_with_label (_(mcs->provider->name)); - if (!first_item) - first_item = spitem->item; - - gtk_signal_connect (GTK_OBJECT (spitem->item), "activate", - GTK_SIGNAL_FUNC (service_page_menuitem_activate), - page); - - gtk_menu_append (GTK_MENU (menu), spitem->item); - page->items = g_list_append (page->items, spitem); - - gtk_widget_show (spitem->item); - } - - gtk_option_menu_set_menu (GTK_OPTION_MENU (page->optionmenu), menu); - service_page_menuitem_activate (first_item, page); - gtk_option_menu_set_history (GTK_OPTION_MENU (page->optionmenu), 0); - - gtk_widget_show_all (page->vbox); - - return page; -} - -/* Source Page */ -static MailDialogSourcePage * -source_page_new (GSList *sources) -{ - MailDialogSourcePage *page = g_new0 (MailDialogSourcePage, 1); - GtkWidget *html; - - page->page = service_page_new (_("Mail source type:"), sources); - page->vbox = page->page->vbox; - - html = html_new (FALSE); - put_html (GTK_HTML (html), - _("Select the kind of mail server you have, and enter " - "the relevant information about it.\n\nIf the server " - "requires authentication, you can click the " - "\"Detect supported types...\" button after entering " - "the other information.")); - gtk_box_pack_start (GTK_BOX (page->vbox), html->parent, - FALSE, TRUE, 0); - gtk_box_reorder_child (GTK_BOX (page->vbox), html->parent, 0); - - return page; -} - -/* News Page */ -static MailDialogNewsPage * -news_page_new (GSList *sources) -{ - MailDialogNewsPage *page = g_new0 (MailDialogNewsPage, 1); - GtkWidget *html; - - page->page = service_page_new (_("News source type:"), sources); - page->vbox = page->page->vbox; - - html = html_new (FALSE); - put_html (GTK_HTML (html), - _("Select the kind of news server you have, and enter " - "the relevant information about it.\n\nIf the server " - "requires authentication, you can click the " - "\"Detect supported types...\" button after entering " - "the other information.")); - gtk_box_pack_start (GTK_BOX (page->vbox), html->parent, - FALSE, TRUE, 0); - gtk_box_reorder_child (GTK_BOX (page->vbox), html->parent, 0); - - return page; -} - -/* Transport page */ -static MailDialogTransportPage * -transport_page_new (GSList *transports) -{ - MailDialogTransportPage *page = g_new0 (MailDialogTransportPage, 1); - GtkWidget *html; - - page->page = service_page_new (_("Mail transport type:"), transports); - page->vbox = page->page->vbox; - - html = html_new (FALSE); - put_html (GTK_HTML (html), - _("Select the kind of mail server you have, and enter " - "the relevant information about it.\n\nIf the server " - "requires authentication, you can click the " - "\"Detect supported types...\" button after entering " - "the other information.")); - gtk_box_pack_start (GTK_BOX (page->vbox), html->parent, - FALSE, TRUE, 0); - gtk_box_reorder_child (GTK_BOX (page->vbox), html->parent, 0); - - return page; -} - -/* Identity dialog */ -static void -iddialog_page_undone (MailDialogIdentityPage *page, gpointer data) -{ - MailDialogIdentity *iddialog = (MailDialogIdentity *)data; - - gnome_dialog_set_sensitive (GNOME_DIALOG (iddialog->dialog), 0, FALSE); -} - -static void -iddialog_page_done (MailDialogIdentityPage *page, gpointer data) -{ - MailDialogIdentity *iddialog = (MailDialogIdentity *)data; - - gnome_dialog_set_sensitive (GNOME_DIALOG (iddialog->dialog), 0, TRUE); -} - -static void -iddialog_ok_clicked (GtkWidget *dialog, MailDialogIdentity *iddialog) -{ - g_return_if_fail (iddialog); - - iddialog->id = identity_page_extract (iddialog->page); -} - -static MailConfigIdentity * -identity_dialog (const MailConfigIdentity *id, GtkWidget *parent) - -{ - MailDialogIdentity *iddialog; - MailConfigIdentity *returnid; - GtkWidget *dialog_vbox; - GtkWidget *area; - gboolean new = !id; - - iddialog = g_new0 (MailDialogIdentity, 1); - - if (new) - iddialog->dialog = gnome_dialog_new (_("Add Identity"), NULL); - else - iddialog->dialog = gnome_dialog_new (_("Edit Identity"), NULL); - - gtk_window_set_modal (GTK_WINDOW (iddialog->dialog), TRUE); - gtk_window_set_policy (GTK_WINDOW (iddialog->dialog), - FALSE, TRUE, FALSE); - gnome_dialog_set_parent (GNOME_DIALOG (iddialog->dialog), - GTK_WINDOW (parent)); - - /* Create the vbox that we will pack the identity widget into */ - dialog_vbox = GNOME_DIALOG (iddialog->dialog)->vbox; - gtk_widget_show (dialog_vbox); - - /* Get the identity widget */ - iddialog->page = identity_page_new (id); - gnome_dialog_editable_enters (GNOME_DIALOG (iddialog->dialog), - GTK_EDITABLE (iddialog->page->name)); - gnome_dialog_editable_enters (GNOME_DIALOG (iddialog->dialog), - GTK_EDITABLE (iddialog->page->address)); - gnome_dialog_editable_enters (GNOME_DIALOG (iddialog->dialog), - GTK_EDITABLE (iddialog->page->org)); - gtk_box_pack_start (GTK_BOX (dialog_vbox), - iddialog->page->vbox, TRUE, TRUE, 0); - - identity_page_set_undone_cb (iddialog->page, - iddialog_page_undone, - iddialog); - identity_page_set_done_cb (iddialog->page, - iddialog_page_done, - iddialog); - gtk_widget_show (iddialog->page->vbox); - - /* Buttons */ - area = GNOME_DIALOG (iddialog->dialog)->action_area; - gtk_widget_show (area); - gtk_button_box_set_layout (GTK_BUTTON_BOX (area), GTK_BUTTONBOX_END); - gtk_button_box_set_spacing (GTK_BUTTON_BOX (area), 8); - - gnome_dialog_append_button (GNOME_DIALOG (iddialog->dialog), - GNOME_STOCK_BUTTON_OK); - gnome_dialog_append_button (GNOME_DIALOG (iddialog->dialog), - GNOME_STOCK_BUTTON_CANCEL); - - gnome_dialog_set_default (GNOME_DIALOG (iddialog->dialog), 0); -/* gnome_dialog_set_default (GNOME_DIALOG (iddialog->dialog), 1); */ - - gnome_dialog_set_sensitive (GNOME_DIALOG (iddialog->dialog), 0, FALSE); - - gnome_dialog_button_connect( GNOME_DIALOG (iddialog->dialog), 0, - GTK_SIGNAL_FUNC (iddialog_ok_clicked), - iddialog); - - gnome_dialog_run_and_close (GNOME_DIALOG (iddialog->dialog)); - - returnid = iddialog->id; - g_free (iddialog); - - return returnid; -} - -/* Source Dialog */ -static void -sdialog_page_undone (MailDialogServicePage *page, gpointer data) -{ - MailDialogSource *sdialog = (MailDialogSource *)data; - - gnome_dialog_set_sensitive (GNOME_DIALOG (sdialog->dialog), 0, FALSE); -} - -static void -sdialog_page_done (MailDialogServicePage *page, gpointer data) -{ - MailDialogSource *sdialog = (MailDialogSource *)data; - - gnome_dialog_set_sensitive (GNOME_DIALOG (sdialog->dialog), 0, TRUE); -} - -static void -sdialog_ok_clicked (GtkWidget *widget, MailDialogSource *sdialog) -{ - g_return_if_fail (sdialog); - - sdialog->source = service_page_extract (sdialog->page->page); -} - -static MailConfigService * -source_dialog (MailConfigService *source, GtkWidget *parent) -{ - MailDialogSource *sdialog; - MailConfigService *returnsource; - GtkWidget *dialog_vbox, *area; - GSList *sources, *news, *transports; - gboolean new = !source; - - sdialog = g_new0 (MailDialogSource, 1); - - provider_list (&sources, &news, &transports); - - if (new) - sdialog->dialog = gnome_dialog_new (_("Add Source"), NULL); - else - sdialog->dialog = gnome_dialog_new (_("Edit Source"), NULL); - - gtk_window_set_modal (GTK_WINDOW (sdialog->dialog), TRUE); - gtk_window_set_policy (GTK_WINDOW (sdialog->dialog), - FALSE, TRUE, FALSE); - gtk_window_set_default_size (GTK_WINDOW (sdialog->dialog), 380, 450); - gnome_dialog_set_parent (GNOME_DIALOG (sdialog->dialog), - GTK_WINDOW (parent)); - - /* Create the vbox that we will pack the identity widget into */ - dialog_vbox = GNOME_DIALOG (sdialog->dialog)->vbox; - gtk_widget_show (dialog_vbox); - - /* Get the identity widget */ - sdialog->page = source_page_new (sources); - if (!new) - service_page_set_url (sdialog->page->page, source); - gtk_box_pack_start (GTK_BOX (dialog_vbox), sdialog->page->vbox, - TRUE, TRUE, 0); - - service_page_set_undone_cb (sdialog->page->page, - sdialog_page_undone, - sdialog); - service_page_set_done_cb (sdialog->page->page, - sdialog_page_done, - sdialog); - gtk_widget_show (sdialog->page->vbox); - - /* Buttons */ - area = GNOME_DIALOG (sdialog->dialog)->action_area; - gtk_widget_show (area); - gtk_button_box_set_layout (GTK_BUTTON_BOX (area), GTK_BUTTONBOX_END); - gtk_button_box_set_spacing (GTK_BUTTON_BOX (area), 8); - - gnome_dialog_append_button (GNOME_DIALOG (sdialog->dialog), - GNOME_STOCK_BUTTON_OK); - gnome_dialog_append_button (GNOME_DIALOG (sdialog->dialog), - GNOME_STOCK_BUTTON_CANCEL); - - gnome_dialog_set_default (GNOME_DIALOG (sdialog->dialog), 0); - gnome_dialog_set_default (GNOME_DIALOG (sdialog->dialog), 1); - - gnome_dialog_set_sensitive (GNOME_DIALOG (sdialog->dialog), 0, FALSE); - - gnome_dialog_button_connect(GNOME_DIALOG (sdialog->dialog), 0, - GTK_SIGNAL_FUNC (sdialog_ok_clicked), - sdialog); - - gnome_dialog_run_and_close (GNOME_DIALOG (sdialog->dialog)); - - returnsource = sdialog->source; - g_free (sdialog); - - return returnsource; -} - -/* News Dialog */ -static void -ndialog_page_undone (MailDialogServicePage *page, gpointer data) -{ - MailDialogNews *ndialog = (MailDialogNews *)data; - - gnome_dialog_set_sensitive (GNOME_DIALOG (ndialog->dialog), 0, FALSE); -} - -static void -ndialog_page_done (MailDialogServicePage *page, gpointer data) -{ - MailDialogNews *ndialog = (MailDialogNews *)data; - - gnome_dialog_set_sensitive (GNOME_DIALOG (ndialog->dialog), 0, TRUE); -} - -static void -ndialog_ok_clicked (GtkWidget *widget, MailDialogNews *ndialog) -{ - g_return_if_fail (ndialog); - - ndialog->source = service_page_extract (ndialog->page->page); -} - -static MailConfigService * -news_dialog (MailConfigService *source, GtkWidget *parent) -{ - MailDialogNews *ndialog; - MailConfigService *returnsource; - GtkWidget *dialog_vbox, *area; - GSList *sources, *news, *transports; - gboolean new = !source; - - ndialog = g_new0 (MailDialogNews, 1); - - provider_list (&sources, &news, &transports); - - if (new) - ndialog->dialog = gnome_dialog_new (_("Add News Server"), NULL); - else - ndialog->dialog = gnome_dialog_new (_("Edit News Server"), NULL); - - gtk_window_set_modal (GTK_WINDOW (ndialog->dialog), TRUE); - gtk_window_set_policy (GTK_WINDOW (ndialog->dialog), - FALSE, TRUE, FALSE); - gtk_window_set_default_size (GTK_WINDOW (ndialog->dialog), 380, 450); - gnome_dialog_set_parent (GNOME_DIALOG (ndialog->dialog), - GTK_WINDOW (parent)); - - /* Create the vbox that we will pack the identity widget into */ - dialog_vbox = GNOME_DIALOG (ndialog->dialog)->vbox; - gtk_widget_show (dialog_vbox); - - /* Get the identity widget */ - ndialog->page = news_page_new (news); - service_page_set_url (ndialog->page->page, source); - gtk_box_pack_start (GTK_BOX (dialog_vbox), ndialog->page->vbox, - TRUE, TRUE, 0); - - service_page_set_undone_cb (ndialog->page->page, - ndialog_page_undone, - ndialog); - service_page_set_done_cb (ndialog->page->page, - ndialog_page_done, - ndialog); - gtk_widget_show (ndialog->page->vbox); - - /* Buttons */ - area = GNOME_DIALOG (ndialog->dialog)->action_area; - gtk_widget_show (area); - gtk_button_box_set_layout (GTK_BUTTON_BOX (area), GTK_BUTTONBOX_END); - gtk_button_box_set_spacing (GTK_BUTTON_BOX (area), 8); - - gnome_dialog_append_button (GNOME_DIALOG (ndialog->dialog), - GNOME_STOCK_BUTTON_OK); - gnome_dialog_append_button (GNOME_DIALOG (ndialog->dialog), - GNOME_STOCK_BUTTON_CANCEL); - - gnome_dialog_set_default (GNOME_DIALOG (ndialog->dialog), 0); - gnome_dialog_set_default (GNOME_DIALOG (ndialog->dialog), 1); - - gnome_dialog_set_sensitive (GNOME_DIALOG (ndialog->dialog), 0, FALSE); - - gnome_dialog_button_connect(GNOME_DIALOG (ndialog->dialog), 0, - GTK_SIGNAL_FUNC (ndialog_ok_clicked), - ndialog); - - gnome_dialog_run_and_close (GNOME_DIALOG (ndialog->dialog)); - - returnsource = ndialog->source; - g_free (ndialog); - - return returnsource; -} - -/* Mail configuration druid */ -static gboolean -mail_druid_prepare (GnomeDruidPage *page, GnomeDruid *druid, gboolean *active) -{ - gnome_druid_set_buttons_sensitive (druid, TRUE, *active, TRUE); - - return FALSE; -} - -static void -mail_druid_identity_undone (MailDialogIdentityPage *page, gpointer data) -{ - MailDruidDialog *dialog = (MailDruidDialog *) data; - - dialog->iddone = FALSE; - gnome_druid_set_buttons_sensitive (GNOME_DRUID (dialog->druid), - TRUE, FALSE, TRUE); -} - -static void -mail_druid_identity_done (MailDialogIdentityPage *page, gpointer data) -{ - MailDruidDialog *dialog = (MailDruidDialog *) data; - - dialog->iddone = TRUE; - gnome_druid_set_buttons_sensitive (GNOME_DRUID (dialog->druid), - TRUE, TRUE, TRUE); -} - -static void -mail_druid_source_undone (MailDialogServicePage *page, gpointer data) -{ - MailDruidDialog *dialog = (MailDruidDialog *) data; - - dialog->sdone = FALSE; - gnome_druid_set_buttons_sensitive (GNOME_DRUID (dialog->druid), - TRUE, FALSE, TRUE); -} - -static void -mail_druid_source_done (MailDialogServicePage *page, gpointer data) -{ - MailDruidDialog *dialog = (MailDruidDialog *) data; - - dialog->sdone = TRUE; - gnome_druid_set_buttons_sensitive (GNOME_DRUID (dialog->druid), - TRUE, TRUE, TRUE); -} - -static void -mail_druid_transport_undone (MailDialogServicePage *page, gpointer data) -{ - MailDruidDialog *dialog = (MailDruidDialog *) data; - - dialog->tdone = FALSE; - gnome_druid_set_buttons_sensitive (GNOME_DRUID (dialog->druid), - TRUE, FALSE, TRUE); -} - -static void -mail_druid_transport_done (MailDialogServicePage *page, gpointer data) -{ - MailDruidDialog *dialog = (MailDruidDialog *) data; - - dialog->tdone = TRUE; - gnome_druid_set_buttons_sensitive (GNOME_DRUID (dialog->druid), - TRUE, TRUE, TRUE); -} - -static void -mail_druid_cancel (GnomeDruid *druid, GtkWindow *window) -{ - gtk_window_set_modal (window, FALSE); - gtk_widget_destroy (GTK_WIDGET (window)); - gtk_main_quit (); -} - -static void -mail_druid_finish (GnomeDruidPage *page, GnomeDruid *druid, - MailDruidDialog *dialog) -{ - MailConfigIdentity *id; - MailConfigService *source; - MailConfigService *transport; - GSList *mini; - - mail_config_clear (); - - /* Identity */ - id = identity_page_extract (dialog->idpage); - mail_config_add_identity (id); - - /* Source */ - source = service_page_extract (dialog->spage->page); - mail_config_add_source (source); - - mini = g_slist_prepend (NULL, source); - mail_load_storages (dialog->shell, mini); - g_slist_free (mini); - - /* Transport */ - transport = service_page_extract (dialog->tpage->page); - mail_config_set_transport (transport); - - mail_config_write (); - - mail_druid_cancel (druid, GTK_WINDOW (dialog->dialog)); -} - -void -mail_config_druid (Evolution_Shell shell) -{ - MailDruidDialog *dialog; - GnomeDruidPageStart *spage; - GnomeDruidPageFinish *fpage; - GnomeDruidPageStandard *dpage; - GSList *sources, *news, *transports; - GdkImlibImage *mail_logo, *identity_logo; - GdkImlibImage *source_logo, *transport_logo; - - provider_list (&sources, &news, &transports); - - mail_logo = load_image ("evolution-inbox.png"); - identity_logo = load_image ("malehead.png"); - source_logo = mail_logo; - transport_logo = load_image ("envelope.png"); - - dialog = g_new0 (MailDruidDialog, 1); - dialog->shell = shell; /*should ref this somewhere*/ - dialog->gui = glade_xml_new (EVOLUTION_GLADEDIR - "/mail-config-druid.glade", NULL); - dialog->dialog = glade_xml_get_widget (dialog->gui, "dialog"); - dialog->druid = glade_xml_get_widget (dialog->gui, "druid"); - - /* Cancel button */ - gtk_signal_connect (GTK_OBJECT (dialog->druid), "cancel", - GTK_SIGNAL_FUNC (mail_druid_cancel), - dialog->dialog); - - /* Start page */ - spage = GNOME_DRUID_PAGE_START (glade_xml_get_widget (dialog->gui, "startpage")); - gnome_druid_page_start_set_logo (spage, mail_logo); - - /* Identity page */ - dpage = GNOME_DRUID_PAGE_STANDARD (glade_xml_get_widget (dialog->gui, "standardpage1")); - gnome_druid_page_standard_set_logo (dpage, identity_logo); - - dialog->idpage = identity_page_new (NULL); - gtk_box_pack_start (GTK_BOX (dpage->vbox), - dialog->idpage->vbox, - TRUE, TRUE, 0); - - identity_page_set_undone_cb (dialog->idpage, - mail_druid_identity_undone, - dialog); - identity_page_set_done_cb (dialog->idpage, - mail_druid_identity_done, - dialog); - gtk_signal_connect (GTK_OBJECT (dpage), "prepare", - GTK_SIGNAL_FUNC (mail_druid_prepare), - &dialog->iddone); - gtk_widget_show (dialog->idpage->vbox); - - /* Source page */ - dpage = GNOME_DRUID_PAGE_STANDARD (glade_xml_get_widget (dialog->gui, "standardpage2")); - gnome_druid_page_standard_set_logo (dpage, source_logo); - - dialog->spage = source_page_new (sources); - gtk_box_pack_start (GTK_BOX (dpage->vbox), - dialog->spage->vbox, - TRUE, TRUE, 0); - - service_page_set_done_cb (dialog->spage->page, - mail_druid_source_done, - dialog); - service_page_set_undone_cb (dialog->spage->page, - mail_druid_source_undone, - dialog); - gtk_signal_connect (GTK_OBJECT (dpage), "prepare", - GTK_SIGNAL_FUNC (mail_druid_prepare), - &dialog->sdone); - - /* In case its already done */ - service_page_item_changed (dialog->spage->page->spitem->item, - dialog->spage->page); - - gtk_widget_show (dialog->spage->vbox); - - /* Transport page */ - dpage = GNOME_DRUID_PAGE_STANDARD (glade_xml_get_widget (dialog->gui, "standardpage3")); - gnome_druid_page_standard_set_logo (dpage, transport_logo); - - dialog->tpage = transport_page_new (transports); - gtk_box_pack_start (GTK_BOX (dpage->vbox), - dialog->tpage->vbox, - TRUE, TRUE, 0); - - service_page_set_undone_cb (dialog->tpage->page, - mail_druid_transport_undone, - dialog); - service_page_set_done_cb (dialog->tpage->page, - mail_druid_transport_done, - dialog); - gtk_signal_connect (GTK_OBJECT (dpage), "prepare", - GTK_SIGNAL_FUNC (mail_druid_prepare), - &dialog->tdone); - - /* In case its already as done as it needs to be */ - service_page_item_changed (dialog->tpage->page->spitem->item, - dialog->tpage->page); - - gtk_widget_show (dialog->tpage->vbox); - - - /* Finish page */ - fpage = GNOME_DRUID_PAGE_FINISH (glade_xml_get_widget (dialog->gui, "finishpage")); - gnome_druid_page_finish_set_logo (fpage, mail_logo); - - gtk_signal_connect (GTK_OBJECT (fpage), "finish", - GTK_SIGNAL_FUNC (mail_druid_finish), - dialog); - - /* GDK_THREADS_ENTER (); */ - gtk_main (); - /* GDK_THREADS_LEAVE (); */ -} - -/* Main configuration dialog */ -static void -identities_select_row (GtkWidget *widget, gint row, gint column, - GdkEventButton *event, MailDialog *dialog) -{ - dialog->idrow = row; -} - -static void -identities_add_clicked (GtkWidget *widget, MailDialog *dialog) -{ - MailConfigIdentity *id; - - id = identity_dialog (NULL, dialog->dialog); - if (id) { - GtkWidget *clist = dialog->clistIdentities; - gchar *text[4]; - gint row = 0; - - text[0] = id->name; - text[1] = id->address; - text[2] = id->org; - text[3] = id->sig; - - row = e_utf8_gtk_clist_append (GTK_CLIST (clist), text); - gtk_clist_set_row_data (GTK_CLIST (clist), row, id); - gtk_clist_select_row (GTK_CLIST (clist), row, 0); - dialog->maxidrow++; - - gnome_property_box_changed (GNOME_PROPERTY_BOX (dialog->dialog)); - } -} - -static void -identities_edit_clicked (GtkWidget *widget, MailDialog *dialog) -{ - MailConfigIdentity *id, *id2; - - if (dialog->idrow < 0) - return; - - id = gtk_clist_get_row_data (GTK_CLIST (dialog->clistIdentities), - dialog->idrow); - - id2 = identity_dialog (id, dialog->dialog); - if (id2) { - GtkCList *clist = GTK_CLIST (dialog->clistIdentities); - - e_utf8_gtk_clist_set_text (clist, dialog->idrow, 0, id2->name); - e_utf8_gtk_clist_set_text (clist, dialog->idrow, 1, id2->address); - e_utf8_gtk_clist_set_text (clist, dialog->idrow, 2, id2->org); - e_utf8_gtk_clist_set_text (clist, dialog->idrow, 3, id2->sig); - - gtk_clist_set_row_data (clist, dialog->idrow, id2); - - gnome_property_box_changed (GNOME_PROPERTY_BOX (dialog->dialog)); - } -} - -static void -identities_delete_clicked (GtkWidget *widget, MailDialog *dialog) -{ - GtkCList *clist; - - if (dialog->idrow == -1) - return; - - clist = GTK_CLIST (dialog->clistIdentities); - - gtk_clist_remove (clist, dialog->idrow); - dialog->maxidrow--; - - if (dialog->idrow > dialog->maxidrow) - gtk_clist_select_row (clist, dialog->maxidrow, 0); - else - gtk_clist_select_row (clist, dialog->idrow, 0); - - gnome_property_box_changed (GNOME_PROPERTY_BOX (dialog->dialog)); -} - -static void -sources_select_row (GtkWidget *widget, gint row, gint column, - GdkEventButton *event, MailDialog *dialog) -{ - dialog->srow = row; -} - -static void -sources_add_clicked (GtkWidget *widget, MailDialog *dialog) -{ - MailConfigService *source; - - source = source_dialog (NULL, dialog->dialog); - if (source) { - GtkCList *clist = GTK_CLIST (dialog->clistSources); - gchar *text[1]; - gint row = 0; - - text[0] = source->url; - - row = e_utf8_gtk_clist_append (clist, text); - gtk_clist_set_row_data (clist, row, source); - gtk_clist_select_row (clist, row, 0); - dialog->maxsrow++; - - gnome_property_box_changed (GNOME_PROPERTY_BOX (dialog->dialog)); - } -} - -static void -sources_edit_clicked (GtkWidget *widget, MailDialog *dialog) -{ - MailConfigService *source, *source2; - - if (dialog->srow < 0) - return; - - source = gtk_clist_get_row_data (GTK_CLIST (dialog->clistSources), - dialog->srow); - - source2 = source_dialog (source, dialog->dialog); - if (source2) { - GtkCList *clist = GTK_CLIST (dialog->clistSources); - - e_utf8_gtk_clist_set_text (clist, dialog->srow, 0, source2->url); - gtk_clist_set_row_data (clist, dialog->srow, source2); - - gnome_property_box_changed (GNOME_PROPERTY_BOX (dialog->dialog)); - } -} - -static void -sources_delete_clicked (GtkWidget *widget, MailDialog *dialog) -{ - GtkCList *clist; - - if (dialog->srow == -1) - return; - - clist = GTK_CLIST (dialog->clistSources); - - gtk_clist_remove (clist, dialog->srow); - dialog->maxsrow--; - - if (dialog->srow > dialog->maxsrow) - gtk_clist_select_row (clist, dialog->maxsrow, 0); - else - gtk_clist_select_row (clist, dialog->srow, 0); - - gnome_property_box_changed (GNOME_PROPERTY_BOX (dialog->dialog)); -} - -static void -news_select_row (GtkWidget *widget, gint row, gint column, - GdkEventButton *event, MailDialog *dialog) -{ - dialog->nrow = row; -} - -static void -news_add_clicked (GtkWidget *widget, MailDialog *dialog) -{ - MailConfigService *news; - - news = news_dialog (NULL, dialog->dialog); - if (news) { - GtkCList *clist = GTK_CLIST (dialog->clistNews); - gchar *text[1]; - gint row = 0; - - text[0] = news->url; - - row = e_utf8_gtk_clist_append (clist, text); - gtk_clist_set_row_data (clist, row, news); - gtk_clist_select_row (clist, row, 0); - dialog->maxnrow++; - - gnome_property_box_changed (GNOME_PROPERTY_BOX (dialog->dialog)); - } -} - -static void -news_edit_clicked (GtkWidget *widget, MailDialog *dialog) -{ - MailConfigService *news, *news2; - - if (dialog->nrow < 0) - return; - - news = gtk_clist_get_row_data (GTK_CLIST (dialog->clistNews), - dialog->nrow); - - news2 = news_dialog (news, dialog->dialog); - if (news2) { - GtkCList *clist = GTK_CLIST (dialog->clistNews); - - e_utf8_gtk_clist_set_text (clist, dialog->nrow, 0, news2->url); - gtk_clist_set_row_data (clist, dialog->nrow, news2); - - gnome_property_box_changed (GNOME_PROPERTY_BOX (dialog->dialog)); - } -} - -static void -news_delete_clicked (GtkWidget *widget, MailDialog *dialog) -{ - GtkCList *clist; - - if (dialog->nrow == -1) - return; - - clist = GTK_CLIST (dialog->clistNews); - - gtk_clist_remove (clist, dialog->nrow); - dialog->maxnrow--; - - if (dialog->nrow > dialog->maxnrow) - gtk_clist_select_row (clist, dialog->maxnrow, 0); - else - gtk_clist_select_row (clist, dialog->nrow, 0); - - gnome_property_box_changed (GNOME_PROPERTY_BOX (dialog->dialog)); -} - -static void -mail_config_tpage_changed (MailDialogServicePage *page, gpointer data) -{ - MailDialog *dialog = (MailDialog *)data; - - gnome_property_box_changed (GNOME_PROPERTY_BOX (dialog->dialog)); -} - -static void -mail_config_tpage_done (MailDialogServicePage *page, gpointer data) -{ - MailDialog *dialog = (MailDialog *)data; - - dialog->tpagedone = TRUE; -} - -static void -format_toggled (GtkWidget *widget, MailDialog *dialog) -{ - gnome_property_box_changed (GNOME_PROPERTY_BOX (dialog->dialog)); -} - -static void -timeout_changed (GtkWidget *widget, MailDialog *dialog) -{ - gnome_property_box_changed (GNOME_PROPERTY_BOX (dialog->dialog)); -} - -static void -mail_config_apply_clicked (GnomePropertyBox *property_box, - gint page_num, - MailDialog *dialog) -{ - GtkCList *clist; - GtkToggleButton *chk; - GtkSpinButton *spin; - MailConfigService *t; - gboolean send_html; - gpointer data; - glong seen_timeout; - int i; - - if (page_num != -1) - return; - - mail_config_clear (); - - /* Identities */ - for (i = 0; i <= dialog->maxidrow; i++) { - clist = GTK_CLIST (dialog->clistIdentities); - - data = gtk_clist_get_row_data (clist, i); - mail_config_add_identity ((MailConfigIdentity *) data); - } - - /* Sources */ - for (i = 0; i <= dialog->maxsrow; i++) { - GSList *mini; - - clist = GTK_CLIST (dialog->clistSources); - - data = gtk_clist_get_row_data (clist, i); - mail_config_add_source ((MailConfigService *) data); - - mini = g_slist_prepend (NULL, data); - mail_load_storages (dialog->shell, mini); - g_slist_free (mini); - } - - /* Transport */ - t = service_page_extract (dialog->page->page); - mail_config_set_transport (t); - - /* News */ - for (i = 0; i <= dialog->maxnrow; i++) { - GSList *mini; - - clist = GTK_CLIST (dialog->clistNews); - - data = gtk_clist_get_row_data (clist, i); - mail_config_add_news ((MailConfigService *) data); - - mini = g_slist_prepend (NULL, data); - mail_load_storages (dialog->shell, mini); - g_slist_free (mini); - } - - /* Format */ - chk = GTK_TOGGLE_BUTTON (dialog->chkFormat); - send_html = gtk_toggle_button_get_active (chk); - mail_config_set_send_html (send_html); - - /* Mark as seen timeout */ - spin = GTK_SPIN_BUTTON (dialog->spinTimeout); - seen_timeout = gtk_spin_button_get_value_as_int (spin); - mail_config_set_mark_as_seen_timeout (seen_timeout); - - mail_config_write (); -} - -static void -mail_config_close (GnomePropertyBox *property_box, MailDialog *dialog) -{ - gtk_object_unref (GTK_OBJECT (dialog->gui)); - g_free (dialog); -} - -void -mail_config (Evolution_Shell shell) -{ - MailDialog *dialog; - GladeXML *gui; - MailConfigService *transport; - GtkCList *clist; - GtkWidget *button, *tvbox; - GSList *l, *sources, *news, *transports; - - provider_list (&sources, &news, &transports); - - dialog = g_new0 (MailDialog, 1); - - gui = glade_xml_new (EVOLUTION_GLADEDIR "/mail-config.glade", NULL); - dialog->gui = gui; - dialog->shell = shell; - - dialog->dialog = glade_xml_get_widget (gui, "dialog"); - - /* Identities Page */ - dialog->clistIdentities = - glade_xml_get_widget (gui, "clistIdentities"); - clist = GTK_CLIST (dialog->clistIdentities); - gtk_clist_column_titles_passive (GTK_CLIST (clist)); - gtk_clist_set_column_width (clist, 0, 80); - - l = mail_config_get_identities (); - - dialog->maxidrow = g_slist_length (l) - 1; - dialog->idrow = -1; - - for (; l != NULL; l = l->next) { - MailConfigIdentity *id; - gint row; - gchar *text[4]; - - id = identity_copy ((MailConfigIdentity *)l->data); - - text[0] = id->name; - text[1] = id->address; - text[2] = id->org; - text[3] = id->sig; - - row = e_utf8_gtk_clist_append (clist, text); - gtk_clist_set_row_data_full (clist, row, id, (GtkDestroyNotify) identity_destroy); - } - - gtk_signal_connect (GTK_OBJECT (clist), "select_row", - GTK_SIGNAL_FUNC (identities_select_row), - dialog); - - button = glade_xml_get_widget (gui, "cmdIdentitiesAdd"); - gtk_signal_connect (GTK_OBJECT (button), "clicked", - GTK_SIGNAL_FUNC (identities_add_clicked), - dialog); - button = glade_xml_get_widget (gui, "cmdIdentitiesEdit"); - gtk_signal_connect (GTK_OBJECT (button), "clicked", - GTK_SIGNAL_FUNC (identities_edit_clicked), - dialog); - button = glade_xml_get_widget (gui, "cmdIdentitiesDelete"); - gtk_signal_connect (GTK_OBJECT (button), "clicked", - GTK_SIGNAL_FUNC (identities_delete_clicked), - dialog); - - /* Sources Page */ - dialog->clistSources = glade_xml_get_widget (gui, "clistSources"); - clist = GTK_CLIST (dialog->clistSources); - gtk_clist_column_titles_passive (GTK_CLIST (clist)); - gtk_clist_set_column_width (clist, 0, 80); - - l = mail_config_get_sources (); - - dialog->maxsrow = g_slist_length (l) - 1; - dialog->srow = -1; - - for (; l != NULL; l = l->next) { - MailConfigService *source; - gint row; - gchar *text[1]; - - source = service_copy ((MailConfigService *)l->data); - - text[0] = source->url; - - row = e_utf8_gtk_clist_append (clist, text); - gtk_clist_set_row_data_full (clist, row, source, (GtkDestroyNotify) service_destroy); - } - - gtk_signal_connect (GTK_OBJECT (clist), "select_row", - GTK_SIGNAL_FUNC (sources_select_row), - dialog); - - button = glade_xml_get_widget (gui, "cmdSourcesAdd"); - gtk_signal_connect (GTK_OBJECT (button), "clicked", - GTK_SIGNAL_FUNC (sources_add_clicked), - dialog); - button = glade_xml_get_widget (gui, "cmdSourcesEdit"); - gtk_signal_connect (GTK_OBJECT (button), "clicked", - GTK_SIGNAL_FUNC (sources_edit_clicked), - dialog); - button = glade_xml_get_widget (gui, "cmdSourcesDelete"); - gtk_signal_connect (GTK_OBJECT (button), "clicked", - GTK_SIGNAL_FUNC (sources_delete_clicked), - dialog); - - /* News Page */ - dialog->clistNews = glade_xml_get_widget (gui, "clistNews"); - clist = GTK_CLIST (dialog->clistNews); - gtk_clist_set_column_width (clist, 0, 80); - gtk_clist_column_titles_passive (GTK_CLIST (clist)); - - l = mail_config_get_news (); - - dialog->maxnrow = g_slist_length (l) - 1; - dialog->nrow = -1; - - for (; l != NULL; l = l->next) { - MailConfigService *news; - gint row; - gchar *text[1]; - - news = service_copy ((MailConfigService *)l->data); - - text[0] = news->url; - - row = e_utf8_gtk_clist_append (clist, text); - gtk_clist_set_row_data_full (clist, row, news, (GtkDestroyNotify) service_destroy); - } - - gtk_signal_connect (GTK_OBJECT (clist), "select_row", - GTK_SIGNAL_FUNC (news_select_row), - dialog); - - button = glade_xml_get_widget (gui, "cmdNewsServersAdd"); - gtk_signal_connect (GTK_OBJECT (button), "clicked", - GTK_SIGNAL_FUNC (news_add_clicked), - dialog); - button = glade_xml_get_widget (gui, "cmdNewsServersEdit"); - gtk_signal_connect (GTK_OBJECT (button), "clicked", - GTK_SIGNAL_FUNC (news_edit_clicked), - dialog); - button = glade_xml_get_widget (gui, "cmdNewsServersDelete"); - gtk_signal_connect (GTK_OBJECT (button), "clicked", - GTK_SIGNAL_FUNC (news_delete_clicked), - dialog); - - /* Transport Page */ - tvbox = glade_xml_get_widget (gui, "transport_vbox"); - dialog->page = transport_page_new (transports); - transport = mail_config_get_transport (); - service_page_set_url (dialog->page->page, transport); - service_page_set_changed_cb (dialog->page->page, - mail_config_tpage_changed, dialog); - service_page_set_done_cb (dialog->page->page, - mail_config_tpage_done, dialog); - gtk_box_pack_start (GTK_BOX (tvbox), - dialog->page->vbox, TRUE, TRUE, 0); - gtk_widget_show (dialog->page->vbox); - - /* Other Page */ - dialog->chkFormat = glade_xml_get_widget (gui, "chkFormat"); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->chkFormat), - mail_config_send_html ()); - gtk_signal_connect (GTK_OBJECT (dialog->chkFormat), "toggled", - GTK_SIGNAL_FUNC (format_toggled), - dialog); - - dialog->spinTimeout = glade_xml_get_widget (gui, "spinTimeout"); - gtk_spin_button_set_value (GTK_SPIN_BUTTON (dialog->spinTimeout), - mail_config_mark_as_seen_timeout ()); - - gtk_signal_connect (GTK_OBJECT (dialog->spinTimeout), "changed", - GTK_SIGNAL_FUNC (timeout_changed), - dialog); - - /* Listen for signals */ - gtk_signal_connect (GTK_OBJECT (dialog->dialog), "apply", - GTK_SIGNAL_FUNC (mail_config_apply_clicked), - dialog); - gtk_signal_connect (GTK_OBJECT (dialog->dialog), "destroy", - GTK_SIGNAL_FUNC (mail_config_close), - dialog); - gtk_signal_connect (GTK_OBJECT (dialog->dialog), "delete_event", - GTK_SIGNAL_FUNC (mail_config_close), - dialog); - - gtk_widget_show (dialog->dialog); -} - -/* ************************************************************************ */ - -typedef struct test_service_input_s { - gchar *url; - CamelProviderType type; -} test_service_input_t; - -typedef struct test_service_data_s { - gboolean success; -} test_service_data_t; - -static gchar *describe_test_service (gpointer in_data, gboolean gerund); -static void setup_test_service (gpointer in_data, gpointer op_data, CamelException *ex); -static void do_test_service (gpointer in_data, gpointer op_data, CamelException *ex); -static void cleanup_test_service (gpointer in_data, gpointer op_data, CamelException *ex); - -static gchar *describe_test_service (gpointer in_data, gboolean gerund) -{ - test_service_input_t *input = (test_service_input_t *) in_data; - - if (gerund) { - return g_strdup_printf (_("Testing \"%s\""), input->url); - } else { - return g_strdup_printf (_("Test connection to \"%s\""), input->url); - } -} - -static void setup_test_service (gpointer in_data, gpointer op_data, CamelException *ex) -{ - test_service_data_t *data = (test_service_data_t *) op_data; - - data->success = FALSE; -} - -static void do_test_service (gpointer in_data, gpointer op_data, CamelException *ex) -{ - test_service_input_t *input = (test_service_input_t *) in_data; - test_service_data_t *data = (test_service_data_t *) op_data; - - CamelService *service; - - service = camel_session_get_service (session, input->url, - input->type, ex); - - if (camel_exception_get_id (ex) != CAMEL_EXCEPTION_NONE) { - data->success = FALSE; - } else if (camel_service_connect (service, ex)) { - camel_service_disconnect (service, TRUE, ex); - data->success = TRUE; - } else { - data->success = FALSE; - } - - camel_object_unref (CAMEL_OBJECT (service)); -} - -static void cleanup_test_service (gpointer in_data, gpointer op_data, CamelException *ex) -{ - test_service_input_t *input = (test_service_input_t *) in_data; - test_service_data_t *data = (test_service_data_t *) op_data; - - GtkWidget *dlg; - - if (data->success) { - dlg = gnome_ok_dialog (_("The connection was successful!")); - gnome_dialog_run_and_close (GNOME_DIALOG (dlg)); - } - - g_free (input->url); -} - -static const mail_operation_spec op_test_service = { - describe_test_service, - sizeof (test_service_data_t), - setup_test_service, - do_test_service, - cleanup_test_service -}; - -static void -config_do_test_service (const char *url, CamelProviderType type) -{ - test_service_input_t *input; - - input = g_new (test_service_input_t, 1); - input->url = g_strdup (url); - input->type = type; - - mail_operation_queue (&op_test_service, input, TRUE); -} - -/* ************************************************************************ */ - -typedef struct query_authtypes_input_s { - MailDialogServicePage *page; - gchar *url; - MailDialogServicePageItem *item; -} query_authtypes_input_t; - -typedef struct query_authtypes_data_s { - CamelService *service; - GList *items; -} query_authtypes_data_t; - -static gchar *describe_query_authtypes (gpointer in_data, gboolean gerund); -static void setup_query_authtypes (gpointer in_data, gpointer op_data, CamelException *ex); -static void do_query_authtypes (gpointer in_data, gpointer op_data, CamelException *ex); -static void cleanup_query_authtypes (gpointer in_data, gpointer op_data, CamelException *ex); - -static gchar *describe_query_authtypes (gpointer in_data, gboolean gerund) -{ - query_authtypes_input_t *input = (query_authtypes_input_t *) in_data; - - if (gerund) { - return g_strdup_printf (_("Querying authorization capabilities of \"%s\""), input->url); - } else { - return g_strdup_printf (_("Query authorization at \"%s\""), input->url); - } -} - -static void setup_query_authtypes (gpointer in_data, gpointer op_data, CamelException *ex) -{ - query_authtypes_data_t *data = (query_authtypes_data_t *) op_data; - - data->items = NULL; - data->service = NULL; -} - -static void do_query_authtypes (gpointer in_data, gpointer op_data, CamelException *ex) -{ - query_authtypes_input_t *input = (query_authtypes_input_t *) in_data; - query_authtypes_data_t *data = (query_authtypes_data_t *) op_data; - - data->service = camel_session_get_service (session, input->url, input->item->type, ex); - if (!data->service) - return; - - data->items = camel_service_query_auth_types (data->service, ex); -} - -static void cleanup_query_authtypes (gpointer in_data, gpointer op_data, CamelException *ex) -{ - query_authtypes_input_t *input = (query_authtypes_input_t *) in_data; - query_authtypes_data_t *data = (query_authtypes_data_t *) op_data; - - if (data->items && input->item->auth_optionmenu) - service_page_item_auth_fill (input->page, input->item, data->items); - - if (data->service) { - mail_tool_camel_lock_up(); - camel_service_free_auth_types (data->service, data->items); - camel_object_unref (CAMEL_OBJECT (data->service)); - mail_tool_camel_lock_down(); - } - - g_free (input->url); -} - -static const mail_operation_spec op_query_authtypes = { - describe_query_authtypes, - sizeof (query_authtypes_data_t), - setup_query_authtypes, - do_query_authtypes, - cleanup_query_authtypes -}; - -static void -config_do_query_authtypes (MailDialogServicePage *page, const char *url, MailDialogServicePageItem *item) -{ - query_authtypes_input_t *input; - - input = g_new (query_authtypes_input_t, 1); - input->page = page; - input->url = g_strdup (url); - input->item = item; - - mail_operation_queue (&op_query_authtypes, input, TRUE); -} diff --git a/mail/mail-config-gui.h b/mail/mail-config-gui.h deleted file mode 100644 index c8cbb33207..0000000000 --- a/mail/mail-config-gui.h +++ /dev/null @@ -1,31 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Copyright 2000, Helix Code, Inc. (http://www.helixcode.com) - * - * 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 - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA. - */ - -#ifndef _MAIL_CONFIG_GUI_H -#define _MAIL_CONFIG_GUI_H - -#include <glib.h> - -#include "shell/Evolution.h" - -void mail_config (Evolution_Shell shell); -void mail_config_druid (Evolution_Shell shell); - -#endif diff --git a/mail/mail-config.c b/mail/mail-config.c deleted file mode 100644 index 73dce61f9c..0000000000 --- a/mail/mail-config.c +++ /dev/null @@ -1,572 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* mail-config.c: Mail configuration dialogs/wizard. */ - -/* - * Authors: - * Dan Winship <danw@helixcode.com> - * Jeffrey Stedfast <fejj@helixcode.com> - * JP Rosevear <jpr@helixcode.com> - * - * Copyright 2000 Helix Code, Inc. (http://www.helixcode.com) - * - * 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 the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#include <config.h> -#include <pwd.h> -#include <ctype.h> - -#include <gnome.h> -#include <gtkhtml/gtkhtml.h> -#include <glade/glade.h> - -#include "e-util/e-html-utils.h" -#include "mail.h" -#include "mail-config.h" - -typedef struct -{ - gboolean configured; - GSList *ids; - GSList *sources; - GSList *news; - MailConfigService *transport; - - gboolean thread_list; - gint paned_size; - gboolean send_html; - gint seen_timeout; -} MailConfig; - -static const char GCONFPATH[] = "/apps/Evolution/Mail"; -static MailConfig *config = NULL; - -/* Prototypes */ -static void config_read (void); - -/* Identity struct */ -MailConfigIdentity * -identity_copy (MailConfigIdentity *id) -{ - MailConfigIdentity *newid; - - g_return_val_if_fail (id, NULL); - - newid = g_new0 (MailConfigIdentity, 1); - newid->name = g_strdup (id->name); - newid->address = g_strdup (id->address); - newid->org = g_strdup (id->org); - newid->sig = g_strdup (id->sig); - - return newid; -} - -void -identity_destroy (MailConfigIdentity *id) -{ - if (!id) - return; - - g_free (id->name); - g_free (id->address); - g_free (id->org); - g_free (id->sig); - - g_free (id); -} - -void -identity_destroy_each (gpointer item, gpointer data) -{ - identity_destroy ((MailConfigIdentity *)item); -} - -/* Service struct */ -MailConfigService * -service_copy (MailConfigService *source) -{ - MailConfigService *newsource; - - g_return_val_if_fail (source, NULL); - - newsource = g_new0 (MailConfigService, 1); - newsource->url = g_strdup (source->url); - newsource->keep_on_server = source->keep_on_server; - - return newsource; -} - -void -service_destroy (MailConfigService *source) -{ - if (!source) - return; - - g_free (source->url); - - g_free (source); -} - -void -service_destroy_each (gpointer item, gpointer data) -{ - service_destroy ((MailConfigService *)item); -} - -/* Config struct routines */ -void -mail_config_init (void) -{ - if (config) - return; - - config = g_new0 (MailConfig, 1); - - config->ids = NULL; - config->sources = NULL; - config->transport = NULL; - - config_read (); -} - -void -mail_config_clear (void) -{ - if (!config) - return; - - if (config->ids) { - g_slist_foreach (config->ids, identity_destroy_each, NULL); - g_slist_free (config->ids); - config->ids = NULL; - } - - if (config->sources) { - g_slist_foreach (config->sources, service_destroy_each, NULL); - g_slist_free (config->sources); - config->sources = NULL; - } - - service_destroy (config->transport); - config->transport = NULL; - - if (config->news) { - g_slist_foreach (config->news, service_destroy_each, NULL); - g_slist_free (config->news); - config->news = NULL; - } -} - -static void -config_read (void) -{ - gchar *str; - gint len, i; - - mail_config_clear (); - - /* Configured */ - str = g_strdup_printf ("=%s/config/General=/General/configured", evolution_dir); - config->configured = gnome_config_get_bool (str); - g_free (str); - - /* Identities */ - str = g_strdup_printf ("=%s/config/Mail=/Identities/", evolution_dir); - gnome_config_push_prefix (str); - g_free (str); - - len = gnome_config_get_int ("num"); - for (i = 0; i < len; i++) { - MailConfigIdentity *id; - gchar *path; - - id = g_new0 (MailConfigIdentity, 1); - - path = g_strdup_printf ("name_%d", i); - id->name = gnome_config_get_string (path); - g_free (path); - path = g_strdup_printf ("address_%d", i); - id->address = gnome_config_get_string (path); - g_free (path); - path = g_strdup_printf ("org_%d", i); - id->org = gnome_config_get_string (path); - g_free (path); - path = g_strdup_printf ("sig_%d", i); - id->sig = gnome_config_get_string (path); - g_free (path); - - config->ids = g_slist_append (config->ids, id); - } - gnome_config_pop_prefix (); - - /* Sources */ - str = g_strdup_printf ("=%s/config/Mail=/Sources/", evolution_dir); - gnome_config_push_prefix (str); - g_free (str); - - len = gnome_config_get_int ("num"); - for (i = 0; i < len; i++) { - MailConfigService *s; - gchar *path; - - s = g_new0 (MailConfigService, 1); - - path = g_strdup_printf ("url_%d", i); - s->url = gnome_config_get_string (path); - g_free (path); - path = g_strdup_printf ("keep_on_server_%d", i); - s->keep_on_server = gnome_config_get_bool (path); - g_free (path); - - config->sources = g_slist_append (config->sources, s); - } - gnome_config_pop_prefix (); - - /* News */ - str = g_strdup_printf ("=%s/config/News=/Sources/", evolution_dir); - gnome_config_push_prefix (str); - g_free (str); - - len = gnome_config_get_int ("num"); - for (i = 0; i < len; i++) { - MailConfigService *n; - gchar *path; - - n = g_new0 (MailConfigService, 1); - - path = g_strdup_printf ("url_%d", i); - n->url = gnome_config_get_string (path); - g_free (path); - - config->news = g_slist_append (config->news, n); - } - gnome_config_pop_prefix (); - - /* Transport */ - config->transport = g_new0 (MailConfigService, 1); - str = g_strdup_printf ("=%s/config/Mail=/Transport/url", - evolution_dir); - config->transport->url = gnome_config_get_string (str); - g_free (str); - - /* Format */ - str = g_strdup_printf ("=%s/config/Mail=/Format/send_html", - evolution_dir); - config->send_html = gnome_config_get_bool (str); - g_free (str); - - /* Mark as seen timeout */ - str = g_strdup_printf ("=%s/config/Mail=/Display/seen_timeout=1500", - evolution_dir); - config->seen_timeout = gnome_config_get_int (str); - g_free (str); - - /* Show Messages Threaded */ - str = g_strdup_printf ("=%s/config/Mail=/Display/thread_list", - evolution_dir); - config->thread_list = gnome_config_get_bool (str); - g_free (str); - - /* Size of vpaned in mail view */ - str = g_strdup_printf ("=%s/config/Mail=/Display/paned_size=200", - evolution_dir); - config->paned_size = gnome_config_get_int (str); - g_free (str); - - gnome_config_sync (); -} - -void -mail_config_write (void) -{ - gchar *str; - gint len, i; - - /* Configured switch */ - str = g_strdup_printf ("=%s/config/General=/General/configured", - evolution_dir); - config->configured = TRUE; - gnome_config_set_bool (str, config->configured); - g_free (str); - - /* Identities */ - str = g_strdup_printf ("=%s/config/Mail=/Identities/", evolution_dir); - gnome_config_push_prefix (str); - g_free (str); - - len = g_slist_length (config->ids); - gnome_config_set_int ("num", len); - for (i = 0; i < len; i++) { - MailConfigIdentity *id; - gchar *path; - - id = (MailConfigIdentity *)g_slist_nth_data (config->ids, i); - - path = g_strdup_printf ("name_%d", i); - gnome_config_set_string (path, id->name); - g_free (path); - path = g_strdup_printf ("address_%d", i); - gnome_config_set_string (path, id->address); - g_free (path); - path = g_strdup_printf ("org_%d", i); - gnome_config_set_string (path, id->org); - g_free (path); - path = g_strdup_printf ("sig_%d", i); - gnome_config_set_string (path, id->sig); - g_free (path); - } - gnome_config_pop_prefix (); - - /* Sources */ - str = g_strdup_printf ("=%s/config/Mail=/Sources/", evolution_dir); - gnome_config_push_prefix (str); - g_free (str); - - len = g_slist_length (config->sources); - gnome_config_set_int ("num", len); - for (i=0; i<len; i++) { - MailConfigService *s; - gchar *path; - - s = (MailConfigService *)g_slist_nth_data (config->sources, i); - - path = g_strdup_printf ("url_%d", i); - gnome_config_set_string (path, s->url); - g_free (path); - path = g_strdup_printf ("keep_on_server_%d", i); - gnome_config_set_bool (path, s->keep_on_server); - g_free (path); - } - gnome_config_pop_prefix (); - - /* News */ - str = g_strdup_printf ("=%s/config/News=/Sources/", evolution_dir); - gnome_config_push_prefix (str); - g_free (str); - - len = g_slist_length (config->news); - gnome_config_set_int ("num", len); - for (i=0; i<len; i++) { - MailConfigService *n; - gchar *path; - - n = (MailConfigService *)g_slist_nth_data (config->news, i); - - path = g_strdup_printf ("url_%d", i); - gnome_config_set_string (path, n->url); - g_free (path); - } - gnome_config_pop_prefix (); - - /* Transport */ - str = g_strdup_printf ("=%s/config/Mail=/Transport/url", - evolution_dir); - gnome_config_set_string (str, config->transport->url); - g_free (str); - - /* Mark as seen timeout */ - str = g_strdup_printf ("=%s/config/Mail=/Display/seen_timeout", - evolution_dir); - gnome_config_set_int (str, config->seen_timeout); - g_free (str); - - /* Format */ - str = g_strdup_printf ("=%s/config/Mail=/Format/send_html", - evolution_dir); - gnome_config_set_bool (str, config->send_html); - g_free (str); - - gnome_config_sync (); -} - -void -mail_config_write_on_exit (void) -{ - gchar *str; - - /* Show Messages Threaded */ - str = g_strdup_printf ("=%s/config/Mail=/Display/thread_list", - evolution_dir); - gnome_config_set_bool (str, config->thread_list); - g_free (str); - - /* Size of vpaned in mail view */ - str = g_strdup_printf ("=%s/config/Mail=/Display/paned_size", - evolution_dir); - gnome_config_set_int (str, config->paned_size); - g_free (str); - - gnome_config_sync (); -} - -/* Accessor functions */ -gboolean -mail_config_is_configured (void) -{ - return config->configured; -} - -gboolean -mail_config_thread_list (void) -{ - return config->thread_list; -} - -void -mail_config_set_thread_list (gboolean value) -{ - config->thread_list = value; -} - -gint -mail_config_paned_size (void) -{ - return config->paned_size; -} - -void -mail_config_set_paned_size (gint value) -{ - config->paned_size = value; -} - -gboolean -mail_config_send_html (void) -{ - return config->send_html; -} - -void -mail_config_set_send_html (gboolean send_html) -{ - config->send_html = send_html; -} - -gint -mail_config_mark_as_seen_timeout (void) -{ - return config->seen_timeout; -} - -void -mail_config_set_mark_as_seen_timeout (gint timeout) -{ - config->seen_timeout = timeout; -} - -MailConfigIdentity * -mail_config_get_default_identity (void) -{ - if (!config->ids) - return NULL; - - return (MailConfigIdentity *)config->ids->data; -} - -GSList * -mail_config_get_identities (void) -{ - return config->ids; -} - -void -mail_config_add_identity (MailConfigIdentity *id) -{ - MailConfigIdentity *new_id = identity_copy (id); - - config->ids = g_slist_append (config->ids, new_id); -} - -MailConfigService * -mail_config_get_default_source (void) -{ - if (!config->sources) - return NULL; - - return (MailConfigService *)config->sources->data; -} - -GSList * -mail_config_get_sources (void) -{ - return config->sources; -} - -void -mail_config_add_source (MailConfigService *source) -{ - MailConfigService *new_source = service_copy (source); - - config->sources = g_slist_append (config->sources, new_source); -} - -MailConfigService * -mail_config_get_transport (void) -{ - return config->transport; -} - -void -mail_config_set_transport (MailConfigService *transport) -{ - if (config->transport) - service_destroy (config->transport); - - config->transport = transport; -} - -MailConfigService * -mail_config_get_default_news (void) -{ - if (!config->news) - return NULL; - - return (MailConfigService *)config->news->data; -} - -GSList * -mail_config_get_news (void) -{ - return config->news; -} - -void -mail_config_add_news (MailConfigService *news) -{ - MailConfigService *new_news = service_copy (news); - - config->news = g_slist_append (config->news, new_news); -} - -char * -mail_config_folder_to_cachename(CamelFolder *folder, const char *prefix) -{ - char *url, *p, *filename; - - url = camel_url_to_string(CAMEL_SERVICE(folder->parent_store)->url, FALSE); - for (p = url; *p; p++) { - if (!isprint((unsigned char)*p) || strchr(" /'\"`&();|<>${}!", *p)) - *p = '_'; - } - - filename = g_strdup_printf("%s/config/%s%s", evolution_dir, prefix, url); - g_free(url); - return filename; -} - - - - diff --git a/mail/mail-config.glade b/mail/mail-config.glade deleted file mode 100644 index f3f797a3b5..0000000000 --- a/mail/mail-config.glade +++ /dev/null @@ -1,496 +0,0 @@ -<?xml version="1.0"?> -<GTK-Interface> - -<project> - <name>config</name> - <program_name>config</program_name> - <directory></directory> - <source_directory>src</source_directory> - <pixmaps_directory>pixmaps</pixmaps_directory> - <language>C</language> - <gnome_support>True</gnome_support> - <gettext_support>True</gettext_support> - <output_main_file>False</output_main_file> - <output_support_files>False</output_support_files> - <output_build_files>False</output_build_files> - <output_translatable_strings>True</output_translatable_strings> - <translatable_strings_file>mail-config.glade.h</translatable_strings_file> -</project> - -<widget> - <class>GnomePropertyBox</class> - <name>dialog</name> - <width>460</width> - <height>360</height> - <position>GTK_WIN_POS_NONE</position> - <modal>False</modal> - <allow_shrink>False</allow_shrink> - <allow_grow>False</allow_grow> - <auto_shrink>False</auto_shrink> - - <widget> - <class>GtkNotebook</class> - <child_name>GnomePropertyBox:notebook</child_name> - <name>notebook</name> - <can_focus>True</can_focus> - <show_tabs>True</show_tabs> - <show_border>True</show_border> - <tab_pos>GTK_POS_TOP</tab_pos> - <scrollable>False</scrollable> - <tab_hborder>2</tab_hborder> - <tab_vborder>2</tab_vborder> - <popup_enable>False</popup_enable> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkHBox</class> - <name>hbox4</name> - <homogeneous>False</homogeneous> - <spacing>0</spacing> - - <widget> - <class>GtkScrolledWindow</class> - <name>scrolledwindow4</name> - <hscrollbar_policy>GTK_POLICY_AUTOMATIC</hscrollbar_policy> - <vscrollbar_policy>GTK_POLICY_AUTOMATIC</vscrollbar_policy> - <hupdate_policy>GTK_UPDATE_CONTINUOUS</hupdate_policy> - <vupdate_policy>GTK_UPDATE_CONTINUOUS</vupdate_policy> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkCList</class> - <name>clistIdentities</name> - <can_focus>True</can_focus> - <columns>4</columns> - <column_widths>80,80,80,80</column_widths> - <selection_mode>GTK_SELECTION_SINGLE</selection_mode> - <show_titles>True</show_titles> - <shadow_type>GTK_SHADOW_IN</shadow_type> - - <widget> - <class>GtkLabel</class> - <child_name>CList:title</child_name> - <name>label27</name> - <label>Identities</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - </widget> - - <widget> - <class>GtkLabel</class> - <child_name>CList:title</child_name> - <name>label28</name> - <label>Address</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - </widget> - - <widget> - <class>GtkLabel</class> - <child_name>CList:title</child_name> - <name>label29</name> - <label>Organization</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - </widget> - - <widget> - <class>GtkLabel</class> - <child_name>CList:title</child_name> - <name>label30</name> - <label>Signature File</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - </widget> - </widget> - </widget> - - <widget> - <class>GtkVButtonBox</class> - <name>vbuttonbox4</name> - <layout_style>GTK_BUTTONBOX_START</layout_style> - <spacing>5</spacing> - <child_min_width>85</child_min_width> - <child_min_height>27</child_min_height> - <child_ipad_x>7</child_ipad_x> - <child_ipad_y>0</child_ipad_y> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - - <widget> - <class>GtkButton</class> - <name>cmdIdentitiesAdd</name> - <can_default>True</can_default> - <can_focus>True</can_focus> - <label>Add</label> - </widget> - - <widget> - <class>GtkButton</class> - <name>cmdIdentitiesEdit</name> - <can_default>True</can_default> - <can_focus>True</can_focus> - <label>Edit</label> - </widget> - - <widget> - <class>GtkButton</class> - <name>cmdIdentitiesDelete</name> - <can_default>True</can_default> - <can_focus>True</can_focus> - <label>Delete</label> - </widget> - </widget> - </widget> - - <widget> - <class>GtkLabel</class> - <child_name>Notebook:tab</child_name> - <name>label1</name> - <label>Identities</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - </widget> - - <widget> - <class>GtkHBox</class> - <name>hbox5</name> - <homogeneous>False</homogeneous> - <spacing>0</spacing> - - <widget> - <class>GtkScrolledWindow</class> - <name>scrolledwindow5</name> - <hscrollbar_policy>GTK_POLICY_AUTOMATIC</hscrollbar_policy> - <vscrollbar_policy>GTK_POLICY_AUTOMATIC</vscrollbar_policy> - <hupdate_policy>GTK_UPDATE_CONTINUOUS</hupdate_policy> - <vupdate_policy>GTK_UPDATE_CONTINUOUS</vupdate_policy> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkCList</class> - <name>clistSources</name> - <can_focus>True</can_focus> - <columns>1</columns> - <column_widths>80</column_widths> - <selection_mode>GTK_SELECTION_SINGLE</selection_mode> - <show_titles>True</show_titles> - <shadow_type>GTK_SHADOW_IN</shadow_type> - - <widget> - <class>GtkLabel</class> - <child_name>CList:title</child_name> - <name>label31</name> - <label>Sources</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - </widget> - </widget> - </widget> - - <widget> - <class>GtkVButtonBox</class> - <name>vbuttonbox5</name> - <layout_style>GTK_BUTTONBOX_START</layout_style> - <spacing>5</spacing> - <child_min_width>85</child_min_width> - <child_min_height>27</child_min_height> - <child_ipad_x>7</child_ipad_x> - <child_ipad_y>0</child_ipad_y> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - - <widget> - <class>GtkButton</class> - <name>cmdSourcesAdd</name> - <can_default>True</can_default> - <can_focus>True</can_focus> - <label>Add</label> - </widget> - - <widget> - <class>GtkButton</class> - <name>cmdSourcesEdit</name> - <can_default>True</can_default> - <can_focus>True</can_focus> - <label>Edit</label> - </widget> - - <widget> - <class>GtkButton</class> - <name>cmdSourcesDelete</name> - <can_default>True</can_default> - <can_focus>True</can_focus> - <label>Delete</label> - </widget> - </widget> - </widget> - - <widget> - <class>GtkLabel</class> - <child_name>Notebook:tab</child_name> - <name>label2</name> - <label>Mail Sources</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - </widget> - - <widget> - <class>GtkVBox</class> - <name>transport_vbox</name> - <border_width>8</border_width> - <homogeneous>False</homogeneous> - <spacing>5</spacing> - - <widget> - <class>Placeholder</class> - </widget> - </widget> - - <widget> - <class>GtkLabel</class> - <child_name>Notebook:tab</child_name> - <name>label25</name> - <label>Mail Transport</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - </widget> - - <widget> - <class>GtkHBox</class> - <name>hbox6</name> - <homogeneous>False</homogeneous> - <spacing>0</spacing> - - <widget> - <class>GtkScrolledWindow</class> - <name>scrolledwindow6</name> - <hscrollbar_policy>GTK_POLICY_AUTOMATIC</hscrollbar_policy> - <vscrollbar_policy>GTK_POLICY_AUTOMATIC</vscrollbar_policy> - <hupdate_policy>GTK_UPDATE_CONTINUOUS</hupdate_policy> - <vupdate_policy>GTK_UPDATE_CONTINUOUS</vupdate_policy> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkCList</class> - <name>clistNews</name> - <can_focus>True</can_focus> - <columns>1</columns> - <column_widths>80</column_widths> - <selection_mode>GTK_SELECTION_SINGLE</selection_mode> - <show_titles>True</show_titles> - <shadow_type>GTK_SHADOW_IN</shadow_type> - - <widget> - <class>GtkLabel</class> - <child_name>CList:title</child_name> - <name>label33</name> - <label>News Servers</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - </widget> - </widget> - </widget> - - <widget> - <class>GtkVButtonBox</class> - <name>vbuttonbox6</name> - <layout_style>GTK_BUTTONBOX_START</layout_style> - <spacing>5</spacing> - <child_min_width>85</child_min_width> - <child_min_height>27</child_min_height> - <child_ipad_x>7</child_ipad_x> - <child_ipad_y>0</child_ipad_y> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - - <widget> - <class>GtkButton</class> - <name>cmdNewsServersAdd</name> - <can_default>True</can_default> - <can_focus>True</can_focus> - <label>Add</label> - </widget> - - <widget> - <class>GtkButton</class> - <name>cmdNewsServersEdit</name> - <can_default>True</can_default> - <can_focus>True</can_focus> - <label>Edit</label> - </widget> - - <widget> - <class>GtkButton</class> - <name>cmdNewsServersDelete</name> - <can_default>True</can_default> - <can_focus>True</can_focus> - <label>Delete</label> - </widget> - </widget> - </widget> - - <widget> - <class>GtkLabel</class> - <child_name>Notebook:tab</child_name> - <name>label26</name> - <label>News Sources</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - </widget> - - <widget> - <class>GtkVBox</class> - <name>vbox3</name> - <border_width>8</border_width> - <homogeneous>False</homogeneous> - <spacing>5</spacing> - - <widget> - <class>GtkCheckButton</class> - <name>chkFormat</name> - <can_focus>True</can_focus> - <label>Send messages in HTML format</label> - <active>False</active> - <draw_indicator>True</draw_indicator> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkHBox</class> - <name>hbox7</name> - <homogeneous>False</homogeneous> - <spacing>0</spacing> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - - <widget> - <class>GtkLabel</class> - <name>labelTimeout</name> - <label>Mark message as seen [ms]: </label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkSpinButton</class> - <name>spinTimeout</name> - <can_focus>True</can_focus> - <climb_rate>1</climb_rate> - <digits>0</digits> - <numeric>True</numeric> - <update_policy>GTK_UPDATE_ALWAYS</update_policy> - <snap>False</snap> - <wrap>False</wrap> - <value>1500</value> - <lower>0</lower> - <upper>10000</upper> - <step>100</step> - <page>1000</page> - <page_size>1000</page_size> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - </widget> - </widget> - </widget> - - <widget> - <class>GtkLabel</class> - <child_name>Notebook:tab</child_name> - <name>label32</name> - <label>Other</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - </widget> - </widget> -</widget> - -</GTK-Interface> diff --git a/mail/mail-config.glade.h b/mail/mail-config.glade.h deleted file mode 100644 index f1daaa4cbc..0000000000 --- a/mail/mail-config.glade.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Translatable strings file generated by Glade. - * Add this file to your project's POTFILES.in. - * DO NOT compile it as part of your application. - */ - -gchar *s = N_("Identities"); -gchar *s = N_("Address"); -gchar *s = N_("Organization"); -gchar *s = N_("Signature File"); -gchar *s = N_("Add"); -gchar *s = N_("Edit"); -gchar *s = N_("Delete"); -gchar *s = N_("Identities"); -gchar *s = N_("Sources"); -gchar *s = N_("Add"); -gchar *s = N_("Edit"); -gchar *s = N_("Delete"); -gchar *s = N_("Mail Sources"); -gchar *s = N_("Mail Transport"); -gchar *s = N_("News Servers"); -gchar *s = N_("Add"); -gchar *s = N_("Edit"); -gchar *s = N_("Delete"); -gchar *s = N_("News Sources"); -gchar *s = N_("Send messages in HTML format"); -gchar *s = N_("Mark message as seen [ms]: "); -gchar *s = N_("Other"); diff --git a/mail/mail-config.h b/mail/mail-config.h deleted file mode 100644 index 47c1e4d6a0..0000000000 --- a/mail/mail-config.h +++ /dev/null @@ -1,92 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Copyright 2000, Helix Code, Inc. (http://www.helixcode.com) - * - * 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 - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA. - */ - -#ifndef _MAIL_CONFIG_H -#define _MAIL_CONFIG_H - - - -#include <glib.h> -#include <camel/camel-folder.h> - -typedef struct -{ - gchar *name; - gchar *address; - gchar *org; - gchar *sig; -} MailConfigIdentity; - -typedef struct -{ - gchar *url; - gboolean keep_on_server; -} MailConfigService; - -/* Identities */ -MailConfigIdentity *identity_copy (MailConfigIdentity *id); -void identity_destroy (MailConfigIdentity *id); -void identity_destroy_each (gpointer item, gpointer data); - -/* Services */ -MailConfigService *service_copy (MailConfigService *source); -void service_destroy (MailConfigService *source); -void service_destroy_each (gpointer item, gpointer data); - -/* Configuration */ -void mail_config_init (void); -void mail_config_clear (void); -void mail_config_write (void); -void mail_config_write_on_exit (void); - -/* General Accessor functions */ -gboolean mail_config_is_configured (void); -gboolean mail_config_thread_list (void); -gint mail_config_paned_size (void); -void mail_config_set_thread_list (gboolean value); -void mail_config_set_paned_size (gint size); -gboolean mail_config_send_html (void); -void mail_config_set_send_html (gboolean send_html); -gint mail_config_mark_as_seen_timeout (void); -void mail_config_set_mark_as_seen_timeout (gint timeout); - -/* Identity Accessor functions */ -MailConfigIdentity *mail_config_get_default_identity (void); -void mail_config_add_identity (MailConfigIdentity *id); -GSList *mail_config_get_identities (void); - -/* Service Accessor functions */ -MailConfigService *mail_config_get_default_source (void); -GSList *mail_config_get_sources (void); -void mail_config_add_source (MailConfigService *source); - -MailConfigService *mail_config_get_transport (void); -void mail_config_set_transport (MailConfigService *transport); - -MailConfigService *mail_config_get_default_news (void); -GSList *mail_config_get_news (void); -void mail_config_add_news (MailConfigService *source); - -/* static utility functions */ -char *mail_config_folder_to_cachename(CamelFolder *folder, const char *prefix); - -#endif - - diff --git a/mail/mail-crypto.c b/mail/mail-crypto.c deleted file mode 100644 index c99b30ba3b..0000000000 --- a/mail/mail-crypto.c +++ /dev/null @@ -1,694 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * mail-crypto.c: OpenPGP en/decryption & signature code - * - * FIXME FIXME FIXME: This should be in its own library or component - */ - -/* - * Authors: - * Nathan Thompson-Amato <ndt@jps.net> - * Dan Winship <danw@helixcode.com> - * Jeffrey Stedfast <fejj@helixcode.com> - * - * Copyright 2000, Helix Code, Inc. (http://www.helixcode.com) - * Copyright 2000, Nathan Thompson-Amato - * Copyright 1999, 2000, Anthony Mulcahy - * - * 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 - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA. - * - */ - -#include <config.h> - -#ifdef PGP_PROGRAM -#include <stdlib.h> -#include <string.h> - -#include "mail-crypto.h" -#include "mail-session.h" - -#include <dirent.h> -#include <errno.h> -#include <fcntl.h> -#include <sys/stat.h> -#include <sys/types.h> - -#include <signal.h> -#include <stdio.h> -#include <sys/ioctl.h> -#include <sys/time.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <termios.h> -#include <unistd.h> -#include <signal.h> - -static int -cleanup_child (pid_t child) -{ - int status; - pid_t wait_result; - sigset_t mask, omask; - - /* PGP5 closes fds before exiting, meaning this might be called - * too early. So wait a bit for the result. - */ - sigemptyset (&mask); - sigaddset (&mask, SIGALRM); - sigprocmask (SIG_BLOCK, &mask, &omask); - alarm (1); - wait_result = waitpid (child, &status, 0); - alarm (0); - sigprocmask (SIG_SETMASK, &omask, NULL); - - if (wait_result == -1 && errno == EINTR) { - /* The child is hanging: send a friendly reminder. */ - kill (child, SIGTERM); - sleep (1); - wait_result = waitpid (child, &status, WNOHANG); - if (wait_result == 0) { - /* Still hanging; use brute force. */ - kill (child, SIGKILL); - sleep (1); - wait_result = waitpid (child, &status, WNOHANG); - } - } - - if (wait_result != -1 && WIFEXITED (status)) - return WEXITSTATUS (status); - else - return -1; -} - -static void -cleanup_before_exec (int fd) -{ - int maxfd, i; - - maxfd = sysconf (_SC_OPEN_MAX); - if (maxfd < 0) - return; - - /* Loop over all fds. */ - for (i = 0; i < maxfd; i++) { - if ((STDIN_FILENO != i) && - (STDOUT_FILENO != i) && - (STDERR_FILENO != i) && - (fd != i)) - close (i); - } -} - -static int -crypto_exec_with_passwd (char *path, char *argv[], const char *input, - int passwd_fds[], const char *passphrase, - char **output, char **diagnostics) -{ - fd_set fdset, write_fdset; - int ip_fds[2], op_fds[2], diag_fds[2]; - int select_result, read_len, write_len; - size_t tmp_len; - pid_t child; - char *buf, *diag_buf; - const char *passwd_next, *input_next; - size_t size, alloc_size, diag_size, diag_alloc_size; - gboolean eof_seen, diag_eof_seen, passwd_eof_seen, input_eof_seen; - size_t passwd_remaining, passwd_incr, input_remaining, input_incr; - struct timeval timeout; - - if ((pipe (ip_fds) < 0 ) || - (pipe (op_fds) < 0 ) || - (pipe (diag_fds) < 0 )) { - *diagnostics = g_strdup_printf (_("Couldn't create pipe to " - "%s: %s"), PGP_PROGRAM, - g_strerror (errno)); - return 0; - } - - if (!(child = fork ())) { - /* In child */ - - if ((dup2 (ip_fds[0], STDIN_FILENO) < 0 ) || - (dup2 (op_fds[1], STDOUT_FILENO) < 0 ) || - (dup2 (diag_fds[1], STDERR_FILENO) < 0 )) { - _exit (255); - } - - /* Dissociate from evolution-mail's controlling - * terminal so that pgp/gpg won't be able to read from - * it: PGP 2 will fall back to asking for the password - * on /dev/tty if the passed-in password is incorrect. - * This will make that fail rather than hanging. - */ - setsid (); - - /* Close excess fds */ - cleanup_before_exec(passwd_fds[0]); - - execvp (path, argv); - fprintf (stderr, _("Could not execute %s: %s\n"), argv[0], - g_strerror (errno)); - _exit (255); - } else if (child < 0) { - *diagnostics = g_strdup_printf (_("Cannot fork %s: %s"), - argv[0], g_strerror (errno)); - return 0; - } - - /* Parent */ - close (ip_fds[0]); - close (op_fds[1]); - close (diag_fds[1]); - close (passwd_fds[0]); - - timeout.tv_sec = 10; /* timeout in seconds */ - timeout.tv_usec = 0; - - size = diag_size = 0; - alloc_size = 4096; - diag_alloc_size = 1024; - eof_seen = diag_eof_seen = FALSE; - - buf = g_malloc (alloc_size); - diag_buf = g_malloc (diag_alloc_size); - - passwd_next = passphrase; - passwd_remaining = strlen (passphrase); - passwd_incr = fpathconf (passwd_fds[1], _PC_PIPE_BUF); - /* Use a reasonable default value on error. */ - if (passwd_incr <= 0) - passwd_incr = 1024; - passwd_eof_seen = FALSE; - - input_next = input; - input_remaining = strlen (input); - input_incr = fpathconf (ip_fds[1], _PC_PIPE_BUF); - if (input_incr <= 0) - input_incr = 1024; - input_eof_seen = FALSE; - - while (!(eof_seen && diag_eof_seen)) { - FD_ZERO (&fdset); - if (!eof_seen) - FD_SET (op_fds[0], &fdset); - if (!diag_eof_seen) - FD_SET (diag_fds[0], &fdset); - - FD_ZERO (&write_fdset); - if (!passwd_eof_seen) - FD_SET (passwd_fds[1], &write_fdset); - if (!input_eof_seen) - FD_SET (ip_fds[1], &write_fdset); - - select_result = select (FD_SETSIZE, &fdset, &write_fdset, - NULL, &timeout); - if (select_result < 0) { - if (errno == EINTR) - continue; - break; - } - if (select_result == 0) { - /* timeout */ - break; - } - - if (FD_ISSET (op_fds[0], &fdset)) { - /* More output is available. */ - - if (size + 4096 > alloc_size) { - alloc_size += 4096; - buf = g_realloc (buf , alloc_size); - } - read_len = read (op_fds[0], &buf[size], - alloc_size - size - 1); - if (read_len < 0) { - if (errno == EINTR) - continue; - break; - } - if (read_len == 0) - eof_seen = TRUE; - size += read_len; - } - - if (FD_ISSET(diag_fds[0], &fdset) ) { - /* More stderr is available. */ - - if (diag_size + 1024 > diag_alloc_size) { - diag_alloc_size += 1024; - diag_buf = g_realloc (diag_buf, - diag_alloc_size); - } - - read_len = read (diag_fds[0], &diag_buf[diag_size], - diag_alloc_size - diag_size - 1); - if (read_len < 0) { - if (errno == EINTR) - continue; - break; - } - if (read_len == 0) - diag_eof_seen = TRUE; - diag_size += read_len; - } - - if (FD_ISSET(passwd_fds[1], &write_fdset)) { - /* Ready for more password input. */ - - tmp_len = passwd_incr; - if (tmp_len > passwd_remaining) - tmp_len = passwd_remaining; - write_len = write (passwd_fds[1], passwd_next, - tmp_len); - if (write_len < 0) { - if (errno == EINTR) - continue; - break; - } - passwd_next += write_len; - passwd_remaining -= write_len; - if (passwd_remaining == 0) { - close (passwd_fds[1]); - passwd_eof_seen = TRUE; - } - } - - if (FD_ISSET(ip_fds[1], &write_fdset)) { - /* Ready for more ciphertext input. */ - - tmp_len = input_incr; - if (tmp_len > input_remaining) - tmp_len = input_remaining; - write_len = write (ip_fds[1], input_next, tmp_len); - if (write_len < 0) { - if (errno == EINTR) - continue; - break; - } - input_next += write_len; - input_remaining -= write_len; - if (input_remaining == 0 ) { - close (ip_fds[1]); - input_eof_seen = TRUE; - } - } - } - - buf[size] = 0; - diag_buf[diag_size] = 0; - close (op_fds[0]); - close (diag_fds[0]); - - *output = buf; - *diagnostics = diag_buf; - - return cleanup_child (child); -} - -/*----------------------------------------------------------------------* - * Public crypto functions - *----------------------------------------------------------------------*/ - -/** - * mail_crypto_openpgp_decrypt: pgp decrypt ciphertext - * @ciphertext: ciphertext to decrypt - * @ex: a CamelException - * - * Decrypts the ciphertext - **/ - -char * -mail_crypto_openpgp_decrypt (const char *ciphertext, CamelException *ex) -{ - int retval, i; - char *path, *argv[12]; - char *passphrase, *plaintext = NULL, *diagnostics = NULL; - int passwd_fds[2]; - char passwd_fd[32]; - - passphrase = mail_session_request_dialog ( - _("Please enter your PGP/GPG passphrase."), - TRUE, "pgp", FALSE); - if (!passphrase) { - camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, - _("No password provided.")); - return NULL; - } - - if (pipe (passwd_fds) < 0) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Couldn't create pipe to GPG/PGP: %s"), - g_strerror (errno)); - return NULL; - } - - i = 0; -#if defined(GPG_PATH) - path = GPG_PATH; - - argv[i++] = "gpg"; - argv[i++] = "--verbose"; - argv[i++] = "--yes"; - argv[i++] = "--batch"; - - argv[i++] = "--output"; - argv[i++] = "-"; /* output to stdout */ - - argv[i++] = "--decrypt"; - - argv[i++] = "--passphrase-fd"; - sprintf (passwd_fd, "%d", passwd_fds[0]); - argv[i++] = passwd_fd; -#elif defined(PGP5_PATH) - path = PGP5_PATH; - - argv[i++] = "pgpv"; - argv[i++] = "-f"; - argv[i++] = "+batchmode=1"; - - sprintf (passwd_fd, "PGPPASSFD=%d", passwd_fds[0]); - putenv (passwd_fd); -#else - path = PGP_PATH; - - argv[i++] = "pgp"; - argv[i++] = "-f"; - - sprintf (passwd_fd, "PGPPASSFD=%d", passwd_fds[0]); - putenv (passwd_fd); -#endif - argv[i++] = NULL; - - retval = crypto_exec_with_passwd (path, argv, ciphertext, passwd_fds, - passphrase, &plaintext, - &diagnostics); - if (retval != 0 || !*plaintext) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - "%s", diagnostics); - g_free (plaintext); - g_free (diagnostics); - return NULL; - } - - g_free (diagnostics); - return plaintext; -} - -/** - * mail_crypto_openpgp_encrypt: pgp encrypt plaintext - * @plaintext: text to encrypt - * @recipients: an array of recipients to encrypt to (preferably each - * element should be a pgp keyring ID however sometimes email - * addresses will work assuming that your pgp keyring has an - * entry for that address) - * @sign: TRUE if you wish to sign the encrypted text as well, FALSE otherwise - * @ex: a CamelException - * - * Encrypts the plaintext to the list of recipients and optionally signs - **/ - -char * -mail_crypto_openpgp_encrypt (const char *plaintext, - const GPtrArray *recipients, - gboolean sign, CamelException *ex) -{ - GPtrArray *recipient_list = NULL; - GPtrArray *argv; - int retval, r; - char *path; - char *passphrase = NULL, *ciphertext = NULL, *diagnostics = NULL; - int passwd_fds[2]; - char passwd_fd[32]; - - if (sign) { - /* we only need the passphrase if we plan to sign */ - passphrase = mail_session_request_dialog ( - _("Please enter your PGP/GPG passphrase."), - TRUE, "pgp", FALSE); - if (!passphrase) { - camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, - _("No password provided.")); - return NULL; - } - - if (pipe (passwd_fds) < 0) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Couldn't create pipe to GPG/PGP: %s"), - g_strerror (errno)); - return NULL; - } - } - - argv = g_ptr_array_new (); -#if defined(GPG_PATH) - path = GPG_PATH; - - recipient_list = g_ptr_array_new (); - for (r = 0; r < recipients->len; r++) { - char *buf, *recipient; - - recipient = recipients->pdata[r]; - buf = g_strdup_printf ("-r %s", recipient); - g_ptr_array_add (recipient_list, buf); - } - - g_ptr_array_add (argv, "gpg"); - g_ptr_array_add (argv, "--verbose"); - g_ptr_array_add (argv, "--yes"); - g_ptr_array_add (argv, "--batch"); - - g_ptr_array_add (argv, "--armor"); - - for (r = 0; r < recipient_list->len; r++) - g_ptr_array_add (argv, recipient_list->pdata[r]); - - g_ptr_array_add (argv, "--output"); - g_ptr_array_add (argv, "-"); /* output to stdout */ - - g_ptr_array_add (argv, "--encrypt"); - - if (sign) { - g_ptr_array_add (argv, "--sign"); - - g_ptr_array_add (argv, "--passphrase-fd"); - sprintf (passwd_fd, "%d", passwd_fds[0]); - g_ptr_array_add (argv, passwd_fd); - } -#elif defined(PGP5_PATH) - path = PGP5_PATH; - - recipient_list = g_ptr_array_new (); - for (r = 0; r < recipients->len; r++) { - char *buf, *recipient; - - recipient = recipients->pdata[r]; - buf = g_strdup_printf ("-r %s", recipient); - g_ptr_array_add (recipient_list, buf); - } - - g_ptr_array_add (argv, "pgpe"); - - for (r = 0; r < recipient_list->len; r++) - g_ptr_array_add (argv, recipient_list->pdata[r]); - - g_ptr_array_add (argv, "-f"); - g_ptr_array_add (argv, "-z"); - g_ptr_array_add (argv, "-a"); - g_ptr_array_add (argv, "-o"); - g_ptr_array_add (argv, "-"); /* output to stdout */ - - if (sign) { - g_ptr_array_add (argv, "-s"); - - sprintf (passwd_fd, "PGPPASSFD=%d", passwd_fds[0]); - putenv (passwd_fd); - } -#else - path = PGP_PATH; - - recipient_list = g_ptr_array_new (); - for (r = 0; r < recipients->len; r++) { - char *buf, *recipient; - - recipient = recipients->pdata[r]; - buf = g_strdup_printf ("-r %s", recipient); - g_ptr_array_add (recipient_list, buf); - } - - g_ptr_array_add (argv, "pgp"); - g_ptr_array_add (argv, "-f"); - g_ptr_array_add (argv, "-e"); - g_ptr_array_add (argv, "-a"); - g_ptr_array_add (argv, "-o"); - g_ptr_array_add (argv, "-"); - - for (r = 0; r < recipient_list->len; r++) - g_ptr_array_add (argv, recipient_list->pdata[r]); - - if (sign) { - g_ptr_array_add (argv, "-s"); - - sprintf (passwd_fd, "PGPPASSFD=%d", passwd_fds[0]); - putenv (passwd_fd); - } -#endif - g_ptr_array_add (argv, NULL); - - retval = crypto_exec_with_passwd (path, (char **) argv->pdata, plaintext, - passwd_fds, passphrase, &ciphertext, - &diagnostics); - - if (retval != 0 || !*ciphertext) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - "%s", diagnostics); - g_free (ciphertext); - ciphertext = NULL; - } - - if (recipient_list) { - for (r = 0; r < recipient_list->len; r++) - g_free (recipient_list->pdata[r]); - g_ptr_array_free (recipient_list, TRUE); - } - - g_ptr_array_free (argv, TRUE); - - g_free (diagnostics); - - return ciphertext; -} - -/** - * mail_crypto_openpgp_clearsign: pgp clearsign plaintext - * @plaintext: text to sign - * @userid: user id to sign with - * @ex: a CamelException - * - * Clearsigns the plaintext using the user id - **/ - -char * -mail_crypto_openpgp_clearsign (const char *plaintext, const char *userid, - CamelException *ex) -{ - int retval; - char *path, *argv[20]; - int i; - char *passphrase; - char *ciphertext = NULL; - char *diagnostics = NULL; - int passwd_fds[2]; - char passwd_fd[32]; - -#ifndef PGP_PROGRAM - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("No GPG/PGP program available.")); - return NULL; -#endif - - passphrase = mail_session_request_dialog (_("Please enter your PGP/GPG passphrase."), - TRUE, "pgp", FALSE); - - if (!passphrase) { - camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, - _("No password provided.")); - return NULL; - } - - if (pipe (passwd_fds) < 0) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Couldn't create pipe to GPG/PGP: %s"), - g_strerror (errno)); - return NULL; - } - - i = 0; -#if defined(GPG_PATH) - path = GPG_PATH; - - argv[i++] = "gpg"; - - argv[i++] = "--clearsign"; - - if (userid) { - argv[i++] = "-u"; - argv[i++] = (char *) userid; - } - - argv[i++] = "--verbose"; - argv[i++] = "--yes"; - argv[i++] = "--batch"; - - argv[i++] = "--armor"; - - argv[i++] = "--output"; - argv[i++] = "-"; /* output to stdout */ - - argv[i++] = "--passphrase-fd"; - sprintf (passwd_fd, "%d", passwd_fds[0]); - argv[i++] = passwd_fd; -#elif defined(PGP5_PATH) - path = PGP5_PATH; - - argv[i++] = "pgps"; - - if (userid) { - argv[i++] = "-u"; - argv[i++] = (char *) userid; - } - - argv[i++] = "-f"; - argv[i++] = "-z"; - argv[i++] = "-a"; - argv[i++] = "-o"; - argv[i++] = "-"; /* output to stdout */ - - argv[i++] = "-s"; - sprintf (passwd_fd, "PGPPASSFD=%d", passwd_fds[0]); - putenv (passwd_fd); -#else - path = PGP_PATH; - - argv[i++] = "pgp"; - argv[i++] = "-f"; - argv[i++] = "-e"; - argv[i++] = "-a"; - argv[i++] = "-o"; - argv[i++] = "-"; - - argv[i++] = "-s"; - sprintf (passwd_fd, "PGPPASSFD=%d", passwd_fds[0]); - putenv (passwd_fd); -#endif - argv[i++] = NULL; - - retval = crypto_exec_with_passwd (path, argv, plaintext, passwd_fds, - passphrase, &ciphertext, - &diagnostics); - - if (retval != 0 || !*ciphertext) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - "%s", diagnostics); - g_free (ciphertext); - ciphertext = NULL; - } - - g_free (diagnostics); - return ciphertext; -} - -#endif /* PGP_PROGRAM */ diff --git a/mail/mail-crypto.h b/mail/mail-crypto.h deleted file mode 100644 index 8ea9999809..0000000000 --- a/mail/mail-crypto.h +++ /dev/null @@ -1,50 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Authors: Jeffrey Stedfast <fejj@helixcode.com> - * - * Copyright 2000 Helix Code, Inc. (www.helixcode.com) - * - * 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 - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA. - * - */ - -#ifndef MAIL_CRYPTO_H -#define MAIL_CRYPTO_H - -#include <gnome.h> -#include <camel/camel.h> - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus }*/ - -char *mail_crypto_openpgp_decrypt (const char *ciphertext, - CamelException *ex); - -char *mail_crypto_openpgp_encrypt (const char *plaintext, - const GPtrArray *recipients, - gboolean sign, - CamelException *ex); - -char *mail_crypto_openpgp_clearsign (const char *plaintext, - const char *userid, - CamelException *ex); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* ! MAIL_CRYPTO_H */ diff --git a/mail/mail-display.c b/mail/mail-display.c deleted file mode 100644 index 1650deca1e..0000000000 --- a/mail/mail-display.c +++ /dev/null @@ -1,852 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * mail-display.c: Mail display widget - * - * Author: - * Miguel de Icaza - * Bertrand Guiheneuf (bg@aful.org) - * - * (C) 2000 Helix Code, Inc. - */ -#include <config.h> -#include <sys/stat.h> -#include <ctype.h> -#include <fcntl.h> -#include <errno.h> -#include <gnome.h> -#include "e-util/e-html-utils.h" -#include <gal/util/e-util.h> -#include <gal/widgets/e-popup-menu.h> -#include "mail-display.h" -#include "mail.h" - -#include <bonobo.h> -#include <libgnorba/gnorba.h> -#include <bonobo/bonobo-stream-memory.h> -#include <libgnomevfs/gnome-vfs-mime-info.h> -#include <libgnomevfs/gnome-vfs-mime-handlers.h> - -#include <bonobo/bonobo-ui-toolbar-icon.h> -#include <gdk-pixbuf/gdk-pixbuf.h> -#include <gdk-pixbuf/gdk-pixbuf-loader.h> - -#define PARENT_TYPE (gtk_vbox_get_type ()) - -static GtkObjectClass *mail_display_parent_class; - -static void redisplay (MailDisplay *md, gboolean unscroll); - -struct _PixbufLoader { - CamelDataWrapper *wrapper; /* The data */ - CamelStream *mstream; - GdkPixbufLoader *loader; - char *type; /* Type of data, in case the conversion fails */ - GtkWidget *pixmap; -}; - -/*----------------------------------------------------------------------* - * Callbacks - *----------------------------------------------------------------------*/ - -static gboolean -write_data_to_file (CamelMimePart *part, const char *name, gboolean unique) -{ - CamelDataWrapper *data; - CamelStream *stream_fs; - int fd; - - g_return_val_if_fail (CAMEL_IS_MIME_PART (part), FALSE); - data = camel_medium_get_content_object (CAMEL_MEDIUM (part)); - - fd = open (name, O_WRONLY | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); - if (fd == -1 && errno == EEXIST && !unique) { - GtkWidget *dlg; - GtkWidget *text; - - dlg = gnome_dialog_new (_("Overwrite file?"), - GNOME_STOCK_BUTTON_YES, - GNOME_STOCK_BUTTON_NO, - NULL); - text = gtk_label_new (_("A file by that name already exists.\nOverwrite it?")); - gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dlg)->vbox), text, TRUE, TRUE, 4); - gtk_window_set_policy(GTK_WINDOW(dlg), FALSE, TRUE, FALSE); - gtk_widget_show (text); - - if (gnome_dialog_run_and_close (GNOME_DIALOG (dlg)) != 0) - return FALSE; - - fd = open (name, O_WRONLY | O_TRUNC); - } - - if (fd == -1) { - char *msg; - - msg = g_strdup_printf (_("Could not open file %s:\n%s"), - name, g_strerror (errno)); - gnome_error_dialog (msg); - g_free (msg); - return FALSE; - } - - stream_fs = camel_stream_fs_new_with_fd (fd); - if (camel_data_wrapper_write_to_stream (data, stream_fs) == -1 - || camel_stream_flush (stream_fs) == -1) { - char *msg; - - msg = g_strdup_printf (_("Could not write data: %s"), - strerror (errno)); - gnome_error_dialog (msg); - g_free (msg); - camel_object_unref (CAMEL_OBJECT (stream_fs)); - return FALSE; - } - camel_object_unref (CAMEL_OBJECT (stream_fs)); - return TRUE; -} - -static char * -make_safe_filename (const char *prefix, CamelMimePart *part) -{ - const char *name = NULL; - char *safe, *p; - - name = camel_mime_part_get_filename (part); - if (!name) { - /* This is a filename. Translators take note. */ - name = _("attachment"); - } - - p = strrchr (name, '/'); - if (p) - safe = g_strdup_printf ("%s%s", prefix, p); - else - safe = g_strdup_printf ("%s/%s", prefix, name); - - for (p = strrchr (safe, '/') + 1; *p; p++) { - if (!isascii ((unsigned char)*p) || - strchr (" /'\"`&();|<>${}!", *p)) - *p = '_'; - } - - return safe; -} - -static void -save_data_cb (GtkWidget *widget, gpointer user_data) -{ - GtkFileSelection *file_select = (GtkFileSelection *) - gtk_widget_get_ancestor (widget, GTK_TYPE_FILE_SELECTION); - - write_data_to_file (user_data, - gtk_file_selection_get_filename (file_select), - FALSE); - gtk_widget_destroy (GTK_WIDGET (file_select)); -} - -static gboolean -idle_redisplay (gpointer data) -{ - MailDisplay *md = data; - - md->idle_id = 0; - redisplay (md, FALSE); - return FALSE; -} - -static void -queue_redisplay (MailDisplay *md) -{ - if (!md->idle_id) { - md->idle_id = g_idle_add_full (G_PRIORITY_LOW, idle_redisplay, - md, NULL); - } -} - -static void -on_link_clicked (GtkHTML *html, const char *url, gpointer user_data) -{ - MailDisplay *md = user_data; - - if (!g_strncasecmp (url, "news:", 5) || - !g_strncasecmp (url, "nntp:", 5)) - g_warning ("Can't handle news URLs yet."); - else if (!g_strncasecmp (url, "mailto:", 7)) - send_to_url (url); - else if (!strcmp (url, "x-evolution-decode-pgp:")) { - g_datalist_set_data (md->data, "show_pgp", - GINT_TO_POINTER (1)); - queue_redisplay (md); - } else - gnome_url_show (url); -} - -static void -save_cb (GtkWidget *widget, gpointer user_data) -{ - CamelMimePart *part = gtk_object_get_data (user_data, "CamelMimePart"); - GtkFileSelection *file_select; - char *filename; - - filename = make_safe_filename (g_get_home_dir (), part); - file_select = GTK_FILE_SELECTION ( - gtk_file_selection_new (_("Save Attachment"))); - gtk_file_selection_set_filename (file_select, filename); - g_free (filename); - - gtk_signal_connect (GTK_OBJECT (file_select->ok_button), "clicked", - GTK_SIGNAL_FUNC (save_data_cb), part); - gtk_signal_connect_object (GTK_OBJECT (file_select->cancel_button), - "clicked", - GTK_SIGNAL_FUNC (gtk_widget_destroy), - GTK_OBJECT (file_select)); - - gtk_widget_show (GTK_WIDGET (file_select)); -} - -static void -launch_cb (GtkWidget *widget, gpointer user_data) -{ - CamelMimePart *part = gtk_object_get_data (user_data, "CamelMimePart"); - GnomeVFSMimeApplication *app; - GMimeContentField *content_type; - char *mime_type, *tmpl, *tmpdir, *filename, *argv[2]; - - content_type = camel_mime_part_get_content_type (part); - mime_type = gmime_content_field_get_mime_type (content_type); - app = gnome_vfs_mime_get_default_application (mime_type); - g_free (mime_type); - - g_return_if_fail (app != NULL); - - tmpl = g_strdup ("/tmp/evolution.XXXXXX"); -#ifdef HAVE_MKDTEMP - tmpdir = mkdtemp (tmpl); -#else - tmpdir = mktemp (tmpl); - if (tmpdir) { - if (mkdir (tmpdir, S_IRWXU) == -1) - tmpdir = NULL; - } -#endif - if (!tmpdir) { - char *msg = g_strdup_printf (_("Could not create temporary " - "directory: %s"), - g_strerror (errno)); - gnome_error_dialog (msg); - g_free (msg); - return; - } - - filename = make_safe_filename (tmpdir, part); - - if (!write_data_to_file (part, filename, TRUE)) { - g_free (tmpl); - g_free (filename); - return; - } - - argv[0] = app->command; - argv[1] = filename; - - gnome_execute_async (tmpdir, 2, argv); - g_free (tmpdir); - g_free (filename); -} - -static void -inline_cb (GtkWidget *widget, gpointer user_data) -{ - MailDisplay *md = gtk_object_get_data (user_data, "MailDisplay"); - CamelMimePart *part = gtk_object_get_data (user_data, "CamelMimePart"); - - if (mail_part_is_inline (part)) - camel_mime_part_set_disposition (part, "attachment"); - else - camel_mime_part_set_disposition (part, "inline"); - - queue_redisplay (md); -} - -static gboolean -pixmap_press (GtkWidget *ebox, GdkEventButton *event, gpointer user_data) -{ - EPopupMenu menu[] = { - { N_("Save to Disk..."), NULL, - GTK_SIGNAL_FUNC (save_cb), 0 }, - { N_("Open in %s..."), NULL, - GTK_SIGNAL_FUNC (launch_cb), 1 }, - { N_("View Inline"), NULL, - GTK_SIGNAL_FUNC (inline_cb), 2 }, - { NULL, NULL, NULL, 0 } - }; - CamelMimePart *part; - MailMimeHandler *handler; - int mask = 0; - - if (event->button != 3) - return FALSE; - - part = gtk_object_get_data (user_data, "CamelMimePart"); - handler = mail_lookup_handler (gtk_object_get_data (user_data, - "mime_type")); - - /* Save item */ - menu[0].name = _(menu[0].name); - - /* External view item */ - if (handler && handler->application) { - menu[1].name = g_strdup_printf (_(menu[1].name), - handler->application->name); - } else { - menu[1].name = g_strdup_printf (_(menu[1].name), - _("External Viewer")); - mask |= 1; - } - - /* Inline view item */ - if (handler && handler->builtin) { - if (!mail_part_is_inline (part)) { - if (handler->component) { - OAF_Property *prop; - char *name; - - prop = oaf_server_info_prop_find ( - handler->component, "name"); - if (!prop) { - prop = oaf_server_info_prop_find ( - handler->component, - "description"); - } - if (prop && prop->v._d == OAF_P_STRING) - name = prop->v._u.value_string; - else - name = "bonobo"; - menu[2].name = g_strdup_printf ( - _("View Inline (via %s)"), name); - } else - menu[2].name = g_strdup (_(menu[2].name)); - } else - menu[2].name = g_strdup (_("Hide")); - } else { - menu[2].name = g_strdup (_(menu[2].name)); - mask |= 2; - } - - e_popup_menu_run (menu, event, mask, 0, user_data); - g_free (menu[1].name); - g_free (menu[2].name); - return TRUE; -} - -static GdkPixbuf * -pixbuf_for_mime_type (const char *mime_type) -{ - const char *icon_name; - char *filename = NULL; - GdkPixbuf *pixbuf; - - icon_name = gnome_vfs_mime_get_value (mime_type, "icon-filename"); - if (icon_name) { - if (*icon_name == '/') { - pixbuf = gdk_pixbuf_new_from_file (icon_name); - if (pixbuf) - return pixbuf; - } - - filename = gnome_pixmap_file (icon_name); - if (!filename) { - char *fm_icon; - - fm_icon = g_strdup_printf ("nautilus/%s", icon_name); - filename = gnome_pixmap_file (fm_icon); - if (!filename) { - fm_icon = g_strdup_printf ("mc/%s", icon_name); - filename = gnome_pixmap_file (fm_icon); - } - } - } - - if (!filename) - filename = gnome_pixmap_file ("gnome-unknown.png"); - - pixbuf = gdk_pixbuf_new_from_file (filename); - g_free (filename); - - return pixbuf; -} - -static gint -pixbuf_gen_idle (struct _PixbufLoader *pbl) -{ - GdkPixbuf *pixbuf, *mini; - gboolean error = FALSE; - char tmp[4096]; - int len, width, height, ratio; - - /* Get a pixbuf from the wrapper */ - - if (!GTK_IS_WIDGET (pbl->pixmap)) { - /* Widget has died */ - if (pbl->mstream) - camel_object_unref (CAMEL_OBJECT (pbl->mstream)); - - if (pbl->loader) { - gdk_pixbuf_loader_close (pbl->loader); - gtk_object_destroy (GTK_OBJECT (pbl->loader)); - } - - g_free (pbl->type); - g_free (pbl); - return FALSE; - } - - if (pbl->mstream) { - if (pbl->loader == NULL) - pbl->loader = gdk_pixbuf_loader_new (); - - len = camel_stream_read (pbl->mstream, tmp, 4096); - if (len > 0) { - error = !gdk_pixbuf_loader_write (pbl->loader, tmp, len); - if (!error) - return TRUE; - } else if (!camel_stream_eos (pbl->mstream)) - error = TRUE; - } - - if (error || !pbl->mstream) - pixbuf = pixbuf_for_mime_type (pbl->type); - else - pixbuf = gdk_pixbuf_loader_get_pixbuf (pbl->loader); - - width = gdk_pixbuf_get_width (pixbuf); - height = gdk_pixbuf_get_height (pixbuf); - - if (width >= height) { - if (width > 24) { - ratio = width / 24; - width = 24; - height /= ratio; - } - } else { - if (height > 24) { - ratio = height / 24; - height = 24; - width /= ratio; - } - } - - mini = gdk_pixbuf_scale_simple (pixbuf, width, height, - GDK_INTERP_BILINEAR); - if (error) - gdk_pixbuf_unref (pixbuf); - bonobo_ui_toolbar_icon_set_pixbuf ( - BONOBO_UI_TOOLBAR_ICON (pbl->pixmap), mini); - gdk_pixbuf_unref (mini); - gtk_widget_set_usize (pbl->pixmap, width, height); - - if (pbl->loader) { - gdk_pixbuf_loader_close (pbl->loader); - gtk_object_destroy (GTK_OBJECT (pbl->loader)); - camel_object_unref (CAMEL_OBJECT (pbl->mstream)); - } - g_free (pbl->type); - g_free (pbl); - return FALSE; -} - -static gboolean -on_object_requested (GtkHTML *html, GtkHTMLEmbedded *eb, gpointer data) -{ - MailDisplay *md = data; - GHashTable *urls; - CamelMedium *medium; - CamelDataWrapper *wrapper; - OAF_ServerInfo *component; - GtkWidget *embedded; - BonoboObjectClient *server; - Bonobo_PersistStream persist; - CORBA_Environment ev; - GByteArray *ba; - CamelStream *cstream; - BonoboStream *bstream; - BonoboControlFrame *control_frame; - Bonobo_PropertyBag prop_bag; - const char *from_address; - char *cid; - - cid = eb->classid; - if (!strncmp (cid, "popup:", 6)) - cid += 6; - if (strncmp (cid, "cid:", 4) != 0) - return FALSE; - - urls = g_datalist_get_data (md->data, "urls"); - g_return_val_if_fail (urls != NULL, FALSE); - - medium = g_hash_table_lookup (urls, cid); - g_return_val_if_fail (CAMEL_IS_MEDIUM (medium), FALSE); - - if (cid != eb->classid) { - /* This is a part wrapper */ - GtkWidget *ebox; - struct _PixbufLoader *pbl; - - pbl = g_new0 (struct _PixbufLoader, 1); - if (g_strncasecmp (eb->type, "image/", 6) == 0) { - pbl->mstream = camel_stream_mem_new (); - camel_data_wrapper_write_to_stream ( - camel_medium_get_content_object (medium), - pbl->mstream); - camel_stream_reset (pbl->mstream); - } - pbl->type = g_strdup (eb->type); - pbl->pixmap = bonobo_ui_toolbar_icon_new (); - - g_idle_add_full (G_PRIORITY_LOW, (GSourceFunc)pixbuf_gen_idle, - pbl, NULL); - - ebox = gtk_event_box_new (); - gtk_widget_set_sensitive (GTK_WIDGET (ebox), TRUE); - gtk_widget_add_events (GTK_WIDGET (ebox), - GDK_BUTTON_PRESS_MASK); - gtk_signal_connect (GTK_OBJECT (ebox), "button_press_event", - GTK_SIGNAL_FUNC (pixmap_press), ebox); - gtk_object_set_data (GTK_OBJECT (ebox), "MailDisplay", md); - gtk_object_set_data (GTK_OBJECT (ebox), "CamelMimePart", - medium); - gtk_object_set_data_full (GTK_OBJECT (ebox), "mime_type", - g_strdup (eb->type), - (GDestroyNotify)g_free); - - gtk_container_add (GTK_CONTAINER (ebox), pbl->pixmap); - gtk_widget_show_all (ebox); - gtk_container_add (GTK_CONTAINER (eb), ebox); - return TRUE; - } - - component = gnome_vfs_mime_get_default_component (eb->type); - if (!component) - return FALSE; - - embedded = bonobo_widget_new_subdoc (component->iid, NULL); - if (embedded) { - /* FIXME: as of bonobo 0.18, there's an extra - * client_site dereference in the BonoboWidget - * destruction path that we have to balance out to - * prevent problems. - */ - bonobo_object_ref (BONOBO_OBJECT(bonobo_widget_get_client_site ( - BONOBO_WIDGET (embedded)))); - } else { - embedded = bonobo_widget_new_control (component->iid, NULL); - if (!embedded) { - CORBA_free (component); - return FALSE; - } - - control_frame = bonobo_widget_get_control_frame (BONOBO_WIDGET (embedded)); - if (control_frame) { - prop_bag = bonobo_control_frame_get_control_property_bag ( control_frame, NULL ); - - if (prop_bag != CORBA_OBJECT_NIL) { - /* Now we can take care of business. Currently, the only control - that needs something passed to it through a property bag is - the iTip control, and it needs only the From email address, - but perhaps in the future we can generalize this section of code - to pass a bunch of useful things to all embedded controls. */ - - CORBA_exception_init (&ev); - - from_address = camel_mime_message_get_from (md->current_message); - bonobo_property_bag_client_set_value_string (prop_bag, "from_address", - from_address, &ev); - CORBA_exception_free (&ev); - } - } - } /* end else (we're going to use a control) */ - CORBA_free (component); - if (!embedded) - return FALSE; - - server = bonobo_widget_get_server (BONOBO_WIDGET (embedded)); - persist = (Bonobo_PersistStream) bonobo_object_client_query_interface ( - server, "IDL:Bonobo/PersistStream:1.0", NULL); - if (persist == CORBA_OBJECT_NIL) { - gtk_object_sink (GTK_OBJECT (embedded)); - return FALSE; - } - - /* Write the data to a CamelStreamMem... */ - ba = g_byte_array_new (); - cstream = camel_stream_mem_new_with_byte_array (ba); - wrapper = camel_medium_get_content_object (medium); - camel_data_wrapper_write_to_stream (wrapper, cstream); - - /* ...convert the CamelStreamMem to a BonoboStreamMem... */ - bstream = bonobo_stream_mem_create (ba->data, ba->len, TRUE, FALSE); - camel_object_unref (CAMEL_OBJECT (cstream)); - - /* ...and hydrate the PersistStream from the BonoboStream. */ - CORBA_exception_init (&ev); - Bonobo_PersistStream_load (persist, - bonobo_object_corba_objref ( - BONOBO_OBJECT (bstream)), - eb->type, &ev); - bonobo_object_unref (BONOBO_OBJECT (bstream)); - Bonobo_Unknown_unref (persist, &ev); - CORBA_Object_release (persist, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - gtk_object_sink (GTK_OBJECT (embedded)); - CORBA_exception_free (&ev); - return FALSE; - } - CORBA_exception_free (&ev); - - gtk_widget_show (embedded); - gtk_container_add (GTK_CONTAINER (eb), embedded); - - return TRUE; -} - -static void -on_url_requested (GtkHTML *html, const char *url, GtkHTMLStream *handle, - gpointer user_data) -{ - MailDisplay *md = user_data; - GHashTable *urls; - - urls = g_datalist_get_data (md->data, "urls"); - g_return_if_fail (urls != NULL); - - user_data = g_hash_table_lookup (urls, url); - if (user_data == NULL) - return; - - if (strncmp (url, "cid:", 4) == 0) { - CamelMedium *medium = user_data; - CamelDataWrapper *data; - CamelStream *stream_mem; - GByteArray *ba; - - g_return_if_fail (CAMEL_IS_MEDIUM (medium)); - data = camel_medium_get_content_object (medium); - - ba = g_byte_array_new (); - stream_mem = camel_stream_mem_new_with_byte_array (ba); - camel_data_wrapper_write_to_stream (data, stream_mem); - gtk_html_write (html, handle, ba->data, ba->len); - camel_object_unref (CAMEL_OBJECT (stream_mem)); - } else if (strncmp (url, "x-evolution-data:", 17) == 0) { - GByteArray *ba = user_data; - - g_return_if_fail (ba != NULL); - gtk_html_write (html, handle, ba->data, ba->len); - } -} - -void -mail_html_write (GtkHTML *html, GtkHTMLStream *stream, - const char *format, ...) -{ - char *buf; - va_list ap; - - va_start (ap, format); - buf = g_strdup_vprintf (format, ap); - va_end (ap); - gtk_html_write (html, stream, buf, strlen (buf)); - g_free (buf); -} - -void -mail_text_write (GtkHTML *html, GtkHTMLStream *stream, - const char *format, ...) -{ - char *buf, *htmltext; - va_list ap; - - va_start (ap, format); - buf = g_strdup_vprintf (format, ap); - va_end (ap); - - htmltext = e_text_to_html (buf, - E_TEXT_TO_HTML_CONVERT_URLS | - E_TEXT_TO_HTML_CONVERT_NL | - E_TEXT_TO_HTML_CONVERT_SPACES); - gtk_html_write (html, stream, "<tt>", 4); - gtk_html_write (html, stream, htmltext, strlen (htmltext)); - gtk_html_write (html, stream, "</tt>", 5); - g_free (htmltext); - g_free (buf); -} - -void -mail_error_write (GtkHTML *html, GtkHTMLStream *stream, - const char *format, ...) -{ - char *buf, *htmltext; - va_list ap; - - va_start (ap, format); - buf = g_strdup_vprintf (format, ap); - va_end (ap); - - htmltext = e_text_to_html (buf, E_TEXT_TO_HTML_CONVERT_NL); - gtk_html_write (html, stream, "<em><font color=red>", 20); - gtk_html_write (html, stream, htmltext, strlen (htmltext)); - gtk_html_write (html, stream, "</font></em><br>", 16); - g_free (htmltext); - g_free (buf); -} - -static void -clear_data (CamelObject *object, gpointer event_data, gpointer user_data) -{ - GData *data = user_data; - - g_datalist_clear (&data); -} - -static void -redisplay (MailDisplay *md, gboolean unscroll) -{ - GtkAdjustment *adj; - gfloat oldv = 0; - - if (!unscroll) { - adj = e_scroll_frame_get_vadjustment (md->scroll); - oldv = adj->value; - } - - md->stream = gtk_html_begin (md->html); - mail_html_write (md->html, md->stream, "%s%s", HTML_HEADER, - "<BODY TEXT=\"#000000\" BGCOLOR=\"#FFFFFF\">\n"); - - if (md->current_message) { - camel_object_ref (CAMEL_OBJECT (md->current_message)); - mail_format_mime_message (md->current_message, md); - } - - mail_html_write (md->html, md->stream, "</BODY></HTML>\n"); - gtk_html_end (md->html, md->stream, GTK_HTML_STREAM_OK); - md->stream = NULL; - - if (unscroll) { - adj = e_scroll_frame_get_hadjustment (md->scroll); - gtk_adjustment_set_value (adj, 0); - e_scroll_frame_set_hadjustment (md->scroll, adj); - } else { - adj = e_scroll_frame_get_vadjustment (md->scroll); - if (oldv < adj->upper) { - gtk_adjustment_set_value (adj, oldv); - e_scroll_frame_set_vadjustment (md->scroll, adj); - } - } -} - -/** - * mail_display_set_message: - * @mail_display: the mail display object - * @medium: the input camel medium, or %NULL - * - * Makes the mail_display object show the contents of the medium - * param. - **/ -void -mail_display_set_message (MailDisplay *md, CamelMedium *medium) -{ - /* For the moment, we deal only with CamelMimeMessage, but in - * the future, we should be able to deal with any medium. - */ - if (medium && !CAMEL_IS_MIME_MESSAGE (medium)) - return; - - /* Clean up from previous message. */ - if (md->current_message) - camel_object_unref (CAMEL_OBJECT (md->current_message)); - - md->current_message = (CamelMimeMessage*)medium; - - g_datalist_init (md->data); - redisplay (md, TRUE); - if (medium) { - camel_object_hook_event (CAMEL_OBJECT (medium), "finalize", - clear_data, *(md->data)); - } -} - - -/*----------------------------------------------------------------------* - * Standard Gtk+ Class functions - *----------------------------------------------------------------------*/ - -static void -mail_display_init (GtkObject *object) -{ - MailDisplay *mail_display = MAIL_DISPLAY (object); - - /* various other initializations */ - mail_display->current_message = NULL; -} - -static void -mail_display_destroy (GtkObject *object) -{ - MailDisplay *mail_display = MAIL_DISPLAY (object); - - g_datalist_clear (mail_display->data); - g_free (mail_display->data); - - mail_display_parent_class->destroy (object); -} - -static void -mail_display_class_init (GtkObjectClass *object_class) -{ - object_class->destroy = mail_display_destroy; - mail_display_parent_class = gtk_type_class (PARENT_TYPE); -} - -GtkWidget * -mail_display_new (void) -{ - MailDisplay *mail_display = gtk_type_new (mail_display_get_type ()); - GtkWidget *scroll, *html; - - gtk_box_set_homogeneous (GTK_BOX (mail_display), FALSE); - gtk_widget_show (GTK_WIDGET (mail_display)); - - scroll = e_scroll_frame_new (NULL, NULL); - e_scroll_frame_set_policy (E_SCROLL_FRAME (scroll), - GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); - e_scroll_frame_set_shadow_type (E_SCROLL_FRAME (scroll), GTK_SHADOW_IN); - gtk_box_pack_start_defaults (GTK_BOX (mail_display), GTK_WIDGET (scroll)); - gtk_widget_show (GTK_WIDGET (scroll)); - - html = gtk_html_new (); - gtk_html_set_editable (GTK_HTML (html), FALSE); - gtk_signal_connect (GTK_OBJECT (html), "url_requested", - GTK_SIGNAL_FUNC (on_url_requested), - mail_display); - gtk_signal_connect (GTK_OBJECT (html), "object_requested", - GTK_SIGNAL_FUNC (on_object_requested), - mail_display); - gtk_signal_connect (GTK_OBJECT (html), "link_clicked", - GTK_SIGNAL_FUNC (on_link_clicked), - mail_display); - gtk_container_add (GTK_CONTAINER (scroll), html); - gtk_widget_show (GTK_WIDGET (html)); - - mail_display->scroll = E_SCROLL_FRAME (scroll); - mail_display->html = GTK_HTML (html); - mail_display->stream = NULL; - mail_display->data = g_new0 (GData *, 1); - g_datalist_init (mail_display->data); - - return GTK_WIDGET (mail_display); -} - - - -E_MAKE_TYPE (mail_display, "MailDisplay", MailDisplay, mail_display_class_init, mail_display_init, PARENT_TYPE); diff --git a/mail/mail-display.h b/mail/mail-display.h deleted file mode 100644 index 9f2d8a2620..0000000000 --- a/mail/mail-display.h +++ /dev/null @@ -1,58 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -#ifndef _MAIL_DISPLAY_H_ -#define _MAIL_DISPLAY_H_ - -#include <gtk/gtkvbox.h> -#include <gtkhtml/gtkhtml.h> - -#include <gal/widgets/e-scroll-frame.h> - -#include <camel/camel-stream.h> -#include <camel/camel-mime-message.h> -#include <camel/camel-medium.h> - -#include "mail-types.h" - -#define MAIL_DISPLAY_TYPE (mail_display_get_type ()) -#define MAIL_DISPLAY(o) (GTK_CHECK_CAST ((o), MAIL_DISPLAY_TYPE, MailDisplay)) -#define MAIL_DISPLAY_CLASS(k) (GTK_CHECK_CLASS_CAST((k), MAIL_DISPLAY_TYPE, MailDisplayClass)) -#define IS_MAIL_DISPLAY(o) (GTK_CHECK_TYPE ((o), MAIL_DISPLAY_TYPE)) -#define IS_MAIL_DISPLAY_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), MAIL_DISPLAY_TYPE)) - -struct _MailDisplay { - GtkVBox parent; - - EScrollFrame *scroll; - GtkHTML *html; - GtkHTMLStream *stream; - guint idle_id; - - CamelMimeMessage *current_message; - GData **data; -}; - -typedef struct { - GtkVBoxClass parent_class; -} MailDisplayClass; - -GtkType mail_display_get_type (void); -GtkWidget * mail_display_new (void); - -void mail_display_set_message (MailDisplay *mail_display, - CamelMedium *medium); - - -#define HTML_HEADER "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 TRANSITIONAL//EN\">\n<HTML>\n<HEAD>\n<META NAME=\"GENERATOR\" CONTENT=\"Evolution Mail Component\">\n</HEAD>\n" - -void mail_html_write (GtkHTML *html, - GtkHTMLStream *stream, - const char *format, ...); -void mail_text_write (GtkHTML *html, - GtkHTMLStream *stream, - const char *format, ...); -void mail_error_write (GtkHTML *html, - GtkHTMLStream *stream, - const char *format, ...); - -#endif /* _MAIL_DISPLAY_H_ */ diff --git a/mail/mail-format.c b/mail/mail-format.c deleted file mode 100644 index bd9aee294b..0000000000 --- a/mail/mail-format.c +++ /dev/null @@ -1,1798 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Authors: - * Matt Loper <matt@helixcode.com> - * Dan Winship <danw@helixcode.com> - * - * Copyright 2000, Helix Code, Inc. (http://www.helixcode.com) - * - * 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 - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA. - * - */ - -#include <config.h> -#include "mail.h" -#include "mail-tools.h" -#include "mail-display.h" -#include "mail-crypto.h" -#include "shell/e-setup.h" -#include "e-util/e-html-utils.h" -#include <camel/camel-mime-utils.h> -#include <libgnome/libgnome.h> -#include <libgnomevfs/gnome-vfs-mime-info.h> -#include <libgnomevfs/gnome-vfs-mime-handlers.h> -#include <liboaf/liboaf.h> - -#include <ctype.h> /* for isprint */ -#include <string.h> /* for strstr */ -#include <fcntl.h> - -static char *try_inline_pgp (char *start, MailDisplay *md); -static char *try_uudecoding (char *start, MailDisplay *md); -static char *try_inline_binhex (char *start, MailDisplay *md); - -static gboolean handle_text_plain (CamelMimePart *part, - const char *mime_type, - MailDisplay *md); -static gboolean handle_text_plain_flowed (char *text, - MailDisplay *md); -static gboolean handle_text_enriched (CamelMimePart *part, - const char *mime_type, - MailDisplay *md); -static gboolean handle_text_html (CamelMimePart *part, - const char *mime_type, - MailDisplay *md); -static gboolean handle_image (CamelMimePart *part, - const char *mime_type, - MailDisplay *md); -static gboolean handle_multipart_mixed (CamelMimePart *part, - const char *mime_type, - MailDisplay *md); -static gboolean handle_multipart_related (CamelMimePart *part, - const char *mime_type, - MailDisplay *md); -static gboolean handle_multipart_alternative (CamelMimePart *part, - const char *mime_type, - MailDisplay *md); -static gboolean handle_multipart_appledouble (CamelMimePart *part, - const char *mime_type, - MailDisplay *md); -static gboolean handle_multipart_encrypted (CamelMimePart *part, - const char *mime_type, - MailDisplay *md); -static gboolean handle_message_rfc822 (CamelMimePart *part, - const char *mime_type, - MailDisplay *md); -static gboolean handle_message_external_body (CamelMimePart *part, - const char *mime_type, - MailDisplay *md); - -static gboolean handle_via_bonobo (CamelMimePart *part, - const char *mime_type, - MailDisplay *md); - -/* writes the header info for a mime message into an html stream */ -static void write_headers (CamelMimeMessage *message, MailDisplay *md); - -/* dispatch html printing via mimetype */ -static gboolean call_handler_function (CamelMimePart *part, MailDisplay *md); - -static void -free_url (gpointer key, gpointer value, gpointer data) -{ - g_free (key); -} - -static void -free_urls (gpointer urls) -{ - g_hash_table_foreach (urls, free_url, NULL); - g_hash_table_destroy (urls); -} - -static char * -add_url (char *url, gpointer data, MailDisplay *md) -{ - GHashTable *urls; - gpointer old_key, old_value; - - urls = g_datalist_get_data (md->data, "urls"); - g_return_val_if_fail (urls != NULL, NULL); - - if (g_hash_table_lookup_extended (urls, url, &old_key, &old_value)) { - g_free (url); - url = old_key; - } - g_hash_table_insert (urls, url, data); - return url; -} - -/** - * mail_format_mime_message: - * @mime_message: the input mime message - * @md: the MailDisplay to render into - * - * Writes a CamelMimeMessage out into a MailDisplay - **/ -void -mail_format_mime_message (CamelMimeMessage *mime_message, MailDisplay *md) -{ - GHashTable *urls; - - g_return_if_fail (CAMEL_IS_MIME_MESSAGE (mime_message)); - - urls = g_datalist_get_data (md->data, "urls"); - if (!urls) { - urls = g_hash_table_new (g_str_hash, g_str_equal); - g_datalist_set_data_full (md->data, "urls", urls, - free_urls); - } - - write_headers (mime_message, md); - call_handler_function (CAMEL_MIME_PART (mime_message), md); -} - -static const char * -get_cid (CamelMimePart *part, MailDisplay *md) -{ - GHashTable *urls; - char *cid; - gpointer orig_name, value; - - urls = g_datalist_get_data (md->data, "urls"); - - /* If we have a real Content-ID, use it. If we don't, - * make a (syntactically invalid) fake one. - */ - if (camel_mime_part_get_content_id (part)) { - cid = g_strdup_printf ("cid:%s", - camel_mime_part_get_content_id (part)); - } else - cid = g_strdup_printf ("cid:@@@%p", part); - - if (g_hash_table_lookup_extended (urls, cid, &orig_name, &value)) { - g_free (cid); - return orig_name; - } else - g_hash_table_insert (urls, cid, part); - - return cid; -} - -static const char * -get_url_for_icon (const char *icon_name, MailDisplay *md) -{ - static GHashTable *icons; - char *icon_path, buf[1024], *url; - GByteArray *ba; - - if (!icons) - icons = g_hash_table_new (g_str_hash, g_str_equal); - - if (*icon_name == '/') - icon_path = g_strdup (icon_name); - else { - icon_path = gnome_pixmap_file (icon_name); - if (!icon_path) - return "file:///dev/null"; - } - - ba = g_hash_table_lookup (icons, icon_path); - if (!ba) { - int fd, nread; - - fd = open (icon_path, O_RDONLY); - if (fd == -1) { - g_free (icon_path); - return "file:///dev/null"; - } - - ba = g_byte_array_new (); - - while (1) { - nread = read (fd, buf, sizeof (buf)); - if (nread < 1) - break; - g_byte_array_append (ba, buf, nread); - } - close (fd); - - /* FIXME: these aren't freed. */ - g_hash_table_insert (icons, g_strdup (icon_path), ba); - } - g_free (icon_path); - - url = g_strdup_printf ("x-evolution-data:%p", ba); - return add_url (url, ba, md); -} - - -static GHashTable *mime_handler_table, *mime_function_table; - -static void -setup_mime_tables (void) -{ - mime_handler_table = g_hash_table_new (g_str_hash, g_str_equal); - mime_function_table = g_hash_table_new (g_str_hash, g_str_equal); - - g_hash_table_insert (mime_function_table, "text/plain", - handle_text_plain); - g_hash_table_insert (mime_function_table, "text/richtext", - handle_text_enriched); - g_hash_table_insert (mime_function_table, "text/enriched", - handle_text_enriched); - g_hash_table_insert (mime_function_table, "text/html", - handle_text_html); - - g_hash_table_insert (mime_function_table, "image/gif", - handle_image); - g_hash_table_insert (mime_function_table, "image/jpeg", - handle_image); - g_hash_table_insert (mime_function_table, "image/png", - handle_image); - g_hash_table_insert (mime_function_table, "image/x-png", - handle_image); - g_hash_table_insert (mime_function_table, "image/tiff", - handle_image); - g_hash_table_insert (mime_function_table, "image/x-bmp", - handle_image); - g_hash_table_insert (mime_function_table, "image/bmp", - handle_image); - g_hash_table_insert (mime_function_table, "image/x-cmu-raster", - handle_image); - g_hash_table_insert (mime_function_table, "image/x-ico", - handle_image); - g_hash_table_insert (mime_function_table, "image/x-portable-anymap", - handle_image); - g_hash_table_insert (mime_function_table, "image/x-portable-bitmap", - handle_image); - g_hash_table_insert (mime_function_table, "image/x-portable-graymap", - handle_image); - g_hash_table_insert (mime_function_table, "image/x-portable-pixmap", - handle_image); - g_hash_table_insert (mime_function_table, "image/x-xpixmap", - handle_image); - - g_hash_table_insert (mime_function_table, "message/rfc822", - handle_message_rfc822); - g_hash_table_insert (mime_function_table, "message/news", - handle_message_rfc822); - g_hash_table_insert (mime_function_table, "message/external-body", - handle_message_external_body); - - g_hash_table_insert (mime_function_table, "multipart/alternative", - handle_multipart_alternative); - g_hash_table_insert (mime_function_table, "multipart/related", - handle_multipart_related); - g_hash_table_insert (mime_function_table, "multipart/mixed", - handle_multipart_mixed); - g_hash_table_insert (mime_function_table, "multipart/appledouble", - handle_multipart_appledouble); - g_hash_table_insert (mime_function_table, "multipart/encrypted", - handle_multipart_encrypted); - - /* RFC 2046 says unrecognized text subtypes can be treated - * as text/plain (as long as you recognize the character set), - * and unrecognized multipart subtypes as multipart/mixed. - */ - g_hash_table_insert (mime_function_table, "text/*", - handle_text_plain); - g_hash_table_insert (mime_function_table, "multipart/*", - handle_multipart_mixed); -} - -static gboolean -component_supports (OAF_ServerInfo *component, const char *mime_type) -{ - OAF_Property *prop; - CORBA_sequence_CORBA_string stringv; - int i; - - prop = oaf_server_info_prop_find (component, - "bonobo:supported_mime_types"); - if (!prop || prop->v._d != OAF_P_STRINGV) - return FALSE; - - stringv = prop->v._u.value_stringv; - for (i = 0; i < stringv._length; i++) { - if (!g_strcasecmp (mime_type, stringv._buffer[i])) - return TRUE; - } - return FALSE; -} - -/** - * mail_lookup_handler: - * @mime_type: a MIME type - * - * Looks up the MIME type in its own tables and GNOME-VFS's and returns - * a MailMimeHandler structure detailing the component, application, - * and built-in handlers (if any) for that MIME type. (If the component - * is non-%NULL, the built-in handler will always be handle_via_bonobo().) - * The MailMimeHandler's @generic field is set if the match was for the - * MIME supertype rather than the exact type. - * - * Return value: a MailMimeHandler (which should not be freed), or %NULL - * if no handlers are available. - **/ -MailMimeHandler * -mail_lookup_handler (const char *mime_type) -{ - MailMimeHandler *handler; - char *mime_type_main; - - if (mime_handler_table == NULL) - setup_mime_tables (); - - /* See if we've already found it. */ - handler = g_hash_table_lookup (mime_handler_table, mime_type); - if (handler) - return handler; - - /* No. Create a new one and look up application and full type - * handler. If we find a builtin, create the handler and - * register it. - */ - handler = g_new0 (MailMimeHandler, 1); - handler->application = - gnome_vfs_mime_get_default_application (mime_type); - handler->builtin = - g_hash_table_lookup (mime_function_table, mime_type); - - if (handler->builtin) { - handler->generic = FALSE; - goto reg; - } - - /* Try for a exact component match. */ - handler->component = gnome_vfs_mime_get_default_component (mime_type); - if (handler->component && - component_supports (handler->component, mime_type)) { - handler->generic = FALSE; - handler->builtin = handle_via_bonobo; - goto reg; - } - - /* Try for a generic builtin match. */ - mime_type_main = g_strdup_printf ("%.*s/*", - (int)strcspn (mime_type, "/"), - mime_type); - handler->builtin = g_hash_table_lookup (mime_function_table, - mime_type_main); - g_free (mime_type_main); - - if (handler->builtin) { - handler->generic = TRUE; - if (handler->component) { - CORBA_free (handler->component); - handler->component = NULL; - } - goto reg; - } - - /* Try for a generic component match. */ - if (handler->component) { - handler->generic = TRUE; - handler->builtin = handle_via_bonobo; - goto reg; - } - - /* If we at least got an application, use that. */ - if (handler->application) { - handler->generic = TRUE; - goto reg; - } - - /* Nada. */ - g_free (handler); - return NULL; - - reg: - g_hash_table_insert (mime_handler_table, g_strdup (mime_type), - handler); - return handler; -} - -/* An "anonymous" MIME part is one that we shouldn't call attention - * to the existence of, but simply display. - */ -static gboolean -is_anonymous (CamelMimePart *part, const char *mime_type) -{ - if (!g_strncasecmp (mime_type, "multipart/", 10) || - !g_strncasecmp (mime_type, "message/", 8)) - return TRUE; - - if (!g_strncasecmp (mime_type, "text/", 5) && - !camel_mime_part_get_filename (part)) - return TRUE; - - return FALSE; -} - -/** - * mail_part_is_inline: - * @part: a CamelMimePart - * - * Return value: whether or not the part should/will be displayed inline. - **/ -gboolean -mail_part_is_inline (CamelMimePart *part) -{ - const char *disposition; - GMimeContentField *content_type; - const char *mime_type; - - /* If it has an explicit disposition, return that. */ - disposition = camel_mime_part_get_disposition (part); - if (disposition) - return g_strcasecmp (disposition, "inline") == 0; - - /* Certain types should default to inline. FIXME: this should - * be customizable. - */ - content_type = camel_mime_part_get_content_type (part); - mime_type = gmime_content_field_get_mime_type (content_type); - if (!g_strncasecmp (mime_type, "message/", 8)) - return TRUE; - - /* Otherwise, display it inline if it's "anonymous", and - * as an attachment otherwise. - */ - return is_anonymous (part, mime_type); -} - -static void -attachment_header (CamelMimePart *part, const char *mime_type, - gboolean is_inline, MailDisplay *md) -{ - const char *info; - char *htmlinfo; - - /* No header for anonymous inline parts. */ - if (is_inline && is_anonymous (part, mime_type)) - return; - - /* Start the table, create the pop-up object. */ - mail_html_write (md->html, md->stream, "<table><tr><td>" - "<object classid=\"popup:%s\" type=\"%s\">" - "</object></td><td><font size=-1>", - get_cid (part, md), mime_type); - - /* Write the MIME type */ - info = gnome_vfs_mime_get_value (mime_type, "description"); - htmlinfo = e_text_to_html (info ? info : mime_type, 0); - mail_html_write (md->html, md->stream, _("%s attachment"), htmlinfo); - g_free (htmlinfo); - - /* Write the name, if we have it. */ - info = camel_mime_part_get_filename (part); - if (info) { - htmlinfo = e_text_to_html (info, 0); - mail_html_write (md->html, md->stream, " (%s)", htmlinfo); - g_free (htmlinfo); - } - - /* Write a description, if we have one. */ - info = camel_mime_part_get_description (part); - if (info) { - htmlinfo = e_text_to_html (info, E_TEXT_TO_HTML_CONVERT_URLS); - mail_html_write (md->html, md->stream, ", \"%s\"", htmlinfo); - g_free (htmlinfo); - } - -#if 0 - /* Describe the click action, if any. */ - if (action) { - mail_html_write (md->html, md->stream, - "<br>Click on the icon to %s.", action); - } -#endif - - mail_html_write (md->html, md->stream, "</font></td></tr></table>"); -} - -static gboolean -call_handler_function (CamelMimePart *part, MailDisplay *md) -{ - CamelDataWrapper *wrapper; - char *mime_type; - MailMimeHandler *handler; - gboolean output, is_inline; - - wrapper = camel_medium_get_content_object (CAMEL_MEDIUM (part)); - mime_type = camel_data_wrapper_get_mime_type (wrapper); - g_strdown (mime_type); - - handler = mail_lookup_handler (mime_type); - if (!handler) { - char *id_type; - - id_type = mail_identify_mime_part (part); - if (id_type) { - g_free (mime_type); - mime_type = id_type; - handler = mail_lookup_handler (id_type); - } - } - - is_inline = mail_part_is_inline (part); - attachment_header (part, mime_type, is_inline, md); - if (handler && handler->builtin && is_inline) - output = (*handler->builtin) (part, mime_type, md); - else - output = TRUE; - - g_free (mime_type); - return output; -} - -static void -write_field_to_stream (const char *description, const char *value, - gboolean value_is_encoded, gboolean bold, GtkHTML *html, - GtkHTMLStream *stream) -{ - char *encoded_value; - - if (value) { - char *raw, *p; - - if (value_is_encoded) - raw = header_decode_string (value); - else - raw = g_strdup (value); - - encoded_value = e_text_to_html (raw, - E_TEXT_TO_HTML_CONVERT_NL | - E_TEXT_TO_HTML_CONVERT_URLS); - g_free (raw); - for (p = encoded_value; *p; p++) { - if (!isprint (*p)) - *p = '?'; - } - } else - encoded_value = ""; - - mail_html_write (html, stream, - "<tr valign=top><%s align=right>%s</%s>" - "<td>%s</td></tr>", bold ? "th" : "td", - description, bold ? "th" : "td", encoded_value); - if (value) - g_free (encoded_value); -} - -static void -write_headers (CamelMimeMessage *message, MailDisplay *md) -{ - const CamelInternetAddress *recipients; - const char *reply_to; - char *string; - - mail_html_write (md->html, md->stream, - "<table bgcolor=\"#EEEEEE\" width=\"100%%\" " - "cellspacing=0 border=1>" - "<tr><td><table>\n"); - - write_field_to_stream (_("From:"), - camel_mime_message_get_from (message), - TRUE, TRUE, md->html, md->stream); - - reply_to = camel_mime_message_get_reply_to (message); - if (reply_to) { - write_field_to_stream (_("Reply-To:"), reply_to, TRUE, FALSE, - md->html, md->stream); - } - - recipients = camel_mime_message_get_recipients ( - message, CAMEL_RECIPIENT_TYPE_TO); - string = camel_address_encode (CAMEL_ADDRESS (recipients)); - write_field_to_stream (_("To:"), string ? string : "", TRUE, TRUE, - md->html, md->stream); - g_free (string); - - recipients = camel_mime_message_get_recipients(message, CAMEL_RECIPIENT_TYPE_CC); - string = camel_address_encode(CAMEL_ADDRESS(recipients)); - if (string) { - write_field_to_stream (_("Cc:"), string, TRUE, TRUE, - md->html, md->stream); - } - g_free (string); - - write_field_to_stream (_("Subject:"), - camel_mime_message_get_subject (message), - FALSE, TRUE, md->html, md->stream); - - mail_html_write (md->html, md->stream, - "</table></td></tr></table></center><p>"); -} - - -/* Return the contents of a text-based data wrapper, or NULL if it - * contains only whitespace. - */ -static char * -get_data_wrapper_text (CamelDataWrapper *data) -{ - CamelStream *memstream; - GByteArray *ba; - char *text, *end; - - ba = g_byte_array_new (); - memstream = camel_stream_mem_new_with_byte_array (ba); - - camel_data_wrapper_write_to_stream (data, memstream); - - for (text = ba->data, end = ba->data + ba->len; text < end; text++) { - if (!isspace ((unsigned char)*text)) - break; - } - - if (text < end) { - text = g_malloc (ba->len + 1); - memcpy (text, ba->data, ba->len); - text[ba->len] = '\0'; - } else - text = NULL; - - camel_object_unref (CAMEL_OBJECT (memstream)); - return text; -} - -/*----------------------------------------------------------------------* - * Mime handling functions - *----------------------------------------------------------------------*/ - -struct { - char *start; - char * (*handler) (char *start, MailDisplay *md); -} text_specials[] = { - { "-----BEGIN PGP MESSAGE-----\n", try_inline_pgp }, - { "begin ", try_uudecoding }, - { "(This file must be converted with BinHex 4.0)\n", try_inline_binhex } -}; -#define NSPECIALS (sizeof (text_specials) / sizeof (*text_specials)) - -static gboolean -handle_text_plain (CamelMimePart *part, const char *mime_type, - MailDisplay *md) -{ - CamelDataWrapper *wrapper = - camel_medium_get_content_object (CAMEL_MEDIUM (part)); - char *text, *p, *start, *subtext; - GMimeContentField *type; - const char *format; - int i; - - text = get_data_wrapper_text (wrapper); - if (!text) - return FALSE; - - /* Check for RFC 2646 flowed text. */ - type = camel_mime_part_get_content_type (part); - format = gmime_content_field_get_parameter (type, "format"); - if (format && !g_strcasecmp (format, "flowed")) - return handle_text_plain_flowed (text, md); - - mail_html_write (md->html, md->stream, "\n<!-- text/plain -->\n"); - - p = text; - while (p) { - /* Look for special cases. */ - for (i = 0; i < NSPECIALS; i++) { - start = strstr (p, text_specials[i].start); - if (start && (start == p || start[-1] == '\n')) - break; - } - if (!start) - break; - - /* Deal with special case */ - if (start != p) { - subtext = g_strndup (p, start - p); - mail_text_write (md->html, md->stream, - "%s", subtext); - g_free (subtext); - } - p = text_specials[i].handler (start, md); - if (p == start) { - /* Oops. That failed. Output this line normally and - * skip over it. - */ - p = strchr (start, '\n'); - if (!p++) - break; - subtext = g_strndup (start, p - start); - mail_text_write (md->html, md->stream, - "%s", subtext); - g_free (subtext); - } else if (p) - mail_html_write (md->html, md->stream, "<hr>"); - } - /* Finish up (or do the whole thing if there were no specials). */ - if (p) - mail_text_write (md->html, md->stream, "%s", p); - - g_free (text); - return TRUE; -} - -static gboolean -handle_text_plain_flowed (char *buf, MailDisplay *md) -{ - char *text, *line, *eol, *p; - int prevquoting = 0, quoting, len; - gboolean br_pending = FALSE; - - mail_html_write (md->html, md->stream, - "\n<!-- text/plain, flowed -->\n<tt>\n"); - - for (line = buf; *line; line = eol + 1) { - /* Process next line */ - eol = strchr (line, '\n'); - if (eol) - *eol = '\0'; - - quoting = 0; - for (p = line; *p == '>'; p++) - quoting++; - if (quoting != prevquoting) { - mail_html_write (md->html, md->stream, "%s\n", - prevquoting == 0 ? "<i>\n" : ""); - while (quoting > prevquoting) { - mail_html_write (md->html, md->stream, - "<blockquote>"); - prevquoting++; - } - while (quoting < prevquoting) { - mail_html_write (md->html, md->stream, - "</blockquote>"); - prevquoting--; - } - mail_html_write (md->html, md->stream, "%s\n", - prevquoting == 0 ? "</i>\n" : ""); - } else if (br_pending) { - mail_html_write (md->html, md->stream, "<br>\n"); - br_pending = FALSE; - } - - if (*p == ' ') - p++; - - /* replace '<' with '<', etc. */ - text = e_text_to_html (p, E_TEXT_TO_HTML_CONVERT_SPACES | - E_TEXT_TO_HTML_CONVERT_URLS); - if (text && *text) - mail_html_write (md->html, md->stream, "%s", text); - g_free (text); - - len = strlen (p); - if (len == 0 || p[len - 1] != ' ' || !strcmp (p, "-- ")) - br_pending = TRUE; - - if (!eol) - break; - } - g_free (buf); - - mail_html_write (md->html, md->stream, "</tt>\n"); - return TRUE; -} - -static CamelMimePart * -fake_mime_part_from_data (const char *data, int len, const char *type) -{ - CamelStream *memstream; - CamelDataWrapper *wrapper; - CamelMimePart *part; - - memstream = camel_stream_mem_new_with_buffer (data, len); - wrapper = camel_data_wrapper_new (); - camel_data_wrapper_construct_from_stream (wrapper, memstream); - camel_data_wrapper_set_mime_type (wrapper, type); - camel_object_unref (CAMEL_OBJECT (memstream)); - part = camel_mime_part_new (); - camel_medium_set_content_object (CAMEL_MEDIUM (part), wrapper); - camel_object_unref (CAMEL_OBJECT (wrapper)); - camel_mime_part_set_disposition (part, "inline"); - return part; -} - -static void -destroy_part (CamelObject *root, gpointer event_data, gpointer user_data) -{ - camel_object_unref (user_data); -} - -static char * -decode_pgp (const char *ciphertext, MailDisplay *md) -{ - CamelException ex; - char *plaintext; - - camel_exception_init (&ex); -#ifdef PGP_PROGRAM - /* FIXME: multipart parts */ - if (g_datalist_get_data (md->data, "show_pgp")) { - plaintext = mail_crypto_openpgp_decrypt (ciphertext, &ex); - if (plaintext) - return plaintext; - } -#else - camel_exception_set (&ex, CAMEL_EXCEPTION_SYSTEM, - _("No GPG/PGP support available in this copy " - "of Evolution.")); -#endif - - mail_html_write (md->html, md->stream, - "<table><tr valign=top><td>" - "<a href=\"x-evolution-decode-pgp:\">" - "<img src=\"%s\"></a></td><td>", - get_url_for_icon ("gnome-lockscreen.png", md)); - - if (camel_exception_is_set (&ex)) { - mail_html_write (md->html, md->stream, "%s<br><br>\n", - _("Encrypted message not displayed")); - mail_error_write (md->html, md->stream, - camel_exception_get_description (&ex)); - camel_exception_clear (&ex); - } else { - mail_html_write (md->html, md->stream, "%s<br><br>\n%s", - _("Encrypted message"), - _("Click icon to decrypt.")); - } - - mail_html_write (md->html, md->stream, "</td></tr></table>"); - return NULL; -} - -static char * -try_inline_pgp (char *start, MailDisplay *md) -{ - char *end, *ciphertext, *plaintext; - - /* FIXME: This should deal with signed data as well. */ - - end = strstr (start, "-----END PGP MESSAGE-----"); - if (!end) - return start; - - end += sizeof ("-----END PGP MESSAGE-----") - 1; - - mail_html_write (md->html, md->stream, "<hr>"); - - ciphertext = g_strndup (start, end - start); - plaintext = decode_pgp (ciphertext, md); - g_free (ciphertext); - if (plaintext) { - mail_html_write (md->html, md->stream, - "<table width=\"100%%\" border=2 " - "cellpadding=4><tr><td>"); - mail_text_write (md->html, md->stream, "%s", plaintext); - mail_html_write (md->html, md->stream, "</td></tr></table>"); - g_free (plaintext); - } - - return end; -} - -static char * -try_uudecoding (char *start, MailDisplay *md) -{ - int mode, len, state = 0; - char *filename, *estart, *p, *out, uulen = 0; - guint32 save = 0; - CamelMimePart *part; - - /* Make sure it's a real uudecode begin line: - * begin [0-7]+ .* - */ - mode = strtoul (start + 6, &p, 8); - if (p == start + 6 || *p != ' ') - return start; - estart = strchr (start, '\n'); - if (!estart) - return start; - - while (isspace ((unsigned char)*p)) - p++; - filename = g_strndup (p, estart++ - p); - - /* Make sure there's an end line. */ - p = strstr (p, "\nend\n"); - if (!p) { - g_free (filename); - return start; - } - - out = g_malloc (p - estart); - len = uudecode_step (estart, p - estart, out, &state, &save, &uulen); - - part = fake_mime_part_from_data (out, len, "application/octet-stream"); - g_free (out); - camel_mime_part_set_filename (part, filename); - g_free (filename); - camel_object_hook_event (CAMEL_OBJECT (md->current_message), - "finalize", destroy_part, part); - - mail_html_write (md->html, md->stream, "<hr>"); - call_handler_function (part, md); - - return p + 4; -} - -static char * -try_inline_binhex (char *start, MailDisplay *md) -{ - char *p; - CamelMimePart *part; - - /* Find data start. */ - p = strstr (start, "\n:"); - if (!p) - return start; - - /* And data end. */ - p = strchr (p + 2, ':'); - if (!p || (*(p + 1) != '\n' && *(p + 1) != '\0')) - return start; - p += 2; - - part = fake_mime_part_from_data (start, p - start, - "application/mac-binhex40"); - camel_object_hook_event (CAMEL_OBJECT (md->current_message), - "finalize", destroy_part, part); - - mail_html_write (md->html, md->stream, "<hr>"); - call_handler_function (part, md); - - return p; -} - -static void -free_byte_array (CamelObject *obj, gpointer event_data, gpointer user_data) -{ - /* We don't have to do a forward event here right now */ - g_byte_array_free (user_data, TRUE); -} - -/* text/enriched (RFC 1896) or text/richtext (included in RFC 1341) */ -static gboolean -handle_text_enriched (CamelMimePart *part, const char *mime_type, - MailDisplay *md) -{ - static GHashTable *translations = NULL; - CamelDataWrapper *wrapper = - camel_medium_get_content_object (CAMEL_MEDIUM (part)); - GString *string; - GByteArray *ba; - char *text, *p, *xed; - int len, nofill = 0; - gboolean enriched; - - if (!translations) { - translations = g_hash_table_new (g_strcase_hash, - g_strcase_equal); - g_hash_table_insert (translations, "bold", "<b>"); - g_hash_table_insert (translations, "/bold", "</b>"); - g_hash_table_insert (translations, "italic", "<i>"); - g_hash_table_insert (translations, "/italic", "</i>"); - g_hash_table_insert (translations, "fixed", "<tt>"); - g_hash_table_insert (translations, "/fixed", "</tt>"); - g_hash_table_insert (translations, "smaller", "<font size=-1>"); - g_hash_table_insert (translations, "/smaller", "</font>"); - g_hash_table_insert (translations, "bigger", "<font size=+1>"); - g_hash_table_insert (translations, "/bigger", "</font>"); - g_hash_table_insert (translations, "underline", "<u>"); - g_hash_table_insert (translations, "/underline", "</u>"); - g_hash_table_insert (translations, "center", "<p align=center>"); - g_hash_table_insert (translations, "/center", "</p>"); - g_hash_table_insert (translations, "flushleft", "<p align=left>"); - g_hash_table_insert (translations, "/flushleft", "</p>"); - g_hash_table_insert (translations, "flushright", "<p align=right>"); - g_hash_table_insert (translations, "/flushright", "</p>"); - g_hash_table_insert (translations, "excerpt", "<blockquote>"); - g_hash_table_insert (translations, "/excerpt", "</blockquote>"); - g_hash_table_insert (translations, "paragraph", "<p>"); - g_hash_table_insert (translations, "signature", "<address>"); - g_hash_table_insert (translations, "/signature", "</address>"); - g_hash_table_insert (translations, "comment", "<!-- "); - g_hash_table_insert (translations, "/comment", " -->"); - g_hash_table_insert (translations, "param", "<!-- "); - g_hash_table_insert (translations, "/param", " -->"); - g_hash_table_insert (translations, "np", "<hr>"); - } - - text = get_data_wrapper_text (wrapper); - if (!text) - return FALSE; - - if (!g_strcasecmp (mime_type, "text/richtext")) { - enriched = FALSE; - mail_html_write (md->html, md->stream, - "\n<!-- text/richtext -->\n"); - } else { - enriched = TRUE; - mail_html_write (md->html, md->stream, - "\n<!-- text/enriched -->\n"); - } - - /* This is not great code, but I don't feel like fixing it right - * now. I mean, it's just text/enriched... - */ - p = text; - string = g_string_sized_new (2 * strlen (p)); - - while (p) { - len = strcspn (p, " <>&\n"); - if (len) - g_string_sprintfa (string, "%.*s", len, p); - - p += len; - if (!*p) - break; - - switch (*p++) { - case ' ': - while (*p == ' ') { - g_string_append (string, " "); - p++; - } - g_string_append (string, " "); - break; - - case '\n': - g_string_append (string, " "); - if (enriched && nofill <= 0) { - while (*p == '\n') { - g_string_append (string, "<br>"); - p++; - } - } - break; - - case '>': - g_string_append (string, ">"); - break; - - case '&': - g_string_append (string, "&"); - break; - - case '<': - if (enriched) { - if (*p == '<') { - g_string_append (string, "<"); - p++; - break; - } - } else { - if (strncmp (p, "lt>", 3) == 0) { - g_string_append (string, "<"); - p += 3; - break; - } else if (strncmp (p, "nl>", 3) == 0) { - g_string_append (string, "<br>"); - p += 3; - break; - } - } - - if (strncmp (p, "nofill>", 7) == 0) { - nofill++; - g_string_append (string, "<pre>"); - } else if (strncmp (p, "/nofill>", 8) == 0) { - nofill--; - g_string_append (string, "</pre>"); - } else { - char *copy, *match; - - len = strcspn (p, ">"); - copy = g_strndup (p, len); - match = g_hash_table_lookup (translations, - copy); - g_free (copy); - if (match) - g_string_append (string, match); - } - - p = strchr (p, '>'); - if (p) - p++; - } - } - g_free (text); - - ba = g_byte_array_new (); - g_byte_array_append (ba, (const guint8 *)string->str, - strlen (string->str)); - g_string_free (string, TRUE); - - xed = g_strdup_printf ("x-evolution-data:%p", part); - mail_html_write (md->html, md->stream, - "<iframe src=\"%s\" frameborder=0 scrolling=no>" - "</iframe>", xed); - add_url (xed, ba, md); - camel_object_hook_event (CAMEL_OBJECT (md->current_message), - "finalize", free_byte_array, ba); - - return TRUE; -} - -static gboolean -handle_text_html (CamelMimePart *part, const char *mime_type, - MailDisplay *md) -{ - mail_html_write (md->html, md->stream, "\n<!-- text/html -->\n"); - mail_html_write (md->html, md->stream, - "<iframe src=\"%s\" frameborder=0 scrolling=no>" - "</iframe>", get_cid (part, md)); - return TRUE; -} - -static gboolean -handle_image (CamelMimePart *part, const char *mime_type, MailDisplay *md) -{ - mail_html_write (md->html, md->stream, "<img src=\"%s\">", - get_cid (part, md)); - return TRUE; -} - -static gboolean -handle_multipart_mixed (CamelMimePart *part, const char *mime_type, - MailDisplay *md) -{ - CamelDataWrapper *wrapper = - camel_medium_get_content_object (CAMEL_MEDIUM (part)); - CamelMultipart *mp; - int i, nparts; - gboolean output = FALSE; - - g_return_val_if_fail (CAMEL_IS_MULTIPART (wrapper), FALSE); - mp = CAMEL_MULTIPART (wrapper); - - nparts = camel_multipart_get_number (mp); - for (i = 0; i < nparts; i++) { - if (i != 0 && output) - mail_html_write (md->html, md->stream, "<hr>\n"); - - part = camel_multipart_get_part (mp, i); - - output = call_handler_function (part, md); - } - - return TRUE; -} - -static gboolean -is_rfc2015 (CamelMimePart *part) -{ - int nparts; - char *text; - CamelDataWrapper *wrapper; - CamelMultipart *mp; - GMimeContentField *type; - - wrapper = camel_medium_get_content_object (CAMEL_MEDIUM (part)); - mp = CAMEL_MULTIPART (wrapper); - nparts = camel_multipart_get_number (mp); - if (nparts != 2) - return FALSE; - - /* Check for application/pgp-encrypted in the first part. */ - part = camel_multipart_get_part (mp, 0); - type = camel_mime_part_get_content_type (part); - if (!gmime_content_field_is_type (type, "application", "pgp-encrypted")) - return FALSE; - - /* Check version. */ - wrapper = camel_medium_get_content_object (CAMEL_MEDIUM (part)); - text = get_data_wrapper_text (wrapper); - if (!text || !strstr(text, "Version: 1")) { - g_free(text); - return FALSE; - } - g_free(text); - - /* Check for application/octet-stream in the second part. */ - part = camel_multipart_get_part(mp, 1); - type = camel_mime_part_get_content_type (part); - if (!gmime_content_field_is_type (type, "application", "octet-stream")) - return FALSE; - - return TRUE; -} - -static gboolean -handle_multipart_encrypted (CamelMimePart *part, const char *mime_type, - MailDisplay *md) -{ - CamelDataWrapper *wrapper = - camel_medium_get_content_object (CAMEL_MEDIUM (part)); - CamelMultipart *mp; - char *ciphertext, *plaintext; - - g_return_val_if_fail (CAMEL_IS_MULTIPART (wrapper), FALSE); - mp = CAMEL_MULTIPART (wrapper); - - /* Currently we only handle RFC2015-style PGP encryption. */ - if (!is_rfc2015 (part)) - return handle_multipart_mixed (part, mime_type, md); - - part = camel_multipart_get_part (mp, 1); - wrapper = camel_medium_get_content_object (CAMEL_MEDIUM (part)); - ciphertext = get_data_wrapper_text (wrapper); - if (!ciphertext) - return FALSE; - - plaintext = decode_pgp (ciphertext, md); - if (plaintext) { - CamelStream *memstream; - - memstream = camel_stream_mem_new_with_buffer (plaintext, - strlen (plaintext)); - part = camel_mime_part_new (); - camel_data_wrapper_construct_from_stream (CAMEL_DATA_WRAPPER (part), - memstream); - camel_object_unref (CAMEL_OBJECT (memstream)); - - mail_html_write (md->html, md->stream, - "<table width=\"100%%\" border=2 " - "cellpadding=4><tr><td>"); - call_handler_function (part, md); - mail_html_write (md->html, md->stream, "</td></tr></table>"); - camel_object_hook_event (CAMEL_OBJECT (md->current_message), - "finalize", destroy_part, part); - g_free (plaintext); - } - - return TRUE; -} - -/* As seen in RFC 2387! */ -static gboolean -handle_multipart_related (CamelMimePart *part, const char *mime_type, - MailDisplay *md) -{ - CamelDataWrapper *wrapper = - camel_medium_get_content_object (CAMEL_MEDIUM (part)); - CamelMultipart *mp; - CamelMimePart *body_part, *display_part = NULL; - GMimeContentField *content_type; - const char *start; - int i, nparts; - - g_return_val_if_fail (CAMEL_IS_MULTIPART (wrapper), FALSE); - mp = CAMEL_MULTIPART (wrapper); - nparts = camel_multipart_get_number (mp); - - content_type = camel_mime_part_get_content_type (part); - start = gmime_content_field_get_parameter (content_type, "start"); - if (start) { - int len; - - /* The "start" parameter includes <>s, which Content-Id - * does not. - */ - len = strlen (start) - 2; - - for (i = 0; i < nparts; i++) { - const char *cid; - - body_part = camel_multipart_get_part (mp, i); - cid = camel_mime_part_get_content_id (body_part); - - if (!strncmp (cid, start + 1, len) && - strlen (cid) == len) { - display_part = body_part; - break; - } - } - - if (!display_part) { - /* Oops. Hrmph. */ - return handle_multipart_mixed (part, mime_type, md); - } - } else { - /* No start parameter, so it defaults to the first part. */ - display_part = camel_multipart_get_part (mp, 0); - } - - /* Record the Content-IDs of any non-displayed parts. */ - for (i = 0; i < nparts; i++) { - body_part = camel_multipart_get_part (mp, i); - if (body_part == display_part) - continue; - - get_cid (body_part, md); - } - - /* Now, display the displayed part. */ - return call_handler_function (display_part, md); -} - -/* RFC 2046 says "display the last part that you are able to display". */ -static CamelMimePart * -find_preferred_alternative (CamelMultipart *multipart, gboolean want_plain) -{ - int i, nparts; - CamelMimePart *preferred_part = NULL; - MailMimeHandler *handler; - - nparts = camel_multipart_get_number (multipart); - for (i = 0; i < nparts; i++) { - CamelMimePart *part = camel_multipart_get_part (multipart, i); - char *mime_type = gmime_content_field_get_mime_type ( - camel_mime_part_get_content_type (part)); - - g_strdown (mime_type); - if (want_plain && !strcmp (mime_type, "text/plain")) - return part; - handler = mail_lookup_handler (mime_type); - if (handler && (!preferred_part || !handler->generic)) - preferred_part = part; - g_free (mime_type); - } - - return preferred_part; -} - -static gboolean -handle_multipart_alternative (CamelMimePart *part, const char *mime_type, - MailDisplay *md) -{ - CamelDataWrapper *wrapper = - camel_medium_get_content_object (CAMEL_MEDIUM (part)); - CamelMultipart *multipart; - CamelMimePart *mime_part; - - g_return_val_if_fail (CAMEL_IS_MULTIPART (wrapper), FALSE); - multipart = CAMEL_MULTIPART (wrapper); - - mime_part = find_preferred_alternative (multipart, FALSE); - if (mime_part) - return call_handler_function (mime_part, md); - else - return handle_multipart_mixed (part, mime_type, md); -} - -/* RFC 1740 */ -static gboolean -handle_multipart_appledouble (CamelMimePart *part, const char *mime_type, - MailDisplay *md) -{ - CamelDataWrapper *wrapper = - camel_medium_get_content_object (CAMEL_MEDIUM (part)); - CamelMultipart *multipart; - - g_return_val_if_fail (CAMEL_IS_MULTIPART (wrapper), FALSE); - multipart = CAMEL_MULTIPART (wrapper); - - /* The first part is application/applefile and is not useful - * to us. The second part _may_ be displayable data. Most - * likely it's application/octet-stream though. - */ - part = camel_multipart_get_part (multipart, 1); - return call_handler_function (part, md); -} - -static gboolean -handle_message_rfc822 (CamelMimePart *part, const char *mime_type, - MailDisplay *md) -{ - CamelDataWrapper *wrapper = - camel_medium_get_content_object (CAMEL_MEDIUM (part)); - - g_return_val_if_fail (CAMEL_IS_MIME_MESSAGE (wrapper), FALSE); - - mail_html_write (md->html, md->stream, "<blockquote>"); - mail_format_mime_message (CAMEL_MIME_MESSAGE (wrapper), md); - mail_html_write (md->html, md->stream, "</blockquote>"); - - return TRUE; -} - -static gboolean -handle_message_external_body (CamelMimePart *part, const char *mime_type, - MailDisplay *md) -{ - GMimeContentField *type; - const char *access_type; - char *url = NULL, *desc = NULL; - - type = camel_mime_part_get_content_type (part); - access_type = gmime_content_field_get_parameter (type, "access-type"); - if (!access_type) - goto fallback; - - if (!g_strcasecmp (access_type, "ftp") || - !g_strcasecmp (access_type, "anon-ftp")) { - const char *name, *site, *dir, *mode, *ftype; - char *path; - - name = gmime_content_field_get_parameter (type, "name"); - site = gmime_content_field_get_parameter (type, "site"); - if (name == NULL || site == NULL) - goto fallback; - dir = gmime_content_field_get_parameter (type, "directory"); - mode = gmime_content_field_get_parameter (type, "mode"); - - /* Generate the path. */ - if (dir) { - const char *p = dir + strlen (dir); - - path = g_strdup_printf ("%s%s%s%s", - *dir == '/' ? "" : "/", - dir, - *p == '/' ? "" : "/", - name); - } else { - path = g_strdup_printf ("%s%s", - *name == '/' ? "" : "/", - name); - } - - if (mode && *mode == 'A') - ftype = ";type=A"; - else if (mode && *mode == 'I') - ftype = ";type=I"; - else - ftype = ""; - - url = g_strdup_printf ("ftp://%s%s%s", site, path, ftype); - g_free (path); - desc = g_strdup_printf (_("Pointer to FTP site (%s)"), url); - } else if (!g_strcasecmp (access_type, "local-file")) { - const char *name, *site; - - name = gmime_content_field_get_parameter (type, "name"); - if (name == NULL) - goto fallback; - site = gmime_content_field_get_parameter (type, "site"); - - url = g_strdup_printf ("file://%s%s", *name == '/' ? "" : "/", - name); - if (site) { - desc = g_strdup_printf (_("Pointer to local file (%s) " - "valid at site \"%s\""), - name, site); - } else { - desc = g_strdup_printf (_("Pointer to local file (%s)"), - name); - } - } else if (!g_strcasecmp (access_type, "URL")) { - const char *urlparam; - char *s, *d; - - /* RFC 2017 */ - - urlparam = gmime_content_field_get_parameter (type, "url"); - if (urlparam == NULL) - goto fallback; - - /* For obscure MIMEy reasons, the URL may be split into - * multiple words, and needs to be rejoined. (The URL - * must have any real whitespace %-encoded, so we just - * get rid of all of it. - */ - url = g_strdup (urlparam); - s = d = url; - - while (*s) { - if (!isspace ((unsigned char)*s)) - *d++ = *s; - s++; - } - *d = *s; - - desc = g_strdup_printf ("Pointer to remote data (%s)", url); - } - - fallback: - if (!desc) { - if (access_type) { - desc = g_strdup_printf (_("Pointer to unknown " - "external data " - "(\"%s\" type)"), - access_type); - } else - desc = g_strdup (_("Malformed external-body part.")); - } - -#if 0 /* FIXME */ - handle_mystery (part, md, url, "gnome-globe.png", desc, - url ? "open it in a browser" : NULL); -#endif - - g_free (desc); - g_free (url); - return TRUE; -} - -static gboolean -handle_via_bonobo (CamelMimePart *part, const char *mime_type, - MailDisplay *md) -{ - mail_html_write (md->html, md->stream, - "<object classid=\"%s\" type=\"%s\"></object>", - get_cid (part, md), mime_type); - return TRUE; -} - -char * -mail_get_message_body (CamelDataWrapper *data, gboolean want_plain, gboolean *is_html) -{ - CamelMultipart *mp; - CamelMimePart *subpart; - int i, nparts; - char *subtext, *old; - const char *boundary; - char *text = NULL; - GMimeContentField *mime_type; - - /* We only include text, message, and multipart bodies. */ - mime_type = camel_data_wrapper_get_mime_type_field (data); - - /* FIXME: This is wrong. We don't want to include large - * images. But if we don't do it this way, we don't get - * the headers... - */ - if (g_strcasecmp (mime_type->type, "message") == 0) { - *is_html = FALSE; - return get_data_wrapper_text (data); - } - - if (g_strcasecmp (mime_type->type, "text") == 0) { - *is_html = !g_strcasecmp (mime_type->subtype, "html"); - return get_data_wrapper_text (data); - } - - /* If it's not message and it's not text, and it's not - * multipart, we don't want to deal with it. - */ - if (g_strcasecmp (mime_type->type, "multipart") != 0) - return NULL; - - mp = CAMEL_MULTIPART (data); - - if (g_strcasecmp (mime_type->subtype, "alternative") == 0) { - /* Pick our favorite alternative and reply to it. */ - - subpart = find_preferred_alternative (mp, want_plain); - if (!subpart) - return NULL; - - data = camel_medium_get_content_object ( - CAMEL_MEDIUM (subpart)); - return mail_get_message_body (data, want_plain, is_html); - } - - nparts = camel_multipart_get_number (mp); - - /* Otherwise, concatenate all the parts that we can. If we find - * an HTML part in there though, return just that: We don't want - * to deal with merging HTML and non-HTML parts. - */ - boundary = camel_multipart_get_boundary (mp); - for (i = 0; i < nparts; i++) { - subpart = camel_multipart_get_part (mp, i); - - if (!mail_part_is_inline (subpart)) - continue; - - data = camel_medium_get_content_object ( - CAMEL_MEDIUM (subpart)); - subtext = mail_get_message_body (data, want_plain, is_html); - if (!subtext) - continue; - if (*is_html) { - g_free (text); - return subtext; - } - - if (text) { - old = text; - text = g_strdup_printf ("%s\n--%s\n%s", old, - boundary, subtext); - g_free (subtext); - g_free (old); - } else - text = subtext; - } - - return text; -} - -static void -free_recipients (GList *list) -{ - GList *l; - - for (l = list; l; l = l->next) - g_free (l->data); - g_list_free (list); -} - -EMsgComposer * -mail_generate_reply (CamelMimeMessage *message, gboolean to_all) -{ - CamelDataWrapper *contents; - char *text, *subject, *recipient; - EMsgComposer *composer; - gboolean want_plain, is_html; - const char *repl_to, *message_id, *references; - GList *to, *cc; - MailConfigIdentity *id; - gchar *sig_file = NULL; - - id = mail_config_get_default_identity (); - if (id) - sig_file = id->sig; - - composer = e_msg_composer_new_with_sig_file (sig_file); - if (!composer) - return NULL; - - want_plain = !mail_config_send_html (); - contents = camel_medium_get_content_object (CAMEL_MEDIUM (message)); - text = mail_get_message_body (contents, want_plain, &is_html); - - /* Set the quoted reply text. */ - if (text) { - char *repl_text; - - if (is_html) { - repl_text = g_strdup_printf ("<blockquote><i>\n%s\n" - "</i></blockquote>\n", - text); - } else { - char *s, *d, *quoted_text; - int lines, len; - - /* Count the number of lines in the body. If - * the text ends with a \n, this will be one - * too high, but that's ok. Allocate enough - * space for the text and the "> "s. - */ - for (s = text, lines = 0; s; s = strchr (s + 1, '\n')) - lines++; - quoted_text = g_malloc (strlen (text) + lines * 2); - - s = text; - d = quoted_text; - - /* Copy text to quoted_text line by line, - * prepending "> ". - */ - while (1) { - len = strcspn (s, "\n"); - if (len == 0 && !*s) - break; - sprintf (d, "> %.*s\n", len, s); - s += len; - if (!*s++) - break; - d += len + 3; - } - *d = '\0'; - - /* Now convert that to HTML. */ - repl_text = e_text_to_html (quoted_text, E_TEXT_TO_HTML_PRE); - g_free (quoted_text); - } - - e_msg_composer_set_body_text (composer, repl_text); - g_free (repl_text); - g_free (text); - } - - /* Set the recipients */ - repl_to = camel_mime_message_get_reply_to (message); - if (!repl_to) - repl_to = camel_mime_message_get_from (message); - - recipient = header_decode_string (repl_to ? repl_to : ""); - to = g_list_append (NULL, (gpointer)recipient); - - if (to_all) { - const CamelInternetAddress *recip; - const char *name, *addr; - char *fulladdr; - int i; - - recip = camel_mime_message_get_recipients (message, - CAMEL_RECIPIENT_TYPE_TO); - i = 0; - cc = NULL; - while (camel_internet_address_get (recip, i++, &name, &addr)) { - if (name && *name) { - char *dname = header_decode_string (name); - - if (dname && *dname) - fulladdr = g_strdup_printf ("\"%s\" <%s>", dname, addr); - else - fulladdr = g_strdup (addr); - - g_free (dname); - } else - fulladdr = g_strdup (addr); - - /* Here I'll check to see if the cc:'d address is the address - of the sender, and if so, don't add it to the cc: list; this - is to fix Bugzilla bug #455. */ - - if (strcmp (addr, id->address) != 0) - cc = g_list_append (cc, fulladdr); - } - - recip = camel_mime_message_get_recipients (message, CAMEL_RECIPIENT_TYPE_CC); - i = 0; - while (camel_internet_address_get (recip, i++, &name, &addr)) { - if (name && *name) { - char *dname = header_decode_string (name); - - if (dname && *dname) - fulladdr = g_strdup_printf ("\"%s\" <%s>", dname, addr); - else - fulladdr = g_strdup (addr); - - g_free (dname); - } else - fulladdr = g_strdup (addr); - - if (strcmp (addr, id->address) != 0) - cc = g_list_append (cc, fulladdr); - } - } else - cc = NULL; - - /* Set the subject of the new message. */ - subject = (char *)camel_mime_message_get_subject (message); - if (!subject) - subject = g_strdup (""); - else { - if (!g_strncasecmp (subject, "Re: ", 4)) - subject = g_strdup (subject); - else - subject = g_strdup_printf ("Re: %s", subject); - } - - e_msg_composer_set_headers (composer, to, cc, NULL, subject); - free_recipients (to); - free_recipients (cc); - g_free (subject); - - /* Add In-Reply-To and References. */ - message_id = camel_medium_get_header (CAMEL_MEDIUM (message), - "Message-Id"); - references = camel_medium_get_header (CAMEL_MEDIUM (message), - "References"); - if (message_id) { - e_msg_composer_add_header (composer, "In-Reply-To", - message_id); - if (references) { - char *reply_refs; - reply_refs = g_strdup_printf ("%s %s", references, - message_id); - e_msg_composer_add_header (composer, "References", - reply_refs); - g_free (reply_refs); - } - } else if (references) { - e_msg_composer_add_header (composer, "References", references); - } - - return composer; -} diff --git a/mail/mail-identify.c b/mail/mail-identify.c deleted file mode 100644 index 3f86ea361c..0000000000 --- a/mail/mail-identify.c +++ /dev/null @@ -1,89 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Dan Winship <danw@helixcode.com> - * - * Copyright 2000, Helix Code, Inc. (http://www.helixcode.com) - * - * 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 - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA. - * - */ - -#include <config.h> - -#include <stdlib.h> -#include <string.h> - -#include <glib.h> -#include <libgnomevfs/gnome-vfs-mime.h> -#include <libgnomevfs/gnome-vfs-mime-sniff-buffer.h> -#include "mail.h" - -/** - * mail_identify_mime_part: - * @part: a CamelMimePart - * - * Try to identify the MIME type of the data in @part (which presumably - * doesn't have a useful Content-Type). - **/ -char * -mail_identify_mime_part (CamelMimePart *part) -{ - const char *filename, *type; - GnomeVFSMimeSniffBuffer *sniffer; - CamelStream *memstream; - CamelDataWrapper *data; - GByteArray *ba; - - /* Try identifying based on name in Content-Type or - * filename in Content-Disposition. - */ - filename = camel_mime_part_get_filename (part); - if (filename) { - type = gnome_vfs_mime_type_from_name_or_default (filename, - NULL); - if (type) - return g_strdup (type); - } - - - /* Try file magic. */ - data = camel_medium_get_content_object (CAMEL_MEDIUM (part)); - ba = g_byte_array_new (); - memstream = camel_stream_mem_new_with_byte_array (ba); - camel_data_wrapper_write_to_stream (data, memstream); - if (ba->len) { - sniffer = gnome_vfs_mime_sniff_buffer_new_from_memory ( - ba->data, ba->len); - type = gnome_vfs_get_mime_type_for_buffer (sniffer); - gnome_vfs_mime_sniff_buffer_free (sniffer); - } else - type = NULL; - camel_object_unref (CAMEL_OBJECT (memstream)); - - if (type) - return g_strdup (type); - - - /* Another possibility to try is the x-mac-type / x-mac-creator - * parameter to Content-Type used by some Mac email clients. That - * would require a Mac type to mime type conversion table. - */ - - - /* We give up. */ - return NULL; -} diff --git a/mail/mail-local-storage.c b/mail/mail-local-storage.c deleted file mode 100644 index ea343c41b0..0000000000 --- a/mail/mail-local-storage.c +++ /dev/null @@ -1,188 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* mail-local-storage.h - * - * Copyright (C) 2000 Helix Code, Inc. - * - * 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 the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: Ettore Perazzoli - */ - -/* This handles the interfacing with the shell's local storage. */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <glib.h> -#include <gtk/gtk.h> -#include <orb/orbit.h> - -#include "e-folder-tree.h" -#include "evolution-storage-listener.h" - -#include "mail-local-storage.h" - - -/* Static stuff. Sigh, it sucks, but it fits in the way the whole mail - compnent is written. */ - -/* The interface to the local storage. */ -static Evolution_LocalStorage corba_local_storage = CORBA_OBJECT_NIL; - -/* The listener on our side. We get notified of things happening in the local - storage through this. */ -static EvolutionStorageListener *local_storage_listener = NULL; - -/* The folder set. The folder data is an Evolution_Folder, allocated through - CORBA normally. */ -static EFolderTree *folder_tree = NULL; - - -/* Folder destroy notification function for the `folder_tree'. */ - -static void -folder_tree_folder_notify_cb (EFolderTree *tree, - const char *path, - void *data, - void *closure) -{ - Evolution_Folder *corba_folder; - - corba_folder = (Evolution_Folder *) data; - CORBA_free (corba_folder); -} - - -/* Callbacks for the EvolutionStorageListner signals. */ - -static void -local_storage_destroyed_cb (EvolutionStorageListener *storage_listener, - void *data) -{ - /* FIXME: Dunno how to handle this yet. */ - g_warning ("%s -- The LocalStorage has gone?!", __FILE__); -} - -static void -local_storage_new_folder_cb (EvolutionStorageListener *storage_listener, - const char *path, - const Evolution_Folder *folder, - void *data) -{ - Evolution_Folder *copy_of_folder; - CORBA_Environment ev; - - if (strcmp (folder->type, "mail") != 0) - return; - - CORBA_exception_init (&ev); - -#if 0 - /* This is how we could do to display extra information about the - folder. */ - display_name = g_strconcat (folder->display_name, _(" (XXX unread)"), NULL); - Evolution_LocalStorage_set_display_name (corba_local_storage, path, display_name, &ev); -#endif - - copy_of_folder = Evolution_Folder__alloc (); - copy_of_folder->type = CORBA_string_dup (folder->type); - copy_of_folder->description = CORBA_string_dup (folder->description); - copy_of_folder->display_name = CORBA_string_dup (folder->display_name); - copy_of_folder->physical_uri = CORBA_string_dup (folder->physical_uri); - - e_folder_tree_add (folder_tree, path, copy_of_folder); - - CORBA_exception_free (&ev); -} - -static void -local_storage_removed_folder_cb (EvolutionStorageListener *storage_listener, - const char *path, - void *data) -{ - /* Prevent a warning from `e_folder_tree_remove()'. */ - if (e_folder_tree_get_folder (folder_tree, path) == NULL) - return; - - e_folder_tree_remove (folder_tree, path); -} - - -gboolean -mail_local_storage_startup (EvolutionShellClient *shell_client) -{ - Evolution_StorageListener corba_local_storage_listener; - - CORBA_Environment ev; - - CORBA_exception_init (&ev); - - corba_local_storage = evolution_shell_client_get_local_storage (shell_client); - if (corba_local_storage == CORBA_OBJECT_NIL) { - CORBA_exception_free (&ev); - return FALSE; - } - - local_storage_listener = evolution_storage_listener_new (); - corba_local_storage_listener = evolution_storage_listener_corba_objref (local_storage_listener); - - gtk_signal_connect (GTK_OBJECT (local_storage_listener), "destroyed", - GTK_SIGNAL_FUNC (local_storage_destroyed_cb), NULL); - gtk_signal_connect (GTK_OBJECT (local_storage_listener), "new_folder", - GTK_SIGNAL_FUNC (local_storage_new_folder_cb), NULL); - gtk_signal_connect (GTK_OBJECT (local_storage_listener), "removed_folder", - GTK_SIGNAL_FUNC (local_storage_removed_folder_cb), NULL); - - folder_tree = e_folder_tree_new (folder_tree_folder_notify_cb, NULL); - - Evolution_Storage_add_listener (corba_local_storage, corba_local_storage_listener, &ev); - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("%s -- Cannot add a listener to the Local Storage.", __FILE__); - - gtk_object_unref (GTK_OBJECT (local_storage_listener)); - - Bonobo_Unknown_unref (corba_local_storage, &ev); - CORBA_Object_release (corba_local_storage, &ev); - - CORBA_exception_free (&ev); - return FALSE; - } - - CORBA_exception_free (&ev); - - return TRUE; -} - -void -mail_local_storage_shutdown (void) -{ - CORBA_Environment ev; - - CORBA_exception_init (&ev); - - Bonobo_Unknown_unref (corba_local_storage, &ev); - CORBA_Object_release (corba_local_storage, &ev); - corba_local_storage = CORBA_OBJECT_NIL; - - gtk_object_unref (GTK_OBJECT (local_storage_listener)); - local_storage_listener = NULL; - - gtk_object_unref (GTK_OBJECT (folder_tree)); - folder_tree = NULL; - - CORBA_exception_free (&ev); -} diff --git a/mail/mail-local-storage.h b/mail/mail-local-storage.h deleted file mode 100644 index 251897681c..0000000000 --- a/mail/mail-local-storage.h +++ /dev/null @@ -1,34 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* mail-local-storage.h - * - * Copyright (C) 2000 Helix Code, Inc. - * - * 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 the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: Ettore Perazzoli - */ - -#ifndef _MAIL_LOCAL_STORAGE_H_ -#define _MAIL_LOCAL_STORAGE_H_ - -#include <glib.h> - -#include "evolution-shell-client.h" - -gboolean mail_local_storage_startup (EvolutionShellClient *shell_client); -void mail_local_storage_shutdown (void); - -#endif diff --git a/mail/mail-local.c b/mail/mail-local.c deleted file mode 100644 index 82f0ef3e18..0000000000 --- a/mail/mail-local.c +++ /dev/null @@ -1,519 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* mail-local.c: Local mailbox support. */ - -/* - * Author: - * Michael Zucchi <NotZed@helixcode.com> - * Peter Williams <peterw@helixcode.com> - * - * Copyright 2000 Helix Code, Inc. (http://www.helixcode.com) - * - * 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 the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - - -/* - code for handling local mail boxes -*/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <bonobo.h> -#include <libgnomeui/gnome-dialog.h> -#include <glade/glade.h> -#include <gnome-xml/xmlmemory.h> - -#include "Evolution.h" -#include "evolution-storage.h" - -#include "evolution-shell-component.h" -#include "folder-browser.h" - -#include "camel/camel.h" - -#include "filter/vfolder-context.h" -#include "filter/vfolder-rule.h" -#include "filter/vfolder-editor.h" - -#include "mail.h" -#include "mail-local.h" -#include "mail-tools.h" -#include "mail-threads.h" - -#define d(x) - -struct _local_meta { - char *path; /* path of metainfo file */ - - char *format; /* format of mailbox */ - char *name; /* name of mbox itself */ - int indexed; /* do we index the body? */ -}; - -static struct _local_meta * -load_metainfo(const char *path) -{ - xmlDocPtr doc; - xmlNodePtr node; - struct _local_meta *meta; - - meta = g_malloc0(sizeof(*meta)); - meta->path = g_strdup(path); - - printf("Loading folder metainfo from : %s\n", meta->path); - - doc = xmlParseFile(meta->path); - if (doc == NULL) { - goto dodefault; - } - node = doc->root; - if (strcmp(node->name, "folderinfo")) { - goto dodefault; - } - node = node->childs; - while (node) { - if (!strcmp(node->name, "folder")) { - char *index; - meta->format = xmlGetProp(node, "type"); - meta->name = xmlGetProp(node, "name"); - index = xmlGetProp(node, "index"); - if (index) { - meta->indexed = atoi(index); - xmlFree(index); - } else - meta->indexed = TRUE; - - } - node = node->next; - } - xmlFreeDoc(doc); - return meta; - -dodefault: - meta->format = g_strdup("mbox"); /* defaults */ - meta->name = g_strdup("mbox"); - meta->indexed = TRUE; - if (doc) - xmlFreeDoc(doc); - return meta; -} - -static void -free_metainfo(struct _local_meta *meta) -{ - g_free(meta->path); - g_free(meta->format); - g_free(meta->name); - g_free(meta); -} - -static int -save_metainfo(struct _local_meta *meta) -{ - xmlDocPtr doc; - xmlNodePtr root, node; - int ret; - - printf("Saving folder metainfo to : %s\n", meta->path); - - doc = xmlNewDoc("1.0"); - root = xmlNewDocNode(doc, NULL, "folderinfo", NULL); - xmlDocSetRootElement(doc, root); - - node = xmlNewChild(root, NULL, "folder", NULL); - xmlSetProp(node, "type", meta->format); - xmlSetProp(node, "name", meta->name); - xmlSetProp(node, "index", meta->indexed?"1":"0"); - - ret = xmlSaveFile(meta->path, doc); - xmlFreeDoc(doc); - return ret; -} - -/* maps a local uri to the real type */ -char * -mail_local_map_uri(const char *uri, int *index) -{ - CamelURL *url; - char *metapath; - char *storename; - struct _local_meta *meta; - CamelException *ex; - - if (index) - *index = TRUE; - - if (strncmp(uri, "file:", 5)) { - g_warning("Trying to map non-local uri: %s", uri); - return g_strdup(uri); - } - - ex = camel_exception_new(); - url = camel_url_new(uri, ex); - if (camel_exception_is_set(ex)) { - camel_exception_free(ex); - return g_strdup(uri); - } - camel_exception_free(ex); - - metapath = g_strdup_printf("%s/local-metadata.xml", url->path); - meta = load_metainfo(metapath); - g_free(metapath); - - if (index) - *index = meta->indexed; - - /* change file: to format: */ - camel_url_set_protocol(url, meta->format); - storename = camel_url_to_string (url, FALSE); - camel_url_free(url); - - return storename; -} - -CamelFolder * -mail_tool_local_uri_to_folder(const char *uri, CamelException *ex) -{ - CamelURL *url; - char *metapath; - char *storename; - CamelFolder *folder = NULL; - struct _local_meta *meta; - int flags; - - if (strncmp(uri, "file:", 5)) { - return NULL; - } - - printf("opening local folder %s\n", uri); - - /* get the actual location of the mailbox */ - url = camel_url_new(uri, ex); - if (camel_exception_is_set(ex)) { - return NULL; - } - - metapath = g_strdup_printf("%s/local-metadata.xml", url->path); - meta = load_metainfo(metapath); - g_free(metapath); - - /* change file: to format: */ - camel_url_set_protocol(url, meta->format); - storename = camel_url_to_string (url, FALSE); - - printf("store name is %s\n", storename); - flags = 0; - if (meta->indexed) - flags |= CAMEL_STORE_FOLDER_BODY_INDEX; - - folder = mail_tool_get_folder_from_urlname (storename, meta->name, flags, ex); - camel_url_free(url); - g_free (storename); - free_metainfo(meta); - - return folder; -} - -/* - open new - copy old->new - close old - rename old oldsave - rename new old - open oldsave - delete oldsave - - close old - rename oldtmp - open new - open oldtmp - copy oldtmp new - close oldtmp - close oldnew - -*/ - -static void update_progress(char *fmt, float percent) -{ - if (fmt) - mail_op_set_message ("%s", fmt); - /*mail_op_set_percentage (percent);*/ -} - -/* ******************** */ - -typedef struct reconfigure_folder_input_s { - FolderBrowser *fb; - gchar *newtype; - GtkWidget *frame; - GtkWidget *apply; - GtkWidget *cancel; - GtkOptionMenu *optionlist; -} reconfigure_folder_input_t; - -static gchar *describe_reconfigure_folder (gpointer in_data, gboolean gerund); -static void setup_reconfigure_folder (gpointer in_data, gpointer op_data, CamelException *ex); -static void do_reconfigure_folder (gpointer in_data, gpointer op_data, CamelException *ex); -static void cleanup_reconfigure_folder (gpointer in_data, gpointer op_data, CamelException *ex); - -static gchar * -describe_reconfigure_folder (gpointer in_data, gboolean gerund) -{ - reconfigure_folder_input_t *input = (reconfigure_folder_input_t *) in_data; - - if (gerund) - return g_strdup_printf (_("Changing folder \"%s\" to \"%s\" format"), - input->fb->uri, - input->newtype); - else - return g_strdup_printf (_("Change folder \"%s\" to \"%s\" format"), - input->fb->uri, - input->newtype); -} - -static void -setup_reconfigure_folder (gpointer in_data, gpointer op_data, CamelException *ex) -{ - reconfigure_folder_input_t *input = (reconfigure_folder_input_t *) in_data; - - gtk_object_ref (GTK_OBJECT (input->fb)); -} - -static void -do_reconfigure_folder(gpointer in_data, gpointer op_data, CamelException *ex) -{ - reconfigure_folder_input_t *input = (reconfigure_folder_input_t *) in_data; - - CamelStore *fromstore = NULL, *tostore = NULL; - char *fromurl = NULL, *tourl = NULL; - CamelFolder *fromfolder = NULL, *tofolder = NULL; - - char *metapath; - char *tmpname; - char *uri; - CamelURL *url = NULL; - struct _local_meta *meta; - guint32 flags; - - printf("reconfiguring folder: %s to type %s\n", input->fb->uri, input->newtype); - - /* get the actual location of the mailbox */ - url = camel_url_new(input->fb->uri, ex); - if (camel_exception_is_set(ex)) { - g_warning("%s is not a workable url!", input->fb->uri); - goto cleanup; - } - - metapath = g_strdup_printf("%s/local-metadata.xml", url->path); - meta = load_metainfo(metapath); - g_free(metapath); - - /* first, 'close' the old folder */ - if (input->fb->folder != NULL) { - update_progress(_("Closing current folder"), 0.0); - - mail_tool_camel_lock_up (); - camel_folder_sync(input->fb->folder, FALSE, ex); - mail_tool_camel_lock_down (); - camel_object_unref (CAMEL_OBJECT (input->fb->folder)); - input->fb->folder = NULL; - } - - camel_url_set_protocol (url, meta->format); - fromurl = camel_url_to_string (url, FALSE); - camel_url_set_protocol (url, input->newtype); - tourl = camel_url_to_string (url, FALSE); - - printf("opening stores %s and %s\n", fromurl, tourl); - - mail_tool_camel_lock_up (); - fromstore = camel_session_get_store(session, fromurl, ex); - mail_tool_camel_lock_down (); - - if (camel_exception_is_set(ex)) - goto cleanup; - - mail_tool_camel_lock_up (); - tostore = camel_session_get_store(session, tourl, ex); - mail_tool_camel_lock_down (); - if (camel_exception_is_set(ex)) - goto cleanup; - - /* rename the old mbox and open it again, without indexing */ - tmpname = g_strdup_printf("%s_reconfig", meta->name); - printf("renaming %s to %s, and opening it\n", meta->name, tmpname); - update_progress(_("Renaming old folder and opening"), 0.0); - - mail_tool_camel_lock_up (); - camel_store_rename_folder(fromstore, meta->name, tmpname, ex); - if (camel_exception_is_set(ex)) { - mail_tool_camel_lock_down (); - goto cleanup; - } - - /* we dont need to set the create flag ... or need an index if it has one */ - fromfolder = camel_store_get_folder(fromstore, tmpname, 0, ex); - if (fromfolder == NULL || camel_exception_is_set(ex)) { - /* try and recover ... */ - camel_exception_clear (ex); - camel_store_rename_folder(fromstore, tmpname, meta->name, ex); - mail_tool_camel_lock_down (); - goto cleanup; - } - - /* create a new mbox */ - printf("Creating the destination mbox\n"); - update_progress(_("Creating new folder"), 0.0); - - flags = CAMEL_STORE_FOLDER_CREATE; - if (meta->indexed) - flags |= CAMEL_STORE_FOLDER_BODY_INDEX; - tofolder = camel_store_get_folder(tostore, meta->name, flags, ex); - if (tofolder == NULL || camel_exception_is_set(ex)) { - printf("cannot open destination folder\n"); - /* try and recover ... */ - camel_exception_clear (ex); - camel_store_rename_folder(fromstore, tmpname, meta->name, ex); - mail_tool_camel_lock_down (); - goto cleanup; - } - - update_progress(_("Copying messages"), 0.0); - mail_tool_move_folder_contents (fromfolder, tofolder, FALSE, ex); - - printf("delete old mbox ...\n"); - camel_store_delete_folder(fromstore, tmpname, ex); - mail_tool_camel_lock_down (); - - /* switch format */ - g_free(meta->format); - meta->format = g_strdup(input->newtype); - if (save_metainfo(meta) == -1) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Cannot save folder metainfo; " - "you'll probably find you can't\n" - "open this folder anymore: %s"), - tourl); - } - free_metainfo(meta); - - /* force a reload of the newly formatted folder */ - printf("opening new source\n"); - uri = g_strdup(input->fb->uri); - folder_browser_set_uri(input->fb, uri); - g_free(uri); - - /* and unref our copy of the new folder ... */ - cleanup: - if (tofolder) - camel_object_unref (CAMEL_OBJECT (tofolder)); - if (fromfolder) - camel_object_unref (CAMEL_OBJECT (fromfolder)); - if (fromstore) - camel_object_unref (CAMEL_OBJECT (fromstore)); - if (tostore) - camel_object_unref (CAMEL_OBJECT (tostore)); - g_free(fromurl); - g_free(tourl); - if (url) - camel_url_free (url); -} - -static void -cleanup_reconfigure_folder (gpointer in_data, gpointer op_data, CamelException *ex) -{ - reconfigure_folder_input_t *input = (reconfigure_folder_input_t *) in_data; - - if (camel_exception_is_set(ex)) { - GtkWidget *win = gtk_widget_get_ancestor((GtkWidget *)input->frame, GTK_TYPE_WINDOW); - gnome_error_dialog_parented (_("If you can no longer open this mailbox, then\n" - "you may need to repair it manually."), GTK_WINDOW (win)); - } - - gtk_object_unref (GTK_OBJECT (input->fb)); - g_free (input->newtype); -} - -static const mail_operation_spec op_reconfigure_folder = -{ - describe_reconfigure_folder, - 0, - setup_reconfigure_folder, - do_reconfigure_folder, - cleanup_reconfigure_folder -}; - -static void -reconfigure_clicked(GnomeDialog *d, int button, reconfigure_folder_input_t *data) -{ - if (button == 0) { - GtkMenu *menu; - int type; - char *types[] = { "mh", "mbox" }; - - menu = (GtkMenu *)gtk_option_menu_get_menu(data->optionlist); - type = g_list_index(GTK_MENU_SHELL(menu)->children, gtk_menu_get_active(menu)); - if (type < 0 || type > 1) - type = 1; - - gtk_widget_set_sensitive(data->frame, FALSE); - gtk_widget_set_sensitive(data->apply, FALSE); - gtk_widget_set_sensitive(data->cancel, FALSE); - - data->newtype = g_strdup (types[type]); - mail_operation_queue (&op_reconfigure_folder, data, TRUE); - } - - if (button != -1) - gnome_dialog_close(d); -} - -void -local_reconfigure_folder(FolderBrowser *fb) -{ - CamelStore *store; - GladeXML *gui; - GnomeDialog *gd; - reconfigure_folder_input_t *data; - - if (fb->folder == NULL) { - g_warning("Trying to reconfigure nonexistant folder"); - return; - } - - data = g_new (reconfigure_folder_input_t, 1); - - store = camel_folder_get_parent_store(fb->folder); - - gui = glade_xml_new(EVOLUTION_GLADEDIR "/local-config.glade", "dialog_format"); - gd = (GnomeDialog *)glade_xml_get_widget (gui, "dialog_format"); - - data->frame = glade_xml_get_widget (gui, "frame_format"); - data->apply = glade_xml_get_widget (gui, "apply_format"); - data->cancel = glade_xml_get_widget (gui, "cancel_format"); - data->optionlist = (GtkOptionMenu *)glade_xml_get_widget (gui, "option_format"); - data->newtype = NULL; - data->fb = fb; - - gtk_label_set_text((GtkLabel *)glade_xml_get_widget (gui, "label_format"), - ((CamelService *)store)->url->protocol); - - gtk_signal_connect((GtkObject *)gd, "clicked", reconfigure_clicked, data); - gtk_object_unref((GtkObject *)gui); - - gnome_dialog_run_and_close (GNOME_DIALOG (gd)); -} diff --git a/mail/mail-local.h b/mail/mail-local.h deleted file mode 100644 index 7c0b619de4..0000000000 --- a/mail/mail-local.h +++ /dev/null @@ -1,37 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* mail-local.h: Local mailbox support. */ - -/* - * Author: - * Michael Zucchi <NotZed@helixcode.com> - * - * Copyright 2000 Helix Code, Inc. (http://www.helixcode.com) - * - * 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 the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#ifndef _MAIL_LOCAL_H -#define _MAIL_LOCAL_H - -#include "camel/camel-folder.h" -#include "folder-browser.h" - -/* mail-local.c */ -CamelFolder *mail_tool_local_uri_to_folder(const char *uri, CamelException *ex); -void local_reconfigure_folder(FolderBrowser *fb); -char *mail_local_map_uri(const char *uri, int *index); - -#endif diff --git a/mail/mail-mlist-magic.c b/mail/mail-mlist-magic.c deleted file mode 100644 index d02638572e..0000000000 --- a/mail/mail-mlist-magic.c +++ /dev/null @@ -1,262 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* mail-mlist-magic.c - * - * Copyright (C) 2000 Helix Code, Inc. - * - * 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 the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: Ettore Perazzoli - */ - -/* Procmail-style magic mail rules for mailing lists: (from Joakim's own - `.procmailrc'.) - - :0: - * ^Sender: owner-\/[^@]+ - lists/$MATCH - - :0: - * ^X-BeenThere: \/[^@]+ - lists/$MATCH - - :0: - * ^Delivered-To: mailing list \/[^@]+ - lists/$MATCH - - :0: - * X-Mailing-List: <\/[^@]+ - lists/$MATCH - - :0: - * X-Loop: \/[^@]+ - lists/$MATCH - -*/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <string.h> -#include <ctype.h> - -#include "camel.h" - -#include "mail-mlist-magic.h" - - -/* Utility functions. */ - -static char * -extract_until_at_sign (const char *s) -{ - const char *at_sign; - - at_sign = strchr (s, '@'); - if (at_sign == NULL) - return g_strdup (s); - - if (at_sign == s) - return NULL; - - return g_strndup (s, at_sign - s); -} - -static const char * -get_header (CamelMimeMessage *message, - const char *header_name) -{ - const char *value; - - value = camel_medium_get_header (CAMEL_MEDIUM (message), header_name); - if (value == NULL) - return NULL; - - /* FIXME: Correct? */ - while (isspace ((int) *value)) - value++; - - return value; -} - - -/* The checks. */ - -/* ^Sender: owner-\/[^@]+ */ -static char * -check_sender (CamelMimeMessage *message, - const char **header_name_return, - char **header_value_return) -{ - const char *value; - - value = get_header (message, "Sender"); - if (value == NULL) - return NULL; - - if (strncmp (value, "owner-", 6) != 0) - return NULL; - - if (value[6] == '\0' || value[6] == '@') - return NULL; - - if (header_name_return != NULL) - *header_name_return = "Sender"; - if (header_value_return != NULL) - *header_value_return = g_strdup (value); - return extract_until_at_sign (value + 6); -} - -/* ^X-BeenThere: \/[^@]+ */ -static char * -check_x_been_there (CamelMimeMessage *message, - const char **header_name_return, - char **header_value_return) -{ - const char *value; - - value = get_header (message, "X-BeenThere"); - if (value == NULL || *value == '@') - return NULL; - - if (header_name_return != NULL) - *header_name_return = "X-BeenThere"; - if (header_value_return != NULL) - *header_value_return = g_strdup (value); - - return extract_until_at_sign (value); -} - -/* ^Delivered-To: mailing list \/[^@]+ */ -static char * -check_delivered_to (CamelMimeMessage *message, - const char **header_name_return, - char **header_value_return) -{ - const char *value; - - value = get_header (message, "Delivered-To"); - if (value == NULL) - return NULL; - - /* FIXME uh? */ - if (strncmp (value, "mailing list ", 13) != 0) - return NULL; - - if (value[13] == '\0' || value[13] == '@') - return NULL; - - if (header_name_return != NULL) - *header_name_return = "Delivered-To"; - if (header_value_return != NULL) - *header_value_return = g_strdup (value); - return extract_until_at_sign (value + 13); -} - -/* X-Mailing-List: <\/[^@]+ */ -static char * -check_x_mailing_list (CamelMimeMessage *message, - const char **header_name_return, - char **header_value_return) -{ - const char *value; - int value_length; - - value = get_header (message, "X-Mailing-List"); - if (value == NULL) - return NULL; - - if (value[0] != '<' || value[1] == '\0' || value[1] == '@') - return NULL; - - value_length = strlen (value); - if (value[value_length - 1] != '>') - return NULL; - - if (header_name_return != NULL) - *header_name_return = "X-Mailing-List"; - if (header_value_return != NULL) - *header_value_return = g_strdup (value); - return extract_until_at_sign (value + 1); -} - -/* X-Loop: \/[^@]+ */ -static char * -check_x_loop (CamelMimeMessage *message, - const char **header_name_return, - char **header_value_return) -{ - const char *value; - - value = get_header (message, "X-Loop"); - if (value == NULL) - return NULL; - - if (*value == '\0' || *value == '@') - return NULL; - - if (header_name_return != NULL) - *header_name_return = "X-Loop"; - if (header_value_return != NULL) - *header_value_return = g_strdup (value); - - return extract_until_at_sign (value); -} - - -/** - * mail_mlist_magic_detect_list: - * @message: - * @header_name_return: - * @header_value_return: - * - * Detect if message was delivered by a mailing list. - * - * Return value: The name of the mailing list, if the message appears to be - * sent from a mailing list. NULL otherwise. - **/ -char * -mail_mlist_magic_detect_list (CamelMimeMessage *message, - const char **header_name_return, - char **header_value_return) -{ - char *list_name; - - g_return_val_if_fail (message != NULL, NULL); - g_return_val_if_fail (CAMEL_IS_MIME_MESSAGE (message), NULL); - - list_name = check_sender (message, header_name_return, header_value_return); - if (list_name != NULL) - return list_name; - - list_name = check_x_been_there (message, header_name_return, header_value_return); - if (list_name != NULL) - return list_name; - - list_name = check_delivered_to (message, header_name_return, header_value_return); - if (list_name != NULL) - return list_name; - - list_name = check_x_mailing_list (message, header_name_return, header_value_return); - if (list_name != NULL) - return list_name; - - list_name = check_x_loop (message, header_name_return, header_value_return); - if (list_name != NULL) - return list_name; - - return NULL; -} diff --git a/mail/mail-mlist-magic.h b/mail/mail-mlist-magic.h deleted file mode 100644 index dcfe3f4bfc..0000000000 --- a/mail/mail-mlist-magic.h +++ /dev/null @@ -1,33 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* mail-mlist-magic.h - * - * Copyright (C) 2000 Helix Code, Inc. - * - * 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 the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: Ettore Perazzoli - */ - -#ifndef MAIL_MLIST_MAGIC_H -#define MAIL_MLIST_MAGIC_H - -#include "camel.h" - -char *mail_mlist_magic_detect_list (CamelMimeMessage *message, - const char **header_name_return, - char **header_value_return); - -#endif diff --git a/mail/mail-ops.c b/mail/mail-ops.c deleted file mode 100644 index f94d065b16..0000000000 --- a/mail/mail-ops.c +++ /dev/null @@ -1,2313 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* mail-ops.c: callbacks for the mail toolbar/menus */ - -/* - * Author : - * Dan Winship <danw@helixcode.com> - * Jeffrey Stedfast <fejj@helixcode.com> - * Peter Williams <peterw@helixcode.com> - * - * Copyright 2000 Helix Code, Inc. (http://www.helixcode.com) - * - * 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 the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#include <config.h> -#include <gnome.h> -#include <ctype.h> -#include "mail.h" -#include "mail-threads.h" -#include "mail-tools.h" -#include "mail-ops.h" -#include "composer/e-msg-composer.h" -#include "folder-browser.h" - -/* ** FETCH MAIL ********************************************************** */ - -typedef struct fetch_mail_input_s -{ - gchar *source_url; - gboolean keep_on_server; - CamelFolder *destination; - gpointer hook_func; - gpointer hook_data; -} -fetch_mail_input_t; - -typedef struct fetch_mail_data_s { - gboolean empty; -} fetch_mail_data_t; - -static gchar * -describe_fetch_mail (gpointer in_data, gboolean gerund) -{ - fetch_mail_input_t *input = (fetch_mail_input_t *) in_data; - char *name; - - /*source = camel_session_get_store (session, input->source_url, NULL); - *if (source) { - * name = camel_service_get_name (CAMEL_SERVICE (source), FALSE); - * camel_object_unref (CAMEL_OBJECT (source)); - *} else - */ - name = input->source_url; - - if (gerund) - return g_strdup_printf (_("Fetching email from %s"), name); - else - return g_strdup_printf (_("Fetch email from %s"), name); -} - -static void -setup_fetch_mail (gpointer in_data, gpointer op_data, CamelException *ex) -{ - fetch_mail_input_t *input = (fetch_mail_input_t *) in_data; - fetch_mail_data_t *data = (fetch_mail_data_t *) op_data; - - data->empty = FALSE; - if (input->destination) - camel_object_ref (CAMEL_OBJECT (input->destination)); -} - -static FilterContext * -mail_load_evolution_rule_context () -{ - gchar *userrules; - gchar *systemrules; - FilterContext *fc; - - userrules = g_strdup_printf ("%s/filters.xml", evolution_dir); - systemrules = g_strdup_printf ("%s/evolution/filtertypes.xml", EVOLUTION_DATADIR); - fc = filter_context_new (); - rule_context_load ((RuleContext *)fc, systemrules, userrules); - g_free (userrules); - g_free (systemrules); - - return fc; -} - -static void -mail_op_report_status (FilterDriver *driver, enum filter_status_t status, const char *desc, void *data) -{ - /* FIXME: make it work */ - switch (status) { - case FILTER_STATUS_START: - mail_op_set_message (desc); - break; - case FILTER_STATUS_END: - break; - case FILTER_STATUS_ACTION: - break; - default: - break; - } -} - -static void -update_changed_folders (CamelStore *store, CamelFolderInfo *info, - EvolutionStorage *storage, const char *path, - CamelException *ex) -{ - CamelFolder *folder; - char *name, *display; - - name = g_strdup_printf ("%s/%s", path, info->name); - if (info->url) { - if (info->unread_message_count > 0) { - display = g_strdup_printf ("%s (%d)", info->name, - info->unread_message_count); - evolution_storage_update_folder (storage, name, - display, TRUE); - g_free (display); - } else { - evolution_storage_update_folder (storage, name, - info->name, FALSE); - } - - /* This is a bit of a hack... if the store is already - * caching the folder, then we update it. Otherwise - * we don't. - */ - folder = CAMEL_STORE_CLASS (CAMEL_OBJECT_GET_CLASS (store))-> - lookup_folder (store, info->full_name); - if (folder) { - camel_folder_sync (folder, FALSE, ex); - if (!camel_exception_is_set (ex)) - camel_folder_refresh_info (folder, ex); - camel_object_unref (CAMEL_OBJECT (folder)); - } - } - if (!camel_exception_is_set (ex) && info->sibling) { - update_changed_folders (store, info->sibling, storage, - path, ex); - } - if (!camel_exception_is_set (ex) && info->child) { - update_changed_folders (store, info->child, storage, - name, ex); - } - g_free (name); -} - -static void -do_fetch_mail (gpointer in_data, gpointer op_data, CamelException *ex) -{ - fetch_mail_input_t *input = (fetch_mail_input_t *) in_data; - fetch_mail_data_t *data = (fetch_mail_data_t *) op_data; - FilterContext *fc; - FilterDriver *filter; - FILE *logfile = NULL; - CamelFolder *folder; - - /* FIXME: This shouldn't be checking for "imap" specifically. */ - if (!strncmp (input->source_url, "imap:", 5)) { - CamelStore *store; - CamelFolderInfo *info; - EvolutionStorage *storage; - - store = camel_session_get_store (session, input->source_url, ex); - if (!store) - return; - storage = mail_lookup_storage (store); - g_return_if_fail (storage != NULL); - - info = camel_store_get_folder_info (store, NULL, FALSE, - TRUE, TRUE, ex); - if (!info) { - camel_object_unref (CAMEL_OBJECT (store)); - gtk_object_unref (GTK_OBJECT (storage)); - return; - } - - update_changed_folders (store, info, storage, "", ex); - camel_store_free_folder_info (store, info); - camel_object_unref (CAMEL_OBJECT (store)); - gtk_object_unref (GTK_OBJECT (storage)); - - data->empty = FALSE; - return; - } - - if (input->destination == NULL) { - input->destination = mail_tool_get_local_inbox (ex); - - if (input->destination == NULL) - return; - } - - /* setup filter driver */ - fc = mail_load_evolution_rule_context (); - filter = filter_driver_new (fc, mail_tool_filter_get_folder_func, 0); - filter_driver_set_default_folder (filter, input->destination); - - if (TRUE /* perform_logging */) { - char *filename = g_strdup_printf ("%s/evolution-filter-log", evolution_dir); - logfile = fopen (filename, "a+"); - g_free (filename); - } - - filter_driver_set_logfile (filter, logfile); - filter_driver_set_status_func (filter, mail_op_report_status, NULL); - - /* why on earth we 'up' a lock to get it, ... */ - mail_tool_camel_lock_up (); - - camel_folder_freeze (input->destination); - - if (!strncmp (input->source_url, "mbox:", 5)) { - char *path = mail_tool_do_movemail (input->source_url, ex); - - if (path && !camel_exception_is_set (ex)) { - filter_driver_filter_mbox (filter, path, FILTER_SOURCE_INCOMING, ex); - - /* ok? zap the output file */ - if (!camel_exception_is_set (ex)) { - unlink (path); - } - } - g_free (path); - } else { - folder = mail_tool_get_inbox (input->source_url, ex); - - if (folder) { - if (camel_folder_get_message_count (folder) > 0) { - CamelUIDCache *cache = NULL; - GPtrArray *uids; - - uids = camel_folder_get_uids (folder); - if (input->keep_on_server) { - char *cachename = mail_config_folder_to_cachename (folder, "cache-"); - - cache = camel_uid_cache_new (cachename); - if (cache) { - GPtrArray *new_uids; - - new_uids = camel_uid_cache_get_new_uids (cache, uids); - camel_folder_free_uids (folder, uids); - uids = new_uids; - } - - g_free (cachename); - } - - filter_driver_filter_folder (filter, folder, FILTER_SOURCE_INCOMING, - uids, !input->keep_on_server, ex); - - if (cache) { - /* save the cache for the next time we fetch mail! */ - camel_uid_cache_free_uids (uids); - - if (!camel_exception_is_set (ex)) - camel_uid_cache_save (cache); - camel_uid_cache_destroy (cache); - } else - camel_folder_free_uids (folder, uids); - } else { - data->empty = TRUE; - } - - /* sync and expunge */ - camel_folder_sync (folder, TRUE, ex); - - camel_object_unref (CAMEL_OBJECT (folder)); - } else { - data->empty = TRUE; - } - } - - if (logfile) - fclose (logfile); - - camel_folder_thaw (input->destination); - - mail_tool_camel_lock_down (); - - /*camel_object_unref (CAMEL_OBJECT (input->destination));*/ - gtk_object_unref (GTK_OBJECT (filter)); -} - -static void -cleanup_fetch_mail (gpointer in_data, gpointer op_data, CamelException *ex) -{ - fetch_mail_input_t *input = (fetch_mail_input_t *) in_data; - fetch_mail_data_t *data = (fetch_mail_data_t *) op_data; - - if (data->empty && !camel_exception_is_set (ex)) { - GtkWidget *dialog; - gchar *str; - - str = g_strdup_printf (_("There is no new mail at %s."), - input->source_url); - dialog = gnome_ok_dialog (str); - g_free (str); - gnome_dialog_run_and_close (GNOME_DIALOG (dialog)); - } - - g_free (input->source_url); - if (input->destination) - camel_object_unref (CAMEL_OBJECT (input->destination)); -} - -static const mail_operation_spec op_fetch_mail = { - describe_fetch_mail, - sizeof (fetch_mail_data_t), - setup_fetch_mail, - do_fetch_mail, - cleanup_fetch_mail -}; - -void -mail_do_fetch_mail (const gchar *source_url, gboolean keep_on_server, - CamelFolder *destination, - gpointer hook_func, gpointer hook_data) -{ - fetch_mail_input_t *input; - - g_return_if_fail (source_url != NULL); - g_return_if_fail (destination == NULL || - CAMEL_IS_FOLDER (destination)); - - input = g_new (fetch_mail_input_t, 1); - input->source_url = g_strdup (source_url); - input->keep_on_server = keep_on_server; - input->destination = destination; - input->hook_func = hook_func; - input->hook_data = hook_data; - - mail_operation_queue (&op_fetch_mail, input, TRUE); -} - -/* ** FILTER ON DEMAND ********************************************************** */ - -/* why do we have this separate code, it is basically a copy of the code above, - should be consolidated */ - -typedef struct filter_ondemand_input_s { - CamelFolder *source; - GPtrArray *uids; -} filter_ondemand_input_t; - -static gchar * -describe_filter_ondemand (gpointer in_data, gboolean gerund) -{ - if (gerund) - return g_strdup_printf (_("Filtering email on demand")); - else - return g_strdup_printf (_("Filter email on demand")); -} - -static void -setup_filter_ondemand (gpointer in_data, gpointer op_data, CamelException *ex) -{ - filter_ondemand_input_t *input = (filter_ondemand_input_t *) in_data; - - camel_object_ref (CAMEL_OBJECT (input->source)); -} - -static void -do_filter_ondemand (gpointer in_data, gpointer op_data, CamelException *ex) -{ - filter_ondemand_input_t *input = (filter_ondemand_input_t *) in_data; - FilterDriver *driver; - FilterContext *context; - FILE *logfile = NULL; - int i; - - mail_tool_camel_lock_up (); - if (camel_folder_get_message_count (input->source) == 0) { - mail_tool_camel_lock_down (); - return; - } - - /* create the filter context */ - context = mail_load_evolution_rule_context (); - - if (((RuleContext *)context)->error) { - gtk_object_unref (GTK_OBJECT (context)); - - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - "Cannot apply filters: failed to load filter rules."); - - mail_tool_camel_lock_down (); - return; - } - - /* setup filter driver - no default destination */ - driver = filter_driver_new (context, mail_tool_filter_get_folder_func, NULL); - - if (TRUE /* perform_logging */) { - char *filename; - - filename = g_strdup_printf ("%s/evolution-filter-log", evolution_dir); - logfile = fopen (filename, "a+"); - g_free (filename); - } - - filter_driver_set_logfile (driver, logfile); - filter_driver_set_status_func (driver, mail_op_report_status, NULL); - - for (i = 0; i < input->uids->len; i++) { - CamelMimeMessage *message; - CamelMessageInfo *info; - - message = camel_folder_get_message (input->source, input->uids->pdata[i], ex); - info = (CamelMessageInfo *) camel_folder_get_message_info (input->source, input->uids->pdata[i]); - - /* filter the message - use "incoming" rules since we don't want special "demand" filters? */ - filter_driver_filter_message (driver, message, info, "", FILTER_SOURCE_INCOMING, ex); - } - - if (logfile) - fclose (logfile); - - gtk_object_unref (GTK_OBJECT (driver)); - mail_tool_camel_lock_down (); -} - -static void -cleanup_filter_ondemand (gpointer in_data, gpointer op_data, CamelException *ex) -{ - filter_ondemand_input_t *input = (filter_ondemand_input_t *) in_data; - int i; - - if (input->source) - camel_object_unref (CAMEL_OBJECT (input->source)); - - for (i = 0; i < input->uids->len; i++) - g_free (input->uids->pdata[i]); - g_ptr_array_free (input->uids, TRUE); -} - -static const mail_operation_spec op_filter_ondemand = { - describe_filter_ondemand, - 0, - setup_filter_ondemand, - do_filter_ondemand, - cleanup_filter_ondemand -}; - -void -mail_do_filter_ondemand (CamelFolder *source, GPtrArray *uids) -{ - filter_ondemand_input_t *input; - - g_return_if_fail (source == NULL || CAMEL_IS_FOLDER (source)); - - input = g_new (filter_ondemand_input_t, 1); - input->source = source; - input->uids = uids; - - mail_operation_queue (&op_filter_ondemand, input, TRUE); -} - -/* ** SEND MAIL *********************************************************** */ - -typedef struct send_mail_input_s -{ - gchar *xport_uri; - CamelMimeMessage *message; - - /* If done_folder != NULL, will add done_flags to - * the flags of the message done_uid in done_folder. */ - - CamelFolder *done_folder; - char *done_uid; - guint32 done_flags; - - GtkWidget *composer; -} -send_mail_input_t; - -static gchar * -describe_send_mail (gpointer in_data, gboolean gerund) -{ - send_mail_input_t *input = (send_mail_input_t *) in_data; - - if (gerund) { - if (input->message->subject && input->message->subject[0]) - return g_strdup_printf (_("Sending \"%s\""), - input->message->subject); - else - return - g_strdup - (_("Sending a message without a subject")); - } else { - if (input->message->subject && input->message->subject[0]) - return g_strdup_printf (_("Send \"%s\""), - input->message->subject); - else - return g_strdup (_("Send a message without a subject")); - } -} - -static void -setup_send_mail (gpointer in_data, gpointer op_data, CamelException *ex) -{ - send_mail_input_t *input = (send_mail_input_t *) in_data; - - camel_object_ref (CAMEL_OBJECT (input->message)); - if (input->done_folder) - camel_object_ref (CAMEL_OBJECT (input->done_folder)); - if (input->composer) { - gtk_object_ref (GTK_OBJECT (input->composer)); - gtk_widget_hide (GTK_WIDGET (input->composer)); - } -} - -static void -do_send_mail (gpointer in_data, gpointer op_data, CamelException *ex) -{ - send_mail_input_t *input = (send_mail_input_t *) in_data; - extern CamelFolder *sent_folder; - CamelMessageInfo *info; - CamelTransport *xport; - FilterContext *context; - char *x_mailer; - - mail_tool_camel_lock_up (); - x_mailer = g_strdup_printf ("Evolution %s (Developer Preview)", VERSION); - camel_medium_add_header (CAMEL_MEDIUM (input->message), "X-Mailer", - x_mailer); - g_free (x_mailer); - camel_mime_message_set_date (input->message, - CAMEL_MESSAGE_DATE_CURRENT, 0); - - xport = camel_session_get_transport (session, input->xport_uri, ex); - mail_tool_camel_lock_down (); - if (camel_exception_is_set (ex)) - return; - - mail_tool_send_via_transport (xport, CAMEL_MEDIUM (input->message), ex); - camel_object_unref (CAMEL_OBJECT (xport)); - - if (camel_exception_is_set (ex)) - return; - - /* if we replied to a message, mark the appropriate flags and stuff */ - if (input->done_folder) { - guint32 set; - - mail_tool_camel_lock_up (); - set = camel_folder_get_message_flags (input->done_folder, - input->done_uid); - camel_folder_set_message_flags (input->done_folder, - input->done_uid, - input->done_flags, - input->done_flags); - mail_tool_camel_lock_down (); - } - - /* now lets run it through the outgoing filters */ - - info = g_new0 (CamelMessageInfo, 1); - info->flags = CAMEL_MESSAGE_SEEN; - - /* setup filter driver */ - context = mail_load_evolution_rule_context (); - - if (!((RuleContext *)context)->error) { - FilterDriver *driver; - FILE *logfile; - - driver = filter_driver_new (context, mail_tool_filter_get_folder_func, NULL); - - if (TRUE /* perform_logging */) { - char *filename; - - filename = g_strdup_printf ("%s/evolution-filter-log", evolution_dir); - logfile = fopen (filename, "a+"); - g_free (filename); - } - - filter_driver_filter_message (driver, input->message, info, "", FILTER_SOURCE_OUTGOING, ex); - - gtk_object_unref (GTK_OBJECT (driver)); - - if (logfile) - fclose (logfile); - } - - /* now to save the message in Sent */ - if (sent_folder) { - mail_tool_camel_lock_up (); - - camel_folder_append_message (sent_folder, input->message, info, ex); - g_free (info); - - mail_tool_camel_lock_down (); - } -} - -static void -cleanup_send_mail (gpointer in_data, gpointer op_data, CamelException *ex) -{ - send_mail_input_t *input = (send_mail_input_t *) in_data; - - camel_object_unref (CAMEL_OBJECT (input->message)); - if (input->done_folder) - camel_object_unref (CAMEL_OBJECT (input->done_folder)); - - g_free (input->xport_uri); - g_free (input->done_uid); - - if (input->composer) { - if (!camel_exception_is_set (ex)) - gtk_widget_destroy (input->composer); - else - gtk_widget_show (input->composer); - } -} - -static const mail_operation_spec op_send_mail = { - describe_send_mail, - 0, - setup_send_mail, - do_send_mail, - cleanup_send_mail -}; - -void -mail_do_send_mail (const char *xport_uri, - CamelMimeMessage *message, - CamelFolder *done_folder, - const char *done_uid, - guint32 done_flags, GtkWidget *composer) -{ - send_mail_input_t *input; - - g_return_if_fail (xport_uri != NULL); - g_return_if_fail (CAMEL_IS_MIME_MESSAGE (message)); - g_return_if_fail (done_folder == NULL || - CAMEL_IS_FOLDER (done_folder)); - g_return_if_fail (done_folder == NULL || done_uid != NULL); - - input = g_new (send_mail_input_t, 1); - input->xport_uri = g_strdup (xport_uri); - input->message = message; - input->done_folder = done_folder; - input->done_uid = g_strdup (done_uid); - input->done_flags = done_flags; - input->composer = composer; - - mail_operation_queue (&op_send_mail, input, TRUE); -} - -/* ** SEND MAIL QUEUE ***************************************************** */ - -typedef struct send_queue_input_s -{ - CamelFolder *folder_queue; - gchar *xport_uri; -} -send_queue_input_t; - -static gchar * -describe_send_queue (gpointer in_data, gboolean gerund) -{ - /*send_queue_input_t *input = (send_queue_input_t *) in_data;*/ - - if (gerund) { - return g_strdup_printf (_("Sending queue")); - } else { - return g_strdup_printf (_("Send queue")); - } -} - -static void -setup_send_queue (gpointer in_data, gpointer op_data, CamelException *ex) -{ - send_queue_input_t *input = (send_queue_input_t *) in_data; - - camel_object_ref (CAMEL_OBJECT (input->folder_queue)); -} - -static void -do_send_queue (gpointer in_data, gpointer op_data, CamelException *ex) -{ - send_queue_input_t *input = (send_queue_input_t *) in_data; - extern CamelFolder *sent_folder; - CamelTransport *xport; - GPtrArray *uids; - char *x_mailer; - guint32 set; - int i; - - uids = camel_folder_get_uids (input->folder_queue); - if (!uids) - return; - - x_mailer = g_strdup_printf ("Evolution %s (Developer Preview)", - VERSION); - - for (i = 0; i < uids->len; i++) { - CamelMimeMessage *message; - - mail_tool_camel_lock_up (); - - message = camel_folder_get_message (input->folder_queue, uids->pdata[i], ex); - if (camel_exception_is_set (ex)) - break; - - camel_medium_add_header (CAMEL_MEDIUM (message), "X-Mailer", x_mailer); - - camel_mime_message_set_date (message, CAMEL_MESSAGE_DATE_CURRENT, 0); - - xport = camel_session_get_transport (session, input->xport_uri, ex); - mail_tool_camel_lock_down (); - if (camel_exception_is_set (ex)) - break; - - mail_tool_send_via_transport (xport, CAMEL_MEDIUM (message), ex); - camel_object_unref (CAMEL_OBJECT (xport)); - - if (camel_exception_is_set (ex)) - break; - - mail_tool_camel_lock_up (); - set = camel_folder_get_message_flags (input->folder_queue, - uids->pdata[i]); - camel_folder_set_message_flags (input->folder_queue, - uids->pdata[i], - CAMEL_MESSAGE_DELETED, ~set); - mail_tool_camel_lock_down (); - - /* now to save the message in Sent */ - if (sent_folder) { - CamelMessageInfo *info; - - mail_tool_camel_lock_up (); - - info = g_new0 (CamelMessageInfo, 1); - info->flags = CAMEL_MESSAGE_SEEN; - camel_folder_append_message (sent_folder, message, info, ex); - g_free (info); - - mail_tool_camel_lock_down (); - } - } - - g_free (x_mailer); - - for (i = 0; i < uids->len; i++) - g_free (uids->pdata[i]); - g_ptr_array_free (uids, TRUE); -} - -static void -cleanup_send_queue (gpointer in_data, gpointer op_data, CamelException *ex) -{ - send_queue_input_t *input = (send_queue_input_t *) in_data; - - camel_object_unref (CAMEL_OBJECT (input->folder_queue)); - - g_free (input->xport_uri); -} - -static const mail_operation_spec op_send_queue = { - describe_send_queue, - 0, - setup_send_queue, - do_send_queue, - cleanup_send_queue -}; - -void -mail_do_send_queue (CamelFolder *folder_queue, - const char *xport_uri) -{ - send_queue_input_t *input; - - g_return_if_fail (xport_uri != NULL); - g_return_if_fail (CAMEL_IS_FOLDER (folder_queue)); - - input = g_new (send_queue_input_t, 1); - input->xport_uri = g_strdup (xport_uri); - input->folder_queue = folder_queue; - - mail_operation_queue (&op_send_queue, input, TRUE); -} - - -/* ** APPEND MESSAGE TO FOLDER ******************************************** */ - -typedef struct append_mail_input_s -{ - CamelFolder *folder; - CamelMimeMessage *message; - CamelMessageInfo *info; -} -append_mail_input_t; - -static gchar * -describe_append_mail (gpointer in_data, gboolean gerund) -{ - append_mail_input_t *input = (append_mail_input_t *) in_data; - - if (gerund) { - if (input->message->subject && input->message->subject[0]) - return g_strdup_printf (_("Appending \"%s\""), - input->message->subject); - else - return - g_strdup (_("Appending a message without a subject")); - } else { - if (input->message->subject && input->message->subject[0]) - return g_strdup_printf (_("Appending \"%s\""), - input->message->subject); - else - return g_strdup (_("Appending a message without a subject")); - } -} - -static void -setup_append_mail (gpointer in_data, gpointer op_data, CamelException *ex) -{ - append_mail_input_t *input = (append_mail_input_t *) in_data; - - camel_object_ref (CAMEL_OBJECT (input->message)); - camel_object_ref (CAMEL_OBJECT (input->folder)); -} - -static void -do_append_mail (gpointer in_data, gpointer op_data, CamelException *ex) -{ - append_mail_input_t *input = (append_mail_input_t *) in_data; - - camel_mime_message_set_date (input->message, - CAMEL_MESSAGE_DATE_CURRENT, 0); - - mail_tool_camel_lock_up (); - - /* now to save the message in the specified folder */ - camel_folder_append_message (input->folder, input->message, input->info, ex); - - mail_tool_camel_lock_down (); -} - -static void -cleanup_append_mail (gpointer in_data, gpointer op_data, CamelException *ex) -{ - append_mail_input_t *input = (append_mail_input_t *) in_data; - - camel_object_unref (CAMEL_OBJECT (input->message)); - camel_object_unref (CAMEL_OBJECT (input->folder)); -} - -static const mail_operation_spec op_append_mail = { - describe_append_mail, - 0, - setup_append_mail, - do_append_mail, - cleanup_append_mail -}; - -void -mail_do_append_mail (CamelFolder *folder, - CamelMimeMessage *message, - CamelMessageInfo *info) -{ - append_mail_input_t *input; - - g_return_if_fail (CAMEL_IS_FOLDER (folder)); - g_return_if_fail (CAMEL_IS_MIME_MESSAGE (message)); - - input = g_new (append_mail_input_t, 1); - input->folder = folder; - input->message = message; - input->info = info; - - mail_operation_queue (&op_append_mail, input, TRUE); -} - -/* ** EXPUNGE FOLDER ****************************************************** */ - -static gchar * -describe_expunge_folder (gpointer in_data, gboolean gerund) -{ - CamelFolder *f = CAMEL_FOLDER (in_data); - - if (gerund) - return g_strdup_printf (_("Expunging \"%s\""), mail_tool_get_folder_name (f)); - else - return g_strdup_printf (_("Expunge \"%s\""), mail_tool_get_folder_name (f)); -} - -static void -setup_expunge_folder (gpointer in_data, gpointer op_data, CamelException *ex) -{ - camel_object_ref (CAMEL_OBJECT (in_data)); -} - -static void -do_expunge_folder (gpointer in_data, gpointer op_data, CamelException *ex) -{ - mail_tool_camel_lock_up (); - camel_folder_expunge (CAMEL_FOLDER (in_data), ex); - mail_tool_camel_lock_down (); -} - -static void -cleanup_expunge_folder (gpointer in_data, gpointer op_data, - CamelException *ex) -{ - camel_object_unref (CAMEL_OBJECT (in_data)); -} - -static const mail_operation_spec op_expunge_folder = { - describe_expunge_folder, - 0, - setup_expunge_folder, - do_expunge_folder, - cleanup_expunge_folder -}; - -void -mail_do_expunge_folder (CamelFolder *folder) -{ - g_return_if_fail (CAMEL_IS_FOLDER (folder)); - - mail_operation_queue (&op_expunge_folder, folder, FALSE); -} - -/* ** TRANSFER MESSAGES **************************************************** */ - -typedef struct transfer_messages_input_s -{ - CamelFolder *source; - GPtrArray *uids; - gboolean delete_from_source; - gchar *dest_uri; -} -transfer_messages_input_t; - -static gchar * -describe_transfer_messages (gpointer in_data, gboolean gerund) -{ - transfer_messages_input_t *input = (transfer_messages_input_t *) in_data; - char *format; - - if (gerund) { - if (input->delete_from_source) - format = _("Moving messages from \"%s\" into \"%s\""); - else - format = _("Copying messages from \"%s\" into \"%s\""); - } else { - if (input->delete_from_source) - format = _("Move messages from \"%s\" into \"%s\""); - else - format = _("Copy messages from \"%s\" into \"%s\""); - } - - return g_strdup_printf (format, - mail_tool_get_folder_name (input->source), - input->dest_uri); -} - -static void -setup_transfer_messages (gpointer in_data, gpointer op_data, - CamelException *ex) -{ - transfer_messages_input_t *input = (transfer_messages_input_t *) in_data; - - camel_object_ref (CAMEL_OBJECT (input->source)); -} - -static void -do_transfer_messages (gpointer in_data, gpointer op_data, CamelException *ex) -{ - transfer_messages_input_t *input = (transfer_messages_input_t *) in_data; - CamelFolder *dest; - gint i; - time_t last_update = 0; - gchar *desc; - void (*func) (CamelFolder *, const char *, - CamelFolder *, - CamelException *); - - if (input->delete_from_source) { - func = camel_folder_move_message_to; - desc = _("Moving"); - } else { - func = camel_folder_copy_message_to; - desc = _("Copying"); - } - - dest = mail_tool_uri_to_folder (input->dest_uri, ex); - if (camel_exception_is_set (ex)) - return; - - mail_tool_camel_lock_up (); - camel_folder_freeze (input->source); - camel_folder_freeze (dest); - - for (i = 0; i < input->uids->len; i++) { - const gboolean last_message = (i+1 == input->uids->len); - time_t now; - - /* - * Update the time display ever 2 seconds - */ - time (&now); - if (last_message || ((now - last_update) > 2)){ - mail_op_set_message (_("%s message %d of %d (uid \"%s\")"), desc, - i + 1, input->uids->len, (char *) input->uids->pdata[i]); - last_update = now; - } - - (func) (input->source, - input->uids->pdata[i], dest, - ex); - g_free (input->uids->pdata[i]); - if (camel_exception_is_set (ex)) - break; - } - - camel_folder_thaw (input->source); - camel_folder_thaw (dest); - camel_object_unref (CAMEL_OBJECT (dest)); - mail_tool_camel_lock_down (); -} - -static void -cleanup_transfer_messages (gpointer in_data, gpointer op_data, - CamelException *ex) -{ - transfer_messages_input_t *input = (transfer_messages_input_t *) in_data; - - camel_object_unref (CAMEL_OBJECT (input->source)); - g_free (input->dest_uri); - g_ptr_array_free (input->uids, TRUE); -} - -static const mail_operation_spec op_transfer_messages = { - describe_transfer_messages, - 0, - setup_transfer_messages, - do_transfer_messages, - cleanup_transfer_messages -}; - -void -mail_do_transfer_messages (CamelFolder *source, GPtrArray *uids, - gboolean delete_from_source, - gchar *dest_uri) -{ - transfer_messages_input_t *input; - - g_return_if_fail (CAMEL_IS_FOLDER (source)); - g_return_if_fail (uids != NULL); - g_return_if_fail (dest_uri != NULL); - - input = g_new (transfer_messages_input_t, 1); - input->source = source; - input->uids = uids; - input->delete_from_source = delete_from_source; - input->dest_uri = g_strdup (dest_uri); - - mail_operation_queue (&op_transfer_messages, input, TRUE); -} - -/* ** FLAG MESSAGES ******************************************************* */ - -typedef struct flag_messages_input_s -{ - CamelFolder *source; - GPtrArray *uids; - gboolean invert; - guint32 mask; - guint32 set; - gboolean flag_all; -} -flag_messages_input_t; - -static gchar * -describe_flag_messages (gpointer in_data, gboolean gerund) -{ - flag_messages_input_t *input = (flag_messages_input_t *) in_data; - - /* FIXME: change based on flags being applied? */ - - if (gerund) - return g_strdup_printf (_("Marking messages in folder \"%s\""), - mail_tool_get_folder_name (input->source)); - else - return g_strdup_printf (_("Mark messages in folder \"%s\""), - mail_tool_get_folder_name (input->source)); -} - -static void -setup_flag_messages (gpointer in_data, gpointer op_data, CamelException *ex) -{ - flag_messages_input_t *input = (flag_messages_input_t *) in_data; - - camel_object_ref (CAMEL_OBJECT (input->source)); -} - -static void -do_flag_messages (gpointer in_data, gpointer op_data, CamelException *ex) -{ - flag_messages_input_t *input = (flag_messages_input_t *) in_data; - gint i; - time_t last_update = 0; - - mail_tool_camel_lock_up (); - camel_folder_freeze (input->source); - if (input->uids == NULL) - input->uids = camel_folder_get_uids (input->source); - mail_tool_camel_lock_down (); - - for (i = 0; i < input->uids->len; i++) { - const gboolean last_message = (i+1 == input->uids->len); - time_t now; - - time (&now); - if (last_message || ((now - last_update) > 2)){ - mail_op_set_message (_("Marking message %d of %d"), i + 1, - input->uids->len); - last_update = now; - } - - if (input->invert) { - const CamelMessageInfo *info; - - mail_tool_camel_lock_up (); - info = camel_folder_get_message_info (input->source, input->uids->pdata[i]); - camel_folder_set_message_flags (input->source, input->uids->pdata[i], - input->mask, ~info->flags); - mail_tool_camel_lock_down (); - } else { - mail_tool_set_uid_flags (input->source, input->uids->pdata[i], - input->mask, input->set); - } - - if (input->flag_all == FALSE) - g_free (input->uids->pdata[i]); - } - - mail_tool_camel_lock_up (); - if (input->flag_all) { - camel_folder_free_uids (input->source, input->uids); - input->uids = NULL; - } - camel_folder_thaw (input->source); - mail_tool_camel_lock_down (); -} - -static void -cleanup_flag_messages (gpointer in_data, gpointer op_data, - CamelException *ex) -{ - flag_messages_input_t *input = (flag_messages_input_t *) in_data; - - camel_object_unref (CAMEL_OBJECT (input->source)); - - if (input->uids) - g_ptr_array_free (input->uids, TRUE); -} - -static const mail_operation_spec op_flag_messages = { - describe_flag_messages, - 0, - setup_flag_messages, - do_flag_messages, - cleanup_flag_messages -}; - -void -mail_do_flag_messages (CamelFolder *source, GPtrArray *uids, - gboolean invert, - guint32 mask, guint32 set) -{ - flag_messages_input_t *input; - - g_return_if_fail (CAMEL_IS_FOLDER (source)); - g_return_if_fail (uids != NULL); - - input = g_new (flag_messages_input_t, 1); - input->source = source; - input->uids = uids; - input->invert = invert; - input->mask = mask; - input->set = set; - input->flag_all = FALSE; - - mail_operation_queue (&op_flag_messages, input, TRUE); -} - -void -mail_do_flag_all_messages (CamelFolder *source, gboolean invert, - guint32 mask, guint32 set) -{ - flag_messages_input_t *input; - - g_return_if_fail (CAMEL_IS_FOLDER (source)); - - input = g_new (flag_messages_input_t, 1); - input->source = source; - input->uids = NULL; - input->invert = invert; - input->mask = mask; - input->set = set; - input->flag_all = TRUE; - - mail_operation_queue (&op_flag_messages, input, TRUE); -} - -/* ** SCAN SUBFOLDERS ***************************************************** */ - -typedef struct scan_subfolders_input_s -{ - CamelStore *store; - EvolutionStorage *storage; -} -scan_subfolders_input_t; - -typedef struct scan_subfolders_folderinfo_s -{ - char *path; - char *name; - char *uri; - gboolean highlighted; -} -scan_subfolders_folderinfo_t; - -typedef struct scan_subfolders_op_s -{ - GPtrArray *new_folders; -} -scan_subfolders_op_t; - -static gchar * -describe_scan_subfolders (gpointer in_data, gboolean gerund) -{ - scan_subfolders_input_t *input = (scan_subfolders_input_t *) in_data; - char *name; - - name = camel_service_get_name (CAMEL_SERVICE (input->store), TRUE); - if (gerund) - return g_strdup_printf (_("Scanning folders in \"%s\""), name); - else - return g_strdup_printf (_("Scan folders in \"%s\""), name); - g_free (name); -} - -static void -setup_scan_subfolders (gpointer in_data, gpointer op_data, - CamelException *ex) -{ - scan_subfolders_input_t *input = (scan_subfolders_input_t *) in_data; - scan_subfolders_op_t *data = (scan_subfolders_op_t *) op_data; - - camel_object_ref (CAMEL_OBJECT (input->store)); - gtk_object_ref (GTK_OBJECT (input->storage)); - - data->new_folders = g_ptr_array_new (); -} - -static void -add_folders (GPtrArray *folders, const char *prefix, CamelFolderInfo *fi) -{ - scan_subfolders_folderinfo_t *info; - - info = g_new (scan_subfolders_folderinfo_t, 1); - info->path = g_strdup_printf ("%s/%s", prefix, fi->name); - if (fi->unread_message_count > 0) { - info->name = g_strdup_printf ("%s (%d)", fi->name, - fi->unread_message_count); - info->highlighted = TRUE; - } else { - info->name = g_strdup (fi->name); - info->highlighted = FALSE; - } - info->uri = g_strdup (fi->url); - g_ptr_array_add (folders, info); - if (fi->child) - add_folders (folders, info->path, fi->child); - if (fi->sibling) - add_folders (folders, prefix, fi->sibling); -} - -static void -do_scan_subfolders (gpointer in_data, gpointer op_data, CamelException *ex) -{ - scan_subfolders_input_t *input = (scan_subfolders_input_t *) in_data; - scan_subfolders_op_t *data = (scan_subfolders_op_t *) op_data; - CamelFolderInfo *tree; - - tree = camel_store_get_folder_info (input->store, NULL, FALSE, - TRUE, TRUE, ex); - if (tree) { - add_folders (data->new_folders, "", tree); - camel_store_free_folder_info (input->store, tree); - } -} - -static void -cleanup_scan_subfolders (gpointer in_data, gpointer op_data, - CamelException *ex) -{ - scan_subfolders_input_t *input = (scan_subfolders_input_t *) in_data; - scan_subfolders_op_t *data = (scan_subfolders_op_t *) op_data; - scan_subfolders_folderinfo_t *info; - int i; - - for (i = 0; i < data->new_folders->len; i++) { - info = data->new_folders->pdata[i]; - evolution_storage_new_folder (input->storage, info->path, - info->name, "mail", - info->uri ? info->uri : "", - _("(No description)"), - info->highlighted); - - g_free (info->uri); - g_free (info->name); - g_free (info->path); - g_free (info); - } - g_ptr_array_free (data->new_folders, TRUE); - - gtk_object_unref (GTK_OBJECT (input->storage)); - camel_object_unref (CAMEL_OBJECT (input->store)); -} - -static const mail_operation_spec op_scan_subfolders = { - describe_scan_subfolders, - sizeof (scan_subfolders_op_t), - setup_scan_subfolders, - do_scan_subfolders, - cleanup_scan_subfolders -}; - -void -mail_do_scan_subfolders (CamelStore *store, EvolutionStorage *storage) -{ - scan_subfolders_input_t *input; - - g_return_if_fail (CAMEL_IS_STORE (store)); - g_return_if_fail (EVOLUTION_IS_STORAGE (storage)); - - input = g_new (scan_subfolders_input_t, 1); - input->store = store; - input->storage = storage; - - mail_operation_queue (&op_scan_subfolders, input, TRUE); -} - -/* ** ATTACH MESSAGE ****************************************************** */ - -typedef struct attach_message_input_s -{ - EMsgComposer *composer; - CamelFolder *folder; - gchar *uid; -} -attach_message_input_t; - -typedef struct attach_message_data_s -{ - CamelMimePart *part; -} -attach_message_data_t; - -static gchar * -describe_attach_message (gpointer in_data, gboolean gerund) -{ - attach_message_input_t *input = (attach_message_input_t *) in_data; - - if (gerund) - return - g_strdup_printf - (_("Attaching messages from folder \"%s\""), - mail_tool_get_folder_name (input->folder)); - else - return g_strdup_printf (_("Attach messages from \"%s\""), - mail_tool_get_folder_name (input->folder)); -} - -static void -setup_attach_message (gpointer in_data, gpointer op_data, CamelException *ex) -{ - attach_message_input_t *input = (attach_message_input_t *) in_data; - - camel_object_ref (CAMEL_OBJECT (input->folder)); - gtk_object_ref (GTK_OBJECT (input->composer)); -} - -static void -do_attach_message (gpointer in_data, gpointer op_data, CamelException *ex) -{ - attach_message_input_t *input = (attach_message_input_t *) in_data; - attach_message_data_t *data = (attach_message_data_t *) op_data; - - CamelMimeMessage *message; - CamelMimePart *part; - - mail_tool_camel_lock_up (); - message = camel_folder_get_message (input->folder, input->uid, ex); - if (!message) { - mail_tool_camel_lock_down (); - return; - } - - part = mail_tool_make_message_attachment (message); - camel_object_unref (CAMEL_OBJECT (message)); - mail_tool_camel_lock_down (); - if (!part) - return; - - data->part = part; -} - -static void -cleanup_attach_message (gpointer in_data, gpointer op_data, - CamelException *ex) -{ - attach_message_input_t *input = (attach_message_input_t *) in_data; - attach_message_data_t *data = (attach_message_data_t *) op_data; - - e_msg_composer_attach (input->composer, data->part); - camel_object_unref (CAMEL_OBJECT (data->part)); - camel_object_unref (CAMEL_OBJECT (input->folder)); - gtk_object_unref (GTK_OBJECT (input->composer)); - g_free (input->uid); -} - -static const mail_operation_spec op_attach_message = { - describe_attach_message, - sizeof (attach_message_data_t), - setup_attach_message, - do_attach_message, - cleanup_attach_message -}; - -void -mail_do_attach_message (CamelFolder *folder, const char *uid, - EMsgComposer *composer) -{ - attach_message_input_t *input; - - g_return_if_fail (CAMEL_IS_FOLDER (folder)); - g_return_if_fail (uid != NULL); - g_return_if_fail (E_IS_MSG_COMPOSER (composer)); - - input = g_new (attach_message_input_t, 1); - input->folder = folder; - input->uid = g_strdup (uid); - input->composer = composer; - - mail_operation_queue (&op_attach_message, input, TRUE); -} - -/* ** FORWARD MESSAGES **************************************************** */ - -typedef struct forward_messages_input_s -{ - CamelMimeMessage *basis; - CamelFolder *source; - GPtrArray *uids; - EMsgComposer *composer; -} -forward_messages_input_t; - -typedef struct forward_messages_data_s -{ - gchar *subject; - GPtrArray *parts; -} -forward_messages_data_t; - -static gchar * -describe_forward_messages (gpointer in_data, gboolean gerund) -{ - forward_messages_input_t *input = (forward_messages_input_t *) in_data; - - if (gerund) { - if (input->basis->subject) - return g_strdup_printf (_("Forwarding messages \"%s\""), - input->basis->subject); - else - return - g_strdup_printf - (_("Forwarding a message without a subject")); - } else { - if (input->basis->subject) - return g_strdup_printf (_("Forward message \"%s\""), - input->basis->subject); - else - return - g_strdup_printf - (_("Forward a message without a subject")); - } -} - -static void -setup_forward_messages (gpointer in_data, gpointer op_data, - CamelException *ex) -{ - forward_messages_input_t *input = (forward_messages_input_t *) in_data; - - camel_object_ref (CAMEL_OBJECT (input->basis)); - camel_object_ref (CAMEL_OBJECT (input->source)); - gtk_object_ref (GTK_OBJECT (input->composer)); -} - -static void -do_forward_messages (gpointer in_data, gpointer op_data, CamelException *ex) -{ - forward_messages_input_t *input = (forward_messages_input_t *) in_data; - forward_messages_data_t *data = (forward_messages_data_t *) op_data; - time_t last_update = 0; - CamelMimeMessage *message; - CamelMimePart *part; - int i; - - data->parts = g_ptr_array_new (); - - mail_tool_camel_lock_up (); - for (i = 0; i < input->uids->len; i++) { - const int last_message = (i+1 == input->uids->len); - time_t now; - - /* - * Update the time display ever 2 seconds - */ - time (&now); - if (last_message || ((now - last_update) > 2)){ - mail_op_set_message (_("Retrieving message number %d of %d (uid \"%s\")"), - i + 1, input->uids->len, (char *) input->uids->pdata[i]); - last_update = now; - } - - - message = - camel_folder_get_message (input->source, - input->uids->pdata[i], ex); - g_free (input->uids->pdata[i]); - if (!message) { - mail_tool_camel_lock_down (); - return; - } - part = mail_tool_make_message_attachment (message); - if (!part) { - camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, - _("Failed to generate mime part from " - "message while generating forwarded message.")); - mail_tool_camel_lock_down (); - return; - } - camel_object_unref (CAMEL_OBJECT (message)); - g_ptr_array_add (data->parts, part); - } - - mail_tool_camel_lock_down (); - - data->subject = mail_tool_generate_forward_subject (input->basis); -} - -static void -cleanup_forward_messages (gpointer in_data, gpointer op_data, - CamelException *ex) -{ - forward_messages_input_t *input = - - (forward_messages_input_t *) in_data; - forward_messages_data_t *data = (forward_messages_data_t *) op_data; - - int i; - - for (i = 0; i < data->parts->len; i++) { - e_msg_composer_attach (input->composer, - data->parts->pdata[i]); - camel_object_unref (CAMEL_OBJECT (data->parts->pdata[i])); - } - camel_object_unref (CAMEL_OBJECT (input->source)); - - e_msg_composer_set_headers (input->composer, NULL, NULL, NULL, - data->subject); - - gtk_object_unref (GTK_OBJECT (input->composer)); - g_free (data->subject); - g_ptr_array_free (data->parts, TRUE); - g_ptr_array_free (input->uids, TRUE); - gtk_widget_show (GTK_WIDGET (input->composer)); -} - -static const mail_operation_spec op_forward_messages = { - describe_forward_messages, - sizeof (forward_messages_data_t), - setup_forward_messages, - do_forward_messages, - cleanup_forward_messages -}; - -void -mail_do_forward_message (CamelMimeMessage *basis, - CamelFolder *source, - GPtrArray *uids, EMsgComposer *composer) -{ - forward_messages_input_t *input; - - g_return_if_fail (CAMEL_IS_MIME_MESSAGE (basis)); - g_return_if_fail (CAMEL_IS_FOLDER (source)); - g_return_if_fail (uids != NULL); - g_return_if_fail (E_IS_MSG_COMPOSER (composer)); - - input = g_new (forward_messages_input_t, 1); - input->basis = basis; - input->source = source; - input->uids = uids; - input->composer = composer; - - mail_operation_queue (&op_forward_messages, input, TRUE); -} - -/* ** LOAD FOLDER ********************************************************* */ - -typedef struct load_folder_input_s -{ - FolderBrowser *fb; - gchar *url; -} -load_folder_input_t; - -static gchar * -describe_load_folder (gpointer in_data, gboolean gerund) -{ - load_folder_input_t *input = (load_folder_input_t *) in_data; - - if (gerund) { - return g_strdup_printf (_("Loading \"%s\""), input->url); - } else { - return g_strdup_printf (_("Load \"%s\""), input->url); - } -} - -static void -setup_load_folder (gpointer in_data, gpointer op_data, CamelException *ex) -{ - load_folder_input_t *input = (load_folder_input_t *) in_data; - - gtk_object_ref (GTK_OBJECT (input->fb)); - - if (input->fb->uri) - g_free (input->fb->uri); - - input->fb->uri = input->url; -} - -static void -do_load_folder (gpointer in_data, gpointer op_data, CamelException *ex) -{ - load_folder_input_t *input = (load_folder_input_t *) in_data; - - CamelFolder *folder; - - folder = mail_tool_uri_to_folder (input->url, ex); - if (!folder) - return; - - if (input->fb->folder) { - mail_tool_camel_lock_up (); - camel_object_unref (CAMEL_OBJECT (input->fb->folder)); - mail_tool_camel_lock_down (); - } - - input->fb->folder = folder; -} - -static void -cleanup_load_folder (gpointer in_data, gpointer op_data, CamelException *ex) -{ - load_folder_input_t *input = (load_folder_input_t *) in_data; - - if (input->fb->folder) { - gtk_widget_set_sensitive (GTK_WIDGET (input->fb->search_entry), - camel_folder_has_search_capability (input-> - fb-> - folder)); - gtk_widget_set_sensitive (GTK_WIDGET (input->fb->search_menu), - camel_folder_has_search_capability (input-> - fb-> - folder)); - message_list_set_folder (input->fb->message_list, input->fb->folder); - } - - /*g_free (input->url); = fb->uri now */ -} - -static const mail_operation_spec op_load_folder = { - describe_load_folder, - 0, - setup_load_folder, - do_load_folder, - cleanup_load_folder -}; - -void -mail_do_load_folder (FolderBrowser *fb, const char *url) -{ - load_folder_input_t *input; - - g_return_if_fail (IS_FOLDER_BROWSER (fb)); - g_return_if_fail (url != NULL); - - input = g_new (load_folder_input_t, 1); - input->fb = fb; - input->url = g_strdup (url); - - mail_operation_queue (&op_load_folder, input, TRUE); -} - -/* ** CREATE FOLDER ******************************************************* */ - -typedef struct create_folder_input_s -{ - Evolution_ShellComponentListener listener; - char *uri; - char *type; -} -create_folder_input_t; - -typedef struct create_folder_data_s -{ - Evolution_ShellComponentListener_Result result; -} -create_folder_data_t; - -static gchar * -describe_create_folder (gpointer in_data, gboolean gerund) -{ - create_folder_input_t *input = (create_folder_input_t *) in_data; - - if (gerund) { - return g_strdup_printf (_("Creating \"%s\""), input->uri); - } else { - return g_strdup_printf (_("Create \"%s\""), input->uri); - } -} - -static void -do_create_folder (gpointer in_data, gpointer op_data, CamelException *ex) -{ - create_folder_input_t *input = (create_folder_input_t *) in_data; - create_folder_data_t *data = (create_folder_data_t *) op_data; - - CamelFolder *folder; - gchar *camel_url; - - if (strcmp (input->type, "mail") != 0) - data->result = - Evolution_ShellComponentListener_UNSUPPORTED_TYPE; - else { - camel_url = g_strdup_printf ("mbox://%s", input->uri); - /* FIXME: supply a way to make indexes optional */ - folder = mail_tool_get_folder_from_urlname (camel_url, - "mbox", CAMEL_STORE_FOLDER_CREATE - |CAMEL_STORE_FOLDER_BODY_INDEX, ex); - g_free (camel_url); - - if (!camel_exception_is_set (ex)) { - camel_object_unref (CAMEL_OBJECT (folder)); - data->result = Evolution_ShellComponentListener_OK; - } else { - data->result = - Evolution_ShellComponentListener_INVALID_URI; - } - } -} - -static void -cleanup_create_folder (gpointer in_data, gpointer op_data, - CamelException *ex) -{ - create_folder_input_t *input = (create_folder_input_t *) in_data; - create_folder_data_t *data = (create_folder_data_t *) op_data; - - CORBA_Environment ev; - - CORBA_exception_init (&ev); - Evolution_ShellComponentListener_report_result (input->listener, - data->result, &ev); - if (ev._major != CORBA_NO_EXCEPTION) - camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, - _("Exception while reporting result to shell " - "component listener.")); - CORBA_Object_release (input->listener, &ev); - - g_free (input->uri); - g_free (input->type); - - CORBA_exception_free (&ev); -} - -static const mail_operation_spec op_create_folder = { - describe_create_folder, - sizeof (create_folder_data_t), - NULL, - do_create_folder, - cleanup_create_folder -}; - -void -mail_do_create_folder (const Evolution_ShellComponentListener listener, - const char *uri, const char *type) -{ - CORBA_Environment ev; - create_folder_input_t *input; - - g_return_if_fail (uri != NULL); - g_return_if_fail (type != NULL); - - input = g_new (create_folder_input_t, 1); - CORBA_exception_init (&ev); - input->listener = CORBA_Object_duplicate (listener, &ev); - CORBA_exception_free (&ev); - input->uri = g_strdup (uri); - input->type = g_strdup (type); - - mail_operation_queue (&op_create_folder, input, FALSE); -} - -/* ** SYNC FOLDER ********************************************************* */ - -static gchar * -describe_sync_folder (gpointer in_data, gboolean gerund) -{ - CamelFolder *f = CAMEL_FOLDER (in_data); - - if (gerund) { - return g_strdup_printf (_("Synchronizing \"%s\""), mail_tool_get_folder_name (f)); - } else { - return g_strdup_printf (_("Synchronize \"%s\""), mail_tool_get_folder_name (f)); - } -} - -static void -setup_sync_folder (gpointer in_data, gpointer op_data, CamelException *ex) -{ - camel_object_ref (CAMEL_OBJECT (in_data)); -} - -static void -do_sync_folder (gpointer in_data, gpointer op_data, CamelException *ex) -{ - mail_tool_camel_lock_up (); - camel_folder_sync (CAMEL_FOLDER (in_data), FALSE, ex); - mail_tool_camel_lock_down (); -} - -static void -cleanup_sync_folder (gpointer in_data, gpointer op_data, CamelException *ex) -{ - camel_object_unref (CAMEL_OBJECT (in_data)); -} - -static const mail_operation_spec op_sync_folder = { - describe_sync_folder, - 0, - setup_sync_folder, - do_sync_folder, - cleanup_sync_folder -}; - -void -mail_do_sync_folder (CamelFolder *folder) -{ - g_return_if_fail (CAMEL_IS_FOLDER (folder)); - - mail_operation_queue (&op_sync_folder, folder, FALSE); -} - -/* ** DISPLAY MESSAGE ***************************************************** */ - -typedef struct display_message_input_s -{ - MessageList *ml; - MailDisplay *md; - gchar *uid; - gint (*timeout) (gpointer); -} -display_message_input_t; - -typedef struct display_message_data_s -{ - CamelMimeMessage *msg; -} -display_message_data_t; - -static gchar * -describe_display_message (gpointer in_data, gboolean gerund) -{ - display_message_input_t *input = (display_message_input_t *) in_data; - - if (gerund) { - if (input->uid) - return g_strdup_printf (_("Displaying message UID \"%s\""), - input->uid); - else - return g_strdup (_("Clearing message display")); - } else { - if (input->uid) - return g_strdup_printf (_("Display message UID \"%s\""), - input->uid); - else - return g_strdup (_("Clear message display")); - } -} - -static void -setup_display_message (gpointer in_data, gpointer op_data, - CamelException *ex) -{ - display_message_input_t *input = (display_message_input_t *) in_data; - display_message_data_t *data = (display_message_data_t *) op_data; - - data->msg = NULL; - gtk_object_ref (GTK_OBJECT (input->ml)); -} - -static void -do_display_message (gpointer in_data, gpointer op_data, CamelException *ex) -{ - display_message_input_t *input = (display_message_input_t *) in_data; - display_message_data_t *data = (display_message_data_t *) op_data; - - if (input->uid == NULL) { - data->msg = NULL; - return; - } - - data->msg = camel_folder_get_message (input->ml->folder, input->uid, ex); -} - -static void -cleanup_display_message (gpointer in_data, gpointer op_data, - CamelException *ex) -{ - display_message_input_t *input = (display_message_input_t *) in_data; - display_message_data_t *data = (display_message_data_t *) op_data; - MailDisplay *md = input->md; - - if (data->msg == NULL) { - mail_display_set_message (md, NULL); - } else { - gint timeout = mail_config_mark_as_seen_timeout (); - - if (input->ml->seen_id) - gtk_timeout_remove (input->ml->seen_id); - - mail_display_set_message (md, CAMEL_MEDIUM (data->msg)); - camel_object_unref (CAMEL_OBJECT (data->msg)); - - if (timeout > 0) { - input->ml->seen_id = gtk_timeout_add (timeout, - input->timeout, - input->ml); - } else { - input->ml->seen_id = 0; - input->timeout (input->ml); - } - } - - if (input->uid) - g_free (input->uid); - gtk_object_unref (GTK_OBJECT (input->ml)); -} - -static const mail_operation_spec op_display_message = { - describe_display_message, - sizeof (display_message_data_t), - setup_display_message, - do_display_message, - cleanup_display_message -}; - -void -mail_do_display_message (MessageList *ml, MailDisplay *md, const char *uid, - gint (*timeout) (gpointer)) -{ - display_message_input_t *input; - - g_return_if_fail (IS_MESSAGE_LIST (ml)); - g_return_if_fail (timeout != NULL); - - if (uid == NULL) { - mail_display_set_message (md, NULL); - return; - } - - input = g_new (display_message_input_t, 1); - input->ml = ml; - input->md = md; - input->uid = g_strdup (uid); - input->timeout = timeout; - - mail_operation_queue (&op_display_message, input, TRUE); -} - -/* ** EDIT MESSAGES ******************************************************* */ - -typedef struct edit_messages_input_s { - CamelFolder *folder; - GPtrArray *uids; - GtkSignalFunc signal; -} edit_messages_input_t; - -typedef struct edit_messages_data_s { - GPtrArray *messages; -} edit_messages_data_t; - -static gchar * -describe_edit_messages (gpointer in_data, gboolean gerund) -{ - edit_messages_input_t *input = (edit_messages_input_t *) in_data; - - if (gerund) - return g_strdup_printf - (_("Opening messages from folder \"%s\""), - mail_tool_get_folder_name (input->folder)); - else - return g_strdup_printf (_("Open messages from \"%s\""), - mail_tool_get_folder_name (input->folder)); -} - -static void -setup_edit_messages (gpointer in_data, gpointer op_data, CamelException *ex) -{ - edit_messages_input_t *input = (edit_messages_input_t *) in_data; - - camel_object_ref (CAMEL_OBJECT (input->folder)); -} - -static void -do_edit_messages (gpointer in_data, gpointer op_data, CamelException *ex) -{ - edit_messages_input_t *input = (edit_messages_input_t *) in_data; - edit_messages_data_t *data = (edit_messages_data_t *) op_data; - - int i; - - data->messages = g_ptr_array_new (); - - for (i = 0; i < input->uids->len; i++) { - CamelMimeMessage *message; - - mail_tool_camel_lock_up (); - message = camel_folder_get_message (input->folder, input->uids->pdata[i], ex); - mail_tool_camel_lock_down (); - - if (message) - g_ptr_array_add (data->messages, message); - - g_free (input->uids->pdata[i]); - } -} - -static void -cleanup_edit_messages (gpointer in_data, gpointer op_data, - CamelException *ex) -{ - edit_messages_input_t *input = (edit_messages_input_t *) in_data; - edit_messages_data_t *data = (edit_messages_data_t *) op_data; - - int i; - - for (i = 0; i < data->messages->len; i++) { - EMsgComposer *composer; - - composer = e_msg_composer_new_with_message (data->messages->pdata[i]); - camel_object_unref (CAMEL_OBJECT (data->messages->pdata[i])); - if (!composer) - continue; - - if (input->signal) - gtk_signal_connect (GTK_OBJECT (composer), "send", - input->signal, NULL); - - gtk_widget_show (GTK_WIDGET (composer)); - } - - g_ptr_array_free (input->uids, TRUE); - g_ptr_array_free (data->messages, TRUE); - camel_object_unref (CAMEL_OBJECT (input->folder)); - -} - -static const mail_operation_spec op_edit_messages = { - describe_edit_messages, - sizeof (edit_messages_data_t), - setup_edit_messages, - do_edit_messages, - cleanup_edit_messages -}; - -void -mail_do_edit_messages (CamelFolder *folder, GPtrArray *uids, - GtkSignalFunc signal) -{ - edit_messages_input_t *input; - - g_return_if_fail (CAMEL_IS_FOLDER (folder)); - g_return_if_fail (uids != NULL); - - input = g_new (edit_messages_input_t, 1); - input->folder = folder; - input->uids = uids; - input->signal = signal; - - mail_operation_queue (&op_edit_messages, input, TRUE); -} - -/* ** SETUP FOLDER ****************************************************** */ - -typedef struct setup_folder_input_s { - gchar *name; - CamelFolder **folder; -} setup_folder_input_t; - -static gchar * -describe_setup_folder (gpointer in_data, gboolean gerund) -{ - setup_folder_input_t *input = (setup_folder_input_t *) in_data; - - if (gerund) - return g_strdup_printf (_("Loading %s Folder"), input->name); - else - return g_strdup_printf (_("Load %s Folder"), input->name); -} - -static void -do_setup_folder (gpointer in_data, gpointer op_data, CamelException *ex) -{ - setup_folder_input_t *input = (setup_folder_input_t *) in_data; - gchar *url; - - url = g_strdup_printf ("mbox://%s/local/%s", evolution_dir, - input->name); - *(input->folder) = mail_tool_get_folder_from_urlname (url, "mbox", - CAMEL_STORE_FOLDER_CREATE - |CAMEL_STORE_FOLDER_BODY_INDEX, - ex); - g_free (url); -} - -static void -cleanup_setup_folder (gpointer in_data, gpointer op_data, CamelException *ex) -{ - setup_folder_input_t *input = (setup_folder_input_t *) in_data; - - g_free (input->name); -} - -static const mail_operation_spec op_setup_folder = { - describe_setup_folder, - 0, - NULL, - do_setup_folder, - cleanup_setup_folder -}; - -void -mail_do_setup_folder (const char *name, CamelFolder **folder) -{ - setup_folder_input_t *input; - - g_return_if_fail (name != NULL); - g_return_if_fail (folder != NULL); - - input = g_new (setup_folder_input_t, 1); - input->name = g_strdup (name); - input->folder = folder; - mail_operation_queue (&op_setup_folder, input, TRUE); -} - -/* ** VIEW MESSAGES ******************************************************* */ - -typedef struct view_messages_input_s { - CamelFolder *folder; - GPtrArray *uids; - FolderBrowser *fb; -} view_messages_input_t; - -typedef struct view_messages_data_s { - GPtrArray *messages; -} view_messages_data_t; - -static gchar * -describe_view_messages (gpointer in_data, gboolean gerund) -{ - view_messages_input_t *input = (view_messages_input_t *) in_data; - - if (gerund) - return g_strdup_printf - (_("Viewing messages from folder \"%s\""), - mail_tool_get_folder_name (input->folder)); - else - return g_strdup_printf (_("View messages from \"%s\""), - mail_tool_get_folder_name (input->folder)); -} - -static void -setup_view_messages (gpointer in_data, gpointer op_data, CamelException *ex) -{ - view_messages_input_t *input = (view_messages_input_t *) in_data; - - camel_object_ref (CAMEL_OBJECT (input->folder)); - gtk_object_ref (GTK_OBJECT (input->fb)); -} - -static void -do_view_messages (gpointer in_data, gpointer op_data, CamelException *ex) -{ - view_messages_input_t *input = (view_messages_input_t *) in_data; - view_messages_data_t *data = (view_messages_data_t *) op_data; - - int i; - - data->messages = g_ptr_array_new (); - - for (i = 0; i < input->uids->len; i++) { - CamelMimeMessage *message; - - mail_op_set_message (_("Retrieving message %d of %d (uid \"%s\")"), - i + 1, input->uids->len, (char *)input->uids->pdata[i]); - - mail_tool_camel_lock_up (); - message = camel_folder_get_message (input->folder, input->uids->pdata[i], ex); - mail_tool_camel_lock_down (); - - g_ptr_array_add (data->messages, message); - } -} - -static void -cleanup_view_messages (gpointer in_data, gpointer op_data, - CamelException *ex) -{ - view_messages_input_t *input = (view_messages_input_t *) in_data; - view_messages_data_t *data = (view_messages_data_t *) op_data; - - int i; - - for (i = 0; i < data->messages->len; i++) { - CamelMimeMessage *msg; - gchar *uid; - GtkWidget *view; - - if (data->messages->pdata[i] == NULL) - continue; - - msg = data->messages->pdata[i]; - uid = input->uids->pdata[i]; - - view = mail_view_create (input->folder, uid, msg); - gtk_widget_show (view); - - /*Owned by the mail_display now*/ - camel_object_unref (CAMEL_OBJECT (data->messages->pdata[i])); - g_free (uid); - } - - g_ptr_array_free (input->uids, TRUE); - g_ptr_array_free (data->messages, TRUE); - camel_object_unref (CAMEL_OBJECT (input->folder)); - gtk_object_unref (GTK_OBJECT (input->fb)); -} - -static const mail_operation_spec op_view_messages = { - describe_view_messages, - sizeof (view_messages_data_t), - setup_view_messages, - do_view_messages, - cleanup_view_messages -}; - -void -mail_do_view_messages (CamelFolder *folder, GPtrArray *uids, - FolderBrowser *fb) -{ - view_messages_input_t *input; - - g_return_if_fail (CAMEL_IS_FOLDER (folder)); - g_return_if_fail (uids != NULL); - g_return_if_fail (IS_FOLDER_BROWSER (fb)); - - input = g_new (view_messages_input_t, 1); - input->folder = folder; - input->uids = uids; - input->fb = fb; - - mail_operation_queue (&op_view_messages, input, TRUE); -} diff --git a/mail/mail-ops.h b/mail/mail-ops.h deleted file mode 100644 index d6cb7a2cc0..0000000000 --- a/mail/mail-ops.h +++ /dev/null @@ -1,74 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Peter Williams <peterw@helixcode.com> - * - * Copyright 2000 Helix Code, Inc. (http://www.helixcode.com) - * - * 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 the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#include <camel/camel.h> -#include <filter/filter-driver.h> -#include "mail-threads.h" -#include "evolution-storage.h" /*EvolutionStorage */ -#include "composer/e-msg-composer.h" /*EMsgComposer */ -#include "message-list.h" /*MessageList */ - -void mail_do_fetch_mail (const gchar *source_url, gboolean keep_on_server, - CamelFolder *destination, - gpointer hook_func, gpointer hook_data); - -void mail_do_filter_ondemand (CamelFolder *source, GPtrArray *uids); - -void mail_do_send_mail (const char *xport_uri, - CamelMimeMessage *message, - CamelFolder *done_folder, - const char *done_uid, - guint32 done_flags, GtkWidget *composer); -void mail_do_send_queue (CamelFolder *folder_queue, - const char *xport_uri); -void mail_do_append_mail (CamelFolder *folder, - CamelMimeMessage *message, - CamelMessageInfo *info); -void mail_do_expunge_folder (CamelFolder *folder); -void mail_do_transfer_messages (CamelFolder *source, GPtrArray *uids, - gboolean delete_from_source, - gchar *dest_uri); -void mail_do_flag_messages (CamelFolder *source, GPtrArray *uids, - gboolean invert, - guint32 mask, guint32 set); -void mail_do_flag_all_messages (CamelFolder *source, gboolean invert, - guint32 mask, guint32 set); -void mail_do_scan_subfolders (CamelStore *store, EvolutionStorage *storage); -void mail_do_attach_message (CamelFolder *folder, const char *uid, - EMsgComposer *composer); -void mail_do_forward_message (CamelMimeMessage *basis, CamelFolder *source, - GPtrArray *uids, /*array of allocated gchar *, will all be freed */ - EMsgComposer *composer); -void mail_do_load_folder (FolderBrowser *fb, const char *url); -void mail_do_create_folder (const Evolution_ShellComponentListener listener, - const char *uri, const char *type); -void mail_do_sync_folder (CamelFolder *folder); -void mail_do_display_message (MessageList *ml, MailDisplay *md, const char *uid, - gint (*timeout) (gpointer)); -void mail_do_edit_messages (CamelFolder *folder, GPtrArray *uids, - GtkSignalFunc signal); -void mail_do_setup_folder (const char *name, CamelFolder **folder); -void mail_do_view_messages (CamelFolder *folder, GPtrArray *uids, - FolderBrowser *fb); - diff --git a/mail/mail-search-dialogue.c b/mail/mail-search-dialogue.c deleted file mode 100644 index 63abfc4efa..0000000000 --- a/mail/mail-search-dialogue.c +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright (C) 2000 Helix Code Inc. - * - * Authors: Not Zed <notzed@lostzed.mmc.com.au> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include <config.h> -#include <gtk/gtk.h> -#include <gnome.h> - -#include "mail-search-dialogue.h" - -static void mail_search_dialogue_class_init (MailSearchDialogueClass *class); -static void mail_search_dialogue_init (MailSearchDialogue *gspaper); -static void mail_search_dialogue_finalise (GtkObject *obj); - -static GnomeDialogClass *parent_class; - -guint -mail_search_dialogue_get_type (void) -{ - static guint type = 0; - - if (!type) { - GtkTypeInfo type_info = { - "MailSearchDialogue", - sizeof(MailSearchDialogue), - sizeof(MailSearchDialogueClass), - (GtkClassInitFunc)mail_search_dialogue_class_init, - (GtkObjectInitFunc)mail_search_dialogue_init, - (GtkArgSetFunc)NULL, - (GtkArgGetFunc)NULL - }; - - type = gtk_type_unique(gnome_dialog_get_type (), &type_info); - } - - return type; -} - -static void -mail_search_dialogue_class_init (MailSearchDialogueClass *class) -{ - GtkObjectClass *object_class; - - object_class = (GtkObjectClass *)class; - parent_class = gtk_type_class(gnome_dialog_get_type ()); - - object_class->finalize = mail_search_dialogue_finalise; - /* override methods */ - -} - -static void -mail_search_dialogue_construct (MailSearchDialogue *o, FilterRule *rule) -{ - FilterPart *part; - GnomeDialog *dialogue = GNOME_DIALOG(o); - - o->context = rule_context_new(); - rule_context_add_part_set(o->context, "partset", filter_part_get_type(), - rule_context_add_part, rule_context_next_part); - rule_context_load(o->context, EVOLUTION_DATADIR "/evolution/vfoldertypes.xml", ""); - if (rule) { - o->rule = rule; - o->guts = filter_rule_get_widget(o->rule, o->context); - } else { - o->rule = filter_rule_new(); - part = rule_context_next_part(o->context, NULL); - if (part == NULL) { - g_warning("Problem loading search: no parts to load"); - o->guts = gtk_entry_new(); - } else { - filter_rule_add_part(o->rule, filter_part_clone(part)); - o->guts = filter_rule_get_widget(o->rule, o->context); - } - } - - gtk_widget_show(o->guts); - gtk_box_pack_start(GTK_BOX(dialogue->vbox), o->guts, FALSE, FALSE, 0); -} - -static void -mail_search_dialogue_init (MailSearchDialogue *o) -{ - GnomeDialog *dialogue = GNOME_DIALOG(o); - - gnome_dialog_append_buttons(dialogue, _("Ok"), _("Search"), _("Cancel"), 0); -} - - -static void -mail_search_dialogue_finalise(GtkObject *obj) -{ - MailSearchDialogue *o = (MailSearchDialogue *)obj; - - if (o->context) - gtk_object_unref((GtkObject *)o->context); - if (o->rule) - gtk_object_unref((GtkObject *)o->rule); - - ((GtkObjectClass *)(parent_class))->finalize(obj); -} - -/** - * mail_search_dialogue_new: - * - * Create a new MailSearchDialogue object. - * - * Return value: A new #MailSearchDialogue object. - **/ -MailSearchDialogue * -mail_search_dialogue_new(void) -{ - MailSearchDialogue *o = (MailSearchDialogue *)gtk_type_new(mail_search_dialogue_get_type ()); - mail_search_dialogue_construct(o, NULL); - return o; -} - -MailSearchDialogue *mail_search_dialogue_new_with_rule(FilterRule *rule) -{ - MailSearchDialogue *o = (MailSearchDialogue *)gtk_type_new(mail_search_dialogue_get_type ()); - if (rule) - gtk_object_ref((GtkObject *)rule); - mail_search_dialogue_construct(o, rule); - return o; -} - -/** - * mail_search_dialogue_get_query: - * @msd: - * - * Get the query string represting the current search criterea. - * - * Return value: - **/ -char * -mail_search_dialogue_get_query(MailSearchDialogue *msd) -{ - GString *out = g_string_new(""); - char *ret; - - filter_rule_build_code(msd->rule, out); - ret = out->str; - g_string_free(out, FALSE); - return ret; -} diff --git a/mail/mail-search-dialogue.h b/mail/mail-search-dialogue.h deleted file mode 100644 index f952bebaf6..0000000000 --- a/mail/mail-search-dialogue.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2000 Helix Code Inc. - * - * Authors: Not Zed <notzed@lostzed.mmc.com.au> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public License - * as published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _MAIL_SEARCH_DIALOGUE_H -#define _MAIL_SEARCH_DIALOGUE_H - -#include <gtk/gtk.h> -#include <libgnomeui/gnome-dialog.h> - -#include "filter/rule-context.h" -#include "filter/filter-rule.h" - -#define MAIL_SEARCH_DIALOGUE(obj) GTK_CHECK_CAST (obj, mail_search_dialogue_get_type (), MailSearchDialogue) -#define MAIL_SEARCH_DIALOGUE_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, mail_search_dialogue_get_type (), MailSearchDialogueClass) -#define IS_MAIL_SEARCH_DIALOGUE(obj) GTK_CHECK_TYPE (obj, mail_search_dialogue_get_type ()) - -typedef struct _MailSearchDialogue MailSearchDialogue; -typedef struct _MailSearchDialogueClass MailSearchDialogueClass; - -struct _MailSearchDialogue { - GnomeDialog parent; - - RuleContext *context; - FilterRule *rule; - GtkWidget *guts; -}; - -struct _MailSearchDialogueClass { - GnomeDialogClass parent_class; - - /* virtual methods */ - - /* signals */ -}; - -guint mail_search_dialogue_get_type (void); -MailSearchDialogue *mail_search_dialogue_new (void); -MailSearchDialogue *mail_search_dialogue_new_with_rule(FilterRule *rule); - -/* methods */ -char *mail_search_dialogue_get_query(MailSearchDialogue *msd); - -#endif /* ! _MAIL_SEARCH_DIALOGUE_H */ - diff --git a/mail/mail-session.h b/mail/mail-session.h deleted file mode 100644 index da0ca15ff3..0000000000 --- a/mail/mail-session.h +++ /dev/null @@ -1,47 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Authors: Jeffrey Stedfast <fejj@helixcode.com> - * - * Copyright 2000 Helix Code, Inc. (www.helixcode.com) - * - * 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 - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA. - * - */ - -#ifndef MAIL_SESSION_H -#define MAIL_SESSION_H - -#include <gnome.h> -#include <bonobo.h> -#include <camel/camel.h> - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus }*/ - -void mail_session_init (void); -char *mail_session_request_dialog (const char *prompt, gboolean secret, - const char *key, gboolean async); -void mail_session_forget_passwords (BonoboUIComponent *uih, void *user_data, - const char *path); - -extern CamelSession *session; - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* ! MAIL_SESSION_H */ diff --git a/mail/mail-summary.c b/mail/mail-summary.c deleted file mode 100644 index 9fa9023022..0000000000 --- a/mail/mail-summary.c +++ /dev/null @@ -1,375 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* mail-summary.c - * - * Authors: Iain Holmes <iain@helixcode.com> - * - * Copyright (C) 2000 Helix Code, Inc. - * - * 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 the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <bonobo.h> - -#include "camel.h" -#include <gnome.h> -#include "mail.h" -#include "mail-tools.h" -#include "mail-ops.h" -#include "mail-vfolder.h" - -#include "Evolution.h" -#include "evolution-storage.h" - -#include "mail-local-storage.h" - -#include "filter/vfolder-context.h" - -#include <evolution-services/executive-summary-component.h> -#include <evolution-services/executive-summary-component-view.h> - -typedef struct { - CamelFolder *folder; - - char *name; - char *uri; - int total, unread; -} FolderSummary; - -typedef struct { - ExecutiveSummaryComponent *component; - ExecutiveSummaryComponentView *view; - - GHashTable *folder_to_summary; - FolderSummary **folders; - int numfolders; -} MailSummary; - -#define SUMMARY_IN() g_print ("IN: %s: %d\n", __FUNCTION__, __LINE__); -#define SUMMARY_OUT() g_print ("OUT: %s: %d\n", __FUNCTION__, __LINE__); - -static int queue_len = 0; - -extern char *evolution_dir; - -#define MAIN_READER main_compipe[0] -#define MAIN_WRITER main_compipe[1] -#define DISPATCH_READER dispatch_compipe[0] -#define DISPATCH_WRITER dispatch_compipe[1] - -static int main_compipe[2] = {-1, -1}; -static int dispatch_compipe[2] = {-1, -1}; - -GIOChannel *summary_chan_reader = NULL; - -static void do_changed (MailSummary *summary); - -/* Read a message from the pipe */ -static gboolean -read_msg (GIOChannel *source, - GIOCondition condition, - gpointer user_data) -{ - MailSummary *summary; - int size; - - summary = g_new0 (MailSummary, 1); - g_io_channel_read (source, (gchar *) summary, - sizeof (MailSummary) / sizeof (gchar), &size); - - if (size != sizeof (MailSummary)) { - g_warning (_("Incomplete message written on pipe!")); - return TRUE; - } - - do_changed (summary); - g_free (summary); - - return TRUE; -} - -/* check_compipes: */ -static void -check_compipes (void) -{ - if (MAIN_READER < 0) { - if (pipe (main_compipe) < 0) { - g_warning ("Call to pipe failed"); - return; - } - - summary_chan_reader = g_io_channel_unix_new (MAIN_READER); - g_io_add_watch (summary_chan_reader, G_IO_IN, read_msg, NULL); - } - - if (DISPATCH_READER < 0) { - if (pipe (dispatch_compipe) < 0) { - g_warning ("Call to pipe failed"); - return; - } - } -} - -static void -folder_free (FolderSummary *folder) -{ - g_free (folder->name); - g_free (folder->uri); -} - -static void -summary_free (MailSummary *summary) -{ - int i; - - for (i = 0; i < summary->numfolders; i++){ - folder_free (summary->folders[i]); - } - - g_free (summary->folders); - g_hash_table_destroy (summary->folder_to_summary); -} - -static void -view_destroy_cb (GtkObject *object, - MailSummary *summary) -{ - summary_free (summary); - g_free (summary); -} - -static char * -generate_html_summary (MailSummary *summary) -{ - char *ret_html = NULL, *tmp; - FolderSummary *fs; - int i; - - /* Inbox first */ - fs = summary->folders[0]; - - tmp = g_strdup_printf ("<table><tr><td><b><a href=\"view://evolution:/local/Inbox\">%s</a>:</b>" - "<td align=\"right\">%d/%d</td></tr>", - fs->name, fs->unread, fs->total); - - ret_html = g_strdup (tmp); - for (i = 1; i < summary->numfolders; i++) { - char *tmp2; - - fs = summary->folders[i]; - tmp2 = g_strdup_printf ("<tr><td><a href=\"view://%s\">%s</a>:</td>" - "<td align=\"right\">%d/%d</td></tr>", - fs->uri, fs->name, fs->unread, fs->total); - - tmp = ret_html; - ret_html = g_strconcat (ret_html, tmp2, NULL); - g_free (tmp); - g_free (tmp2); - } - - tmp = ret_html; - ret_html = g_strconcat (ret_html, "</table>", NULL); - g_free (tmp); - - return ret_html; -} - -static void -do_changed (MailSummary *summary) -{ - char *ret_html; - - ret_html = generate_html_summary (summary); - executive_summary_component_view_set_html(summary->view, ret_html); - g_free (ret_html); -} - -/* These two callbacks are called from the Camel thread, - which can't make any CORBA calls, or else ORBit locks up, - and likewise the thread that can call ORBit, cannot call - camel. - - So, when the callbacks are triggered, they generate a MailSummary - structure and write this onto a pipe. The ORBit calling thread - detects when something is written to the pipe and creates its own - MailSummary structure, and calls the appropriate CORBA calls. - - Same theory as mail-threads.c, but a lot less complicated - as there is only one way communication, and only one type of message -*/ -static void -folder_changed_cb (CamelObject *folder, - gpointer event_data, - gpointer user_data) -{ - MailSummary *summary; - FolderSummary *fs; - - summary = (MailSummary *) user_data; - fs = g_hash_table_lookup (summary->folder_to_summary, folder); - if (fs == NULL) { - g_warning ("%s: Unknown folder", __FUNCTION__); - return; - } - - fs->total = camel_folder_get_message_count (fs->folder); - fs->unread = camel_folder_get_unread_message_count (fs->folder); - - write (MAIN_WRITER, summary, sizeof (MailSummary)); - queue_len++; - - return; -} - -static void -message_changed_cb (CamelObject *folder, - gpointer event_data, - gpointer user_data) -{ - MailSummary *summary; - FolderSummary *fs; - - summary = (MailSummary *)user_data; - fs = g_hash_table_lookup (summary->folder_to_summary, folder); - if (fs == NULL) { - g_warning ("%s: Unknown folder.", __FUNCTION__); - return; - } - - fs->unread = camel_folder_get_unread_message_count (fs->folder); - fs->total = camel_folder_get_message_count (fs->folder); - - write (MAIN_WRITER, summary, sizeof (MailSummary)); - queue_len++; - - return; -} - -static void -generate_folder_summaries (MailSummary *summary) -{ - int numfolders = 1; /* Always at least the Inbox */ - char *user, *system; - FilterRule *rule; - VfolderContext *context; - FolderSummary *fs; - CamelException *ex; - int i; - - user = g_strdup_printf ("%s/vfolders.xml", evolution_dir); - system = g_strdup_printf ("%s/evolution/vfoldertypes.xml", EVOLUTION_DATADIR); - - context = vfolder_context_new (); - rule_context_load ((RuleContext *)context, system, user); - g_free (user); - g_free (system); - - rule = NULL; - while ((rule = rule_context_next_rule ((RuleContext *)context, rule, NULL))){ - g_print ("rule->name: %s\n", rule->name); - numfolders++; - } - - summary->folders = g_new (FolderSummary *, numfolders); - - /* Inbox */ - fs = summary->folders[0] = g_new (FolderSummary, 1); - fs->name = g_strdup ("Inbox"); - fs->uri = NULL; - mail_tool_camel_lock_up (); - ex = camel_exception_new (); - fs->folder = mail_tool_get_local_inbox (ex); - - fs->total = camel_folder_get_message_count (fs->folder); - fs->unread = camel_folder_get_unread_message_count (fs->folder); - camel_exception_free (ex); - mail_tool_camel_lock_down (); - camel_object_hook_event (CAMEL_OBJECT (fs->folder), "folder_changed", - (CamelObjectEventHookFunc) folder_changed_cb, - summary); - camel_object_hook_event (CAMEL_OBJECT (fs->folder), "message_changed", - (CamelObjectEventHookFunc) message_changed_cb, - summary); - g_hash_table_insert (summary->folder_to_summary, fs->folder, fs); - - - summary->numfolders = 1; - - for (i = 1, rule = NULL; i < numfolders; i++) { - char *uri; - - ex = camel_exception_new (); - fs = summary->folders[i] = g_new (FolderSummary, 1); - rule = rule_context_next_rule ((RuleContext *)context, rule, NULL); - fs->name = g_strdup (rule->name); - - uri = g_strconcat ("vfolder:", rule->name, NULL); - mail_tool_camel_lock_up (); - fs->folder = vfolder_uri_to_folder (uri, ex); - fs->uri = g_strconcat ("evolution:/VFolders/", rule->name, NULL); - g_free (uri); - - fs->total = camel_folder_get_message_count (fs->folder); - fs->unread = camel_folder_get_unread_message_count (fs->folder); - - /* Connect to each folder */ - camel_object_hook_event (CAMEL_OBJECT (fs->folder), - "folder_changed", - (CamelObjectEventHookFunc) folder_changed_cb, - summary); - camel_object_hook_event (CAMEL_OBJECT (fs->folder), - "message_changed", - (CamelObjectEventHookFunc) message_changed_cb, - summary); - g_hash_table_insert (summary->folder_to_summary, fs->folder, fs); - summary->numfolders++; - - camel_exception_free (ex); - mail_tool_camel_lock_down (); - } - - gtk_object_destroy (GTK_OBJECT (context)); -} - -void -create_summary_view (ExecutiveSummaryComponent *component, - ExecutiveSummaryComponentView *view, - void *closure) -{ - char *html; - MailSummary *summary; - - summary = g_new (MailSummary, 1); - summary->component = component; - summary->folder_to_summary = g_hash_table_new (NULL, NULL); - summary->view = view; - - generate_folder_summaries (summary); - - html = generate_html_summary (summary); - - check_compipes (); - - executive_summary_component_view_construct (view, component, NULL, html, - _("Mailbox summary"), - "envelope.png"); - gtk_signal_connect (GTK_OBJECT (view), "destroy", - GTK_SIGNAL_FUNC (view_destroy_cb), summary); - g_free (html); -} diff --git a/mail/mail-summary.h b/mail/mail-summary.h deleted file mode 100644 index f9f72d9cc7..0000000000 --- a/mail/mail-summary.h +++ /dev/null @@ -1,33 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* mail-summary.h - * - * Authors: Iain Holmes <iain@helixcode.com> - * - * Copyright (C) 2000 Helix Code, Inc. - * - * 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 the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __MAIL_SUMMARY_H__ -#define __MAIL_SUMMARY_H__ - -#include <evolution-services/executive-summary-component-view.h> - -void create_summary_view (ExecutiveSummaryComponent *component, - ExecutiveSummaryComponentView *view, - void *closure); - -#endif diff --git a/mail/mail-threads.c b/mail/mail-threads.c deleted file mode 100644 index cc66b60ce2..0000000000 --- a/mail/mail-threads.c +++ /dev/null @@ -1,1126 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Peter Williams (peterw@helixcode.com) - * - * Copyright 2000, Helix Code, Inc. (http://www.helixcode.com) - * - * 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 - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA. - * - */ - -#include <config.h> - -#include <string.h> -#include <errno.h> -#include <glib.h> - -#include <gal/widgets/e-gui-utils.h> - -#include "folder-browser-factory.h" - -#include "camel/camel-object.h" -#include "mail.h" -#include "mail-threads.h" - -#define DEBUG(p) g_print p - -/** - * A function and its userdata - **/ - -typedef struct closure_s -{ - gpointer in_data; - gboolean free_in_data; - gpointer op_data; - const mail_operation_spec *spec; - CamelException *ex; - gchar *infinitive; - gchar *gerund; -} -closure_t; - -/** - * A command issued through the compipe - **/ - -typedef struct com_msg_s -{ - enum com_msg_type_e { - STARTING, - -#if 0 - PERCENTAGE, - HIDE_PBAR, - SHOW_PBAR, -#endif - - MESSAGE, - PASSWORD, - ERROR, - FORWARD_EVENT, - FINISHED - } type; - - gfloat percentage; - gchar *message; - - closure_t *clur; - - /* Password stuff */ - gchar **reply; - gboolean secret; - gboolean *success; - - /* Event stuff */ - CamelObjectEventHookFunc event_hook; - CamelObject *event_obj; - gpointer event_event_data; - gpointer event_user_data; -} com_msg_t; - -/** - * Stuff needed for blocking - **/ - -typedef struct block_info_s { - GMutex *mutex; - GCond *cond; - gboolean val; -} block_info_t; - -#define BLOCK_INFO_INIT { NULL, NULL, FALSE } - -/** - * @dispatch_thread_started: gboolean that tells us whether - * the dispatch thread has been launched. - **/ - -static gboolean dispatch_thread_started = FALSE; - -/** - * @queue_len : the number of operations pending - * and being executed. - * - * Because camel is not thread-safe we work - * with the restriction that more than one mailbox - * cannot be accessed at once. Thus we cannot - * concurrently check mail and move messages, etc. - **/ - -static gint queue_len = 0; - -/** - * @main_compipe: The pipe through which the dispatcher communicates - * with the main thread for GTK+ calls - * - * @chan_reader: the GIOChannel that reads our pipe - * - * @MAIN_READER: the fd in our main pipe that.... reads! - * @MAIN_WRITER: the fd in our main pipe that.... writes! - */ - -#define MAIN_READER main_compipe[0] -#define MAIN_WRITER main_compipe[1] -#define DISPATCH_READER dispatch_compipe[0] -#define DISPATCH_WRITER dispatch_compipe[1] - -static int main_compipe[2] = { -1, -1 }; -static int dispatch_compipe[2] = { -1, -1 }; - -GIOChannel *chan_reader = NULL; - -/** - * @modal_block: a condition maintained so that the - * calling thread (the dispatch thread) blocks correctly - * until the user has responded to some kind of modal - * dialog boxy thing. - */ - -static block_info_t modal_block = BLOCK_INFO_INIT; - -/** - * @finish_block: A condition so that the dispatch thread - * blocks until the main thread has finished the cleanup. - **/ - -static block_info_t finish_block = BLOCK_INFO_INIT; - -/** - * @current_message: The current message for the status bar. - * @busy_status: Whether we are currently busy doing some async operation, - * for status bar purposes. - */ - -static char *current_message = NULL; -static gboolean busy = FALSE; - -/** - * Static prototypes - **/ - -static void ui_set_busy (void); -static void ui_unset_busy (void); -static void ui_set_message (const char *message); -static void ui_unset_message (void); - -static void block_prepare (block_info_t *info); -static void block_wait (block_info_t *info); -static void block_hold (block_info_t *info); -static void block_release (block_info_t *info); - -static void *dispatch (void * data); -static void check_dispatcher (void); -static void check_compipes (void); -static gboolean read_msg (GIOChannel * source, GIOCondition condition, - gpointer userdata); - -static void show_error (com_msg_t * msg); - -static void get_password (com_msg_t * msg); -static void get_password_cb (gchar * string, gpointer data); - -static void cleanup_op (com_msg_t * msg); - -static closure_t *new_closure (const mail_operation_spec * spec, gpointer input, - gboolean free_in_data); -static void free_closure (closure_t *clur); - -/* Pthread code */ -/* FIXME: support other thread types!!!! */ - -#ifdef G_THREADS_IMPL_POSIX - -#include <pthread.h> - -/** - * @dispatch_thread: the pthread_t (when using pthreads, of - * course) representing our dispatcher routine. Never used - * except to make pthread_create happy - **/ - -static pthread_t dispatch_thread; - -/* FIXME: do we need to set any attributes for our thread? - * If so, we need to create a pthread_attr structure and - * fill it in somewhere. But the defaults should be good - * enough. - */ - -#elif defined( G_THREADS_IMPL_SOLARIS ) - -#include <thread.h> - -static thread_t dispatch_thread; - -#else /* no supported thread impl */ -void -f (void) -{ - Error_No_supported_thread_implementation_recognized (); - choke on this; -} -#endif - -static int -pipe_write (int fd, const void *buf, size_t count) -{ - size_t res; - - do { - res = write (fd, buf, count); - } - while (res == -1 && errno == EINTR); - - return res; -} - -static size_t -pipe_read (int fd, void *buf, size_t count) -{ - size_t res; - - do { - res = read (fd, buf, count); - } while (res == -1 && errno == EINTR); - - return res; -} - -/** - * mail_operation_queue: - * @spec: describes the operation to be performed - * @input: input data for the operation. - * - * Runs a mail operation asynchronously. If no other operation is running, - * we start another thread and call the callback in that thread. The function - * can then use the mail_op_ functions to perform limited UI returns, while - * the main UI is completely unlocked. - * - * If an async operation is going on when this function is called again, - * it waits for the currently executing operation to finish, then - * executes the callback function in another thread. - * - * Returns TRUE on success, FALSE on some sort of queueing error. - **/ - -gboolean -mail_operation_queue (const mail_operation_spec * spec, gpointer input, - gboolean free_in_data) -{ - closure_t *clur; - - g_assert (spec); - - clur = new_closure (spec, input, free_in_data); - - if (spec->setup) - (spec->setup) (clur->in_data, clur->op_data, clur->ex); - - if (camel_exception_is_set (clur->ex)) { - if (clur->ex->id != CAMEL_EXCEPTION_USER_CANCEL) { - GtkWidget *err_dialog; - gchar *msg; - - msg = - g_strdup_printf - (_("Error while preparing to %s:\n" "%s"), - clur->infinitive, - camel_exception_get_description (clur->ex)); - err_dialog = gnome_error_dialog (msg); - g_free (msg); - gnome_dialog_set_close (GNOME_DIALOG (err_dialog), - TRUE); - gnome_dialog_run_and_close (GNOME_DIALOG (err_dialog)); - - g_warning ("Setup failed for `%s': %s", - clur->infinitive, - camel_exception_get_description (clur-> - ex)); - } - - free_closure (clur); - return FALSE; - } - - if (queue_len == 0) { - check_compipes (); - check_dispatcher (); - } /* else add self to queue */ - - pipe_write (DISPATCH_WRITER, clur, sizeof (closure_t)); - /* dispatch allocates a separate buffer - * to hold the closure; it's in the pipe and - * can safely be freed - */ - g_free (clur); - queue_len++; - return TRUE; -} - -#if 0 -/** - * mail_op_set_percentage: - * @percentage: the percentage that will be displayed in the progress bar - * - * Set the percentage of the progress bar for the currently executing operation. - * Threadsafe for, nay, intended to be called by, the dispatching thread. - **/ - -void -mail_op_set_percentage (gfloat percentage) -{ - com_msg_t msg; - - msg.type = PERCENTAGE; - msg.percentage = percentage; - pipe_write (MAIN_WRITER, &msg, sizeof (msg)); -} - -/** - * mail_op_hide_progressbar: - * - * Hide the progress bar in the status box - * Threadsafe for, nay, intended to be called by, the dispatching thread. - **/ - -void -mail_op_hide_progressbar (void) -{ - com_msg_t msg; - - msg.type = HIDE_PBAR; - pipe_write (MAIN_WRITER, &msg, sizeof (msg)); -} - -/** - * mail_op_show_progressbar: - * - * Show the progress bar in the status box - * Threadsafe for, nay, intended to be called by, the dispatching thread. - **/ - -void -mail_op_show_progressbar (void) -{ - com_msg_t msg; - - msg.type = SHOW_PBAR; - pipe_write (MAIN_WRITER, &msg, sizeof (msg)); -} - -#endif - -/** - * mail_op_set_message: - * @fmt: printf-style format string for the message - * @...: arguments to the format string - * - * Set the message displayed above the progress bar for the currently - * executing operation. - * Threadsafe for, nay, intended to be called by, the dispatching thread. - **/ - -void -mail_op_set_message (const gchar *fmt, ...) -{ - com_msg_t msg; - va_list val; - - va_start (val, fmt); - msg.type = MESSAGE; - msg.message = g_strdup_vprintf (fmt, val); - va_end (val); - - pipe_write (MAIN_WRITER, &msg, sizeof (msg)); -} - -/** - * mail_op_get_password: - * @prompt: the question put to the user - * @secret: whether the dialog box shold print stars when the user types - * @dest: where to store the reply - * - * Asks the user for a password (or string entry in general). Waits for - * the user's response. On success, returns TRUE and @dest contains the - * response. On failure, returns FALSE and @dest contains the error - * message. - **/ - -gboolean -mail_op_get_password (gchar * prompt, gboolean secret, gchar ** dest) -{ - com_msg_t msg; - gboolean result; - - msg.type = PASSWORD; - msg.secret = secret; - msg.message = prompt; - msg.reply = dest; - msg.success = &result; - - (*dest) = NULL; - - block_prepare (&modal_block); - pipe_write (MAIN_WRITER, &msg, sizeof (msg)); - block_wait (&modal_block); - - return result; -} - -/** - * mail_op_error: - * @fmt: printf-style format string for the error - * @...: arguments to the format string - * - * Opens an error dialog for the currently executing operation. - * Threadsafe for, nay, intended to be called by, the dispatching thread. - **/ - -void -mail_op_error (gchar * fmt, ...) -{ - com_msg_t msg; - va_list val; - - va_start (val, fmt); - msg.type = ERROR; - msg.message = g_strdup_vprintf (fmt, val); - va_end (val); - - block_prepare (&modal_block); - pipe_write (MAIN_WRITER, &msg, sizeof (msg)); - block_wait (&modal_block); -} - -/** - * mail_op_forward_event: - * - * Communicate a camel event over to the main thread. - **/ - -void -mail_op_forward_event (CamelObjectEventHookFunc func, CamelObject *o, - gpointer event_data, gpointer user_data) -{ - com_msg_t msg; - - msg.type = FORWARD_EVENT; - msg.event_hook = func; - msg.event_obj = o; - msg.event_event_data = event_data; - msg.event_user_data = user_data; - pipe_write (MAIN_WRITER, &msg, sizeof (msg)); -} -/** - * mail_operation_wait_for_finish: - * - * Waits for the currently executing async operations - * to finish executing - */ - -void -mail_operation_wait_for_finish (void) -{ - while (queue_len) - gtk_main_iteration (); - /* Sigh. Otherwise we deadlock upon exit. */ - GDK_THREADS_LEAVE (); -} - -/** - * mail_operations_are_executing: - * - * Returns TRUE if operations are being executed asynchronously - * when called, FALSE if not. - **/ - -gboolean -mail_operations_are_executing (void) -{ - return (queue_len > 0); -} - -/** - * mail_operations_terminate: - * - * Let the operations finish then terminate the dispatch thread - **/ - -void -mail_operations_terminate (void) -{ - closure_t clur; - - mail_operation_wait_for_finish(); - - memset (&clur, 0, sizeof (closure_t)); - clur.spec = NULL; - - pipe_write (DISPATCH_WRITER, &clur, sizeof (closure_t)); - - close (DISPATCH_WRITER); - close (MAIN_READER); -} - -void -mail_operations_get_status (int *busy_return, - const char **message_return) -{ - *busy_return = busy; - *message_return = current_message; -} - -/* ** Static functions **************************************************** */ - -static void check_dispatcher (void) -{ - int res; - - if (dispatch_thread_started) - return; - -#if defined( G_THREADS_IMPL_POSIX ) - res = pthread_create (&dispatch_thread, NULL, - (void *) &dispatch, NULL); -#elif defined( G_THREADS_IMPL_SOLARIS ) - res = thr_create (NULL, 0, (void *) &dispatch, NULL, 0, &dispatch_thread); -#else /* no known impl */ - Error_No_thread_create_implementation (); - choke on this; -#endif - if (res != 0) { - g_warning ("Error launching dispatch thread!"); - /* FIXME: more error handling */ - } else - dispatch_thread_started = TRUE; -} - -/** - * check_compipes: - * - * Check and see if our pipe has been opened and open - * it if necessary. - **/ - -static void -check_compipes (void) -{ - if (MAIN_READER < 0) { - if (pipe (main_compipe) < 0) { - g_warning ("Call to pipe(2) failed!"); - - /* FIXME: better error handling. How do we react? */ - return; - } - - chan_reader = g_io_channel_unix_new (MAIN_READER); - g_io_add_watch (chan_reader, G_IO_IN, read_msg, NULL); - } - - if (DISPATCH_READER < 0) { - if (pipe (dispatch_compipe) < 0) { - g_warning ("Call to pipe(2) failed!"); - - /* FIXME: better error handling. How do we react? */ - return; - } - } -} - -/** - * dispatch: - * @clur: The operation to execute and its parameters - * - * Start a thread that executes the closure and exit - * it when done. - */ - -static void * -dispatch (void *unused) -{ - size_t len; - closure_t *clur; - com_msg_t msg; - - /* Let the compipes be created */ - sleep (1); - - while (1) { - clur = g_new (closure_t, 1); - len = pipe_read (DISPATCH_READER, clur, sizeof (closure_t)); - - if (len <= 0) - break; - - if (len != sizeof (closure_t)) { - g_warning ("dispatcher: Didn't read full message!"); - continue; - } - - if (clur->spec == NULL) - break; - - msg.type = STARTING; - msg.message = g_strdup (clur->gerund); - pipe_write (MAIN_WRITER, &msg, sizeof (msg)); - - (clur->spec->callback) (clur->in_data, clur->op_data, clur->ex); - - if (camel_exception_is_set (clur->ex)) { - if (clur->ex->id != CAMEL_EXCEPTION_USER_CANCEL) { - g_warning ("Callback failed for `%s': %s", - clur->infinitive, - camel_exception_get_description (clur-> - ex)); - mail_op_error (_("Error while `%s':\n%s"), - clur->gerund, - camel_exception_get_description (clur-> - ex)); - } - } - - msg.type = FINISHED; - msg.clur = clur; - - /* Wait for the cleanup to finish before starting our next op */ - block_prepare (&finish_block); - pipe_write (MAIN_WRITER, &msg, sizeof (msg)); - block_wait (&finish_block); - } - - close (DISPATCH_READER); - close (MAIN_WRITER); - -#ifdef G_THREADS_IMPL_POSIX - pthread_exit (0); -#elif defined( G_THREADS_IMPL_SOLARIS ) - thr_exit (NULL); -#else /* no known impl */ - Error_No_thread_exit_implemented (); - choke on this; -#endif - return NULL; - /*NOTREACHED*/ -} - -/** - * read_msg: - * @source: the channel that has data to read - * @condition: the reason we were called - * @userdata: unused - * - * A message has been recieved on our pipe; perform the appropriate - * action. - **/ - -static gboolean -read_msg (GIOChannel * source, GIOCondition condition, gpointer userdata) -{ - com_msg_t *msg; - guint size; - - msg = g_new0 (com_msg_t, 1); - - g_io_channel_read (source, (gchar *) msg, - sizeof (com_msg_t) / sizeof (gchar), &size); - - if (size != sizeof (com_msg_t)) { - g_warning (_("Incomplete message written on pipe!")); - msg->type = ERROR; - msg->message = - g_strdup (_ - ("Error reading commands from dispatching thread.")); - } - - /* This is very important, though I'm not quite sure why - * it is as we are in the main thread right now. - */ - - /*g_message ("DLG: IN: read_msg");*/ - - switch (msg->type) { - case STARTING: - DEBUG (("*** Message -- STARTING %s\n", msg->message)); - ui_set_message (msg->message); - ui_set_busy (); - g_free (msg->message); - break; -#if 0 - case PERCENTAGE: - DEBUG (("*** Message -- PERCENTAGE\n")); - g_warning ("PERCENTAGE operation unsupported"); - break; - case HIDE_PBAR: - DEBUG (("*** Message -- HIDE_PBAR\n")); - g_warning ("HIDE_PBAR operation unsupported"); - break; - case SHOW_PBAR: - DEBUG (("*** Message -- SHOW_PBAR\n")); - g_warning ("HIDE_PBAR operation unsupported"); - break; -#endif - - case MESSAGE: - DEBUG (("*** Message -- MESSAGE\n")); - ui_set_message (msg->message); - g_free (msg->message); - break; - - case PASSWORD: - DEBUG (("*** Message -- PASSWORD\n")); - g_assert (msg->reply); - g_assert (msg->success); - get_password (msg); - break; - - case ERROR: - DEBUG (("*** Message -- ERROR\n")); - show_error (msg); - break; - - /* Don't fall through; dispatch_func does the FINISHED - * call for us - */ - - case FORWARD_EVENT: - DEBUG (("*** Message -- FORWARD_EVENT %p\n", msg->event_hook)); - g_assert (msg->event_hook); - (msg->event_hook) (msg->event_obj, msg->event_event_data, msg->event_user_data); - break; - - case FINISHED: - DEBUG (("*** Message -- FINISH %s\n", msg->clur->gerund)); - cleanup_op (msg); - break; - - default: - g_warning (_("Corrupted message from dispatching thread?")); - break; - } - - /*g_message ("DLG: OUT: read_msg");*/ - g_free (msg); - - return TRUE; -} - -/** - * cleanup_op: - * - * Cleanup after a finished operation - **/ - -static void -cleanup_op (com_msg_t * msg) -{ - block_hold (&finish_block); - - /* Run the cleanup */ - - if (msg->clur->spec->cleanup) - (msg->clur->spec->cleanup) (msg->clur->in_data, - msg->clur->op_data, - msg->clur->ex); - - /* Tell the dispatch thread that it can start - * the next operation */ - - block_release (&finish_block); - - /* Print an exception if the cleanup caused one */ - - if (camel_exception_is_set (msg->clur->ex) && - msg->clur->ex->id != CAMEL_EXCEPTION_USER_CANCEL) { - g_warning ("Error on cleanup of `%s': %s", - msg->clur->infinitive, - camel_exception_get_description (msg->clur->ex)); - } - - free_closure (msg->clur); - queue_len--; - - ui_unset_busy (); - ui_unset_message (); -} - -/** - * show_error: - * - * Show the error dialog and wait for user OK - **/ - -static void -show_error (com_msg_t * msg) -{ - GtkWidget *err_dialog; - - /* Create the dialog */ - - err_dialog = gnome_error_dialog (msg->message); - g_free (msg->message); - - /* Stop the other thread until the user reacts */ - - ui_unset_busy (); - block_hold (&modal_block); - - /* Show the dialog. */ - - /* Do not GDK_THREADS_ENTER; we're inside the read_msg - * handler which takes care of this for us. Oh, if - * only GDK_THREADS_ENTER were recursive... - */ - - gnome_dialog_run_and_close (GNOME_DIALOG (err_dialog)); - - /* Allow the other thread to proceed */ - - block_release (&modal_block); - ui_set_busy (); -} - -static void -focus_on_entry(GtkWidget *widget, gpointer user_data) -{ - if (GTK_IS_ENTRY(widget)) { - gtk_widget_grab_focus(widget); - } -} - -/** - * get_password: - * - * Ask for a password and put the answer in *(msg->reply) - **/ - -static void -get_password (com_msg_t * msg) -{ - GtkWidget *dialog; - int button; - - /* Create the dialog */ - - dialog = gnome_request_dialog (msg->secret, msg->message, NULL, - 0, get_password_cb, msg, NULL); - - /* Stop the other thread */ - - ui_unset_busy (); - block_hold (&modal_block); - - /* Show the dialog (or report an error) */ - - if (dialog == NULL) { - *(msg->success) = FALSE; - *(msg->reply) = g_strdup (_("Could not create dialog box.")); - button = -1; - } else { - e_container_foreach_leaf (GTK_CONTAINER (dialog), - focus_on_entry, NULL); - *(msg->reply) = NULL; - button = gnome_dialog_run_and_close (GNOME_DIALOG (dialog)); - } - - if (button == 1 || *(msg->reply) == NULL) { - *(msg->success) = FALSE; - *(msg->reply) = g_strdup (_("User cancelled query.")); - } else if (button >= 0) { - *(msg->success) = TRUE; - } - - /* Allow the other thread to proceed */ - - block_release (&modal_block); - ui_set_busy (); -} - -static void -get_password_cb (gchar * string, gpointer data) -{ - com_msg_t *msg = (com_msg_t *) data; - - if (string) - *(msg->reply) = g_strdup (string); - else - *(msg->reply) = NULL; -} - -static closure_t * -new_closure (const mail_operation_spec * spec, gpointer input, - gboolean free_in_data) -{ - closure_t *clur; - - clur = g_new0 (closure_t, 1); - clur->spec = spec; - clur->in_data = input; - clur->free_in_data = free_in_data; - clur->ex = camel_exception_new (); - - clur->op_data = g_malloc (spec->datasize); - - camel_exception_init (clur->ex); - - clur->infinitive = (spec->describe) (input, FALSE); - clur->gerund = (spec->describe) (input, TRUE); - - return clur; -} - -static void -free_closure (closure_t *clur) -{ - clur->spec = NULL; - - if (clur->free_in_data) - g_free (clur->in_data); - clur->in_data = NULL; - - g_free (clur->op_data); - clur->op_data = NULL; - - camel_exception_free (clur->ex); - clur->ex = NULL; - - g_free (clur->infinitive); - g_free (clur->gerund); - - g_free (clur); -} - -/* ******************** */ - -/** - * - * Thread A calls block_prepare - * Thread A causes thread B to do something - * Thread A calls block_wait - * Thread A continues when thread B calls block_release - * - * Thread B gets thread A's message - * Thread B calls block_hold - * Thread B does something - * Thread B calls block_release - * - **/ - -static void -block_prepare (block_info_t *info) -{ - if (info->cond == NULL) { - info->cond = g_cond_new (); - info->mutex = g_mutex_new (); - } - - g_mutex_lock (info->mutex); - info->val = FALSE; -} - -static void -block_wait (block_info_t *info) -{ - g_assert (info->cond); - - while (info->val == FALSE) - g_cond_wait (info->cond, info->mutex); - - g_mutex_unlock (info->mutex); -} -static void -block_hold (block_info_t *info) -{ - g_assert (info->cond); - - g_mutex_lock (info->mutex); - info->val = FALSE; -} - -static void -block_release (block_info_t *info) -{ - g_assert (info->cond); - - info->val = TRUE; - g_cond_signal (info->cond); - g_mutex_unlock (info->mutex); -} - -/* ******************** */ - -/* FIXME FIXME FIXME This is a totally evil hack. */ - -static Evolution_ShellView -retrieve_shell_view_interface_from_control (BonoboControl *control) -{ - Bonobo_ControlFrame control_frame; - Evolution_ShellView shell_view_interface; - CORBA_Environment ev; - - control_frame = bonobo_control_get_control_frame (control); - - if (control_frame == NULL) - return CORBA_OBJECT_NIL; - - CORBA_exception_init (&ev); - shell_view_interface = Bonobo_Unknown_queryInterface (control_frame, - "IDL:Evolution/ShellView:1.0", - &ev); - CORBA_exception_free (&ev); - - if (shell_view_interface != CORBA_OBJECT_NIL) - gtk_object_set_data (GTK_OBJECT (control), - "mail_threads_shell_view_interface", - shell_view_interface); - else - g_warning ("Control frame doesn't have Evolution/ShellView."); - - return shell_view_interface; -} - -static void -update_active_views (void) -{ - GList *controls; - GList *p; - - controls = folder_browser_factory_get_control_list (); - for (p = controls; p != NULL; p = p->next) { - BonoboControl *control; - Evolution_ShellView shell_view_interface; - CORBA_Environment ev; - - control = BONOBO_CONTROL (p->data); - - shell_view_interface = gtk_object_get_data (GTK_OBJECT (control), "mail_threads_shell_view_interface"); - - if (shell_view_interface == CORBA_OBJECT_NIL) - shell_view_interface = retrieve_shell_view_interface_from_control (control); - - CORBA_exception_init (&ev); - - if (shell_view_interface != CORBA_OBJECT_NIL) { - if (current_message == NULL && ! busy) { - Evolution_ShellView_unset_message (shell_view_interface, &ev); - } else { - if (current_message == NULL) - Evolution_ShellView_set_message (shell_view_interface, - "", - busy, - &ev); - else - Evolution_ShellView_set_message (shell_view_interface, - current_message, - busy, - &ev); - } - } - - CORBA_exception_free (&ev); - } -} - -static void -ui_set_busy (void) -{ - busy = TRUE; - update_active_views (); -} - -static void -ui_unset_busy (void) -{ - busy = FALSE; - update_active_views (); -} - -static void -ui_set_message (const char *message) -{ - g_free (current_message); - current_message = g_strdup (message); - update_active_views (); -} - -static void -ui_unset_message (void) -{ - g_free (current_message); - current_message = NULL; - update_active_views (); -} diff --git a/mail/mail-threads.h b/mail/mail-threads.h deleted file mode 100644 index d3872276f3..0000000000 --- a/mail/mail-threads.h +++ /dev/null @@ -1,75 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Peter Williams (peterw@helixcode.com) - * - * Copyright 2000, Helix Code, Inc. (http://www.helixcode.com) - * - * 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 - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA. - * - */ - -#ifndef _MAIL_THREADS_H_ -#define _MAIL_THREADS_H_ - -#include <camel/camel-exception.h> -#include <camel/camel-object.h> -#include <stdlib.h> /*size_t */ - -/* Returns a g_strdup'ed string that describes what's going to happen, - * tersely but specifically. - */ -typedef gchar *(*mail_op_describe_func) (gpointer /*input_data*/, gboolean /*gerund*/); -typedef void (*mail_op_func) (gpointer, gpointer, CamelException *); - -typedef struct _mail_operation_spec -{ - mail_op_describe_func describe; - size_t datasize; - mail_op_func setup; - mail_op_func callback; - mail_op_func cleanup; -} -mail_operation_spec; - -/* Schedule to operation to happen eventually */ - -gboolean mail_operation_queue (const mail_operation_spec * spec, - gpointer input, gboolean free_in_data); - -/* User interface hooks for the other thread */ - -#if 0 -void mail_op_set_percentage (gfloat percentage); -void mail_op_hide_progressbar (void); -void mail_op_show_progressbar (void); -#endif - -void mail_op_set_message (const gchar *fmt, ...) G_GNUC_PRINTF (1, 2); -void mail_op_error (gchar * fmt, ...) G_GNUC_PRINTF (1, 2); -gboolean mail_op_get_password (gchar * prompt, gboolean secret, - gchar ** dest); -void mail_op_forward_event (CamelObjectEventHookFunc func, CamelObject *o, - gpointer event_data, gpointer user_data); -/* Wait for the async operations to finish */ -void mail_operation_wait_for_finish (void); -gboolean mail_operations_are_executing (void); -void mail_operations_terminate (void); - -void mail_operations_get_status (int *busy_return, const char **message_return); -void mail_operations_update_status (void); - -#endif /* defined _MAIL_THREADS_H_ */ diff --git a/mail/mail-tools.c b/mail/mail-tools.c deleted file mode 100644 index e12331819d..0000000000 --- a/mail/mail-tools.c +++ /dev/null @@ -1,550 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* mail-ops.c: callbacks for the mail toolbar/menus */ - -/* - * Author : - * Dan Winship <danw@helixcode.com> - * Peter Williams <peterw@helixcode.com> - * - * Copyright 2000 Helix Code, Inc. (http://www.helixcode.com) - * - * 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 the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#include <config.h> -#include <ctype.h> -#include <errno.h> -#include "camel/camel.h" -#include "camel/providers/vee/camel-vee-folder.h" -#include "mail-vfolder.h" -#include "filter/vfolder-rule.h" -#include "filter/vfolder-context.h" -#include "filter/filter-option.h" -#include "filter/filter-input.h" -#include "filter/filter-driver.h" -#include "mail.h" /*session*/ -#include "mail-tools.h" -#include "mail-local.h" - -/* **************************************** */ - -G_LOCK_DEFINE_STATIC (camel); -G_LOCK_DEFINE_STATIC (camel_locklevel); -static GPrivate *camel_locklevel = NULL; - -#define LOCK_VAL (GPOINTER_TO_INT (g_private_get (camel_locklevel))) -#define LOCK_SET(val) g_private_set (camel_locklevel, (GINT_TO_POINTER (val))) - -void mail_tool_camel_lock_up (void) -{ - G_LOCK (camel_locklevel); - - if (camel_locklevel == NULL) - camel_locklevel = g_private_new (GINT_TO_POINTER (0)); - - if (LOCK_VAL == 0) { - G_UNLOCK (camel_locklevel); - G_LOCK (camel); - G_LOCK (camel_locklevel); - } - - LOCK_SET (LOCK_VAL + 1); - - G_UNLOCK (camel_locklevel); -} - -void mail_tool_camel_lock_down (void) -{ - G_LOCK (camel_locklevel); - - if (camel_locklevel == NULL) { - g_warning ("mail_tool_camel_lock_down: lock down before a lock up?"); - camel_locklevel = g_private_new (GINT_TO_POINTER (0)); - return; - } - - LOCK_SET (LOCK_VAL - 1); - - if (LOCK_VAL == 0) - G_UNLOCK (camel); - - G_UNLOCK (camel_locklevel); -} - -/* **************************************** */ - -CamelFolder * -mail_tool_get_folder_from_urlname (const gchar *url, const gchar *name, - guint32 flags, CamelException *ex) -{ - CamelStore *store; - CamelFolder *folder; - - mail_tool_camel_lock_up(); - - store = camel_session_get_store (session, url, ex); - if (!store) { - mail_tool_camel_lock_down(); - return NULL; - } - - /*camel_service_connect (CAMEL_SERVICE (store), ex); - *if (camel_exception_is_set (ex)) { - * camel_object_unref (CAMEL_OBJECT (store)); - * mail_tool_camel_lock_down(); - * return NULL; - *} - */ - - folder = camel_store_get_folder (store, name, flags, ex); - camel_object_unref (CAMEL_OBJECT (store)); - mail_tool_camel_lock_down(); - - return folder; -} - -const gchar * -mail_tool_get_folder_name (CamelFolder *folder) -{ - const char *name = camel_folder_get_full_name (folder); - char *path; - - /* This is a kludge. */ - - if (strcmp (name, "//mbox") && strcmp (name, "//mh")) - return name; - - /* For mbox/mh, return the parent store's final path component. */ - path = CAMEL_SERVICE (folder->parent_store)->url->path; - if (strchr (path, '/')) - return strrchr (path, '/') + 1; - else - return path; -} - -gchar * -mail_tool_get_local_inbox_url (int *index) -{ - char *uri, *new; - - uri = g_strdup_printf("file://%s/local/Inbox", evolution_dir); - new = mail_local_map_uri(uri, index); - g_free(uri); - return new; -} - -gchar * -mail_tool_get_local_movemail_url (void) -{ - return g_strdup_printf ("mbox://%s/local/Inbox", evolution_dir); -} - -gchar * -mail_tool_get_local_movemail_path (void) -{ - return g_strdup_printf ("%s/local/Inbox/movemail", evolution_dir); -} - -CamelFolder * -mail_tool_get_local_inbox (CamelException *ex) -{ - gchar *url; - CamelFolder *folder; - int index; - guint32 flags = CAMEL_STORE_FOLDER_CREATE; - - url = mail_tool_get_local_inbox_url(&index); - if (index) - flags |= CAMEL_STORE_FOLDER_BODY_INDEX; - folder = mail_tool_get_folder_from_urlname (url, "mbox", flags, ex); - g_free (url); - return folder; -} - -CamelFolder * -mail_tool_get_inbox (const gchar *url, CamelException *ex) -{ - /* FIXME: should be smarter? get_default_folder, etc */ - return mail_tool_get_folder_from_urlname (url, "inbox", 0, ex); -} - - -/* why is this function so stupidly complex when allthe work is done elsehwere? */ -char * -mail_tool_do_movemail (const gchar *source_url, CamelException *ex) -{ - gchar *dest_url; - gchar *dest_path; - const gchar *source; - struct stat sb; -#ifndef MOVEMAIL_PATH - int tmpfd; -#endif - g_return_val_if_fail (strncmp (source_url, "mbox:", 5) == 0, NULL); - - /* Set up our destination. */ - - dest_url = mail_tool_get_local_movemail_url(); - dest_path = mail_tool_get_local_movemail_path(); - - /* Create a new movemail mailbox file of 0 size */ - -#ifndef MOVEMAIL_PATH - tmpfd = open (dest_path, O_RDWR | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR); - - if (tmpfd == -1) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Couldn't create temporary " - "mbox `%s': %s"), dest_path, g_strerror (errno)); - g_free (dest_path); - g_free (dest_url); - return NULL; - } - - close (tmpfd); -#endif - - /* Skip over "mbox:" plus host part (if any) of url. */ - - source = source_url + 5; - if (!strncmp (source, "//", 2)) - source = strchr (source + 2, '/'); - - - /* Movemail from source (source_url) to dest_path */ - - mail_tool_camel_lock_up(); - camel_movemail (source, dest_path, ex); - mail_tool_camel_lock_down(); - - if (stat (dest_path, &sb) < 0 || sb.st_size == 0) { - g_free (dest_path); - g_free (dest_url); - return NULL; - } - - if (camel_exception_is_set (ex)) { - g_free (dest_url); - g_free (dest_path); - return NULL; - } - - g_free (dest_url); - return dest_path; -} - -void -mail_tool_move_folder_contents (CamelFolder *source, CamelFolder *dest, gboolean use_cache, CamelException *ex) -{ - CamelUIDCache *cache; - GPtrArray *uids; - int i; - gboolean summary_capability; - - mail_tool_camel_lock_up(); - - camel_object_ref (CAMEL_OBJECT (source)); - camel_object_ref (CAMEL_OBJECT (dest)); - - /* Get all uids of source */ - - mail_op_set_message (_("Examining %s"), source->full_name); - - uids = camel_folder_get_uids (source); - printf ("mail_tool_move_folder: got %d messages in source\n", uids->len); - - /* If we're using the cache, ... use it */ - - if (use_cache) { - GPtrArray *new_uids; - char *url, *p, *filename; - - url = camel_url_to_string ( - CAMEL_SERVICE (source->parent_store)->url, FALSE); - for (p = url; *p; p++) { - if (!isascii ((unsigned char)*p) || - strchr (" /'\"`&();|<>${}!", *p)) - *p = '_'; - } - filename = g_strdup_printf ("%s/config/cache-%s", - evolution_dir, url); - g_free (url); - - cache = camel_uid_cache_new (filename); - - if (cache) { - new_uids = camel_uid_cache_get_new_uids (cache, uids); - camel_folder_free_uids (source, uids); - uids = new_uids; - } else { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Could not read UID " - "cache file \"%s\". You may " - "receive duplicate " - "messages."), filename); - } - - g_free (filename); - } else - cache = NULL; - - printf ("mail_tool_move_folder: %d of those messages are new\n", uids->len); - - summary_capability = camel_folder_has_summary_capability (source); - - /* Copy the messages */ - for (i = 0; i < uids->len; i++) { - CamelMimeMessage *msg; - const CamelMessageInfo *info = NULL; - - /* Info */ - - mail_op_set_message (_("Retrieving message %d of %d"), - i + 1, uids->len); - - /* Get the message */ - - msg = camel_folder_get_message (source, uids->pdata[i], ex); - if (camel_exception_is_set (ex)) { - camel_object_unref (CAMEL_OBJECT (msg)); - goto cleanup; - } - - /* Append it to dest */ - - mail_op_set_message (_("Writing message %d of %d"), - i + 1, uids->len); - - if (summary_capability) - info = camel_folder_get_message_info (source, uids->pdata[i]); - camel_folder_append_message (dest, msg, info, ex); - if (camel_exception_is_set (ex)) { - camel_object_unref (CAMEL_OBJECT (msg)); - goto cleanup; - } - - /* (Maybe) get rid of the message */ - - camel_object_unref (CAMEL_OBJECT (msg)); - if (!use_cache) - camel_folder_delete_message (source, uids->pdata[i]); - } - - /* All done. Sync n' free. */ - - if (cache) { - camel_uid_cache_free_uids (uids); - - if (!camel_exception_is_set (ex)) - camel_uid_cache_save (cache); - camel_uid_cache_destroy (cache); - } else - camel_folder_free_uids (source, uids); - - mail_op_set_message (_("Saving changes to %s"), source->full_name); - - camel_folder_sync (source, TRUE, ex); - - cleanup: - camel_object_unref (CAMEL_OBJECT (source)); - camel_object_unref (CAMEL_OBJECT (dest)); - mail_tool_camel_lock_down(); -} - -void -mail_tool_set_uid_flags (CamelFolder *folder, const char *uid, guint32 mask, guint32 set) -{ - mail_tool_camel_lock_up (); - camel_folder_set_message_flags (folder, uid, mask, set); - mail_tool_camel_lock_down (); -} - -gchar * -mail_tool_generate_forward_subject (CamelMimeMessage *msg) -{ - const gchar *from; - const gchar *subject; - gchar *fwd_subj; - - mail_tool_camel_lock_up(); - from = camel_mime_message_get_from (msg); - subject = camel_mime_message_get_subject (msg); - mail_tool_camel_lock_down(); - - if (from) { - if (subject && *subject) { - fwd_subj = g_strdup_printf ("[%s] %s", from, subject); - } else { - fwd_subj = g_strdup_printf (_("[%s] (forwarded message)"), - from); - } - } else { - if (subject && *subject) { - if (strncmp (subject, "Fwd: ", 5) == 0) - subject += 4; - fwd_subj = g_strdup_printf ("Fwd: %s", subject); - } else - fwd_subj = g_strdup (_("Fwd: (no subject)")); - } - - return fwd_subj; -} - -void -mail_tool_send_via_transport (CamelTransport *transport, CamelMedium *medium, CamelException *ex) -{ - mail_tool_camel_lock_up(); - - /*camel_service_connect (CAMEL_SERVICE (transport), ex);*/ - - if (camel_exception_is_set (ex)) - goto cleanup; - - camel_transport_send (transport, medium, ex); - - /*camel_service_disconnect (CAMEL_SERVICE (transport), - *camel_exception_is_set (ex) ? NULL : ex);*/ - - cleanup: - mail_tool_camel_lock_down(); -} - -CamelMimePart * -mail_tool_make_message_attachment (CamelMimeMessage *message) -{ - CamelMimePart *part; - const char *subject; - gchar *desc; - - mail_tool_camel_lock_up(); - /*camel_object_ref (CAMEL_OBJECT (message));*/ - - subject = camel_mime_message_get_subject (message); - if (subject) - desc = g_strdup_printf (_("Forwarded message - %s"), subject); - else - desc = g_strdup (_("Forwarded message (no subject)")); - - part = camel_mime_part_new (); - camel_mime_part_set_disposition (part, "inline"); - camel_mime_part_set_description (part, desc); - camel_medium_set_content_object (CAMEL_MEDIUM (part), - CAMEL_DATA_WRAPPER (message)); - camel_mime_part_set_content_type (part, "message/rfc822"); - /*camel_object_unref (CAMEL_OBJECT (message));*/ - mail_tool_camel_lock_down(); - return part; -} - -CamelFolder * -mail_tool_filter_get_folder_func (FilterDriver *d, const char *uri, void *data) -{ - return mail_tool_uri_to_folder_noex (uri); -} - -CamelFolder * -mail_tool_get_root_of_store (const char *source_uri, CamelException *ex) -{ - CamelStore *store; - CamelFolder *folder; - - mail_tool_camel_lock_up(); - - store = camel_session_get_store (session, source_uri, ex); - if (!store) { - mail_tool_camel_lock_down (); - return NULL; - } - - /*camel_service_connect (CAMEL_SERVICE (store), ex); - *if (camel_exception_is_set (ex)) { - * camel_object_unref (CAMEL_OBJECT (store)); - * mail_tool_camel_lock_down(); - * return NULL; - *} - */ - - folder = camel_store_get_root_folder (store, ex); - camel_object_unref (CAMEL_OBJECT (store)); - mail_tool_camel_lock_down(); - - return folder; -} - -CamelFolder * -mail_tool_uri_to_folder (const char *uri, CamelException *ex) -{ - CamelStore *store = NULL; - CamelFolder *folder = NULL; - - if (!strncmp (uri, "vfolder:", 8)) { - folder = vfolder_uri_to_folder (uri, ex); - } else if (!strncmp (uri, "imap:", 5) || !strncmp (uri, "nntp:", 5)) { - mail_tool_camel_lock_up (); - store = camel_session_get_store (session, uri, ex); - if (store) { - char *ptr; - - for (ptr = (char *)(uri + 7); *ptr && *ptr != '/'; ptr++); - if (*ptr == '/') - folder = camel_store_get_folder (store, ptr + 1, CAMEL_STORE_FOLDER_CREATE, ex); - } - mail_tool_camel_lock_down (); - } else if (!strncmp (uri, "file:", 5)) { - folder = mail_tool_local_uri_to_folder (uri, ex); - } else { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Don't know protocol to open URI `%s'"), uri); - } - - if (camel_exception_is_set (ex)) { - if (folder) { - camel_object_unref (CAMEL_OBJECT (folder)); - folder = NULL; - } - } - - if (store) - camel_object_unref (CAMEL_OBJECT (store)); - - return folder; -} - -CamelFolder * -mail_tool_uri_to_folder_noex (const char *uri) -{ - CamelException ex; - CamelFolder *result; - - camel_exception_init (&ex); - result = mail_tool_uri_to_folder (uri, &ex); - - if (camel_exception_is_set (&ex)) { - gchar *msg; - GtkWidget *dialog; - - msg = g_strdup_printf (_("Cannot open location `%s':\n" - "%s"), - uri, - camel_exception_get_description (&ex)); - dialog = gnome_error_dialog (msg); - g_free (msg); - gnome_dialog_run_and_close (GNOME_DIALOG (dialog)); - gtk_widget_destroy (dialog); - } - - return result; -} diff --git a/mail/mail-tools.h b/mail/mail-tools.h deleted file mode 100644 index da5c0af8ff..0000000000 --- a/mail/mail-tools.h +++ /dev/null @@ -1,102 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Peter Williams <peterw@helixcode.com> - * - * Copyright 2000 Helix Code, Inc. (http://www.helixcode.com) - * - * 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 the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#ifndef MAIL_TOOLS_H -#define MAIL_TOOLS_H - -#include <camel/camel.h> -#include <filter/filter-driver.h> /*eek*/ - -/* A global recursive lock on Camel */ -void mail_tool_camel_lock_up (void); -void mail_tool_camel_lock_down (void); - -/* Get a CamelFolder from a root url and a foldername (uses the global session)*/ -CamelFolder * -mail_tool_get_folder_from_urlname (const gchar *url, const gchar *name, - guint32 flags, CamelException *ex); - -/* Get a useful name for a given CamelFolder (ie, not "mbox") */ -const gchar *mail_tool_get_folder_name (CamelFolder *folder); - -/* Get the url for the local inbox, index returns if the mailbox is indexed */ -gchar *mail_tool_get_local_inbox_url (int *index); - -/* Get the filename for our movemail folder or storage */ -gchar *mail_tool_get_local_movemail_path (void); -gchar *mail_tool_get_local_movemail_url (void); - -/* Get the CamelFolder for the local inbox */ -CamelFolder *mail_tool_get_local_inbox (CamelException *ex); - -/* Get the "inbox" for a url (uses global session) */ -CamelFolder *mail_tool_get_inbox (const gchar *url, CamelException *ex); - -/* Does a camel_movemail into the local movemail folder - * and returns the path to the new movemail folder that was created. which shoudl be freed later */ -char * -mail_tool_do_movemail (const gchar *source_url, CamelException *ex); - -/* Transfers all the messages from source into dest; - * source is emptied and synced. */ -void -mail_tool_move_folder_contents (CamelFolder *source, CamelFolder *dest, gboolean use_cache, CamelException *ex); - -/* Sets the flags on a message represented by a UID in a folder. */ -void -mail_tool_set_uid_flags (CamelFolder *folder, const char *uid, guint32 mask, guint32 set); - -/* Generates the subject for a message forwarding @msg */ -gchar * -mail_tool_generate_forward_subject (CamelMimeMessage *msg); - -/* Sends the medium over transport */ -void -mail_tool_send_via_transport (CamelTransport *transport, CamelMedium *medium, CamelException *ex); - -/* Make a message into an attachment */ -CamelMimePart * -mail_tool_make_message_attachment (CamelMimeMessage *message); - -/* Get the root folder of the store specified by @source_uri */ -CamelFolder * -mail_tool_get_root_of_store (const char *source_uri, CamelException *ex); - -/* Parse the ui into a real CamelFolder any way we know how. */ -CamelFolder * -mail_tool_uri_to_folder (const char *uri, CamelException *ex); - -/* Same as above taking no exceptions, popping up a GnomeErrorDialog - * if any problems occur. */ -CamelFolder * -mail_tool_uri_to_folder_noex (const char *uri); - -GHashTable * -mail_lookup_url_table (CamelMimeMessage *mime_message); - -/* Appropriate for filter_driver_run */ -CamelFolder * -mail_tool_filter_get_folder_func (FilterDriver *d, const char *uri, void *data); - -#endif diff --git a/mail/mail-types.h b/mail/mail-types.h deleted file mode 100644 index 74e650fd4f..0000000000 --- a/mail/mail-types.h +++ /dev/null @@ -1,40 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Copyright 2000 Helix Code, Inc. (http://www.helixcode.com) - * - * 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 the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#ifndef MAIL_TYPES_H -#define MAIL_TYPES_H 1 - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus }*/ - - -typedef struct _FolderBrowser FolderBrowser; -typedef struct _SubscribeDialog SubscribeDialog; -typedef struct _MessageList MessageList; -typedef struct _MailDisplay MailDisplay; - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* MAIL_TYPES_H */ diff --git a/mail/mail-vfolder.c b/mail/mail-vfolder.c deleted file mode 100644 index 5bdac810cc..0000000000 --- a/mail/mail-vfolder.c +++ /dev/null @@ -1,312 +0,0 @@ -/* - Copyright 2000 Helix Code Inc. - - Author: Michael Zucchi <notzed@helixcode.com> - - code for managing vfolders - - NOTE: dont run this through fucking indent. -*/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <bonobo.h> - -#include "Evolution.h" -#include "evolution-storage.h" - -#include "evolution-shell-component.h" -#include "folder-browser.h" -#include "mail-vfolder.h" -#include "mail-tools.h" -#include "mail-autofilter.h" - -#include "camel/camel.h" - -#include "filter/vfolder-context.h" -#include "filter/vfolder-editor.h" - -#define d(x) x - -struct _vfolder_info { - char *name; - char *query; -}; - -/* list of vfolders available */ -static GList *available_vfolders = NULL; -static VfolderContext *context; -static EvolutionStorage *vfolder_storage; - -/* GROSS HACK: for passing to other parts of the program */ -EvolutionShellClient *global_shell_client = NULL; - -/* more globals ... */ -extern char *evolution_dir; -extern CamelSession *session; - -static struct _vfolder_info * -vfolder_find(const char *name) -{ - GList *l = available_vfolders; - struct _vfolder_info *info; - - while (l) { - info = l->data; - if (!strcmp(info->name, name)) - return info; - l = g_list_next(l); - } - return NULL; -} - -/* go through the list of what we have, what we want, and make - them match, deleting/reconfiguring as required */ -static void -vfolder_refresh(void) -{ - GList *l; - GList *head = NULL; /* processed list */ - struct _vfolder_info *info; - FilterRule *rule; - GString *expr = g_string_new(""); - char *uri, *path; - - rule = NULL; - while ( (rule = rule_context_next_rule((RuleContext *)context, rule, NULL)) ) { - info = vfolder_find(rule->name); - g_string_truncate(expr, 0); - filter_rule_build_code(rule, expr); - if (info) { - available_vfolders = g_list_remove(available_vfolders, info); - - /* check if the rule has changed ... otherwise, leave it */ - if (strcmp(expr->str, info->query)) { - d(printf("Must reconfigure vfolder with new rule?\n")); - g_free(info->query); - info->query = g_strdup(expr->str); - - uri = g_strdup_printf("vfolder:%s", info->name); - path = g_strdup_printf("/%s", info->name); - evolution_storage_removed_folder(vfolder_storage, path); - evolution_storage_new_folder(vfolder_storage, path, g_basename(path), - "mail", uri, info->name, FALSE); - g_free(uri); - g_free(path); - } - } else { - info = g_malloc(sizeof(*info)); - info->name = g_strdup(rule->name); - info->query = g_strdup(expr->str); - d(printf("Adding new vfolder: %s %s\n", rule->name, expr->str)); - - uri = g_strdup_printf("vfolder:%s", info->name); - path = g_strdup_printf("/%s", info->name); - evolution_storage_new_folder(vfolder_storage, path, g_basename(path), - "mail", uri, info->name, FALSE); - g_free(uri); - g_free(path); - } - head = g_list_append(head, info); - } - /* everything in available_vfolders are to be removed ... */ - l = available_vfolders; - while (l) { - info = l->data; - d(printf("removing vfolders %s %s\n", info->name, info->query)); - path = g_strdup_printf("/%s", info->name); - evolution_storage_removed_folder(vfolder_storage, path); - g_free(path); - g_free(info->name); - g_free(info->query); - l = g_list_next(l); - } - g_list_free(available_vfolders); - available_vfolders = head; - g_string_free(expr, TRUE); -} - -void -vfolder_create_storage(EvolutionShellComponent *shell_component) -{ - EvolutionShellClient *shell_client; - Evolution_Shell corba_shell; - EvolutionStorage *storage; - char *user, *system; - - shell_client = evolution_shell_component_get_owner (shell_component); - if (shell_client == NULL) { - g_warning ("We have no shell!?"); - return; - } - global_shell_client = shell_client; - - corba_shell = bonobo_object_corba_objref (BONOBO_OBJECT (shell_client)); - - storage = evolution_storage_new (_("VFolders")); - if (evolution_storage_register_on_shell (storage, corba_shell) != EVOLUTION_STORAGE_OK) { - g_warning ("Cannot register storage"); - return; - } - - vfolder_storage = storage; - - user = g_strdup_printf ("%s/vfolders.xml", evolution_dir); - system = g_strdup_printf("%s/evolution/vfoldertypes.xml", EVOLUTION_DATADIR); - - context = vfolder_context_new(); - printf("loading rules %s %s\n", system, user); - if (rule_context_load((RuleContext *)context, system, user) != 0) { - g_warning("cannot load vfolders: %s\n", ((RuleContext *)context)->error); - } - g_free(user); - g_free(system); - vfolder_refresh(); -} - -/* maps the shell's uri to the real vfolder uri and open the folder */ -CamelFolder * -vfolder_uri_to_folder(const char *uri, CamelException *ex) -{ - void camel_vee_folder_add_folder(CamelFolder *, CamelFolder *); - - struct _vfolder_info *info; - char *storeuri, *foldername; - VfolderRule *rule; - CamelFolder *folder = NULL, *sourcefolder; - const char *sourceuri; - int sources; - - if (strncmp (uri, "vfolder:", 8)) - return NULL; - - info = vfolder_find(uri+8); - if (info == NULL) { - g_warning("Shell trying to open unknown vFolder: %s", uri); - return NULL; - } - - d(printf("Opening vfolder: %s\n", uri)); - - rule = (VfolderRule *)rule_context_find_rule((RuleContext *)context, info->name, NULL); - - storeuri = g_strdup_printf("vfolder:%s/vfolder/%s", evolution_dir, info->name); - foldername = g_strdup_printf("mbox?%s", info->query); - - /* we dont have indexing on vfolders */ - folder = mail_tool_get_folder_from_urlname (storeuri, foldername, CAMEL_STORE_FOLDER_CREATE, ex); - - sourceuri = NULL; - sources = 0; - while ( (sourceuri = vfolder_rule_next_source(rule, sourceuri)) ) { - d(printf("adding vfolder source: %s\n", sourceuri)); - sourcefolder = mail_tool_uri_to_folder (sourceuri, ex); - if (sourcefolder) { - sources++; - mail_tool_camel_lock_up (); - camel_vee_folder_add_folder(folder, sourcefolder); - mail_tool_camel_lock_down (); - } - } - /* if we didn't have any sources, just use Inbox as the default */ - if (sources == 0) { - char *defaulturi; - - defaulturi = g_strdup_printf("file://%s/local/Inbox", evolution_dir); - d(printf("No sources configured/found, using default: %s\n", defaulturi)); - sourcefolder = mail_tool_uri_to_folder (defaulturi, ex); - g_free(defaulturi); - if (sourcefolder) { - mail_tool_camel_lock_up (); - camel_vee_folder_add_folder(folder, sourcefolder); - mail_tool_camel_lock_down (); - } - } - - g_free(foldername); - g_free(storeuri); - - return folder; -} - -static void -vfolder_editor_clicked(GtkWidget *w, int button, void *data) -{ - if (button == 0) { - char *user; - - user = g_strdup_printf("%s/vfolders.xml", evolution_dir); - rule_context_save((RuleContext *)context, user); - g_free(user); - vfolder_refresh(); - } - if (button != -1) { - gnome_dialog_close((GnomeDialog *)w); - } -} - -void -vfolder_edit(void) -{ - GtkWidget *w; - - w = vfolder_editor_construct(context); - gtk_signal_connect((GtkObject *)w, "clicked", vfolder_editor_clicked, NULL); - gtk_widget_show(w); -} - -static void -new_rule_clicked(GtkWidget *w, int button, void *data) -{ - if (button == 0) { - char *user; - FilterRule *rule = gtk_object_get_data((GtkObject *)w, "rule"); - - gtk_object_ref((GtkObject *)rule); - rule_context_add_rule((RuleContext *)context, rule); - user = g_strdup_printf("%s/vfolders.xml", evolution_dir); - rule_context_save((RuleContext *)context, user); - g_free(user); - vfolder_refresh(); - } - if (button != -1) { - gnome_dialog_close((GnomeDialog *)w); - } -} - -FilterPart * -vfolder_create_part(const char *name) -{ - return rule_context_create_part((RuleContext *)context, name); -} - -/* adds a rule with a gui */ -void -vfolder_gui_add_rule(VfolderRule *rule) -{ - GtkWidget *w; - GnomeDialog *gd; - - w = filter_rule_get_widget((FilterRule *)rule, (RuleContext *)context); - gd = (GnomeDialog *)gnome_dialog_new(_("New VFolder"), - GNOME_STOCK_BUTTON_OK, - GNOME_STOCK_BUTTON_CANCEL, - NULL); - gtk_window_set_policy(GTK_WINDOW(gd), FALSE, TRUE, FALSE); - gtk_box_pack_start((GtkBox *)gd->vbox, w, FALSE, TRUE, 0); - gtk_widget_show((GtkWidget *)gd); - gtk_object_set_data_full((GtkObject *)gd, "rule", rule, (GtkDestroyNotify)gtk_object_unref); - gtk_signal_connect((GtkObject *)gd, "clicked", new_rule_clicked, NULL); - gtk_widget_show((GtkWidget *)gd); -} - -void -vfolder_gui_add_from_message(CamelMimeMessage *msg, int flags, const char *source) -{ - VfolderRule *rule; - - rule = (VfolderRule*)vfolder_rule_from_message(context, msg, flags, source); - vfolder_gui_add_rule(rule); -} - diff --git a/mail/mail-vfolder.h b/mail/mail-vfolder.h deleted file mode 100644 index 2ff19cc3ea..0000000000 --- a/mail/mail-vfolder.h +++ /dev/null @@ -1,24 +0,0 @@ - -#ifndef _MAIL_VFOLDER_H -#define _MAIL_VFOLDER_H - -#include <bonobo.h> - -#include "Evolution.h" -#include "evolution-storage.h" -#include "evolution-shell-component.h" - -#include "camel/camel-folder.h" -#include "camel/camel-mime-message.h" -#include "filter/vfolder-rule.h" -#include "filter/filter-part.h" - -void vfolder_create_storage(EvolutionShellComponent *shell_component); - -CamelFolder *vfolder_uri_to_folder(const char *uri, CamelException *ex); -void vfolder_edit(void); -FilterPart *vfolder_create_part(const char *name); -void vfolder_gui_add_rule(VfolderRule *rule); -void vfolder_gui_add_from_message(CamelMimeMessage *msg, int flags, const char *source); - -#endif diff --git a/mail/mail-view.c b/mail/mail-view.c deleted file mode 100644 index 2d95fb4f24..0000000000 --- a/mail/mail-view.c +++ /dev/null @@ -1,265 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Authors: Jeffrey Stedfast <fejj@helixcode.com> - * - * Copyright 2000 Helix Code, Inc. (www.helixcode.com) - * - * 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 - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA. - * - */ - -#include <config.h> -#include "mail.h" -#include "mail-ops.h" -#include "camel/camel.h" -#include "mail-display.h" -#include "mail-callbacks.h" - -typedef struct mail_view_data_s { - CamelFolder *source; - gchar *uid; - CamelMimeMessage *msg; - MailDisplay *md; -} mail_view_data; - -#define MINIMUM_WIDTH 600 -#define MINIMUM_HEIGHT 400 - -/* Size of the window last time it was changed. */ -static GtkAllocation last_allocation = { 0, 0 }; - -static void -mail_view_data_free (gpointer mvd) -{ - mail_view_data *data = (mail_view_data *) mvd; - - if (data->uid) - g_free (data->uid); - if (data->msg) - camel_object_unref (CAMEL_OBJECT (data->msg)); - if (data->source) - camel_object_unref (CAMEL_OBJECT (data->source)); - - g_free (data); -} - -static mail_view_data * -mail_view_data_new (CamelFolder *source, const gchar *uid, CamelMimeMessage *msg) -{ - mail_view_data *data; - - data = g_new (mail_view_data, 1); - data->source = source; - camel_object_ref (CAMEL_OBJECT (data->source)); - data->msg = msg; - camel_object_ref (CAMEL_OBJECT (data->msg)); - data->uid = g_strdup (uid); - - return data; -} - -static void -on_close (GtkWidget *menuitem, gpointer user_data) -{ - GtkWidget *view_window; - - view_window = gtk_object_get_data (GTK_OBJECT (menuitem), "view-window"); - g_return_if_fail (view_window); - gtk_widget_destroy (GTK_WIDGET (view_window)); -} - -static void -view_reply_to_sender (GtkWidget *widget, gpointer user_data) -{ - mail_view_data *data = (mail_view_data *) user_data; - - mail_reply (data->source, data->msg, data->uid, FALSE); -} - -static void -view_reply_to_all (GtkWidget *widget, gpointer user_data) -{ - mail_view_data *data = (mail_view_data *) user_data; - - mail_reply (data->source, data->msg, data->uid, TRUE); -} - -static void -view_forward_msg (GtkWidget *widget, gpointer user_data) -{ - mail_view_data *data = (mail_view_data *) user_data; - - GPtrArray *uids; - EMsgComposer *composer; - - composer = e_msg_composer_new (); - if (!composer) - return; - - uids = g_ptr_array_new(); - g_ptr_array_add (uids, g_strdup (data->uid)); - - gtk_signal_connect (GTK_OBJECT (composer), "send", - GTK_SIGNAL_FUNC (composer_send_cb), NULL); - - mail_do_forward_message (data->msg, data->source, uids, composer); -} - -static void -view_print_msg (GtkWidget *widget, gpointer user_data) -{ - mail_view_data *data = (mail_view_data *) user_data; - - mail_print_msg (data->md); -} - -static void -view_delete_msg (GtkWidget *button, gpointer user_data) -{ - mail_view_data *data = (mail_view_data *) user_data; - - GPtrArray *uids; - - uids = g_ptr_array_new(); - g_ptr_array_add (uids, g_strdup (data->uid)); - mail_do_flag_messages (data->source, uids, TRUE, - CAMEL_MESSAGE_DELETED, CAMEL_MESSAGE_DELETED); -} - -static void -view_size_allocate_cb (GtkWidget *widget, - GtkAllocation *allocation) -{ - last_allocation = *allocation; -} - -static GnomeUIInfo mail_view_toolbar [] = { - - /*GNOMEUIINFO_ITEM_STOCK (N_("Save"), N_("Save this message"), - save_msg, GNOME_STOCK_PIXMAP_SAVE),*/ - - GNOMEUIINFO_ITEM_STOCK (N_("Reply"), N_("Reply to the sender of this message"), - view_reply_to_sender, GNOME_STOCK_PIXMAP_MAIL_RPL), - - GNOMEUIINFO_ITEM_STOCK (N_("Reply to All"), N_("Reply to all recipients of this message"), - view_reply_to_all, GNOME_STOCK_PIXMAP_MAIL_RPL), - - GNOMEUIINFO_ITEM_STOCK (N_("Forward"), N_("Forward this message"), view_forward_msg, GNOME_STOCK_PIXMAP_MAIL_FWD), - - GNOMEUIINFO_SEPARATOR, - - GNOMEUIINFO_ITEM_STOCK (N_("Print"), N_("Print the selected message"), view_print_msg, GNOME_STOCK_PIXMAP_PRINT), - - GNOMEUIINFO_ITEM_STOCK (N_("Delete"), N_("Delete this message"), view_delete_msg, GNOME_STOCK_PIXMAP_TRASH), - - /*GNOMEUIINFO_SEPARATOR,*/ - - /*GNOMEUIINFO_ITEM_STOCK (N_("Next"), N_("Next message"), mail_view_next_msg, GNOME_STOCK_PIXMAP_NEXT), - - GNOMEUIINFO_ITEM_STOCK (N_("Previous"), N_("Previous message"), mail_view_prev_msg, GNOME_STOCK_PIXMAP_PREVIOUS),*/ - - GNOMEUIINFO_END -}; - -static GnomeUIInfo file_menu[] = { - /*GNOMEUIINFO_MENU_SAVE_ITEM (save, NULL),*/ - /*GNOMEUIINFO_MENU_SAVE_AS_ITEM (save_as, NULL),*/ - /*GNOMEUIINFO_SEPARATOR,*/ - GNOMEUIINFO_MENU_CLOSE_ITEM (on_close, NULL), - GNOMEUIINFO_END -}; - -static GnomeUIInfo view_menu[] = -{ - GNOMEUIINFO_END -}; - -static GnomeUIInfo mail_view_menubar[] = -{ - GNOMEUIINFO_MENU_FILE_TREE (file_menu), - GNOMEUIINFO_MENU_VIEW_TREE (view_menu), - GNOMEUIINFO_END -}; - -static void -set_default_size (GtkWidget *widget) -{ - int width, height; - - width = MAX (MINIMUM_WIDTH, last_allocation.width); - height = MAX (MINIMUM_HEIGHT, last_allocation.height); - - gtk_window_set_default_size (GTK_WINDOW (widget), width, height); -} - -GtkWidget * -mail_view_create (CamelFolder *source, const char *uid, CamelMimeMessage *msg) -{ - GtkWidget *window; - GtkWidget *toolbar; - GtkWidget *mail_display; - char *subject; - mail_view_data *data; - - data = mail_view_data_new (source, uid, msg); - - subject = (char *) camel_mime_message_get_subject (msg); - if (!subject) - subject = ""; - - window = gnome_app_new ("Evolution", subject); - - toolbar = gtk_toolbar_new (GTK_ORIENTATION_HORIZONTAL, GTK_TOOLBAR_BOTH); - - gnome_app_fill_toolbar_with_data (GTK_TOOLBAR (toolbar), - mail_view_toolbar, - NULL, data); - - gnome_app_set_toolbar (GNOME_APP (window), GTK_TOOLBAR (toolbar)); - gnome_app_create_menus (GNOME_APP (window), mail_view_menubar); - - gtk_object_set_data_full (GTK_OBJECT (window), "mvd", data, - mail_view_data_free); - - gtk_widget_ref (mail_view_menubar[0].widget); - gtk_object_set_data_full (GTK_OBJECT (window), "file", - mail_view_menubar[0].widget, - (GtkDestroyNotify) gtk_widget_unref); - - gtk_widget_ref (file_menu[0].widget); - gtk_object_set_data (GTK_OBJECT (file_menu[0].widget), "view-window", window); - gtk_object_set_data_full (GTK_OBJECT (window), "close", - file_menu[0].widget, - (GtkDestroyNotify) gtk_widget_unref); - - gtk_widget_ref (mail_view_menubar[1].widget); - gtk_object_set_data_full (GTK_OBJECT (window), "view", - mail_view_menubar[1].widget, - (GtkDestroyNotify) gtk_widget_unref); - - mail_display = mail_display_new (); - mail_display_set_message (MAIL_DISPLAY (mail_display), CAMEL_MEDIUM (msg)); - data->md = MAIL_DISPLAY (mail_display); - gnome_app_set_contents (GNOME_APP (window), mail_display); - gtk_widget_grab_focus (GTK_WIDGET (MAIL_DISPLAY (mail_display)->html)); - - gtk_signal_connect (GTK_OBJECT (window), "size_allocate", - GTK_SIGNAL_FUNC (view_size_allocate_cb), NULL); - - set_default_size (window); - - return window; -} - diff --git a/mail/mail.h b/mail/mail.h deleted file mode 100644 index 481c031585..0000000000 --- a/mail/mail.h +++ /dev/null @@ -1,69 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Copyright 2000, Helix Code, Inc. (http://www.helixcode.com) - * - * 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 - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA. - */ - -/* This file is a F*CKING MESS. Shame to us! */ - -#include <gtkhtml/gtkhtml.h> -#include <libgnomevfs/gnome-vfs-mime-handlers.h> -#include "camel/camel.h" -#include "composer/e-msg-composer.h" -#include "mail-callbacks.h" -#include "mail-config.h" -#include "mail-config-gui.h" -/*#include "folder-browser.h"*/ -#include "mail-session.h" -#include "mail-types.h" -#include "shell/evolution-storage.h" - -extern char *evolution_dir; - -/* mail-format */ -void mail_format_mime_message (CamelMimeMessage *mime_message, - MailDisplay *md); - -typedef gboolean (*MailMimeHandlerFn) (CamelMimePart *part, - const char *mime_type, - MailDisplay *md); -typedef struct { - gboolean generic; - OAF_ServerInfo *component; - GnomeVFSMimeApplication *application; - MailMimeHandlerFn builtin; -} MailMimeHandler; -MailMimeHandler *mail_lookup_handler (const char *mime_type); - -gboolean mail_part_is_inline (CamelMimePart *part); - -EMsgComposer *mail_generate_reply (CamelMimeMessage *mime_message, - gboolean to_all); - -char *mail_get_message_body (CamelDataWrapper *data, gboolean want_plain, - gboolean *is_html); - -/* mail-identify */ -char *mail_identify_mime_part (CamelMimePart *part); - -/* mail view */ -GtkWidget *mail_view_create (CamelFolder *source, const char *uid, CamelMimeMessage *msg); - -/* component factory for lack of a better place */ -/*takes a GSList of MailConfigServices */ -void mail_load_storages (Evolution_Shell corba_shell, GSList *sources); -/* used in the subscribe dialog code */ -EvolutionStorage *mail_lookup_storage (CamelStore *store); diff --git a/mail/main.c b/mail/main.c deleted file mode 100644 index a8b5e1298a..0000000000 --- a/mail/main.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * main.c: The core of the mail component - * - * Author: - * Miguel de Icaza (miguel@helixcode.com) - * - * (C) 2000 Helix Code, Inc. - */ - -#include <config.h> - -#include <signal.h> - -#include <gnome.h> -#include <bonobo/bonobo-main.h> -#include <bonobo/bonobo-object-directory.h> -#include <glade/glade.h> -#include <liboaf/liboaf.h> -#include <libgnomevfs/gnome-vfs.h> - -#ifdef GTKHTML_HAVE_GCONF -#include <gconf/gconf.h> -#endif - -#include <gal/widgets/e-gui-utils.h> -#include <gal/widgets/e-cursors.h> -#include <gal/widgets/e-unicode.h> - -#include "component-factory.h" -#include "composer/evolution-composer.h" -#include "mail.h" - -#if 0 -static int blowup(int status) -{ - printf("memory blew up, status %d\n", status); - /*abort();*/ - return status; -} -#endif - -int -main (int argc, char *argv []) -{ - CORBA_ORB orb; - -#if 0 - /* used to make elfence work */ -#if 0 - free (malloc (10)); -#else - /*mtrace();*/ - mcheck(blowup); -#endif -#endif -#ifdef ENABLE_NLS - bindtextdomain (PACKAGE, EVOLUTION_LOCALEDIR); - textdomain (PACKAGE); -#endif - - g_thread_init( NULL ); - - gnome_init_with_popt_table ("evolution-mail-component", VERSION, - argc, argv, oaf_popt_options, 0, NULL); - orb = oaf_init (argc, argv); - - if (bonobo_init (orb, CORBA_OBJECT_NIL, - CORBA_OBJECT_NIL) == FALSE) { - g_error ("Mail component could not initialize Bonobo.\n" - "If there was a warning message about the " - "RootPOA, it probably means\nyou compiled " - "Bonobo against GOAD instead of OAF."); - } - -#ifdef GTKHTML_HAVE_GCONF - gconf_init (argc, argv, NULL); -#endif - - glade_gnome_init (); - - gnome_vfs_init (); - - e_unicode_init (); - - e_cursors_init (); - - component_factory_init (); - evolution_composer_factory_init (composer_send_cb, - composer_postpone_cb); - - signal (SIGSEGV, SIG_DFL); - signal (SIGBUS, SIG_DFL); - - if (gdk_threads_mutex) { - g_mutex_free (gdk_threads_mutex); - gdk_threads_mutex = NULL; - } - - GDK_THREADS_ENTER (); - bonobo_main (); - GDK_THREADS_LEAVE (); - - mail_config_write_on_exit (); - - return 0; -} diff --git a/mail/message-list.c b/mail/message-list.c deleted file mode 100644 index d28021f77e..0000000000 --- a/mail/message-list.c +++ /dev/null @@ -1,2161 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * message-list.c: Displays the messages. - * Implements CORBA's Evolution::MessageList - * - * Author: - * Miguel de Icaza (miguel@helixcode.com) - * Bertrand Guiheneuf (bg@aful.org) - * And just about everyone else in evolution ... - * - * (C) 2000 Helix Code, Inc. - */ - -#include <config.h> -#include <gnome.h> -#include <bonobo/bonobo-main.h> -#include <camel/camel-exception.h> -#include <camel/camel-folder.h> -#include <e-util/ename/e-name-western.h> - -#include <string.h> -#include <ctype.h> - -#include "mail-config.h" -#include "message-list.h" -#include "message-thread.h" -#include "mail-threads.h" -#include "mail-tools.h" -#include "Mail.h" - -#include <gal/util/e-util.h> -#include <gal/widgets/e-gui-utils.h> -#include <gal/e-table/e-table-header-item.h> -#include <gal/e-table/e-table-item.h> - -#include "art/mail-new.xpm" -#include "art/mail-read.xpm" -#include "art/mail-replied.xpm" -#include "art/attachment.xpm" -#include "art/priority-high.xpm" -#include "art/empty.xpm" -#include "art/score-lowest.xpm" -#include "art/score-lower.xpm" -#include "art/score-low.xpm" -#include "art/score-normal.xpm" -#include "art/score-high.xpm" -#include "art/score-higher.xpm" -#include "art/score-highest.xpm" - -#define TIMEIT - -#ifdef TIMEIT -#include <sys/time.h> -#include <unistd.h> -#endif - -#define d(x) -#define t(x) - -/* - * Default sizes for the ETable display - * - */ -#define N_CHARS(x) (CHAR_WIDTH * (x)) - -#define COL_ICON_WIDTH (16) -#define COL_ATTACH_WIDTH (16) -#define COL_CHECK_BOX_WIDTH (16) -#define COL_FROM_EXPANSION (24.0) -#define COL_FROM_WIDTH_MIN (32) -#define COL_SUBJECT_EXPANSION (30.0) -#define COL_SUBJECT_WIDTH_MIN (32) -#define COL_SENT_EXPANSION (24.0) -#define COL_SENT_WIDTH_MIN (32) -#define COL_RECEIVED_EXPANSION (20.0) -#define COL_RECEIVED_WIDTH_MIN (32) -#define COL_TO_EXPANSION (24.0) -#define COL_TO_WIDTH_MIN (32) -#define COL_SIZE_EXPANSION (6.0) -#define COL_SIZE_WIDTH_MIN (32) - -#define PARENT_TYPE (bonobo_object_get_type ()) - -static BonoboObjectClass *message_list_parent_class; -static POA_Evolution_MessageList__vepv evolution_message_list_vepv; - -static void on_cursor_change_cmd (ETableScrolled *table, int row, gpointer user_data); -static gint on_click (ETableScrolled *table, gint row, gint col, GdkEvent *event, MessageList *list); -static char *filter_date (const void *data); -static void free_tree_ids (ETreeModel *etm); - -static void save_tree_state(MessageList *ml); - -/* note: @changes is owned/freed by the caller */ -static void mail_do_regenerate_messagelist (MessageList *list, const gchar *search, CamelFolderChangeInfo *changes); - -/* macros for working with id's (stored in the tree nodes) */ -#define id_is_uid(id) (id[0] == 'u')/* is this a uid id? */ -#define id_is_subject(id) (id[0] == 's') /* is this a subject id? */ -#define id_uid(id) (&id[1]) /* get the uid part of the id */ -#define id_subject(id) (&id[1]) /* get the subject part of the id */ - -enum { - MESSAGE_SELECTED, - LAST_SIGNAL -}; - -static guint message_list_signals [LAST_SIGNAL] = {0, }; - -static struct { - char **image_base; - GdkPixbuf *pixbuf; -} states_pixmaps [] = { - { mail_new_xpm, NULL }, - { mail_read_xpm, NULL }, - { mail_replied_xpm, NULL }, - { empty_xpm, NULL }, - { attachment_xpm, NULL }, - { priority_high_xpm, NULL }, - { score_lowest_xpm, NULL }, - { score_lower_xpm, NULL }, - { score_low_xpm, NULL }, - { score_normal_xpm, NULL }, - { score_high_xpm, NULL }, - { score_higher_xpm, NULL }, - { score_highest_xpm, NULL }, - { NULL, NULL } -}; - -enum DndTargetTyhpe { - DND_TARGET_LIST_TYPE_URI, -}; -#define URI_LIST_TYPE "text/uri-list" -static GtkTargetEntry drag_types[] = { - { URI_LIST_TYPE, 0, DND_TARGET_LIST_TYPE_URI }, -}; -static const int num_drag_types = sizeof (drag_types) / sizeof (drag_types[0]); - -static gint -address_compare (gconstpointer address1, gconstpointer address2) -{ - CamelInternetAddress *ia1, *ia2; - const char *name1, *name2; - const char *addr1, *addr2; - gint retval = 0; - - ia1 = camel_internet_address_new (); - ia2 = camel_internet_address_new (); - - camel_address_decode (CAMEL_ADDRESS (ia1), (const char *) address1); - camel_address_decode (CAMEL_ADDRESS (ia2), (const char *) address2); - - if (!camel_internet_address_get (ia1, 0, &name1, &addr1)) { - camel_object_unref (CAMEL_OBJECT (ia1)); - camel_object_unref (CAMEL_OBJECT (ia2)); - return 1; - } - - if (!camel_internet_address_get (ia2, 0, &name2, &addr2)) { - camel_object_unref (CAMEL_OBJECT (ia1)); - camel_object_unref (CAMEL_OBJECT (ia2)); - return -1; - } - - if (!name1 && !name2) { - /* if neither has a name we should compare addresses */ - retval = g_strcasecmp (addr1, addr2); - } else { - if (!name1) - retval = -1; - else if (!name2) - retval = 1; - else { - ENameWestern *wname1, *wname2; - - wname1 = e_name_western_parse (name1); - wname2 = e_name_western_parse (name2); - - if (!wname1->last && !wname2->last) { - /* neither has a last name */ - retval = g_strcasecmp (name1, name2); - } else { - /* compare last names */ - if (!wname1->last) - retval = -1; - else if (!wname2->last) - retval = 1; - else { - retval = g_strcasecmp (wname1->last, wname2->last); - if (!retval) { - /* last names are identical - compare first names */ - if (!wname1->first) - retval = -1; - else if (!wname2->first) - retval = 1; - else { - retval = g_strcasecmp (wname1->first, wname2->first); - if (!retval) { - /* first names are identical - compare addresses */ - retval = g_strcasecmp (addr1, addr2); - } - } - } - } - } - - e_name_western_free (wname1); - e_name_western_free (wname2); - } - } - - camel_object_unref (CAMEL_OBJECT (ia1)); - camel_object_unref (CAMEL_OBJECT (ia2)); - - return retval; -} - -static gint -subject_compare (gconstpointer subject1, gconstpointer subject2) -{ - char *sub1; - char *sub2; - - /* trim off any "Re:"'s at the beginning of subject1 */ - sub1 = (char *) subject1; - while (!g_strncasecmp (sub1, "Re:", 3)) { - sub1 += 3; - /* jump over any spaces */ - for ( ; *sub1 && isspace (*sub1); sub1++); - } - - /* trim off any "Re:"'s at the beginning of subject2 */ - sub2 = (char *) subject2; - while (!g_strncasecmp (sub2, "Re:", 3)) { - sub2 += 3; - /* jump over any spaces */ - for ( ; *sub2 && isspace (*sub2); sub2++); - } - - /* jump over any spaces */ - for ( ; *sub1 && isspace (*sub1); sub1++); - for ( ; *sub2 && isspace (*sub2); sub2++); - - return g_strcasecmp (sub1, sub2); -} - -/* Gets the uid of the message displayed at a given view row */ -static const char * -get_message_uid (MessageList *message_list, int row) -{ - ETreeModel *model = (ETreeModel *)message_list->table_model; - ETreePath *node; - const char *uid; - - if (row >= e_table_model_row_count (message_list->table_model)) - return NULL; - - node = e_tree_model_node_at_row (model, row); - g_return_val_if_fail (node != NULL, NULL); - uid = e_tree_model_node_get_data (model, node); - - if (!id_is_uid(uid)) - return NULL; - - return id_uid(uid); -} - -/* Gets the CamelMessageInfo for the message displayed at the given - * view row. - */ -static const CamelMessageInfo * -get_message_info (MessageList *message_list, int row) -{ - const char *uid; - - uid = get_message_uid(message_list, row); - if (uid) - return camel_folder_get_message_info(message_list->folder, uid); - - return NULL; -} - -/** - * message_list_select: - * @message_list: a MessageList - * @base_row: the (model) row to start from - * @direction: the direction to search in - * @flags: a set of flag values - * @mask: a mask for comparing against @flags - * - * This moves the message list selection to a suitable row. @base_row - * lists the first (model) row to try, but as a special case, model - * row -1 is mapped to the last row. @flags and @mask combine to specify - * what constitutes a suitable row. @direction is - * %MESSAGE_LIST_SELECT_NEXT if it should find the next matching - * message, or %MESSAGE_LIST_SELECT_PREVIOUS if it should find the - * previous. If no suitable row is found, the selection will be - * unchanged but the message display will be cleared. - **/ -void -message_list_select (MessageList *message_list, int base_row, - MessageListSelectDirection direction, - guint32 flags, guint32 mask) -{ - const CamelMessageInfo *info; - int vrow, mrow, last; - ETableScrolled *ets = E_TABLE_SCROLLED (message_list->etable); - - switch (direction) { - case MESSAGE_LIST_SELECT_PREVIOUS: - last = -1; - break; - case MESSAGE_LIST_SELECT_NEXT: - last = e_table_model_row_count (message_list->table_model); - break; - default: - g_warning("Invalid argument to message_list_select"); - return; - } - - if (base_row == -1) - base_row = e_table_model_row_count(message_list->table_model) - 1; - - /* model_to_view_row etc simply dont work for sorted views. Sigh. */ - vrow = e_table_model_to_view_row (ets->table, base_row); - - /* We don't know whether to use < or > due to "direction" */ - while (vrow != last) { - mrow = e_table_view_to_model_row (ets->table, vrow); - info = get_message_info (message_list, mrow); - if (info && (info->flags & mask) == flags) { - e_table_scrolled_set_cursor_row (ets, vrow); - gtk_signal_emit(GTK_OBJECT (message_list), message_list_signals [MESSAGE_SELECTED], info->uid); - return; - } - vrow += direction; - } - - gtk_signal_emit(GTK_OBJECT (message_list), message_list_signals [MESSAGE_SELECTED], NULL); -} - -#if 0 -static void -message_list_drag_data_get (ETable *table, - int row, - int col, - GdkDragContext *context, - GtkSelectionData *selection_data, - guint info, - guint time, - gpointer user_data) -{ - MessageList *mlist = (MessageList *) user_data; - CamelMessageInfo *info = get_message_info (mlist, row); - CamelException *ex; - CamelFolder *folder; - char *dirname = "/tmp/ev-XXXXXXXXXX"; - char *filename; - char *url; - - switch (info) { - case DND_TARGET_LIST_TYPE_URI: - mktemp (dirname); - filename = g_strdup_printf ("%s.eml", info->subject); - url = g_strdup_printf ("file:%s", dirname); - - ex = camel_exception_new (); - folder = mail_tool_get_folder_from_urlname (url, filename, CAMEL_STORE_FOLDER_CREATE, ex); - if (camel_exception_is_set (ex)) { - camel_exception_free (ex); - g_free (url); - return; - } - - gtk_selection_data_set (selection_data, selection_data->target, 8, - (guchar *) url, strlen (url)); - - camel_object_unref (CAMEL_OBJECT (folder)); - g_free (filename); - g_free (url); - break; - default: - break; - } -} -#endif - -/* - * SimpleTableModel::col_count - */ -static int -ml_col_count (ETableModel *etm, void *data) -{ - return COL_LAST; -} - -static void * -ml_duplicate_value (ETableModel *etm, int col, const void *value, void *data) -{ - switch (col){ - case COL_MESSAGE_STATUS: - case COL_FLAGGED: - case COL_SCORE: - case COL_ATTACHMENT: - case COL_DELETED: - case COL_UNREAD: - case COL_SENT: - case COL_RECEIVED: - return (void *) value; - - case COL_FROM: - case COL_SUBJECT: - case COL_TO: - case COL_SIZE: - return g_strdup (value); - default: - g_assert_not_reached (); - } - return NULL; -} - -static void -ml_free_value (ETableModel *etm, int col, void *value, void *data) -{ - switch (col){ - case COL_MESSAGE_STATUS: - case COL_FLAGGED: - case COL_SCORE: - case COL_ATTACHMENT: - case COL_DELETED: - case COL_UNREAD: - case COL_SENT: - case COL_RECEIVED: - break; - - case COL_FROM: - case COL_SUBJECT: - case COL_TO: - case COL_SIZE: - g_free (value); - break; - default: - g_assert_not_reached (); - } -} - -static void * -ml_initialize_value (ETableModel *etm, int col, void *data) -{ - switch (col){ - case COL_MESSAGE_STATUS: - case COL_FLAGGED: - case COL_SCORE: - case COL_ATTACHMENT: - case COL_DELETED: - case COL_UNREAD: - case COL_SENT: - case COL_RECEIVED: - return NULL; - - case COL_FROM: - case COL_SUBJECT: - case COL_TO: - case COL_SIZE: - return g_strdup(""); - default: - g_assert_not_reached (); - } - - return NULL; -} - -static gboolean -ml_value_is_empty (ETableModel *etm, int col, const void *value, void *data) -{ - switch (col){ - case COL_MESSAGE_STATUS: - case COL_FLAGGED: - case COL_SCORE: - case COL_ATTACHMENT: - case COL_DELETED: - case COL_UNREAD: - case COL_SENT: - case COL_RECEIVED: - return value == NULL; - - case COL_FROM: - case COL_SUBJECT: - case COL_TO: - case COL_SIZE: - return !(value && *(char *)value); - default: - g_assert_not_reached (); - return FALSE; - } -} - -static char * -ml_value_to_string (ETableModel *etm, int col, const void *value, void *data) -{ - switch (col){ - case COL_MESSAGE_STATUS: - switch ((int) value) { - case 0: - return g_strdup (_("Unseen")); - break; - case 1: - return g_strdup (_("Seen")); - break; - case 2: - return g_strdup (_("Answered")); - break; - default: - return g_strdup (""); - break; - } - break; - - case COL_SCORE: - switch ((int) value) { - case -3: - return g_strdup ("Lowest"); - break; - case -2: - return g_strdup ("Lower"); - break; - case -1: - return g_strdup ("Low"); - break; - case 1: - return g_strdup ("High"); - break; - case 2: - return g_strdup ("Higher"); - break; - case 3: - return g_strdup ("Highest"); - break; - default: - return g_strdup ("Normal"); - break; - } - break; - - case COL_ATTACHMENT: - case COL_FLAGGED: - case COL_DELETED: - case COL_UNREAD: - return g_strdup_printf("%d", (int) value); - - case COL_SENT: - case COL_RECEIVED: - return filter_date (value); - - case COL_FROM: - case COL_SUBJECT: - case COL_TO: - case COL_SIZE: - return g_strdup (value); - default: - g_assert_not_reached (); - return NULL; - } -} - -static GdkPixbuf * -ml_tree_icon_at (ETreeModel *etm, ETreePath *path, void *model_data) -{ - /* we dont really need an icon ... */ - return NULL; -} - -/* return true if there are any unread messages in the subtree */ -static int -subtree_unread(MessageList *ml, ETreePath *node) -{ - const CamelMessageInfo *info; - char *uid; - - while (node) { - ETreePath *child; - uid = e_tree_model_node_get_data((ETreeModel *)ml->table_model, node); - if (id_is_uid(uid)) { - info = camel_folder_get_message_info(ml->folder, id_uid(uid)); - if (!(info->flags & CAMEL_MESSAGE_SEEN)) - return TRUE; - } - if ((child = e_tree_model_node_get_first_child (E_TREE_MODEL (ml->table_model), node))) - if (subtree_unread(ml, child)) - return TRUE; - node = e_tree_model_node_get_next (E_TREE_MODEL (ml->table_model), node); - } - return FALSE; -} - -static gboolean -content_is_attachment(CamelMessageContentInfo *ci) -{ - CamelMessageContentInfo *child; - - /* no info about content */ - if (ci == NULL) - return FALSE; - - /* we assume multipart/mixed is an attachment always - other multipart / * is only an attachment if it contains multipart/mixed's, or - non-text parts */ - if (header_content_type_is(ci->type, "multipart", "*")) { - if (header_content_type_is(ci->type, "multipart", "mixed")) { - return TRUE; - } - child = ci->childs; - while (child) { - if (content_is_attachment(child)) { - return TRUE; - } - child = child->next; - } - return FALSE; - } else { - return !header_content_type_is(ci->type, "text", "*"); - } -} - -static void * -ml_tree_value_at (ETreeModel *etm, ETreePath *path, int col, void *model_data) -{ - MessageList *message_list = model_data; - const CamelMessageInfo *msg_info; - static char buffer [10]; - char *uid; - - /* retrieve the message information array */ - uid = e_tree_model_node_get_data (etm, path); - if (!id_is_uid(uid)) - goto fake; - uid = id_uid(uid); - - msg_info = camel_folder_get_message_info (message_list->folder, uid); - if (msg_info == NULL) { - g_warning("UID for message-list not found in folder: %s", uid); - return NULL; - } - - switch (col){ - case COL_MESSAGE_STATUS: - if (msg_info->flags & CAMEL_MESSAGE_ANSWERED) - return GINT_TO_POINTER (2); - else if (msg_info->flags & CAMEL_MESSAGE_SEEN) - return GINT_TO_POINTER (1); - else - return GINT_TO_POINTER (0); - - case COL_FLAGGED: - if (msg_info->flags & CAMEL_MESSAGE_FLAGGED) - return GINT_TO_POINTER (1); - else - return GINT_TO_POINTER (0); - - case COL_SCORE: - { - const char *tag; - int score = 0; - - tag = camel_tag_get ((CamelTag **) &msg_info->user_tags, "score"); - if (tag) - score = atoi (tag); - - return GINT_TO_POINTER (score); - } - - case COL_ATTACHMENT: - if (content_is_attachment(msg_info->content)) - return (void *)1; - else - return (void *)0; - - case COL_FROM: - if (msg_info->from) - return msg_info->from; - else - return ""; - - case COL_SUBJECT: - if (msg_info->subject) - return msg_info->subject; - else - return ""; - - case COL_SENT: - return GINT_TO_POINTER (msg_info->date_sent); - - case COL_RECEIVED: - return GINT_TO_POINTER (msg_info->date_received); - - case COL_TO: - if (msg_info->to) - return msg_info->to; - else - return ""; - - case COL_SIZE: - sprintf (buffer, "%d", msg_info->size); - return buffer; - - case COL_DELETED: - if (msg_info->flags & CAMEL_MESSAGE_DELETED) - return GINT_TO_POINTER (1); - else - return GINT_TO_POINTER (0); - - case COL_UNREAD: - return GINT_TO_POINTER (!(msg_info->flags & CAMEL_MESSAGE_SEEN)); - - case COL_COLOUR: - { - const char *colour; - - colour = camel_tag_get ((CamelTag **) &msg_info->user_tags, - "colour"); - if (colour) - return (void *)colour; - else if (msg_info->flags & CAMEL_MESSAGE_FLAGGED) - /* FIXME: extract from the xpm somehow. */ - return "#A7453E"; - else - return NULL; - } - } - - g_assert_not_reached (); - - fake: - /* This is a fake tree parent */ - switch (col){ - case COL_UNREAD: - /* this value should probably be cached, as it could take a bit - of processing to evaluate all the time */ - return (void *)subtree_unread(message_list, - e_tree_model_node_get_first_child(etm, path)); - case COL_MESSAGE_STATUS: - case COL_FLAGGED: - case COL_SCORE: - case COL_ATTACHMENT: - case COL_DELETED: - case COL_COLOUR: - case COL_SENT: - case COL_RECEIVED: - return (void *) 0; - - case COL_SUBJECT: - return id_subject(uid); - - case COL_FROM: - case COL_TO: - case COL_SIZE: - return "?"; - } - g_assert_not_reached (); - - return NULL; -} - -static void -ml_tree_set_value_at (ETreeModel *etm, ETreePath *path, int col, - const void *val, void *model_data) -{ - g_assert_not_reached (); -} - -static gboolean -ml_tree_is_cell_editable (ETreeModel *etm, ETreePath *path, int col, void *model_data) -{ - return FALSE; -} - -static void -message_list_init_images (void) -{ - int i; - - /* - * Only load once, and share - */ - if (states_pixmaps [0].pixbuf) - return; - - for (i = 0; states_pixmaps [i].image_base; i++){ - states_pixmaps [i].pixbuf = gdk_pixbuf_new_from_xpm_data ( - (const char **) states_pixmaps [i].image_base); - } -} - -static char * -filter_date (const void *data) -{ - time_t date = GPOINTER_TO_INT (data); - char buf[26], *p; - - if (date == 0) - return g_strdup ("?"); - -#ifdef CTIME_R_THREE_ARGS - ctime_r (&date, buf, 26); -#else - ctime_r (&date, buf); -#endif - - p = strchr (buf, '\n'); - if (p) - *p = '\0'; - - return g_strdup (buf); -} - -static ETableExtras * -message_list_create_extras (void) -{ - int i; - GdkPixbuf *images [7]; - ETableExtras *extras; - ECell *cell; - - extras = e_table_extras_new(); - e_table_extras_add_pixbuf(extras, "status", states_pixmaps [0].pixbuf); - e_table_extras_add_pixbuf(extras, "score", states_pixmaps [11].pixbuf); - e_table_extras_add_pixbuf(extras, "attachment", states_pixmaps [4].pixbuf); - e_table_extras_add_pixbuf(extras, "flagged", states_pixmaps [5].pixbuf); - - e_table_extras_add_compare(extras, "address_compare", address_compare); - e_table_extras_add_compare(extras, "subject_compare", subject_compare); - - for (i = 0; i < 3; i++) - images [i] = states_pixmaps [i].pixbuf; - - e_table_extras_add_cell(extras, "render_message_status", e_cell_toggle_new (0, 3, images)); - - for (i = 0; i < 2; i++) - images [i] = states_pixmaps [i + 3].pixbuf; - - e_table_extras_add_cell(extras, "render_attachment", e_cell_toggle_new (0, 2, images)); - - images [1] = states_pixmaps [5].pixbuf; - e_table_extras_add_cell(extras, "render_flagged", e_cell_toggle_new (0, 2, images)); - - for (i = 0; i < 7; i++) - images[i] = states_pixmaps [i + 5].pixbuf; - - e_table_extras_add_cell(extras, "render_score", e_cell_toggle_new (0, 7, images)); - - cell = e_cell_text_new ( - NULL, GTK_JUSTIFY_LEFT); - - gtk_object_set (GTK_OBJECT (cell), - "text_filter", filter_date, - NULL); - gtk_object_set (GTK_OBJECT (cell), - "strikeout_column", COL_DELETED, - NULL); - gtk_object_set (GTK_OBJECT (cell), - "bold_column", COL_UNREAD, - NULL); - gtk_object_set (GTK_OBJECT (cell), - "color_column", COL_COLOUR, - NULL); - e_table_extras_add_cell(extras, "render_date", cell); - - cell = e_cell_text_new ( - NULL, GTK_JUSTIFY_LEFT); - - gtk_object_set (GTK_OBJECT (cell), - "strikeout_column", COL_DELETED, - NULL); - gtk_object_set (GTK_OBJECT (cell), - "bold_column", COL_UNREAD, - NULL); - gtk_object_set (GTK_OBJECT (cell), - "color_column", COL_COLOUR, - NULL); - e_table_extras_add_cell(extras, "render_text", cell); - - e_table_extras_add_cell(extras, "render_tree", - e_cell_tree_new (NULL, NULL, /* let the tree renderer default the pixmaps */ - TRUE, cell)); - - return extras; -} - -static void -save_header_state(MessageList *ml) -{ - char *filename; - - if (ml->folder == NULL - || ml->etable == NULL) - return; - - filename = mail_config_folder_to_cachename(ml->folder, "et-header-"); - e_table_scrolled_save_state(E_TABLE_SCROLLED(ml->etable), filename); - g_free(filename); -} - -static char * -message_list_get_layout (MessageList *message_list) -{ - /* Default: Status, Attachments, Priority, From, Subject, Date */ - return g_strdup ("<ETableSpecification cursor-mode=\"line\" draw-grid=\"true\">" - "<ETableColumn model_col= \"0\" pixbuf=\"status\" expansion=\"0.0\" minimum_width=\"18\" resizable=\"false\" cell=\"render_message_status\" compare=\"integer\" sortable=\"false\"/>" - "<ETableColumn model_col= \"1\" pixbuf=\"flagged\" expansion=\"0.0\" minimum_width=\"20\" resizable=\"false\" cell=\"render_flagged\" compare=\"integer\"/>" - "<ETableColumn model_col= \"2\" pixbuf=\"score\" expansion=\"0.0\" minimum_width=\"20\" resizable=\"false\" cell=\"render_score\" compare=\"integer\"/>" - "<ETableColumn model_col= \"3\" pixbuf=\"attachment\" expansion=\"0.0\" minimum_width=\"18\" resizable=\"false\" cell=\"render_attachment\" compare=\"integer\" sortable=\"false\"/>" - "<ETableColumn model_col= \"4\" _title=\"From\" expansion=\"24.0\" minimum_width=\"32\" resizable=\"true\" cell=\"render_text\" compare=\"address_compare\"/>" - "<ETableColumn model_col= \"5\" _title=\"Subject\" expansion=\"30.0\" minimum_width=\"32\" resizable=\"true\" cell=\"render_tree\" compare=\"subject_compare\"/>" - "<ETableColumn model_col= \"6\" _title=\"Date\" expansion=\"24.0\" minimum_width=\"32\" resizable=\"true\" cell=\"render_date\" compare=\"integer\"/>" - "<ETableColumn model_col= \"7\" _title=\"Received\" expansion=\"20.0\" minimum_width=\"32\" resizable=\"true\" cell=\"render_date\" compare=\"integer\"/>" - "<ETableColumn model_col= \"8\" _title=\"To\" expansion=\"24.0\" minimum_width=\"32\" resizable=\"true\" cell=\"render_text\" compare=\"address_compare\"/>" - "<ETableColumn model_col= \"9\" _title=\"Size\" expansion=\"6.0\" minimum_width=\"32\" resizable=\"true\" cell=\"render_text\" compare=\"string\"/>" - "<ETableState> <column source=\"0\"/> <column source=\"3\"/> <column source=\"1\"/>" - "<column source=\"4\"/> <column source=\"5\"/> <column source=\"6\"/>" - "<grouping> </grouping> </ETableState>" - "</ETableSpecification>"); -} - -static void -message_list_setup_etable(MessageList *message_list) -{ - /* build the spec based on the folder, and possibly from a saved file */ - /* otherwise, leave default */ - if (message_list->folder) { - char *path; - char *name; - struct stat st; - - name = camel_service_get_name (CAMEL_SERVICE (message_list->folder->parent_store), TRUE); - printf ("folder name is '%s'\n", name); - path = mail_config_folder_to_cachename (message_list->folder, "et-header-"); - - if (path && stat (path, &st) == 0 && st.st_size > 0 && S_ISREG (st.st_mode)) { - /* build based on saved file */ - e_table_scrolled_load_state (E_TABLE_SCROLLED (message_list->etable), path); - } else if (strstr (name, "/Drafts") || strstr (name, "/Outbox") || strstr (name, "/Sent")) { - /* these folders have special defaults */ - char *state = "<ETableState>" - "<column source=\"0\"/> <column source=\"1\"/> " - "<column source=\"8\"/> <column source=\"5\"/> " - "<column source=\"6\"/> <grouping> </grouping> </ETableState>"; - - e_table_scrolled_set_state (E_TABLE_SCROLLED (message_list->etable), state); - } - - g_free (path); - g_free (name); - } -} - -/* - * GtkObject::init - */ -static void -message_list_init (GtkObject *object) -{ - ETableExtras *extras; - MessageList *message_list = MESSAGE_LIST (object); - char *spec; - - message_list->table_model = (ETableModel *) - e_tree_simple_new (ml_col_count, - ml_duplicate_value, - ml_free_value, - ml_initialize_value, - ml_value_is_empty, - ml_value_to_string, - ml_tree_icon_at, ml_tree_value_at, - ml_tree_set_value_at, - ml_tree_is_cell_editable, - message_list); - e_tree_model_root_node_set_visible ((ETreeModel *)message_list->table_model, FALSE); - gtk_signal_connect (GTK_OBJECT (message_list->table_model), "destroy", - (GtkSignalFunc) free_tree_ids, NULL); - - /* - * The etable - */ - - spec = message_list_get_layout (message_list); - extras = message_list_create_extras(); - message_list->etable = e_table_scrolled_new (message_list->table_model, extras, spec, NULL); - g_free (spec); - gtk_object_sink(GTK_OBJECT(extras)); - - e_scroll_frame_set_policy (E_SCROLL_FRAME (message_list->etable), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); - - gtk_object_set(GTK_OBJECT(message_list->etable), - "drawfocus", FALSE, - NULL); - - /* - *gtk_signal_connect (GTK_OBJECT (message_list->etable), "realize", - * GTK_SIGNAL_FUNC (select_row), message_list); - */ - - gtk_signal_connect (GTK_OBJECT (message_list->etable), "cursor_change", - GTK_SIGNAL_FUNC (on_cursor_change_cmd), message_list); - - gtk_signal_connect (GTK_OBJECT (message_list->etable), "click", - GTK_SIGNAL_FUNC (on_click), message_list); - -#if 0 - /* drag & drop */ - e_table_drag_source_set (message_list->etable, GDK_BUTTON1_MASK, - drag_types, num_drag_types, GDK_ACTION_MOVE); - - gtk_signal_connect (GTK_OBJECT (message_list->etable), "drag_data_get", - GTK_SIGNAL_FUNC (message_list_drag_data_get), message_list); -#endif - - gtk_widget_show (message_list->etable); - - gtk_object_ref (GTK_OBJECT (message_list->table_model)); - gtk_object_sink (GTK_OBJECT (message_list->table_model)); - - /* - * We do own the Etable, not some widget container - */ - gtk_object_ref (GTK_OBJECT (message_list->etable)); - gtk_object_sink (GTK_OBJECT (message_list->etable)); - - message_list->uid_rowmap = g_hash_table_new (g_str_hash, g_str_equal); -} - -static void -message_list_destroy (GtkObject *object) -{ - MessageList *message_list = MESSAGE_LIST (object); - - if (message_list->folder) { - save_tree_state(message_list); - save_header_state(message_list); - } - - gtk_object_unref (GTK_OBJECT (message_list->table_model)); - gtk_object_unref (GTK_OBJECT (message_list->etable)); - - g_hash_table_destroy (message_list->uid_rowmap); - - if (message_list->idle_id != 0) - g_source_remove(message_list->idle_id); - - if (message_list->seen_id) - gtk_timeout_remove (message_list->seen_id); - - if (message_list->folder) - camel_object_unref (CAMEL_OBJECT (message_list->folder)); - - GTK_OBJECT_CLASS (message_list_parent_class)->destroy (object); -} - -/* - * CORBA method: Evolution::MessageList::select_message - */ -static void -MessageList_select_message (PortableServer_Servant _servant, - const CORBA_long message_number, - CORBA_Environment *ev) -{ - printf ("FIXME: select message method\n"); -} - -/* - * CORBA method: Evolution::MessageList::open_message - */ -static void -MessageList_open_message (PortableServer_Servant _servant, - const CORBA_long message_number, - CORBA_Environment *ev) -{ - printf ("FIXME: open message method\n"); -} - -static POA_Evolution_MessageList__epv * -evolution_message_list_get_epv (void) -{ - POA_Evolution_MessageList__epv *epv; - - epv = g_new0 (POA_Evolution_MessageList__epv, 1); - - epv->select_message = MessageList_select_message; - epv->open_message = MessageList_open_message; - - return epv; -} - -static void -message_list_corba_class_init (void) -{ - evolution_message_list_vepv.Bonobo_Unknown_epv = bonobo_object_get_epv (); - evolution_message_list_vepv.Evolution_MessageList_epv = evolution_message_list_get_epv (); -} - -/* - * GtkObjectClass::init - */ -static void -message_list_class_init (GtkObjectClass *object_class) -{ - message_list_parent_class = gtk_type_class (PARENT_TYPE); - - object_class->destroy = message_list_destroy; - - message_list_corba_class_init (); - - message_list_signals[MESSAGE_SELECTED] = - gtk_signal_new ("message_selected", - GTK_RUN_LAST, - object_class->type, - GTK_SIGNAL_OFFSET (MessageListClass, message_selected), - gtk_marshal_NONE__STRING, - GTK_TYPE_NONE, 1, GTK_TYPE_STRING); - - gtk_object_class_add_signals(object_class, message_list_signals, LAST_SIGNAL); - - message_list_init_images (); -} - -static void -message_list_construct (MessageList *message_list, Evolution_MessageList corba_message_list) -{ - bonobo_object_construct (BONOBO_OBJECT (message_list), corba_message_list); -} - -static Evolution_MessageList -create_corba_message_list (BonoboObject *object) -{ - POA_Evolution_MessageList *servant; - CORBA_Environment ev; - - servant = (POA_Evolution_MessageList *) g_new0 (BonoboObjectServant, 1); - servant->vepv = &evolution_message_list_vepv; - - CORBA_exception_init (&ev); - POA_Evolution_MessageList__init ((PortableServer_Servant) servant, &ev); - if (ev._major != CORBA_NO_EXCEPTION){ - g_free (servant); - CORBA_exception_free (&ev); - return CORBA_OBJECT_NIL; - } - - CORBA_exception_free (&ev); - return (Evolution_MessageList) bonobo_object_activate_servant (object, servant); -} - -BonoboObject * -message_list_new (void) -{ - Evolution_MessageList corba_object; - MessageList *message_list; - - message_list = gtk_type_new (message_list_get_type ()); - - corba_object = create_corba_message_list (BONOBO_OBJECT (message_list)); - if (corba_object == CORBA_OBJECT_NIL){ - gtk_object_destroy (GTK_OBJECT (message_list)); - return NULL; - } - - message_list->idle_id = 0; - - message_list_construct (message_list, corba_object); - - return BONOBO_OBJECT (message_list); -} - -static void -clear_tree (MessageList *ml) -{ - ETreeModel *etm = E_TREE_MODEL (ml->table_model); - -#ifdef TIMEIT - struct timeval start, end; - unsigned long diff; - - printf("Clearing tree\n"); - gettimeofday(&start, NULL); -#endif - - /* we also reset the uid_rowmap since it is no longer useful/valid anyway */ - g_hash_table_destroy (ml->uid_rowmap); - ml->uid_rowmap = g_hash_table_new(g_str_hash, g_str_equal); - free_tree_ids(etm); - - if (ml->tree_root) { - e_table_model_pre_change((ETableModel *)etm); - e_tree_model_node_remove (etm, ml->tree_root); - } - - ml->tree_root = e_tree_model_node_insert (etm, NULL, 0, NULL); - e_tree_model_node_set_expanded (etm, ml->tree_root, TRUE); - -#ifdef TIMEIT - gettimeofday(&end, NULL); - diff = end.tv_sec * 1000 + end.tv_usec/1000; - diff -= start.tv_sec * 1000 + start.tv_usec/1000; - printf("Clearing tree took %ld.%03ld seconds\n", diff / 1000, diff % 1000); -#endif - -} - -/* we save the node id to the file if the node should be closed when - we start up. We only save nodeid's for messages with children */ -static void -save_node_state(MessageList *ml, FILE *out, ETreePath *node) -{ - char *data; - const CamelMessageInfo *info; - - while (node) { - ETreePath *child = e_tree_model_node_get_first_child (E_TREE_MODEL (ml->table_model), node); - if (child - && !e_tree_model_node_is_expanded((ETreeModel *)ml->table_model, node)) { - data = e_tree_model_node_get_data((ETreeModel *)ml->table_model, node); - if (data) { - if (id_is_uid(data)) { - info = camel_folder_get_message_info(ml->folder, id_uid(data)); - if (info) { - fprintf(out, "%s\n", info->message_id); - } - } else { - fprintf(out, "%s\n", data); - } - } - } - if (child) { - save_node_state(ml, out, child); - } - node = e_tree_model_node_get_next (E_TREE_MODEL (ml->table_model), node); - } -} - -static GHashTable * -load_tree_state(MessageList *ml) -{ - char *filename, linebuf[10240]; - GHashTable *result; - FILE *in; - int len; - - result = g_hash_table_new(g_str_hash, g_str_equal); - filename = mail_config_folder_to_cachename(ml->folder, "treestate-"); - in = fopen(filename, "r"); - if (in) { - while (fgets(linebuf, sizeof(linebuf), in) != NULL) { - len = strlen(linebuf); - if (len) { - linebuf[len-1] = 0; - g_hash_table_insert(result, g_strdup(linebuf), (void *)1); - } - } - fclose(in); - } - g_free(filename); - return result; -} - -/* save tree info */ -static void -save_tree_state(MessageList *ml) -{ - char *filename; - ETreePath *node; - ETreePath *child; - FILE *out; - - filename = mail_config_folder_to_cachename(ml->folder, "treestate-"); - out = fopen(filename, "w"); - if (out) { - node = e_tree_model_get_root((ETreeModel *)ml->table_model); - child = e_tree_model_node_get_first_child ((ETreeModel *)ml->table_model, node); - if (node && child) { - save_node_state(ml, out, child); - } - fclose(out); - } - g_free(filename); -} - -static void -free_node_state(void *key, void *value, void *data) -{ - g_free(key); -} - -static void -free_tree_state(GHashTable *expanded_nodes) -{ - g_hash_table_foreach(expanded_nodes, free_node_state, 0); - g_hash_table_destroy(expanded_nodes); -} - -/* only call if we have a tree model */ -/* builds the tree structure */ -static void build_subtree (MessageList *ml, ETreePath *parent, struct _container *c, int *row, GHashTable *); - -static void build_subtree_diff (MessageList *ml, ETreePath *parent, ETreePath *path, struct _container *c, int *row, GHashTable *expanded_nodes); - -static void -build_tree (MessageList *ml, struct _thread_messages *thread) -{ - int row = 0; - GHashTable *expanded_nodes; - ETreeModel *etm = (ETreeModel *)ml->table_model; - ETreePath *top; - -#ifdef TIMEIT - struct timeval start, end; - unsigned long diff; - - printf("Building tree\n"); - gettimeofday(&start, NULL); -#endif - expanded_nodes = load_tree_state(ml); - -#ifdef TIMEIT - gettimeofday(&end, NULL); - diff = end.tv_sec * 1000 + end.tv_usec/1000; - diff -= start.tv_sec * 1000 + start.tv_usec/1000; - printf("Loading tree state took %ld.%03ld seconds\n", diff / 1000, diff % 1000); -#endif - - if (ml->tree_root == NULL) { - ml->tree_root = e_tree_model_node_insert(etm, NULL, 0, NULL); - e_tree_model_node_set_expanded(etm, ml->tree_root, TRUE); - } - - top = e_tree_model_node_get_first_child(etm, ml->tree_root); - if (top == NULL) { - e_table_model_pre_change(ml->table_model); - build_subtree(ml, ml->tree_root, thread->tree, &row, expanded_nodes); - e_table_model_changed(ml->table_model); - } else { - build_subtree_diff(ml, ml->tree_root, top, thread->tree, &row, expanded_nodes); - } - - free_tree_state(expanded_nodes); - -#ifdef TIMEIT - gettimeofday(&end, NULL); - diff = end.tv_sec * 1000 + end.tv_usec/1000; - diff -= start.tv_sec * 1000 + start.tv_usec/1000; - printf("Building tree took %ld.%03ld seconds\n", diff / 1000, diff % 1000); -#endif - -} - -static char * -new_id_from_uid(const char *uid) -{ - char *res; - int len; - - len = strlen(uid)+2; - res = g_malloc(len); - res[0] = 'u'; - strcpy(res+1, uid); - return res; -} - -static char * -new_id_from_subject(const char *subject) -{ - char *res; - int len; - - len = strlen(subject)+2; - res = g_malloc(len); - res[0] = 's'; - strcpy(res+1, subject); - return res; -} - -/* this is about 20% faster than build_subtree_diff, - entirely because e_tree_model_node_insert(xx, -1 xx) - is faster than inserting to the right row :( */ -/* Otherwise, this code would probably go as it does the same thing essentially */ -static void -build_subtree (MessageList *ml, ETreePath *parent, struct _container *c, int *row, GHashTable *expanded_nodes) -{ - ETreeModel *tree = E_TREE_MODEL (ml->table_model); - ETreePath *node; - char *id; - int expanded = FALSE; - - while (c) { - if (c->message) { - id = new_id_from_uid(c->message->uid); - g_hash_table_insert(ml->uid_rowmap, id_uid(id), GINT_TO_POINTER ((*row)++)); - if (c->child) { - if (c->message && c->message->message_id) - expanded = !g_hash_table_lookup(expanded_nodes, c->message->message_id) != 0; - else - expanded = TRUE; - } - } else { - id = new_id_from_subject(c->root_subject); - if (c->child) { - expanded = !g_hash_table_lookup(expanded_nodes, id) != 0; - } - } - node = e_tree_model_node_insert(tree, parent, -1, id); - if (c->child) { - /* by default, open all trees */ - if (expanded) - e_tree_model_node_set_expanded(tree, node, expanded); - build_subtree(ml, node, c->child, row, expanded_nodes); - } - c = c->next; - } -} - -/* compares a thread tree node with the etable tree node to see if they point to - the same object */ -static int -node_equal(ETreeModel *etm, ETreePath *ap, struct _container *bp) -{ - char *uid; - - uid = e_tree_model_node_get_data(etm, ap); - - if (id_is_uid(uid)) { - if (bp->message && strcmp(id_uid(uid), bp->message->uid)==0) - return 1; - } else if (id_is_subject(uid)) { - if (bp->message == NULL && strcmp(id_subject(uid), bp->root_subject) == 0) - return 1; - } - return 0; -} - -/* adds a single node, retains save state, and handles adding children if required */ -static void -add_node_diff(MessageList *ml, ETreePath *parent, ETreePath *path, struct _container *c, int *row, int myrow, GHashTable *expanded_nodes) -{ - ETreeModel *etm = E_TREE_MODEL (ml->table_model); - ETreePath *node; - char *id; - int expanded = FALSE; - - if (c->message) { - id = new_id_from_uid(c->message->uid); - /* need to remove the id first, as GHashTable' wont replace the key pointer for us */ - g_hash_table_remove(ml->uid_rowmap, id_uid(id)); - g_hash_table_insert(ml->uid_rowmap, id_uid(id), GINT_TO_POINTER (*row)); - if (c->child) { - if (c->message && c->message->message_id) - expanded = !g_hash_table_lookup(expanded_nodes, c->message->message_id) != 0; - else - expanded = TRUE; - } - } else { - id = new_id_from_subject(c->root_subject); - if (c->child) { - expanded = !g_hash_table_lookup(expanded_nodes, id) != 0; - } - } - - t(printf("Adding node: %s row %d\n", id, myrow)); - - node = e_tree_model_node_insert(etm, parent, myrow, id); - (*row)++; - if (c->child) { - e_tree_model_node_set_expanded(etm, node, expanded); - t(printf("Building subtree ...\n")); - build_subtree_diff(ml, node, NULL, c->child, row, expanded_nodes); - } -} - -/* removes node, children recursively and all associated data */ -static void -remove_node_diff(MessageList *ml, ETreePath *node, int depth) -{ - ETreeModel *etm = E_TREE_MODEL (ml->table_model); - ETreePath *cp, *cn; - char *uid, *olduid; - int oldrow; - - t(printf("Removing node: %s\n", (char *)e_tree_model_node_get_data(etm, node))); - - /* we depth-first remove all node data's ... */ - cp = e_tree_model_node_get_first_child(etm, node); - while (cp) { - cn = e_tree_model_node_get_next(etm, cp); - remove_node_diff(ml, cp, depth+1); - cp = cn; - } - - /* and the rowid entry - if and only if it is referencing this node */ - uid = e_tree_model_node_get_data(etm, node); - if (id_is_uid(uid) - && g_hash_table_lookup_extended(ml->uid_rowmap, id_uid(uid), (void *)&olduid, (void *)&oldrow) - && olduid == id_uid(uid)) { - t(printf("removing rowid map entry: %s\n", id_uid(uid))); - g_hash_table_remove(ml->uid_rowmap, id_uid(uid)); - } - g_free(uid); - e_tree_model_node_set_data(etm, node, NULL); - - /* and only at the toplevel, remove the node (etree should optimise this remove somewhat) */ - if (depth == 0) - e_tree_model_node_remove(etm, node); -} - -/* applies a new tree structure to an existing tree, but only by changing things - that have changed */ -static void -build_subtree_diff(MessageList *ml, ETreePath *parent, ETreePath *path, struct _container *c, int *row, GHashTable *expanded_nodes) -{ - ETreeModel *etm = E_TREE_MODEL (ml->table_model); - ETreePath *ap, *ai, *at, *tmp; - struct _container *bp, *bi, *bt; - int i, j, myrow = 0; - - ap = path; - bp = c; - - while (ap || bp) { - t(printf("Processing row: %d (subtree row %d)\n", *row, myrow)); - if (ap == NULL) { - t(printf("out of old nodes\n")); - /* ran out of old nodes - remaining nodes are added */ - add_node_diff(ml, parent, ap, bp, row, myrow, expanded_nodes); - myrow++; - bp = bp->next; - } else if (bp == NULL) { - t(printf("out of new nodes\n")); - /* ran out of new nodes - remaining nodes are removed */ - tmp = e_tree_model_node_get_next(etm, ap); - remove_node_diff(ml, ap, 0); - ap = tmp; - } else if (node_equal(etm, ap, bp)) { - /*t(printf("nodes match, verify\n"));*/ - /* matching nodes, verify details/children */ - if (bp->message) { - char *olduid; - int oldrow; - - /* if this is a message row, check/update the row id map */ - if (g_hash_table_lookup_extended(ml->uid_rowmap, bp->message->uid, (void *)&olduid, (void *)&oldrow)) { - if (oldrow != (*row)) { - g_hash_table_insert(ml->uid_rowmap, olduid, (void *)(*row)); - } - } else { - g_warning("Cannot find uid %s in table?", bp->message->uid); - /*g_assert_not_reached();*/ - } - } - *row = (*row)+1; - myrow++; - tmp = e_tree_model_node_get_first_child(etm, ap); - /* make child lists match (if either has one) */ - if (bp->child || tmp) { - build_subtree_diff(ml, ap, tmp, bp->child, row, expanded_nodes); - } - ap = e_tree_model_node_get_next(etm, ap); - bp = bp->next; - } else { - t(printf("searching for matches\n")); - /* we have to scan each side for a match */ - bi = bp->next; - ai = e_tree_model_node_get_next(etm, ap); - for (i=1;bi!=NULL;i++,bi=bi->next) { - if (node_equal(etm, ap, bi)) - break; - } - for (j=1;ai!=NULL;j++,ai=e_tree_model_node_get_next(etm, ai)) { - if (node_equal(etm, ai, bp)) - break; - } - if (i<j) { - /* smaller run of new nodes - must be nodes to add */ - if (bi) { - bt = bp; - while (bt != bi) { - t(printf("adding new node 0\n")); - add_node_diff(ml, parent, NULL, bt, row, myrow, expanded_nodes); - myrow++; - bt = bt->next; - } - bp = bi; - } else { - t(printf("adding new node 1\n")); - /* no match in new nodes, add one, try next */ - add_node_diff(ml, parent, NULL, bp, row, myrow, expanded_nodes); - myrow++; - bp = bp->next; - } - } else { - /* bigger run of old nodes - must be nodes to remove */ - if (ai) { - at = ap; - while (at != ai) { - t(printf("removing old node 0\n")); - tmp = e_tree_model_node_get_next(etm, at); - remove_node_diff(ml, at, 0); - at = tmp; - } - ap = ai; - } else { - t(printf("adding new node 2\n")); - /* didn't find match in old nodes, must be new node? */ - add_node_diff(ml, parent, NULL, bp, row, myrow, expanded_nodes); - myrow++; - bp = bp->next; -#if 0 - tmp = e_tree_model_node_get_next(etm, ap); - remove_node_diff(etm, ap, 0); - ap = tmp; -#endif - } - } - } - } -} - -static gboolean -free_ids_cb (ETreeModel *model, ETreePath *node, gpointer data) -{ - g_free (e_tree_model_node_get_data (model, node)); - return FALSE; -} - -static void -free_tree_ids (ETreeModel *etm) -{ - ETreePath *root = e_tree_model_get_root (etm); - - if (root) - e_tree_model_node_traverse(etm, root, free_ids_cb, NULL); -} - -static void build_flat_diff(MessageList *ml, CamelFolderChangeInfo *changes); - -static void -build_flat (MessageList *ml, GPtrArray *uids, CamelFolderChangeInfo *changes) -{ - ETreeModel *tree = E_TREE_MODEL (ml->table_model); - ETreePath *node; - char *uid; - int i; - -#ifdef TIMEIT - struct timeval start, end; - unsigned long diff; - - printf("Building flat\n"); - gettimeofday(&start, NULL); -#endif - - if (changes) { - build_flat_diff(ml, changes); - } else { - e_table_model_pre_change(ml->table_model); - clear_tree (ml); - for (i = 0; i < uids->len; i++) { - uid = new_id_from_uid(uids->pdata[i]); - node = e_tree_model_node_insert (tree, ml->tree_root, -1, uid); - g_hash_table_insert (ml->uid_rowmap, id_uid(uid), GINT_TO_POINTER (i)); - } - e_table_model_changed(ml->table_model); - } - -#ifdef TIMEIT - gettimeofday(&end, NULL); - diff = end.tv_sec * 1000 + end.tv_usec/1000; - diff -= start.tv_sec * 1000 + start.tv_usec/1000; - printf("Building flat took %ld.%03ld seconds\n", diff / 1000, diff % 1000); -#endif - -} - -/* used to sort the rows to match list order */ -struct _uidsort { - int row; - char *uid; -}; - -static int -sort_uid_cmp(const void *ap, const void *bp) -{ - const struct _uidsort *a = (struct _uidsort *)ap; - const struct _uidsort *b = (struct _uidsort *)bp; - - if (a->row < b->row) - return -1; - else if (a->row > b->row) - return 1; - return 0; -} - -static void -sort_uid_to_rows(MessageList *ml, GPtrArray *uids) -{ - struct _uidsort *uidlist; - int i; - - uidlist = g_malloc(sizeof(struct _uidsort) * uids->len); - for (i=0;i<uids->len;i++) { - uidlist[i].row = (int)g_hash_table_lookup(ml->uid_rowmap, uids->pdata[i]); - uidlist[i].uid = uids->pdata[i]; - } - qsort(uidlist, uids->len, sizeof(struct _uidsort), sort_uid_cmp); - for (i=0;i<uids->len;i++) { - uids->pdata[i] = uidlist[i].uid; - } - g_free(uidlist); -} - -static void -build_flat_diff(MessageList *ml, CamelFolderChangeInfo *changes) -{ - int row, i; - ETreePath *node; - char *uid; - int oldrow; - char *olduid; - -#ifdef TIMEIT - struct timeval start, end; - unsigned long diff; - - gettimeofday(&start, NULL); -#endif - - printf("updating changes to display\n"); - - /* remove individual nodes? */ - if (changes->uid_removed->len > 0) { - /* first, we need to sort the row id's to match the summary order */ - sort_uid_to_rows(ml, changes->uid_removed); - - /* we remove from the end, so that the rowmap remains valid as we go */ - d(printf("Removing messages from view:\n")); - for (i=changes->uid_removed->len-1;i>=0;i--) { - d(printf(" %s\n", (char *)changes->uid_removed->pdata[i])); - if (g_hash_table_lookup_extended(ml->uid_rowmap, changes->uid_removed->pdata[i], (void *)&olduid, (void *)&row)) { - node = e_tree_model_node_at_row((ETreeModel *)ml->table_model, row); - uid = e_tree_model_node_get_data((ETreeModel *)ml->table_model, node); - if (uid && id_is_uid(uid) && !strcmp(id_uid(uid), changes->uid_removed->pdata[i])) { - g_hash_table_remove(ml->uid_rowmap, olduid); - e_tree_model_node_remove((ETreeModel *)ml->table_model, node); - g_free(uid); - d(printf(" - removed\n")); - } else { - d(printf(" - is this the right uid, it doesn't match my map?\n")); - } - } - } - } - - /* add new nodes? - just append to the end */ - if (changes->uid_added->len > 0) { - node = e_tree_model_node_get_last_child((ETreeModel *)ml->table_model, ml->tree_root); - row = e_tree_model_row_of_node((ETreeModel *)ml->table_model, node) + 1; - d(printf("Adding messages to view:\n")); - for (i=0;i<changes->uid_added->len;i++) { - d(printf(" %s\n", (char *)changes->uid_added->pdata[i])); - uid = new_id_from_uid(changes->uid_added->pdata[i]); - node = e_tree_model_node_insert((ETreeModel *)ml->table_model, ml->tree_root, row, uid); - g_hash_table_insert(ml->uid_rowmap, id_uid(uid), GINT_TO_POINTER (row)); - row++; - } - } - - /* now, check the rowmap, some rows might've changed (with removes) */ - if (changes->uid_removed->len) { - d(printf("checking uid mappings\n")); - row = 0; - node = e_tree_model_node_get_first_child ((ETreeModel *)ml->table_model, ml->tree_root); - while (node) { - uid = e_tree_model_node_get_data((ETreeModel *)ml->table_model, node); - if (id_is_uid(uid)) { - if (g_hash_table_lookup_extended(ml->uid_rowmap, id_uid(uid), (void *)&olduid, (void *)&oldrow)) { - if (oldrow != row) { - d(printf("row %d moved to new row %d\n", oldrow, row)); - g_hash_table_insert(ml->uid_rowmap, olduid, (void *)row); - } - } else { /* missing? shouldn't happen */ - g_warning("Uid vanished from rowmap?: %s\n", uid); - } - } - row++; - node = e_tree_model_node_get_next((ETreeModel *)ml->table_model, node); - } - } - -#ifdef TIMEIT - gettimeofday(&end, NULL); - diff = end.tv_sec * 1000 + end.tv_usec/1000; - diff -= start.tv_sec * 1000 + start.tv_usec/1000; - printf("Inserting changes took %ld.%03ld seconds\n", diff / 1000, diff % 1000); -#endif - -} - -static void -main_folder_changed (CamelObject *o, gpointer event_data, gpointer user_data) -{ - MessageList *ml = MESSAGE_LIST (user_data); - CamelFolderChangeInfo *changes = (CamelFolderChangeInfo *)event_data; - - printf("folder changed event, changes = %p\n", changes); - - mail_do_regenerate_messagelist(ml, ml->search, changes); -} - -static void -folder_changed (CamelObject *o, gpointer event_data, gpointer user_data) -{ - /* similarly to message_changed, copy the change list and propagate it to - the main thread and free it */ - CamelFolderChangeInfo *changes; - - if (event_data) { - changes = camel_folder_change_info_new(); - camel_folder_change_info_cat(changes, (CamelFolderChangeInfo *)event_data); - } else { - changes = NULL; - } - mail_op_forward_event (main_folder_changed, o, changes, user_data); -} - -static void -main_message_changed (CamelObject *o, gpointer uid, gpointer user_data) -{ - MessageList *message_list = MESSAGE_LIST (user_data); - int row; - - row = GPOINTER_TO_INT (g_hash_table_lookup (message_list->uid_rowmap, - uid)); - if (row != -1) - e_table_model_row_changed (message_list->table_model, row); - - g_free (uid); -} - -static void -message_changed (CamelObject *o, gpointer event_data, gpointer user_data) -{ - /* Here we copy the data because our thread may free the copy that we would reference. - * The other thread would be passed a uid parameter that pointed to freed data. - * We copy it and free it in the handler. - */ - mail_op_forward_event (main_message_changed, o, g_strdup ((gchar *)event_data), user_data); -} - -void -message_list_set_folder (MessageList *message_list, CamelFolder *camel_folder) -{ - CamelException ex; - - g_return_if_fail (message_list != NULL); - g_return_if_fail (camel_folder != NULL); - g_return_if_fail (IS_MESSAGE_LIST (message_list)); - g_return_if_fail (CAMEL_IS_FOLDER (camel_folder)); - g_return_if_fail (camel_folder_has_summary_capability (camel_folder)); - - if (message_list->folder == camel_folder) - return; - - camel_exception_init (&ex); - - if (message_list->folder) - camel_object_unref (CAMEL_OBJECT (message_list->folder)); - - message_list->folder = camel_folder; - - /* build the etable suitable for this folder */ - message_list_setup_etable(message_list); - - camel_object_hook_event(CAMEL_OBJECT (camel_folder), "folder_changed", - folder_changed, message_list); - camel_object_hook_event(CAMEL_OBJECT (camel_folder), "message_changed", - message_changed, message_list); - - camel_object_ref (CAMEL_OBJECT (camel_folder)); - - clear_tree(message_list); - mail_do_regenerate_messagelist (message_list, message_list->search, NULL); -} - -GtkWidget * -message_list_get_widget (MessageList *message_list) -{ - return message_list->etable; -} - -E_MAKE_TYPE (message_list, "MessageList", MessageList, message_list_class_init, message_list_init, PARENT_TYPE); - -static gboolean -on_cursor_change_idle (gpointer data) -{ - MessageList *message_list = data; - - printf("emitting cursor changed signal, for uid %s\n", message_list->cursor_uid); - gtk_signal_emit(GTK_OBJECT (message_list), message_list_signals [MESSAGE_SELECTED], message_list->cursor_uid); - - message_list->idle_id = 0; - return FALSE; -} - -static void -on_cursor_change_cmd (ETableScrolled *table, int row, gpointer user_data) -{ - MessageList *message_list; - - message_list = MESSAGE_LIST (user_data); - - message_list->cursor_row = row; - message_list->cursor_uid = get_message_uid (message_list, row); - - if (!message_list->idle_id) { - message_list->idle_id = - g_idle_add_full (G_PRIORITY_LOW, on_cursor_change_idle, - message_list, NULL); - } -} - -static gint -on_click (ETableScrolled *table, gint row, gint col, GdkEvent *event, MessageList *list) -{ - int flag; - const CamelMessageInfo *info; - - if (col == COL_MESSAGE_STATUS) - flag = CAMEL_MESSAGE_SEEN; - else if (col == COL_FLAGGED) - flag = CAMEL_MESSAGE_FLAGGED; - else - return FALSE; - - mail_tool_camel_lock_up(); - - info = get_message_info(list, row); - if (info == NULL) { - mail_tool_camel_lock_down(); - return FALSE; - } - - camel_folder_set_message_flags(list->folder, info->uid, flag, ~info->flags); - - mail_tool_camel_lock_down(); - - if (flag == CAMEL_MESSAGE_SEEN && list->seen_id) { - gtk_timeout_remove (list->seen_id); - list->seen_id = 0; - } - - return TRUE; -} - -struct message_list_foreach_data { - MessageList *message_list; - MessageListForeachFunc callback; - gpointer user_data; -}; - -static void -mlfe_callback (int row, gpointer user_data) -{ - struct message_list_foreach_data *mlfe_data = user_data; - const char *uid; - - uid = get_message_uid (mlfe_data->message_list, row); - if (uid) { - mlfe_data->callback (mlfe_data->message_list, - uid, - mlfe_data->user_data); - } -} - -void -message_list_foreach (MessageList *message_list, - MessageListForeachFunc callback, - gpointer user_data) -{ - struct message_list_foreach_data mlfe_data; - - mlfe_data.message_list = message_list; - mlfe_data.callback = callback; - mlfe_data.user_data = user_data; - e_table_scrolled_selected_row_foreach (E_TABLE_SCROLLED (message_list->etable), - mlfe_callback, &mlfe_data); -} - -/* set whether we are in threaded view or flat view */ -void -message_list_set_threaded(MessageList *ml, gboolean threaded) -{ - if (ml->threaded ^ threaded) { - ml->threaded = threaded; - - clear_tree(ml); - mail_do_regenerate_messagelist(ml, ml->search, NULL); - } -} - -void -message_list_set_search(MessageList *ml, const char *search) -{ - if (search == NULL || search[0] == '\0') - if (ml->search == NULL || ml->search[0]=='\0') - return; - - if (search != NULL && ml->search !=NULL && strcmp(search, ml->search)==0) - return; - - clear_tree(ml); - mail_do_regenerate_messagelist(ml, search, NULL); -} - -/* ** REGENERATE MESSAGELIST ********************************************** */ - -typedef struct regenerate_messagelist_input_s { - MessageList *ml; - CamelFolder *folder; - char *search; - CamelFolderChangeInfo *changes; - gboolean dotree; /* we are building a tree */ -} regenerate_messagelist_input_t; - -typedef struct regenerate_messagelist_data_s { - GPtrArray *uids; - struct _thread_messages *tree; - CamelFolderChangeInfo *changes; -} regenerate_messagelist_data_t; - -static gchar *describe_regenerate_messagelist (gpointer in_data, gboolean gerund); -static void setup_regenerate_messagelist (gpointer in_data, gpointer op_data, CamelException *ex); -static void do_regenerate_messagelist (gpointer in_data, gpointer op_data, CamelException *ex); -static void cleanup_regenerate_messagelist (gpointer in_data, gpointer op_data, CamelException *ex); - -static gchar *describe_regenerate_messagelist (gpointer in_data, gboolean gerund) -{ - if (gerund) - return g_strdup (_("Rebuilding message view")); - else - return g_strdup (_("Rebuild message view")); -} - -static void setup_regenerate_messagelist (gpointer in_data, gpointer op_data, CamelException *ex) -{ - regenerate_messagelist_input_t *input = (regenerate_messagelist_input_t *) in_data; - - if (!IS_MESSAGE_LIST (input->ml)) { - camel_exception_set (ex, CAMEL_EXCEPTION_INVALID_PARAM, - "No messagelist specified to regenerate"); - return; - } - - gtk_object_ref (GTK_OBJECT (input->ml)); -} - -static void do_regenerate_messagelist (gpointer in_data, gpointer op_data, CamelException *ex) -{ - regenerate_messagelist_input_t *input = (regenerate_messagelist_input_t *) in_data; - regenerate_messagelist_data_t *data = (regenerate_messagelist_data_t *) op_data; - - mail_tool_camel_lock_up(); - - if (input->search) { - data->uids = camel_folder_search_by_expression(input->ml->folder, input->search, ex); - } else { - data->uids = camel_folder_get_uids (input->ml->folder); - } - - if (camel_exception_is_set (ex)) { - mail_tool_camel_lock_down(); - return; - } - - if (input->dotree && data->uids) - data->tree = thread_messages(input->ml->folder, data->uids); - else - data->tree = NULL; - - mail_tool_camel_lock_down(); -} - -static void cleanup_regenerate_messagelist (gpointer in_data, gpointer op_data, CamelException *ex) -{ - regenerate_messagelist_input_t *input = (regenerate_messagelist_input_t *) in_data; - regenerate_messagelist_data_t *data = (regenerate_messagelist_data_t *) op_data; - - ETreeModel *etm; - - etm = E_TREE_MODEL (input->ml->table_model); - - if (data->uids == NULL) { /*exception*/ - gtk_object_unref (GTK_OBJECT (input->ml)); - return; - } - - if (input->dotree) - build_tree(input->ml, data->tree); - else - build_flat(input->ml, data->uids, input->changes); - - if (input->search) - camel_folder_search_free (input->ml->folder, data->uids); - else - camel_folder_free_uids (input->ml->folder, data->uids); - - /* update what we have as our search string */ - if (input->ml->search && input->ml->search != input->search) - g_free(input->ml->search); - input->ml->search = input->search; - - if (data->tree) - thread_messages_free(data->tree); - - if (input->changes) - camel_folder_change_info_free(input->changes); - - gtk_object_unref (GTK_OBJECT (input->ml)); -} - -static const mail_operation_spec op_regenerate_messagelist = -{ - describe_regenerate_messagelist, - sizeof (regenerate_messagelist_data_t), - setup_regenerate_messagelist, - do_regenerate_messagelist, - cleanup_regenerate_messagelist -}; - -/* if changes == NULL, then update the whole list, otherwise just update the changes */ -static void -mail_do_regenerate_messagelist (MessageList *list, const gchar *search, CamelFolderChangeInfo *changes) -{ - regenerate_messagelist_input_t *input; - - /* This gets called on empty folder-browsers by the bonobo ui - * callback for threaded view. - */ - if (!list->folder) - return; - - /* see if we need to goto the child thread at all anyway */ - /* currently the only case is the flat view with updates and no search */ - if (search == NULL && changes != NULL && !list->threaded) { - build_flat_diff(list, changes); - camel_folder_change_info_free(changes); - return; - } - - input = g_new (regenerate_messagelist_input_t, 1); - input->ml = list; - input->search = g_strdup (search); - input->changes = changes; - input->dotree = list->threaded; - - mail_operation_queue (&op_regenerate_messagelist, input, TRUE); -} diff --git a/mail/message-list.h b/mail/message-list.h deleted file mode 100644 index 99776948b3..0000000000 --- a/mail/message-list.h +++ /dev/null @@ -1,104 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -#ifndef _MESSAGE_LIST_H_ -#define _MESSAGE_LIST_H_ - -#include <gnome.h> -#include "mail-types.h" -#include <bonobo/bonobo-main.h> -#include <bonobo/bonobo-object.h> -#include <bonobo/bonobo-ui-component.h> -#include <gal/e-table/e-table-scrolled.h> -#include <gal/e-table/e-table-simple.h> -#include <gal/e-table/e-tree-simple.h> -#include <gal/e-table/e-cell-text.h> -#include <gal/e-table/e-cell-toggle.h> -#include <gal/e-table/e-cell-checkbox.h> -#include <gal/e-table/e-cell-tree.h> - -#define MESSAGE_LIST_TYPE (message_list_get_type ()) -#define MESSAGE_LIST(o) (GTK_CHECK_CAST ((o), MESSAGE_LIST_TYPE, MessageList)) -#define MESSAGE_LIST_CLASS(k) (GTK_CHECK_CLASS_CAST((k), MESSAGE_LIST_TYPE, MessageListClass)) -#define IS_MESSAGE_LIST(o) (GTK_CHECK_TYPE ((o), MESSAGE_LIST_TYPE)) -#define IS_MESSAGE_LIST_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), MESSAGE_LIST_TYPE)) - -typedef struct _Renderer Renderer; - -enum { - COL_MESSAGE_STATUS, - COL_FLAGGED, - COL_SCORE, - COL_ATTACHMENT, - COL_FROM, - COL_SUBJECT, - COL_SENT, - COL_RECEIVED, - COL_TO, - COL_SIZE, - - COL_LAST, - - /* Invisible columns */ - COL_DELETED, - COL_UNREAD, - COL_COLOUR, -}; - -struct _MessageList { - BonoboObject parent; - - ETableModel *table_model; - - ETreePath *tree_root; - - GtkWidget *etable; - - CamelFolder *folder; - - GHashTable *uid_rowmap; /* key is the uid, value is the row number. - Note: The key string is owned by table_model */ - - char *search; /* current search string */ - - gboolean threaded; /* are we displaying threaded view? */ - int cursor_row; - const char *cursor_uid; - - /* row-selection and seen-marking timers */ - guint idle_id, seen_id; -}; - -typedef struct { - BonoboObjectClass parent_class; - - /* signals - select a message */ - void (*message_selected)(MessageList *ml, const char *uid); -} MessageListClass; - -typedef void (*MessageListForeachFunc) (MessageList *message_list, - const char *uid, - gpointer user_data); - -typedef enum { - MESSAGE_LIST_SELECT_NEXT = 1, - MESSAGE_LIST_SELECT_PREVIOUS = -1 -} MessageListSelectDirection; - -GtkType message_list_get_type (void); -BonoboObject *message_list_new (void); -void message_list_set_folder (MessageList *message_list, - CamelFolder *camel_folder); -GtkWidget *message_list_get_widget (MessageList *message_list); - -void message_list_foreach (MessageList *message_list, - MessageListForeachFunc callback, - gpointer user_data); - -void message_list_select (MessageList *message_list, - int base_row, - MessageListSelectDirection direction, - guint32 flags, guint32 mask); - -void message_list_set_threaded(MessageList *ml, gboolean threaded); -void message_list_set_search(MessageList *ml, const char *search); - -#endif /* _MESSAGE_LIST_H_ */ diff --git a/mail/message-thread.c b/mail/message-thread.c deleted file mode 100644 index 098803e28e..0000000000 --- a/mail/message-thread.c +++ /dev/null @@ -1,744 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Copyright (C) 2000 Helix Code Inc. - * - * Authors: Michael Zucchi <notzed@helixcode.com> - * - * 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 the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#include <config.h> -#include "camel/camel.h" -#include <sys/types.h> -#include <unistd.h> -#include <errno.h> -#include <string.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <glib.h> -#include <ctype.h> - -#include "message-thread.h" -#include "mail-tools.h" -#include "mail-threads.h" - -#define d(x) - -#define TIMEIT - -#ifdef TIMEIT -#include <sys/time.h> -#include <unistd.h> -#endif - -/* for debug only */ -int dump_tree(struct _container *c); - -static void -container_add_child(struct _container *node, struct _container *child) -{ - d(printf("\nAdding child %p to parent %p \n", child, node)); - child->next = node->child; - node->child = child; - child->parent = node; -} - -static void -container_parent_child(struct _container *parent, struct _container *child) -{ - struct _container *c, *node; - - /* are we already the right parent? */ - if (child->parent == parent) - return; - - /* are we unparented? */ - if (child->parent == NULL) { - container_add_child(parent, child); - return; - } - - /* else remove child from its existing parent, and reparent */ - node = child->parent; - c = (struct _container *)&node->child; - d(printf("scanning children:\n")); - while (c->next) { - d(printf(" %p\n", c)); - if (c->next==child) { - d(printf("found node %p\n", child)); - c->next = c->next->next; - child->parent = NULL; - container_add_child(parent, child); - return; - } - c = c->next; - } - - printf("DAMN, we shouldn't be here!\n"); -} - -static void -prune_empty(struct _container **cp) -{ - struct _container *child, *next, *c, *lastc; - - /* yes, this is intentional */ - lastc = (struct _container *)cp; - while (lastc->next) { - c = lastc->next; - - d(printf("checking message %p %p (%s)\n", c, - c->message, c->message?c->message->message_id:"<empty>")); - if (c->message == NULL) { - if (c->child == NULL) { - d(printf("removing empty node\n")); - lastc->next = c->next; - g_free(c); - continue; - } - if (c->parent || c->child->next==0) { - d(printf("promoting child\n")); - lastc->next = c->next; /* remove us */ - child = c->child; - while (child) { - next = child->next; - - child->parent = c->parent; - child->next = lastc->next; - lastc->next = child; - - child = next; - } - continue; - } - } - prune_empty(&c->child); - lastc = c; - } -} - -static void -hashloop(void *key, void *value, void *data) -{ - struct _container *c = value; - struct _container *tail = data; - - if (c->parent == NULL) { - c->next = tail->next; - tail->next = c; - } -} - -static char * -get_root_subject(struct _container *c, int *re) -{ - char *s, *p; - struct _container *scan; - - s = NULL; - *re = FALSE; - if (c->message) - s = c->message->subject; - else { - /* one of the children will always have a message */ - scan = c->child; - while (scan) { - if (scan->message) { - s = scan->message->subject; - break; - } - scan = scan->next; - } - } - if (s != NULL) { - while (*s) { - while (isspace(*s)) - s++; - if (s[0] == 0) - break; - if ((s[0] == 'r' || s[0]=='R') - && (s[1] == 'e' || s[1]=='E')) { - p = s+2; - while (isdigit(*p) || (ispunct(*p) && (*p != ':'))) - p++; - if (*p==':') { - *re = TRUE; - s = p+1; - } else - break; - } else - break; - } - if (*s) - return s; - } - return NULL; -} - -/* this can be pretty slow, but not used often */ -/* clast cannot be null */ -static void -remove_node(struct _container **list, struct _container *node, struct _container **clast) -{ - struct _container *c; - - /* this is intentional, even if it looks funny */ - /* if we have a parent, then we should remove it from the parent list, - otherwise we remove it from the root list */ - if (node->parent) { - c = (struct _container *)&node->parent->child; - } else { - c = (struct _container *)list; - } - while (c->next) { - if (c->next == node) { - if (*clast == c->next) - *clast = c; - c->next = c->next->next; - return; - } - c = c->next; - } - - printf("ERROR: removing node %p failed\n", node); -} - -static void -group_root_set(struct _container **cp) -{ - GHashTable *subject_table = g_hash_table_new(g_str_hash, g_str_equal); - struct _container *c, *clast, *scan, *container; - - /* gather subject lines */ - d(printf("gathering subject lines\n")); - clast = (struct _container *)cp; - c = clast->next; - while (c) { - c->root_subject = get_root_subject(c, &c->re); - if (c->root_subject) { - container = g_hash_table_lookup(subject_table, c->root_subject); - if (container == NULL - || (container->message == NULL && c->message) - || (container->re == TRUE && !c->re)) { - g_hash_table_insert(subject_table, c->root_subject, c); - } - } - c = c->next; - } - - /* merge common subjects? */ - clast = (struct _container *)cp; - while (clast->next) { - c = clast->next; - d(printf("checking %p %s\n", c, c->root_subject)); - if (c->root_subject - && (container = g_hash_table_lookup(subject_table, c->root_subject)) - && (container != c)) { - d(printf(" matching %p %s\n", container, container->root_subject)); - if (c->message == NULL && container->message == NULL) { - d(printf("merge containers children\n")); - /* steal the children from c onto container, and unlink c */ - scan = (struct _container *)&container->child; - while (scan->next) - scan = scan->next; - scan->next = c->child; - clast->next = c->next; - g_free(c); - continue; - } if (c->message == NULL && container->message != NULL) { - d(printf("container is non-empty parent\n")); - remove_node(cp, container, &clast); - container_add_child(c, container); - } else if (c->message != NULL && container->message == NULL) { - d(printf("container is empty child\n")); - clast->next = c->next; - container_add_child(container, c); - continue; - } else if (c->re && !container->re) { - d(printf("container is re\n")); - clast->next = c->next; - container_add_child(container, c); - continue; - } else if (!c->re && container->re) { - d(printf("container is not re\n")); - remove_node(cp, container, &clast); - container_add_child(c, container); - } else if (c->re && container->re) { - d(printf("subjects are common %p and %p\n", c, container)); - - remove_node(cp, container, &clast); - remove_node(cp, c, &clast); - - scan = g_malloc0(sizeof(*scan)); - scan->root_subject = c->root_subject; - scan->re = c->re && container->re; - scan->next = c->next; - clast->next = scan; - container_add_child(scan, c); - container_add_child(scan, container); - clast = scan; - g_hash_table_insert(subject_table, scan->root_subject, scan); - continue; - } - } - clast = c; - } - g_hash_table_destroy(subject_table); -} - -struct _tree_info { - GHashTable *visited; -}; - -static int -dump_tree_rec(struct _tree_info *info, struct _container *c, int depth) -{ - char *p; - int count=0; - - p = alloca(depth*2+1); - memset(p, ' ', depth*2); - p[depth*2] = 0; - - while (c) { - if (g_hash_table_lookup(info->visited, c)) { - printf("WARNING: NODE REVISITED: %p\n", c); - } else { - g_hash_table_insert(info->visited, c, c); - } - if (c->message) { - printf("%s %p Subject: %s <%s>\n", p, c, c->message->subject, c->message->message_id); - count += 1; - } else { - printf("%s %p <empty>\n", p, c); - } - if (c->child) - count += dump_tree_rec(info, c->child, depth+1); - c = c->next; - } - return count; -} - -int -dump_tree(struct _container *c) -{ - int count; - struct _tree_info info; - - info.visited = g_hash_table_new(g_direct_hash, g_direct_equal); - count = dump_tree_rec(&info, c, 0); - g_hash_table_destroy(info.visited); - return count; -} - -static void -container_free(struct _container *c) -{ - struct _container *n; - - while (c) { - n = c->next; - if (c->child) - container_free(c->child); /* free's children first */ - g_free(c); - c = n; - } -} - -void -thread_messages_free(struct _thread_messages *thread) -{ - container_free(thread->tree); - g_free(thread); -} - -static int -sort_node(const void *a, const void *b) -{ - const struct _container *a1 = ((struct _container **)a)[0]; - const struct _container *b1 = ((struct _container **)b)[0]; - - /* if we have no message, it must be a dummy node, which - also means it must have a child, just use that as the - sort data (close enough?) */ - if (a1->message == NULL) - a1 = a1->child; - if (b1->message == NULL) - b1 = b1->child; - if (a1->order == b1->order) - return 0; - if (a1->order < b1->order) - return -1; - else - return 1; -} - -static void -sort_thread(struct _container **cp) -{ - struct _container *c, *head, **carray; - int size=0; - - c = *cp; - while (c) { - /* sort the children while we're at it */ - if (c->child) - sort_thread(&c->child); - size++; - c = c->next; - } - if (size<2) - return; - carray = alloca(size*sizeof(struct _container *)); - c = *cp; - size=0; - while (c) { - carray[size] = c; - c = c->next; - size++; - } - qsort(carray, size, sizeof(struct _container *), sort_node); - size--; - head = carray[size]; - head->next = NULL; - size--; - do { - c = carray[size]; - c->next = head; - head = c; - size--; - } while (size>=0); - *cp = head; -} - -/* NOTE: This function assumes you have obtained the relevant locks for - the folder, BEFORE calling it */ -struct _thread_messages * -thread_messages(CamelFolder *folder, GPtrArray *uids) -{ - GHashTable *id_table, *no_id_table; - int i; - struct _container *c, *p, *child, *head; - struct _header_references *ref; - struct _thread_messages *thread; - -#ifdef TIMEIT - struct timeval start, end; - unsigned long diff; - - gettimeofday(&start, NULL); -#endif - - id_table = g_hash_table_new(g_str_hash, g_str_equal); - no_id_table = g_hash_table_new(NULL, NULL); - for (i=0;i<uids->len;i++) { - const CamelMessageInfo *mi; - mi = camel_folder_get_message_info (folder, uids->pdata[i]); - - if (mi == NULL) { - g_warning("Folder doesn't contain uid %s", (char *)uids->pdata[i]); - continue; - } - - if (mi->message_id) { - c = g_hash_table_lookup(id_table, mi->message_id); - /* check for duplicate messages */ - if (c) { - /* if duplicate, just make out it is a no-id message, but try and insert it - into the right spot in the tree */ - d(printf("doing: (duplicate message id)\n")); - c = g_malloc0(sizeof(*c)); - g_hash_table_insert(no_id_table, (void *)mi, c); - } else { - d(printf("doing : %s\n", mi->message_id)); - c = g_malloc0(sizeof(*c)); - g_hash_table_insert(id_table, mi->message_id, c); - } - } else { - d(printf("doing : (no message id)\n")); - c = g_malloc0(sizeof(*c)); - g_hash_table_insert(no_id_table, (void *)mi, c); - } - - c->message = mi; - c->order = i; - child = c; - ref = mi->references; - p = NULL; - head = NULL; - d(printf("references:\n")); - while (ref) { - if (ref->id == NULL) { - /* this shouldn't actually happen, and indicates - some problems in camel */ - d(printf("ref missing id!?\n")); - ref = ref->next; - continue; - } - - d(printf("looking up reference: %s\n", ref->id)); - c = g_hash_table_lookup(id_table, ref->id); - if (c == NULL) { - d(printf("not found\n")); - c = g_malloc0(sizeof(*c)); - g_hash_table_insert(id_table, ref->id, c); - } - if (c!=child) - container_parent_child(c, child); - child = c; - if (head == NULL) - head = c; - ref = ref->next; - } - } - - d(printf("\n\n")); - /* build a list of root messages (no parent) */ - head = NULL; - g_hash_table_foreach(id_table, hashloop, &head); - g_hash_table_foreach(no_id_table, hashloop, &head); - - g_hash_table_destroy(id_table); - g_hash_table_destroy(no_id_table); - - /* remove empty parent nodes */ - prune_empty(&head); - - /* find any siblings which missed out */ - group_root_set(&head); - -#if 0 - printf("finished\n"); - i = dump_tree(head); - printf("%d count, %d items in tree\n", uids->len, i); -#endif - - sort_thread(&head); - - thread = g_malloc(sizeof(*thread)); - thread->tree = head; - -#ifdef TIMEIT - gettimeofday(&end, NULL); - diff = end.tv_sec * 1000 + end.tv_usec/1000; - diff -= start.tv_sec * 1000 + start.tv_usec/1000; - printf("Message threading %d messages took %ld.%03ld seconds\n", - uids->len, diff / 1000, diff % 1000); -#endif - return thread; -} - -/* intended for incremental update. Not implemented yet as, well, its probbaly - not worth it (memory overhead vs speed, may as well just rethread the whole - lot?) - - But it might be implemented at a later date. -*/ -void -thread_messages_add(struct _thread_messages *thread, CamelFolder *folder, GPtrArray *uids) -{ - -} - -void -thread_messages_remove(struct _thread_messages *thread, CamelFolder *folder, GPtrArray *uids) -{ - -} - -/* ** THREAD MESSAGES ***************************************************** */ - -typedef struct thread_messages_input_s { - MessageList *ml; - GPtrArray *uids; - gboolean use_camel_uidfree; - void (*build) (MessageList *, struct _container *); -} thread_messages_input_t; - -typedef struct thread_messages_data_s { - struct _thread_messages *thread; -} thread_messages_data_t; - -static gchar *describe_thread_messages (gpointer in_data, gboolean gerund); -static void setup_thread_messages (gpointer in_data, gpointer op_data, CamelException *ex); -static void do_thread_messages (gpointer in_data, gpointer op_data, CamelException *ex); -static void cleanup_thread_messages (gpointer in_data, gpointer op_data, CamelException *ex); - -static gchar *describe_thread_messages (gpointer in_data, gboolean gerund) -{ - if (gerund) - return g_strdup (_("Threading message list")); - else - return g_strdup (_("Thread message list")); -} - -static void setup_thread_messages (gpointer in_data, gpointer op_data, CamelException *ex) -{ - thread_messages_input_t *input = (thread_messages_input_t *) in_data; - - gtk_object_ref (GTK_OBJECT (input->ml)); -} - -static void do_thread_messages (gpointer in_data, gpointer op_data, CamelException *ex) -{ - thread_messages_input_t *input = (thread_messages_input_t *) in_data; - thread_messages_data_t *data = (thread_messages_data_t *) op_data; - - mail_tool_camel_lock_up (); - data->thread = thread_messages (input->ml->folder, input->uids); - mail_tool_camel_lock_down (); -} - -static void cleanup_thread_messages (gpointer in_data, gpointer op_data, CamelException *ex) -{ - thread_messages_input_t *input = (thread_messages_input_t *) in_data; - thread_messages_data_t *data = (thread_messages_data_t *) op_data; - - (input->build) (input->ml, data->thread->tree); - thread_messages_free (data->thread); - - if (input->use_camel_uidfree) { - mail_tool_camel_lock_up (); - camel_folder_free_uids (input->ml->folder, input->uids); - mail_tool_camel_lock_down (); - } else { - g_ptr_array_add(input->uids, 0); - g_strfreev ((char **)input->uids->pdata); - g_ptr_array_free (input->uids, FALSE); - } - - gtk_object_unref (GTK_OBJECT (input->ml)); -} - -static const mail_operation_spec op_thread_messages = -{ - describe_thread_messages, - sizeof (thread_messages_data_t), - setup_thread_messages, - do_thread_messages, - cleanup_thread_messages -}; - -void mail_do_thread_messages (MessageList *ml, GPtrArray *uids, - gboolean use_camel_uidfree, - void (*build) (MessageList *, - struct _container *)) -{ - thread_messages_input_t *input; - - input = g_new (thread_messages_input_t, 1); - input->ml = ml; - input->uids = uids; - input->use_camel_uidfree = use_camel_uidfree; - input->build = build; - - mail_operation_queue (&op_thread_messages, input, TRUE); -} - -/* ************************************************************************ */ - -#ifdef STANDALONE - -static char * -auth_callback(char *prompt, gboolean secret, - CamelService *service, char *item, - CamelException *ex) -{ - printf ("auth_callback called: %s\n", prompt); - return NULL; -} - -int -main (int argc, char**argv) -{ - CamelSession *session; - CamelException *ex; - CamelStore *store; - gchar *store_url = "mbox:///home/notzed/evolution/local/Inbox"; - CamelFolder *folder; - CamelMimeMessage *message; - GList *uid_list; - GPtrArray *summary; - - gtk_init (&argc, &argv); - camel_init (); - ex = camel_exception_new (); - - session = camel_session_new (auth_callback); - store = camel_session_get_store (session, store_url, ex); - if (camel_exception_get_id (ex)) { - printf ("Exception caught in camel_session_get_store\n" - "Full description : %s\n", camel_exception_get_description (ex)); - return -1; - } - - folder = camel_store_get_folder (store, "mbox", 0, ex); - if (camel_exception_get_id (ex)) { - printf ("Exception caught in camel_store_get_folder\n" - "Full description : %s\n", camel_exception_get_description (ex)); - return -1; - } - -#if 0 - camel_folder_open (folder, FOLDER_OPEN_RW, ex); - if (camel_exception_get_id (ex)) { - printf ("Exception caught when trying to open the folder\n" - "Full description : %s\n", camel_exception_get_description (ex)); - return -1; - } -#endif - - summary = camel_folder_get_summary(folder); - thread_messages((CamelMessageInfo **)summary->pdata, summary->len); - - return 0; -} - -#endif - -/* - - msgid: d - references: a b c - - msgid: f - references: c d - - msgid: e - references: c - - a - \ - b - \ - c - \ - d - |\ - e f - */ -/* - lookup d - create new node d - child = d - loop on c b a - lookup node? - if no node, create node - add child to node - child = node - endloop - - */ diff --git a/mail/message-thread.h b/mail/message-thread.h deleted file mode 100644 index d5153cbfc0..0000000000 --- a/mail/message-thread.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef _MESSAGE_THREAD_H -#define _MESSAGE_THREAD_H - -#include <gnome.h> -#include "message-list.h" - -struct _container { - struct _container *next, - *parent, - *child; - const CamelMessageInfo *message; - char *root_subject; /* cached root equivalent subject */ - int re; /* re version of subject? */ - int order; -}; - -struct _thread_messages { - struct _container *tree; -}; - -struct _thread_messages *thread_messages(CamelFolder *folder, GPtrArray *uids); -void thread_messages_add(struct _thread_messages *thread, CamelFolder *folder, GPtrArray *uids); -void thread_messages_remove(struct _thread_messages *thread, CamelFolder *folder, GPtrArray *uids); -void thread_messages_free(struct _thread_messages *c); - -void mail_do_thread_messages (MessageList *ml, GPtrArray *uids, - gboolean use_camel_uidfree, - void (*build) (MessageList *, - struct _container *)); - -#endif /* !_MESSAGE_THREAD_H */ - diff --git a/mail/session.c b/mail/session.c deleted file mode 100644 index 6bcfc96404..0000000000 --- a/mail/session.c +++ /dev/null @@ -1,216 +0,0 @@ -/* - * mail-session.c: handles the session information and resource manipulation - * - * Author: - * Miguel de Icaza (miguel@gnu.org) - * - * (C) 2000 Helix Code, Inc. http://www.helixcode.com - */ -#include <config.h> -#include <gnome.h> -#include "mail.h" -#include "mail-session.h" -#include "mail-threads.h" - -CamelSession *session; -GHashTable *passwords; - -static void -request_callback (gchar *string, gpointer data) -{ - char **ans = data; - - if (string) - *ans = g_strdup(string); - else - *ans = NULL; -} - -char * -mail_session_request_dialog (const char *prompt, gboolean secret, const char *key, - gboolean async) -{ - GtkWidget *dialog; - - char *ans; - - if (!passwords) - passwords = g_hash_table_new (g_str_hash, g_str_equal); - - ans = g_hash_table_lookup (passwords, key); - if (ans) - return g_strdup (ans); - - if (!async) { - dialog = gnome_request_dialog (secret, prompt, NULL, 0, - request_callback, &ans, NULL); - if (!dialog) - return NULL; - if (gnome_dialog_run_and_close (GNOME_DIALOG (dialog)) == -1 || - ans == NULL) - return NULL; - } else { - if (!mail_op_get_password ((char *) prompt, secret, &ans)) - return NULL; - } - - g_hash_table_insert (passwords, g_strdup (key), g_strdup (ans)); - return ans; -} - -static char * -auth_callback (CamelAuthCallbackMode mode, char *data, gboolean secret, - CamelService *service, char *item, CamelException *ex) -{ - char *key, *ans, *url; - - if (!passwords) - passwords = g_hash_table_new (g_str_hash, g_str_equal); - - url = camel_url_to_string (service->url, FALSE); - key = g_strdup_printf ("%s:%s", url, item); - g_free (url); - - if (mode == CAMEL_AUTHENTICATOR_TELL) { - if (!data) { - g_hash_table_remove (passwords, key); - g_free (key); - } else { - gpointer old_key, old_data; - - if (g_hash_table_lookup_extended (passwords, key, - &old_key, - &old_data)) { - g_hash_table_insert (passwords, old_key, data); - g_free (old_data); - g_free (key); - } else - g_hash_table_insert (passwords, key, data); - } - - return NULL; - } - - ans = mail_session_request_dialog (data, secret, key, TRUE); - g_free (key); - - if (!ans) { - camel_exception_set (ex, CAMEL_EXCEPTION_USER_CANCEL, - "User canceled operation."); - } - - return ans; -} - -/* ******************** */ - -typedef struct _timeout_data_s { - CamelTimeoutCallback cb; - gpointer camel_data; - gboolean result; -} timeout_data_t; - -static gchar * -describe_camel_timeout (gpointer in_data, gboolean gerund) -{ - /* FIXME this is so wrong */ - - if (gerund) - return g_strdup ("Keeping connection alive"); - else - return g_strdup ("Keep connection alive"); -} - -static void -noop_camel_timeout (gpointer in_data, gpointer op_data, CamelException *ex) -{ -} - -static void -do_camel_timeout (gpointer in_data, gpointer op_data, CamelException *ex) -{ - timeout_data_t *td = (timeout_data_t *) in_data; - - td->result = (td->cb) (td->camel_data); -} - -static const mail_operation_spec spec_camel_timeout = -{ - describe_camel_timeout, - 0, - noop_camel_timeout, - do_camel_timeout, - noop_camel_timeout -}; - -static gboolean -camel_timeout (gpointer data) -{ - timeout_data_t *td = (timeout_data_t *) data; - - if (td->result == FALSE) { - g_free (td); - return FALSE; - } - - mail_operation_queue (&spec_camel_timeout, td, FALSE); - return TRUE; -} - -static guint -register_callback (guint32 interval, CamelTimeoutCallback cb, gpointer camel_data) -{ - timeout_data_t *td; - - /* We do this because otherwise the timeout can get called - * more often than the dispatch thread can get rid of it, - * leading to timeout calls piling up, and we don't have a - * good way to watch the return values. It's not cool. - */ - g_return_val_if_fail (interval > 1000, 0); - - td = g_new (timeout_data_t, 1); - td->result = TRUE; - td->cb = cb; - td->camel_data = camel_data; - - return gtk_timeout_add_full (interval, camel_timeout, NULL, - td, g_free); -} - -static gboolean -remove_callback (guint handle) -{ - gtk_timeout_remove (handle); - return TRUE; -} - -/* ******************** */ - -void -mail_session_init (void) -{ - char *camel_dir; - - camel_init (); - camel_dir = g_strdup_printf ("%s/mail", evolution_dir); - session = camel_session_new (camel_dir, auth_callback, - register_callback, remove_callback); - g_free (camel_dir); -} - -static gboolean -free_entry (gpointer key, gpointer value, gpointer user_data) -{ - g_free (key); - memset (value, 0, strlen (value)); - g_free (value); - return TRUE; -} - -void -mail_session_forget_passwords (BonoboUIComponent *uih, void *user_data, - const char *path) -{ - g_hash_table_foreach_remove (passwords, free_entry, NULL); -} diff --git a/mail/subscribe-dialog.c b/mail/subscribe-dialog.c deleted file mode 100644 index 7f198181de..0000000000 --- a/mail/subscribe-dialog.c +++ /dev/null @@ -1,1188 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* subscribe-dialog.c: Subscribe dialog */ -/* - * Authors: Chris Toshok <toshok@helixcode.com> - * - * Copyright 2000 Helix Code, Inc. (www.helixcode.com) - * - * 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 - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA. - * - */ - -#include <config.h> -#include <gnome.h> -#include "subscribe-dialog.h" -#include "e-util/e-html-utils.h" -#include "e-title-bar.h" -#include <gtkhtml/gtkhtml.h> -#include <gal/util/e-util.h> -#include <gal/widgets/e-unicode.h> -#include <gal/e-table/e-cell-toggle.h> -#include <gal/e-table/e-cell-text.h> -#include <gal/e-table/e-cell-tree.h> -#include <gal/e-table/e-table-scrolled.h> -#include <gal/e-table/e-tree-simple.h> -#include <gal/e-paned/e-hpaned.h> -#include <bonobo/bonobo-main.h> -#include <bonobo/bonobo-object.h> -#include <bonobo/bonobo-generic-factory.h> -#include <bonobo/bonobo-control.h> -#include <bonobo/bonobo-ui-component.h> -#include <bonobo/bonobo-ui-util.h> -#include <bonobo/bonobo-widget.h> - -#include "mail.h" -#include "mail-tools.h" -#include "mail-threads.h" -#include "camel/camel.h" - -#include "art/empty.xpm" -#include "art/mark.xpm" - - -#define DEFAULT_STORE_TABLE_WIDTH 200 -#define DEFAULT_WIDTH 500 -#define DEFAULT_HEIGHT 300 - -#define PARENT_TYPE (gtk_object_get_type ()) - -#define FOLDER_ETABLE_SPEC "<ETableSpecification cursor-mode=\"line\"> \ - <ETableColumn model_col=\"0\" pixbuf=\"subscribed-image\" expansion=\"0.0\" minimum_width=\"16\" resizable=\"false\" cell=\"cell_toggle\" compare=\"integer\"/> \ - <ETableColumn model_col=\"1\" _title=\"Folder\" expansion=\"1.0\" minimum_width=\"20\" resizable=\"true\" cell=\"cell_tree\" compare=\"string\"/> \ - <ETableState> \ - <column source=\"0\"/> \ - <column source=\"1\"/> \ - <grouping></grouping> \ - </ETableState> \ -</ETableSpecification>" - -#define STORE_ETABLE_SPEC "<ETableSpecification cursor-mode=\"line\"> \ - <ETableColumn model_col=\"0\" _title=\"Store\" expansion=\"1.0\" minimum_width=\"20\" resizable=\"true\" cell=\"string\" compare=\"string\"/> \ - <ETableState> \ - <column source=\"0\"/> \ - <grouping></grouping> \ - </ETableState> \ -</ETableSpecification>" - -enum { - FOLDER_COL_SUBSCRIBED, - FOLDER_COL_NAME, - FOLDER_COL_LAST -}; - -enum { - STORE_COL_NAME, - STORE_COL_LAST -}; - -static GtkObjectClass *subscribe_dialog_parent_class; - -static void build_tree (SubscribeDialog *sc, CamelStore *store); - -static void -set_pixmap (BonoboUIComponent *component, - const char *xml_path, - const char *icon) -{ - char *path; - GdkPixbuf *pixbuf; - - path = g_concat_dir_and_file (EVOLUTION_DATADIR "/images/evolution/buttons", icon); - - pixbuf = gdk_pixbuf_new_from_file (path); - g_return_if_fail (pixbuf != NULL); - - bonobo_ui_util_set_pixbuf (component, xml_path, pixbuf); - - gdk_pixbuf_unref (pixbuf); - - g_free (path); -} - -static void -update_pixmaps (BonoboUIComponent *component) -{ - set_pixmap (component, "/Toolbar/SubscribeFolder", "fetch-mail.png"); /* XXX */ - set_pixmap (component, "/Toolbar/UnsubscribeFolder", "compose-message.png"); /* XXX */ - set_pixmap (component, "/Toolbar/RefreshList", "forward.png"); /* XXX */ -} - -static GtkWidget* -make_folder_search_widget (GtkSignalFunc start_search_func, - gpointer user_data_for_search) -{ - SubscribeDialog *sc = SUBSCRIBE_DIALOG (user_data_for_search); - GtkWidget *search_hbox = gtk_hbox_new (FALSE, 0); - - sc->search_entry = gtk_entry_new (); - - if (start_search_func) { - gtk_signal_connect (GTK_OBJECT (sc->search_entry), "activate", - start_search_func, - user_data_for_search); - } - - /* add the search entry to the our search_vbox */ - gtk_box_pack_start (GTK_BOX (search_hbox), - gtk_label_new(_("Display folders starting with:")), - FALSE, TRUE, 0); - gtk_box_pack_start (GTK_BOX (search_hbox), sc->search_entry, - FALSE, TRUE, 3); - - return search_hbox; -} - - -/* Our async operations */ - -typedef void (*SubscribeGetStoreCallback)(SubscribeDialog *sc, CamelStore *store, gpointer cb_data); -typedef void (*SubscribeFolderCallback)(SubscribeDialog *sc, gboolean success, gpointer cb_data); - -/* ** GET STORE ******************************************************* */ - -typedef struct get_store_input_s { - SubscribeDialog *sc; - gchar *url; - SubscribeGetStoreCallback cb; - gpointer cb_data; -} get_store_input_t; - -typedef struct get_store_data_s { - CamelStore *store; -} get_store_data_t; - -static gchar * -describe_get_store (gpointer in_data, gboolean gerund) -{ - get_store_input_t *input = (get_store_input_t *) in_data; - - if (gerund) { - return g_strdup_printf (_("Getting store for \"%s\""), input->url); - } - else { - return g_strdup_printf (_("Get store for \"%s\""), input->url); - } -} - -static void -setup_get_store (gpointer in_data, gpointer op_data, CamelException *ex) -{ -} - -static void -do_get_store (gpointer in_data, gpointer op_data, CamelException *ex) -{ - get_store_input_t *input = (get_store_input_t *)in_data; - get_store_data_t *data = (get_store_data_t*)op_data; - - mail_tool_camel_lock_up (); - data->store = camel_session_get_store (session, input->url, ex); - mail_tool_camel_lock_down (); - - if (camel_exception_is_set (ex)) - data->store = NULL; -} - -static void -cleanup_get_store (gpointer in_data, gpointer op_data, CamelException *ex) -{ - get_store_input_t *input = (get_store_input_t *)in_data; - get_store_data_t *data = (get_store_data_t*)op_data; - - input->cb (input->sc, data->store, input->cb_data); - - g_free (input->url); -} - -static const mail_operation_spec op_get_store = { - describe_get_store, - sizeof (get_store_data_t), - setup_get_store, - do_get_store, - cleanup_get_store -}; - -static void -subscribe_do_get_store (SubscribeDialog *sc, const char *url, SubscribeGetStoreCallback cb, gpointer cb_data) -{ - get_store_input_t *input; - - input = g_new (get_store_input_t, 1); - input->sc = sc; - input->url = g_strdup (url); - input->cb = cb; - input->cb_data = cb_data; - - mail_operation_queue (&op_get_store, input, TRUE); -} - -/* ** SUBSCRIBE FOLDER ******************************************************* */ -/* Given a CamelFolderInfo, construct the corresponding - * EvolutionStorage path to it. - */ -static char * -storage_tree_path (CamelFolderInfo *info) -{ - int len; - CamelFolderInfo *i; - char *path, *p; - - for (len = 0, i = info; i; i = i->parent) - len += strlen (i->name) + 1; - - /* We do this backwards because that's the way the pointers point. */ - path = g_malloc (len + 1); - p = path + len; - *p = '\0'; - for (i = info; i; i = i->parent) { - len = strlen (i->name); - p -= len; - memcpy (p, i->name, len); - *--p = '/'; - } - - return path; -} - -typedef struct subscribe_folder_input_s { - SubscribeDialog *sc; - CamelStore *store; - CamelFolderInfo *info; - SubscribeFolderCallback cb; - gpointer cb_data; -} subscribe_folder_input_t; - -typedef struct subscribe_folder_data_s { - char *path; - char *name; - char *url; -} subscribe_folder_data_t; - -static gchar * -describe_subscribe_folder (gpointer in_data, gboolean gerund) -{ - subscribe_folder_input_t *input = (subscribe_folder_input_t *) in_data; - - if (gerund) - return g_strdup_printf - (_("Subscribing to folder \"%s\""), - input->info->name); - else - return g_strdup_printf (_("Subscribe to folder \"%s\""), - input->info->name); -} - -static void -setup_subscribe_folder (gpointer in_data, gpointer op_data, CamelException *ex) -{ - subscribe_folder_input_t *input = (subscribe_folder_input_t *) in_data; - subscribe_folder_data_t *data = (subscribe_folder_data_t *) op_data; - - data->path = storage_tree_path (input->info); - data->name = g_strdup (input->info->name); - data->url = g_strdup (input->info->url); - - camel_object_ref (CAMEL_OBJECT (input->store)); - gtk_object_ref (GTK_OBJECT (input->sc)); -} - -static void -do_subscribe_folder (gpointer in_data, gpointer op_data, CamelException *ex) -{ - subscribe_folder_input_t *input = (subscribe_folder_input_t *) in_data; - subscribe_folder_data_t *data = (subscribe_folder_data_t *) op_data; - - mail_tool_camel_lock_up (); - camel_store_subscribe_folder (input->store, data->name, ex); - mail_tool_camel_lock_down (); -} - -static void -cleanup_subscribe_folder (gpointer in_data, gpointer op_data, - CamelException *ex) -{ - subscribe_folder_input_t *input = (subscribe_folder_input_t *) in_data; - subscribe_folder_data_t *data = (subscribe_folder_data_t *) op_data; - - if (!camel_exception_is_set (ex)) - evolution_storage_new_folder (input->sc->storage, - data->path, - data->name, "mail", - data->url, - _("(No description)") /* XXX */, - FALSE); - - if (input->cb) - input->cb (input->sc, !camel_exception_is_set(ex), input->cb_data); - - g_free (data->path); - g_free (data->name); - g_free (data->url); - - camel_object_unref (CAMEL_OBJECT (input->store)); - gtk_object_unref (GTK_OBJECT (input->sc)); -} - -static const mail_operation_spec op_subscribe_folder = { - describe_subscribe_folder, - sizeof (subscribe_folder_data_t), - setup_subscribe_folder, - do_subscribe_folder, - cleanup_subscribe_folder -}; - -static void -subscribe_do_subscribe_folder (SubscribeDialog *sc, CamelStore *store, CamelFolderInfo *info, - SubscribeFolderCallback cb, gpointer cb_data) -{ - subscribe_folder_input_t *input; - - g_return_if_fail (CAMEL_IS_STORE (store)); - g_return_if_fail (info); - - input = g_new (subscribe_folder_input_t, 1); - input->sc = sc; - input->store = store; - input->info = info; - input->cb = cb; - input->cb_data = cb_data; - - mail_operation_queue (&op_subscribe_folder, input, TRUE); -} - -/* ** UNSUBSCRIBE FOLDER ******************************************************* */ - -typedef struct unsubscribe_folder_input_s { - SubscribeDialog *sc; - CamelStore *store; - CamelFolderInfo *info; - SubscribeFolderCallback cb; - gpointer cb_data; -} unsubscribe_folder_input_t; - -typedef struct unsubscribe_folder_data_s { - char *name; - char *path; -} unsubscribe_folder_data_t; - -static gchar * -describe_unsubscribe_folder (gpointer in_data, gboolean gerund) -{ - unsubscribe_folder_input_t *input = (unsubscribe_folder_input_t *) in_data; - - if (gerund) - return g_strdup_printf - (_("Unsubscribing to folder \"%s\""), - input->info->name); - else - return g_strdup_printf (_("Unsubscribe to folder \"%s\""), - input->info->name); -} - -static void -setup_unsubscribe_folder (gpointer in_data, gpointer op_data, CamelException *ex) -{ - unsubscribe_folder_input_t *input = (unsubscribe_folder_input_t *) in_data; - unsubscribe_folder_data_t *data = (unsubscribe_folder_data_t *) op_data; - - data->name = g_strdup (input->info->name); - data->path = storage_tree_path (input->info); - - camel_object_ref (CAMEL_OBJECT (input->store)); - gtk_object_ref (GTK_OBJECT (input->sc)); -} - -static void -do_unsubscribe_folder (gpointer in_data, gpointer op_data, CamelException *ex) -{ - unsubscribe_folder_input_t *input = (unsubscribe_folder_input_t *) in_data; - unsubscribe_folder_data_t *data = (unsubscribe_folder_data_t *) op_data; - - mail_tool_camel_lock_up (); - camel_store_unsubscribe_folder (input->store, data->name, ex); - mail_tool_camel_lock_down (); -} - -static void -cleanup_unsubscribe_folder (gpointer in_data, gpointer op_data, - CamelException *ex) -{ - unsubscribe_folder_input_t *input = (unsubscribe_folder_input_t *) in_data; - unsubscribe_folder_data_t *data = (unsubscribe_folder_data_t *) op_data; - - if (!camel_exception_is_set (ex)) - evolution_storage_removed_folder (input->sc->storage, data->path); - - if (input->cb) - input->cb (input->sc, !camel_exception_is_set(ex), input->cb_data); - - g_free (data->path); - g_free (data->name); - - camel_object_unref (CAMEL_OBJECT (input->store)); - gtk_object_unref (GTK_OBJECT (input->sc)); -} - -static const mail_operation_spec op_unsubscribe_folder = { - describe_unsubscribe_folder, - sizeof (unsubscribe_folder_data_t), - setup_unsubscribe_folder, - do_unsubscribe_folder, - cleanup_unsubscribe_folder -}; - -static void -subscribe_do_unsubscribe_folder (SubscribeDialog *sc, CamelStore *store, CamelFolderInfo *info, - SubscribeFolderCallback cb, gpointer cb_data) -{ - unsubscribe_folder_input_t *input; - - g_return_if_fail (CAMEL_IS_STORE (store)); - g_return_if_fail (info); - - input = g_new (unsubscribe_folder_input_t, 1); - input->sc = sc; - input->store = store; - input->info = info; - input->cb = cb; - input->cb_data = cb_data; - - mail_operation_queue (&op_unsubscribe_folder, input, TRUE); -} - - - -static gboolean -folder_info_subscribed (SubscribeDialog *sc, CamelFolderInfo *info) -{ - return camel_store_folder_subscribed (sc->store, info->full_name); -} - -static void -node_changed_cb (SubscribeDialog *sc, gboolean changed, gpointer data) -{ - ETreePath *node = data; - - if (changed) - e_tree_model_node_changed (sc->folder_model, node); -} - -static void -subscribe_folder_info (SubscribeDialog *sc, CamelFolderInfo *info, ETreePath *node) -{ - /* folders without urls cannot be subscribed to */ - if (info->url == NULL) - return; - - subscribe_do_subscribe_folder (sc, sc->store, info, node_changed_cb, node); -} - -static void -unsubscribe_folder_info (SubscribeDialog *sc, CamelFolderInfo *info, ETreePath *node) -{ - /* folders without urls cannot be subscribed to */ - if (info->url == NULL) - return; - - subscribe_do_unsubscribe_folder (sc, sc->store, info, node_changed_cb, node); -} - -static void -subscribe_close (BonoboUIComponent *uic, - void *user_data, const char *path) -{ - SubscribeDialog *sc = (SubscribeDialog*)user_data; - - gtk_widget_destroy (sc->app); -} - -static void -subscribe_select_all (BonoboUIComponent *uic, - void *user_data, const char *path) -{ - SubscribeDialog *sc = (SubscribeDialog*)user_data; - ETableScrolled *scrolled = E_TABLE_SCROLLED (sc->folder_etable); - - e_table_select_all (scrolled->table); -} - -static void -subscribe_invert_selection (BonoboUIComponent *uic, - void *user_data, const char *path) -{ - SubscribeDialog *sc = (SubscribeDialog*)user_data; - ETableScrolled *scrolled = E_TABLE_SCROLLED (sc->folder_etable); - - e_table_invert_selection (scrolled->table); -} - -static void -subscribe_folder_foreach (int model_row, gpointer closure) -{ - SubscribeDialog *sc = SUBSCRIBE_DIALOG (closure); - ETreePath *node = e_tree_model_node_at_row (sc->folder_model, model_row); - CamelFolderInfo *info = e_tree_model_node_get_data (sc->folder_model, node); - - if (!folder_info_subscribed (sc, info)) - subscribe_folder_info (sc, info, node); -} - -static void -subscribe_folders (GtkWidget *widget, gpointer user_data) -{ - SubscribeDialog *sc = SUBSCRIBE_DIALOG (user_data); - - e_table_selected_row_foreach (E_TABLE_SCROLLED(sc->folder_etable)->table, - subscribe_folder_foreach, sc); -} - -static void -unsubscribe_folder_foreach (int model_row, gpointer closure) -{ - SubscribeDialog *sc = SUBSCRIBE_DIALOG (closure); - ETreePath *node = e_tree_model_node_at_row (sc->folder_model, model_row); - CamelFolderInfo *info = e_tree_model_node_get_data (sc->folder_model, node); - - if (folder_info_subscribed(sc, info)) - unsubscribe_folder_info (sc, info, node); -} - - -static void -unsubscribe_folders (GtkWidget *widget, gpointer user_data) -{ - SubscribeDialog *sc = SUBSCRIBE_DIALOG (user_data); - - e_table_selected_row_foreach (E_TABLE_SCROLLED(sc->folder_etable)->table, - unsubscribe_folder_foreach, sc); -} - -static void -subscribe_refresh_list (GtkWidget *widget, gpointer user_data) -{ - SubscribeDialog *sc = SUBSCRIBE_DIALOG (user_data); - - e_utf8_gtk_entry_set_text (GTK_ENTRY (sc->search_entry), ""); - if (sc->search_top) { - g_free (sc->search_top); - sc->search_top = NULL; - } - if (sc->store) - build_tree (sc, sc->store); -} - -static void -subscribe_search (GtkWidget *widget, gpointer user_data) -{ - SubscribeDialog *sc = SUBSCRIBE_DIALOG (user_data); - char* search_pattern = e_utf8_gtk_entry_get_text(GTK_ENTRY(widget)); - - if (sc->search_top) { - g_free (sc->search_top); - sc->search_top = NULL; - } - - if (search_pattern && *search_pattern) - sc->search_top = search_pattern; - - if (sc->store) - build_tree (sc, sc->store); -} - - -#if 0 -/* HTML Helpers */ -static void -html_size_req (GtkWidget *widget, GtkRequisition *requisition) -{ - if (GTK_LAYOUT (widget)->height > 90) - requisition->height = 90; - else - requisition->height = GTK_LAYOUT (widget)->height; -} - -/* Returns a GtkHTML which is already inside a GtkScrolledWindow. If - * @white is TRUE, the GtkScrolledWindow will be inside a GtkFrame. - */ -static GtkWidget * -html_new (gboolean white) -{ - GtkWidget *html, *scrolled, *frame; - GtkStyle *style; - - html = gtk_html_new (); - GTK_LAYOUT (html)->height = 0; - gtk_signal_connect (GTK_OBJECT (html), "size_request", - GTK_SIGNAL_FUNC (html_size_req), NULL); - gtk_html_set_editable (GTK_HTML (html), FALSE); - style = gtk_rc_get_style (html); - if (style) { - gtk_html_set_default_background_color (GTK_HTML (html), - white ? &style->white : - &style->bg[0]); - } - gtk_widget_set_sensitive (html, FALSE); - scrolled = gtk_scrolled_window_new (NULL, NULL); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled), - GTK_POLICY_NEVER, - GTK_POLICY_NEVER); - gtk_container_add (GTK_CONTAINER (scrolled), html); - - if (white) { - frame = gtk_frame_new (NULL); - gtk_frame_set_shadow_type (GTK_FRAME (frame), - GTK_SHADOW_ETCHED_IN); - gtk_container_add (GTK_CONTAINER (frame), scrolled); - gtk_widget_show_all (frame); - } else - gtk_widget_show_all (scrolled); - - return html; -} - -static void -put_html (GtkHTML *html, char *text) -{ - GtkHTMLStream *handle; - - text = e_text_to_html (text, (E_TEXT_TO_HTML_CONVERT_NL | - E_TEXT_TO_HTML_CONVERT_SPACES | - E_TEXT_TO_HTML_CONVERT_URLS)); - handle = gtk_html_begin (html); - gtk_html_write (html, handle, "<HTML><BODY>", 12); - gtk_html_write (html, handle, text, strlen (text)); - gtk_html_write (html, handle, "</BODY></HTML>", 14); - g_free (text); - gtk_html_end (html, handle, GTK_HTML_STREAM_OK); -} -#endif - - -/* etable stuff for the subscribe ui */ - -static int -folder_etable_col_count (ETableModel *etm, void *data) -{ - return FOLDER_COL_LAST; -} - -static void* -folder_etable_duplicate_value (ETableModel *etm, int col, const void *val, void *data) -{ - return g_strdup (val); -} - -static void -folder_etable_free_value (ETableModel *etm, int col, void *val, void *data) -{ - g_free (val); -} - -static void* -folder_etable_init_value (ETableModel *etm, int col, void *data) -{ - return g_strdup (""); -} - -static gboolean -folder_etable_value_is_empty (ETableModel *etm, int col, const void *val, void *data) -{ - return !(val && *(char *)val); -} - -static char* -folder_etable_value_to_string (ETableModel *etm, int col, const void *val, void *data) -{ - return g_strdup(val); -} - -static GdkPixbuf* -folder_etree_icon_at (ETreeModel *etree, ETreePath *path, void *model_data) -{ - return NULL; /* XXX no icons for now */ -} - -static void* -folder_etree_value_at (ETreeModel *etree, ETreePath *path, int col, void *model_data) -{ - SubscribeDialog *dialog = SUBSCRIBE_DIALOG (model_data); - CamelFolderInfo *info = e_tree_model_node_get_data (etree, path); - - if (col == FOLDER_COL_NAME) { - return info->name; - } - else /* FOLDER_COL_SUBSCRIBED */ { - /* folders without urls cannot be subscribed to */ - if (info->url == NULL) - return GINT_TO_POINTER(0); /* empty */ - else if (!folder_info_subscribed(dialog, info)) - return GINT_TO_POINTER(0); /* XXX unchecked */ - else - return GUINT_TO_POINTER (1); /* checked */ - } -} - -static void -folder_etree_set_value_at (ETreeModel *etree, ETreePath *path, int col, const void *val, void *model_data) -{ - /* nothing */ -} - -static gboolean -folder_etree_is_editable (ETreeModel *etree, ETreePath *path, int col, void *model_data) -{ - return FALSE; -} - - - -static int -store_etable_col_count (ETableModel *etm, void *data) -{ - return STORE_COL_LAST; -} - -static int -store_etable_row_count (ETableModel *etm, void *data) -{ - SubscribeDialog *sc = SUBSCRIBE_DIALOG (data); - - return g_list_length (sc->store_list); -} - -static void* -store_etable_value_at (ETableModel *etm, int col, int row, void *data) -{ - SubscribeDialog *sc = SUBSCRIBE_DIALOG (data); - CamelStore *store = (CamelStore*)g_list_nth_data (sc->store_list, row); - - return camel_service_get_name (CAMEL_SERVICE (store), TRUE); -} - -static void -store_etable_set_value_at (ETableModel *etm, int col, int row, const void *val, void *data) -{ - /* nada */ -} - -static gboolean -store_etable_is_editable (ETableModel *etm, int col, int row, void *data) -{ - return FALSE; -} - -static void* -store_etable_duplicate_value (ETableModel *etm, int col, const void *val, void *data) -{ - return g_strdup (val); -} - -static void -store_etable_free_value (ETableModel *etm, int col, void *val, void *data) -{ - g_free (val); -} - -static void* -store_etable_initialize_value (ETableModel *etm, int col, void *data) -{ - return g_strdup (""); -} - -static gboolean -store_etable_value_is_empty (ETableModel *etm, int col, const void *val, void *data) -{ - return !(val && *(char *)val); -} - -static char* -store_etable_value_to_string (ETableModel *etm, int col, const void *val, void *data) -{ - return g_strdup(val); -} - - - -static void -build_etree_from_folder_info (SubscribeDialog *sc, ETreePath *parent, CamelFolderInfo *info) -{ - CamelFolderInfo *i; - - if (info == NULL) - return; - - for (i = info; i; i = i->sibling) { - ETreePath *node = e_tree_model_node_insert (sc->folder_model, parent, -1, i); - build_etree_from_folder_info (sc, node, i->child); - } -} - -static void -build_tree (SubscribeDialog *sc, CamelStore *store) -{ - CamelException *ex = camel_exception_new(); - - /* free up the existing CamelFolderInfo* if there is any */ - if (sc->folder_info) - camel_store_free_folder_info (sc->store, sc->folder_info); - if (sc->storage) - gtk_object_unref (GTK_OBJECT (sc->storage)); - - sc->store = store; - sc->storage = mail_lookup_storage (sc->store); - sc->folder_info = camel_store_get_folder_info (sc->store, sc->search_top, TRUE, TRUE, FALSE, ex); - - if (camel_exception_is_set (ex)) { - printf ("camel_store_get_folder_info failed\n"); - camel_exception_free (ex); - return; - } - - e_tree_model_node_remove (sc->folder_model, sc->folder_root); - sc->folder_root = e_tree_model_node_insert (sc->folder_model, NULL, - 0, NULL); - - - build_etree_from_folder_info (sc, sc->folder_root, sc->folder_info); - - camel_exception_free (ex); -} - -static void -storage_selected_cb (ETable *table, - int row, - gpointer data) -{ - SubscribeDialog *sc = SUBSCRIBE_DIALOG (data); - CamelStore *store = (CamelStore*)g_list_nth_data (sc->store_list, row); - - build_tree (sc, store); -} - - - -static void -folder_toggle_cb (ETable *table, - int row, - gpointer data) -{ - SubscribeDialog *sc = SUBSCRIBE_DIALOG (data); - ETreePath *node = e_tree_model_node_at_row (sc->folder_model, row); - CamelFolderInfo *info = e_tree_model_node_get_data (sc->folder_model, node); - - if (folder_info_subscribed(sc, info)) - unsubscribe_folder_info (sc, info, node); - else - subscribe_folder_info (sc, info, node); - - e_tree_model_node_changed (sc->folder_model, node); -} - - - -#define EXAMPLE_DESCR "And the beast shall come forth surrounded by a roiling cloud of vengeance.\n" \ -" The house of the unbelievers shall be razed and they shall be scorched to the\n" \ -" earth. Their tags shall blink until the end of days. \n" \ -" from The Book of Mozilla, 12:10" - -static BonoboUIVerb verbs [] = { - /* File Menu */ - BONOBO_UI_UNSAFE_VERB ("FileCloseWin", subscribe_close), - - /* Edit Menu */ - BONOBO_UI_UNSAFE_VERB ("EditSelectAll", subscribe_select_all), - BONOBO_UI_UNSAFE_VERB ("EditInvertSelection", subscribe_invert_selection), - - /* Folder Menu / Toolbar */ - BONOBO_UI_UNSAFE_VERB ("SubscribeFolder", subscribe_folders), - BONOBO_UI_UNSAFE_VERB ("UnsubscribeFolder", unsubscribe_folders), - - /* Toolbar Specific */ - BONOBO_UI_UNSAFE_VERB ("RefreshList", subscribe_refresh_list), - - BONOBO_UI_VERB_END -}; - -static void -store_cb (SubscribeDialog *sc, CamelStore *store, gpointer data) -{ - if (!store) - return; - - if (camel_store_supports_subscriptions (store)) { - sc->store_list = g_list_prepend (sc->store_list, store); - e_table_model_row_inserted (sc->store_model, 0); - } - else { - camel_object_unref (CAMEL_OBJECT (store)); - } -} - -static void -populate_store_foreach (MailConfigService *service, SubscribeDialog *sc) -{ - subscribe_do_get_store (sc, service->url, store_cb, NULL); -} - -static void -populate_store_list (SubscribeDialog *sc) -{ - GSList *sources; - - sources = mail_config_get_sources (); - g_slist_foreach (sources, (GFunc)populate_store_foreach, sc); - sources = mail_config_get_news (); - g_slist_foreach (sources, (GFunc)populate_store_foreach, sc); - - e_table_model_changed (sc->store_model); -} - -static void -subscribe_dialog_gui_init (SubscribeDialog *sc) -{ - ETableExtras *extras; - ECell *cell; - GdkPixbuf *toggles[2]; - BonoboUIComponent *component; - BonoboUIContainer *container; - GtkWidget *folder_search_widget; - BonoboControl *search_control; - CORBA_Environment ev; - - CORBA_exception_init (&ev); - - /* Construct the app */ - sc->app = bonobo_window_new ("subscribe-dialog", "Manage Subscriptions"); - - /* Build the menu and toolbar */ - container = bonobo_ui_container_new (); - bonobo_ui_container_set_win (container, BONOBO_WINDOW (sc->app)); - - /* set up the bonobo stuff */ - component = bonobo_ui_component_new_default (); - bonobo_ui_component_set_container ( - component, bonobo_object_corba_objref (BONOBO_OBJECT (container))); - - bonobo_ui_component_add_verb_list_with_data ( - component, verbs, sc); - - bonobo_ui_component_freeze (component, NULL); - - bonobo_ui_util_set_ui (component, EVOLUTION_DATADIR, - "evolution-subscribe.xml", - "evolution-subscribe"); - - update_pixmaps (component); - - bonobo_ui_component_thaw (component, NULL); - - sc->table = gtk_table_new (1, 2, FALSE); - - sc->hpaned = e_hpaned_new (); - - folder_search_widget = make_folder_search_widget (subscribe_search, sc); - gtk_widget_show_all (folder_search_widget); - search_control = bonobo_control_new (folder_search_widget); - - bonobo_ui_component_object_set ( - component, "/Toolbar/FolderSearch", - bonobo_object_corba_objref (BONOBO_OBJECT (search_control)), NULL); - - /* set our our contents */ -#if 0 - sc->description = html_new (TRUE); - put_html (GTK_HTML (sc->description), EXAMPLE_DESCR); - - gtk_table_attach ( - GTK_TABLE (sc->table), sc->description->parent->parent, - 0, 1, 0, 1, - GTK_FILL | GTK_EXPAND, - 0, - 0, 0); -#endif - - /* set up the store etable */ - sc->store_model = e_table_simple_new (store_etable_col_count, - store_etable_row_count, - store_etable_value_at, - store_etable_set_value_at, - store_etable_is_editable, - store_etable_duplicate_value, - store_etable_free_value, - store_etable_initialize_value, - store_etable_value_is_empty, - store_etable_value_to_string, - sc); - - extras = e_table_extras_new (); - - sc->store_etable = e_table_scrolled_new (E_TABLE_MODEL(sc->store_model), - extras, STORE_ETABLE_SPEC, NULL); - - gtk_object_sink (GTK_OBJECT (extras)); - - gtk_signal_connect (GTK_OBJECT (E_TABLE_SCROLLED (sc->store_etable)->table), - "cursor_change", GTK_SIGNAL_FUNC (storage_selected_cb), - sc); - - /* set up the folder etable */ - sc->folder_model = e_tree_simple_new (folder_etable_col_count, - folder_etable_duplicate_value, - folder_etable_free_value, - folder_etable_init_value, - folder_etable_value_is_empty, - folder_etable_value_to_string, - folder_etree_icon_at, - folder_etree_value_at, - folder_etree_set_value_at, - folder_etree_is_editable, - sc); - - sc->folder_root = e_tree_model_node_insert (sc->folder_model, NULL, - 0, NULL); - - e_tree_model_root_node_set_visible (sc->folder_model, FALSE); - e_tree_model_set_expanded_default (sc->folder_model, TRUE); - - toggles[0] = gdk_pixbuf_new_from_xpm_data ((const char **)empty_xpm); - toggles[1] = gdk_pixbuf_new_from_xpm_data ((const char **)mark_xpm); - - extras = e_table_extras_new (); - - cell = e_cell_text_new(NULL, GTK_JUSTIFY_LEFT); - - e_table_extras_add_cell (extras, "cell_text", cell); - e_table_extras_add_cell (extras, "cell_toggle", e_cell_toggle_new (0, 2, toggles)); - e_table_extras_add_cell (extras, "cell_tree", e_cell_tree_new(NULL, NULL, TRUE, cell)); - - gtk_object_set (GTK_OBJECT (cell), - "bold_column", FOLDER_COL_SUBSCRIBED, - NULL); - - e_table_extras_add_pixbuf (extras, "subscribed-image", toggles[1]); - - sc->folder_etable = e_table_scrolled_new (E_TABLE_MODEL(sc->folder_model), - extras, FOLDER_ETABLE_SPEC, NULL); - - gtk_object_sink (GTK_OBJECT (extras)); - gdk_pixbuf_unref(toggles[0]); - gdk_pixbuf_unref(toggles[1]); - - gtk_signal_connect (GTK_OBJECT (E_TABLE_SCROLLED (sc->folder_etable)->table), - "double_click", GTK_SIGNAL_FUNC (folder_toggle_cb), - sc); - gtk_table_attach ( - GTK_TABLE (sc->table), sc->folder_etable, - 0, 1, 1, 3, - GTK_FILL | GTK_EXPAND, - GTK_FILL | GTK_EXPAND, - 0, 0); - - e_paned_add1 (E_PANED (sc->hpaned), sc->store_etable); - e_paned_add2 (E_PANED (sc->hpaned), sc->table); - e_paned_set_position (E_PANED (sc->hpaned), DEFAULT_STORE_TABLE_WIDTH); - - bonobo_window_set_contents (BONOBO_WINDOW (sc->app), sc->hpaned); - -#if 0 - gtk_widget_show (sc->description); -#endif - - gtk_widget_show (sc->folder_etable); - gtk_widget_show (sc->table); - gtk_widget_show (sc->store_etable); - gtk_widget_show (sc->hpaned); - - /* FIXME: Session management and stuff? */ - gtk_window_set_default_size ( - GTK_WINDOW (sc->app), - DEFAULT_WIDTH, DEFAULT_HEIGHT); - - populate_store_list (sc); -} - -static void -subscribe_dialog_destroy (GtkObject *object) -{ - SubscribeDialog *sc; - - sc = SUBSCRIBE_DIALOG (object); - - /* free our folder information */ - e_tree_model_node_remove (sc->folder_model, sc->folder_root); - gtk_object_unref (GTK_OBJECT (sc->folder_model)); - if (sc->folder_info) - camel_store_free_folder_info (sc->store, sc->folder_info); - - /* free our store information */ - gtk_object_unref (GTK_OBJECT (sc->store_model)); - g_list_foreach (sc->store_list, (GFunc)gtk_object_unref, NULL); - - /* free our storage */ - if (sc->storage) - gtk_object_unref (GTK_OBJECT (sc->storage)); - - /* free our search */ - if (sc->search_top) - g_free (sc->search_top); - - subscribe_dialog_parent_class->destroy (object); -} - -static void -subscribe_dialog_class_init (GtkObjectClass *object_class) -{ - object_class->destroy = subscribe_dialog_destroy; - - subscribe_dialog_parent_class = gtk_type_class (PARENT_TYPE); -} - -static void -subscribe_dialog_init (GtkObject *object) -{ -} - -static void -subscribe_dialog_construct (GtkObject *object, Evolution_Shell shell) -{ - SubscribeDialog *sc = SUBSCRIBE_DIALOG (object); - - /* - * Our instance data - */ - sc->shell = shell; - sc->store = NULL; - sc->storage = NULL; - sc->folder_info = NULL; - sc->store_list = NULL; - sc->search_top = NULL; - - subscribe_dialog_gui_init (sc); -} - -GtkWidget * -subscribe_dialog_new (Evolution_Shell shell) -{ - SubscribeDialog *subscribe_dialog; - - subscribe_dialog = gtk_type_new (subscribe_dialog_get_type ()); - - subscribe_dialog_construct (GTK_OBJECT (subscribe_dialog), shell); - - return GTK_WIDGET (subscribe_dialog->app); -} - -E_MAKE_TYPE (subscribe_dialog, "SubscribeDialog", SubscribeDialog, subscribe_dialog_class_init, subscribe_dialog_init, PARENT_TYPE); - diff --git a/mail/subscribe-dialog.h b/mail/subscribe-dialog.h deleted file mode 100644 index 4e1c5a2b49..0000000000 --- a/mail/subscribe-dialog.h +++ /dev/null @@ -1,77 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Authors: Chris Toshok <toshok@helixcode.com> - * - * Copyright 2000 Helix Code, Inc. (www.helixcode.com) - * - * 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 - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA. - * - */ - - -#ifndef _SUBSCRIBE_DIALOG_H_ -#define _SUBSCRIBE_DIALOG_H_ - -#include "mail-types.h" -#include "camel.h" -#include <gtk/gtktable.h> -#include <gal/e-table/e-tree-model.h> -#include <bonobo/bonobo-control.h> -#include <bonobo/bonobo-property-bag.h> -#include "shell/evolution-storage.h" - -#define SUBSCRIBE_DIALOG_TYPE (subscribe_dialog_get_type ()) -#define SUBSCRIBE_DIALOG(o) (GTK_CHECK_CAST ((o), SUBSCRIBE_DIALOG_TYPE, SubscribeDialog)) -#define SUBSCRIBE_DIALOG_CLASS(k) (GTK_CHECK_CLASS_CAST((k), SUBSCRIBE_DIALOG_TYPE, SubscribeDialogClass)) -#define IS_SUBSCRIBE_DIALOG(o) (GTK_CHECK_TYPE ((o), SUBSCRIBE_DIALOG_TYPE)) -#define IS_SUBSCRIBE_DIALOG_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), SUBSCRIBE_DIALOG_TYPE)) - -struct _SubscribeDialog { - GtkObject parent; - - Evolution_Shell shell; - - GtkWidget *app; - - GtkWidget *hpaned; - GtkWidget *table; - GtkWidget *description; - - GtkWidget *store_etable; - ETableModel *store_model; - - GtkWidget *folder_etable; - ETreeModel *folder_model; - ETreePath *folder_root; - - CamelStore *store; - EvolutionStorage *storage; - CamelFolderInfo *folder_info; - - GList *store_list; - - GtkWidget *search_entry; - char *search_top; -}; - - -typedef struct { - GtkObjectClass parent_class; -} SubscribeDialogClass; - -GtkType subscribe_dialog_get_type (void); -GtkWidget *subscribe_dialog_new (Evolution_Shell shell); - -#endif /* _SUBSCRIBE_DIALOG_H_ */ diff --git a/mail/test-mail.c b/mail/test-mail.c deleted file mode 100644 index 917f2a2a2a..0000000000 --- a/mail/test-mail.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Tests the mail summary display bonobo component - * - * Author: - * Miguel de Icaza (miguel@kernel.org) - * - * (C) 2000 Helix Code, Inc. - */ - -#include <config.h> - -#include <gnome.h> -#include <bonobo.h> -#include <liboaf/liboaf.h> - -static guint -create_container (void) -{ - GtkWidget *window, *control; - BonoboUIContainer *container; - - gdk_rgb_init (); - - gtk_widget_set_default_colormap (gdk_rgb_get_cmap ()); - gtk_widget_set_default_visual (gdk_rgb_get_visual ()); - - window = bonobo_window_new ("Test", "test"); - gtk_widget_set_usize (GTK_WIDGET (window), 640, 480); - gtk_widget_show (GTK_WIDGET (window)); - - container = bonobo_ui_container_new (); - bonobo_ui_container_set_win (BONOBO_WINDOW (window), container); - - control = bonobo_widget_new_control ( - "OAFIID:control:evolution-mail:833d5a71-a201-4a0e-b7e6-5475c5c4cb45", - bonobo_object_corba_objref (BONOBO_OBJECT (container))); - - if (control == NULL){ - printf ("Could not launch mail control\n"); - exit (1); - } - gtk_container_add (GTK_CONTAINER (window), control); - - gtk_widget_show (window); - gtk_widget_show (control); - - - return FALSE; -} - -int -main (int argc, char *argv []) -{ - gnome_init ("sample-control-container", "1.0", argc, argv); - oaf_init (argc, argv); - - if (bonobo_init (CORBA_OBJECT_NIL, CORBA_OBJECT_NIL, CORBA_OBJECT_NIL) == FALSE) - g_error ("Could not initialize Bonobo\n"); - - gtk_idle_add ((GtkFunction) create_container, NULL); - - /* - * Main loop - */ - bonobo_main (); - - return 0; -} - - - - - diff --git a/mail/test-thread.c b/mail/test-thread.c deleted file mode 100644 index eddf9dd7c8..0000000000 --- a/mail/test-thread.c +++ /dev/null @@ -1,230 +0,0 @@ -/* Tests the multithreaded UI code */ - -#include "config.h" -#include <unistd.h> -#include <glib.h> -#include <gtk/gtk.h> -#include <libgnomeui/libgnomeui.h> -#include <stdio.h> -#include "mail-threads.h" - -static gchar *desc_1 (gpointer in, gboolean gerund); -static void op_1( gpointer in, gpointer op, CamelException *ex ); -static gchar *desc_2 (gpointer in, gboolean gerund); -static void op_2( gpointer in, gpointer op, CamelException *ex ); -static gchar *desc_3 (gpointer in, gboolean gerund); -static void op_3( gpointer in, gpointer op, CamelException *ex ); -static gchar *desc_4 (gpointer in, gboolean gerund); -static void op_4( gpointer in, gpointer op, CamelException *ex ); -static gchar *desc_5 (gpointer in, gboolean gerund); -static void op_5( gpointer in, gpointer op, CamelException *ex ); -static gchar *desc_6 (gpointer in, gboolean gerund); -static gchar *desc_7 (gpointer in, gboolean gerund); -static gchar *desc_8 (gpointer in, gboolean gerund); -static void done( gpointer in, gpointer op, CamelException *ex ); -static void exception( gpointer in, gpointer op, CamelException *ex ); -static gboolean queue_ops( void ); - -const mail_operation_spec spec1 = { desc_1, 0, NULL, op_1, done }; -const mail_operation_spec spec2 = { desc_2, 0, NULL, op_2, done }; -const mail_operation_spec spec3 = { desc_3, 0, NULL, op_3, done }; -const mail_operation_spec spec4 = { desc_4, 0, NULL, op_4, NULL }; -const mail_operation_spec spec5 = { desc_5, 0, NULL, op_5, done }; -const mail_operation_spec spec6 = { desc_6, 0, exception, op_4, NULL }; -const mail_operation_spec spec7 = { desc_7, 0, NULL, exception, NULL }; -const mail_operation_spec spec8 = { desc_8, 0, NULL, op_4, exception }; - -static gboolean queue_ops( void ) -{ - int i; - - g_message( "Top of queue_ops" ); - - mail_operation_queue( &spec1, "op1 finished", FALSE ); - mail_operation_queue( &spec2, "op2 finished", FALSE ); - mail_operation_queue( &spec3, "op3 finished", FALSE ); - - for( i = 0; i < 3; i++ ) { - mail_operation_queue( &spec4, GINT_TO_POINTER( i ), FALSE ); - } - - g_message( "Waiting for finish..." ); - mail_operation_wait_for_finish(); - - g_message( "Ops done -- queue some more!" ); - - mail_operation_queue( &spec1, "done a second time", FALSE ); - - g_message( "Waiting for finish again..." ); - mail_operation_wait_for_finish(); - - g_message( "Ops done -- more, more!" ); - - mail_operation_queue( &spec5, "passwords stolen", FALSE ); - - for( i = 0; i < 3; i++ ) { - mail_operation_queue( &spec4, GINT_TO_POINTER( i ), FALSE ); - } - - mail_operation_queue( &spec6, NULL, FALSE ); - mail_operation_queue( &spec7, NULL, FALSE ); - mail_operation_queue( &spec8, NULL, FALSE ); - - g_message( "Waiting for finish for the last time..." ); - mail_operations_terminate(); - g_message( "Ops done again. Exiting 0" ); - gtk_exit( 0 ); - return FALSE; -} - -static void exception( gpointer in, gpointer op, CamelException *ex ) -{ - camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, "I don't feel like it."); -} - -static void op_1( gpointer in, gpointer op, CamelException *ex ) -{ - gfloat pct; - - mail_op_show_progressbar(); - mail_op_set_message( "Watch the progress bar!" ); - - for( pct = 0.0; pct < 1.0; pct += 0.2 ) { - sleep( 1 ); - mail_op_set_percentage( pct ); - } -} - -static void op_2( gpointer in, gpointer op, CamelException *ex ) -{ - int i; - - mail_op_hide_progressbar(); - for( i = 5; i > 0; i-- ) { - mail_op_set_message( "%d", i ); - sleep( 1 ); - } - - mail_op_set_message( "BOOOM!" ); - sleep( 1 ); -} - -static void op_3( gpointer in, gpointer op, CamelException *ex ) -{ - gfloat pct; - - mail_op_show_progressbar(); - mail_op_set_message( "Frobulating the foosamatic" ); - - for( pct = 0.0; pct < 0.3; pct += 0.1 ) { - mail_op_set_percentage( pct ); - sleep( 1 ); - } - - mail_op_error( "Oh no! The foosamatic was booby-trapped!" ); - sleep( 1 ); -} - -static void op_4( gpointer in, gpointer op, CamelException *ex ) -{ - mail_op_hide_progressbar(); - mail_op_set_message( "Filler # %d", GPOINTER_TO_INT( in ) ); - sleep( 1 ); -} - -static void op_5( gpointer in, gpointer op, CamelException *ex ) -{ - gchar *pass; - gboolean ret; - - mail_op_show_progressbar(); - mail_op_set_percentage( 0.5 ); - - ret = mail_op_get_password( "What is your super-secret password?", TRUE, &pass ); - - if( ret == FALSE ) - mail_op_set_message( "Oh no, you cancelled! : %s", pass ); - else - mail_op_set_message( "\"%s\", you said?", pass ); - - sleep( 1 ); -} - -static void done( gpointer in, gpointer op, CamelException *ex ) -{ - g_message( "Operation done: %s", (gchar *) in ); -} - -static gchar *desc_1 (gpointer in, gboolean gerund) -{ - if (gerund) - return g_strdup ("Showing the Crawling Progress Bar of Doom"); - else - return g_strdup ("Progress Bar"); -} - -static gchar *desc_2 (gpointer in, gboolean gerund) -{ - if (gerund) - return g_strdup ("Exploring the Mysterious Message Setter"); - else - return g_strdup ("Explore"); -} - -static gchar *desc_3 (gpointer in, gboolean gerund) -{ - if (gerund) - return g_strdup ("Dare the Error Dialog of No Return"); - else - return g_strdup ("Dare"); -} - -static gchar *desc_4 (gpointer in, gboolean gerund) -{ - if (gerund) - return g_strdup_printf ("Filling Queue Space -- %d", GPOINTER_TO_INT (in)); - else - return g_strdup_printf ("Filler -- %d", GPOINTER_TO_INT (in)); -} - -static gchar *desc_5 (gpointer in, gboolean gerund) -{ - if (gerund) - return g_strdup ("Stealing your Password"); - else - return g_strdup ("The Dastardly Password Stealer"); -} - -static gchar *desc_6 (gpointer in, gboolean gerund) -{ - if (gerund) - return g_strdup ("Setting exception on setup"); - else - return g_strdup ("Exception on setup"); -} - -static gchar *desc_7 (gpointer in, gboolean gerund) -{ - if (gerund) - return g_strdup ("Setting exception in process"); - else - return g_strdup ("Exception coming soon"); -} - -static gchar *desc_8 (gpointer in, gboolean gerund) -{ - if (gerund) - return g_strdup ("Setting exception in cleanup"); - else - return g_strdup ("Exception in cleanup"); -} - - -int main( int argc, char **argv ) -{ - g_thread_init( NULL ); - gnome_init( "test-thread", "0.0", argc, argv ); - gtk_idle_add( (GtkFunction) queue_ops, NULL ); - gtk_main(); - return 0; -} |