diff options
Diffstat (limited to 'mail')
41 files changed, 0 insertions, 14608 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 d28861ab89..0000000000 --- a/mail/ChangeLog +++ /dev/null @@ -1,2496 +0,0 @@ -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 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-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-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-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 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 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 0e3c09cfb0..0000000000 --- a/mail/Makefile.am +++ /dev/null @@ -1,132 +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) \ - $(GCONF_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 \ - mail-config.c \ - mail-crypto.c \ - mail-display.c \ - mail-display.h \ - mail-format.c \ - mail-identify.c \ - mail-ops.c \ - mail-threads.c \ - mail-threads.h \ - mail-types.h \ - mail-vfolder.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) \ - $(GCONF_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 = \ - $(BONOBO_HTML_GNOME_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 - -schemadir = $(sysconfdir)/gconf/schemas -schema_DATA = evolution-mail.schemas - -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/component-factory.c b/mail/component-factory.c deleted file mode 100644 index 8f25483f0d..0000000000 --- a/mail/component-factory.c +++ /dev/null @@ -1,471 +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 "evolution-shell-component.h" -#include "folder-browser.h" -#include "mail.h" /* YUCK FIXME */ -#include "mail-threads.h" -#include "e-util/e-gui-utils.h" -#include "e-util/e-setup.h" - -#include "component-factory.h" - -static void create_vfolder_storage (EvolutionShellComponent *shell_component); -static void create_imap_storage (EvolutionShellComponent *shell_component); -static void real_create_imap_storage( gpointer user_data ); -static void create_news_storage (EvolutionShellComponent *shell_component); -static void real_create_news_storage( gpointer user_data ); - -#define COMPONENT_FACTORY_ID "OAFIID:evolution-shell-component-factory:evolution-mail:0ea887d5-622b-4b8c-b525-18aa1cbe18a6" - -static BonoboGenericFactory *factory = NULL; - -static const EvolutionShellComponentFolderType folder_types[] = { - { "mail", "evolution-inbox.png" }, - { NULL, NULL } -}; - -/* GROSS HACK: for passing to other parts of the program */ -/*EvolutionShellClient *global_shell_client = 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) -{ - CORBA_Environment ev; - CamelStore *store; - CamelFolder *folder; - CamelException ex; - Evolution_ShellComponentListener_Result result; - - camel_exception_init (&ex); - if (strcmp (type, "mail") != 0) - result = Evolution_ShellComponentListener_UNSUPPORTED_TYPE; - else { - char *camel_url = g_strdup_printf ("mbox://%s", physical_uri); - - store = camel_session_get_store (session, camel_url, &ex); - g_free (camel_url); - if (!camel_exception_is_set (&ex)) { - folder = camel_store_get_folder (store, "mbox", - TRUE, &ex); - gtk_object_unref (GTK_OBJECT (store)); - } else { - folder = NULL; - } - - if (!camel_exception_is_set (&ex)) { - gtk_object_unref (GTK_OBJECT (folder)); - result = Evolution_ShellComponentListener_OK; - } else { - result = Evolution_ShellComponentListener_INVALID_URI; - } - } - - camel_exception_clear (&ex); - - CORBA_exception_init (&ev); - Evolution_ShellComponentListener_report_result (listener, result, &ev); - CORBA_exception_free (&ev); -} - -static void -owner_set_cb (EvolutionShellComponent *shell_component, - EvolutionShellClient *shell_client, - gpointer user_data) -{ - g_print ("evolution-mail: Yeeeh! We have an owner!\n"); /* FIXME */ - - /* GROSS HACK */ - /*global_shell_client = shell_client;*/ - - create_vfolder_storage (shell_component); - create_imap_storage (shell_component); - create_news_storage (shell_component); -} - -static void -owner_unset_cb (EvolutionShellComponent *shell_component, gpointer user_data) -{ - gtk_main_quit (); -} - -/* The factory function. */ - -static BonoboObject * -factory_fn (BonoboGenericFactory *factory, void *closure) -{ - EvolutionShellComponent *shell_component; - - shell_component = evolution_shell_component_new (folder_types, - create_view, - create_folder, - NULL, - NULL, - 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); -} - -struct create_info_s { - EvolutionStorage *storage; - char *source; -}; - -static void -create_imap_storage (EvolutionShellComponent *shell_component) -{ - const MailConfig *config; - EvolutionShellClient *shell_client; - Evolution_Shell corba_shell; - EvolutionStorage *storage; - char *source=NULL, *server, *p; - struct create_info_s *ii; - - config = mail_config_fetch (); - if (config->sources) { - const MailConfigService *s; - s = (MailConfigService *)config->sources->data; - source = s->url; - } - - if (!source || strncasecmp (source, "imap://", 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)); - - if (!(server = strchr (source, '@'))) { - g_free (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"); - g_free (source); - return; - } - - ii = g_new (struct create_info_s, 1); - ii->storage = storage; - ii->source = g_strdup (source); - -#ifdef USE_BROKEN_THREADS - mail_operation_try ("Create IMAP Storage", real_create_imap_storage, g_free, ii); -#else - real_create_imap_storage (ii); - g_free (ii); -#endif - /* Note the g_free as our cleanup function deleting the ii struct when we're done */ -} - -static void -real_create_imap_storage (gpointer user_data) -{ - CamelException *ex; - EvolutionStorage *storage; - char *p, *source; - CamelStore *store; - CamelFolder *folder; - GPtrArray *lsub; - int i, max; - struct create_info_s *ii; - - ii = (struct create_info_s *) user_data; - storage = ii->storage; - source = ii->source; - -#ifdef USE_BROKEN_THREADS - mail_op_hide_progressbar (); - mail_op_set_message ("Connecting to IMAP service..."); -#endif - ex = camel_exception_new (); - - store = camel_session_get_store (session, source, ex); - if (!store) { - goto cleanup; - } - - camel_service_connect (CAMEL_SERVICE (store), ex); - if (camel_exception_get_id (ex) != CAMEL_EXCEPTION_NONE) { - goto cleanup; - } - -#ifdef USE_BROKEN_THREADS - mail_op_set_message ("Connected. Examining folders..."); -#endif - - folder = camel_store_get_root_folder (store, ex); - if (camel_exception_get_id (ex) != CAMEL_EXCEPTION_NONE) { - goto cleanup; - } - - /* we need a way to set the namespace */ - lsub = camel_folder_get_subfolder_names (folder); - - p = g_strdup_printf ("%s/INBOX", source); - evolution_storage_new_folder (storage, "/INBOX", "mail", p, "description"); - - /*dir_sep = CAMEL_IMAP_STORE (store)->dir_sep;*/ - - max = lsub->len; - for (i = 0; i < max; i++) { - char *path, *buf, *dirname; - -#if 0 - if (strcmp (dir_sep, "/")) { - dirname = e_strreplace ((char *)lsub->pdata[i], dir_sep, "/"); - } else { - dirname = g_strdup ((char *)lsub->pdata[i]); - } -#endif - dirname = g_strdup ((char *)lsub->pdata[i]); - - path = g_strdup_printf ("/%s", dirname); - g_free (dirname); - buf = g_strdup_printf ("%s/%s", source, path + 1); - printf ("buf = %s\n", buf); - -#ifdef USE_BROKEN_THREADS - mail_op_set_message ("Adding %s", path); -#endif - - evolution_storage_new_folder (storage, path, "mail", buf, "description"); - } - - cleanup: - g_free (ii->source); -#ifdef USE_BROKEN_THREADS - if (camel_exception_is_set (ex)) - mail_op_error ("%s", camel_exception_get_description (ex)); -#endif - camel_exception_free (ex); -} - -static void -create_news_storage (EvolutionShellComponent *shell_component) -{ - const MailConfig *config; - EvolutionShellClient *shell_client; - Evolution_Shell corba_shell; - EvolutionStorage *storage; - char *source=NULL, *server, *p; - struct create_info_s *ni; - - config = mail_config_fetch (); - if (config->news) { - const MailConfigService *s; - s = (MailConfigService *)config->news->data; - source = s->url; - } - - if (!source || 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"); - g_free (source); - return; - } - - ni = g_new( struct create_info_s, 1 ); - ni->storage = storage; - ni->source = g_strdup( source ); - -#ifdef USE_BROKEN_THREADS - mail_operation_try( "Create News Storage", real_create_news_storage, g_free, ni ); -#else - real_create_news_storage( ni ); - g_free( ni ); -#endif - /* again note the g_free cleanup func */ -} - -static void -real_create_news_storage( gpointer user_data ) -{ - EvolutionStorage *storage; - char *source; - CamelStore *store; - CamelFolder *folder; - CamelException *ex; - GPtrArray *lsub; - int i, max; - struct create_info_s *ni; - - ni = (struct create_info_s *) user_data; - storage = ni->storage; - source = ni->source; - -#ifdef USE_BROKEN_THREADS - mail_op_hide_progressbar(); - mail_op_set_message( "Connecting to news service..." ); -#endif - - ex = camel_exception_new (); - - store = camel_session_get_store (session, source, ex); - if (!store) { - goto cleanup; - } - - camel_service_connect (CAMEL_SERVICE (store), ex); - if (camel_exception_get_id (ex) != CAMEL_EXCEPTION_NONE) { - goto cleanup; - } - -#ifdef USE_BROKEN_THREADS - mail_op_set_message( "Connected. Examining folders..." ); -#endif - - folder = camel_store_get_root_folder (store, ex); - if (camel_exception_get_id (ex) != CAMEL_EXCEPTION_NONE) { - goto cleanup; - } - - /* we need a way to set the namespace */ - lsub = camel_folder_get_subfolder_names (folder); - - max = lsub->len; - for (i = 0; i < max; i++) { - char *path, *buf; - - path = g_strdup_printf ("/%s", (char *)lsub->pdata[i]); - buf = g_strdup_printf ("%s%s", source, path); - -#ifdef USE_BROKEN_THREADS - mail_op_set_message( "Adding %s", path ); -#endif - /* FIXME: should be s,"mail","news",? */ - evolution_storage_new_folder (storage, path, "mail", buf, "description"); - } - - cleanup: - g_free( ni->source ); -#ifdef USE_BROKEN_THREADS - if( camel_exception_is_set( ex ) ) - mail_op_error( "%s", camel_exception_get_description( ex ) ); -#endif - camel_exception_free (ex); -} 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/evolution-mail.schemas b/mail/evolution-mail.schemas deleted file mode 100644 index 44e8d5181a..0000000000 --- a/mail/evolution-mail.schemas +++ /dev/null @@ -1,66 +0,0 @@ -<gconfschemafile> - <schemalist> - <schema> - <key>/schemas/apps/Evolution/Mail/sources</key> - <applyto>/apps/Evolution/Mail/sources</applyto> - <owner>Evolution Mail</owner> - <type>list</type> - <locale name="C"> - <short>A list of mail sources</short> - <long>A list of mail sources, in the form of Camel - URLs. When the user clicks "Get Mail", Evolution will - move all of the mail from these sources through any - configured filters or into the Inbox, deleting the - original copies.</long> - </locale> - </schema> - - <schema> - <key>/schemas/apps/Evolution/Mail/transport</key> - <applyto>/apps/Evolution/Mail/transport</applyto> - <owner>Evolution Mail</owner> - <type>string</type> - <locale name="C"> - <short>Default mail transport</short> - <long>A Camel URL representing the default mail - transport.</long> - </locale> - </schema> - - - <schema> - <key>/schemas/apps/Evolution/Mail/identities</key> - <applyto>/apps/Evolution/Mail/identities</applyto> - <owner>Evolution Mail</owner> - <type>list</type> - <locale name="C"> - <short>A list of identities</short> - <long>A list of the user's identities. Each identity - consists of four newline-separated fields: an address, - a name, an organization, and the path to a file - containing a signature. (All fields but the first can - be empty.)</long> - </locale> - </schema> - - - <schema> - <key>/schemas/apps/Evolution/Mail/send_html</key> - <applyto>/apps/Evolution/Mail/send_html</applyto> - <owner>Evolution Mail</owner> - <type>bool</type> - <locale name="C"> - <short>Whether or not to send HTML mail</short> - <long>Whether or not to send HTML mail. If TRUE, - Evolution will send multipart/alternative mail - containing text/plain and text/html parts. If FALSE, - it will send only the text/plain part. (There is no - way to send only HTML.)</long> - </locale> - </schema> - - - </schemalist> -</gconfschemafile> - - diff --git a/mail/folder-browser-factory.c b/mail/folder-browser-factory.c deleted file mode 100644 index f6ea1d3bd7..0000000000 --- a/mail/folder-browser-factory.c +++ /dev/null @@ -1,206 +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.h" -#include "mail.h" -#include "shell/Evolution.h" - -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_("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 -control_activate (BonoboControl *control, BonoboUIHandler *uih, - FolderBrowser *fb) -{ - Bonobo_UIHandler remote_uih; - BonoboControl *toolbar_control; - 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); - - 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", - threaded_view); - bonobo_ui_handler_menu_set_callback (uih, "/View/Threaded", - message_list_toggle_threads, - FOLDER_BROWSER (folder_browser)->message_list -#ifdef BONOBO_POST_0_15 - , NULL -#endif - ); - - bonobo_ui_handler_menu_new_item (uih, "/Actions/Mark all seen", - _("_Mark all messages seen"), - NULL, -1, - BONOBO_UI_HANDLER_PIXMAP_STOCK, - GNOME_STOCK_PIXMAP_CLEAR, - 0, 0, mark_all_seen, folder_browser); - - bonobo_ui_handler_menu_new_item (uih, "/Actions/Expunge", _("_Expunge"), - NULL, -1, - BONOBO_UI_HANDLER_PIXMAP_STOCK, - GNOME_STOCK_PIXMAP_TRASH, - 0, 0, expunge_folder, folder_browser); - - bonobo_ui_handler_menu_new_item (uih, "/Tools/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, "/Tools/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, "/Tools/Mail Configuration ...", _("_Mail Configuration ..."), - NULL, -1, - BONOBO_UI_HANDLER_PIXMAP_NONE, - 0, - 0, 0, providers_config, NULL); - - bonobo_ui_handler_menu_new_item (uih, "/Tools/Forget Passwords", _("Forget _Passwords"), - NULL, -1, - BONOBO_UI_HANDLER_PIXMAP_NONE, - 0, - 0, 0, forget_passwords, NULL); - - 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); - - 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)), - GNOME_DOCK_ITEM_BEH_EXCLUSIVE | GNOME_DOCK_ITEM_BEH_NEVER_VERTICAL, - 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, "/View/Threaded"); - bonobo_ui_handler_menu_remove (uih, "/Actions/Mark all seen"); - bonobo_ui_handler_menu_remove (uih, "/Actions/Expunge"); - bonobo_ui_handler_menu_remove (uih, "/Tools/Mail Filters ..."); - bonobo_ui_handler_menu_remove (uih, "/Tools/vFolder Editor ..."); - bonobo_ui_handler_menu_remove (uih, "/Tools/Mail Configuration ..."); - bonobo_ui_handler_menu_remove (uih, "/Tools/Forget Passwords"); - bonobo_ui_handler_dock_remove (uih, toolbar_name); - g_free (toolbar_name); -} - -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; - - 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); - - return control; -} diff --git a/mail/folder-browser.c b/mail/folder-browser.c deleted file mode 100644 index 27f345fce0..0000000000 --- a/mail/folder-browser.c +++ /dev/null @@ -1,513 +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 "message-list.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" - -#define PARENT_TYPE (gtk_table_get_type ()) - -static GtkObjectClass *folder_browser_parent_class; - - -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) { - camel_folder_sync (folder_browser->folder, FALSE, NULL); - gtk_object_unref (GTK_OBJECT (folder_browser->folder)); - } - - if (folder_browser->message_list) - bonobo_object_unref (BONOBO_OBJECT (folder_browser->message_list)); - - 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); -} - -CamelFolder * -mail_uri_to_folder (const char *name) -{ - char *store_name, *msg; - CamelStore *store = NULL; - CamelFolder *folder = NULL; - CamelException *ex; - - ex = camel_exception_new (); - - if (!strncmp (name, "vfolder:", 8)) { - folder = vfolder_uri_to_folder(name); - } else if (!strncmp (name, "imap:", 5)) { - char *service, *ptr; - - service = g_strdup_printf ("%s/", name); - for (ptr = service + 7; *ptr && *ptr != '/'; ptr++); - ptr++; - *ptr = '\0'; - - store = camel_session_get_store (session, service, ex); - g_free (service); - - if (store) { - CamelURL *url = CAMEL_SERVICE (store)->url; - char *folder_name; - - /*dir_sep = CAMEL_IMAP_STORE (store)->dir_sep;*/ - - for (ptr = (char *)(name + 7); *ptr && *ptr != '/'; ptr++); - if (*ptr == '/') { - if (url && url->path) { - ptr += strlen (url->path); - if (*ptr == '/') - ptr++; - } - - if (*ptr == '/') - ptr++; - /*for ( ; *ptr && *ptr == '/'; ptr++);*/ - - folder_name = g_strdup (ptr); - /*tree_name = g_strdup (ptr);*/ - /*folder_name = e_strreplace (tree_name, "/", dir_sep);*/ - - folder = camel_store_get_folder (store, folder_name, TRUE, ex); - g_free (folder_name); - } - } - } else if (!strncmp(name, "news:", 5)) { - store = camel_session_get_store (session, name, ex); - if (store) { - const char *folder_name; - - folder_name = name + 5; - - folder = camel_store_get_folder (store, folder_name, FALSE, ex); - } - } else if (!strncmp (name, "file:", 5)) { - /* Change "file:" to "mbox:". */ - store_name = g_strdup_printf ("mbox:%s", name + 5); - store = camel_session_get_store (session, store_name, ex); - g_free (store_name); - if (store) { - folder = camel_store_get_folder (store, "mbox", FALSE, ex); - } - } else { - msg = g_strdup_printf ("Can't open URI %s", name); - gnome_error_dialog (msg); - g_free (msg); - } - - if (camel_exception_get_id (ex)) { - msg = g_strdup_printf ("Unable to get folder %s: %s\n", name, - camel_exception_get_description (ex)); - gnome_error_dialog (msg); - if (folder) { - gtk_object_unref (GTK_OBJECT (folder)); - folder = NULL; - } - } - camel_exception_free (ex); - - if (store) - gtk_object_unref (GTK_OBJECT (store)); - - return folder; -} - -static gboolean -folder_browser_load_folder (FolderBrowser *fb, const char *name) -{ - CamelFolder *new_folder; - - new_folder = mail_uri_to_folder (name); - if (!new_folder) - return FALSE; - - if (fb->folder) - gtk_object_unref (GTK_OBJECT (fb->folder)); - fb->folder = new_folder; - - gtk_widget_set_sensitive (GTK_WIDGET (fb->search_entry), camel_folder_has_search_capability (fb->folder)); - gtk_widget_set_sensitive (GTK_WIDGET (fb->search_menu), camel_folder_has_search_capability (fb->folder)); - - message_list_set_folder (fb->message_list, new_folder); - - return TRUE; -} - -#define EQUAL(a,b) (strcmp (a,b) == 0) - -gboolean -folder_browser_set_uri (FolderBrowser *folder_browser, const char *uri) -{ - if (folder_browser->uri) - g_free (folder_browser->uri); - - folder_browser->uri = g_strdup (uri); - return folder_browser_load_folder (folder_browser, folder_browser->uri); -} - -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) { - message_list_regenerate (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++; - } - } - message_list_regenerate (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); - message_list_regenerate (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); - - e_paned_add2 (E_PANED (fb->vpaned), GTK_WIDGET (fb->mail_display)); - e_paned_set_position (E_PANED (fb->vpaned), 200); - - 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 (fb)); - - gtk_signal_connect (GTK_OBJECT (fb->message_list->etable), - "key_press", GTK_SIGNAL_FUNC (etable_key), fb); - - 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); - - - - diff --git a/mail/folder-browser.h b/mail/folder-browser.h deleted file mode 100644 index ae16b64153..0000000000 --- a/mail/folder-browser.h +++ /dev/null @@ -1,66 +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 "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; - -}; - - -typedef struct { - GtkTableClass parent_class; -} FolderBrowserClass; - - - - -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/mail-config-druid.glade b/mail/mail-config-druid.glade deleted file mode 100644 index 8fd6755651..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>255,255,255</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>255,255,255</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>255,255,255</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>255,255,255</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>255,255,255</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.c b/mail/mail-config.c deleted file mode 100644 index be4dd77231..0000000000 --- a/mail/mail-config.c +++ /dev/null @@ -1,2283 +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 <gconf/gconf.h> -#include <gconf/gconf-client.h> - -#include "e-util/e-html-utils.h" -#include "e-util/e-setup.h" -#include "mail.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 cb; - gpointer data; -}; - -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; - gint pnum; -} MailDialogServicePageItem; - -struct _MailDialogServicePage -{ - GtkWidget *vbox; - GtkWidget *optionmenu; - GList *items; - GtkWidget *notebook; - MailDialogServicePageItem *spitem; - ServicePageCallback changedcb; - gpointer changeddata; - 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; - MailDialogSourcePage *spage; - MailDialogTransportPage *tpage; -} MailDruidDialog; - -typedef struct -{ - GladeXML *gui; - GtkWidget *dialog; - GtkWidget *notebook; - GtkWidget *clistIdentities; - gint idrow; - gint maxidrow; - GtkWidget *clistSources; - gint srow; - gint maxsrow; - GtkWidget *clistNewsServers; - gint nrow; - gint maxnrow; - MailDialogTransportPage *page; - gboolean tpagedone; - GtkWidget *chkFormat; -} MailDialog; - -static const char GCONFPATH[] = "/apps/Evolution/Mail"; -static GConfClient *client = NULL; -static MailConfig *config; - -/* private prototypes - these are ugly, rename some of them? */ -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); -} - -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); -} - -/* 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_append (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 = 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]) { - *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 struct */ -static 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; -} - -static 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); -} - -static void -identity_destroy_each (gpointer item, gpointer data) -{ - identity_destroy ((MailConfigIdentity *)item); -} - -/* Source struct */ -static 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); - - return newsource; -} - -static void -service_destroy (MailConfigService *source) -{ - if (!source) - return; - - g_free (source->url); - - g_free (source); -} - -static void -service_destroy_each (gpointer item, gpointer data) -{ - service_destroy ((MailConfigService *)item); -} - -/* Config struct routines */ -static void -init_config (const gchar *path) -{ - if (config) - return; - - config = g_new0 (MailConfig, 1); - - if (client) - return; - -#ifdef HAVE_GCONF_CLIENT_GET_DEFAULT - client = gconf_client_get_default (); -#else - client = gconf_client_new (); -#endif - - gconf_client_add_dir (client, path, - GCONF_CLIENT_PRELOAD_RECURSIVE, NULL); -} - -static void -clear_config - () -{ - if (!config) - return; - - g_slist_foreach (config->ids, identity_destroy_each, NULL); - g_slist_free (config->ids); - config->ids = NULL; - - g_slist_foreach (config->sources, service_destroy_each, NULL); - g_slist_free (config->sources); - config->sources = NULL; - - service_destroy (config->transport); - config->transport = NULL; -} - -static void -read_config (const gchar *path) -{ - GConfError *err = NULL; - GSList *names, *addr, *orgs, *sigs, *sources, *news; - gchar *str; - gint len, i; - - init_config (path); - clear_config (); - - /* Configured */ - str = g_strdup_printf ("%s/configured", path); - config->configured = gconf_client_get_bool (client, str, &err); - g_free (str); - - /* Identities */ - str = g_strdup_printf ("%s/Identities/names", path); - names = gconf_client_get_list (client, str, GCONF_VALUE_STRING, &err); - g_free (str); - str = g_strdup_printf ("%s/Identities/addresses", path); - addr = gconf_client_get_list (client, str, GCONF_VALUE_STRING, &err); - g_free (str); - str = g_strdup_printf ("%s/Identities/orgs", path); - orgs = gconf_client_get_list (client, str, GCONF_VALUE_STRING, &err); - g_free (str); - str = g_strdup_printf ("%s/Identities/sigs", path); - sigs = gconf_client_get_list (client, str, GCONF_VALUE_STRING, &err); - g_free (str); - - len = g_slist_length (names); - for (i=0; i<len; i++) { - MailConfigIdentity *id; - - id = g_new0 (MailConfigIdentity, 1); - id->name = g_strdup ((gchar *)g_slist_nth_data (names, i)); - id->address = g_strdup ((gchar *)g_slist_nth_data (addr, i)); - id->org = g_strdup ((gchar *)g_slist_nth_data (orgs, i)); - id->sig = g_strdup ((gchar *)g_slist_nth_data (sigs, i)); - - config->ids = g_slist_append (config->ids, id); - } - - /* Sources */ - str = g_strdup_printf ("%s/Sources/urls", path); - sources = gconf_client_get_list (client, str, - GCONF_VALUE_STRING, &err); - g_free (str); - len = g_slist_length (sources); - for (i=0; i<len; i++) { - MailConfigService *s; - - s = g_new0 (MailConfigService, 1); - s->url = g_strdup ((gchar *)g_slist_nth_data (sources, i)); - - config->sources = g_slist_append (config->sources, s); - } - - /* News */ - str = g_strdup_printf ("%s/News/urls", path); - news = gconf_client_get_list (client, str, - GCONF_VALUE_STRING, &err); - g_free (str); - len = g_slist_length (news); - for (i=0; i<len; i++) { - MailConfigService *n; - - n = g_new0 (MailConfigService, 1); - n->url = g_strdup ((gchar *)g_slist_nth_data (news, i)); - - config->news = g_slist_append (config->news, n); - } - - /* Transport */ - str = g_strdup_printf ("%s/transport", path); - config->transport = g_new0 (MailConfigService, 1); - config->transport->url = gconf_client_get_string (client, str, &err); - g_free (str); - - /* Format */ - str = g_strdup_printf ("%s/send_html", path); - config->send_html = gconf_client_get_bool (client, str, &err); - g_free (str); -} - -static void -write_config (const gchar *path) -{ - GConfError *err = NULL; - GSList *names = NULL, *addr = NULL, *orgs = NULL, *sigs = NULL; - GSList *sources = NULL, *news = NULL; - gchar *str; - gint len, i; - - init_config (path); - - /* Format */ - str = g_strdup_printf ("%s/configured", path); - gconf_client_set_bool (client, str, TRUE, &err); - g_free (str); - - /* Identities */ - len = g_slist_length (config->ids); - for (i=0; i<len; i++) { - MailConfigIdentity *id; - - id = (MailConfigIdentity *)g_slist_nth_data (config->ids, i); - - names = g_slist_append (names, g_strdup (id->name)); - addr = g_slist_append (addr, g_strdup (id->address)); - orgs = g_slist_append (orgs, g_strdup (id->org)); - sigs = g_slist_append (sigs, g_strdup (id->sig)); - } - - str = g_strdup_printf ("%s/Identities/names", path); - gconf_client_set_list (client, str, GCONF_VALUE_STRING, names, &err); - g_free (str); - str = g_strdup_printf ("%s/Identities/addresses", path); - gconf_client_set_list (client, str, GCONF_VALUE_STRING, addr, &err); - g_free (str); - str = g_strdup_printf ("%s/Identities/orgs", path); - gconf_client_set_list (client, str, GCONF_VALUE_STRING, orgs, &err); - g_free (str); - str = g_strdup_printf ("%s/Identities/sigs", path); - gconf_client_set_list (client, str, GCONF_VALUE_STRING, sigs, &err); - g_free (str); - - /* Sources */ - len = g_slist_length (config->sources); - for (i=0; i<len; i++) { - MailConfigService *s; - - s = (MailConfigService *)g_slist_nth_data (config->sources, i); - - sources = g_slist_append (sources, g_strdup (s->url)); - } - - str = g_strdup_printf ("%s/Sources/urls", path); - gconf_client_set_list (client, str, GCONF_VALUE_STRING, sources, &err); - g_free (str); - - /* News */ - len = g_slist_length (config->news); - for (i=0; i<len; i++) { - MailConfigService *n; - - n = (MailConfigService *)g_slist_nth_data (config->news, i); - - news = g_slist_append (news, g_strdup (n->url)); - } - - str = g_strdup_printf ("%s/News/urls", path); - gconf_client_set_list (client, str, GCONF_VALUE_STRING, news, &err); - g_free (str); - - /* Transport */ - str = g_strdup_printf ("%s/transport", path); - gconf_client_set_string (client, str, config->transport->url, &err); - g_free (str); - - /* Format */ - str = g_strdup_printf ("%s/send_html", path); - gconf_client_set_bool (client, str, config->send_html, &err); - g_free (str); - - gconf_client_suggest_sync (client, &err); -} - -/* 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 && name && page->cb) - page->cb (page, page->data); - - 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_done_cb (MailDialogIdentityPage *page, - IdentityPageCallback cb, gpointer data) -{ - page->cb = cb; - page->data = 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 (0, FALSE); - - 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); - 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); - } - } - - 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 (); - gtk_option_menu_set_menu (GTK_OPTION_MENU (spitem->auth_optionmenu), - menu); - 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_history (GTK_OPTION_MENU (spitem->auth_optionmenu), 0); - if (firstitem) - service_page_item_auth_activate (firstitem, spitem); -} - -static gboolean -service_acceptable (MailDialogServicePage *page) -{ - char *url=NULL; - CamelService *service; - CamelException *ex; - - url = service_page_get_url (page); - - ex = camel_exception_new (); - camel_exception_clear (ex); - service = camel_session_get_service (session, url, - page->spitem->type, ex); - g_free (url); - - if (camel_exception_get_id (ex) != CAMEL_EXCEPTION_NONE) - goto error; - - if (camel_service_connect (service, ex)) { - camel_service_disconnect (service, ex); - gtk_object_unref (GTK_OBJECT (service)); - camel_exception_free (ex); - - info_dialog (page->vbox, "Connection successful!"); - - return TRUE; - } - - gtk_object_unref (GTK_OBJECT (service)); - - error: - error_dialog (page->vbox, camel_exception_get_description (ex)); - camel_exception_free (ex); - - return FALSE; -} - -static MailConfigService * -service_page_extract (MailDialogServicePage *page) -{ - MailConfigService *source = g_new0 (MailConfigService, 1); - - source->url = service_page_get_url (page); - - 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); - } -} - -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 (5, 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, - 0, 0, 0); - - item->auth_detect = gtk_button_new_with_label (_("Detect supported types...")); - gtk_table_attach (GTK_TABLE (table), item->auth_detect, - 2, 3, row, row + 1, 0, 0, 0, 0); - gtk_widget_set_sensitive (item->auth_detect, FALSE); - gtk_signal_connect (GTK_OBJECT (item->auth_detect), - "clicked", - GTK_SIGNAL_FUNC (service_page_detect), - page); - - item->auth_html = html_new (TRUE); - gtk_table_attach (GTK_TABLE (table), - item->auth_html->parent->parent, - 0, 3, row + 1, row + 2, - GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); - - service_page_item_auth_fill (page, item, mcs->authtypes); - - row += 2; - } - - 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_SHRINK, GTK_SHRINK, 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_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, 0); - - 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_option_menu_set_menu (GTK_OPTION_MENU (page->optionmenu), menu); - 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); - } - - 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 ("Mail 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 source 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_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), - TRUE, 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); - identity_page_set_done_cb (iddialog->page, iddialog_page_done, - iddialog); - gtk_box_pack_start (GTK_BOX (dialog_vbox), - iddialog->page->vbox, TRUE, TRUE, 0); - gtk_widget_show (iddialog->page->vbox); - - /* Buttons */ - area = GNOME_DIALOG (iddialog->dialog)->action_area; - gtk_widget_show (area); - gtk_button_box_set_layout (GTK_BUTTON_BOX (area), GTK_BUTTONBOX_END); - gtk_button_box_set_spacing (GTK_BUTTON_BOX (area), 8); - - gnome_dialog_append_button (GNOME_DIALOG (iddialog->dialog), - GNOME_STOCK_BUTTON_OK); - gnome_dialog_append_button (GNOME_DIALOG (iddialog->dialog), - GNOME_STOCK_BUTTON_CANCEL); - - gnome_dialog_set_default (GNOME_DIALOG (iddialog->dialog), 0); - gnome_dialog_set_default (GNOME_DIALOG (iddialog->dialog), 1); - - gnome_dialog_set_sensitive (GNOME_DIALOG (iddialog->dialog), 0, FALSE); - - gnome_dialog_button_connect( GNOME_DIALOG (iddialog->dialog), 0, - GTK_SIGNAL_FUNC (iddialog_ok_clicked), - iddialog); - - gnome_dialog_run_and_close (GNOME_DIALOG (iddialog->dialog)); - - returnid = iddialog->id; - g_free (iddialog); - - return returnid; -} - -/* Source Dialog */ -static void -sdialog_page_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), - TRUE, 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); - service_page_set_url (sdialog->page->page, source); - service_page_set_done_cb (sdialog->page->page, - sdialog_page_done, sdialog); - gtk_box_pack_start (GTK_BOX (dialog_vbox), sdialog->page->vbox, - TRUE, TRUE, 0); - gtk_widget_show (sdialog->page->vbox); - - /* Buttons */ - area = GNOME_DIALOG (sdialog->dialog)->action_area; - gtk_widget_show (area); - gtk_button_box_set_layout (GTK_BUTTON_BOX (area), GTK_BUTTONBOX_END); - gtk_button_box_set_spacing (GTK_BUTTON_BOX (area), 8); - - gnome_dialog_append_button (GNOME_DIALOG (sdialog->dialog), - GNOME_STOCK_BUTTON_OK); - gnome_dialog_append_button (GNOME_DIALOG (sdialog->dialog), - GNOME_STOCK_BUTTON_CANCEL); - - gnome_dialog_set_default (GNOME_DIALOG (sdialog->dialog), 0); - gnome_dialog_set_default (GNOME_DIALOG (sdialog->dialog), 1); - - gnome_dialog_set_sensitive (GNOME_DIALOG (sdialog->dialog), 0, FALSE); - - gnome_dialog_button_connect(GNOME_DIALOG (sdialog->dialog), 0, - GTK_SIGNAL_FUNC (sdialog_ok_clicked), - sdialog); - - gnome_dialog_run_and_close (GNOME_DIALOG (sdialog->dialog)); - - returnsource = sdialog->source; - g_free (sdialog); - - return returnsource; -} - -/* News Dialog */ -static void -ndialog_page_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), - TRUE, 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); - service_page_set_done_cb (ndialog->page->page, - ndialog_page_done, ndialog); - gtk_box_pack_start (GTK_BOX (dialog_vbox), ndialog->page->vbox, - TRUE, TRUE, 0); - gtk_widget_show (ndialog->page->vbox); - - /* Buttons */ - area = GNOME_DIALOG (ndialog->dialog)->action_area; - gtk_widget_show (area); - gtk_button_box_set_layout (GTK_BUTTON_BOX (area), GTK_BUTTONBOX_END); - gtk_button_box_set_spacing (GTK_BUTTON_BOX (area), 8); - - gnome_dialog_append_button (GNOME_DIALOG (ndialog->dialog), - GNOME_STOCK_BUTTON_OK); - gnome_dialog_append_button (GNOME_DIALOG (ndialog->dialog), - GNOME_STOCK_BUTTON_CANCEL); - - gnome_dialog_set_default (GNOME_DIALOG (ndialog->dialog), 0); - gnome_dialog_set_default (GNOME_DIALOG (ndialog->dialog), 1); - - gnome_dialog_set_sensitive (GNOME_DIALOG (ndialog->dialog), 0, FALSE); - - gnome_dialog_button_connect(GNOME_DIALOG (ndialog->dialog), 0, - GTK_SIGNAL_FUNC (ndialog_ok_clicked), - ndialog); - - gnome_dialog_run_and_close (GNOME_DIALOG (ndialog->dialog)); - - returnsource = ndialog->source; - g_free (ndialog); - - return returnsource; -} - -/* Mail configuration druid */ - -/* static gboolean */ -/* mail_druid_identity_next (GnomeDruidPage *page, gpointer arg1, */ -/* MailDruidDialog *dialog) */ -/* { */ -/* char *addr, *at; */ - -/* FIXME: we need more sanity checking than this. */ - -/* addr = gtk_editable_get_chars (GTK_EDITABLE (dialog->idpage->address), */ -/* 0, -1); */ -/* at = strchr (addr, '@'); */ -/* if (!at || !strchr (at + 1, '.')) { */ -/* error_dialog (GTK_WIDGET (page), "Email address must be " */ -/* "of the form \"user@domain\"."); */ -/* return TRUE; */ -/* } */ -/* g_free (addr); */ - -/* dialog->id = identity_page_extract (dialog->idpage); */ - -/* return FALSE; */ -/* } */ - -static gboolean -mail_druid_prepare (GnomeDruidPage *page, GnomeDruid *druid, gpointer data) -{ - gnome_druid_set_buttons_sensitive (druid, TRUE, FALSE, TRUE); - - return FALSE; -} - -static void -mail_druid_identity_done (MailDialogIdentityPage *page, gpointer data) -{ - MailDruidDialog *dialog = (MailDruidDialog *) data; - - gnome_druid_set_buttons_sensitive (GNOME_DRUID (dialog->druid), - TRUE, TRUE, TRUE); -} - -static void -mail_druid_service_done (MailDialogServicePage *page, gpointer data) -{ - MailDruidDialog *dialog = (MailDruidDialog *) data; - - 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; - - clear_config (); - - /* Identity */ - id = identity_page_extract (dialog->idpage); - config->ids = g_slist_append (config->ids, id); - - /* Source */ - source = service_page_extract (dialog->spage->page); - config->sources = g_slist_append (config->sources, source); - - /* Transport */ - config->transport = service_page_extract (dialog->tpage->page); - - write_config (GCONFPATH); - - 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; - - read_config (GCONFPATH); - 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); - identity_page_set_done_cb (dialog->idpage, - mail_druid_identity_done, - dialog); - gtk_box_pack_start (GTK_BOX (dpage->vbox), - dialog->idpage->vbox, - TRUE, TRUE, 0); - - gtk_signal_connect (GTK_OBJECT (dpage), "prepare", - GTK_SIGNAL_FUNC (mail_druid_prepare), dialog); - 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); - service_page_set_done_cb (dialog->spage->page, - mail_druid_service_done, dialog); - gtk_box_pack_start (GTK_BOX (dpage->vbox), - dialog->spage->vbox, - TRUE, TRUE, 0); - - gtk_signal_connect (GTK_OBJECT (dpage), "prepare", - GTK_SIGNAL_FUNC (mail_druid_prepare), dialog); - 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); - service_page_set_done_cb (dialog->tpage->page, - mail_druid_service_done, dialog); - gtk_box_pack_start (GTK_BOX (dpage->vbox), - dialog->tpage->vbox, - TRUE, TRUE, 0); - - gtk_signal_connect (GTK_OBJECT (dpage), "prepare", - GTK_SIGNAL_FUNC (mail_druid_prepare), - dialog); - 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); - - gtk_main (); -} - -/* 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->clistNewsServers); - 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->maxsrow++; - - gnome_property_box_changed (GNOME_PROPERTY_BOX (dialog->dialog)); - } -} - -static void -news_edit_clicked (GtkWidget *widget, MailDialog *dialog) -{ - MailConfigService *news, *news2; - - if (dialog->srow < 0) - return; - - news = gtk_clist_get_row_data (GTK_CLIST (dialog->clistNewsServers), - dialog->srow); - - news2 = source_dialog (news, dialog->dialog); - if (news2) { - GtkCList *clist = GTK_CLIST (dialog->clistNewsServers); - - 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->clistNewsServers); - - 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 -mail_config_apply_clicked (GnomePropertyBox *property_box, gint page_num, - MailDialog *dialog) -{ - gpointer data; - int i; - - if (page_num != -1) - return; - - clear_config (); - - /* Identities */ - for (i = 0; i <= dialog->maxidrow; i++) { - data = gtk_clist_get_row_data (GTK_CLIST (dialog->clistIdentities), i); - config->ids = g_slist_append (config->ids, data); - } - - /* Sources */ - for (i = 0; i <= dialog->maxsrow; i++) { - data = gtk_clist_get_row_data (GTK_CLIST (dialog->clistSources), i); - config->sources = g_slist_append (config->sources, data); - } - - /* Transport */ - config->transport = service_page_extract (dialog->page->page); - - /* Format */ - config->send_html = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->chkFormat)); - - write_config (GCONFPATH); -} - -void -mail_config (void) -{ - MailDialog *dialog; - GladeXML *gui; - GtkCList *clist; - GtkWidget *button, *tvbox; - GSList *sources, *news, *transports; - gint len, row; - - read_config (GCONFPATH); - 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); - - len = g_slist_length (config->ids); - for (row=0; row<len; row++) { - MailConfigIdentity *id; - gchar *text[4]; - - id = identity_copy ((MailConfigIdentity *) - g_slist_nth_data (config->ids, row)); - - text[0] = id->name; - text[1] = id->address; - text[2] = id->org; - text[3] = id->sig; - - gtk_clist_append (clist, text); - gtk_clist_set_row_data (clist, row, id); - } - - dialog->maxidrow = len - 1; - dialog->idrow = -1; - 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); - - len = g_slist_length (config->sources); - for (row=0; row<len; row++) { - MailConfigService *source; - gchar *text[1]; - - source = service_copy ((MailConfigService *)g_slist_nth_data (config->sources, row)); - - text[0] = source->url; - - gtk_clist_append (clist, text); - gtk_clist_set_row_data (clist, row, source); - } - - dialog->maxsrow = len - 1; - dialog->srow = -1; - 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->clistNewsServers = glade_xml_get_widget (gui, "clistNewsServers"); - clist = GTK_CLIST (dialog->clistNewsServers); - gtk_clist_set_column_width (clist, 0, 80); - - len = g_slist_length (config->news); - for (row=0; row<len; row++) { - MailConfigService *news; - gchar *text[1]; - - news = service_copy ((MailConfigService *) - g_slist_nth_data (config->news, row)); - - text[0] = news->url; - - gtk_clist_append (clist, text); - gtk_clist_set_row_data (clist, row, news); - } - - dialog->maxnrow = len - 1; - dialog->nrow = -1; - 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); - service_page_set_url (dialog->page->page, config->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), - config->send_html); - gtk_signal_connect (GTK_OBJECT (dialog->chkFormat), "toggled", - GTK_SIGNAL_FUNC (format_toggled), - dialog); - - /* Listen for apply signal */ - gtk_signal_connect (GTK_OBJECT (dialog->dialog), "apply", - GTK_SIGNAL_FUNC (mail_config_apply_clicked), - dialog); - - gnome_dialog_run (GNOME_DIALOG (dialog->dialog)); - - /* Clean up */ - gtk_object_unref (GTK_OBJECT (gui)); - g_free (dialog); -} - -const MailConfig * -mail_config_fetch (void) -{ - read_config (GCONFPATH); - - return config; -} diff --git a/mail/mail-config.glade b/mail/mail-config.glade deleted file mode 100644 index fdaf8e775a..0000000000 --- a/mail/mail-config.glade +++ /dev/null @@ -1,444 +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>340</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>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>clistNewsServers</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> - - <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 d79e7a79a3..0000000000 --- a/mail/mail-config.glade.h +++ /dev/null @@ -1,27 +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_("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_("Other"); diff --git a/mail/mail-config.h b/mail/mail-config.h deleted file mode 100644 index 6bd5532110..0000000000 --- a/mail/mail-config.h +++ /dev/null @@ -1,54 +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; -} MailConfigService; - -typedef struct -{ - gboolean configured; - GSList *ids; - GSList *sources; - GSList *news; - MailConfigService *transport; - gboolean send_html; -} MailConfig; - -void mail_config (void); -void mail_config_druid (void); - -const MailConfig *mail_config_fetch (void); - -#endif diff --git a/mail/mail-crypto.c b/mail/mail-crypto.c deleted file mode 100644 index 4db4357b44..0000000000 --- a/mail/mail-crypto.c +++ /dev/null @@ -1,405 +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> - * - * 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; - long tmp; - - 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, const char *passphrase, - CamelException *ex) -{ - int retval; - char *path, *argv[12]; - int i; - char *plaintext = NULL; - char *diagnostics = NULL; - int passwd_fds[2]; - char passwd_fd[32]; - -#ifndef PGP_PROGRAM - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - "No GPG/PGP program available."); - return NULL; -#endif - - 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; -} - -#endif /* PGP_PROGRAM */ diff --git a/mail/mail-display.c b/mail/mail-display.c deleted file mode 100644 index 3af2ec1b15..0000000000 --- a/mail/mail-display.c +++ /dev/null @@ -1,524 +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-setup.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; - - -/*----------------------------------------------------------------------* - * 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); - gtk_main (); - 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); - gtk_object_unref (GTK_OBJECT (stream_fs)); - return FALSE; - } - gtk_object_unref (GTK_OBJECT (stream_fs)); - - return TRUE; -} - -static char * -make_safe_filename (const char *prefix, CamelMimePart *part) -{ - GMimeContentField *type; - const char *name; - 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; -} - -CamelMimePart * -part_for_url (const char *url, CamelMimeMessage *message) -{ - GHashTable *urls; - - urls = gtk_object_get_data (GTK_OBJECT (message), "urls"); - g_return_val_if_fail (urls != NULL, NULL); - return g_hash_table_lookup (urls, url); -} - -static void -launch_external (const char *url, CamelMimeMessage *message) -{ - const char *command = url + 21; - char *tmpl, *tmpdir, *filename, *argv[2]; - CamelMimePart *part = part_for_url (url, message); - - 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, CamelMimeMessage *message) -{ - GtkFileSelection *file_select; - char *filename; - CamelMimePart *part; - - part = part_for_url (cid, message); - 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 void -on_link_clicked (GtkHTML *html, const char *url, gpointer user_data) -{ - CamelMimeMessage *message; - - message = gtk_object_get_data (GTK_OBJECT (html), "message"); - - if (!strncasecmp (url, "news:", 5) || - !strncasecmp (url, "nntp:", 5)) - g_warning ("Can't handle news URLs yet."); - else if (!strncasecmp (url, "mailto:", 7)) - send_to_url (url); - else if (!strncasecmp (url, "cid:", 4)) - save_data (url, message); - else if (!strncasecmp (url, "x-evolution-external:", 21)) - launch_external (url, message); - else - gnome_url_show (url); -} - -static gboolean -on_object_requested (GtkHTML *html, GtkHTMLEmbedded *eb, gpointer data) -{ - CamelMimeMessage *message; - 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; - message = gtk_object_get_data (GTK_OBJECT (html), "message"); - urls = gtk_object_get_data (GTK_OBJECT (message), "urls"); - 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); - 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); - gtk_object_unref (GTK_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) -{ - CamelMimeMessage *message; - GHashTable *urls; - - message = gtk_object_get_data (GTK_OBJECT (html), "message"); - urls = gtk_object_get_data (GTK_OBJECT (message), "urls"); - - 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); - gtk_object_unref (GTK_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); -} - - -/** - * 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. This means feeding mail_display->body_stream and - * mail_display->headers_stream with html. - * - **/ -void -mail_display_set_message (MailDisplay *mail_display, - CamelMedium *medium) -{ - GtkHTMLStream *stream; - GtkAdjustment *adj; - - /* - * 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 (mail_display->current_message) - gtk_object_unref (GTK_OBJECT (mail_display->current_message)); - - mail_display->current_message = (CamelMimeMessage*)medium; - - stream = gtk_html_begin (mail_display->html); - mail_html_write (mail_display->html, stream, "%s%s", HTML_HEADER, - "<BODY TEXT=\"#000000\" BGCOLOR=\"#FFFFFF\">\n"); - - if (medium) { - gtk_object_ref (GTK_OBJECT (medium)); - gtk_object_set_data (GTK_OBJECT (mail_display->html), - "message", medium); - mail_format_mime_message (CAMEL_MIME_MESSAGE (medium), - mail_display->html, stream, - CAMEL_MIME_MESSAGE (medium)); - } - - mail_html_write (mail_display->html, stream, "</BODY></HTML>\n"); - gtk_html_end (mail_display->html, stream, GTK_HTML_STREAM_OK); - - adj = e_scroll_frame_get_vadjustment (mail_display->scroll); - gtk_adjustment_set_value (adj, 0); - e_scroll_frame_set_vadjustment (mail_display->scroll, adj); - - adj = e_scroll_frame_get_hadjustment (mail_display->scroll); - gtk_adjustment_set_value (adj, 0); - e_scroll_frame_set_hadjustment (mail_display->scroll, adj); -} - - -/*----------------------------------------------------------------------* - * 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); */ - - 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 (FolderBrowser *parent_folder_browser) -{ - MailDisplay *mail_display = gtk_type_new (mail_display_get_type ()); - GtkWidget *scroll, *html; - - g_assert (parent_folder_browser); - - mail_display->parent_folder_browser = parent_folder_browser; - - 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), NULL); - gtk_signal_connect (GTK_OBJECT (html), "object_requested", - GTK_SIGNAL_FUNC (on_object_requested), NULL); - gtk_signal_connect (GTK_OBJECT (html), "link_clicked", - GTK_SIGNAL_FUNC (on_link_clicked), NULL); - 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); - - 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 d839978371..0000000000 --- a/mail/mail-display.h +++ /dev/null @@ -1,55 +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; - - FolderBrowser *parent_folder_browser; - CamelMimeMessage *current_message; -}; - -typedef struct { - GtkVBoxClass parent_class; -} MailDisplayClass; - -GtkType mail_display_get_type (void); -GtkWidget * mail_display_new (FolderBrowser *parent_folder_browser); - -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 df09cace9c..0000000000 --- a/mail/mail-format.c +++ /dev/null @@ -1,1786 +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-display.h" -#include "mail.h" -#include "e-util/e-html-utils.h" -#include "e-util/e-setup.h" /*for evolution_dir*/ -#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> - -struct mail_format_data { - CamelMimeMessage *root; - GHashTable *urls; - GtkHTML *html; - GtkHTMLStream *stream; -}; - -static char *try_inline_pgp (char *start, struct mail_format_data *mfd); -static char *try_uudecoding (char *start, struct mail_format_data *mfd); -static char *try_inline_binhex (char *start, struct mail_format_data *mfd); - -static gboolean handle_text_plain (CamelMimePart *part, - const char *mime_type, - struct mail_format_data *mfd); -static gboolean handle_text_plain_flowed (char *text, - struct mail_format_data *mfd); -static gboolean handle_text_enriched (CamelMimePart *part, - const char *mime_type, - struct mail_format_data *mfd); -static gboolean handle_text_html (CamelMimePart *part, - const char *mime_type, - struct mail_format_data *mfd); -static gboolean handle_image (CamelMimePart *part, - const char *mime_type, - struct mail_format_data *mfd); -static gboolean handle_multipart_mixed (CamelMimePart *part, - const char *mime_type, - struct mail_format_data *mfd); -static gboolean handle_multipart_related (CamelMimePart *part, - const char *mime_type, - struct mail_format_data *mfd); -static gboolean handle_multipart_alternative (CamelMimePart *part, - const char *mime_type, - struct mail_format_data *mfd); -static gboolean handle_multipart_appledouble (CamelMimePart *part, - const char *mime_type, - struct mail_format_data *mfd); -static gboolean handle_multipart_encrypted (CamelMimePart *part, - const char *mime_type, - struct mail_format_data *mfd); -static gboolean handle_audio (CamelMimePart *part, - const char *mime_type, - struct mail_format_data *mfd); -static gboolean handle_message_rfc822 (CamelMimePart *part, - const char *mime_type, - struct mail_format_data *mfd); -static gboolean handle_message_external_body (CamelMimePart *part, - const char *mime_type, - struct mail_format_data *mfd); - -static gboolean handle_unknown_type (CamelMimePart *part, - const char *mime_type, - struct mail_format_data *mfd); -static gboolean handle_via_bonobo (CamelMimePart *part, - const char *mime_type, - struct mail_format_data *mfd); -static gboolean handle_via_external (CamelMimePart *part, - const char *mime_type, - struct mail_format_data *mfd); - -/* writes the header info for a mime message into an html stream */ -static void write_headers (CamelMimeMessage *message, - struct mail_format_data *mfd); - -/* dispatch html printing via mimetype */ -static gboolean call_handler_function (CamelMimePart *part, - struct mail_format_data *mfd); - -static void free_urls (gpointer data); - - -/** - * mail_format_mime_message: - * @mime_message: the input mime message - * @html: a GtkHTML - * @stream: a stream on @html - * @root: the root message being displayed (may be the same as @mime_message) - * - * Writes a CamelMimeMessage out into a GtkHTML - **/ -void -mail_format_mime_message (CamelMimeMessage *mime_message, - GtkHTML *html, GtkHTMLStream *stream, - CamelMimeMessage *root) -{ - struct mail_format_data mfd; - - g_return_if_fail (CAMEL_IS_MIME_MESSAGE (mime_message)); - - mfd.html = html; - mfd.stream = stream; - mfd.root = root; - mfd.urls = gtk_object_get_data (GTK_OBJECT (root), "urls"); - if (!mfd.urls) { - mfd.urls = g_hash_table_new (g_str_hash, g_str_equal); - gtk_object_set_data_full (GTK_OBJECT (root), "urls", - mfd.urls, free_urls); - } - - write_headers (mime_message, &mfd); - call_handler_function (CAMEL_MIME_PART (mime_message), &mfd); -} - -static void -free_url (gpointer key, gpointer value, gpointer data) -{ - g_free (key); -} - -static void -free_urls (gpointer data) -{ - GHashTable *urls = data; - - g_hash_table_foreach (urls, free_url, NULL); - g_hash_table_destroy (urls); -} - -static const char * -get_cid (CamelMimePart *part, struct mail_format_data *mfd) -{ - char *cid; - gpointer orig_name, value; - - /* 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 (mfd->urls, cid, &orig_name, &value)) { - g_free (cid); - return orig_name; - } else - g_hash_table_insert (mfd->urls, cid, part); - - return cid; -} - -static const char * -get_url_for_icon (const char *icon_name, struct mail_format_data *mfd) -{ - 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); - - g_hash_table_insert (icons, icon_path, ba); - } - g_free (icon_path); - - url = g_strdup_printf ("x-evolution-data:%p", ba); - g_hash_table_insert (mfd->urls, url, ba); - - return url; -} - - - -/* 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, - struct mail_format_data *mfd); - -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; - } - -/* FIXME: Remove this #ifdef after gnome-vfs 0.3 is released */ -#ifdef HAVE_GNOME_VFS_MIME_GET_DEFAULT_ACTION_WITHOUT_FALLBACK - 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; - } -#endif - - 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, struct mail_format_data *mfd) -{ - 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, mfd); - else - output = handle_unknown_type (part, mime_type, mfd); - - 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_recipients_to_stream (const gchar *recipient_type, - const CamelInternetAddress *recipients, - gboolean optional, gboolean bold, - GtkHTML *html, GtkHTMLStream *stream) -{ - int i; - char *recipients_string = NULL; - const char *name, *addr; - - i = 0; - while (camel_internet_address_get (recipients, i++, &name, &addr)) { - char *old_string = recipients_string; - - if (*name) { - recipients_string = g_strdup_printf ( - "%s%s\"%s\" <%s>", - old_string ? old_string : "", - old_string ? ", " : "", - name, addr); - } else { - recipients_string = g_strdup_printf ( - "%s%s%s", old_string ? old_string : "", - old_string ? ", " : "", addr); - } - g_free (old_string); - } - - if (recipients_string || !optional) { - write_field_to_stream (recipient_type, recipients_string, - bold, html, stream); - } - g_free (recipients_string); -} - - - -static void -write_headers (CamelMimeMessage *message, struct mail_format_data *mfd) -{ - const CamelInternetAddress *recipients; - - mail_html_write (mfd->html, mfd->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, mfd->html, mfd->stream); - - if (camel_mime_message_get_reply_to (message)) { - write_field_to_stream ("Reply-To:", - camel_mime_message_get_reply_to (message), - FALSE, mfd->html, mfd->stream); - } - - write_recipients_to_stream ("To:", - camel_mime_message_get_recipients (message, CAMEL_RECIPIENT_TYPE_TO), - FALSE, TRUE, mfd->html, mfd->stream); - - recipients = camel_mime_message_get_recipients (message, CAMEL_RECIPIENT_TYPE_CC); - write_recipients_to_stream ("Cc:", recipients, TRUE, TRUE, - mfd->html, mfd->stream); - write_field_to_stream ("Subject:", - camel_mime_message_get_subject (message), - TRUE, mfd->html, mfd->stream); - - mail_html_write (mfd->html, mfd->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; - - gtk_object_unref (GTK_OBJECT (memstream)); - return text; -} - -/*----------------------------------------------------------------------* - * Mime handling functions - *----------------------------------------------------------------------*/ - -struct { - char *start; - char * (*handler) (char *start, struct mail_format_data *mfd); -} 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, - struct mail_format_data *mfd) -{ - 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, mfd); - - mail_html_write (mfd->html, mfd->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 (mfd->html, mfd->stream, - "%s", subtext); - g_free (subtext); - } - p = text_specials[i].handler (start, mfd); - 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 (mfd->html, mfd->stream, - "%s", subtext); - g_free (subtext); - } else if (p) - mail_html_write (mfd->html, mfd->stream, "<hr>"); - } - /* Finish up (or do the whole thing if there were no specials). */ - if (p) - mail_text_write (mfd->html, mfd->stream, "%s", p); - - g_free (text); - return TRUE; -} - -static gboolean -handle_text_plain_flowed (char *buf, struct mail_format_data *mfd) -{ - char *text, *line, *eol, *p; - int prevquoting = 0, quoting, len; - gboolean br_pending = FALSE; - - mail_html_write (mfd->html, mfd->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 (mfd->html, mfd->stream, "%s\n", - prevquoting == 0 ? "<i>\n" : ""); - while (quoting > prevquoting) { - mail_html_write (mfd->html, mfd->stream, - "<blockquote>"); - prevquoting++; - } - while (quoting < prevquoting) { - mail_html_write (mfd->html, mfd->stream, - "</blockquote>"); - prevquoting--; - } - mail_html_write (mfd->html, mfd->stream, "%s\n", - prevquoting == 0 ? "</i>\n" : ""); - } else if (br_pending) { - mail_html_write (mfd->html, mfd->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 (mfd->html, mfd->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 (mfd->html, mfd->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); - gtk_object_unref (GTK_OBJECT (memstream)); - part = camel_mime_part_new (); - camel_medium_set_content_object (CAMEL_MEDIUM (part), wrapper); - gtk_object_unref (GTK_OBJECT (wrapper)); - return part; -} - -static void -destroy_part (GtkObject *root, GtkObject *part) -{ - gtk_object_unref (part); -} - -static char * -try_inline_pgp (char *start, struct mail_format_data *mfd) -{ - char *end; - CamelMimePart *part; - CamelMultipart *mp; - - /* FIXME: This should deal with converting to multipart/signed - * as well. - */ - - end = strstr (start, "-----END PGP MESSAGE-----"); - if (!end) - return start; - - end += sizeof ("-----END PGP MESSAGE-----") - 1; - - /* Build a multipart/encrypted. */ - mp = camel_multipart_new (); - camel_data_wrapper_set_mime_type (CAMEL_DATA_WRAPPER (mp), - "multipart/encrypted"); - - part = fake_mime_part_from_data ("Version: 1\n", 11, - "application/pgp-encrypted"); - camel_multipart_add_part (mp, part); - gtk_object_unref (GTK_OBJECT (part)); - - part = fake_mime_part_from_data (start, end - start, - "application/octet-stream"); - camel_multipart_add_part (mp, part); - gtk_object_unref (GTK_OBJECT (part)); - - part = camel_mime_part_new (); - camel_medium_set_content_object (CAMEL_MEDIUM (part), - CAMEL_DATA_WRAPPER (mp)); - gtk_object_unref (GTK_OBJECT (mp)); - - gtk_signal_connect (GTK_OBJECT (mfd->root), "destroy", - destroy_part, part); - mail_html_write (mfd->html, mfd->stream, "<hr>"); - call_handler_function (part, mfd); - - return end; -} - -static char * -try_uudecoding (char *start, struct mail_format_data *mfd) -{ - 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); - gtk_signal_connect (GTK_OBJECT (mfd->root), "destroy", - destroy_part, part); - - mail_html_write (mfd->html, mfd->stream, "<hr>"); - call_handler_function (part, mfd); - - return p + 4; -} - -static char * -try_inline_binhex (char *start, struct mail_format_data *mfd) -{ - 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"); - gtk_signal_connect (GTK_OBJECT (mfd->root), "destroy", - destroy_part, part); - - mail_html_write (mfd->html, mfd->stream, "<hr>"); - call_handler_function (part, mfd); - - return p; -} - -static void -free_byte_array (GtkWidget *widget, gpointer user_data) -{ - 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, - struct mail_format_data *mfd) -{ - 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 (mfd->html, mfd->stream, - "\n<!-- text/richtext -->\n"); - } else { - enriched = TRUE; - mail_html_write (mfd->html, mfd->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); - g_hash_table_insert (mfd->urls, xed, ba); - gtk_signal_connect (GTK_OBJECT (mfd->root), "destroy", - GTK_SIGNAL_FUNC (free_byte_array), ba); - mail_html_write (mfd->html, mfd->stream, - "<iframe src=\"%s\" frameborder=0 scrolling=no>" - "</iframe>", xed); - - return TRUE; -} - -static gboolean -handle_text_html (CamelMimePart *part, const char *mime_type, - struct mail_format_data *mfd) -{ - mail_html_write (mfd->html, mfd->stream, "\n<!-- text/html -->\n"); - mail_html_write (mfd->html, mfd->stream, - "<iframe src=\"%s\" frameborder=0 scrolling=no>" - "</iframe>", get_cid (part, mfd)); - return TRUE; -} - -static gboolean -handle_image (CamelMimePart *part, const char *mime_type, - struct mail_format_data *mfd) -{ - mail_html_write (mfd->html, mfd->stream, "<img src=\"%s\">", - get_cid (part, mfd)); - return TRUE; -} - -static gboolean -handle_multipart_mixed (CamelMimePart *part, const char *mime_type, - struct mail_format_data *mfd) -{ - 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 (mfd->html, mfd->stream, "<hr>\n"); - - part = camel_multipart_get_part (mp, i); - - output = call_handler_function (part, mfd); - } - - 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, - struct mail_format_data *mfd) -{ - CamelDataWrapper *wrapper = - camel_medium_get_content_object (CAMEL_MEDIUM (part)); - CamelMultipart *mp; - char *ciphertext, *passphrase, *plaintext; - CamelException ex; - - 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, mfd); - - 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; - - camel_exception_init (&ex); - -#ifdef PGP_PROGRAM - /* Get the passphrase. */ - passphrase = mail_request_dialog ( - "Please enter your PGP/GPG passphrase.", TRUE, "pgp"); - if (passphrase) { - plaintext = mail_crypto_openpgp_decrypt (ciphertext, - passphrase, &ex); - g_free (passphrase); - } else { - camel_exception_set (&ex, CAMEL_EXCEPTION_SYSTEM, - "No password provided."); - } -#else - camel_exception_set (&ex, CAMEL_EXCEPTION_SYSTEM, - "No GPG/PGP support available in this copy " - "of Evolution."); -#endif - g_free (ciphertext); - - if (camel_exception_is_set (&ex)) { - mail_html_write (mfd->html, mfd->stream, - "<table><tr valign=top><td>" - "<table border=2><tr><td>" - "<img src=\"%s\"></td></tr></table><td>", - get_url_for_icon ("gnome-lockscreen.png", - mfd)); - mail_error_write (mfd->html, mfd->stream, - "(Encrypted message not displayed)\n\n%s", - camel_exception_get_description (&ex)); - mail_html_write (mfd->html, mfd->stream, "</td></tr></table>"); - - camel_exception_clear (&ex); - } else { - mail_text_write (mfd->html, mfd->stream, "%s", plaintext); - g_free (plaintext); - } - - return TRUE; -} - -/* As seen in RFC 2387! */ -static gboolean -handle_multipart_related (CamelMimePart *part, const char *mime_type, - struct mail_format_data *mfd) -{ - 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, mfd); - } - } 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, mfd); - } - - /* Now, display the displayed part. */ - return call_handler_function (display_part, mfd); -} - -/* 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, - struct mail_format_data *mfd) -{ - 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, mfd); - else - return handle_unknown_type (part, mime_type, mfd); -} - -/* RFC 1740 */ -static gboolean -handle_multipart_appledouble (CamelMimePart *part, const char *mime_type, - struct mail_format_data *mfd) -{ - 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, mfd); -} - -static void -handle_mystery (CamelMimePart *part, struct mail_format_data *mfd, - const char *url, const char *icon_name, const char *id, - const char *action) -{ - const char *info; - char *htmlinfo; - GMimeContentField *content_type; - - mail_html_write (mfd->html, mfd->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 (mfd->html, mfd->stream, - "<a href=\"%s\">", url); - } else { - mail_html_write (mfd->html, mfd->stream, - "<table border=2><tr><td>"); - } - mail_html_write (mfd->html, mfd->stream, "<img src=\"%s\">", - get_url_for_icon (icon_name, mfd)); - - if (url) - mail_html_write (mfd->html, mfd->stream, "</a>"); - else - mail_html_write (mfd->html, mfd->stream, "</td></tr></table>"); - mail_html_write (mfd->html, mfd->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 (mfd->html, mfd->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 (mfd->html, mfd->stream, "Name: %s<br>", - htmlinfo); - g_free (htmlinfo); - } - - /* Describe the click action, if any. */ - if (action) { - mail_html_write (mfd->html, mfd->stream, - "<br>Click on the icon to %s.", action); - } - - mail_html_write (mfd->html, mfd->stream, "</td></tr></table>"); -} - -static gboolean -handle_audio (CamelMimePart *part, const char *mime_type, - struct mail_format_data *mfd) -{ - 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, mfd, get_cid (part, mfd), "gnome-audio2.png", - id, "play it"); - g_free (id); - - return TRUE; -} - -static gboolean -handle_message_rfc822 (CamelMimePart *part, const char *mime_type, - struct mail_format_data *mfd) -{ - CamelDataWrapper *wrapper = - camel_medium_get_content_object (CAMEL_MEDIUM (part)); - - g_return_val_if_fail (CAMEL_IS_MIME_MESSAGE (wrapper), FALSE); - - mail_html_write (mfd->html, mfd->stream, "<blockquote>"); - mail_format_mime_message (CAMEL_MIME_MESSAGE (wrapper), - mfd->html, mfd->stream, mfd->root); - mail_html_write (mfd->html, mfd->stream, "</blockquote>"); - - return TRUE; -} - -static gboolean -handle_message_external_body (CamelMimePart *part, const char *mime_type, - struct mail_format_data *mfd) -{ - 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, mfd, 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, - struct mail_format_data *mfd) -{ - 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, mfd, get_cid (part, mfd), "gnome-question.png", - id, "save it to disk"); - g_free (id); - - return TRUE; -} - -static gboolean -handle_unknown_type (CamelMimePart *part, const char *mime_type, - struct mail_format_data *mfd) -{ - 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, mfd); - g_free (type); - return output; - } - } else - type = g_strdup (mime_type); - - /* OK. Give up. */ - handle_undisplayable (part, type, mfd); - g_free (type); - - return TRUE; -} - -static gboolean -handle_via_bonobo (CamelMimePart *part, const char *mime_type, - struct mail_format_data *mfd) -{ - mail_html_write (mfd->html, mfd->stream, - "<object classid=\"%s\" type=\"%s\">", - get_cid (part, mfd), 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, mfd); - - mail_html_write (mfd->html, mfd->stream, "</object>"); - - return TRUE; -} - -static gboolean -handle_via_external (CamelMimePart *part, const char *mime_type, - struct mail_format_data *mfd) -{ - 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); - g_hash_table_insert (mfd->urls, url, part); - - handle_mystery (part, mfd, url, icon, desc, action); - - g_free (action); - - return TRUE; -} - - -static char * -reply_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 reply_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 = reply_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) -{ - const MailConfig *config; - CamelDataWrapper *contents; - char *text, *subject; - EMsgComposer *composer; - gboolean want_plain, is_html; - const char *repl_to, *message_id, *references; - GList *to, *cc; - - config = mail_config_fetch (); - want_plain = !config->send_html; - - contents = camel_medium_get_content_object (CAMEL_MEDIUM (message)); - text = reply_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)) { - fulladdr = g_strdup_printf ("%s <%s>", name, 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)) { - fulladdr = g_strdup_printf ("%s <%s>", name, 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 { - while (*subject == ' ') - subject++; - - if (!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 ba8a943f38..0000000000 --- a/mail/mail-identify.c +++ /dev/null @@ -1,127 +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" - -/* gnome-vfs 0.2 has a bug that makes memory-based sniff buffers cause - * segfaults sometimes. It's fixed in CVS, but we'll work around it for - * now until gnome-vfs 0.3 comes out. - */ -#define GNOME_VFS_0_2_WORKAROUND - -#ifdef GNOME_VFS_0_2_WORKAROUND -#include <libgnomevfs/gnome-vfs-mime-sniff-buffer-private.h> - -static GnomeVFSResult sniffer_seek (gpointer context, - GnomeVFSSeekPosition whence, - GnomeVFSFileOffset offset); -#endif - -/** - * 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); -#ifdef GNOME_VFS_0_2_WORKAROUND - sniffer->seek = sniffer_seek; -#endif - type = gnome_vfs_get_mime_type_for_buffer (sniffer); - gnome_vfs_mime_sniff_buffer_free (sniffer); - } else - type = NULL; - gtk_object_unref (GTK_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; -} - -#ifdef GNOME_VFS_0_2_WORKAROUND -static GnomeVFSResult -sniffer_seek (gpointer context, GnomeVFSSeekPosition whence, - GnomeVFSFileOffset offset) -{ - return GNOME_VFS_ERROR_EOF; -} -#endif diff --git a/mail/mail-ops.c b/mail/mail-ops.c deleted file mode 100644 index 76030e996a..0000000000 --- a/mail/mail-ops.c +++ /dev/null @@ -1,977 +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> - * - * 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-threads.h" -#include "folder-browser.h" -#include "e-util/e-setup.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; - const char *uid; - guint32 flags; -}; - -typedef struct rfm_s { - FolderBrowser *fb; - char *source_url; -} rfm_t; - -typedef struct rsm_s { - EMsgComposer *composer; - CamelTransport *transport; - CamelMimeMessage *message; - const char *subject; - char *from; - struct post_send_data *psd; - gboolean ok; -} rsm_t; - -static void -real_fetch_mail( gpointer user_data ); - -static void -real_send_mail( gpointer user_data ); - -static void -cleanup_send_mail( gpointer userdata ); - -static void -mail_exception_dialog (char *head, CamelException *ex, gpointer widget) -{ - char *msg; - GtkWindow *window = - GTK_WINDOW (gtk_widget_get_ancestor (widget, GTK_TYPE_WINDOW)); - - msg = g_strdup_printf ("%s:\n%s", head, - camel_exception_get_description (ex)); - gnome_error_dialog_parented (msg, window); - g_free (msg); -} - -#ifdef USE_BROKEN_THREADS -static void -async_mail_exception_dialog (char *head, CamelException *ex, gpointer unused ) -{ - mail_op_error( "%s: %s", head, camel_exception_get_description( ex ) ); -} -#else -#define async_mail_exception_dialog mail_exception_dialog -#endif - -static gboolean -check_configured (void) -{ - const MailConfig *config; - - config = mail_config_fetch (); - if (config->configured) - return TRUE; - - mail_config_druid (); - - config = mail_config_fetch (); - - return config->configured; -} - -static void -select_first_unread (CamelFolder *folder, int type, gpointer data) -{ - FolderBrowser *fb = data; - - message_list_select (fb->message_list, 0, MESSAGE_LIST_SELECT_NEXT, - 0, CAMEL_MESSAGE_SEEN); -} - -static CamelFolder * -filter_get_folder(FilterDriver *fd, const char *uri, void *data) -{ - return mail_uri_to_folder(uri); -} - -void -real_fetch_mail (gpointer user_data) -{ - rfm_t *info; - FolderBrowser *fb = NULL; - CamelException *ex; - CamelStore *store = NULL, *dest_store = NULL; - CamelFolder *folder = NULL, *dest_folder = NULL; - char *url = NULL, *dest_url; - FilterContext *fc = NULL; - FilterDriver *driver = NULL; - char *userrules, *systemrules; - char *tmp_mbox = NULL, *source; - guint handler_id = 0; - struct stat st; - - info = (rfm_t *) user_data; - fb = info->fb; - url = info->source_url; - - /* If using IMAP, don't do anything... */ - if (!strncmp (url, "imap:", 5)) - return; - - ex = camel_exception_new (); - - dest_url = g_strdup_printf ("mbox://%s/local/Inbox", evolution_dir); - dest_store = camel_session_get_store (session, dest_url, ex); - g_free (dest_url); - if (!dest_store) { - async_mail_exception_dialog ("Unable to get new mail", ex, fb); - goto cleanup; - } - - dest_folder = camel_store_get_folder (dest_store, "mbox", FALSE, ex); - if (!dest_folder) { - async_mail_exception_dialog ("Unable to get new mail", ex, fb); - goto cleanup; - } - - tmp_mbox = g_strdup_printf ("%s/local/Inbox/movemail", evolution_dir); - - /* If fetching mail from an mbox store, safely copy it to a - * temporary store first. - */ - if (!strncmp (url, "mbox:", 5)) { - int tmpfd; - - tmpfd = open (tmp_mbox, O_RDWR | O_CREAT | O_APPEND, 0660); - - if (tmpfd == -1) { - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - "Couldn't create temporary " - "mbox: %s", g_strerror (errno)); - async_mail_exception_dialog ("Unable to move mail", ex, fb ); - goto cleanup; - } - close (tmpfd); - - /* Skip over "mbox:" plus host part (if any) of url. */ - source = url + 5; - if (!strncmp (source, "//", 2)) - source = strchr (source + 2, '/'); - - camel_movemail (source, tmp_mbox, ex); - if (camel_exception_is_set (ex)) { - async_mail_exception_dialog ("Unable to move mail", - ex, fb); - goto cleanup; - } - - if (stat (tmp_mbox, &st) == -1 || st.st_size == 0) { - gnome_ok_dialog ("No new messages."); - goto cleanup; - } - - folder = camel_store_get_folder (dest_store, "movemail", - FALSE, ex); - if (camel_exception_get_id (ex) != CAMEL_EXCEPTION_NONE) { - async_mail_exception_dialog ("Unable to move mail", ex, fb); - goto cleanup; - } - } else { - CamelFolder *sourcefolder; - - store = camel_session_get_store(session, url, ex); - if (!store) { - async_mail_exception_dialog("Unable to get new mail", ex, fb); - goto cleanup; - } - - camel_service_connect(CAMEL_SERVICE (store), ex); - if (camel_exception_get_id(ex) != CAMEL_EXCEPTION_NONE) { - if (camel_exception_get_id(ex) != CAMEL_EXCEPTION_USER_CANCEL) - async_mail_exception_dialog("Unable to get new mail", ex, fb); - goto cleanup; - } - - sourcefolder = camel_store_get_folder(store, "inbox", FALSE, ex); - if (camel_exception_get_id(ex) != CAMEL_EXCEPTION_NONE) { - async_mail_exception_dialog("Unable to get new mail", ex, fb); - goto cleanup; - } - - /* can we perform filtering on this source? */ - if (!(sourcefolder->has_summary_capability - && sourcefolder->has_search_capability)) { - GPtrArray *uids; - int i; - - folder = camel_store_get_folder (dest_store, - "movemail", TRUE, ex); - if (camel_exception_get_id (ex) != CAMEL_EXCEPTION_NONE) { - async_mail_exception_dialog ("Unable to move mail", ex, fb); - goto cleanup; - } - - uids = camel_folder_get_uids (sourcefolder); - printf("got %d messages in source\n", uids->len); - for (i = 0; i < uids->len; i++) { - CamelMimeMessage *msg; - - msg = camel_folder_get_message (sourcefolder, uids->pdata[i], ex); - - if (camel_exception_get_id (ex) != CAMEL_EXCEPTION_NONE) { - async_mail_exception_dialog ("Unable to get read message", ex, fb); - gtk_object_unref (GTK_OBJECT (sourcefolder)); - gtk_object_unref (GTK_OBJECT (msg)); - - goto cleanup; - } - - /* append with flags = 0 since this is a new message */ - camel_folder_append_message (folder, msg, 0, ex); - if (camel_exception_get_id (ex) != CAMEL_EXCEPTION_NONE) { - async_mail_exception_dialog ("Unable to write message", ex, fb); - gtk_object_unref (GTK_OBJECT (msg)); - gtk_object_unref (GTK_OBJECT (sourcefolder)); - - goto cleanup; - } - - camel_folder_delete_message (sourcefolder, uids->pdata[i]); - gtk_object_unref (GTK_OBJECT (msg)); - } - camel_folder_free_uids (sourcefolder, uids); - camel_folder_sync (sourcefolder, TRUE, ex); - if (camel_exception_is_set (ex)) - async_mail_exception_dialog ("", ex, fb); - gtk_object_unref (GTK_OBJECT (sourcefolder)); - } else { - folder = sourcefolder; - } - } - - if (camel_folder_get_message_count (folder) == 0) { - gnome_ok_dialog ("No new messages."); - goto cleanup; - } else if (camel_exception_is_set (ex)) { - async_mail_exception_dialog ("Unable to get new mail", ex, fb); - goto cleanup; - } - - folder_browser_clear_search (fb); - - /* apply filtering rules to this inbox */ - 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); - g_free (userrules); - g_free (systemrules); - - driver = filter_driver_new(fc, filter_get_folder, 0); - - /* Attach a handler to the destination folder to select the first unread - * message iff it changes and iff it's the folder being viewed. - */ - if (dest_folder == fb->folder) - handler_id = gtk_signal_connect (GTK_OBJECT (dest_folder), "folder_changed", - GTK_SIGNAL_FUNC (select_first_unread), fb); - - if (filter_driver_run(driver, folder, dest_folder) == -1) { - async_mail_exception_dialog ("Unable to get new mail", ex, fb); - goto cleanup; - } - - if (dest_folder == fb->folder) - gtk_signal_disconnect (GTK_OBJECT (dest_folder), handler_id); - - cleanup: - if (stat (tmp_mbox, &st) == 0 && st.st_size == 0) - unlink (tmp_mbox); /* FIXME: should use camel to do this */ - g_free (tmp_mbox); - - if (driver) - gtk_object_unref((GtkObject *)driver); - if (fc) - gtk_object_unref((GtkObject *)fc); - if (url) - g_free (url); - - if (folder) { - camel_folder_sync (folder, TRUE, ex); - gtk_object_unref (GTK_OBJECT (folder)); - } - - if (dest_folder) { - camel_folder_sync (dest_folder, TRUE, ex); - gtk_object_unref (GTK_OBJECT (dest_folder)); - } - - if (store) { - camel_service_disconnect (CAMEL_SERVICE (store), ex); - gtk_object_unref (GTK_OBJECT (store)); - } - - if (dest_store && dest_store != fb->folder->parent_store) { - camel_service_disconnect (CAMEL_SERVICE (dest_store), ex); - gtk_object_unref (GTK_OBJECT (dest_store)); - } - camel_exception_free (ex); -} - -void -fetch_mail (GtkWidget *button, gpointer user_data) -{ - const MailConfig *config; - const MailConfigService *source; - char *url = NULL; - rfm_t *info; - - if (!check_configured ()) - return; - - config = mail_config_fetch (); - if (config->sources) { - source = (MailConfigService *)config->sources->data; - url = source->url; - } - - if (!url) { - GtkWidget *win = gtk_widget_get_ancestor (GTK_WIDGET (user_data), - GTK_TYPE_WINDOW); - - gnome_error_dialog_parented ("You have no remote mail source " - "configured", GTK_WINDOW (win)); - return; - } - - /* This must be dynamically allocated so as not to be clobbered - * when we return. Actually, making it static in the whole file - * would probably work. - */ - - info = g_new (rfm_t, 1); - info->fb = FOLDER_BROWSER (user_data); - info->source_url = url; -#ifdef USE_BROKEN_THREADS - mail_operation_try (_("Fetching mail"), real_fetch_mail, NULL, info); -#else - real_fetch_mail (info); -#endif -} - -static gboolean -ask_confirm_for_empty_subject (EMsgComposer *composer) -{ - GtkWidget *message_box; - int button; - - message_box = gnome_message_box_new (_("This message has no subject.\nReally send?"), - GNOME_MESSAGE_BOX_QUESTION, - GNOME_STOCK_BUTTON_YES, GNOME_STOCK_BUTTON_NO, - NULL); - - button = gnome_dialog_run_and_close (GNOME_DIALOG (message_box)); - - if (button == 0) - return TRUE; - else - return FALSE; -} - -static void -set_x_mailer_header (CamelMedium *medium) -{ - char *mailer_string; - - mailer_string = g_strdup_printf ("Evolution %s (Developer Preview)", VERSION); - - camel_medium_add_header (medium, "X-Mailer", mailer_string); - - g_free (mailer_string); -} - -static void -real_send_mail (gpointer user_data) -{ - rsm_t *info = (rsm_t *) user_data; - EMsgComposer *composer = NULL; - CamelTransport *transport = NULL; - CamelException *ex = NULL; - CamelMimeMessage *message = NULL; - const char *subject = NULL; - char *from = NULL; - struct post_send_data *psd = NULL; - -#ifdef USE_BROKEN_THREADS - mail_op_hide_progressbar (); - mail_op_set_message ("Connecting to transport..."); -#endif - - ex = camel_exception_new (); - composer = info->composer; - transport = info->transport; - message = info->message; - subject = info->subject; - from = info->from; - psd = info->psd; - - set_x_mailer_header (CAMEL_MEDIUM (message)); - - camel_mime_message_set_from (message, from); - camel_mime_message_set_date (message, CAMEL_MESSAGE_DATE_CURRENT, 0); - - camel_service_connect (CAMEL_SERVICE (transport), ex); - -#ifdef USE_BROKEN_THREADS - mail_op_set_message ("Connected. Sending..."); -#endif - - if (!camel_exception_is_set (ex)) - camel_transport_send (transport, CAMEL_MEDIUM (message), ex); - - if (!camel_exception_is_set (ex)) { -#ifdef USE_BROKEN_THREADS - mail_op_set_message ("Sent. Disconnecting..."); -#endif - camel_service_disconnect (CAMEL_SERVICE (transport), ex); - } - - if (camel_exception_is_set (ex)) { - async_mail_exception_dialog ("Could not send message", ex, composer); - info->ok = FALSE; - } else { - if (psd) { - camel_folder_set_message_flags (psd->folder, psd->uid, - psd->flags, psd->flags); - } - info->ok = TRUE; - - } - - camel_exception_free (ex); -} - -static void -cleanup_send_mail (gpointer userdata) -{ - rsm_t *info = (rsm_t *) userdata; - - if (info->ok) { - gtk_object_destroy (GTK_OBJECT (info->composer)); - } - - gtk_object_unref (GTK_OBJECT (info->message)); - g_free (info); -} - -static void -composer_send_cb (EMsgComposer *composer, gpointer data) -{ - const MailConfig *config; - const MailConfigIdentity *id = NULL; - static CamelTransport *transport = NULL; - struct post_send_data *psd = data; - rsm_t *info; - static char *from = NULL; - const char *subject; - CamelException *ex; - CamelMimeMessage *message; - char *name, *addr; - - ex = camel_exception_new (); - - config = mail_config_fetch (); - - if (!from) { - CamelInternetAddress *ciaddr; - - if (config->ids->data) { - id = (MailConfigIdentity *)config->ids->data; - } - g_assert (id); - - name = id->name; - g_assert (name); - - addr = id->address; - g_assert (addr); - - ciaddr = camel_internet_address_new (); - camel_internet_address_add (ciaddr, name, addr); - - from = camel_address_encode (CAMEL_ADDRESS (ciaddr)); - } - - if (!transport) { - char *url; - - url = config->transport->url; - g_assert (url); - - transport = camel_session_get_transport (session, url, ex); - if (camel_exception_get_id (ex) != CAMEL_EXCEPTION_NONE) { - mail_exception_dialog ("Could not load mail transport", - ex, composer); - camel_exception_free (ex); - return; - } - } - - message = e_msg_composer_get_message (composer); - - subject = camel_mime_message_get_subject (message); - if (subject == NULL || subject[0] == '\0') { - if (! ask_confirm_for_empty_subject (composer)) { - gtk_object_unref (GTK_OBJECT (message)); - return; - } - } - - info = g_new0 (rsm_t, 1); - info->composer = composer; - info->transport = transport; - info->message = message; - info->subject = subject; - info->from = from; - info->psd = psd; - -#ifdef USE_BROKEN_THREADS - mail_operation_try ("Send Message", real_send_mail, cleanup_send_mail, info); -#else - real_send_mail (info); - cleanup_send_mail (info); -#endif -} - -static void -free_psd (GtkWidget *composer, gpointer user_data) -{ - struct post_send_data *psd = user_data; - - gtk_object_unref (GTK_OBJECT (psd->folder)); - g_free (psd); -} - -static GtkWidget * -create_msg_composer (const char *url) -{ - const MailConfig *config; - gchar *sig_file = NULL; - GtkWidget *composer_widget; - - config = mail_config_fetch (); - if (config->ids) { - const MailConfigIdentity *id; - - id = (MailConfigIdentity *)config->ids->data; - 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), - config->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); -} - -static void -reply (FolderBrowser *fb, gboolean to_all) -{ - EMsgComposer *composer; - struct post_send_data *psd; - - if (!check_configured () || !fb->message_list->cursor_uid || - !fb->mail_display->current_message) - return; - - psd = g_new (struct post_send_data, 1); - psd->folder = fb->folder; - gtk_object_ref (GTK_OBJECT (psd->folder)); - psd->uid = fb->message_list->cursor_uid; - psd->flags = CAMEL_MESSAGE_ANSWERED; - - composer = mail_generate_reply (fb->mail_display->current_message, 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 *button, gpointer user_data) -{ - reply (FOLDER_BROWSER (user_data), FALSE); -} - -void -reply_to_all (GtkWidget *button, gpointer user_data) -{ - reply (FOLDER_BROWSER (user_data), TRUE); -} - -static void -attach_msg (MessageList *ml, const char *uid, gpointer data) -{ - EMsgComposer *composer = data; - CamelMimeMessage *message; - CamelMimePart *part; - const char *subject; - char *desc; - - message = camel_folder_get_message (ml->folder, uid, NULL); - if (!message) - return; - subject = camel_mime_message_get_subject (message); - if (subject) - desc = g_strdup_printf ("Forwarded message - %s", subject); - else - desc = g_strdup ("Forwarded message"); - - 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"); - - e_msg_composer_attach (composer, part); - - gtk_object_unref (GTK_OBJECT (part)); - gtk_object_unref (GTK_OBJECT (message)); - g_free (desc); -} - -void -forward_msg (GtkWidget *button, gpointer user_data) -{ - FolderBrowser *fb = FOLDER_BROWSER (user_data); - EMsgComposer *composer; - CamelMimeMessage *cursor_msg; - const char *from, *subject; - char *fwd_subj; - - cursor_msg = fb->mail_display->current_message; - if (!check_configured () || !cursor_msg) - return; - - composer = E_MSG_COMPOSER (create_msg_composer (NULL)); - message_list_foreach (fb->message_list, attach_msg, composer); - - from = camel_mime_message_get_from (cursor_msg); - subject = camel_mime_message_get_subject (cursor_msg); - if (from) { - if (subject && *subject) { - while (*subject == ' ') - subject++; - fwd_subj = g_strdup_printf ("[%s] %s", from, subject); - } else { - fwd_subj = g_strdup_printf ("[%s] (forwarded message)", - from); - } - } else { - fwd_subj = NULL; - } - - e_msg_composer_set_headers (composer, NULL, NULL, NULL, fwd_subj); - g_free (fwd_subj); - - gtk_signal_connect (GTK_OBJECT (composer), "send", - GTK_SIGNAL_FUNC (composer_send_cb), NULL); - - gtk_widget_show (GTK_WIDGET (composer)); -} - -struct move_data { - CamelFolder *source, *dest; - CamelException *ex; -}; - -static void -real_move_msg (MessageList *ml, const char *uid, gpointer user_data) -{ - struct move_data *rfd = user_data; - - if (camel_exception_is_set (rfd->ex)) - return; - - camel_folder_move_message_to (rfd->source, uid, rfd->dest, rfd->ex); -} - -void -move_msg (GtkWidget *button, gpointer user_data) -{ - FolderBrowser *fb = user_data; - MessageList *ml = fb->message_list; - char *uri, *physical, *path; - struct move_data rfd; - const char *allowed_types[] = { "mail", NULL }; - - extern EvolutionShellClient *global_shell_client; - static char *last; - - if (last == NULL) - last = g_strdup (""); - - evolution_shell_client_user_select_folder (global_shell_client, - _("Move message(s) to"), - 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); - - rfd.source = ml->folder; - rfd.dest = mail_uri_to_folder (physical); - g_free (physical); - if (!rfd.dest) - return; - rfd.ex = camel_exception_new (); - - message_list_foreach (ml, real_move_msg, &rfd); - gtk_object_unref (GTK_OBJECT (rfd.dest)); - - if (camel_exception_is_set (rfd.ex)) - mail_exception_dialog ("Could not move message", rfd.ex, fb); - camel_exception_free (rfd.ex); -} - -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; - int i; - - uids = camel_folder_get_uids (ml->folder); - for (i = 0; i < uids->len; i++) - { - camel_folder_set_message_flags (ml->folder, uids->pdata[i], - CAMEL_MESSAGE_SEEN, - CAMEL_MESSAGE_SEEN); - } -} - -static void -real_delete_msg (MessageList *ml, const char *uid, gpointer user_data) -{ - CamelException *ex = user_data; - guint32 flags; - - if (camel_exception_is_set (ex)) - return; - - /* Toggle the deleted flag without touching other flags. */ - flags = camel_folder_get_message_flags (ml->folder, uid); - camel_folder_set_message_flags (ml->folder, uid, - CAMEL_MESSAGE_DELETED, ~flags); -} - -void -delete_msg (GtkWidget *button, gpointer user_data) -{ - FolderBrowser *fb = user_data; - MessageList *ml = fb->message_list; - CamelException ex; - - camel_exception_init (&ex); - message_list_foreach (ml, real_delete_msg, &ex); - if (camel_exception_is_set (&ex)) { - mail_exception_dialog ("Could not toggle deleted flag", - &ex, fb); - camel_exception_clear (&ex); - return; - } -} - -static void real_expunge_folder (gpointer user_data) -{ - FolderBrowser *fb = FOLDER_BROWSER (user_data); - CamelException ex; - - e_table_model_pre_change(fb->message_list->table_model); - -#ifdef USE_BROKEN_THREADS - mail_op_hide_progressbar (); - mail_op_set_message ("Expunging %s...", fb->message_list->folder->full_name); -#endif - - camel_exception_init (&ex); - - camel_folder_expunge (fb->message_list->folder, &ex); - - /* FIXME: is there a better way to force an update? */ - /* FIXME: Folder should raise a signal to say its contents has changed ... */ - e_table_model_changed (fb->message_list->table_model); - - if (camel_exception_get_id (&ex) != CAMEL_EXCEPTION_NONE) { - async_mail_exception_dialog ("Unable to expunge deleted messages", &ex, fb); - } -} - -void -expunge_folder (BonoboUIHandler *uih, void *user_data, const char *path) -{ - FolderBrowser *fb = FOLDER_BROWSER(user_data); - - if (fb->message_list->folder) { -#ifdef USE_BROKEN_THREADS - mail_operation_try ("Expunge Folder", real_expunge_folder, NULL, fb); -#else - real_expunge_folder (fb); -#endif - } -} - -static void -filter_druid_clicked(GtkWidget *w, int button, FolderBrowser *fb) -{ - FilterContext *fc; - - if (button == 0) { - char *user; - - fc = gtk_object_get_data((GtkObject *)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((GnomeDialog *)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); - g_free(user); - g_free(system); - w = filter_editor_construct(fc); - gtk_object_set_data_full((GtkObject *)w, "context", fc, (GtkDestroyNotify)gtk_object_unref); - gtk_signal_connect((GtkObject *)w, "clicked", filter_druid_clicked, fb); - gtk_widget_show(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 -print_msg (GtkWidget *button, gpointer user_data) -{ - FolderBrowser *fb = user_data; - 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 (fb->mail_display->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)); -} diff --git a/mail/mail-threads.c b/mail/mail-threads.c deleted file mode 100644 index a5dbac2427..0000000000 --- a/mail/mail-threads.c +++ /dev/null @@ -1,904 +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> - -#ifdef USE_BROKEN_THREADS - -#include <string.h> -#include <glib.h> -#include "mail.h" -#include "mail-threads.h" - -#define DEBUG(p) g_print p - -/* FIXME TODO: Do we need operations that don't get a progress window because - * they're quick, but we still want camel to be locked? We need some kind - * of flag to mail_operation_try, but then we also need some kind of monitor - * to open the window if it takes more than a second or something. That would - * probably entail another thread.... - */ - -/** - * A function and its userdata - **/ - -typedef struct closure_s { - void (*callback)( gpointer ); - void (*cleanup)( gpointer ); - gpointer data; - - gchar *prettyname; - /* gboolean gets_window; */ -} closure_t; - -/** - * A command issued through the compipe - **/ - -typedef struct com_msg_s { - enum com_msg_type_e { STARTING, PERCENTAGE, HIDE_PBAR, SHOW_PBAR, MESSAGE, PASSWORD, ERROR, FINISHED } type; - gfloat percentage; - gchar *message; - - void (*func)( gpointer ); - gpointer userdata; - - /* Password stuff */ - gchar **reply; - gboolean secret; - gboolean *success; -} com_msg_t; - -/** - * @mail_operation_in_progress: When true, there's - * another thread executing a major ev-mail operation: - * fetch_mail, etc. - * - * 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 gboolean mail_operation_in_progress; - -/** - * @queue_window: The little window on the screen that - * shows the progress of the current operation and the - * operations that are queued to proceed after it. - * - * @queue_window_pending: The vbox that contains the - * list of pending operations. - * - * @queue_window_message: The label that contains the - * operation's message to the user - **/ - -static GtkWidget *queue_window = NULL; -static GtkWidget *queue_window_pending = NULL; -static GtkWidget *queue_window_message = NULL; -static GtkWidget *queue_window_progress = NULL; - -/** - * @progress_timeout_handle: the handle to our timer - * function so that we can remove it when the progress bar - * mode changes. - **/ - -static int progress_timeout_handle = -1; - -/** - * @op_queue: The list of operations the are scheduled - * to proceed after the currently executing one. When - * only one operation is going, this is NULL. - **/ - -static GSList *op_queue = NULL; - -/** - * @compipe: The pipe through which the dispatcher communicates - * with the main thread for GTK+ calls - * - * @chan_reader: the GIOChannel that reads our pipe - * - * @READER: the fd in our pipe that.... reads! - * @WRITER: the fd in our pipe that.... writes! - */ - -#define READER compipe[0] -#define WRITER compipe[1] - -static int compipe[2] = { -1, -1 }; - -GIOChannel *chan_reader = NULL; - -/** - * @modal_cond: 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. - * - * @modal_lock: a mutex for said condition - * - * @modal_may_proceed: a gboolean telling us whether - * the dispatch thread may proceed its operations. - */ - -G_LOCK_DEFINE_STATIC( modal_lock ); -static GCond *modal_cond = NULL; -static gboolean modal_may_proceed = FALSE; - -/** - * Static prototypes - **/ - -static void create_queue_window( void ); -static void dispatch( closure_t *clur ); -static void *dispatch_func( void *data ); -static void check_compipe( void ); -static void check_cond( void ); -static gboolean read_msg( GIOChannel *source, GIOCondition condition, gpointer userdata ); -static void remove_next_pending( void ); -static void show_error( com_msg_t *msg ); -static void show_error_clicked( void ); -static void get_password( com_msg_t *msg ); -static void get_password_cb( gchar *string, gpointer data ); -static void get_password_clicked( GnomeDialog *dialog, gint button, gpointer user_data ); -static gboolean progress_timeout( gpointer data ); -static void timeout_toggle( gboolean active ); - -/* 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. - */ - -#else /* defined USE_PTHREADS */ -choke on this: no thread type defined -#endif - -/** - * mail_operation_try: - * @description: A user-friendly string describing the operation. - * @callback: the function to call in another thread to start the operation - * @cleanup: the function to call in the main thread when the callback is finished. - * NULL is allowed. - * @user_data: extra data passed to the callback - * - * 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_try( const gchar *description, void (*callback)( gpointer ), - void (*cleanup)( gpointer ), gpointer user_data ) -{ - closure_t *clur; - g_assert( callback ); - - clur = g_new( closure_t, 1 ); - clur->callback = callback; - clur->cleanup = cleanup; - clur->data = user_data; - clur->prettyname = g_strdup( description ); - - if( mail_operation_in_progress == FALSE ) { - /* No operations are going on, none are pending. So - * we check to see if we're initialized (create the - * window and the pipes), and send off the operation - * on its merry way. - */ - - mail_operation_in_progress = TRUE; - - check_compipe(); - create_queue_window(); - gtk_widget_show_all( queue_window ); - gnome_win_hints_set_layer( queue_window, - WIN_LAYER_ONTOP ); - gnome_win_hints_set_state( queue_window, - WIN_STATE_ARRANGE_IGNORE ); - gnome_win_hints_set_hints( queue_window, - WIN_HINTS_SKIP_FOCUS | - WIN_HINTS_SKIP_WINLIST | - WIN_HINTS_SKIP_TASKBAR ); - gtk_widget_hide( queue_window_pending ); - - dispatch( clur ); - } else { - GtkWidget *label; - - /* Zut. We already have an operation running. Well, - * queue ourselves up. - * - * Yes, g_slist_prepend is faster down here.. But we pop - * operations off the beginning of the list later and - * that's a lot faster. - */ - - op_queue = g_slist_append( op_queue, clur ); - - /* Show us in the pending window. */ - label = gtk_label_new( description ); - gtk_misc_set_alignment( GTK_MISC( label ), 1.0, 0.5 ); - gtk_box_pack_start( GTK_BOX( queue_window_pending ), label, - FALSE, TRUE, 2 ); - - /* If we want the next op to be on the bottom, uncomment this */ - /* 1 = first on list always (0-based) */ - /* gtk_box_reorder_child( GTK_BOX( queue_window_pending ), label, 1 ); */ - gtk_widget_show_all( queue_window_pending ); - } - - return TRUE; -} - -/** - * 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( 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. - **/ - -/* FIXME: I'd much rather have one of those Netscape-style progress - * bars that just zips back and forth, but gtkprogressbar can't do - * that, right? - */ - -void mail_op_hide_progressbar( void ) -{ - com_msg_t msg; - - msg.type = HIDE_PBAR; - write( 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( WRITER, &msg, sizeof( msg ) ); -} - -/** - * 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( 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; - - check_cond(); - - msg.type = PASSWORD; - msg.secret = secret; - msg.message = prompt; - msg.reply = dest; - msg.success = &result; - - (*dest) = NULL; - - G_LOCK( modal_lock ); - - write( WRITER, &msg, sizeof( msg ) ); - modal_may_proceed = FALSE; - - while( modal_may_proceed == FALSE ) - g_cond_wait( modal_cond, g_static_mutex_get_mutex( &G_LOCK_NAME( modal_lock ) ) ); - - G_UNLOCK( modal_lock ); - - 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; - - check_cond(); - - va_start( val, fmt ); - msg.type = ERROR; - msg.message = g_strdup_vprintf( fmt, val ); - va_end( val ); - - G_LOCK( modal_lock ); - - modal_may_proceed = FALSE; - write( WRITER, &msg, sizeof( msg ) ); - - while( modal_may_proceed == FALSE ) - g_cond_wait( modal_cond, g_static_mutex_get_mutex( &G_LOCK_NAME( modal_lock ) ) ); - - G_UNLOCK( modal_lock ); -} - -/** - * mail_operation_wait_for_finish: - * - * Waits for the currently executing async operations - * to finish executing - */ - -void mail_operation_wait_for_finish( void ) -{ - while( mail_operation_in_progress ) { - while( gtk_events_pending() ) - gtk_main_iteration(); - } -} - -/** - * mail_operations_are_executing: - * - * Returns TRUE if operations are being executed asynchronously - * when called, FALSE if not. - */ - -gboolean mail_operations_are_executing( void ) -{ - return mail_operation_in_progress; -} - -/* ** Static functions **************************************************** */ - -/** - * create_queue_window: - * - * Creates the queue_window widget that displays the progress of the - * current operation. - */ - -static void -create_queue_window( void ) -{ - GtkWidget *vbox; - GtkWidget *pending_vb, *pending_lb; - GtkWidget *progress_lb, *progress_bar; - - /* Check to see if we've only hidden it */ - if( queue_window != NULL ) - return; - - queue_window = gtk_window_new( GTK_WINDOW_DIALOG ); - gtk_container_set_border_width( GTK_CONTAINER( queue_window ), 8 ); - - vbox = gtk_vbox_new( FALSE, 4 ); - - pending_vb = gtk_vbox_new( FALSE, 2 ); - queue_window_pending = pending_vb; - - pending_lb = gtk_label_new( _("Currently pending operations:") ); - gtk_misc_set_alignment( GTK_MISC( pending_lb ), 0.0, 0.0 ); - gtk_box_pack_start( GTK_BOX( pending_vb ), pending_lb, - FALSE, TRUE, 0 ); - - gtk_box_pack_start( GTK_BOX( vbox ), pending_vb, - TRUE, TRUE, 4 ); - - /* FIXME: 'operation' is not the warmest cuddliest word. */ - progress_lb = gtk_label_new( "" ); - queue_window_message = progress_lb; - gtk_box_pack_start( GTK_BOX( vbox ), progress_lb, - FALSE, TRUE, 4 ); - - progress_bar = gtk_progress_bar_new(); - queue_window_progress = progress_bar; - /* FIXME: is this fit for l10n? */ - gtk_progress_bar_set_orientation( GTK_PROGRESS_BAR( progress_bar ), - GTK_PROGRESS_LEFT_TO_RIGHT ); - gtk_progress_bar_set_bar_style( GTK_PROGRESS_BAR( progress_bar ), - GTK_PROGRESS_CONTINUOUS ); - gtk_box_pack_start( GTK_BOX( vbox ), progress_bar, - FALSE, TRUE, 4 ); - - gtk_container_add( GTK_CONTAINER( queue_window ), vbox ); -} - -/** - * check_compipe: - * - * Check and see if our pipe has been opened and open - * it if necessary. - **/ - -static void check_compipe( void ) -{ - if( READER > 0 ) - return; - - if( pipe( 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( READER ); - g_io_add_watch( chan_reader, G_IO_IN, read_msg, NULL ); -} - -/** - * check_cond: - * - * See if our condition is initialized and do so if necessary - **/ - -static void check_cond( void ) -{ - if( modal_cond == NULL ) - modal_cond = g_cond_new(); -} - -/** - * dispatch: - * @clur: The function to execute and its userdata - * - * Start a thread that executes the closure and exit - * it when done. - */ - -static void dispatch( closure_t *clur ) -{ - int res; - - res = pthread_create( &dispatch_thread, NULL, (void *) &dispatch_func, clur ); - - if( res != 0 ) { - g_warning( "Error launching dispatch thread!" ); - /* FIXME: more error handling */ - } -} - -/** - * dispatch_func: - * @data: the closure to run - * - * Runs the closure and exits the thread. - */ - -static void *dispatch_func( void *data ) -{ - com_msg_t msg; - closure_t *clur = (closure_t *) data; - - msg.type = STARTING; - msg.message = clur->prettyname; - write( WRITER, &msg, sizeof( msg ) ); - - /*GDK_THREADS_ENTER ();*/ - (clur->callback)( clur->data ); - /*GDK_THREADS_LEAVE ();*/ - - msg.type = FINISHED; - msg.func = clur->cleanup; /* NULL is ok */ - msg.userdata = clur->data; - write( WRITER, &msg, sizeof( msg ) ); - - g_free( clur->prettyname ); - g_free( data ); - - pthread_exit( 0 ); - 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; - closure_t *clur; - GSList *temp; - 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\n")); - gtk_label_set_text( GTK_LABEL( queue_window_message ), msg->message ); - gtk_progress_bar_update( GTK_PROGRESS_BAR( queue_window_progress ), 0.0 ); - g_free( msg ); - break; - case PERCENTAGE: - DEBUG (("*** Message -- PERCENTAGE\n")); - gtk_progress_bar_update( GTK_PROGRESS_BAR( queue_window_progress ), msg->percentage ); - g_free( msg ); - break; - case HIDE_PBAR: - DEBUG (("*** Message -- HIDE_PBAR\n")); - gtk_progress_set_activity_mode( GTK_PROGRESS( queue_window_progress ), TRUE ); - timeout_toggle( TRUE ); - - g_free( msg ); - break; - case SHOW_PBAR: - DEBUG (("*** Message -- SHOW_PBAR\n")); - timeout_toggle( FALSE ); - gtk_progress_set_activity_mode( GTK_PROGRESS( queue_window_progress ), FALSE ); - - g_free( msg ); - break; - case MESSAGE: - DEBUG (("*** Message -- MESSAGE\n")); - gtk_label_set_text( GTK_LABEL( queue_window_message ), - msg->message ); - g_free( msg->message ); - g_free( msg ); - break; - case PASSWORD: - DEBUG (("*** Message -- PASSWORD\n")); - g_assert( msg->reply ); - g_assert( msg->success ); - get_password( msg ); - /* don't free msg! done later */ - break; - case ERROR: - DEBUG (("*** Message -- ERROR\n")); - show_error( msg ); - g_free( msg ); - break; - - /* Don't fall through; dispatch_func does the FINISHED - * call for us - */ - - case FINISHED: - DEBUG (("*** Message -- FINISH\n")); - if( msg->func ) - (msg->func)( msg->userdata ); - - if( op_queue == NULL ) { - g_print("\tNo more ops -- hide %p.\n", queue_window); - /* All done! */ - gtk_widget_hide( queue_window ); - mail_operation_in_progress = FALSE; - } else { - g_print("\tOperation left.\n"); - - /* There's another operation left */ - - /* Pop it off the front */ - clur = op_queue->data; - temp = g_slist_next( op_queue ); - g_slist_free_1( op_queue ); - op_queue = temp; - - /* Clear it out of the 'pending' vbox */ - remove_next_pending(); - - /* Run run run little process */ - dispatch( clur ); - } - g_free( msg ); - break; - default: - g_warning( _("Corrupted message from dispatching thread?") ); - break; - } - - GDK_THREADS_LEAVE(); - return TRUE; -} - -/** - * remove_next_pending: - * - * Remove an item from the list of pending items. If - * that's the last one, additionally hide the little - * 'pending' message. - **/ - -static void remove_next_pending( void ) -{ - GList *children; - - children = gtk_container_children( GTK_CONTAINER( queue_window_pending ) ); - - /* Skip past the header label */ - children = g_list_first( children ); - children = g_list_next( children ); - - /* Nuke the one on top */ - gtk_container_remove( GTK_CONTAINER( queue_window_pending ), - GTK_WIDGET( children->data ) ); - - /* Hide it? */ - if( g_list_next( children ) == NULL ) - gtk_widget_hide( queue_window_pending ); -} - -/** - * show_error: - * - * Show the error dialog and wait for user OK - **/ - -static void show_error( com_msg_t *msg ) -{ - GtkWidget *err_dialog; - - err_dialog = gnome_error_dialog( msg->message ); - gnome_dialog_set_close( GNOME_DIALOG(err_dialog), TRUE ); - gtk_signal_connect( GTK_OBJECT( err_dialog ), "clicked", (GtkSignalFunc) show_error_clicked, NULL ); - g_free( msg->message ); - - G_LOCK( modal_lock ); - - timeout_toggle( FALSE ); - modal_may_proceed = FALSE; - gtk_widget_show( GTK_WIDGET( err_dialog ) ); - gnome_win_hints_set_layer( err_dialog, - WIN_LAYER_ONTOP ); - gnome_win_hints_set_state( err_dialog, - WIN_STATE_ARRANGE_IGNORE ); - gnome_win_hints_set_hints( err_dialog, - WIN_HINTS_SKIP_FOCUS | - WIN_HINTS_SKIP_WINLIST | - WIN_HINTS_SKIP_TASKBAR ); -} - -/** - * show_error_clicked: - * - * Called when the user makes hits okay to the error dialog -- - * the dispatch thread is allowed to continue. - **/ - -static void show_error_clicked( void ) -{ - modal_may_proceed = TRUE; - timeout_toggle( TRUE ); - g_cond_signal( modal_cond ); - G_UNLOCK( modal_lock ); -} - -/** - * get_password: - * - * Ask for a password and put the answer in *(msg->reply) - **/ - -static void get_password( com_msg_t *msg ) -{ - GtkWidget *dialog; - - dialog = gnome_request_dialog( msg->secret, msg->message, NULL, - 0, get_password_cb, msg, - NULL ); - gnome_dialog_set_close( GNOME_DIALOG(dialog), TRUE ); - gtk_signal_connect( GTK_OBJECT( dialog ), "clicked", get_password_clicked, msg ); - - G_LOCK( modal_lock ); - - modal_may_proceed = FALSE; - - if( dialog == NULL ) { - *(msg->success) = FALSE; - *(msg->reply) = g_strdup( _("Could not create dialog box.") ); - modal_may_proceed = TRUE; - g_cond_signal( modal_cond ); - G_UNLOCK( modal_lock ); - } else { - *(msg->reply) = NULL; - timeout_toggle( FALSE ); - gtk_widget_show( GTK_WIDGET( dialog ) ); - gnome_win_hints_set_layer( dialog, - WIN_LAYER_ONTOP ); - gnome_win_hints_set_state( dialog, - WIN_STATE_ARRANGE_IGNORE ); - gnome_win_hints_set_hints( dialog, - WIN_HINTS_SKIP_FOCUS | - WIN_HINTS_SKIP_WINLIST | - WIN_HINTS_SKIP_TASKBAR ); - } -} - -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 void get_password_clicked( GnomeDialog *dialog, gint button, gpointer user_data ) -{ - com_msg_t *msg = (com_msg_t *) user_data; - - if( button == 1 || *(msg->reply) == NULL ) { - *(msg->success) = FALSE; - *(msg->reply) = g_strdup( _("User cancelled query.") ); - } else - *(msg->success) = TRUE; - - g_free( msg ); - modal_may_proceed = TRUE; - timeout_toggle( TRUE ); - g_cond_signal( modal_cond ); - G_UNLOCK( modal_lock ); -} - -/* NOT totally copied from gtk+/gtk/testgtk.c, really! */ - -static gboolean -progress_timeout (gpointer data) -{ - gfloat new_val; - GtkAdjustment *adj; - - adj = GTK_PROGRESS (data)->adjustment; - - new_val = adj->value + 1; - if (new_val > adj->upper) - new_val = adj->lower; - - gtk_progress_set_value (GTK_PROGRESS (data), new_val); - - return TRUE; -} - -/** - * timeout_toggle: - * - * Turn on and off our timeout to zip the progressbar along, - * protecting against recursion (Ie, call with TRUE twice - * in a row. - **/ - -static void -timeout_toggle( gboolean active ) -{ - if( (GTK_PROGRESS( queue_window_progress ))->activity_mode == 0 ) - return; - - if( active ) { - if( progress_timeout_handle < 0 ) - progress_timeout_handle = gtk_timeout_add( 80, progress_timeout, queue_window_progress ); - } else { - if( progress_timeout_handle >= 0 ) { - gtk_timeout_remove( progress_timeout_handle ); - progress_timeout_handle = -1; - } - } -} - -#endif diff --git a/mail/mail-threads.h b/mail/mail-threads.h deleted file mode 100644 index e26acdbb14..0000000000 --- a/mail/mail-threads.h +++ /dev/null @@ -1,52 +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_ - -#ifdef USE_BROKEN_THREADS -/* Schedule to operation to happen eventually */ - -gboolean mail_operation_try( const gchar *description, - void (*callback)( gpointer ), - void (*cleanup)( gpointer ), - gpointer user_data ); - -/* User interface hooks for the other thread */ - -void mail_op_set_percentage( gfloat percentage ); -void mail_op_hide_progressbar( void ); -void mail_op_show_progressbar( void ); -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 ); - -/* Wait for the async operations to finish */ -void mail_operation_wait_for_finish( void ); - -gboolean mail_operations_are_executing( void ); - -#endif /* defined USE_BROKEN_THREADS */ - -#endif /* defined _MAIL_THREADS_H_ */ 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 cd613040b1..0000000000 --- a/mail/mail-vfolder.c +++ /dev/null @@ -1,306 +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 "camel/camel.h" - -#include "filter/vfolder-context.h" -#include "filter/vfolder-rule.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) != 0) { - g_warning("cannot load vfolders: %s\n", ((RuleContext *)context)->error); - } - g_free(user); - g_free(system); - vfolder_refresh(); -} - -/* maps the shell's uri to the real vfolder uri and open the folder */ -CamelFolder * -vfolder_uri_to_folder(const char *uri) -{ - CamelFolder *mail_uri_to_folder(const char *); - void camel_vee_folder_add_folder(CamelFolder *, CamelFolder *); - - struct _vfolder_info *info; - char *storeuri, *foldername; - VfolderRule *rule; - CamelStore *store = NULL; - CamelFolder *folder = NULL, *sourcefolder; - CamelException *ex; - 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); - ex = camel_exception_new (); - store = camel_session_get_store (session, storeuri, ex); - if (store == NULL) - goto cleanup; - - folder = camel_store_get_folder (store, foldername, TRUE, ex); - if (folder == NULL) - goto cleanup; - - sourceuri = NULL; - sources = 0; - while ( (sourceuri = vfolder_rule_next_source(rule, sourceuri)) ) { - d(printf("adding vfolder source: %s\n", sourceuri)); - sourcefolder = mail_uri_to_folder(sourceuri); - if (sourcefolder) { - sources++; - camel_vee_folder_add_folder(folder, sourcefolder); - } - } - /* 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_uri_to_folder(defaulturi); - g_free(defaulturi); - if (sourcefolder) - camel_vee_folder_add_folder(folder, sourcefolder); - } -cleanup: - 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", "Ok", "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); -} diff --git a/mail/mail-vfolder.h b/mail/mail-vfolder.h deleted file mode 100644 index 10f20777d2..0000000000 --- a/mail/mail-vfolder.h +++ /dev/null @@ -1,22 +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 "filter/vfolder-rule.h" -#include "filter/filter-part.h" - -void vfolder_create_storage(EvolutionShellComponent *shell_component); - -CamelFolder *vfolder_uri_to_folder(const char *uri); -void vfolder_edit(void); -FilterPart *vfolder_create_part(const char *name); -void vfolder_gui_add_rule(VfolderRule *rule); - -#endif diff --git a/mail/mail.h b/mail/mail.h deleted file mode 100644 index 83f5001605..0000000000 --- a/mail/mail.h +++ /dev/null @@ -1,73 +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" - -/* FIXME FIXME FIXME this sucks sucks sucks sucks */ - -/* folder-browser-factory */ -void folder_browser_factory_init (void); -BonoboControl *folder_browser_factory_new_control (const char *uri); - -/* folder-browser */ -CamelFolder *mail_uri_to_folder (const char *uri); - -/* mail-crypto */ -char *mail_crypto_openpgp_decrypt (const char *ciphertext, - const char *passphrase, - CamelException *ex); -/* FIXME: add encryption & signing functions */ - -/* mail-format */ -void mail_format_mime_message (CamelMimeMessage *mime_message, - GtkHTML *html, GtkHTMLStream *stream, - CamelMimeMessage *root_message); - -EMsgComposer *mail_generate_reply (CamelMimeMessage *mime_message, - gboolean to_all); - -/* mail-identify */ -char *mail_identify_mime_part (CamelMimePart *part); - -/* mail-ops */ -void fetch_mail (GtkWidget *button, gpointer user_data); -void compose_msg (GtkWidget *button, gpointer user_data); -void send_to_url (const char *url); -void forward_msg (GtkWidget *button, gpointer user_data); -void reply_to_sender (GtkWidget *button, gpointer user_data); -void reply_to_all (GtkWidget *button, gpointer user_data); -void delete_msg (GtkWidget *button, gpointer user_data); -void move_msg (GtkWidget *button, gpointer user_data); -void print_msg (GtkWidget *button, gpointer user_data); - -void mark_all_seen (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); - -/* session */ -void session_init (void); -char *mail_request_dialog (const char *prompt, gboolean secret, const char *key); -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 c330f412e5..0000000000 --- a/mail/main.c +++ /dev/null @@ -1,65 +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 <gnome.h> -#include <bonobo/bonobo-main.h> -#include <bonobo/bonobo-object-directory.h> -#include <glade/glade.h> -#include <gconf/gconf.h> -#include <liboaf/liboaf.h> - -#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 []) -{ - bindtextdomain (PACKAGE, EVOLUTION_LOCALEDIR); - textdomain (PACKAGE); - -#ifdef USE_BROKEN_THREADS - g_thread_init( NULL ); -#endif - - od_assert_using_oaf (); - gnome_init_with_popt_table ("evolution-mail-component", VERSION, - argc, argv, oaf_popt_options, 0, NULL); - oaf_init (argc, argv); - - if (bonobo_init (CORBA_OBJECT_NIL, 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."); - } - - gconf_init (argc, argv, NULL); - - glade_gnome_init (); - - session_init (); - e_cursors_init (); - - component_factory_init (); - -#ifdef USE_BROKEN_THREADS - GDK_THREADS_ENTER (); -#endif - bonobo_main (); -#ifdef USE_BROKEN_THREADS - GDK_THREADS_LEAVE (); -#endif - - return 0; -} diff --git a/mail/message-list.c b/mail/message-list.c deleted file mode 100644 index f2565866d4..0000000000 --- a/mail/message-list.c +++ /dev/null @@ -1,1003 +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 "camel/camel-exception.h" -#include <camel/camel-folder.h> -#include "message-list.h" -#include "message-thread.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 void select_msg (MessageList *message_list, gint row); -static char *filter_date (const void *data); - -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); -} - -/** - * message_list_select: - * @message_list: a MessageList - * @base_row: the 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 row to try, and @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 last; - - if (direction == MESSAGE_LIST_SELECT_PREVIOUS) - last = 0; - else - last = e_table_model_row_count (message_list->table_model); - - while (base_row != last) { - base_row += direction; - info = get_message_info (message_list, base_row); - if (info && (info->flags & mask) == flags) { - e_table_scrolled_set_cursor_row (E_TABLE_SCROLLED (message_list->etable), - base_row); - return; - } - } - - mail_display_set_message (message_list->parent_folder_browser->mail_display, NULL); -} - -static gint -mark_msg_seen (gpointer data) -{ - MessageList *ml = data; - guint32 flags; - - if (!ml->cursor_uid) - return FALSE; - - flags = camel_folder_get_message_flags (ml->folder, ml->cursor_uid); - camel_folder_set_message_flags (ml->folder, ml->cursor_uid, - CAMEL_MESSAGE_SEEN, - CAMEL_MESSAGE_SEEN); - return FALSE; -} - -/* select a message and display it */ -static void -select_msg (MessageList *message_list, gint row) -{ - CamelException ex; - CamelMimeMessage *message; - const CamelMessageInfo *msg_info; - MailDisplay *md = message_list->parent_folder_browser->mail_display; - - camel_exception_init (&ex); - - msg_info = get_message_info (message_list, row); - if (msg_info) { - message = camel_folder_get_message (message_list->folder, - msg_info->uid, &ex); - if (camel_exception_get_id (&ex)) { - printf ("Unable to get message: %s\n", - ex.desc?ex.desc:"unknown_reason"); - return; - } - - if (message_list->seen_id) - gtk_timeout_remove (message_list->seen_id); - - mail_display_set_message (md, CAMEL_MEDIUM (message)); - gtk_object_unref (GTK_OBJECT (message)); - - message_list->seen_id = - gtk_timeout_add (1500, mark_msg_seen, message_list); - } else - mail_display_set_message (md, NULL); -} - - -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)); - } - - 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_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; - - 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; - - camel_folder_set_message_flags (message_list->folder, msg_info->uid, - CAMEL_MESSAGE_SEEN, ~msg_info->flags); - 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); - - 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); - - 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); - - 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_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->folder) - gtk_object_unref (GTK_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); -} - -/* only call if we have a tree model */ -/* builds the tree structure */ -static void -build_tree (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_tree (ml, node, c->child, row); - } - c = c->next; - } -} - -static void -build_flat (MessageList *ml, ETreePath *parent, GPtrArray *uids) -{ - ETreeModel *tree = E_TREE_MODEL (ml->table_model); - ETreePath *node; - char *uid; - int i; - - 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)); - } -} - -void -message_list_regenerate (MessageList *message_list, const char *search) -{ - ETreeModel *etm = E_TREE_MODEL (message_list->table_model); - GPtrArray *uids; - int row = 0; - - e_table_model_pre_change(message_list->table_model); - - if (message_list->search) { - g_free (message_list->search); - message_list->search = NULL; - } - - if (message_list->uid_rowmap) { - g_hash_table_foreach (message_list->uid_rowmap, - free_key, NULL); - g_hash_table_destroy (message_list->uid_rowmap); - } - message_list->uid_rowmap = g_hash_table_new (g_str_hash, g_str_equal); - - if (search && camel_folder_has_search_capability (message_list->folder)) { - CamelException ex; - - camel_exception_init (&ex); - uids = camel_folder_search_by_expression (message_list->folder, - search, &ex); - if (camel_exception_is_set (&ex)) { - e_notice (NULL, GNOME_MESSAGE_BOX_ERROR, - "Search failed: %s", - camel_exception_get_description (&ex)); - camel_exception_clear (&ex); - } else - message_list->search = g_strdup (search); - } else - uids = camel_folder_get_uids (message_list->folder); - - /* FIXME: free the old tree data */ - - /* Clear the old contents, build the new */ - if (message_list->tree_root) - e_tree_model_node_remove(etm, message_list->tree_root); - message_list->tree_root = - e_tree_model_node_insert(etm, NULL, 0, message_list); - e_tree_model_node_set_expanded (etm, message_list->tree_root, TRUE); - - if (threaded_view) { - struct _container *head; - - head = thread_messages (message_list->folder, uids); - build_tree (message_list, message_list->tree_root, head, &row); - thread_messages_free (head); - } else - build_flat (message_list, message_list->tree_root, uids); - - if (search) { - g_strfreev ((char **)uids->pdata); - g_ptr_array_free (uids, FALSE); - } else - camel_folder_free_uids (message_list->folder, uids); - - e_table_model_changed (message_list->table_model); - select_msg (message_list, 0); -} - -static void -folder_changed (CamelFolder *f, int type, MessageList *message_list) -{ - message_list_regenerate (message_list, message_list->search); -} - -static void -message_changed (CamelFolder *f, const char *uid, MessageList *message_list) -{ - 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); -} - -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) - gtk_object_unref (GTK_OBJECT (message_list->folder)); - - message_list->folder = camel_folder; - - gtk_signal_connect(GTK_OBJECT (camel_folder), "folder_changed", - folder_changed, message_list); - gtk_signal_connect(GTK_OBJECT (camel_folder), "message_changed", - message_changed, message_list); - - gtk_object_ref (GTK_OBJECT (camel_folder)); - - folder_changed (camel_folder, 0, message_list); -} - -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 CamelMessageInfo *info; - - message_list = MESSAGE_LIST (user_data); - - message_list->cursor_row = row; - info = get_message_info (message_list, row); - message_list->cursor_uid = info ? info->uid : NULL; - - 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) -{ - e_table_scrolled_set_cursor_row (user_data, 0); - return FALSE; -} - -static void -select_row (ETableScrolled *table, gpointer user_data) -{ - MessageList *message_list = user_data; - - gtk_idle_add (idle_select_row, message_list->etable); -} - - -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 CamelMessageInfo *info; - - info = get_message_info (mlfe_data->message_list, row); - if (info) { - mlfe_data->callback (mlfe_data->message_list, - info->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); -} - -gboolean threaded_view = TRUE; - -void -message_list_toggle_threads (BonoboUIHandler *uih, void *user_data, - const char *path) -{ - MessageList *ml = user_data; - - threaded_view = bonobo_ui_handler_menu_get_toggle_state (uih, path); - message_list_regenerate (ml, ml->search); -} diff --git a/mail/message-list.h b/mail/message-list.h deleted file mode 100644 index 4406536110..0000000000 --- a/mail/message-list.h +++ /dev/null @@ -1,119 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -#ifndef _MESSAGE_LIST_H_ -#define _MESSAGE_LIST_H_ - -#include "mail-types.h" -#include <bonobo/bonobo-main.h> -#include <bonobo/bonobo-object.h> -#include <bonobo/bonobo-ui-handler.h> -#include "camel/camel-folder.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, -}; - -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); -void message_list_regenerate (MessageList *message_list, const char *search); -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 c35e39f470..0000000000 --- a/mail/message-thread.c +++ /dev/null @@ -1,589 +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" - -#define d(x) - -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; - - /* are we already the right parent? */ - if (child->parent == parent) - return; - - /* are we unparented? */ - if (child->parent == NULL) { - container_add_child(parent, child); - return; - } - - /* else remove child from its existing parent, and reparent */ - node = child->parent; - c = (struct _container *)&node->child; - d(printf("scanning children:\n")); - while (c->next) { - d(printf(" %p\n", c)); - if (c->next==child) { - d(printf("found node %p\n", child)); - c->next = c->next->next; - child->parent = NULL; - container_add_child(parent, child); - return; - } - c = c->next; - } - - printf("DAMN, we shouldn't be here!\n"); -} - -static void -prune_empty(struct _container **cp) -{ - struct _container *child, *next, *c, *lastc; - - /* yes, this is intentional */ - lastc = (struct _container *)cp; - while (lastc->next) { - c = lastc->next; - - d(printf("checking message %p %p (%s)\n", c, - c->message, c->message?c->message->message_id:"<empty>")); - if (c->message == NULL) { - if (c->child == NULL) { - d(printf("removing empty node\n")); - lastc->next = c->next; - continue; - } - if (c->parent || c->child->next==0) { - d(printf("promoting child\n")); - lastc->next = c->next; /* remove us */ - child = c->child; - while (child) { - next = child->next; - - child->parent = c->parent; - child->next = lastc->next; - lastc->next = child; - - child = next; - } - continue; - } - } - prune_empty(&c->child); - lastc = c; - } -} - -static void -hashloop(void *key, void *value, void *data) -{ - struct _container *c = value; - struct _container *tail = data; - - if (c->parent == NULL) { - c->next = tail->next; - tail->next = c; - } -} - -static char * -get_root_subject(struct _container *c, int *re) -{ - char *s, *p; - struct _container *scan; - - s = NULL; - *re = FALSE; - if (c->message) - s = c->message->subject; - else { - /* one of the children will always have a message */ - scan = c->child; - while (scan) { - if (scan->message) { - s = scan->message->subject; - break; - } - scan = scan->next; - } - } - if (s != NULL) { - while (*s) { - while (isspace(*s)) - s++; - if (s[0] == 0) - break; - if ((s[0] == 'r' || s[0]=='R') - && (s[1] == 'e' || s[1]=='E')) { - p = s+2; - while (isdigit(*p) || (ispunct(*p) && (*p != ':'))) - p++; - if (*p==':') { - *re = TRUE; - s = p+1; - } else - break; - } else - break; - } - if (*s) - return s; - } - return NULL; -} - -/* this 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 = g_malloc0(sizeof(*scan)); - scan->root_subject = c->root_subject; - scan->re = c->re && container->re; - scan->next = c->next; - clast->next = scan; - container_add_child(scan, c); - container_add_child(scan, container); - clast = scan; - g_hash_table_insert(subject_table, scan->root_subject, scan); - continue; - } - } - clast = c; - } - g_hash_table_destroy(subject_table); -} - -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; -} - -void thread_messages_free(struct _container *c) -{ - struct _container *n; - - return; - - /* 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 */ - g_free(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; -} - -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; - mi = camel_folder_get_message_info (folder, uids->pdata[i]); - - if (mi == NULL) { - g_warning("Folder doesn't contain uid %s", 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 = g_malloc0(sizeof(*c)); - g_hash_table_insert(id_table, mi->message_id, c); - } - } else { - d(printf("doing : (no message id)\n")); - c = g_malloc0(sizeof(*c)); - g_hash_table_insert(no_id_table, 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 = g_malloc0(sizeof(*c)); - g_hash_table_insert(id_table, ref->id, c); - } - if (c!=child) - container_parent_child(c, child); - child = c; - if (head == NULL) - head = c; - ref = ref->next; - } - } - - d(printf("\n\n")); - /* build a list of root messages (no parent) */ - head = NULL; - g_hash_table_foreach(id_table, hashloop, &head); - g_hash_table_foreach(no_id_table, hashloop, &head); - - g_hash_table_destroy(id_table); - g_hash_table_destroy(no_id_table); - - /* remove empty parent nodes */ - prune_empty(&head); - - /* find any siblings which missed out */ - group_root_set(&head); - -#if 0 - printf("finished\n"); - i = dump_tree(head, 0); - printf("%d count, %d items in tree\n", uids->len, i); -#endif - - sort_thread(&head); - return head; -} - -#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, ex); - 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 d66baacbdd..0000000000 --- a/mail/message-thread.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef _MESSAGE_THREAD_H -#define _MESSAGE_THREAD_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 */ -}; - -struct _container *thread_messages(CamelFolder *folder, GPtrArray *uids); -void thread_messages_free(struct _container *); - -/* for debug only */ -int dump_tree(struct _container *c, int depth); - -#endif /* !_MESSAGE_THREAD_H */ - diff --git a/mail/session.c b/mail/session.c deleted file mode 100644 index 7eaefd390c..0000000000 --- a/mail/session.c +++ /dev/null @@ -1,140 +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" -#include "e-util/e-setup.h" - -CamelSession *session; -GHashTable *passwords; - -/* FIXME: Will this ever be called in a non-async - * manner? Better hope not, cause if that happens - * we deadlock.... - */ - -#ifdef USE_BROKEN_THREADS -#define ASYNC_AUTH_CALLBACK -#endif - -#ifndef ASYNC_AUTH_CALLBACK -static void -request_callback (gchar *string, gpointer data) -{ - char **ans = data; - - if (string) - *ans = g_strdup(string); - else - *ans = NULL; -} -#endif - -char * -mail_request_dialog (const char *prompt, gboolean secret, const char *key) -{ -#ifndef ASYNC_AUTH_CALLBACK - GtkWidget *dialog; -#endif - - 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); - -#ifndef ASYNC_AUTH_CALLBACK - /* XXX parent window? */ - dialog = gnome_request_dialog (secret, prompt, NULL, 0, - request_callback, &ans, NULL); - if (!dialog) - return NULL; - if (gnome_dialog_run_and_close (GNOME_DIALOG (dialog)) == -1 || - ans == NULL) - return NULL; -#else - if (!mail_op_get_password (data, secret, &ans)) - return NULL; -#endif - - 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; - - if (!passwords) - passwords = g_hash_table_new (g_str_hash, g_str_equal); - - key = g_strdup_printf ("%s:%s", - camel_url_to_string (service->url, FALSE), - item); - - 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); - g_free (key); - - if (!ans) { - camel_exception_set (ex, CAMEL_EXCEPTION_USER_CANCEL, - "User canceled operation."); - } - - return ans; -} - -void -session_init (void) -{ - e_setup_base_dir (); - camel_init (); - - session = camel_session_new (auth_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 b9fb5bb0b2..0000000000 --- a/mail/test-thread.c +++ /dev/null @@ -1,153 +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" - -#ifdef ENABLE_BROKEN_THREADS - -static void op_1( gpointer userdata ); -static void op_2( gpointer userdata ); -static void op_3( gpointer userdata ); -static void op_4( gpointer userdata ); -static void op_5( gpointer userdata ); -static void done( gpointer userdata ); -static gboolean queue_ops( void ); - -static gboolean queue_ops( void ) -{ - int i; - gchar buf[32]; - - g_message( "Top of queue_ops" ); - - mail_operation_try( "The Crawling Progress Bar of Doom", op_1, done, "op1 finished" ); - mail_operation_try( "The Mysterious Message Setter", op_2, done, "op2 finished" ); - mail_operation_try( "The Error Dialog of No Return", op_3, done, "op3 finished" ); - - for( i = 0; i < 3; i++ ) { - sprintf( buf, "Queue Filler %d", i ); - mail_operation_try( buf, op_4, NULL, GINT_TO_POINTER( i ) ); - } - - g_message( "Waiting for finish..." ); - mail_operation_wait_for_finish(); - - g_message( "Ops done -- queue some more!" ); - - mail_operation_try( "Progress Bar Redux", op_1, NULL, NULL ); - - g_message( "Waiting for finish again..." ); - mail_operation_wait_for_finish(); - - g_message( "Ops done -- more, more!" ); - - mail_operation_try( "Dastardly Password Stealer", op_5, NULL, NULL ); - - for( i = 0; i < 3; i++ ) { - sprintf( buf, "Queue Filler %d", i ); - mail_operation_try( buf, op_4, NULL, GINT_TO_POINTER( i ) ); - } - - g_message( "Waiting for finish AGAIN..." ); - mail_operation_wait_for_finish(); - g_message( "Ops done again. Exiting 0" ); - gtk_exit( 0 ); - return FALSE; -} - -static void op_1( gpointer userdata ) -{ - 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 userdata ) -{ - 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 userdata ) -{ - 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 userdata ) -{ - mail_op_hide_progressbar(); - mail_op_set_message( "Filler # %d", GPOINTER_TO_INT( userdata ) ); - sleep( 1 ); -} - -static void op_5( gpointer userdata ) -{ - 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 userdata ) -{ - g_message( "Operation done: %s", (gchar *) userdata ); -} - -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; -} - -#else - -int main( int argc, char **argv ) -{ - g_message( "Threads aren't enabled, so they cannot be tested." ); - return 0; -} - -#endif |