diff options
author | nobody <nobody@localhost> | 2000-08-22 20:05:30 +0800 |
---|---|---|
committer | nobody <nobody@localhost> | 2000-08-22 20:05:30 +0800 |
commit | 9175a4df8da8389d0ce5e0bc22a6ac3a64278735 (patch) | |
tree | 3b4824784cd30983db4a6ae1f38db287d5815941 /mail | |
parent | 44ae37c371e25fe05e8aee145f1d9af7130a201d (diff) | |
download | gsoc2013-evolution-GNOME_CORE_1_2_3.tar gsoc2013-evolution-GNOME_CORE_1_2_3.tar.gz gsoc2013-evolution-GNOME_CORE_1_2_3.tar.bz2 gsoc2013-evolution-GNOME_CORE_1_2_3.tar.lz gsoc2013-evolution-GNOME_CORE_1_2_3.tar.xz gsoc2013-evolution-GNOME_CORE_1_2_3.tar.zst gsoc2013-evolution-GNOME_CORE_1_2_3.zip |
This commit was manufactured by cvs2svn to create tagGNOME_CORE_1_2_3
'GNOME_CORE_1_2_3'.
svn path=/tags/GNOME_CORE_1_2_3/; revision=4939
Diffstat (limited to 'mail')
54 files changed, 0 insertions, 21622 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 e05e83f780..0000000000 --- a/mail/ChangeLog +++ /dev/null @@ -1,3693 +0,0 @@ -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-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 2be622f3f6..0000000000 --- a/mail/GNOME_Evolution_Mail.oaf.in +++ /dev/null @@ -1,54 +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_server> - -</oaf_info> diff --git a/mail/GNOME_Evolution_Mail.oafinfo b/mail/GNOME_Evolution_Mail.oafinfo deleted file mode 100644 index 2be622f3f6..0000000000 --- a/mail/GNOME_Evolution_Mail.oafinfo +++ /dev/null @@ -1,54 +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_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 cf13d00c54..0000000000 --- a/mail/Makefile.am +++ /dev/null @@ -1,145 +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) \ - -I$(top_srcdir)/camel \ - -I$(top_builddir)/shell \ - -I$(top_srcdir)/shell \ - $(BONOBO_HTML_GNOME_CFLAGS) \ - $(GNOME_VFS_CFLAGS) \ - $(UNICODE_CFLAGS) \ - $(GTKHTML_CFLAGS) \ - -DEVOLUTION_VERSION=\""$(VERSION)"\" \ - -DEVOLUTION_GLADEDIR=\""$(gladedir)"\" \ - -DEVOLUTION_ICONSDIR=\""$(iconsdir)"\" \ - -DEVOLUTION_LOCALEDIR=\""$(datadir)/locale"\" \ - -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-config.c \ - mail-config.h \ - mail-config-gui.c \ - mail-config-gui.h \ - mail-crypto.c \ - mail-display.c \ - mail-display.h \ - mail-format.c \ - mail-identify.c \ - mail-local.c \ - mail-local.h \ - mail-ops.c \ - mail-ops.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.h - -evolution_mail_LDADD = \ - $(top_builddir)/shell/libeshell.a \ - $(top_builddir)/composer/libcomposer.la \ - $(top_builddir)/widgets/e-paned/libepaned.a \ - $(top_builddir)/widgets/misc/libemiscwidgets.a \ - $(top_builddir)/widgets/e-table/libetable.a \ - $(top_builddir)/widgets/e-text/libetext.a \ - $(CAMEL_OBJS_EXTRA) \ - $(top_builddir)/camel/libcamel.la \ - $(top_builddir)/e-util/libeutil.la \ - $(top_builddir)/libibex/libibex.la \ - $(top_builddir)/filter/libfilter.la \ - $(BONOBO_VFS_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) - -GOAD_FILES = evolution-mail.gnorba -OAF_FILES = evolution-mail.oafinfo - -if USING_OAF -oafdir = $(datadir)/oaf -oaf_DATA = $(OAF_FILES) -else -gnorbadir = $(sysconfdir)/CORBA/servers -gnorba_DATA = $(GOAD_FILES) -endif - -gladedir = $(datadir)/evolution/glade -glade_DATA = mail-config.glade mail-config-druid.glade local-config.glade - -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) $(GOAD_FILES) $(OAF_FILES) - -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 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 eaabce8e38..0000000000 --- a/mail/component-factory.c +++ /dev/null @@ -1,276 +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 "e-util/e-gui-utils.h" - -#include "component-factory.h" - -CamelFolder *drafts_folder = NULL; -char *evolution_dir; - -static void create_vfolder_storage (EvolutionShellComponent *shell_component); -static void create_imap_storage (EvolutionShellComponent *shell_component, - const char *source); -static void create_news_storage (EvolutionShellComponent *shell_component); - -#define COMPONENT_FACTORY_ID "OAFIID:evolution-shell-component-factory:evolution-mail:0ea887d5-622b-4b8c-b525-18aa1cbe18a6" - -static BonoboGenericFactory *factory = NULL; -static gint running_objects = 0; - -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) -{ - BonoboControl *control; - GtkWidget *folder_browser_widget; - - if (g_strcasecmp (folder_type, "mail") != 0) - return EVOLUTION_SHELL_COMPONENT_UNSUPPORTEDTYPE; - - control = folder_browser_factory_new_control (physical_uri); - 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; - MailConfigService *s; - - g_print ("evolution-mail: Yeeeh! We have an owner!\n"); /* FIXME */ - - evolution_dir = g_strdup (evolution_homedir); - - mail_config_init (); - mail_do_setup_draftbox (); - create_vfolder_storage (shell_component); - create_news_storage (shell_component); - - sources = mail_config_get_sources (); - while (sources) { - s = sources->data; - if (!g_strncasecmp (s->url, "imap:", 5)) - create_imap_storage (shell_component, s->url); - sources = sources->next; - } -} - -static void -owner_unset_cb (EvolutionShellComponent *shell_component, gpointer user_data) -{ - mail_operations_terminate (); - gtk_main_quit (); -} - -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; - - gtk_main_quit (); -} - -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); - - if (factory == NULL) { - e_notice (NULL, GNOME_MESSAGE_BOX_ERROR, - _("Cannot initialize Evolution's mail component.")); - exit (1); - } -} - -/* FIXME: remove */ -static void -create_vfolder_storage (EvolutionShellComponent *shell_component) -{ - void vfolder_create_storage(EvolutionShellComponent *shell_component); - - vfolder_create_storage(shell_component); -} - -static void -create_imap_storage (EvolutionShellComponent *shell_component, - const char *source) -{ - EvolutionShellClient *shell_client; - Evolution_Shell corba_shell; - EvolutionStorage *storage; - char *server, *p; - - shell_client = evolution_shell_component_get_owner (shell_component); - if (shell_client == NULL) { - g_warning ("We have no shell!?"); - return; - } - - corba_shell = bonobo_object_corba_objref (BONOBO_OBJECT (shell_client)); - - if (!(server = strchr (source, '@'))) - return; - - server++; - for (p = server; *p && *p != '/'; p++); - - server = g_strndup (server, (gint)(p - server)); - - storage = evolution_storage_new (server); - g_free (server); - - if (evolution_storage_register_on_shell (storage, corba_shell) != EVOLUTION_STORAGE_OK) { - g_warning ("Cannot register storage"); - return; - } - - mail_do_scan_subfolders (source, storage); -} - -static void -create_news_storage (EvolutionShellComponent *shell_component) -{ - const MailConfigService *s; - EvolutionShellClient *shell_client; - Evolution_Shell corba_shell; - EvolutionStorage *storage; - char *source = NULL, *server, *p; - - s = mail_config_get_default_news (); - if (s) - source = s->url; - - if (!source || g_strncasecmp (source, "news://", 7)) - return; - - shell_client = evolution_shell_component_get_owner (shell_component); - if (shell_client == NULL) { - g_warning ("We have no shell!?"); - return; - } - - corba_shell = bonobo_object_corba_objref (BONOBO_OBJECT (shell_client)); - - server = source + 7; - for (p = server; *p && *p != '/'; p++); - - server = g_strndup (server, (gint)(p - server)); - - storage = evolution_storage_new (server); - g_free (server); - - if (evolution_storage_register_on_shell (storage, corba_shell) != EVOLUTION_STORAGE_OK) { - g_warning ("Cannot register storage"); - return; - } - - mail_do_scan_subfolders (source, 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.gnorba b/mail/evolution-mail.gnorba deleted file mode 100644 index b799a57aa2..0000000000 --- a/mail/evolution-mail.gnorba +++ /dev/null @@ -1,23 +0,0 @@ -[control-factory:evolution-mail] -type=exe -repo_id=IDL:GNOME/GenericFactory:1.0 -description=Evolution mail folder factory component. -location_info=evolution-mail - -[control:evolution-mail] -type=factory -repo_id=IDL:BonoboControl/evolution-mail:1.0 IDL:GNOME/Control:1.0 -description=Evolution mail folder display component. -location_info=control-factory:evolution-mail - -[evolution-shell-component-factory:evolution-mail] -type=exe -repo_id=IDL:GNOME/GenericFactory:1.0 -description=Factory for the Evolution mail component. -location_info=evolution-mail - -[evolution-shell-component:evolution-mail] -type=factory -repo_id=IDL:Evolution/ShellComponent:1.0 -description=Evolution component for handling mail. -location_info=evolution-shell-component-factory:evolution-mail diff --git a/mail/evolution-mail.oafinfo b/mail/evolution-mail.oafinfo deleted file mode 100644 index 2be622f3f6..0000000000 --- a/mail/evolution-mail.oafinfo +++ /dev/null @@ -1,54 +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_server> - -</oaf_info> diff --git a/mail/folder-browser-factory.c b/mail/folder-browser-factory.c deleted file mode 100644 index fcb1242286..0000000000 --- a/mail/folder-browser-factory.c +++ /dev/null @@ -1,349 +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 "e-util/e-util.h" -#include "e-util/e-gui-utils.h" - -#include "folder-browser-factory.h" - -#include "folder-browser.h" -#include "mail.h" -#include "shell/Evolution.h" -#include "mail-config.h" - -/* The FolderBrowser BonoboControls we have. */ -static GList *control_list = NULL; - -static GnomeUIInfo gnome_toolbar [] = { - GNOMEUIINFO_ITEM_STOCK (N_("Get mail"), N_("Check for new mail"), fetch_mail, GNOME_STOCK_PIXMAP_MAIL_RCV), - GNOMEUIINFO_ITEM_STOCK (N_("Compose"), N_("Compose a new message"), compose_msg, GNOME_STOCK_PIXMAP_MAIL_NEW), - - GNOMEUIINFO_SEPARATOR, - - GNOMEUIINFO_ITEM_STOCK (N_("Reply"), N_("Reply to the sender of this message"), reply_to_sender, GNOME_STOCK_PIXMAP_MAIL_RPL), - GNOMEUIINFO_ITEM_STOCK (N_("Reply to All"), N_("Reply to all recipients of this message"), reply_to_all, GNOME_STOCK_PIXMAP_MAIL_RPL), - - GNOMEUIINFO_ITEM_STOCK (N_("Forward"), N_("Forward this message"), forward_msg, GNOME_STOCK_PIXMAP_MAIL_FWD), - - GNOMEUIINFO_SEPARATOR, - - GNOMEUIINFO_ITEM_STOCK (N_("Move"), N_("Move message to a new folder"), move_msg, GNOME_STOCK_PIXMAP_MAIL_SND), - GNOMEUIINFO_ITEM_STOCK (N_("Copy"), N_("Copy message to a new folder"), copy_msg, GNOME_STOCK_PIXMAP_MAIL_SND), - - GNOMEUIINFO_ITEM_STOCK (N_("Print"), N_("Print the selected message"), print_msg, GNOME_STOCK_PIXMAP_PRINT), - - GNOMEUIINFO_ITEM_STOCK (N_("Delete"), N_("Delete this message"), delete_msg, GNOME_STOCK_PIXMAP_TRASH), - - GNOMEUIINFO_END -}; - -static void -register_ondemand (RuleContext *f, FilterRule *rule, gpointer data) -{ - FolderBrowser *fb = FOLDER_BROWSER (data); - BonoboUIHandler *uih = gtk_object_get_data (GTK_OBJECT (fb), "uih"); - gchar *text; - struct fb_ondemand_closure *oc; - - oc = g_new (struct fb_ondemand_closure, 1); - oc->rule = rule; - oc->fb = fb; - oc->path = g_strdup_printf ("/<Component Placeholder>/Folder/Filter-%s", rule->name); - - if (fb->filter_menu_paths == NULL) - bonobo_ui_handler_menu_new_separator (uih, "/<Component Placeholder>/Folder/separator1", -1); - - text = g_strdup_printf (_("Run filter \"%s\""), rule->name); - fb->filter_menu_paths = g_slist_prepend (fb->filter_menu_paths, oc); - - bonobo_ui_handler_menu_new_item (uih, oc->path, text, - NULL, -1, - BONOBO_UI_HANDLER_PIXMAP_NONE, - 0, - 0, 0, run_filter_ondemand, oc); - g_free (text); -} - -static void -create_ondemand_hooks (FolderBrowser *fb, BonoboUIHandler *uih) -{ - gchar *system, *user; - - user = g_strdup_printf ("%s/filters.xml", evolution_dir); - system = EVOLUTION_DATADIR "/evolution/filtertypes.xml"; - fb->filter_context = filter_context_new(); - gtk_object_set_data (GTK_OBJECT (fb), "uih", uih); - rule_context_load ((RuleContext *) fb->filter_context, system, user, - register_ondemand, fb); - gtk_object_remove_data (GTK_OBJECT (fb), "uih"); - g_free (user); -} - -static void -remove_ondemand_hooks (FolderBrowser *fb, BonoboUIHandler *uih) -{ - GSList *iter; - struct fb_ondemand_closure *oc; - - for (iter = fb->filter_menu_paths; iter; iter = iter->next) { - oc = (struct fb_ondemand_closure *) iter->data; - - bonobo_ui_handler_menu_remove (uih, oc->path); - } -} - -static void -control_activate (BonoboControl *control, BonoboUIHandler *uih, - FolderBrowser *fb) -{ - Bonobo_UIHandler remote_uih; - BonoboControl *toolbar_control; - GnomeDockItemBehavior behavior; - GtkWidget *toolbar, *toolbar_frame, *folder_browser; - char *toolbar_name = g_strdup_printf ("/Toolbar%d", fb->serial); - - remote_uih = bonobo_control_get_remote_ui_handler (control); - bonobo_ui_handler_set_container (uih, remote_uih); - bonobo_object_release_unref (remote_uih, NULL); - - folder_browser = bonobo_control_get_widget (control); - - bonobo_ui_handler_menu_new_toggleitem (uih, "/View/Threaded", - _("_Threaded Message List"), - NULL, -1, 0, 0, NULL, NULL); - bonobo_ui_handler_menu_set_toggle_state (uih, "/View/Threaded", - mail_config_thread_list()); - bonobo_ui_handler_menu_set_callback (uih, "/View/Threaded", - message_list_toggle_threads, - FOLDER_BROWSER (folder_browser)->message_list, - NULL); - - bonobo_ui_handler_menu_new_item (uih, "/File/<Print Placeholder>/Print message...", - _("_Print Message"), - NULL, -1, - BONOBO_UI_HANDLER_PIXMAP_STOCK, - GNOME_STOCK_MENU_PRINT, - 0, 0, (void *) print_msg, folder_browser); - - bonobo_ui_handler_menu_new_separator (uih, "/File/<Print Placeholder>/separator1", -1); - - bonobo_ui_handler_menu_new_subtree (uih, "/<Component Placeholder>/Folder", - _("F_older"), - NULL, -1, - BONOBO_UI_HANDLER_PIXMAP_NONE, NULL, - 0, 0); - - bonobo_ui_handler_menu_new_item (uih, "/<Component Placeholder>/Folder/Mark all as Read", - _("_Mark all as Read"), - NULL, -1, - BONOBO_UI_HANDLER_PIXMAP_NONE, NULL, - 0, 0, mark_all_seen, folder_browser); - - bonobo_ui_handler_menu_new_item (uih, "/<Component Placeholder>/Folder/Expunge", - _("_Expunge"), - NULL, -1, - BONOBO_UI_HANDLER_PIXMAP_STOCK, - GNOME_STOCK_MENU_TRASH, - 0, 0, expunge_folder, folder_browser); - - bonobo_ui_handler_menu_new_item (uih, "/<Component Placeholder>/Folder/Configure Folder", - _("_Configure Folder"), - NULL, -1, - BONOBO_UI_HANDLER_PIXMAP_NONE, - 0, - 0, 0, configure_folder, folder_browser); - - bonobo_ui_handler_menu_new_subtree (uih, "/<Component Placeholder>/Message", - _("_Message"), - NULL, -1, - BONOBO_UI_HANDLER_PIXMAP_NONE, NULL, - 0, 0); - - bonobo_ui_handler_menu_new_item (uih, "/<Component Placeholder>/Message/Edit", - _("E_dit"), - NULL, -1, - BONOBO_UI_HANDLER_PIXMAP_STOCK, - GNOME_STOCK_MENU_MAIL, - 0, 0, edit_message, folder_browser); - - bonobo_ui_handler_menu_new_item (uih, "/<Component Placeholder>/Message/View", - _("_View"), - NULL, -1, - BONOBO_UI_HANDLER_PIXMAP_STOCK, - GNOME_STOCK_MENU_MAIL, - 0, 0, view_message, folder_browser); - - bonobo_ui_handler_menu_new_item (uih, "/Settings/Mail Filters ...", - _("Mail _Filters ..."), - NULL, -1, - BONOBO_UI_HANDLER_PIXMAP_NONE, - 0, - 0, 0, filter_edit, folder_browser); - - bonobo_ui_handler_menu_new_item (uih, "/Settings/vFolder Editor ...", - _("_vFolder Editor ..."), - NULL, -1, - BONOBO_UI_HANDLER_PIXMAP_NONE, - 0, - 0, 0, vfolder_edit_vfolders, folder_browser); - - bonobo_ui_handler_menu_new_item (uih, "/Settings/Mail Configuration ...", - _("_Mail Configuration ..."), - NULL, -1, - BONOBO_UI_HANDLER_PIXMAP_NONE, - 0, - 0, 0, (void *) mail_config, NULL); - - bonobo_ui_handler_menu_new_item (uih, "/Settings/Forget Passwords", - _("Forget _Passwords"), - NULL, -1, - BONOBO_UI_HANDLER_PIXMAP_NONE, - 0, - 0, 0, forget_passwords, NULL); - - create_ondemand_hooks (fb, uih); - - toolbar = gtk_toolbar_new (GTK_ORIENTATION_HORIZONTAL, - GTK_TOOLBAR_BOTH); - - gnome_app_fill_toolbar_with_data (GTK_TOOLBAR (toolbar), - gnome_toolbar, - NULL, folder_browser); - - gtk_widget_show_all (toolbar); - - behavior = GNOME_DOCK_ITEM_BEH_EXCLUSIVE | - GNOME_DOCK_ITEM_BEH_NEVER_VERTICAL; - if (!gnome_preferences_get_toolbar_detachable ()) - behavior |= GNOME_DOCK_ITEM_BEH_LOCKED; - - toolbar_frame = gtk_frame_new (NULL); - gtk_frame_set_shadow_type (GTK_FRAME (toolbar_frame), GTK_SHADOW_OUT); - gtk_container_add (GTK_CONTAINER (toolbar_frame), toolbar); - gtk_widget_show (toolbar_frame); - - gtk_widget_show_all (toolbar_frame); - - toolbar_control = bonobo_control_new (toolbar_frame); - bonobo_ui_handler_dock_add (uih, toolbar_name, - bonobo_object_corba_objref (BONOBO_OBJECT (toolbar_control)), - behavior, - GNOME_DOCK_TOP, - 1, 1, 0); - g_free (toolbar_name); -} - -static void -control_deactivate (BonoboControl *control, - BonoboUIHandler *uih, - FolderBrowser *fb) -{ - char *toolbar_name = g_strdup_printf ("/Toolbar%d", fb->serial); - - bonobo_ui_handler_menu_remove (uih, "/File/<Print Placeholder>/separator1"); - bonobo_ui_handler_menu_remove (uih, "/File/<Print Placeholder>/Print message..."); - - bonobo_ui_handler_menu_remove (uih, "/View/Threaded"); - - bonobo_ui_handler_menu_remove (uih, "/<Component Placeholder>/Folder"); - bonobo_ui_handler_menu_remove (uih, "/<Component Placeholder>/Folder/Mark all as Read"); - bonobo_ui_handler_menu_remove (uih, "/<Component Placeholder>/Folder/Expunge"); - bonobo_ui_handler_menu_remove (uih, "/<Component Placeholder>/Folder/Configure Folder"); - - bonobo_ui_handler_menu_remove (uih, "/<Component Placeholder>/Message"); - bonobo_ui_handler_menu_remove (uih, "/<Component Placeholder>/Message/Edit"); - bonobo_ui_handler_menu_remove (uih, "/<Component Placeholder>/Message/View"); - - bonobo_ui_handler_menu_remove (uih, "/Settings/Mail Filters ..."); - bonobo_ui_handler_menu_remove (uih, "/Settings/vFolder Editor ..."); - bonobo_ui_handler_menu_remove (uih, "/Settings/Mail Configuration ..."); - bonobo_ui_handler_menu_remove (uih, "/Settings/Forget Passwords"); - - bonobo_ui_handler_dock_remove (uih, toolbar_name); - g_free (toolbar_name); - - remove_ondemand_hooks (fb, uih); -} - -static void -control_activate_cb (BonoboControl *control, - gboolean activate, - gpointer user_data) -{ - BonoboUIHandler *uih; - - uih = bonobo_control_get_ui_handler (control); - g_assert (uih); - - if (activate) - control_activate (control, uih, user_data); - else - control_deactivate (control, uih, 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) -{ - BonoboControl *control; - GtkWidget *folder_browser; - - folder_browser = folder_browser_new (); - 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 7af5028ada..0000000000 --- a/mail/folder-browser-factory.h +++ /dev/null @@ -1,19 +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> - -BonoboControl *folder_browser_factory_new_control (const char *uri); -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 44da49e0e4..0000000000 --- a/mail/folder-browser.c +++ /dev/null @@ -1,451 +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-util.h" -#include "e-util/e-sexp.h" -#include "folder-browser.h" -#include "mail.h" -#include "mail-tools.h" -#include "message-list.h" -#include "mail-threads.h" -#include "mail-ops.h" -#include <widgets/e-paned/e-vpaned.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 "mail-local.h" -#include "mail-config.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 = FOLDER_BROWSER (object); - - if (folder_browser->shell) { - CORBA_Environment ev; - - CORBA_exception_init (&ev); - Bonobo_Unknown_unref (folder_browser->shell, &ev); - CORBA_exception_free (&ev); - } - - if (folder_browser->uri) - 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); - } - - 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) -{ - 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[] = { - "Body or subject contains", - "Body contains", - "Subject contains", - "Body does not contain", - "Subject does not contain", - 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)))" -}; - -static void -search_set(FolderBrowser *fb) -{ - GtkWidget *widget; - GString *out; - char *str; - int index; - char *text; - - text = gtk_entry_get_text((GtkEntry *)fb->search_entry); - - if (text == NULL || text[0] == 0) { - mail_do_regenerate_messagelist (fb->message_list, NULL); - return; - } - - 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 > 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++; - } - } - mail_do_regenerate_messagelist (fb->message_list, out->str); - g_string_free(out, TRUE); -} - -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; - - 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 = gtk_entry_get_text((GtkEntry *)fb->search_entry); - - if (text == NULL || text[0] == 0) { - return; - } - - widget = gtk_menu_get_active (GTK_MENU(GTK_OPTION_MENU(fb->search_menu)->menu)); - index = (int)gtk_object_get_data((GtkObject *)widget, "search_option"); - 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) { - 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); -} - -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); - mail_do_regenerate_messagelist (fb->message_list, NULL); -} - -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; - - if (ev->key.keyval == GDK_space || ev->key.keyval == 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; - } else if (ev->key.keyval == GDK_Delete || - ev->key.keyval == GDK_KP_Delete) { - delete_msg (NULL, fb); - message_list_select (fb->message_list, row, - MESSAGE_LIST_SELECT_NEXT, - 0, CAMEL_MESSAGE_DELETED); - return TRUE; - } else if (ev->key.keyval == 'n' || ev->key.keyval == 'N' || - ev->key.keyval == 'p' || ev->key.keyval == 'P') { - message_list_select (fb->message_list, row, - tolower (ev->key.keyval) == 'p' ? - MESSAGE_LIST_SELECT_PREVIOUS : - MESSAGE_LIST_SELECT_NEXT, - 0, CAMEL_MESSAGE_SEEN); - } - - return FALSE; -} - -static void -folder_browser_gui_init (FolderBrowser *fb) -{ - GtkWidget *hbox, *label; - GtkButton *button; - - /* - * 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); - /* gtk_signal_connect(fb->search_entry, "changed", search_activate, fb); */ - 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); - gtk_signal_connect((GtkObject *)button, "clicked", search_save, fb); - gtk_box_pack_end((GtkBox *)hbox, (GtkWidget *)button, 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_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); - - /* (jwise) <-- for searching purposes :) */ - 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 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 = MESSAGE_LIST (message_list_new (fb)); - fb->mail_display = MAIL_DISPLAY (mail_display_new ()); - - gtk_signal_connect (GTK_OBJECT (fb->message_list->etable), - "key_press", GTK_SIGNAL_FUNC (etable_key), fb); - - fb->filter_menu_paths = NULL; - fb->filter_context = NULL; - - folder_browser_gui_init (fb); -} - -GtkWidget * -folder_browser_new (void) -{ - static int serial; - FolderBrowser *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++; - - 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 + 90); -} diff --git a/mail/folder-browser.h b/mail/folder-browser.h deleted file mode 100644 index 86c1c6f149..0000000000 --- a/mail/folder-browser.h +++ /dev/null @@ -1,73 +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; - - 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 (void); -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); - -#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 2de013a448..0000000000 --- a/mail/mail-autofilter.c +++ /dev/null @@ -1,265 +0,0 @@ -/* - code for autogenerating rules or filters from a message -*/ - -#include <ctype.h> - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <bonobo.h> - -#include <libgnomeui/gnome-app-helper.h> -#include <libgnomeui/gnome-popup-menu.h> - -#include "Evolution.h" -#include "evolution-storage.h" - -#include "evolution-shell-component.h" -#include "folder-browser.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 *s) -{ - const char *p; - - 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 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, "contains"); - 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) { - rule_match_subject(context, rule, msg->subject); - filter_rule_set_name(rule, strip_re(msg->subject)); - } - /* 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) - 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, NULL, NULL); - rule = filter_rule_from_message(fc, msg, flags); - rule_context_add_rule_gui((RuleContext *)fc, rule, "Add Filter Rule", userrules); - g_free (userrules); - g_free (systemrules); - gtk_object_unref((GtkObject *)fc); -} - diff --git a/mail/mail-autofilter.h b/mail/mail-autofilter.h deleted file mode 100644 index 61df9273fd..0000000000 --- a/mail/mail-autofilter.h +++ /dev/null @@ -1,21 +0,0 @@ -#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); - -#endif diff --git a/mail/mail-callbacks.c b/mail/mail-callbacks.c deleted file mode 100644 index 33b44c1c6c..0000000000 --- a/mail/mail-callbacks.c +++ /dev/null @@ -1,654 +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 <errno.h> -#include <gnome.h> -#include <libgnomeprint/gnome-print-master.h> -#include <libgnomeprint/gnome-print-master-preview.h> -#include "mail.h" -#include "mail-config.h" -#include "mail-threads.h" -#include "mail-tools.h" -#include "mail-ops.h" -#include "mail-local.h" -#include "folder-browser.h" -#include "filter/filter-editor.h" -#include "filter/filter-driver.h" -#include "widgets/e-table/e-table.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 (void) -{ - if (mail_config_is_configured ()) - return TRUE; - - mail_config_druid (); - - return mail_config_is_configured (); -} - -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, -1, 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 *button, gpointer user_data) -{ - GSList *sources; - - if (!check_configured ()) { - 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); - } -} - -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); - - GDK_THREADS_ENTER (); - button = gnome_dialog_run_and_close (GNOME_DIALOG (message_box)); - GDK_THREADS_LEAVE (); - - if (button == 0) - return TRUE; - else - return FALSE; -} - -void -composer_send_cb (EMsgComposer *composer, gpointer data) -{ - gchar *from = NULL; - const MailConfigIdentity *id = NULL; - MailConfigService *xport = NULL; - CamelMimeMessage *message; - const char *subject; - - struct post_send_data *psd = data; - - /* Check for an identity */ - - id = mail_config_get_default_identity (); - if (!check_configured () || !id) { - GtkWidget *message; - - message = gnome_warning_dialog_parented (_("You need to configure an identity\n" - "before you can send mail."), - GTK_WINDOW (gtk_widget_get_ancestor (GTK_WIDGET (composer), - GTK_TYPE_WINDOW))); - GDK_THREADS_ENTER (); - gnome_dialog_run_and_close (GNOME_DIALOG (message)); - GDK_THREADS_LEAVE (); - return; - } - - /* 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 send mail."), - GTK_WINDOW (gtk_widget_get_ancestor (GTK_WIDGET (composer), - GTK_TYPE_WINDOW))); - GDK_THREADS_ENTER (); - gnome_dialog_run_and_close (GNOME_DIALOG (message)); - GDK_THREADS_LEAVE (); - return; - } - - /* Generate our from address */ - - from = g_strdup (e_msg_composer_hdrs_get_from (E_MSG_COMPOSER_HDRS (composer->hdrs))); - if (!from) { - CamelInternetAddress *ciaddr; - - ciaddr = camel_internet_address_new (); - camel_internet_address_add (ciaddr, id->name, id->address); - from = camel_address_encode (CAMEL_ADDRESS (ciaddr)); - camel_object_unref (CAMEL_OBJECT (ciaddr)); - } - - /* 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; - } - } - - if (psd) { - mail_do_send_mail (xport->url, message, from, - psd->folder, psd->uid, psd->flags, - GTK_WIDGET (composer)); - g_free (psd->uid); - } else { - mail_do_send_mail (xport->url, message, from, - NULL, NULL, 0, - GTK_WIDGET (composer)); - } -} - -static void -free_psd (GtkWidget *composer, gpointer user_data) -{ - struct post_send_data *psd = user_data; - - camel_object_unref (CAMEL_OBJECT (psd->folder)); - g_free (psd); -} - - -static GtkWidget * -create_msg_composer (const char *url) -{ - MailConfigIdentity *id; - gboolean send_html; - gchar *sig_file = NULL; - GtkWidget *composer_widget; - - id = mail_config_get_default_identity (); - send_html = mail_config_send_html (); - - if (id) - sig_file = id->sig; - - if (url != NULL) - composer_widget = e_msg_composer_new_from_url (url); - else - composer_widget = e_msg_composer_new_with_sig_file (sig_file); - - e_msg_composer_set_send_html (E_MSG_COMPOSER (composer_widget), - send_html); - - return composer_widget; -} - -void -compose_msg (GtkWidget *widget, gpointer user_data) -{ - GtkWidget *composer; - - if (!check_configured ()) - return; - - composer = create_msg_composer (NULL); - - gtk_signal_connect (GTK_OBJECT (composer), "send", - GTK_SIGNAL_FUNC (composer_send_cb), NULL); - gtk_widget_show (composer); -} - -/* Send according to a mailto (RFC 2368) URL. */ -void -send_to_url (const char *url) -{ - GtkWidget *composer; - - if (!check_configured ()) - return; - - composer = create_msg_composer (url); - - gtk_signal_connect (GTK_OBJECT (composer), "send", - GTK_SIGNAL_FUNC (composer_send_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; - - if (!check_configured () || !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); - - gtk_signal_connect (GTK_OBJECT (composer), "send", - GTK_SIGNAL_FUNC (composer_send_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); - - 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); - - mail_reply (fb->folder, fb->mail_display->current_message, - fb->message_list->cursor_uid, TRUE); -} - -static 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_configured () || !cursor_msg) - return; - - composer = E_MSG_COMPOSER (e_msg_composer_new ()); - - 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); - - 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 -mark_all_seen (BonoboUIHandler *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 = camel_folder_get_uids (ml->folder); - mail_do_flag_messages (ml->folder, uids, FALSE, - CAMEL_MESSAGE_SEEN, CAMEL_MESSAGE_SEEN); -} - -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.")); - GDK_THREADS_ENTER (); - gnome_dialog_run_and_close (GNOME_DIALOG (message)); - GDK_THREADS_LEAVE (); - return; - } - - uids = g_ptr_array_new(); - message_list_foreach (fb->message_list, enumerate_msg, uids); - 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); - if (uids->len == 1) { - guint32 flags; - char *uid = uids->pdata[0]; - - mail_tool_camel_lock_up (); - flags = camel_folder_get_message_flags (ml->folder, uid); - camel_folder_set_message_flags (ml->folder, uid, - CAMEL_MESSAGE_DELETED, - ~flags); - mail_tool_camel_lock_down (); - } else { - mail_do_flag_messages (ml->folder, uids, TRUE, - CAMEL_MESSAGE_DELETED, - CAMEL_MESSAGE_DELETED); - } -} - -void -expunge_folder (BonoboUIHandler *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 (BonoboUIHandler *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, NULL, NULL); - 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); - - /* These are necessary because gtk_main, called by - * g_d_r_a_c, does a LEAVE/ENTER pair when running - * a main loop recursively. I don't know why the threads - * lock isn't being held at this point, as we're in a - * callback, but I don't ask questions. It works, and - * threads are enabled so we know that it works. - */ - GDK_THREADS_ENTER(); - gnome_dialog_run_and_close (GNOME_DIALOG (dialog)); - GDK_THREADS_LEAVE(); - 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 (BonoboUIHandler *uih, void *user_data, const char *path) -{ - void vfolder_edit(void); - - vfolder_edit(); -} - -/* - *void - *providers_config (BonoboUIHandler *uih, void *user_data, const char *path) - *{ - * mail_config(); - *} - */ - -void -mail_print_msg (MailDisplay *md) -{ - GnomePrintMaster *print_master; - GnomePrintContext *print_context; - GtkWidget *preview; - - print_master = gnome_print_master_new (); - - print_context = gnome_print_master_get_context (print_master); - gtk_html_print (md->html, print_context); - - preview = GTK_WIDGET (gnome_print_master_preview_new ( - print_master, "Mail Print Preview")); - gtk_widget_show (preview); - - gtk_object_unref (GTK_OBJECT (print_master)); -} - -void -print_msg (GtkWidget *button, gpointer user_data) -{ - FolderBrowser *fb = user_data; - - mail_print_msg (fb->mail_display); -} - -void -configure_folder(BonoboUIHandler *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 (BonoboUIHandler *uih, void *user_data, const char *path) -{ - view_msg (NULL, user_data); -} - -void -edit_message (BonoboUIHandler *uih, void *user_data, const char *path) -{ - edit_msg (NULL, user_data); -} - -void -run_filter_ondemand (BonoboUIHandler *uih, gpointer user_data, const char *path) -{ - struct fb_ondemand_closure *oc = (struct fb_ondemand_closure *) user_data; - FilterDriver *d; - - if (oc->fb->folder == NULL) - return; - - printf ("Running filter \"%s\"\n", oc->rule->name); - - d = filter_driver_new (oc->fb->filter_context, - mail_tool_filter_get_folder_func, - NULL); - filter_driver_run (d, oc->fb->folder, oc->fb->folder, - FILTER_SOURCE_DEMAND, TRUE, - NULL, NULL); -} diff --git a/mail/mail-config-druid.glade b/mail/mail-config-druid.glade deleted file mode 100644 index 98849aadf4..0000000000 --- a/mail/mail-config-druid.glade +++ /dev/null @@ -1,143 +0,0 @@ -<?xml version="1.0"?> -<GTK-Interface> - -<project> - <name>Project1</name> - <program_name>project1</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_translatable_strings>True</output_translatable_strings> - <translatable_strings_file>mail-config-druid.glade.h</translatable_strings_file> -</project> - -<widget> - <class>GtkWindow</class> - <name>dialog</name> - <title>Mail Configuration</title> - <type>GTK_WINDOW_TOPLEVEL</type> - <position>GTK_WIN_POS_NONE</position> - <modal>True</modal> - <allow_shrink>False</allow_shrink> - <allow_grow>True</allow_grow> - <auto_shrink>False</auto_shrink> - - <widget> - <class>GnomeDruid</class> - <name>druid</name> - - <widget> - <class>GnomeDruidPageStart</class> - <name>startpage</name> - <title>Mail Configuration</title> - <text>Welcome to the Evolution Mail configuration wizard! -By filling in some information about your email -settings, you can start sending and receiving email -right away. Click Next to continue.</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> - </widget> - - <widget> - <class>GnomeDruidPageStandard</class> - <name>standardpage1</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> - - <widget> - <class>GtkVBox</class> - <child_name>GnomeDruidPageStandard:vbox</child_name> - <name>pagevbox1</name> - <border_width>8</border_width> - <homogeneous>False</homogeneous> - <spacing>5</spacing> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>Placeholder</class> - </widget> - </widget> - </widget> - - <widget> - <class>GnomeDruidPageStandard</class> - <name>standardpage2</name> - <title>Mail Source</title> - <title_color>255,255,255</title_color> - <background_color>25,25,112</background_color> - <logo_background_color>25,25,112</logo_background_color> - - <widget> - <class>GtkVBox</class> - <child_name>GnomeDruidPageStandard:vbox</child_name> - <name>pagevbox2</name> - <border_width>8</border_width> - <homogeneous>False</homogeneous> - <spacing>5</spacing> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>Placeholder</class> - </widget> - </widget> - </widget> - - <widget> - <class>GnomeDruidPageStandard</class> - <name>standardpage3</name> - <title>Mail Transport</title> - <title_color>255,255,255</title_color> - <background_color>25,25,112</background_color> - <logo_background_color>25,25,112</logo_background_color> - - <widget> - <class>GtkVBox</class> - <child_name>GnomeDruidPageStandard:vbox</child_name> - <name>pagevbox3</name> - <border_width>8</border_width> - <homogeneous>False</homogeneous> - <spacing>5</spacing> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>Placeholder</class> - </widget> - </widget> - </widget> - - <widget> - <class>GnomeDruidPageFinish</class> - <name>finishpage</name> - <title>Mail Configuration</title> - <text>Your email configuration is now complete. -Click "Finish" to save your new 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> - </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 955c457e7c..0000000000 --- a/mail/mail-config-gui.c +++ /dev/null @@ -1,2268 +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 "mail.h" -#include "mail-threads.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; - GList *authtypes; -} 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 -{ - GladeXML *gui; - GtkWidget *dialog; - GtkWidget *druid; - MailDialogIdentityPage *idpage; - gboolean iddone; - MailDialogSourcePage *spage; - gboolean sdone; - MailDialogTransportPage *tpage; - gboolean tdone; -} MailDruidDialog; - -typedef struct -{ - GladeXML *gui; - GtkWidget *dialog; - GtkWidget *notebook; - 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 html_size_req (GtkWidget *widget, GtkRequisition *requisition); -static GtkWidget *html_new (gboolean white); -static void put_html (GtkHTML *html, char *text); -static void error_dialog (GtkWidget *parent_finder, const char *fmt, ...); -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); -} - - -/* 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); -} - -#if 0 -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); - g_free (url); - if (!service) { - camel_exception_free (ex); - return services; - } - - mcs = g_new (MailService, 1); - mcs->provider = prov; - mcs->service = service; - mcs->type = type; - mcs->authtypes = camel_service_query_auth_types (mcs->service, ex); - camel_exception_free (ex); - - 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 = gtk_editable_get_chars (GTK_EDITABLE (page->name), 0, -1); - addr = 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 = gtk_editable_get_chars (GTK_EDITABLE (page->name), 0, -1); - id->address = - gtk_editable_get_chars (GTK_EDITABLE (page->address), 0, -1); - id->org = gtk_editable_get_chars (GTK_EDITABLE (page->org), 0, -1); - id->sig = 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); - - 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) - 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) - 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) { - 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)) - 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) - url->user = gtk_editable_get_chars (GTK_EDITABLE (spitem->user), 0, -1); - if (spitem->host) - url->host = gtk_editable_get_chars (GTK_EDITABLE (spitem->host), 0, -1); - if (spitem->path) { - gchar *path; - path = 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) - gtk_entry_set_text (GTK_ENTRY (spitem->user), url->user); - - if (spitem->host && url && url->host) - gtk_entry_set_text (GTK_ENTRY (spitem->host), url->host); - - if (spitem->path && url && url->path) { - if (url->host && *url->path) - gtk_entry_set_text (GTK_ENTRY (spitem->path), - url->path + 1); - else - 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); - 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 = 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 = 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 = gtk_editable_get_chars (GTK_EDITABLE (spitem->path), 0, -1); - if (!data || !*data) - complete = FALSE; - } - } - - 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; - CamelException *ex; - CamelService *service; - GList *authtypes; - - spitem = page->spitem; - url = service_page_get_url (page); - - ex = camel_exception_new (); - service = camel_session_get_service (session, url, spitem->type, ex); - g_free (url); - if (camel_exception_get_id (ex) != CAMEL_EXCEPTION_NONE) - goto error; - - authtypes = camel_service_query_auth_types (service, ex); - if (camel_exception_get_id (ex) != CAMEL_EXCEPTION_NONE) - goto error; - - service_page_item_auth_fill (page, spitem, authtypes); - - camel_exception_free (ex); - - return; - - error: - error_dialog (button, "Could not detect supported authentication " - "types:\n%s", camel_exception_get_description (ex)); - camel_exception_free (ex); -} - -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->url_flags & ~CAMEL_SERVICE_URL_NEED_AUTH; - - if (service_flags & CAMEL_SERVICE_URL_ALLOW_HOST) { - item->host = service_page_add_elem (page, table, row++, _("Server:")); - item->hostneed = ((service_flags & CAMEL_SERVICE_URL_NEED_HOST) - == CAMEL_SERVICE_URL_NEED_HOST); - } - - if (service_flags & CAMEL_SERVICE_URL_ALLOW_USER) { - item->user = service_page_add_elem (page, table, row++, _("Username:")); - item->userneed = ((service_flags & CAMEL_SERVICE_URL_NEED_USER) - == CAMEL_SERVICE_URL_NEED_USER); - } - - if (service_flags & CAMEL_SERVICE_URL_ALLOW_PATH) { - item->path = service_page_add_elem (page, table, row++, _("Path:")); - item->pathneed = ((service_flags & CAMEL_SERVICE_URL_NEED_PATH) - == CAMEL_SERVICE_URL_NEED_PATH); - } - - if (mcs->authtypes) { - GtkWidget *label; - - 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_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, - 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, GTK_FILL | GTK_EXPAND, - 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); - - service_page_item_auth_fill (page, item, mcs->authtypes); - - 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 (_("Edit Identity"), NULL); - else - iddialog->dialog = gnome_dialog_new (_("Add 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); - 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); - - /*GDK_THREADS_ENTER ();*/ - gnome_dialog_run_and_close (GNOME_DIALOG (iddialog->dialog)); - /*GDK_THREADS_LEAVE ();*/ - - 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 (_("Edit Source"), NULL); - else - sdialog->dialog = gnome_dialog_new (_("Add 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); - - /*GDK_THREADS_ENTER ();*/ - gnome_dialog_run_and_close (GNOME_DIALOG (sdialog->dialog)); - /*GDK_THREADS_LEAVE ();*/ - - 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 (_("Edit News Server"), NULL); - else - ndialog->dialog = gnome_dialog_new (_("Add 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); - - /*GDK_THREADS_ENTER ();*/ - gnome_dialog_run_and_close (GNOME_DIALOG (ndialog->dialog)); - /*GDK_THREADS_LEAVE ();*/ - - 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; - - 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); - - /* 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 (void) -{ - 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->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 = 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); - - gtk_clist_set_text (clist, dialog->idrow, 0, id2->name); - gtk_clist_set_text (clist, dialog->idrow, 1, id2->address); - gtk_clist_set_text (clist, dialog->idrow, 2, id2->org); - gtk_clist_set_text (clist, dialog->idrow, 3, id2->sig); - - gtk_clist_set_row_data (clist, dialog->idrow, id2); - identity_destroy (id); - - 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 = 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); - - gtk_clist_set_text (clist, dialog->srow, 0, source2->url); - gtk_clist_set_row_data (clist, dialog->srow, source2); - service_destroy (source); - - 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 = 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); - - gtk_clist_set_text (clist, dialog->nrow, 0, news2->url); - gtk_clist_set_row_data (clist, dialog->nrow, news2); - service_destroy (news); - - 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++) { - clist = GTK_CLIST (dialog->clistSources); - - data = gtk_clist_get_row_data (clist, i); - mail_config_add_source ((MailConfigService *) data); - } - - /* Transport */ - t = service_page_extract (dialog->page->page); - mail_config_set_transport (t); - - /* News */ - for (i = 0; i <= dialog->maxnrow; i++) { - clist = GTK_CLIST (dialog->clistNews); - - data = gtk_clist_get_row_data (clist, i); - mail_config_add_news ((MailConfigService *) data); - } - - /* 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 (); -} - -void -mail_config (void) -{ - 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->dialog = glade_xml_get_widget (gui, "dialog"); - dialog->notebook = glade_xml_get_widget (gui, "notebook"); - - /* Identities Page */ - dialog->clistIdentities = - glade_xml_get_widget (gui, "clistIdentities"); - clist = GTK_CLIST (dialog->clistIdentities); - 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 = gtk_clist_append (clist, text); - gtk_clist_set_row_data (clist, row, id); - } - - 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_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 = gtk_clist_append (clist, text); - gtk_clist_set_row_data (clist, row, source); - } - - 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); - - 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 = gtk_clist_append (clist, text); - gtk_clist_set_row_data (clist, row, news); - } - - 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 apply signal */ - gtk_signal_connect (GTK_OBJECT (dialog->dialog), "apply", - GTK_SIGNAL_FUNC (mail_config_apply_clicked), - dialog); - - GDK_THREADS_ENTER (); - gnome_dialog_run (GNOME_DIALOG (dialog->dialog)); - GDK_THREADS_LEAVE (); - - /* Clean up */ - gtk_object_unref (GTK_OBJECT (gui)); - g_free (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_input_t *input = (test_service_input_t *) in_data; - test_service_data_t *data = (test_service_data_t *) op_data; - - if (!input->url) { - camel_exception_set (ex, CAMEL_EXCEPTION_INVALID_PARAM, - "No URL was provided to test"); - return; - } - - 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, 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); -} diff --git a/mail/mail-config-gui.h b/mail/mail-config-gui.h deleted file mode 100644 index be122966fc..0000000000 --- a/mail/mail-config-gui.h +++ /dev/null @@ -1,29 +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> - -void mail_config (void); -void mail_config_druid (void); - -#endif diff --git a/mail/mail-config.c b/mail/mail-config.c deleted file mode 100644 index da9629488e..0000000000 --- a/mail/mail-config.c +++ /dev/null @@ -1,549 +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 "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) -{ - config->ids = g_slist_append (config->ids, 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) -{ - config->sources = g_slist_append (config->sources, 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) -{ - config->news = g_slist_append (config->news, news); -} - - - - 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 f716373dce..0000000000 --- a/mail/mail-config.h +++ /dev/null @@ -1,88 +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> - -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); - -#endif - - diff --git a/mail/mail-crypto.c b/mail/mail-crypto.c deleted file mode 100644 index 71a2573eeb..0000000000 --- a/mail/mail-crypto.c +++ /dev/null @@ -1,529 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * mail-crypto.h: 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 <glib.h> -#include <gnome.h> - -#include "mail.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 - *----------------------------------------------------------------------*/ - - -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_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; -} - -char * -mail_crypto_openpgp_encrypt (const char *plaintext, - const GPtrArray *recipients, - gboolean sign, CamelException *ex) -{ - GPtrArray *recipient_list = NULL; - int retval, i, r; - char *path, *argv[12]; - char *passphrase, *ciphertext = NULL, *diagnostics = NULL; - int passwd_fds[2]; - char passwd_fd[32]; - - passphrase = mail_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; - - recipient_list = g_ptr_array_new (); - for (r = 0; r < recipients->len; r++) { - char *buf, *recipient; - - recipient = recipients->pdata[i]; - buf = g_strdup_printf ("-r %s", recipient); - g_ptr_array_add (recipient_list, buf); - } - - argv[i++] = "gpg"; - argv[i++] = "--verbose"; - argv[i++] = "--yes"; - argv[i++] = "--batch"; - - argv[i++] = "--armor"; - - for (r = 0; r < recipient_list->len; r++) - argv[i++] = recipient_list->pdata[r]; - - argv[i++] = "--output"; - argv[i++] = "-"; /* output to stdout */ - - argv[i++] = "--encrypt"; - - if (sign) { - argv[i++] = "--sign"; - - argv[i++] = "--passphrase-fd"; - sprintf (passwd_fd, "%d", passwd_fds[0]); - argv[i++] = 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[i]; - buf = g_strdup_printf ("-r %s", recipient); - g_ptr_array_add (recipient_list, buf); - } - - argv[i++] = "pgpe"; - - for (r = 0; r < recipient_list->len; r++) - argv[i++] = recipient_list->pdata[r]; - - argv[i++] = "-f"; - argv[i++] = "-z"; - argv[i++] = "-a"; - argv[i++] = "-o"; - argv[i++] = "-"; /* output to stdout */ - - if (sign) { - argv[i++] = "-s"; - - sprintf (passwd_fd, "PGPPASSFD=%d", passwd_fds[0]); - putenv (passwd_fd); - } -#else /* We still gotta get pgp 2.6.3 workin here ;-) */ - 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, 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_free (diagnostics); - return ciphertext; -} - -#endif /* PGP_PROGRAM */ diff --git a/mail/mail-display.c b/mail/mail-display.c deleted file mode 100644 index 760c45c92e..0000000000 --- a/mail/mail-display.c +++ /dev/null @@ -1,564 +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-util.h" -#include "e-util/e-html-utils.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> - -#define PARENT_TYPE (gtk_vbox_get_type ()) - -static GtkObjectClass *mail_display_parent_class; - -static void redisplay (MailDisplay *md); - -/*----------------------------------------------------------------------* - * Callbacks - *----------------------------------------------------------------------*/ - -static void -save_data_eexist_cb (int reply, gpointer user_data) -{ - gboolean *ok = user_data; - - *ok = reply == 0; - gtk_main_quit (); -} - -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) { - gboolean ok = FALSE; - - gnome_ok_cancel_dialog_modal ( - "A file by that name already exists.\nOverwrite it?", - save_data_eexist_cb, &ok); - GDK_THREADS_ENTER(); - gtk_main (); - GDK_THREADS_LEAVE(); - if (!ok) - 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) -{ - GMimeContentField *type; - const char *name = NULL; - char *safe, *p; - - type = camel_mime_part_get_content_type (part); - if (type) - name = gmime_content_field_get_parameter (type, "name"); - if (!name) - name = camel_mime_part_get_filename (part); - if (!name) - 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 CamelMimePart * -part_for_url (const char *url, MailDisplay *md) -{ - GHashTable *urls; - - urls = g_datalist_get_data (md->data, "urls"); - g_return_val_if_fail (urls != NULL, NULL); - return g_hash_table_lookup (urls, url); -} - -static void -launch_external (const char *url, MailDisplay *md) -{ - const char *command = url + 21; - char *tmpl, *tmpdir, *filename, *argv[2]; - CamelMimePart *part = part_for_url (url, md); - - 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] = (char *)command; - argv[1] = filename; - - gnome_execute_async (tmpdir, 2, argv); - g_free (tmpdir); - g_free (filename); -} - -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 void -save_data (const char *cid, MailDisplay *md) -{ - GtkFileSelection *file_select; - char *filename; - CamelMimePart *part; - - part = part_for_url (cid, md); - g_return_if_fail (part != NULL); - 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 gboolean -idle_redisplay (gpointer data) -{ - MailDisplay *md = data; - - md->idle_id = 0; - redisplay (md); - 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 (!strncmp (url, "cid:", 4)) - save_data (url, md); - else if (!strncmp (url, "x-evolution-external:", 21)) - launch_external (url, md); - 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 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; - - if (strncmp (eb->classid, "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, eb->classid); - g_return_val_if_fail (CAMEL_IS_MEDIUM (medium), FALSE); - wrapper = camel_medium_get_content_object (medium); - - component = gnome_vfs_mime_get_default_component (eb->type); - if (!component) - return FALSE; - - embedded = bonobo_widget_new_subdoc (component->iid, NULL); - if (!embedded) - embedded = bonobo_widget_new_control (component->iid, NULL); - 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); - 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) -{ - GtkAdjustment *adj; - - 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; - - adj = e_scroll_frame_get_vadjustment (md->scroll); - gtk_adjustment_set_value (adj, 0); - e_scroll_frame_set_vadjustment (md->scroll, adj); - - adj = e_scroll_frame_get_hadjustment (md->scroll); - gtk_adjustment_set_value (adj, 0); - e_scroll_frame_set_hadjustment (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); - 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_AUTOMATIC); - 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 838921848d..0000000000 --- a/mail/mail-display.h +++ /dev/null @@ -1,57 +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 "widgets/misc/e-scroll-frame.h" - -#include "camel/camel-stream.h" -#include "camel/camel-mime-message.h" -#include "folder-browser.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 a73d2faf89..0000000000 --- a/mail/mail-format.c +++ /dev/null @@ -1,1764 +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-tools.h" -#include "mail-display.h" -#include "mail.h" -#include "e-util/e-html-utils.h" -#include <libgnome/libgnome.h> -#include <libgnomevfs/gnome-vfs-mime-info.h> -#include <libgnomevfs/gnome-vfs-mime-handlers.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_audio (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_unknown_type (CamelMimePart *part, - const char *mime_type, - MailDisplay *md); -static gboolean handle_via_bonobo (CamelMimePart *part, - const char *mime_type, - MailDisplay *md); -static gboolean handle_via_external (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); -} - - - -/* We're maintaining a hashtable of mimetypes -> functions; - * Those functions have the following signature... - */ -typedef gboolean (*mime_handler_fn) (CamelMimePart *part, - const char *mime_type, - MailDisplay *md); - -static GHashTable *mime_function_table, *mime_fallback_table; - -static void -setup_function_table (void) -{ - mime_function_table = g_hash_table_new (g_str_hash, g_str_equal); - mime_fallback_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/*", - handle_image); - - g_hash_table_insert (mime_function_table, "audio/*", - handle_audio); - - 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_fallback_table, "text/*", - handle_text_plain); - g_hash_table_insert (mime_function_table, "multipart/*", - handle_multipart_mixed); -} - -static mime_handler_fn -lookup_handler (const char *mime_type, gboolean *generic) -{ - mime_handler_fn handler_function; - char *mime_type_main; - GnomeVFSMimeAction *action; - - if (mime_function_table == NULL) - setup_function_table (); - - mime_type_main = g_strdup_printf ("%.*s/*", - (int)strcspn (mime_type, "/"), - mime_type); - - /* OK. There are 6 possibilities, which we try in this order: - * 1) full match in the main table - * 2) partial match in the main table - * 3) full match in gnome_vfs_mime_* - * 4) full match in the fallback table - * 5) partial match in the fallback table - * 6) partial match in gnome_vfs_mime_* - * - * Of these, 1-4 are considered exact matches, and 5 and 6 are - * considered generic. - */ - - /* Check for full match in mime_function_table. */ - handler_function = g_hash_table_lookup (mime_function_table, - mime_type); - if (!handler_function) { - handler_function = g_hash_table_lookup (mime_function_table, - mime_type_main); - if (handler_function) { - /* Optimize this for the next time through. */ - g_hash_table_insert (mime_function_table, - g_strdup (mime_type), - handler_function); - } - } - - if (handler_function) { - g_free (mime_type_main); - *generic = FALSE; - return handler_function; - } - - action = gnome_vfs_mime_get_default_action_without_fallback (mime_type); - if (action) { - if (action->action_type == GNOME_VFS_MIME_ACTION_TYPE_COMPONENT) - handler_function = handle_via_bonobo; - else - handler_function = handle_via_external; - - /* Optimize this for the next time through. */ - g_hash_table_insert (mime_function_table, - g_strdup (mime_type), handler_function); - g_free (mime_type_main); - gnome_vfs_mime_action_free (action); - *generic = FALSE; - return handler_function; - } - - handler_function = g_hash_table_lookup (mime_fallback_table, - mime_type); - if (handler_function) - *generic = FALSE; - else { - handler_function = g_hash_table_lookup (mime_fallback_table, - mime_type_main); - if (!handler_function) { - action = gnome_vfs_mime_get_default_action (mime_type_main); - if (action) { - if (action->action_type == - GNOME_VFS_MIME_ACTION_TYPE_COMPONENT) - handler_function = handle_via_bonobo; - else - handler_function = handle_via_external; - gnome_vfs_mime_action_free (action); - } - } - *generic = TRUE; - } - - g_free (mime_type_main); - return handler_function; -} - -static gboolean -call_handler_function (CamelMimePart *part, MailDisplay *md) -{ - CamelDataWrapper *wrapper; - char *mime_type; - mime_handler_fn handler_function = NULL; - gboolean generic, output; - - wrapper = camel_medium_get_content_object (CAMEL_MEDIUM (part)); - mime_type = camel_data_wrapper_get_mime_type (wrapper); - g_strdown (mime_type); - - handler_function = lookup_handler (mime_type, &generic); - if (handler_function) - output = (*handler_function) (part, mime_type, md); - else - output = handle_unknown_type (part, mime_type, md); - - g_free (mime_type); - return output; -} - -static void -write_field_to_stream (const char *description, const char *value, - gboolean bold, GtkHTML *html, - GtkHTMLStream *stream) -{ - char *encoded_value; - - if (value) { - unsigned char *p; - - encoded_value = e_text_to_html (value, - E_TEXT_TO_HTML_CONVERT_NL | - E_TEXT_TO_HTML_CONVERT_URLS); - for (p = (unsigned char *)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, md->html, md->stream); - - reply_to = camel_mime_message_get_reply_to (message); - if (reply_to) { - write_field_to_stream ("Reply-To:", reply_to, 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, - 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, - md->html, md->stream); - } - g_free (string); - - write_field_to_stream ("Subject:", - camel_mime_message_get_subject (message), - 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)); - 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, - "Encrypted message not displayed<br><br>\n"); - mail_error_write (md->html, md->stream, - camel_exception_get_description (&ex)); - camel_exception_clear (&ex); - } else { - mail_html_write (md->html, md->stream, - "Encrypted message<br><br>\n" - "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; - gboolean generic; - - 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; - if (lookup_handler (mime_type, &generic) && - (!preferred_part || !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_unknown_type (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 void -handle_mystery (CamelMimePart *part, MailDisplay *md, - const char *url, const char *icon_name, const char *id, - const char *action) -{ - const char *info; - char *htmlinfo; - GMimeContentField *content_type; - - mail_html_write (md->html, md->stream, "<table><tr><td>"); - - /* Draw the icon, surrounded by an <a href> if we have a URL, - * or a plain inactive border if not. - */ - if (url) { - mail_html_write (md->html, md->stream, - "<a href=\"%s\">", url); - } else { - mail_html_write (md->html, md->stream, - "<table border=2><tr><td>"); - } - mail_html_write (md->html, md->stream, "<img src=\"%s\">", - get_url_for_icon (icon_name, md)); - - if (url) - mail_html_write (md->html, md->stream, "</a>"); - else - mail_html_write (md->html, md->stream, "</td></tr></table>"); - mail_html_write (md->html, md->stream, "</td><td>%s<br>", id); - - /* 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, "Description: %s<br>", - htmlinfo); - g_free (htmlinfo); - } - - /* Write the name, if we have it. */ - content_type = camel_mime_part_get_content_type (part); - info = gmime_content_field_get_parameter (content_type, "name"); - if (!info) - info = camel_mime_part_get_filename (part); - if (info) { - htmlinfo = e_text_to_html (info, 0); - mail_html_write (md->html, md->stream, "Name: %s<br>", - htmlinfo); - g_free (htmlinfo); - } - - /* Describe the click action, if any. */ - if (action) { - mail_html_write (md->html, md->stream, - "<br>Click on the icon to %s.", action); - } - - mail_html_write (md->html, md->stream, "</td></tr></table>"); -} - -static gboolean -handle_audio (CamelMimePart *part, const char *mime_type, MailDisplay *md) -{ - char *id; - const char *desc; - - desc = gnome_vfs_mime_get_value (mime_type, "description"); - if (desc) - id = g_strdup_printf ("%s data", desc); - else { - id = g_strdup_printf ("Audio data in \"%s\" format.", - mime_type); - } - handle_mystery (part, md, get_cid (part, md), "gnome-audio2.png", - id, "play it"); - g_free (id); - - return TRUE; -} - -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); - desc = g_strdup_printf ("Pointer to local file (%s)%s%s%s", - name, site ? " valid at site \"" : "", - site ? site : "", site ? "\"" : ""); - } 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."); - } - - handle_mystery (part, md, url, "gnome-globe.png", desc, - url ? "open it in a browser" : NULL); - - g_free (desc); - g_free (url); - return TRUE; -} - -static gboolean -handle_undisplayable (CamelMimePart *part, const char *mime_type, - MailDisplay *md) -{ - const char *desc; - char *id; - - desc = gnome_vfs_mime_get_value (mime_type, "description"); - if (desc) - id = g_strdup (desc); - else - id = g_strdup_printf ("Data of type \"%s\".", mime_type); - handle_mystery (part, md, get_cid (part, md), "gnome-question.png", - id, "save it to disk"); - g_free (id); - - return TRUE; -} - -static gboolean -handle_unknown_type (CamelMimePart *part, const char *mime_type, - MailDisplay *md) -{ - char *type; - - /* Don't give up quite yet. */ - type = mail_identify_mime_part (part); - if (type) { - mime_handler_fn handler_function; - gboolean generic, output; - - handler_function = lookup_handler (type, &generic); - if (handler_function && - handler_function != handle_unknown_type) { - output = (*handler_function) (part, type, md); - g_free (type); - return output; - } - } else - type = g_strdup (mime_type); - - /* OK. Give up. */ - handle_undisplayable (part, type, md); - g_free (type); - - 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\">", - get_cid (part, md), mime_type); - - /* Call handle_undisplayable to output its HTML inside the - * <object> ... </object>. It will only be displayed if the - * object loading fails. - */ - handle_undisplayable (part, mime_type, md); - - mail_html_write (md->html, md->stream, "</object>"); - - return TRUE; -} - -static gboolean -handle_via_external (CamelMimePart *part, const char *mime_type, - MailDisplay *md) -{ - GnomeVFSMimeApplication *app; - const char *desc, *icon; - char *action, *url; - - app = gnome_vfs_mime_get_default_application (mime_type); - g_return_val_if_fail (app != NULL, FALSE); - - desc = gnome_vfs_mime_get_value (mime_type, "description"); - icon = gnome_vfs_mime_get_value (mime_type, "icon-filename"); - if (!icon) - icon = "gnome-unknown.png"; - action = g_strdup_printf ("open the file in %s", app->name); - url = g_strdup_printf ("x-evolution-external:%s", app->command); - handle_mystery (part, md, url, icon, desc, action); - add_url (url, part, md); - - g_free (action); - - 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, *disp; - 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); - - disp = camel_mime_part_get_disposition (subpart); - if (disp && g_strcasecmp (disp, "inline") != 0) - 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", text, - boundary, subtext); - g_free (subtext); - g_free (old); - } else - text = subtext; - } - - if (!text) - return NULL; - - return text; -} - -EMsgComposer * -mail_generate_reply (CamelMimeMessage *message, gboolean to_all) -{ - CamelDataWrapper *contents; - char *text, *subject; - EMsgComposer *composer; - gboolean want_plain, is_html; - const char *repl_to, *message_id, *references; - GList *to, *cc; - - 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); - - composer = E_MSG_COMPOSER (e_msg_composer_new ()); - - /* 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; - } - - /* 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); - to = g_list_append (NULL, (gpointer)repl_to); - - 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) { - fulladdr = g_strdup_printf ("\"%s\" <%s>", - name, addr); - } else - fulladdr = g_strdup (addr); - 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) { - fulladdr = g_strdup_printf ("\"%s\" <%s>", - name, addr); - } else - fulladdr = g_strdup (addr); - 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); - g_list_free (to); - g_list_free (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 e8d82cb8f5..0000000000 --- a/mail/mail-identify.c +++ /dev/null @@ -1,101 +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) -{ - GMimeContentField *content_type; - const char *filename, *type; - GnomeVFSMimeSniffBuffer *sniffer; - CamelStream *memstream; - CamelDataWrapper *data; - GByteArray *ba; - - content_type = camel_mime_part_get_content_type (part); - - - /* Try identifying based on name in Content-Type or - * filename in Content-Disposition. - */ - filename = gmime_content_field_get_parameter (content_type, "name"); - if (filename) { - type = gnome_vfs_mime_type_from_name_or_default (filename, - NULL); - if (type) - return g_strdup (type); - } - - 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.c b/mail/mail-local.c deleted file mode 100644 index eb03db0dd4..0000000000 --- a/mail/mail-local.c +++ /dev/null @@ -1,504 +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 <gnome.h> -#include <glade/glade.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 */ -}; - -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")) { - meta->format = xmlGetProp(node, "type"); - meta->name = xmlGetProp(node, "name"); - } - node = node->next; - } - xmlFreeDoc(doc); - return meta; - -dodefault: - meta->format = g_strdup("mbox"); /* defaults */ - meta->name = g_strdup("mbox"); - 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); - - 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) -{ - CamelURL *url; - char *metapath; - char *storename; - struct _local_meta *meta; - CamelException *ex; - - 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); - - /* change file: to format: */ - camel_url_set_protocol(url, meta->format); - storename = camel_url_to_string(url, TRUE); - 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; - - 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, TRUE); - - printf("store name is %s\n", storename); - - folder = mail_tool_get_folder_from_urlname (storename, meta->name, FALSE, 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; - - if (!IS_FOLDER_BROWSER (input->fb)) { - camel_exception_set (ex, CAMEL_EXCEPTION_INVALID_PARAM, - "Input has a bad FolderBrowser in reconfigure_folder"); - return; - } - - if (!input->newtype) { - camel_exception_set (ex, CAMEL_EXCEPTION_INVALID_PARAM, - "No new folder type in reconfigure_folder"); - return; - } - - 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; - - 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, TRUE); - camel_url_set_protocol(url, input->newtype); - tourl = camel_url_to_string(url, TRUE); - - 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 */ - 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; - } - - fromfolder = camel_store_get_folder(fromstore, tmpname, TRUE, 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); - - tofolder = camel_store_get_folder(tostore, meta->name, TRUE, 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); - - GDK_THREADS_ENTER (); - gnome_dialog_run_and_close (GNOME_DIALOG (gd)); - GDK_THREADS_LEAVE (); -} diff --git a/mail/mail-local.h b/mail/mail-local.h deleted file mode 100644 index c5892d29d9..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); - -#endif diff --git a/mail/mail-ops.c b/mail/mail-ops.c deleted file mode 100644 index f90d492dd8..0000000000 --- a/mail/mail-ops.c +++ /dev/null @@ -1,1975 +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 <gnome.h> -#include "mail.h" -#include "mail-threads.h" -#include "mail-tools.h" -#include "mail-ops.h" -#include "composer/e-msg-composer.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); -static void setup_fetch_mail (gpointer in_data, gpointer op_data, - CamelException *ex); -static void do_fetch_mail (gpointer in_data, gpointer op_data, - CamelException *ex); -static void cleanup_fetch_mail (gpointer in_data, gpointer op_data, - CamelException *ex); - -static gchar * -describe_fetch_mail (gpointer in_data, gboolean gerund) -{ - fetch_mail_input_t *input = (fetch_mail_input_t *) in_data; - CamelStore *source; - 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; - - if (!input->source_url) { - camel_exception_set (ex, CAMEL_EXCEPTION_INVALID_PARAM, - _("You have no remote mail source configured " - "to fetch mail from.")); - return; - } - - if (input->destination == NULL) - return; - - if (!CAMEL_IS_FOLDER (input->destination)) { - camel_exception_set (ex, CAMEL_EXCEPTION_INVALID_PARAM, - _("Bad folder passed to fetch_mail")); - return; - } - - data->empty = FALSE; - camel_object_ref (CAMEL_OBJECT (input->destination)); -} - -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; - - CamelFolder *search_folder = NULL; - - /* If using IMAP, don't do anything... */ - - if (!strncmp (input->source_url, "imap:", 5)) { - data->empty = FALSE; - return; - } - - if (input->destination == NULL) { - input->destination = mail_tool_get_local_inbox (ex); - - if (input->destination == NULL) - return; - } - - search_folder = - mail_tool_fetch_mail_into_searchable (input->source_url, - input->keep_on_server, ex); - - if (search_folder == NULL) { - /* This happens with an IMAP source and on error - * and on "no new mail" - */ - camel_object_unref (CAMEL_OBJECT (input->destination)); - input->destination = NULL; - data->empty = TRUE; - return; - } - - mail_tool_camel_lock_up (); - if (camel_folder_get_message_count (search_folder) == 0) { - data->empty = TRUE; - } else { - mail_tool_filter_contents_into (search_folder, input->destination, - TRUE, - input->hook_func, input->hook_data, - ex); - data->empty = FALSE; - } - mail_tool_camel_lock_down (); - - camel_object_unref (CAMEL_OBJECT (search_folder)); -} - -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; - - dialog = gnome_ok_dialog (_("There is no new mail.")); - 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; - - 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); -} - -/* ** SEND MAIL *********************************************************** */ - -typedef struct send_mail_input_s -{ - gchar *xport_uri; - CamelMimeMessage *message; - gchar *from; - - /* 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); -static void setup_send_mail (gpointer in_data, gpointer op_data, - CamelException *ex); -static void do_send_mail (gpointer in_data, gpointer op_data, - - CamelException *ex); -static void cleanup_send_mail (gpointer in_data, gpointer op_data, - CamelException *ex); - -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; - - if (!input->xport_uri) { - camel_exception_set (ex, CAMEL_EXCEPTION_INVALID_PARAM, - /* doesn't really need i18n */ - "No transport URI specified for send_mail operation."); - return; - } - - if (!CAMEL_IS_MIME_MESSAGE (input->message)) { - camel_exception_set (ex, CAMEL_EXCEPTION_INVALID_PARAM, - "No message specified for send_mail operation."); - return; - } - - if (input->from == NULL) { - camel_exception_set (ex, CAMEL_EXCEPTION_INVALID_PARAM, - "No from address specified for send_mail operation."); - return; - } - - /* NOTE THE EARLY EXIT!! */ - - if (input->done_folder == NULL) { - camel_object_ref (CAMEL_OBJECT (input->message)); - gtk_object_ref (GTK_OBJECT (input->composer)); - gtk_widget_hide (GTK_WIDGET (input->composer)); - return; - } - - if (!CAMEL_IS_FOLDER (input->done_folder)) { - camel_exception_set (ex, CAMEL_EXCEPTION_INVALID_PARAM, - "Bad done_folder specified for send_mail operation."); - return; - } - - if (input->done_uid == NULL) { - camel_exception_set (ex, CAMEL_EXCEPTION_INVALID_PARAM, - "No done_uid specified for send_mail operation."); - return; - } - - if (!GTK_IS_WIDGET (input->composer)) { - camel_exception_set (ex, CAMEL_EXCEPTION_INVALID_PARAM, - "No composer specified for send_mail operation."); - return; - } - - camel_object_ref (CAMEL_OBJECT (input->message)); - camel_object_ref (CAMEL_OBJECT (input->done_folder)); - 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; - CamelTransport *xport; - - mail_tool_camel_lock_up (); - camel_mime_message_set_from (input->message, input->from); - - camel_medium_add_header (CAMEL_MEDIUM (input->message), "X-Mailer", - "Evolution (Developer Preview)"); - 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 (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, ~set); - 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->from); - g_free (input->xport_uri); - g_free (input->done_uid); - - 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, - const char *from, - CamelFolder *done_folder, - const char *done_uid, - guint32 done_flags, GtkWidget *composer) -{ - send_mail_input_t *input; - - input = g_new (send_mail_input_t, 1); - input->xport_uri = g_strdup (xport_uri); - input->message = message; - input->from = g_strdup (from); - 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); -} - -/* ** EXPUNGE FOLDER ****************************************************** */ - -static gchar *describe_expunge_folder (gpointer in_data, gboolean gerund); -static void setup_expunge_folder (gpointer in_data, gpointer op_data, - CamelException *ex); -static void do_expunge_folder (gpointer in_data, gpointer op_data, - CamelException *ex); -static void cleanup_expunge_folder (gpointer in_data, gpointer op_data, - CamelException *ex); - -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) -{ - if (!CAMEL_IS_FOLDER (in_data)) { - camel_exception_set (ex, CAMEL_EXCEPTION_INVALID_PARAM, - /* doesn't need i18n */ - "No folder is selected to be expunged"); - return; - } - - 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) -{ - 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); -static void setup_transfer_messages (gpointer in_data, gpointer op_data, - CamelException *ex); -static void do_transfer_messages (gpointer in_data, gpointer op_data, - CamelException *ex); -static void cleanup_transfer_messages (gpointer in_data, gpointer op_data, - CamelException *ex); - -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; - char *verb; - - if (input->delete_from_source) - /* don't need i18n */ - verb = "move"; - else - verb = "copy"; - - if (!CAMEL_IS_FOLDER (input->source)) { - camel_exception_setv (ex, CAMEL_EXCEPTION_INVALID_PARAM, - "No source folder to %s messages from specified.", - verb); - return; - } - - if (input->uids == NULL) { - camel_exception_setv (ex, CAMEL_EXCEPTION_INVALID_PARAM, - "No messages to %s have been specified.", - verb); - return; - } - - if (input->dest_uri == NULL) { - camel_exception_setv (ex, CAMEL_EXCEPTION_INVALID_PARAM, - "No URI to %s to has been specified.", - verb); - return; - } - - 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; - void (*func) (CamelFolder *, const char *, - CamelFolder *, - CamelException *); - - if (input->delete_from_source) - func = camel_folder_move_message_to; - else - func = camel_folder_copy_message_to; - - 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++) { - (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; - - 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; -} -flag_messages_input_t; - -static gchar *describe_flag_messages (gpointer in_data, gboolean gerund); -static void setup_flag_messages (gpointer in_data, gpointer op_data, - CamelException *ex); -static void do_flag_messages (gpointer in_data, gpointer op_data, - CamelException *ex); -static void cleanup_flag_messages (gpointer in_data, gpointer op_data, - CamelException *ex); - -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; - - if (!CAMEL_IS_FOLDER (input->source)) { - camel_exception_set (ex, CAMEL_EXCEPTION_INVALID_PARAM, - /* doesn't need i18n */ - "No source folder to flag messages from specified."); - return; - } - - if (input->uids == NULL) { - camel_exception_set (ex, CAMEL_EXCEPTION_INVALID_PARAM, - "No messages to flag have been specified."); - return; - } - - 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; - - mail_tool_camel_lock_up (); - camel_folder_freeze (input->source); - mail_tool_camel_lock_down (); - - for (i = 0; i < input->uids->len; i++) { - 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); - } - - g_free (input->uids->pdata[i]); - } - - mail_tool_camel_lock_up (); - 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)); - 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; - - input = g_new (flag_messages_input_t, 1); - input->source = source; - input->uids = uids; - input->invert = invert; - input->mask = mask; - input->set = set; - - mail_operation_queue (&op_flag_messages, input, TRUE); -} - -/* ** SCAN SUBFOLDERS ***************************************************** */ - -typedef struct scan_subfolders_input_s -{ - gchar *source_uri; - gboolean add_INBOX; - EvolutionStorage *storage; -} -scan_subfolders_input_t; - -typedef struct scan_subfolders_folderinfo_s -{ - char *path; - char *uri; -} -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); -static void setup_scan_subfolders (gpointer in_data, gpointer op_data, - CamelException *ex); -static void do_scan_subfolders (gpointer in_data, gpointer op_data, - CamelException *ex); -static void cleanup_scan_subfolders (gpointer in_data, gpointer op_data, - CamelException *ex); - -static gchar * -describe_scan_subfolders (gpointer in_data, gboolean gerund) -{ - scan_subfolders_input_t *input = (scan_subfolders_input_t *) in_data; - - if (gerund) - return g_strdup_printf (_("Scanning folders in \"%s\""), - input->source_uri); - else - return g_strdup_printf (_("Scan folders in \"%s\""), - input->source_uri); -} - -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; - - if (!input->source_uri) { - camel_exception_set (ex, CAMEL_EXCEPTION_INVALID_PARAM, - /* doesn't need i18n */ - "No source uri to scan subfolders from was provided."); - return; - } - - if (!EVOLUTION_IS_STORAGE (input->storage)) { - camel_exception_set (ex, CAMEL_EXCEPTION_INVALID_PARAM, - "No storage to scan subfolders into was provided."); - return; - } - - gtk_object_ref (GTK_OBJECT (input->storage)); - data->new_folders = g_ptr_array_new (); -} - -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; - scan_subfolders_folderinfo_t *info; - GPtrArray *lsub; - CamelFolder *folder; - int i; - char *splice; - - if (input->source_uri[strlen (input->source_uri) - 1] == '/') - splice = ""; - else - splice = "/"; - - folder = mail_tool_get_root_of_store (input->source_uri, ex); - if (camel_exception_is_set (ex)) - return; - - mail_tool_camel_lock_up (); - - lsub = camel_folder_get_subfolder_names (folder); - - mail_tool_camel_lock_down (); - - for (i = 0; i < lsub->len; i++) { - info = g_new (scan_subfolders_folderinfo_t, 1); - info->path = g_strdup_printf ("/%s", (char *) lsub->pdata[i]); - info->uri = g_strdup_printf ("%s%s%s", input->source_uri, splice, - (char *)lsub->pdata[i]); - g_ptr_array_add (data->new_folders, info); - } - - camel_folder_free_subfolder_names (folder, lsub); - - /* FIXME: We intentionally lose a reference to the store here - * for the benefit of the IMAP provider. Undo this when the - * namespace situation is fixed. - */ - camel_object_ref (CAMEL_OBJECT (folder->parent_store)); - camel_object_unref (CAMEL_OBJECT (folder)); -} - -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; - int i; - - for (i = 0; i < data->new_folders->len; i++) { - scan_subfolders_folderinfo_t *info; - - info = data->new_folders->pdata[i]; - evolution_storage_new_folder (input->storage, - info->path, - "mail", - info->uri, _("(No description)")); - g_free (info->path); - g_free (info->uri); - g_free (info); - } - - g_ptr_array_free (data->new_folders, TRUE); - gtk_object_unref (GTK_OBJECT (input->storage)); - g_free (input->source_uri); -} - -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 (const gchar *source_uri, EvolutionStorage *storage) -{ - scan_subfolders_input_t *input; - - input = g_new (scan_subfolders_input_t, 1); - input->source_uri = g_strdup (source_uri); - 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); -static void setup_attach_message (gpointer in_data, gpointer op_data, - CamelException *ex); -static void do_attach_message (gpointer in_data, gpointer op_data, - CamelException *ex); -static void cleanup_attach_message (gpointer in_data, gpointer op_data, - CamelException *ex); - -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; - - if (!input->uid) { - camel_exception_set (ex, CAMEL_EXCEPTION_INVALID_PARAM, - /* doesn't need i18n */ - "No UID specified to attach."); - return; - } - - if (!CAMEL_IS_FOLDER (input->folder)) { - camel_exception_set (ex, CAMEL_EXCEPTION_INVALID_PARAM, - "No folder to fetch the message from specified."); - return; - } - - if (!E_IS_MSG_COMPOSER (input->composer)) { - camel_exception_set (ex, CAMEL_EXCEPTION_INVALID_PARAM, - "No message composer from specified."); - return; - } - - 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; - - 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); -static void setup_forward_messages (gpointer in_data, gpointer op_data, - CamelException *ex); -static void do_forward_messages (gpointer in_data, gpointer op_data, - CamelException *ex); -static void cleanup_forward_messages (gpointer in_data, gpointer op_data, - CamelException *ex); - -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; - - if (!input->uids) { - camel_exception_set (ex, CAMEL_EXCEPTION_INVALID_PARAM, - /* doesn't need i18n */ - "No UIDs specified to attach."); - return; - } - - if (!CAMEL_IS_MIME_MESSAGE (input->basis)) { - camel_exception_set (ex, CAMEL_EXCEPTION_INVALID_PARAM, - "No basic message to forward was specified."); - return; - } - - if (!CAMEL_IS_FOLDER (input->source)) { - camel_exception_set (ex, CAMEL_EXCEPTION_INVALID_PARAM, - "No folder to fetch the messages from specified."); - return; - } - - if (!E_IS_MSG_COMPOSER (input->composer)) { - camel_exception_set (ex, CAMEL_EXCEPTION_INVALID_PARAM, - "No message composer from specified."); - return; - } - - 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; - - 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++) { - 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; - - 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); -static void setup_load_folder (gpointer in_data, gpointer op_data, - CamelException *ex); -static void do_load_folder (gpointer in_data, gpointer op_data, - CamelException *ex); -static void cleanup_load_folder (gpointer in_data, gpointer op_data, - CamelException *ex); - -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; - - if (!IS_FOLDER_BROWSER (input->fb)) { - camel_exception_set (ex, CAMEL_EXCEPTION_INVALID_PARAM, - /* doesn't need i18n */ - "No folder browser specified to load into."); - return; - } - - if (!input->url) { - camel_exception_set (ex, CAMEL_EXCEPTION_INVALID_PARAM, - "No URL to load was specified."); - return; - } - - 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; - - 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; - - 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); -static void setup_create_folder (gpointer in_data, gpointer op_data, - CamelException *ex); -static void do_create_folder (gpointer in_data, gpointer op_data, - CamelException *ex); -static void cleanup_create_folder (gpointer in_data, gpointer op_data, - CamelException *ex); - -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 -setup_create_folder (gpointer in_data, gpointer op_data, CamelException *ex) -{ - create_folder_input_t *input = (create_folder_input_t *) in_data; - - if (input->listener == CORBA_OBJECT_NIL) { - camel_exception_set (ex, CAMEL_EXCEPTION_INVALID_PARAM, - /* doesn't need i18n */ - "Invalid listener passed to create_folder"); - return; - } - - if (input->uri == NULL) { - camel_exception_set (ex, CAMEL_EXCEPTION_INVALID_PARAM, - "Invalid url passed to create_folder"); - return; - } - - if (input->type == NULL) { - camel_exception_set (ex, CAMEL_EXCEPTION_INVALID_PARAM, - "No type passed to create_folder"); - return; - } -} - -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); - folder = mail_tool_get_folder_from_urlname (camel_url, - "mbox", TRUE, 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), - setup_create_folder, - 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; - - CORBA_exception_init (&ev); - - input = g_new (create_folder_input_t, 1); - input->listener = CORBA_Object_duplicate (listener, &ev); - input->uri = g_strdup (uri); - input->type = g_strdup (type); - - CORBA_exception_free (&ev); - - mail_operation_queue (&op_create_folder, input, FALSE); -} - -/* ** SYNC FOLDER ********************************************************* */ - -static gchar *describe_sync_folder (gpointer in_data, gboolean gerund); -static void setup_sync_folder (gpointer in_data, gpointer op_data, - CamelException *ex); -static void do_sync_folder (gpointer in_data, gpointer op_data, - CamelException *ex); -static void cleanup_sync_folder (gpointer in_data, gpointer op_data, - CamelException *ex); - -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) -{ - if (!CAMEL_IS_FOLDER (in_data)) { - camel_exception_set (ex, CAMEL_EXCEPTION_INVALID_PARAM, - /* doesn't need i18n */ - "No folder is selected to be synced"); - return; - } - - 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) -{ - mail_operation_queue (&op_sync_folder, folder, FALSE); -} - -/* ** DISPLAY MESSAGE ***************************************************** */ - -typedef struct display_message_input_s -{ - MessageList *ml; - 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); -static void setup_display_message (gpointer in_data, gpointer op_data, - CamelException *ex); -static void do_display_message (gpointer in_data, gpointer op_data, - CamelException *ex); -static void cleanup_display_message (gpointer in_data, gpointer op_data, - CamelException *ex); - -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; - - if (!IS_MESSAGE_LIST (input->ml)) { - camel_exception_set (ex, CAMEL_EXCEPTION_INVALID_PARAM, - /* doesn't need i18n */ - "Invalid message list passed to display_message"); - return; - } - - if (!input->timeout) { - camel_exception_set (ex, CAMEL_EXCEPTION_INVALID_PARAM, - "No timeout callback passed to display_message"); - return; - } - - 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->ml->parent_folder_browser->mail_display; - - 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, const char *uid, - gint (*timeout) (gpointer)) -{ - display_message_input_t *input; - - input = g_new (display_message_input_t, 1); - input->ml = ml; - 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); -static void setup_edit_messages (gpointer in_data, gpointer op_data, - CamelException *ex); -static void do_edit_messages (gpointer in_data, gpointer op_data, - CamelException *ex); -static void cleanup_edit_messages (gpointer in_data, gpointer op_data, - CamelException *ex); - -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; - - if (!input->uids) { - camel_exception_set (ex, CAMEL_EXCEPTION_INVALID_PARAM, - /* doesn't need i18n */ - "No UIDs specified to edit."); - return; - } - - if (!CAMEL_IS_FOLDER (input->folder)) { - camel_exception_set (ex, CAMEL_EXCEPTION_INVALID_PARAM, - "No folder to fetch the messages from specified."); - return; - } - - 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++) { - GtkWidget *composer; - - composer = e_msg_composer_new_with_message (data->messages->pdata[i]); - - if (input->signal) - gtk_signal_connect (GTK_OBJECT (composer), "send", - input->signal, NULL); - - gtk_widget_show (composer); - - camel_object_unref (CAMEL_OBJECT (data->messages->pdata[i])); - } - - 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; - - 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 DRAFTBOX ****************************************************** */ - -static gchar *describe_setup_draftbox (gpointer in_data, gboolean gerund); -static void noop_setup_draftbox (gpointer in_data, gpointer op_data, - CamelException *ex); -static void do_setup_draftbox (gpointer in_data, gpointer op_data, - CamelException *ex); - -static gchar * -describe_setup_draftbox (gpointer in_data, gboolean gerund) -{ - if (gerund) - return g_strdup_printf (_("Loading Draftbox")); - else - return g_strdup_printf (_("Load Draftbox")); -} - -static void -noop_setup_draftbox (gpointer in_data, gpointer op_data, CamelException *ex) -{ -} - -static void -do_setup_draftbox (gpointer in_data, gpointer op_data, CamelException *ex) -{ - extern CamelFolder *drafts_folder; - gchar *url; - - url = g_strdup_printf ("mbox://%s/local/Drafts", evolution_dir); - drafts_folder = mail_tool_get_folder_from_urlname (url, "mbox", TRUE, ex); - g_free (url); -} - -/* - *static void - *cleanup_setup_draftbox (gpointer in_data, gpointer op_data, - * CamelException *ex) - *{ - *} - */ - -static const mail_operation_spec op_setup_draftbox = { - describe_setup_draftbox, - 0, - noop_setup_draftbox, - do_setup_draftbox, - noop_setup_draftbox -}; - -void -mail_do_setup_draftbox (void) -{ - mail_operation_queue (&op_setup_draftbox, NULL, FALSE); -} - -/* ** 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); -static void setup_view_messages (gpointer in_data, gpointer op_data, - CamelException *ex); -static void do_view_messages (gpointer in_data, gpointer op_data, - CamelException *ex); -static void cleanup_view_messages (gpointer in_data, gpointer op_data, - CamelException *ex); - -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; - - if (!input->uids) { - camel_exception_set (ex, CAMEL_EXCEPTION_INVALID_PARAM, - /* doesn't need i18n */ - "No UIDs specified to view."); - return; - } - - if (!CAMEL_IS_FOLDER (input->folder)) { - camel_exception_set (ex, CAMEL_EXCEPTION_INVALID_PARAM, - "No folder to fetch the messages from specified."); - return; - } - - if (!IS_FOLDER_BROWSER (input->fb)) { - camel_exception_set (ex, CAMEL_EXCEPTION_INVALID_PARAM, - "No folder browser was specified."); - return; - } - - - 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_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; - - 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 3566c40116..0000000000 --- a/mail/mail-ops.h +++ /dev/null @@ -1,68 +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 "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_send_mail (const char *xport_uri, - CamelMimeMessage *message, - const char *from, - CamelFolder *done_folder, - const char *done_uid, - - guint32 done_flags, GtkWidget *composer); -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_scan_subfolders (const gchar *source_uri, 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, const char *uid, - gint (*timeout) (gpointer)); -void mail_do_edit_messages (CamelFolder *folder, GPtrArray *uids, - GtkSignalFunc signal); -void mail_do_setup_draftbox (void); -void mail_do_view_messages (CamelFolder *folder, GPtrArray *uids, - FolderBrowser *fb); - -/* This actually lives in message-list.c */ -void mail_do_regenerate_messagelist (MessageList *list, - const gchar *search); diff --git a/mail/mail-threads.c b/mail/mail-threads.c deleted file mode 100644 index 8fe170eea2..0000000000 --- a/mail/mail-threads.c +++ /dev/null @@ -1,1096 +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 <glib.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 - -/** - * 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); - GDK_THREADS_ENTER (); - gnome_dialog_run_and_close (GNOME_DIALOG (err_dialog)); - GDK_THREADS_LEAVE (); - /*gtk_widget_destroy (err_dialog); */ - /*gtk_widget_show (GTK_WIDGET (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 */ - - 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; - 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; - 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; - 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 (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); - - 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); - 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); - 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; - 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; - - 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 = 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); - 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); - 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. - */ - - GDK_THREADS_ENTER (); - - 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; - } - - GDK_THREADS_LEAVE (); - 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... - */ - - /*GDK_THREADS_ENTER ();*/ - gnome_dialog_run_and_close (GNOME_DIALOG (err_dialog)); - /*GDK_THREADS_LEAVE ();*/ - - /* Allow the other thread to proceed */ - - block_release (&modal_block); - ui_set_busy (); -} - -/** - * 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 { - *(msg->reply) = NULL; - /*GDK_THREADS_ENTER ();*/ - button = gnome_dialog_run_and_close (GNOME_DIALOG (dialog)); - /*GDK_THREADS_LEAVE ();*/ - } - - 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_query_interface (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 e27f07d789..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 (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 2d10411f91..0000000000 --- a/mail/mail-tools.c +++ /dev/null @@ -1,676 +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, - gboolean create, 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, create, 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 (void) -{ - char *uri, *new; - - uri = g_strdup_printf("file://%s/local/Inbox", evolution_dir); - new = mail_local_map_uri(uri); - 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; - - url = mail_tool_get_local_inbox_url(); - folder = mail_tool_get_folder_from_urlname (url, "mbox", TRUE, 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", FALSE, ex); -} - - -CamelFolder * -mail_tool_do_movemail (const gchar *source_url, CamelException *ex) -{ - gchar *dest_url; - gchar *dest_path; - const gchar *source; - CamelFolder *ret; - 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; - } - - g_free (dest_path); - - if (camel_exception_is_set (ex)) { - g_free (dest_url); - return NULL; - } - - /* Get the CamelFolder for our dest_path. */ - - ret = mail_tool_get_folder_from_urlname (dest_url, "movemail", TRUE, ex); - g_free (dest_url); - return ret; -} - -void -mail_tool_move_folder_contents (CamelFolder *source, CamelFolder *dest, gboolean use_cache, CamelException *ex) -{ - CamelUIDCache *cache; - GPtrArray *uids; - int i; - - mail_tool_camel_lock_up(); - - camel_object_ref (CAMEL_OBJECT (source)); - camel_object_ref (CAMEL_OBJECT (dest)); - - /* Get all uids of source */ - - 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); - - /* Copy the messages */ - - for (i = 0; i < uids->len; i++) { - CamelMimeMessage *msg; - const CamelMessageInfo *info; - /* 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 */ - - 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); - - 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_fetch_mail_into_searchable (const char *source_url, gboolean keep_on_server, CamelException *ex) -{ - CamelFolder *search_folder = NULL; - CamelFolder *spool_folder = NULL; - - /* If fetching mail from an mbox store, safely copy it to a - * temporary store first. - */ - - if (!strncmp (source_url, "mbox:", 5)) - spool_folder = mail_tool_do_movemail (source_url, ex); - else - spool_folder = mail_tool_get_inbox (source_url, ex); - - /* No new mail */ - if (spool_folder == NULL) - return NULL; - - if (camel_exception_is_set (ex)) - goto cleanup; - - /* can we perform filtering on this source? */ - - if (!(spool_folder->has_summary_capability - && spool_folder->has_search_capability)) { - - /* no :-(. Copy the messages to a local tempbox - * so that the folder browser can search it. */ - gchar *url; - - url = mail_tool_get_local_movemail_url(); - search_folder = mail_tool_get_folder_from_urlname (url, "movemail", TRUE, ex); - g_free (url); - if (camel_exception_is_set (ex)) - goto cleanup; - - mail_tool_move_folder_contents (spool_folder, search_folder, keep_on_server, ex); - if (camel_exception_is_set (ex)) - goto cleanup; - - } else { - /* we can search! don't bother movemailing */ - search_folder = spool_folder; - mail_tool_camel_lock_up(); - camel_object_ref (CAMEL_OBJECT (search_folder)); - mail_tool_camel_lock_down(); - } - - cleanup: - mail_tool_camel_lock_up(); - camel_object_unref (CAMEL_OBJECT (spool_folder)); - mail_tool_camel_lock_down(); - return search_folder; -} - -CamelFolder * -mail_tool_filter_get_folder_func (FilterDriver *d, const char *uri, void *data) -{ - return mail_tool_uri_to_folder_noex (uri); -} - -void -mail_tool_filter_contents_into (CamelFolder *source, CamelFolder *dest, - gboolean delete_source, - gpointer hook_func, gpointer hook_data, - CamelException *ex) -{ - gchar *userrules; - gchar *systemrules; - FilterContext *fc; - FilterDriver *filter; - - 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, NULL, NULL); - g_free (userrules); - g_free (systemrules); - - filter = filter_driver_new (fc, mail_tool_filter_get_folder_func, 0); - - if (hook_func) - camel_object_hook_event (CAMEL_OBJECT (dest), "folder_changed", - hook_func, hook_data); - - filter_driver_run (filter, source, dest, FILTER_SOURCE_INCOMING, - TRUE, hook_func, hook_data); - - camel_folder_sync (CAMEL_FOLDER (source), TRUE, ex); - camel_folder_sync (CAMEL_FOLDER (dest), TRUE, ex); - - if (delete_source) { - gchar *path = mail_tool_get_local_movemail_path(); - struct stat sb; - - if (stat (path, &sb) < 0) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("Couldn't stat(2) movemail folder %s"), - path); - g_free (path); - return; - } - - if (sb.st_size == 0) - unlink (path); - - g_free (path); - } -} - -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)) { - char *service, *ptr; - - service = g_strdup_printf ("%s/", uri); - for (ptr = service + 7; *ptr && *ptr != '/'; ptr++); - ptr++; - *ptr = '\0'; - - mail_tool_camel_lock_up (); - store = camel_session_get_store (session, service, ex); - g_free (service); - if (store) { - CamelURL *url = CAMEL_SERVICE (store)->url; - char *folder_uri; - - for (ptr = (char *)(uri + 7); *ptr && *ptr != '/'; ptr++); - if (*ptr == '/') { - if (url && url->path) { - ptr += strlen (url->path); - printf ("ptr = %s\n", ptr); - if (*ptr == '/') - ptr++; - } - - if (*ptr == '/') - ptr++; - /*for ( ; *ptr && *ptr == '/'; ptr++);*/ - - folder_uri = g_strdup (ptr); - folder = camel_store_get_folder (store, folder_uri, TRUE, ex); - g_free (folder_uri); - } - } - - mail_tool_camel_lock_down (); - - } else if (!strncmp (uri, "news:", 5)) { - mail_tool_camel_lock_up(); - store = camel_session_get_store (session, uri, ex); - if (store) { - const char *folder_path; - - folder_path = uri + 5; - folder = camel_store_get_folder (store, folder_path, FALSE, 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); - GDK_THREADS_ENTER (); - gnome_dialog_run_and_close (GNOME_DIALOG (dialog)); - GDK_THREADS_LEAVE (); - gtk_widget_destroy (dialog); - } - - return result; -} - diff --git a/mail/mail-tools.h b/mail/mail-tools.h deleted file mode 100644 index 3aba7dde2c..0000000000 --- a/mail/mail-tools.h +++ /dev/null @@ -1,115 +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, - gboolean create, 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 */ -gchar *mail_tool_get_local_inbox_url (void); - -/* 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 movemail folder that was created. */ -CamelFolder * -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); - -/* Fetch mail from the source URL's inbox into a searchable folder. - * (not guaranteed to be local). Returns the searchable folder. */ -CamelFolder * -mail_tool_fetch_mail_into_searchable (const char *source_url, gboolean keep_on_server, CamelException *ex); - -/* Filter source into dest using the default filters. */ -void -mail_tool_filter_contents_into (CamelFolder *source, CamelFolder *dest, - gboolean delete_source, - gpointer hook_func, gpointer hook_data, - CamelException *ex); - -/* 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 c5b690563d..0000000000 --- a/mail/mail-types.h +++ /dev/null @@ -1,39 +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 _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 b425fe7bec..0000000000 --- a/mail/mail-vfolder.c +++ /dev/null @@ -1,317 +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)) ) { - 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/vfolder/%s?%s", evolution_dir, info->name, info->query);*/ - 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, - "mail", - uri, - info->name); - 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/vfolder/%s?%s", evolution_dir, info->name, info->query);*/ - uri = g_strdup_printf("vfolder:%s", info->name); - path = g_strdup_printf("/%s", info->name); - evolution_storage_new_folder (vfolder_storage, path, - "mail", - uri, - info->name); - 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, NULL, NULL) != 0) { - g_warning("cannot load vfolders: %s\n", ((RuleContext *)context)->error); - } - g_free(user); - g_free(system); - vfolder_refresh(); -} - -/* THIS IS ANALOGOUS TO mail_tool_uri_to_folder. IT IS NOT ASYNCHRONOUS */ -/* 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); - - storeuri = g_strdup_printf("vfolder:%s/vfolder/%s", evolution_dir, info->name); - foldername = g_strdup_printf("mbox?%s", info->query); - - folder = mail_tool_get_folder_from_urlname (storeuri, foldername, TRUE, 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_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 6c336a47f8..0000000000 --- a/mail/mail-view.c +++ /dev/null @@ -1,243 +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" - -typedef struct mail_view_data_s { - CamelFolder *source; - gchar *uid; - CamelMimeMessage *msg; - MailDisplay *md; -} mail_view_data; - -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; - - uids = g_ptr_array_new(); - g_ptr_array_add (uids, g_strdup (data->uid)); - - composer = E_MSG_COMPOSER (e_msg_composer_new ()); - 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 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 -}; - -GtkWidget * -mail_view_create (CamelFolder *source, const char *uid, CamelMimeMessage *msg) -{ - GtkWidget *window; - GtkWidget *toolbar; - GtkWidget *mail_display; - GnomeDockItemBehavior behavior; - 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); - - behavior = GNOME_DOCK_ITEM_BEH_NORMAL; - if (!gnome_preferences_get_toolbar_detachable ()) - behavior |= GNOME_DOCK_ITEM_BEH_LOCKED; - - gnome_app_add_toolbar (GNOME_APP (window), - GTK_TOOLBAR (toolbar), - GNOME_APP_TOOLBAR_NAME, - behavior, - GNOME_DOCK_TOP, 1, 0, 0); - - 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)); - gtk_widget_set_usize (mail_display, 600, 600); - data->md = MAIL_DISPLAY (mail_display); - gnome_app_set_contents (GNOME_APP (window), mail_display); - - return window; -} - - - diff --git a/mail/mail.h b/mail/mail.h deleted file mode 100644 index 8a67d745fb..0000000000 --- a/mail/mail.h +++ /dev/null @@ -1,94 +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. - */ - -#include <gtkhtml/gtkhtml.h> -#include "camel/camel.h" -#include "composer/e-msg-composer.h" -#include "mail-config.h" -#include "mail-config-gui.h" -#include "folder-browser.h" - -extern char *evolution_dir; - -/* mail-config */ -void mail_config_druid (void); - -/* mail-crypto */ -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); -/* FIXME: add encryption & signing functions */ - -/* mail-format */ -void mail_format_mime_message (CamelMimeMessage *mime_message, - MailDisplay *md); - -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-callbacks */ -void fetch_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 move_msg (GtkWidget *widget, gpointer user_data); -void copy_msg (GtkWidget *widget, gpointer user_data); -void print_msg (GtkWidget *widget, gpointer user_data); -void edit_msg (GtkWidget *widget, gpointer user_data); -void view_msg (GtkWidget *widget, gpointer user_data); - -void mark_all_seen (BonoboUIHandler *uih, void *user_data, const char *path); -void edit_message (BonoboUIHandler *uih, void *user_data, const char *path); -void view_message (BonoboUIHandler *uih, void *user_data, const char *path); -void expunge_folder (BonoboUIHandler *uih, void *user_data, const char *path); -void filter_edit (BonoboUIHandler *uih, void *user_data, const char *path); -void vfolder_edit_vfolders (BonoboUIHandler *uih, void *user_data, const char *path); -void providers_config (BonoboUIHandler *uih, void *user_data, const char *path); - -void configure_folder(BonoboUIHandler *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 mail_print_msg (MailDisplay *md); - -void run_filter_ondemand (BonoboUIHandler *uih, gpointer user_data, const char *path); - -/* mail view */ -GtkWidget *mail_view_create (CamelFolder *source, const char *uid, CamelMimeMessage *msg); - -/* session */ -void session_init (void); -char *mail_request_dialog (const char *prompt, gboolean secret, - const char *key, gboolean async); -void forget_passwords (BonoboUIHandler *uih, void *user_data, - const char *path); -extern CamelSession *session; diff --git a/mail/main.c b/mail/main.c deleted file mode 100644 index a88117b2c3..0000000000 --- a/mail/main.c +++ /dev/null @@ -1,75 +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> - -#ifdef GTKHTML_HAVE_GCONF -#include <gconf/gconf.h> -#endif - -#include "e-util/e-gui-utils.h" -#include "e-util/e-cursors.h" - -#include "component-factory.h" -#include "mail.h" - -int -main (int argc, char *argv []) -{ - CORBA_ORB orb; - - /* free (malloc (10));*/ - - bindtextdomain (PACKAGE, EVOLUTION_LOCALEDIR); - textdomain (PACKAGE); - - 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 (); - - session_init (); - e_cursors_init (); - - component_factory_init (); - - signal (SIGSEGV, SIG_DFL); - signal (SIGBUS, SIG_DFL); - - 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 7499cbb651..0000000000 --- a/mail/message-list.c +++ /dev/null @@ -1,1267 +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) - * - * (C) 2000 Helix Code, Inc. - */ - -#include <config.h> -#include <gnome.h> -#include <bonobo/bonobo-main.h> -#include <e-util/e-util.h> -#include <e-util/e-gui-utils.h> -#include <e-util/e-popup-menu.h> -#include <camel/camel-exception.h> -#include <camel/camel-folder.h> -#include "message-list.h" -#include "message-thread.h" -#include "mail-threads.h" -#include "mail-tools.h" -#include "mail-ops.h" -#include "mail-config.h" -#include "mail-vfolder.h" -#include "mail-autofilter.h" -#include "mail.h" -#include "Mail.h" -#include "widgets/e-table/e-table-header-item.h" -#include "widgets/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/empty.xpm" -#include "art/tree-expanded.xpm" -#include "art/tree-unexpanded.xpm" - -/* - * Default sizes for the ETable display - * - */ -#define N_CHARS(x) (CHAR_WIDTH * (x)) - -#define COL_ICON_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 void select_row (ETableScrolled *table, gpointer user_data); -static gint on_right_click (ETableScrolled *table, gint row, gint col, GdkEvent *event, MessageList *list); -static void on_double_click (ETableScrolled *table, gint row, MessageList *list); -static void select_msg (MessageList *message_list, gint row); -static char *filter_date (const void *data); -static void nuke_uids (GtkObject *o); - -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 }, - { tree_expanded_xpm, NULL }, - { tree_unexpanded_xpm, NULL }, - { NULL, NULL } -}; - -/* Gets the CamelMessageInfo for the message displayed at the given - * view row. - */ -static const CamelMessageInfo * -get_message_info (MessageList *message_list, int row) -{ - ETreeModel *model = (ETreeModel *)message_list->table_model; - ETreePath *node; - 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 (strncmp (uid, "uid:", 4) != 0) - return NULL; - uid += 4; - - return camel_folder_get_message_info (message_list->folder, uid); -} - -/* 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 (strncmp (uid, "uid:", 4) != 0) - return NULL; - uid += 4; - - return uid; -} - -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; -} - -/** - * 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 view row 0. @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); - - if (direction == MESSAGE_LIST_SELECT_PREVIOUS) - last = 0; - else - last = e_table_model_row_count (message_list->table_model); - - if (base_row == -1) - vrow = 0; - else - 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, mrow); - mail_do_display_message (message_list, info->uid, mark_msg_seen); - return; - } - vrow += direction; - } - - mail_display_set_message (message_list->parent_folder_browser->mail_display, NULL); -} - -/* select a message and display it */ -static void -select_msg (MessageList *message_list, gint row) -{ - const char *uid; - - uid = get_message_uid (message_list, row); - mail_do_display_message (message_list, uid, mark_msg_seen); -} - - -static GdkPixbuf * -ml_tree_icon_at (ETreeModel *etm, ETreePath *path, void *model_data) -{ - /* we dont really need an icon ... */ - return NULL; -} - -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 (strncmp (uid, "uid:", 4) != 0) - goto fake; - uid += 4; - - msg_info = camel_folder_get_message_info (message_list->folder, uid); - g_return_val_if_fail (msg_info != NULL, NULL); - - switch (col){ - case COL_ONLINE_STATUS: - return GINT_TO_POINTER (0); - - 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_PRIORITY: - return GINT_TO_POINTER (1); - - case COL_ATTACHMENT: - return GINT_TO_POINTER (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: - return GINT_TO_POINTER(!!(msg_info->flags & CAMEL_MESSAGE_DELETED)); - - case COL_UNREAD: - return GINT_TO_POINTER(!(msg_info->flags & CAMEL_MESSAGE_SEEN)); - - case COL_COLOUR: - return (void *) camel_tag_get((CamelTag **) &msg_info->user_tags, "colour"); - } - - g_assert_not_reached (); - - fake: - /* This is a fake tree parent */ - switch (col){ - case COL_ONLINE_STATUS: - case COL_MESSAGE_STATUS: - case COL_PRIORITY: - case COL_ATTACHMENT: - case COL_DELETED: - case COL_COLOUR: - case COL_UNREAD: - case COL_SENT: - case COL_RECEIVED: - return (void *) 0; - - case COL_SUBJECT: - return strchr (uid, ':') + 1; - - 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) -{ - MessageList *message_list = model_data; - const CamelMessageInfo *msg_info; - char *uid; - GPtrArray *uids; - - if (col != COL_MESSAGE_STATUS) - return; - - uid = e_tree_model_node_get_data (etm, path); - if (strncmp (uid, "uid:", 4) != 0) - return; - uid += 4; - - msg_info = camel_folder_get_message_info (message_list->folder, uid); - if (!msg_info) - return; - - uids = g_ptr_array_new (); - g_ptr_array_add (uids, g_strdup (uid)); - mail_do_flag_messages (message_list->folder, uids, TRUE, - CAMEL_MESSAGE_SEEN, CAMEL_MESSAGE_SEEN); - - if (message_list->seen_id) { - gtk_timeout_remove (message_list->seen_id); - message_list->seen_id = 0; - } -} - -static gboolean -ml_tree_is_cell_editable (ETreeModel *etm, ETreePath *path, int col, void *model_data) -{ - return col == COL_MESSAGE_STATUS; -} - -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 void -message_list_init_renderers (MessageList *message_list) -{ - GdkPixbuf *images [3]; - - g_assert (message_list); - g_assert (message_list->table_model); - - message_list->render_text = e_cell_text_new ( - message_list->table_model, - NULL, GTK_JUSTIFY_LEFT); - - gtk_object_set(GTK_OBJECT(message_list->render_text), - "strikeout_column", COL_DELETED, - NULL); - gtk_object_set(GTK_OBJECT(message_list->render_text), - "bold_column", COL_UNREAD, - NULL); - gtk_object_set(GTK_OBJECT(message_list->render_text), - "color_column", COL_COLOUR, - NULL); - - message_list->render_date = e_cell_text_new ( - message_list->table_model, - NULL, GTK_JUSTIFY_LEFT); - - gtk_object_set(GTK_OBJECT(message_list->render_date), - "text_filter", filter_date, - NULL); - gtk_object_set(GTK_OBJECT(message_list->render_date), - "strikeout_column", COL_DELETED, - NULL); - gtk_object_set(GTK_OBJECT(message_list->render_date), - "bold_column", COL_UNREAD, - NULL); - gtk_object_set(GTK_OBJECT(message_list->render_date), - "color_column", COL_COLOUR, - NULL); - - message_list->render_online_status = e_cell_checkbox_new (); - - /* - * Message status - */ - images [0] = states_pixmaps [0].pixbuf; - images [1] = states_pixmaps [1].pixbuf; - images [2] = states_pixmaps [2].pixbuf; - - message_list->render_message_status = e_cell_toggle_new (0, 3, images); - - /* - * Attachment - */ - images [0] = states_pixmaps [3].pixbuf; - images [1] = states_pixmaps [4].pixbuf; - - message_list->render_attachment = e_cell_toggle_new (0, 2, images); - - /* - * FIXME: We need a real renderer here - */ - message_list->render_priority = e_cell_checkbox_new (); - - /* - * for tree view - */ - message_list->render_tree = - e_cell_tree_new (message_list->table_model, - states_pixmaps[5].pixbuf, - states_pixmaps[6].pixbuf, - TRUE, message_list->render_text); -} - -static void -message_list_init_header (MessageList *message_list) -{ - int i; - - /* - * FIXME: - * - * Use the font metric to compute this. - */ - - message_list->header_model = e_table_header_new (); - gtk_object_ref (GTK_OBJECT (message_list->header_model)); - gtk_object_sink (GTK_OBJECT (message_list->header_model)); - - message_list->table_cols [COL_ONLINE_STATUS] = - e_table_col_new ( - COL_ONLINE_STATUS, _("Online Status"), - 0.0, COL_CHECK_BOX_WIDTH, - message_list->render_online_status, - g_int_compare, FALSE); - - message_list->table_cols [COL_MESSAGE_STATUS] = - e_table_col_new_with_pixbuf ( - COL_MESSAGE_STATUS, states_pixmaps [0].pixbuf, - 0.0, COL_CHECK_BOX_WIDTH, - message_list->render_message_status, - g_int_compare, FALSE); - - gtk_object_set(GTK_OBJECT(message_list->table_cols[COL_MESSAGE_STATUS]), - "sortable", FALSE, - NULL); - - message_list->table_cols [COL_PRIORITY] = - e_table_col_new ( - COL_PRIORITY, _("Priority"), - 0.0, COL_CHECK_BOX_WIDTH, - message_list->render_priority, - g_int_compare, FALSE); - - message_list->table_cols [COL_ATTACHMENT] = - e_table_col_new_with_pixbuf ( - COL_ATTACHMENT, states_pixmaps [4].pixbuf, - 0.0, COL_ICON_WIDTH, - message_list->render_attachment, - g_int_compare, FALSE); - - gtk_object_set(GTK_OBJECT(message_list->table_cols[COL_ATTACHMENT]), - "sortable", FALSE, - NULL); - - message_list->table_cols [COL_FROM] = - e_table_col_new ( - COL_FROM, _("From"), - COL_FROM_EXPANSION, COL_FROM_WIDTH_MIN, - message_list->render_text, - g_str_compare, TRUE); - - message_list->table_cols [COL_SUBJECT] = - e_table_col_new ( - COL_SUBJECT, _("Subject"), - COL_SUBJECT_EXPANSION, COL_SUBJECT_WIDTH_MIN, - message_list->render_tree, - g_str_compare, TRUE); - - message_list->table_cols [COL_SENT] = - e_table_col_new ( - COL_SENT, _("Date"), - COL_SENT_EXPANSION, COL_SENT_WIDTH_MIN, - message_list->render_date, - g_int_compare, TRUE); - - message_list->table_cols [COL_RECEIVED] = - e_table_col_new ( - COL_RECEIVED, _("Received"), - COL_RECEIVED_EXPANSION, COL_RECEIVED_WIDTH_MIN, - message_list->render_date, - g_int_compare, TRUE); - - message_list->table_cols [COL_TO] = - e_table_col_new ( - COL_TO, _("To"), - COL_TO_EXPANSION, COL_TO_WIDTH_MIN, - message_list->render_text, - g_str_compare, TRUE); - - message_list->table_cols [COL_SIZE] = - e_table_col_new ( - COL_SIZE, _("Size"), - COL_SIZE_EXPANSION, COL_SIZE_WIDTH_MIN, - message_list->render_text, - g_str_compare, TRUE); - - for (i = 0; i < COL_LAST; i++) { - gtk_object_ref (GTK_OBJECT (message_list->table_cols [i])); - e_table_header_add_column (message_list->header_model, - message_list->table_cols [i], i); - } -} - -static char * -message_list_get_layout (MessageList *message_list) -{ - /* Message status, From, Subject, Sent Date */ - return g_strdup ("<ETableSpecification> <columns-shown> <column> 1 </column> <column> 4 </column> <column> 5 </column> <column> 6 </column> </columns-shown> <grouping> </grouping> </ETableSpecification>"); -} - -/* - * GtkObject::init - */ -static void -message_list_init (GtkObject *object) -{ - MessageList *message_list = MESSAGE_LIST (object); - char *spec; - - message_list->table_model = (ETableModel *) - e_tree_simple_new (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) nuke_uids, NULL); - - message_list_init_renderers (message_list); - message_list_init_header (message_list); - - /* - * The etable - */ - - spec = message_list_get_layout (message_list); - message_list->etable = e_table_scrolled_new ( - message_list->header_model, message_list->table_model, spec); - g_free (spec); - - gtk_object_set(GTK_OBJECT(message_list->etable), - "cursor_mode", E_TABLE_CURSOR_LINE, - "drawfocus", FALSE, - "drawgrid", 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), "right_click", - GTK_SIGNAL_FUNC (on_right_click), message_list); - - gtk_signal_connect (GTK_OBJECT (message_list->etable), "double_click", - GTK_SIGNAL_FUNC (on_double_click), message_list); - - 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)); -} - -static void -free_key (gpointer key, gpointer value, gpointer data) -{ - g_free (key); -} - -static void -message_list_destroy (GtkObject *object) -{ - MessageList *message_list = MESSAGE_LIST (object); - int i; - - - gtk_object_unref (GTK_OBJECT (message_list->table_model)); - gtk_object_unref (GTK_OBJECT (message_list->header_model)); - - /* - * Renderers - */ - gtk_object_unref (GTK_OBJECT (message_list->render_text)); - gtk_object_unref (GTK_OBJECT (message_list->render_online_status)); - gtk_object_unref (GTK_OBJECT (message_list->render_message_status)); - gtk_object_unref (GTK_OBJECT (message_list->render_priority)); - gtk_object_unref (GTK_OBJECT (message_list->render_attachment)); - gtk_object_unref (GTK_OBJECT (message_list->render_tree)); - - gtk_object_unref (GTK_OBJECT (message_list->etable)); - - if (message_list->uid_rowmap) { - g_hash_table_foreach (message_list->uid_rowmap, - free_key, NULL); - g_hash_table_destroy (message_list->uid_rowmap); - } - - for (i = 0; i < COL_LAST; i++) - gtk_object_unref (GTK_OBJECT (message_list->table_cols [i])); - - 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_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 (FolderBrowser *parent_folder_browser) -{ - Evolution_MessageList corba_object; - MessageList *message_list; - - g_assert (parent_folder_browser); - - 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->parent_folder_browser = parent_folder_browser; - - 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); - - if (ml->tree_root) - e_tree_model_node_remove (etm, ml->tree_root); - ml->tree_root = - e_tree_model_node_insert (etm, NULL, 0, ml); - e_tree_model_node_set_expanded (etm, ml->tree_root, TRUE); -} - -/* 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); - -static void -build_tree (MessageList *ml, struct _container *c) -{ - int row = 0; - - clear_tree (ml); - build_subtree (ml, ml->tree_root, c, &row); -} - -static void -build_subtree (MessageList *ml, ETreePath *parent, - struct _container *c, int *row) -{ - ETreeModel *tree = E_TREE_MODEL (ml->table_model); - ETreePath *node; - char *id; - - while (c) { - if (c->message) { - id = g_strdup_printf ("uid:%s", c->message->uid); - g_hash_table_insert (ml->uid_rowmap, - g_strdup (c->message->uid), - GINT_TO_POINTER ((*row)++)); - } else - id = g_strdup_printf ("subject:%s", c->root_subject); - node = e_tree_model_node_insert (tree, parent, 0, id); - if (c->child) { - /* by default, open all trees */ - e_tree_model_node_set_expanded (tree, node, TRUE); - build_subtree (ml, node, c->child, row); - } - c = c->next; - } -} - -static gboolean -nuke_uids_cb (GNode *node, gpointer data) -{ - g_free (e_tree_model_node_get_data (E_TREE_MODEL (data), node)); - return FALSE; -} - -static void -nuke_uids (GtkObject *o) -{ - ETreeModel *etm = E_TREE_MODEL (o); - - g_node_traverse (etm->root, G_IN_ORDER, - G_TRAVERSE_ALL, 0, - nuke_uids_cb, etm); -} - -static void -build_flat (MessageList *ml, GPtrArray *uids) -{ - ETreeModel *tree = E_TREE_MODEL (ml->table_model); - ETreePath *node; - char *uid; - int i; - - clear_tree (ml); - for (i = 0; i < uids->len; i++) { - uid = g_strdup_printf ("uid:%s", (char *)uids->pdata[i]); - node = e_tree_model_node_insert (tree, ml->tree_root, i, uid); - g_hash_table_insert (ml->uid_rowmap, g_strdup (uids->pdata[i]), - GINT_TO_POINTER (i)); - } -} - -static void -main_folder_changed (CamelObject *o, gpointer event_data, gpointer user_data) -{ - MessageList *message_list = MESSAGE_LIST (user_data); - - mail_do_regenerate_messagelist (message_list, message_list->search); -} - -static void -folder_changed (CamelObject *o, gpointer event_data, gpointer user_data) -{ - mail_op_forward_event (main_folder_changed, o, event_data, 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)); - - camel_exception_init (&ex); - - if (message_list->folder) - camel_object_unref (CAMEL_OBJECT (message_list->folder)); - - message_list->folder = camel_folder; - - 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)); - - /*gtk_idle_add (regen_message_list, message_list);*/ - /*folder_changed (CAMEL_OBJECT (camel_folder), 0, message_list);*/ - mail_do_regenerate_messagelist (message_list, message_list->search); -} - -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; - - select_msg (message_list, message_list->cursor_row); - - message_list->idle_id = 0; - return FALSE; -} - -static void -on_cursor_change_cmd (ETableScrolled *table, int row, gpointer user_data) -{ - MessageList *message_list; - const char *uid; - - message_list = MESSAGE_LIST (user_data); - - message_list->cursor_row = row; - uid = get_message_uid (message_list, row); - message_list->cursor_uid = uid; /*NULL ok*/ - - if (!message_list->idle_id) { - message_list->idle_id = - g_idle_add_full (G_PRIORITY_LOW, on_cursor_change_idle, - message_list, NULL); - } -} - -/* FIXME: this is all a kludge. */ -static gint -idle_select_row (gpointer user_data) -{ - MessageList *ml = MESSAGE_LIST (user_data); - - message_list_select (ml, -1, MESSAGE_LIST_SELECT_NEXT, - 0, CAMEL_MESSAGE_SEEN); - return FALSE; -} - -static void -select_row (ETableScrolled *table, gpointer user_data) -{ - MessageList *message_list = user_data; - - gtk_idle_add (idle_select_row, message_list); -} - -static void -vfolder_subject(GtkWidget *w, FolderBrowser *fb) -{ - vfolder_gui_add_from_message(fb->mail_display->current_message, AUTO_SUBJECT, - fb->uri); -} - -static void -vfolder_sender(GtkWidget *w, FolderBrowser *fb) -{ - vfolder_gui_add_from_message(fb->mail_display->current_message, AUTO_FROM, - fb->uri); -} - -static void -vfolder_recipient(GtkWidget *w, FolderBrowser *fb) -{ - vfolder_gui_add_from_message(fb->mail_display->current_message, AUTO_TO, - fb->uri); -} - -static void -filter_subject(GtkWidget *w, FolderBrowser *fb) -{ - filter_gui_add_from_message(fb->mail_display->current_message, AUTO_SUBJECT); -} - -static void -filter_sender(GtkWidget *w, FolderBrowser *fb) -{ - filter_gui_add_from_message(fb->mail_display->current_message, AUTO_FROM); -} - -static void -filter_recipient(GtkWidget *w, FolderBrowser *fb) -{ - filter_gui_add_from_message(fb->mail_display->current_message, AUTO_TO); -} - -static gint -on_right_click (ETableScrolled *table, gint row, gint col, GdkEvent *event, MessageList *list) -{ - FolderBrowser *fb = list->parent_folder_browser; - extern CamelFolder *drafts_folder; - int enable_mask = 0; - EPopupMenu menu[] = { - { "Open in New Window", NULL, GTK_SIGNAL_FUNC (view_msg), 0 }, - { "Edit Message", NULL, GTK_SIGNAL_FUNC (edit_msg), 1 }, - { "Print Message", 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 Message", NULL, GTK_SIGNAL_FUNC (forward_msg), 0 }, - { "", NULL, GTK_SIGNAL_FUNC (NULL), 0 }, - { "Delete Message", NULL, GTK_SIGNAL_FUNC (delete_msg), 0 }, - { "Move Message", NULL, GTK_SIGNAL_FUNC (move_msg), 0 }, - { "Copy Message", NULL, GTK_SIGNAL_FUNC (copy_msg), 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 }, - { NULL, NULL, NULL, 0 } - }; - - if (fb->folder != drafts_folder) - enable_mask |= 1; - if (fb->mail_display->current_message == NULL) - enable_mask |= 2; - - e_popup_menu_run (menu, (GdkEventButton *)event, enable_mask, 0, fb); - - return TRUE; -} - -static void -on_double_click (ETableScrolled *table, gint row, MessageList *list) -{ - FolderBrowser *fb = list->parent_folder_browser; - - view_msg (NULL, fb); -} - -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); -} - -void -message_list_toggle_threads (BonoboUIHandler *uih, void *user_data, - const char *path) -{ - MessageList *ml = user_data; - - mail_config_set_thread_list (bonobo_ui_handler_menu_get_toggle_state (uih, path)); - mail_do_regenerate_messagelist (ml, ml->search); -} - -/* ** REGENERATE MESSAGELIST ********************************************** */ - -typedef struct regenerate_messagelist_input_s { - MessageList *ml; - char *search; -} regenerate_messagelist_input_t; - -typedef struct regenerate_messagelist_data_s { - GPtrArray *uids; -} 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)); - e_table_model_pre_change (input->ml->table_model); -} - -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; - - if (input->ml->search) { - g_free (input->ml->search); - input->ml->search = NULL; - } - - if (input->ml->uid_rowmap) { - g_hash_table_foreach (input->ml->uid_rowmap, - free_key, NULL); - g_hash_table_destroy (input->ml->uid_rowmap); - } - input->ml->uid_rowmap = g_hash_table_new (g_str_hash, g_str_equal); - - mail_tool_camel_lock_up(); - - if (input->search) { - data->uids = camel_folder_search_by_expression (input->ml->folder, - input->search, ex); - if (camel_exception_is_set (ex)) { - mail_tool_camel_lock_down(); - return; - } - - input->ml->search = g_strdup (input->search); - } else - data->uids = camel_folder_get_uids (input->ml->folder); - - 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); - - /* FIXME: free the old tree data */ - - if (data->uids == NULL) { /*exception*/ - gtk_object_unref (GTK_OBJECT (input->ml)); - return; - } - - if (mail_config_thread_list()) { - mail_do_thread_messages (input->ml, data->uids, - (gboolean) !(input->search), - build_tree); - } else { - build_flat (input->ml, data->uids); - - if (input->search) { - camel_folder_search_free (input->ml->folder, data->uids); - } else { - camel_folder_free_uids (input->ml->folder, data->uids); - } - } - - e_table_model_changed (input->ml->table_model); - select_row (NULL, input->ml); - g_free (input->search); - 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 -}; - -void mail_do_regenerate_messagelist (MessageList *list, const gchar *search) -{ - regenerate_messagelist_input_t *input; - - input = g_new (regenerate_messagelist_input_t, 1); - input->ml = list; - input->search = g_strdup (search); - - 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 4f9719f30b..0000000000 --- a/mail/message-list.h +++ /dev/null @@ -1,118 +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-handler.h> -#include "e-table/e-table-scrolled.h" -#include "e-table/e-table-simple.h" -#include "e-table/e-tree-simple.h" -#include "e-table/e-cell-text.h" -#include "e-table/e-cell-toggle.h" -#include "e-table/e-cell-checkbox.h" -#include "e-table/e-cell-tree.h" -#include "folder-browser.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_ONLINE_STATUS, - COL_MESSAGE_STATUS, - COL_PRIORITY, - 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; - - /* the folder browser that contains the - * this message list */ - FolderBrowser *parent_folder_browser; - - ETableModel *table_model; - ETableHeader *header_model; - ETableCol *table_cols [COL_LAST]; - - ECell *render_text; - ECell *render_date; - ECell *render_online_status; - ECell *render_message_status; - ECell *render_priority; - ECell *render_attachment; - ECell *render_tree; - - ETreePath *tree_root; /* for tree view */ - - GtkWidget *etable; - - CamelFolder *folder; - - GHashTable *uid_rowmap; - - char *search; /* search string */ - - int cursor_row; - const char *cursor_uid; - - /* row-selection and seen-marking timers */ - guint idle_id, seen_id; -}; - -typedef struct { - BonoboObjectClass parent_class; -} 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 (FolderBrowser *parent_folder_browser); -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); - -extern gboolean threaded_view; -void message_list_toggle_threads (BonoboUIHandler *uih, - void *user_data, - const char *path); - -#endif /* _MESSAGE_LIST_H_ */ diff --git a/mail/message-thread.c b/mail/message-thread.c deleted file mode 100644 index c8ed152e71..0000000000 --- a/mail/message-thread.c +++ /dev/null @@ -1,942 +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 "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 LEAKDEBUG*/ - -/* **************************************** */ -/* mem leak debug stuff */ - -#ifdef LEAKDEBUG - -static GHashTable *allocedht = NULL; - -#define EXISTS (1 << 0) -#define WALKED (1 << 1) -#define FREED (1 << 2) -#define AL_401 (1 << 3) -#define AL_541 (1 << 4) -#define AL_546 (1 << 5) -#define AL_569 (1 << 6) -#define LINKED (1 << 7) -#define EXCUSED (1 << 8) - -#define GITP(x) GINT_TO_POINTER(x) -#define GPTI(x) GPOINTER_TO_INT(x) - -static struct _container * -alloc_container (int where) -{ - struct _container *c; - - c = g_new0 (struct _container, 1); - - if (!allocedht) - allocedht = g_hash_table_new (g_direct_hash, g_direct_equal); - - g_hash_table_insert (allocedht, c, GITP(EXISTS|where)); - return c; -} - -static void -free_container (struct _container **c) -{ - gpointer flags; - - memset ((*c), 0, sizeof (struct _container)); - if ((flags = g_hash_table_lookup (allocedht, (*c))) == NULL) - printf ("** threading mem debug: freeing unalloced entry %p?\n", (*c)); - g_hash_table_insert (allocedht, (*c), GITP(GPTI(flags)|FREED)); - g_free ((*c)); - (*c) = NULL; -} - -static void -cont_print (gpointer key, gpointer value, gpointer user) -{ - struct _container *c = (struct _container *) key; - char *line; - - if (GPTI(value) & FREED) - return; - - if (GPTI(value) & AL_401) - line = "401"; - else if (GPTI(value) & AL_541) - line = "541"; - else if (GPTI(value) & AL_546) - line = "546"; - else if (GPTI(value) & AL_569) - line = "569"; - else - line = "???"; - - printf (" %p : %s %s %s %s %s", - c, - GPTI(value) & FREED ? "freed" : "unfrd", - GPTI(value) & WALKED ? "walked" : "unwlkd", - line, - GPTI(value) & LINKED ? "linked" : "unlnkd", - GPTI(value) & EXCUSED ? "excused" : "unexcsd"); - - if ((GPTI(value) & FREED) == 0) { - gpointer oth_flags; - - printf (" : %p %p %p : \"%s\" \"%s\" %d %d", - c->next, c->parent, c->child, - c->message ? c->message->subject : "(null message)", - c->root_subject ? c->root_subject : "(null root-subject)", - c->re, c->order); - - if (c->next) { - oth_flags = g_hash_table_lookup (allocedht, c->next); - - printf ("\n next : %p : %s %s %s", - c->next, - GPTI(oth_flags) & WALKED ? "walked" : "unwlkd", - GPTI(oth_flags) & LINKED ? "linked" : "unlnkd", - GPTI(oth_flags) & EXCUSED ? "excused" : "unexcsd"); - } - - if (c->parent) { - oth_flags = g_hash_table_lookup (allocedht, c->parent); - - printf ("\n prnt : %p : %s %s %s", - c->parent, - GPTI(oth_flags) & WALKED ? "walked" : "unwlkd", - GPTI(oth_flags) & LINKED ? "linked" : "unlnkd", - GPTI(oth_flags) & EXCUSED ? "excused" : "unexcsd"); - } - - if (c->child) { - oth_flags = g_hash_table_lookup (allocedht, c->child); - - printf ("\n chld : %p : %s %s %s", - c->child, - GPTI(oth_flags) & WALKED ? "walked" : "unwlkd", - GPTI(oth_flags) & LINKED ? "linked" : "unlnkd", - GPTI(oth_flags) & EXCUSED ? "excused" : "unexcsd"); - } - - } - - printf ("\n"); - -} - -static void -make_excuses (gpointer key, gpointer value, gpointer user) -{ - struct _container *c; - gpointer chldflags; - gpointer nextflags; - - if (GPTI(value) & FREED) - return; - - c = (struct _container *) key; - - if (c->next) { - nextflags = g_hash_table_lookup (allocedht, c->next); - - if ((GPTI(nextflags) & EXCUSED) == 0) { - g_hash_table_insert (allocedht, c->next, GITP(GPTI(nextflags)|EXCUSED)); - ((gint *)user) = 1; - } - } - - if (c->child) { - chldflags = g_hash_table_lookup (allocedht, c->child); - - if ((GPTI(chldflags) & EXCUSED) == 0) { - g_hash_table_insert (allocedht, c->child, GITP(GPTI(chldflags)|EXCUSED)); - ((gint *)user) = 1; - } - } -} - -static void -print_containers (void) -{ - gint hit; - - do { - hit = 0; - g_hash_table_foreach (allocedht, make_excuses, &hit); - } while (hit); - - printf ("List of container stats:\n"); - g_hash_table_foreach (allocedht, cont_print, NULL); - printf ("End of list.\n"); -} - -static void -walk_containers (struct _container *head) -{ - gpointer flags; - - while (head) { - if (head->child) - walk_containers (head->child); - if ((flags = g_hash_table_lookup (allocedht, head)) == NULL) { - printf ("*** walk_containers : bad pointer %p\n", head); - } else { - g_hash_table_insert (allocedht, head, GITP(GPTI(flags)|WALKED)); - } - - head = head->next; - } -} - -static void -link_container (struct _container *c) -{ - gpointer flags; - - if ((flags = g_hash_table_lookup (allocedht, c)) == NULL) - printf ("** threading mem debug: linking unalloced entry %p?\n", c); - g_hash_table_insert (allocedht, c, GITP(GPTI(flags)|LINKED)); -} - -#else -#define alloc_container(w) (g_new0 (struct _container, 1)) -#define free_container(c) g_free (*(c)) -#define print_containers() -#define walk_containers(c) -#define link_container(c) -#endif - -/* **************************************** */ - -static struct _container *thread_messages(CamelFolder *folder, GPtrArray *uids); -static void thread_messages_free(struct _container *); - -/* for debug only */ -int dump_tree(struct _container *c, int depth); - -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; -} - -#if 0 -static void -container_unparent_child(struct _container *child) -{ - struct _container *c, *node; - - /* are we unparented? */ - if (child->parent == NULL) { - 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; - return; - } - c = c->next; - } - - printf("DAMN, we shouldn't be here!\n"); -} -#endif - -static void -container_parent_child(struct _container *parent, struct _container *child) -{ - struct _container *c, *node, **prev; - - /* are we already the right parent? */ - if (child->parent == parent) - return; - - /* are we unparented? */ - if (child->parent == NULL) { - container_add_child(parent, child); - return; - } - - /* check for trying to make my child my parent */ - for (c = parent; c; c = c->parent) { - if (c == child) { - d(printf("AIIE: trying to lop off hunk of nodes!\n")); - 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; - *} - */ - - d(printf("PKGW deparent child")); - c = node->child; - prev = &(node->child); - while (c) { - d(printf (" %p\n", c)); - - if (c == child) { - d(printf (" hit child %p\n", child)); - (*prev) = c->next; - c->next = NULL; - c->parent = NULL; - container_add_child (parent, child); - return; - } - - prev = &(c->next); - 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; - free_container (&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; - } - free_container (&c); - 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; - link_container(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 is pretty slow, but not used often */ -static void -remove_node(struct _container **list, struct _container *node, struct _container **clast) -{ - struct _container *c; - - /* this is intentional, even if it looks funny */ - c = (struct _container *)list; - while (c->next) { - if (c->next == node) { - if (clast && *clast == c->next) - *clast = c; - c->next = c->next->next; - break; - } - c = c->next; - } -} - -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; - 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 = alloc_container(AL_401); - 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); -} - -int -dump_tree(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 (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(c->child, depth+1); - c = c->next; - } - return count; -} - -static void thread_messages_free(struct _container *c) -{ - struct _container *n; - - /* FIXME: ok, for some reason this doesn't work .. investigate later ... */ - - while (c) { - n = c->next; - if (c->child) - thread_messages_free(c->child); /* free's children first */ - free_container (&c); - c = n; - } -} - -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; -} - -static struct _container * -thread_messages(CamelFolder *folder, GPtrArray *uids) -{ - GHashTable *id_table, *no_id_table; - int i; - struct _container *c, *p, *child, *head, *container; - struct _header_references *ref; - - 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; - mail_tool_camel_lock_up (); - mi = camel_folder_get_message_info (folder, uids->pdata[i]); - mail_tool_camel_lock_down (); - - if (mi == NULL) { - g_warning("Folder doesn't contain uid %s", (char *)uids->pdata[i]); - continue; - } - - if (mi->message_id) { - d(printf("doing : %s\n", mi->message_id)); - c = g_hash_table_lookup(id_table, mi->message_id); - if (!c) { - c = alloc_container(AL_541); - g_hash_table_insert(id_table, mi->message_id, c); - } - } else { - d(printf("doing : (no message id)\n")); - c = alloc_container(AL_546); - g_hash_table_insert(no_id_table, (void *)mi, c); - } - - c->message = mi; - c->order = i; - container = c; - ref = mi->references; - p = NULL; - child = container; - head = NULL; - d(printf("references:\n")); - while (ref) { - if (ref->id == NULL) { - 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 = alloc_container(AL_569); - 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, 0); - printf("%d count, %d items in tree\n", uids->len, i); -#endif - - sort_thread(&head); - return head; -} - -/* ** 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 _container *container; -} 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; - - if (!IS_MESSAGE_LIST (input->ml)) { - camel_exception_set (ex, CAMEL_EXCEPTION_INVALID_PARAM, - "No messagelist to thread was provided to thread_messages"); - return; - } - - if (!input->uids) { - camel_exception_set (ex, CAMEL_EXCEPTION_INVALID_PARAM, - "No uids were provided to thread_messages"); - return; - } - - if (!input->build) { - camel_exception_set (ex, CAMEL_EXCEPTION_INVALID_PARAM, - "No build callback provided to thread_messages"); - return; - } - - 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; - - data->container = thread_messages (input->ml->folder, input->uids); -} - -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->container); - walk_containers (data->container); - thread_messages_free (data->container); - - print_containers(); - - 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, NULL); - 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", TRUE, 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 5c4be91ade..0000000000 --- a/mail/message-thread.h +++ /dev/null @@ -1,23 +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; /* the order of this message in the folder */ -}; - -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 b76e096abb..0000000000 --- a/mail/session.c +++ /dev/null @@ -1,215 +0,0 @@ -/* - * 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-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_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; - GDK_THREADS_ENTER (); - if (gnome_dialog_run_and_close (GNOME_DIALOG (dialog)) == -1 || - ans == NULL) { - GDK_THREADS_LEAVE (); - return NULL; - } - - GDK_THREADS_LEAVE (); - } 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_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 -session_init (void) -{ - camel_init (); - session = camel_session_new (auth_callback, register_callback, - remove_callback); -} - -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 -forget_passwords (BonoboUIHandler *uih, void *user_data, const char *path) -{ - g_hash_table_foreach_remove (passwords, free_entry, NULL); -} diff --git a/mail/test-mail.c b/mail/test-mail.c deleted file mode 100644 index ecf8c5eda5..0000000000 --- a/mail/test-mail.c +++ /dev/null @@ -1,71 +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; - BonoboUIHandler *uih; - - gdk_rgb_init (); - - gtk_widget_set_default_colormap (gdk_rgb_get_cmap ()); - gtk_widget_set_default_visual (gdk_rgb_get_visual ()); - - window = gtk_window_new (GTK_WINDOW_TOPLEVEL); - gtk_widget_set_usize (GTK_WIDGET (window), 640, 480); - gtk_widget_show (GTK_WIDGET (window)); - - uih = bonobo_ui_handler_new (); - - control = bonobo_widget_new_control ("OAFIID:control:evolution-mail:833d5a71-a201-4a0e-b7e6-5475c5c4cb45", - bonobo_object_corba_objref (BONOBO_OBJECT (uih))); - - 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; -} |