From 9663037f6c0daaf03d74c88afb002a6bb33f222b Mon Sep 17 00:00:00 2001 From: Ettore Perazzoli Date: Wed, 17 Nov 1999 15:35:43 +0000 Subject: More work: - Fixed some Camel API naming issues. - Moved the message composer stuff to the `composer' directory. svn path=/trunk/; revision=1395 --- ChangeLog | 46 ++ Makefile.am | 9 +- camel/camel-data-wrapper.h | 2 +- camel/camel-folder-pt-proxy.h | 2 +- camel/camel-folder-summary.h | 2 +- camel/camel-folder.h | 2 +- camel/camel-medium.h | 2 +- camel/camel-mime-body-part.h | 2 +- camel/camel-mime-message.c | 2 +- camel/camel-mime-message.h | 8 +- camel/camel-mime-part.h | 2 +- camel/camel-multipart.h | 2 +- camel/camel-service.h | 2 +- camel/camel-session.h | 2 +- camel/camel-simple-data-wrapper-stream.c | 6 +- camel/camel-simple-data-wrapper-stream.h | 4 +- camel/camel-simple-data-wrapper.h | 2 +- camel/camel-store.h | 2 +- camel/camel-stream-buffered-fs.h | 2 +- camel/camel-stream-data-wrapper.c | 4 +- camel/camel-stream-data-wrapper.h | 4 +- camel/camel-stream-fs.h | 2 +- camel/camel-stream-mem.h | 2 +- camel/camel-stream.h | 2 +- composer/.cvsignore | 6 + composer/ChangeLog | 20 + composer/Makefile.am | 44 ++ composer/e-msg-composer-address-dialog.c | 660 ++++++++++++++++++++++++++ composer/e-msg-composer-address-dialog.glade | 575 +++++++++++++++++++++++ composer/e-msg-composer-address-dialog.h | 75 +++ composer/e-msg-composer-address-entry.c | 175 +++++++ composer/e-msg-composer-address-entry.h | 63 +++ composer/e-msg-composer-attachment-bar.c | 665 +++++++++++++++++++++++++++ composer/e-msg-composer-attachment-bar.h | 74 +++ composer/e-msg-composer-attachment.c | 480 +++++++++++++++++++ composer/e-msg-composer-attachment.glade | 290 ++++++++++++ composer/e-msg-composer-attachment.h | 72 +++ composer/e-msg-composer-hdrs.c | 355 ++++++++++++++ composer/e-msg-composer-hdrs.h | 80 ++++ composer/e-msg-composer.c | 564 +++++++++++++++++++++++ composer/e-msg-composer.glade | 587 +++++++++++++++++++++++ composer/e-msg-composer.h | 87 ++++ composer/main.c | 52 +++ configure.in | 1 + tests/test1.c | 18 +- tests/ui-tests/Makefile.am | 3 - widgets/ChangeLog | 19 + widgets/Makefile.am | 22 - widgets/e-msg-composer-address-dialog.c | 659 -------------------------- widgets/e-msg-composer-address-dialog.glade | 575 ----------------------- widgets/e-msg-composer-address-dialog.h | 75 --- widgets/e-msg-composer-address-entry.c | 175 ------- widgets/e-msg-composer-address-entry.h | 63 --- widgets/e-msg-composer-attachment-bar.c | 665 --------------------------- widgets/e-msg-composer-attachment-bar.h | 74 --- widgets/e-msg-composer-attachment.c | 480 ------------------- widgets/e-msg-composer-attachment.glade | 290 ------------ widgets/e-msg-composer-attachment.h | 72 --- widgets/e-msg-composer-hdrs.c | 355 -------------- widgets/e-msg-composer-hdrs.h | 80 ---- widgets/e-msg-composer.c | 564 ----------------------- widgets/e-msg-composer.glade | 587 ----------------------- widgets/e-msg-composer.h | 87 ---- widgets/e-table/ChangeLog | 19 + widgets/e-table/Makefile.am | 22 - 65 files changed, 5057 insertions(+), 4887 deletions(-) create mode 100644 composer/.cvsignore create mode 100644 composer/ChangeLog create mode 100644 composer/Makefile.am create mode 100644 composer/e-msg-composer-address-dialog.c create mode 100644 composer/e-msg-composer-address-dialog.glade create mode 100644 composer/e-msg-composer-address-dialog.h create mode 100644 composer/e-msg-composer-address-entry.c create mode 100644 composer/e-msg-composer-address-entry.h create mode 100644 composer/e-msg-composer-attachment-bar.c create mode 100644 composer/e-msg-composer-attachment-bar.h create mode 100644 composer/e-msg-composer-attachment.c create mode 100644 composer/e-msg-composer-attachment.glade create mode 100644 composer/e-msg-composer-attachment.h create mode 100644 composer/e-msg-composer-hdrs.c create mode 100644 composer/e-msg-composer-hdrs.h create mode 100644 composer/e-msg-composer.c create mode 100644 composer/e-msg-composer.glade create mode 100644 composer/e-msg-composer.h create mode 100644 composer/main.c delete mode 100644 widgets/e-msg-composer-address-dialog.c delete mode 100644 widgets/e-msg-composer-address-dialog.glade delete mode 100644 widgets/e-msg-composer-address-dialog.h delete mode 100644 widgets/e-msg-composer-address-entry.c delete mode 100644 widgets/e-msg-composer-address-entry.h delete mode 100644 widgets/e-msg-composer-attachment-bar.c delete mode 100644 widgets/e-msg-composer-attachment-bar.h delete mode 100644 widgets/e-msg-composer-attachment.c delete mode 100644 widgets/e-msg-composer-attachment.glade delete mode 100644 widgets/e-msg-composer-attachment.h delete mode 100644 widgets/e-msg-composer-hdrs.c delete mode 100644 widgets/e-msg-composer-hdrs.h delete mode 100644 widgets/e-msg-composer.c delete mode 100644 widgets/e-msg-composer.glade delete mode 100644 widgets/e-msg-composer.h diff --git a/ChangeLog b/ChangeLog index e0ed428fdb..18cfd0b918 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,49 @@ +1999-11-17 Ettore Perazzoli + + * camel/camel-mime-message.c (_write_to_stream): Removed extra ':' + in the `Mime-Version' header. + + * tests/ui-tests/msg-composer-test.c: Removed. + + * Makefile.am (SUBDIRS): Added `composer'. + + * configure.in: Create `composer/Makefile'. + + * camel/camel-simple-data-wrapper-stream.c + (camel_simple_data_wrapper_stream_construct): Updated accordingly. + (camel_simple_data_wrapper_stream_new): Updated accordingly. + * camel/camel-stream-data-wrapper.c + (camel_stream_data_wrapper_construct): Updated accordingly. + + * camel/camel-data-wrapper.h: Replaced `IS_CAMEL...()' type check + macro name with `CAMEL_IS...()'. + * camel/camel-folder-pt-proxy.h: Likewise. + * camel/camel-folder-summary.h: Likewise. + * camel/camel-folder.h: Likewise. + * camel/camel-medium.h: Likewise. + * camel/camel-mime-body-part.h: Likewise. + * camel/camel-mime-message.h: Likewise. + * camel/camel-mime-part.h: Likewise. + * camel/camel-multipart.h: Likewise. + * camel/camel-service.h: Likewise. + * camel/camel-session.h: Likewise. + * camel/camel-simple-data-wrapper-stream.h: Likewise. + * camel/camel-simple-data-wrapper.h: Likewise. + * camel/camel-store.h: Likewise. + * camel/camel-stream-buffered-fs.h: Likewise. + * camel/camel-stream-data-wrapper.h: Likewise. + * camel/camel-stream-fs.h: Likewise. + * camel/camel-stream-mem.h: Likewise. + * camel/camel-stream.h: Likewise. + + * tests/test1.c (main): Updated to match the `RECIPIENT_TYPE' + changes. + + * camel/camel-mime-message.h: Changed `RECIPIENT_TYPE_TO', + `RECIPIENT_TYPE_CC' and `RECIPIENT_TYPE_BCC' into + `CAMEL_RECIPIENT_TYPE_TO', `CAMEL_RECIPIENT_TYPE_CC' and + `CAMEL_RECIPIENT_TYPE_BCC', respectively. + 1999-11-17 Ettore Perazzoli * camel/camel-mime-message.c (_write_to_stream): Write diff --git a/Makefile.am b/Makefile.am index bba70a23da..280f2610c4 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,6 +1,9 @@ -SUBDIRS = po macros camel tests - - +SUBDIRS = \ + po \ + macros \ + camel \ + composer \ + tests dist-hook: for subdir in intl ; do \ diff --git a/camel/camel-data-wrapper.h b/camel/camel-data-wrapper.h index e5a97f0f78..7e8fb8c72c 100644 --- a/camel/camel-data-wrapper.h +++ b/camel/camel-data-wrapper.h @@ -44,7 +44,7 @@ extern "C" { #define CAMEL_DATA_WRAPPER_TYPE (camel_data_wrapper_get_type ()) #define CAMEL_DATA_WRAPPER(obj) (GTK_CHECK_CAST((obj), CAMEL_DATA_WRAPPER_TYPE, CamelDataWrapper)) #define CAMEL_DATA_WRAPPER_CLASS(k) (GTK_CHECK_CLASS_CAST ((k), CAMEL_DATA_WRAPPER_TYPE, CamelDataWrapperClass)) -#define IS_CAMEL_DATA_WRAPPER(o) (GTK_CHECK_TYPE((o), CAMEL_DATA_WRAPPER_TYPE)) +#define CAMEL_IS_DATA_WRAPPER(o) (GTK_CHECK_TYPE((o), CAMEL_DATA_WRAPPER_TYPE)) typedef struct diff --git a/camel/camel-folder-pt-proxy.h b/camel/camel-folder-pt-proxy.h index 0c8098490b..dd0d87c7d5 100644 --- a/camel/camel-folder-pt-proxy.h +++ b/camel/camel-folder-pt-proxy.h @@ -45,7 +45,7 @@ extern "C" { #define CAMEL_FOLDER_PT_PROXY_TYPE (camel_folder_pt_proxy_get_type ()) #define CAMEL_FOLDER_PT_PROXY(obj) (GTK_CHECK_CAST((obj), CAMEL_FOLDER_PT_PROXY_TYPE, CamelFolderPtProxy)) #define CAMEL_FOLDER_PT_PROXY_CLASS(k) (GTK_CHECK_CLASS_CAST ((k), CAMEL_FOLDER_PT_PROXY_TYPE, CamelFolderPtProxyClass)) -#define IS_CAMEL_FOLDER_PT_PROXY(o) (GTK_CHECK_TYPE((o), CAMEL_FOLDER_PT_PROXY_TYPE)) +#define CAMEL_IS_FOLDER_PT_PROXY(o) (GTK_CHECK_TYPE((o), CAMEL_FOLDER_PT_PROXY_TYPE)) typedef struct _CamelFolderPtProxy CamelFolderPtProxy; diff --git a/camel/camel-folder-summary.h b/camel/camel-folder-summary.h index 0b4e500c2b..bc8ea0be28 100644 --- a/camel/camel-folder-summary.h +++ b/camel/camel-folder-summary.h @@ -41,7 +41,7 @@ extern "C" { #define CAMEL_FOLDER_SUMMARY_TYPE (camel_folder_summary_get_type ()) #define CAMEL_FOLDER_SUMMARY(obj) (GTK_CHECK_CAST((obj), CAMEL_FOLDER_SUMMARY_TYPE, CamelFolderSummary)) #define CAMEL_FOLDER_SUMMARY_CLASS(k) (GTK_CHECK_CLASS_CAST ((k), CAMEL_FOLDER_SUMMARY_TYPE, CamelFolderSummaryClass)) -#define IS_CAMEL_FOLDER_SUMMARY(o) (GTK_CHECK_TYPE((o), CAMEL_FOLDER_SUMMARY_TYPE)) +#define CAMEL_IS_FOLDER_SUMMARY(o) (GTK_CHECK_TYPE((o), CAMEL_FOLDER_SUMMARY_TYPE)) typedef struct { gchar *name; diff --git a/camel/camel-folder.h b/camel/camel-folder.h index 0f2d210418..fcc84aaa04 100644 --- a/camel/camel-folder.h +++ b/camel/camel-folder.h @@ -46,7 +46,7 @@ typedef struct _CamelFolder CamelFolder; #define CAMEL_FOLDER_TYPE (camel_folder_get_type ()) #define CAMEL_FOLDER(obj) (GTK_CHECK_CAST((obj), CAMEL_FOLDER_TYPE, CamelFolder)) #define CAMEL_FOLDER_CLASS(k) (GTK_CHECK_CLASS_CAST ((k), CAMEL_FOLDER_TYPE, CamelFolderClass)) -#define IS_CAMEL_FOLDER(o) (GTK_CHECK_TYPE((o), CAMEL_FOLDER_TYPE)) +#define CAMEL_IS_FOLDER(o) (GTK_CHECK_TYPE((o), CAMEL_FOLDER_TYPE)) typedef enum { FOLDER_OPEN, diff --git a/camel/camel-medium.h b/camel/camel-medium.h index 33deb52a96..a75efed3c2 100644 --- a/camel/camel-medium.h +++ b/camel/camel-medium.h @@ -42,7 +42,7 @@ extern "C" { #define CAMEL_MEDIUM_TYPE (camel_medium_get_type ()) #define CAMEL_MEDIUM(obj) (GTK_CHECK_CAST((obj), CAMEL_MEDIUM_TYPE, CamelMedium)) #define CAMEL_MEDIUM_CLASS(k) (GTK_CHECK_CLASS_CAST ((k), CAMEL_MEDIUM_TYPE, CamelMediumClass)) -#define IS_CAMEL_MEDIUM(o) (GTK_CHECK_TYPE((o), CAMEL_MEDIUM_TYPE)) +#define CAMEL_IS_MEDIUM(o) (GTK_CHECK_TYPE((o), CAMEL_MEDIUM_TYPE)) typedef struct diff --git a/camel/camel-mime-body-part.h b/camel/camel-mime-body-part.h index 59537af35a..5835dd2ec1 100644 --- a/camel/camel-mime-body-part.h +++ b/camel/camel-mime-body-part.h @@ -45,7 +45,7 @@ typedef struct _CamelMimeBodyPart CamelMimeBodyPart; #define CAMEL_MIME_BODY_PART_TYPE (camel_mime_body_part_get_type ()) #define CAMEL_MIME_BODY_PART(obj) (GTK_CHECK_CAST((obj), CAMEL_MIME_BODY_PART_TYPE, CamelMimeBodyPart)) #define CAMEL_MIME_BODY_PART_CLASS(k) (GTK_CHECK_CLASS_CAST ((k), CAMEL_MIME_BODY_PART_TYPE, CamelMimeBodyPartClass)) -#define IS_CAMEL_MIME_BODY_PART(o) (GTK_CHECK_TYPE((o), CAMEL_MIME_BODY_PART_TYPE)) +#define CAMEL_IS_MIME_BODY_PART(o) (GTK_CHECK_TYPE((o), CAMEL_MIME_BODY_PART_TYPE)) struct _CamelMimeBodyPart diff --git a/camel/camel-mime-message.c b/camel/camel-mime-message.c index 4742dea638..8a5928c542 100644 --- a/camel/camel-mime-message.c +++ b/camel/camel-mime-message.c @@ -602,7 +602,7 @@ _write_to_stream (CamelDataWrapper *data_wrapper, CamelStream *stream) /* FIXME correct to do it here? */ CAMEL_LOG_FULL_DEBUG ( "CamelMimeMessage:: Writing \"Mime-Version\"\n"); - WHPT (stream, "Mime-Version:", "1.0"); + WHPT (stream, "Mime-Version", "1.0"); CAMEL_DATA_WRAPPER_CLASS (parent_class)->write_to_stream (data_wrapper, stream); diff --git a/camel/camel-mime-message.h b/camel/camel-mime-message.h index 4b5bf39b25..e233f99899 100644 --- a/camel/camel-mime-message.h +++ b/camel/camel-mime-message.h @@ -43,15 +43,15 @@ typedef struct _CamelMimeMessage CamelMimeMessage; #include "camel-recipient.h" -#define RECIPIENT_TYPE_TO "To" -#define RECIPIENT_TYPE_CC "Cc" -#define RECIPIENT_TYPE_BCC "Bcc" +#define CAMEL_RECIPIENT_TYPE_TO "To" +#define CAMEL_RECIPIENT_TYPE_CC "Cc" +#define CAMEL_RECIPIENT_TYPE_BCC "Bcc" #define CAMEL_MIME_MESSAGE_TYPE (camel_mime_message_get_type ()) #define CAMEL_MIME_MESSAGE(obj) (GTK_CHECK_CAST((obj), CAMEL_MIME_MESSAGE_TYPE, CamelMimeMessage)) #define CAMEL_MIME_MESSAGE_CLASS(k) (GTK_CHECK_CLASS_CAST ((k), CAMEL_MIME_MESSAGE_TYPE, CamelMimeMessageClass)) -#define IS_CAMEL_MIME_MESSAGE(o) (GTK_CHECK_TYPE((o), CAMEL_MIME_MESSAGE_TYPE)) +#define CAMEL_IS_MIME_MESSAGE(o) (GTK_CHECK_TYPE((o), CAMEL_MIME_MESSAGE_TYPE)) diff --git a/camel/camel-mime-part.h b/camel/camel-mime-part.h index 375d4aa0e3..b7da6f109b 100644 --- a/camel/camel-mime-part.h +++ b/camel/camel-mime-part.h @@ -42,7 +42,7 @@ extern "C" { #define CAMEL_MIME_PART_TYPE (camel_mime_part_get_type ()) #define CAMEL_MIME_PART(obj) (GTK_CHECK_CAST((obj), CAMEL_MIME_PART_TYPE, CamelMimePart)) #define CAMEL_MIME_PART_CLASS(k) (GTK_CHECK_CLASS_CAST ((k), CAMEL_MIME_PART_TYPE, CamelMimePartClass)) -#define IS_CAMEL_MIME_PART(o) (GTK_CHECK_TYPE((o), CAMEL_MIME_PART_TYPE)) +#define CAMEL_IS_MIME_PART(o) (GTK_CHECK_TYPE((o), CAMEL_MIME_PART_TYPE)) enum _CamelMimePartEncodingType { diff --git a/camel/camel-multipart.h b/camel/camel-multipart.h index a207db60cd..b53d8af4f2 100644 --- a/camel/camel-multipart.h +++ b/camel/camel-multipart.h @@ -44,7 +44,7 @@ typedef struct _CamelMultipart CamelMultipart; #define CAMEL_MULTIPART_TYPE (camel_multipart_get_type ()) #define CAMEL_MULTIPART(obj) (GTK_CHECK_CAST((obj), CAMEL_MULTIPART_TYPE, CamelMultipart)) #define CAMEL_MULTIPART_CLASS(k) (GTK_CHECK_CLASS_CAST ((k), CAMEL_MULTIPART_TYPE, CamelMultipartClass)) -#define IS_CAMEL_MULTIPART(o) (GTK_CHECK_TYPE((o), CAMEL_MULTIPART_TYPE)) +#define CAMEL_IS_MULTIPART(o) (GTK_CHECK_TYPE((o), CAMEL_MULTIPART_TYPE)) struct _CamelMultipart diff --git a/camel/camel-service.h b/camel/camel-service.h index 043c7b7203..4849273226 100644 --- a/camel/camel-service.h +++ b/camel/camel-service.h @@ -39,7 +39,7 @@ extern "C" { #define CAMEL_SERVICE_TYPE (camel_service_get_type ()) #define CAMEL_SERVICE(obj) (GTK_CHECK_CAST((obj), CAMEL_SERVICE_TYPE, CamelService)) #define CAMEL_SERVICE_CLASS(k) (GTK_CHECK_CLASS_CAST ((k), CAMEL_SERVICE_TYPE, CamelServiceClass)) -#define IS_CAMEL_SERVICE(o) (GTK_CHECK_TYPE((o), CAMEL_SERVICE_TYPE)) +#define CAMEL_IS_SERVICE(o) (GTK_CHECK_TYPE((o), CAMEL_SERVICE_TYPE)) diff --git a/camel/camel-session.h b/camel/camel-session.h index 3e7b09877b..0b40e71dd7 100644 --- a/camel/camel-session.h +++ b/camel/camel-session.h @@ -44,7 +44,7 @@ typedef struct _CamelSession CamelSession; #define CAMEL_SESSION_TYPE (camel_session_get_type ()) #define CAMEL_SESSION(obj) (GTK_CHECK_CAST((obj), CAMEL_SESSION_TYPE, CamelSession)) #define CAMEL_SESSION_CLASS(k) (GTK_CHECK_CLASS_CAST ((k), CAMEL_SESSION_TYPE, CamelSessionClass)) -#define IS_CAMEL_SESSION(o) (GTK_CHECK_TYPE((o), CAMEL_SESSION_TYPE)) +#define CAMEL_IS_SESSION(o) (GTK_CHECK_TYPE((o), CAMEL_SESSION_TYPE)) diff --git a/camel/camel-simple-data-wrapper-stream.c b/camel/camel-simple-data-wrapper-stream.c index 8c45c7530d..e9d4ebe8ad 100644 --- a/camel/camel-simple-data-wrapper-stream.c +++ b/camel/camel-simple-data-wrapper-stream.c @@ -249,9 +249,9 @@ camel_simple_data_wrapper_stream_construct (CamelSimpleDataWrapperStream *stream CamelSimpleDataWrapper *wrapper) { g_return_if_fail (stream != NULL); - g_return_if_fail (IS_CAMEL_SIMPLE_DATA_WRAPPER_STREAM (stream)); + g_return_if_fail (CAMEL_IS_SIMPLE_DATA_WRAPPER_STREAM (stream)); g_return_if_fail (wrapper != NULL); - g_return_if_fail (IS_CAMEL_SIMPLE_DATA_WRAPPER (wrapper)); + g_return_if_fail (CAMEL_IS_SIMPLE_DATA_WRAPPER (wrapper)); gtk_object_ref (GTK_OBJECT (wrapper)); stream->wrapper = wrapper; @@ -265,7 +265,7 @@ camel_simple_data_wrapper_stream_new (CamelSimpleDataWrapper *wrapper) CamelStream *stream; g_return_val_if_fail (wrapper != NULL, NULL); - g_return_val_if_fail (IS_CAMEL_SIMPLE_DATA_WRAPPER (wrapper), NULL); + g_return_val_if_fail (CAMEL_IS_SIMPLE_DATA_WRAPPER (wrapper), NULL); stream = gtk_type_new (camel_simple_data_wrapper_stream_get_type ()); diff --git a/camel/camel-simple-data-wrapper-stream.h b/camel/camel-simple-data-wrapper-stream.h index ee24fd71d3..bdb6741693 100644 --- a/camel/camel-simple-data-wrapper-stream.h +++ b/camel/camel-simple-data-wrapper-stream.h @@ -43,9 +43,9 @@ extern "C" { (GTK_CHECK_CAST ((obj), CAMEL_TYPE_SIMPLE_DATA_WRAPPER_STREAM, CamelSimpleDataWrapperStream)) #define CAMEL_SIMPLE_DATA_WRAPPER_STREAM_CLASS(klass) \ (GTK_CHECK_CLASS_CAST ((klass), CAMEL_TYPE_SIMPLE_DATA_WRAPPER_STREAM, CamelSimpleDataWrapperStreamClass)) -#define IS_CAMEL_SIMPLE_DATA_WRAPPER_STREAM(obj) \ +#define CAMEL_IS_SIMPLE_DATA_WRAPPER_STREAM(obj) \ (GTK_CHECK_TYPE ((obj), CAMEL_TYPE_SIMPLE_DATA_WRAPPER_STREAM)) -#define IS_CAMEL_SIMPLE_DATA_WRAPPER_STREAM_CLASS(klass) \ +#define CAMEL_IS_SIMPLE_DATA_WRAPPER_STREAM_CLASS(klass) \ (GTK_CHECK_CLASS_TYPE ((obj), CAMEL_TYPE_SIMPLE_DATA_WRAPPER_STREAM)) diff --git a/camel/camel-simple-data-wrapper.h b/camel/camel-simple-data-wrapper.h index b3be850f9d..335f512213 100644 --- a/camel/camel-simple-data-wrapper.h +++ b/camel/camel-simple-data-wrapper.h @@ -45,7 +45,7 @@ extern "C" { #define CAMEL_SIMPLE_DATA_WRAPPER_TYPE (camel_simple_data_wrapper_get_type ()) #define CAMEL_SIMPLE_DATA_WRAPPER(obj) (GTK_CHECK_CAST((obj), CAMEL_SIMPLE_DATA_WRAPPER_TYPE, CamelSimpleDataWrapper)) #define CAMEL_SIMPLE_DATA_WRAPPER_CLASS(k) (GTK_CHECK_CLASS_CAST ((k), CAMEL_SIMPLE_DATA_WRAPPER_TYPE, CamelSimpleDataWrapperClass)) -#define IS_CAMEL_SIMPLE_DATA_WRAPPER(o) (GTK_CHECK_TYPE((o), CAMEL_SIMPLE_DATA_WRAPPER_TYPE)) +#define CAMEL_IS_SIMPLE_DATA_WRAPPER(o) (GTK_CHECK_TYPE((o), CAMEL_SIMPLE_DATA_WRAPPER_TYPE)) typedef struct diff --git a/camel/camel-store.h b/camel/camel-store.h index da6c085139..05a5909501 100644 --- a/camel/camel-store.h +++ b/camel/camel-store.h @@ -45,7 +45,7 @@ typedef struct _CamelStore CamelStore; #define CAMEL_STORE_TYPE (camel_store_get_type ()) #define CAMEL_STORE(obj) (GTK_CHECK_CAST((obj), CAMEL_STORE_TYPE, CamelStore)) #define CAMEL_STORE_CLASS(k) (GTK_CHECK_CLASS_CAST ((k), CAMEL_STORE_TYPE, CamelStoreClass)) -#define IS_CAMEL_STORE(o) (GTK_CHECK_TYPE((o), CAMEL_STORE_TYPE)) +#define CAMEL_IS_STORE(o) (GTK_CHECK_TYPE((o), CAMEL_STORE_TYPE)) struct _CamelStore diff --git a/camel/camel-stream-buffered-fs.h b/camel/camel-stream-buffered-fs.h index c11edabf19..65a64b4340 100644 --- a/camel/camel-stream-buffered-fs.h +++ b/camel/camel-stream-buffered-fs.h @@ -41,7 +41,7 @@ extern "C" { #define CAMEL_STREAM_BUFFERED_FS_TYPE (camel_stream_buffered_fs_get_type ()) #define CAMEL_STREAM_BUFFERED_FS(obj) (GTK_CHECK_CAST((obj), CAMEL_STREAM_BUFFERED_FS_TYPE, CamelStreamBufferedFs)) #define CAMEL_STREAM_BUFFERED_FS_CLASS(k) (GTK_CHECK_CLASS_CAST ((k), CAMEL_STREAM_BUFFERED_FS_TYPE, CamelStreamBufferedFsClass)) -#define IS_CAMEL_STREAM_BUFFERED_FS(o) (GTK_CHECK_TYPE((o), CAMEL_STREAM_BUFFERED_FS_TYPE)) +#define CAMEL_IS_STREAM_BUFFERED_FS(o) (GTK_CHECK_TYPE((o), CAMEL_STREAM_BUFFERED_FS_TYPE)) typedef enum { diff --git a/camel/camel-stream-data-wrapper.c b/camel/camel-stream-data-wrapper.c index 564571cf09..38ac8d92c1 100644 --- a/camel/camel-stream-data-wrapper.c +++ b/camel/camel-stream-data-wrapper.c @@ -177,9 +177,9 @@ camel_stream_data_wrapper_construct (CamelStreamDataWrapper *wrapper, CamelStream *stream) { g_return_if_fail (wrapper != NULL); - g_return_if_fail (IS_CAMEL_STREAM_DATA_WRAPPER (wrapper)); + g_return_if_fail (CAMEL_IS_STREAM_DATA_WRAPPER (wrapper)); g_return_if_fail (stream != NULL); - g_return_if_fail (IS_CAMEL_STREAM (stream)); + g_return_if_fail (CAMEL_IS_STREAM (stream)); wrapper->stream = stream; gtk_signal_connect (GTK_OBJECT (stream), "destroy", diff --git a/camel/camel-stream-data-wrapper.h b/camel/camel-stream-data-wrapper.h index 3f972a99f9..b804f748d7 100644 --- a/camel/camel-stream-data-wrapper.h +++ b/camel/camel-stream-data-wrapper.h @@ -43,9 +43,9 @@ extern "C" { (GTK_CHECK_CAST ((obj), CAMEL_TYPE_STREAM_DATA_WRAPPER, CamelStreamDataWrapper)) #define CAMEL_STREAM_DATA_WRAPPER_CLASS(klass) \ (GTK_CHECK_CLASS_CAST ((klass), CAMEL_TYPE_STREAM_DATA_WRAPPER, CamelStreamDataWrapperClass)) -#define IS_CAMEL_STREAM_DATA_WRAPPER(obj) \ +#define CAMEL_IS_STREAM_DATA_WRAPPER(obj) \ (GTK_CHECK_TYPE ((obj), CAMEL_TYPE_STREAM_DATA_WRAPPER)) -#define IS_CAMEL_STREAM_DATA_WRAPPER_CLASS(klass) \ +#define CAMEL_IS_STREAM_DATA_WRAPPER_CLASS(klass) \ (GTK_CHECK_CLASS_TYPE ((obj), CAMEL_TYPE_STREAM_DATA_WRAPPER)) diff --git a/camel/camel-stream-fs.h b/camel/camel-stream-fs.h index 2f33d046b3..3f27cc5bc0 100644 --- a/camel/camel-stream-fs.h +++ b/camel/camel-stream-fs.h @@ -41,7 +41,7 @@ extern "C" { #define CAMEL_STREAM_FS_TYPE (camel_stream_fs_get_type ()) #define CAMEL_STREAM_FS(obj) (GTK_CHECK_CAST((obj), CAMEL_STREAM_FS_TYPE, CamelStreamFs)) #define CAMEL_STREAM_FS_CLASS(k) (GTK_CHECK_CLASS_CAST ((k), CAMEL_STREAM_FS_TYPE, CamelStreamFsClass)) -#define IS_CAMEL_STREAM_FS(o) (GTK_CHECK_TYPE((o), CAMEL_STREAM_FS_TYPE)) +#define CAMEL_IS_STREAM_FS(o) (GTK_CHECK_TYPE((o), CAMEL_STREAM_FS_TYPE)) typedef enum { diff --git a/camel/camel-stream-mem.h b/camel/camel-stream-mem.h index 1f1d2f5d25..d5d314d42d 100644 --- a/camel/camel-stream-mem.h +++ b/camel/camel-stream-mem.h @@ -41,7 +41,7 @@ extern "C" { #define CAMEL_STREAM_MEM_TYPE (camel_stream_mem_get_type ()) #define CAMEL_STREAM_MEM(obj) (GTK_CHECK_CAST((obj), CAMEL_STREAM_MEM_TYPE, CamelStreamMem)) #define CAMEL_STREAM_MEM_CLASS(k) (GTK_CHECK_CLASS_CAST ((k), CAMEL_STREAM_MEM_TYPE, CamelStreamMemClass)) -#define IS_CAMEL_STREAM_MEM(o) (GTK_CHECK_TYPE((o), CAMEL_STREAM_MEM_TYPE)) +#define CAMEL_IS_STREAM_MEM(o) (GTK_CHECK_TYPE((o), CAMEL_STREAM_MEM_TYPE)) typedef enum { diff --git a/camel/camel-stream.h b/camel/camel-stream.h index bf63ada5d4..be2c0d2988 100644 --- a/camel/camel-stream.h +++ b/camel/camel-stream.h @@ -39,7 +39,7 @@ extern "C" { #define CAMEL_STREAM_TYPE (camel_stream_get_type ()) #define CAMEL_STREAM(obj) (GTK_CHECK_CAST((obj), CAMEL_STREAM_TYPE, CamelStream)) #define CAMEL_STREAM_CLASS(k) (GTK_CHECK_CLASS_CAST ((k), CAMEL_STREAM_TYPE, CamelStreamClass)) -#define IS_CAMEL_STREAM(o) (GTK_CHECK_TYPE((o), CAMEL_STREAM_TYPE)) +#define CAMEL_IS_STREAM(o) (GTK_CHECK_TYPE((o), CAMEL_STREAM_TYPE)) typedef enum { diff --git a/composer/.cvsignore b/composer/.cvsignore new file mode 100644 index 0000000000..09980ae6ba --- /dev/null +++ b/composer/.cvsignore @@ -0,0 +1,6 @@ +.deps +.libs +Makefile +Makefile.in +*.lo +*.la diff --git a/composer/ChangeLog b/composer/ChangeLog new file mode 100644 index 0000000000..744d633eae --- /dev/null +++ b/composer/ChangeLog @@ -0,0 +1,20 @@ +1999-11-17 Ettore Perazzoli + + * Makefile.am: New Makefile to compile the message composer + executable. + + * main.c: New file. + + * e-msg-composer-hdrs.c (e_msg_composer_hdrs_to_message): Use + `CAMEL_RECIPIENT*' macros instead of the old `RECIPIENT*' ones + that do not exist anymore. + + * e-msg-composer-address-dialog.c + (e_msg_composer_address_dialog_construct): Use `E_GLADEDIR' + instead of `E_GUIDIR'. + * e-msg-composer-attachment.c (e_msg_composer_attachment_edit): + Likewise. + * e-msg-composer.c (e_msg_composer_construct): Likewise. + +(See `$(top_srcdir)/widgets/ChangeLog' for previous changes to the +message composer.) diff --git a/composer/Makefile.am b/composer/Makefile.am new file mode 100644 index 0000000000..fe924bc9e3 --- /dev/null +++ b/composer/Makefile.am @@ -0,0 +1,44 @@ +gladedir = $(datadir)/evolution/glade + +glade_DATA = \ + e-msg-composer-address-dialog.glade \ + e-msg-composer-attachment.glade \ + e-msg-composer.glade + +INCLUDES = \ + -I$(top_srcdir)/camel \ + -I$(top_builddir)/camel \ + $(GNOME_INCLUDEDIR) + +CPPFLAGS = \ + -DE_GLADEDIR=\"$(gladedir)\" + +bin_PROGRAMS = \ + evolution-msg-composer + +evolution_msg_composer_SOURCES = \ + e-msg-composer-address-dialog.c \ + e-msg-composer-address-dialog.h \ + e-msg-composer-address-entry.c \ + e-msg-composer-address-entry.h \ + e-msg-composer-attachment-bar.c \ + e-msg-composer-attachment-bar.h \ + e-msg-composer-attachment.c \ + e-msg-composer-attachment.h \ + e-msg-composer-hdrs.c \ + e-msg-composer-hdrs.h \ + e-msg-composer.c \ + e-msg-composer.h \ + main.c + +evolution_msg_composer_LDADD = \ + $(top_builddir)/camel/libcamel.la \ + $(GNOME_LIBDIR) \ + $(GNOMEUI_LIBS) \ + $(INTLLIBS) \ + $(PTHREAD_LIB) \ + $(EXTRA_GNOME_LIBS) + + +EXTRA_DIST = \ + ChangeLog diff --git a/composer/e-msg-composer-address-dialog.c b/composer/e-msg-composer-address-dialog.c new file mode 100644 index 0000000000..42a594756d --- /dev/null +++ b/composer/e-msg-composer-address-dialog.c @@ -0,0 +1,660 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* e-msg-composer-address-dialog.c + * + * Copyright (C) 1999 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 + */ + +#include +#include "e-msg-composer-address-dialog.h" + + +enum { + APPLY, + LAST_SIGNAL +}; +static guint signals[LAST_SIGNAL] = { 0 }; + +static GnomeDialogClass *parent_class = NULL; + + +/* This function should load the addresses we know of into the dialog. We + don't have a precise setup for the addressbook yet, so we will just put some + fake entries in. */ +static void +load_addresses (EMsgComposerAddressDialog *dialog) +{ + gchar *text[][3] = { + { "Bertrand Guiheneuf", "Bertrand.Guiheneuf@aful.org", NULL }, + { "Ettore Perazzoli", "ettore@gnu.org", NULL }, + { "Miguel de Icaza", "miguel@gnu.org", NULL }, + { "Nat Friedman", "nat@nat.org", NULL }, + { NULL, NULL, NULL } + }; + GtkCList *clist; + guint i; + + clist = GTK_CLIST (glade_xml_get_widget (dialog->gui, "address_clist")); + + for (i = 0; text[i][0] != NULL; i++) + gtk_clist_append (clist, text[i]); +} + +/* Combine name and email into an address, e.g. "Ettore Perazzoli + ". FIXME FIXME FIXME this does not handle quoting (commas + will cause troubles), but it should. */ +static gchar * +make_full_address (const gchar *name, + const gchar *email) +{ + return g_strconcat (name, " <", email, ">", NULL); +} + +/* This loads the selected address in the address GtkCList into the requested + GtkList. */ +static void +add_address (EMsgComposerAddressDialog *dialog, + const gchar *list_name) +{ + GtkCList *src_clist; + GtkCList *dest_clist; + gchar *name, *email; + gchar *text[2]; + guint row; + + src_clist = GTK_CLIST (glade_xml_get_widget (dialog->gui, + "address_clist")); + if (src_clist->selection == NULL) + return; + + dest_clist = GTK_CLIST (glade_xml_get_widget (dialog->gui, list_name)); + row = GPOINTER_TO_INT (src_clist->selection->data); + + gtk_clist_get_text (src_clist, row, 0, &name); + gtk_clist_get_text (src_clist, row, 1, &email); + + text[0] = make_full_address (name, email); + text[1] = NULL; + + gtk_clist_append (dest_clist, text); + + g_free (text[0]); +} + +static void +apply (EMsgComposerAddressDialog *dialog) +{ + gtk_signal_emit (GTK_OBJECT (dialog), signals[APPLY]); +} + + +/* Recipient list popup menu. */ + +struct _RecipientListInfo { + EMsgComposerAddressDialog *dialog; + GtkCList *clist; + gint row; /* -1 if menu was popped up in an empty + area. */ +}; +typedef struct _RecipientListInfo RecipientListInfo; + +static void +copy_recipient (RecipientListInfo *info, + gboolean remove) +{ + gchar *text; + gint row; + + if (info->clist->selection == NULL) + return; + + row = GPOINTER_TO_INT (info->clist->selection->data); + gtk_clist_get_text (info->clist, row, 0, &text); + + g_free (info->dialog->cut_buffer); + info->dialog->cut_buffer = g_strdup (text); + + if (remove) + gtk_clist_remove (info->clist, row); + + gtk_selection_owner_set (GTK_WIDGET (info->clist), + GDK_SELECTION_PRIMARY, + GDK_CURRENT_TIME); +} + +static void +copy_recipient_cb (GtkWidget *widget, + gpointer data) +{ + RecipientListInfo *info; + + info = (RecipientListInfo *) data; + copy_recipient (info, FALSE); + g_free (info); +} + +static void +cut_recipient_cb (GtkWidget *widget, + gpointer data) +{ + RecipientListInfo *info; + + info = (RecipientListInfo *) data; + copy_recipient (info, TRUE); + g_free (info); +} + +static void +paste_recipient_cb (GtkWidget *widget, + gpointer data) +{ + RecipientListInfo *info; + GdkAtom atom; + gchar *text[2]; + + info = (RecipientListInfo *) data; + + atom = gdk_atom_intern ("STRING", FALSE); + gtk_selection_convert (GTK_WIDGET (info->clist), + GDK_SELECTION_PRIMARY, + atom, + GDK_CURRENT_TIME); + + g_free (info); +} + +static GnomeUIInfo recipient_list_item_popup_info[] = { + GNOMEUIINFO_ITEM_STOCK (N_("Cut"), + N_("Cut selected item into clipboard"), + cut_recipient_cb, + GNOME_STOCK_MENU_CUT), + GNOMEUIINFO_ITEM_STOCK (N_("Copy"), + N_("Copy selected item into clipboard"), + copy_recipient_cb, + GNOME_STOCK_MENU_COPY), + GNOMEUIINFO_ITEM_STOCK (N_("Paste"), + N_("Paste item from clipboard"), + paste_recipient_cb, + GNOME_STOCK_MENU_PASTE), + GNOMEUIINFO_END +}; + +static GnomeUIInfo recipient_list_popup_info[] = { + GNOMEUIINFO_ITEM_STOCK (N_("Paste"), + N_("Paste item from clipboard"), + paste_recipient_cb, + GNOME_STOCK_MENU_PASTE), + GNOMEUIINFO_END +}; + + +/* Signals. */ + +static void +add_to_cb (GtkWidget *widget, + gpointer data) +{ + add_address (E_MSG_COMPOSER_ADDRESS_DIALOG (data), "to_clist"); +} + +static void +add_cc_cb (GtkWidget *widget, + gpointer data) +{ + add_address (E_MSG_COMPOSER_ADDRESS_DIALOG (data), "cc_clist"); +} + +static void +add_bcc_cb (GtkWidget *widget, + gpointer data) +{ + add_address (E_MSG_COMPOSER_ADDRESS_DIALOG (data), "bcc_clist"); +} + +static void +glade_connect (GladeXML *gui, + const gchar *widget_name, + const gchar *signal_name, + GtkSignalFunc callback, + gpointer callback_data) +{ + GtkWidget *widget; + + widget = glade_xml_get_widget (gui, widget_name); + if (widget == NULL) + g_warning ("Widget `%s' was not found.", widget_name); + else + gtk_signal_connect (GTK_OBJECT (widget), signal_name, + GTK_SIGNAL_FUNC (callback), callback_data); +} + +static gint +recipient_clist_button_press_cb (GtkWidget *widget, + GdkEventButton *event, + gpointer data) +{ + EMsgComposerAddressDialog *dialog; + RecipientListInfo *info; + GtkWidget *popup; + GtkCList *clist; + gboolean on_row; + gint row, column; + + dialog = E_MSG_COMPOSER_ADDRESS_DIALOG (data); + + clist = GTK_CLIST (widget); + + if (event->window != clist->clist_window || event->button != 3) + return FALSE; + + on_row = gtk_clist_get_selection_info (clist, event->x, event->y, + &row, &column); + + info = g_new (RecipientListInfo, 1); + info->dialog = dialog; + info->clist = clist; + + if (on_row) { + gtk_clist_unselect_all (clist); + gtk_clist_select_row (clist, row, 0); + info->row = row; + popup = gnome_popup_menu_new (recipient_list_item_popup_info); + } else { + info->row = -1; + popup = gnome_popup_menu_new (recipient_list_popup_info); + } + + gnome_popup_menu_do_popup_modal (popup, NULL, NULL, event, info); + + gtk_widget_destroy (popup); + + return TRUE; +} + +/* FIXME needs more work. */ +static void +recipient_clist_selection_received_cb (GtkWidget *widget, + GtkSelectionData *selection_data, + guint time, + gpointer data) +{ + GtkCList *clist; + gchar *text[2]; + gchar *p; + + puts (__FUNCTION__); + + if (selection_data->length < 0) + return; + + clist = GTK_CLIST (widget); + + /* FIXME quoting. */ + text[0] = g_strdup (selection_data->data); + text[1] = NULL; + + /* It is a common mistake to paste `\n's, let's work around that. */ + for (p = text[0]; *p != '\0'; p++) { + if (*p == '\n') { + *p = '\0'; + break; + } + } + + if (clist->selection != NULL) { + gint row; + + row = GPOINTER_TO_INT (clist->selection->data); + gtk_clist_insert (clist, row, text); + } else { + gtk_clist_append (clist, text); + } + + g_free (text[0]); +} + +static void +recipient_clist_selection_get_cb (GtkWidget *widget, + GtkSelectionData *selection_data, + guint info, + guint time, + gpointer data) +{ + EMsgComposerAddressDialog *dialog; + GdkAtom atom; + + puts (__FUNCTION__); + + dialog = E_MSG_COMPOSER_ADDRESS_DIALOG (data); + if (dialog->cut_buffer == NULL) + return; /* FIXME should I do something special? */ + + atom = gdk_atom_intern ("STRING", FALSE); + gtk_selection_data_set (selection_data, atom, 8, + dialog->cut_buffer, + strlen (dialog->cut_buffer)); +} + +static void +recipient_clist_selection_clear_event_cb (GtkWidget *widget, + GdkEventSelection *selection, + gpointer data) +{ + EMsgComposerAddressDialog *dialog; + + dialog = E_MSG_COMPOSER_ADDRESS_DIALOG (data); + g_free (dialog->cut_buffer); + dialog->cut_buffer = NULL; +} + +static void +setup_recipient_list_signals (EMsgComposerAddressDialog *dialog, + const gchar *name) +{ + glade_connect (dialog->gui, name, "button_press_event", + GTK_SIGNAL_FUNC (recipient_clist_button_press_cb), + dialog); + glade_connect (dialog->gui, name, "selection_received", + GTK_SIGNAL_FUNC (recipient_clist_selection_received_cb), + dialog); + glade_connect (dialog->gui, name, "selection_get", + GTK_SIGNAL_FUNC (recipient_clist_selection_get_cb), + dialog); + glade_connect (dialog->gui, name, "selection_clear_event", + GTK_SIGNAL_FUNC (recipient_clist_selection_clear_event_cb), + dialog); +} + +static void +setup_signals (EMsgComposerAddressDialog *dialog) +{ + glade_connect (dialog->gui, "to_add_button", "clicked", + GTK_SIGNAL_FUNC (add_to_cb), dialog); + glade_connect (dialog->gui, "cc_add_button", "clicked", + GTK_SIGNAL_FUNC (add_cc_cb), dialog); + glade_connect (dialog->gui, "bcc_add_button", "clicked", + GTK_SIGNAL_FUNC (add_bcc_cb), dialog); + + setup_recipient_list_signals (dialog, "to_clist"); + setup_recipient_list_signals (dialog, "cc_clist"); + setup_recipient_list_signals (dialog, "bcc_clist"); +} + + +static void +setup_selection_targets (EMsgComposerAddressDialog *dialog) +{ + gtk_selection_add_target (glade_xml_get_widget (dialog->gui, "to_clist"), + GDK_SELECTION_PRIMARY, + GDK_SELECTION_TYPE_STRING, 0); + gtk_selection_add_target (glade_xml_get_widget (dialog->gui, "cc_clist"), + GDK_SELECTION_PRIMARY, + GDK_SELECTION_TYPE_STRING, 0); + gtk_selection_add_target (glade_xml_get_widget (dialog->gui, "bcc_clist"), + GDK_SELECTION_PRIMARY, + GDK_SELECTION_TYPE_STRING, 0); +} + + +/* GnomeDialog methods. */ + +static void +clicked (GnomeDialog *dialog, + gint button_number) +{ + switch (button_number) { + case 0: /* OK */ + apply (E_MSG_COMPOSER_ADDRESS_DIALOG (dialog)); + gnome_dialog_close (dialog); + break; + case 1: /* Apply */ + apply (E_MSG_COMPOSER_ADDRESS_DIALOG (dialog)); + break; + case 2: /* Cancel */ + gnome_dialog_close (dialog); + break; + } +} + + +/* GtkObject methods. */ + +static void +destroy (GtkObject *object) +{ + EMsgComposerAddressDialog *dialog; + GtkCList *address_clist; + GList *p; + + dialog = E_MSG_COMPOSER_ADDRESS_DIALOG (object); + + gtk_object_unref (GTK_OBJECT (dialog->gui)); + g_free (dialog->cut_buffer); + + if (GTK_OBJECT_CLASS (parent_class)->destroy != NULL) + (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); +} + + +/* Initialization. */ + +static void +class_init (EMsgComposerAddressDialogClass *class) +{ + GtkObjectClass *object_class; + GnomeDialogClass *gnome_dialog_class; + + object_class = GTK_OBJECT_CLASS (class); + object_class->destroy = destroy; + + gnome_dialog_class = GNOME_DIALOG_CLASS (class); + gnome_dialog_class->clicked = clicked; + + parent_class = gtk_type_class (gnome_dialog_get_type ()); + + signals[APPLY] + = gtk_signal_new ("apply", + GTK_RUN_FIRST, + object_class->type, + GTK_SIGNAL_OFFSET (EMsgComposerAddressDialogClass, + apply), + gtk_marshal_NONE__NONE, + GTK_TYPE_NONE, 0); + + gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL); +} + +static void +init (EMsgComposerAddressDialog *dialog) +{ + dialog->gui = NULL; + dialog->cut_buffer = NULL; +} + + +GtkType +e_msg_composer_address_dialog_get_type (void) +{ + static GtkType type = 0; + + if (type == 0) { + static const GtkTypeInfo info = { + "EMsgComposerAddressDialog", + sizeof (EMsgComposerAddressDialog), + sizeof (EMsgComposerAddressDialogClass), + (GtkClassInitFunc) class_init, + (GtkObjectInitFunc) init, + /* reserved_1 */ NULL, + /* reserved_2 */ NULL, + (GtkClassInitFunc) NULL, + }; + + type = gtk_type_unique (gnome_dialog_get_type (), &info); + } + + return type; +} + +void +e_msg_composer_address_dialog_construct (EMsgComposerAddressDialog *dialog) +{ + static const gchar *buttons[] = { + GNOME_STOCK_BUTTON_OK, + GNOME_STOCK_BUTTON_APPLY, + GNOME_STOCK_BUTTON_CANCEL, + NULL + }; + + g_return_if_fail (dialog != NULL); + g_return_if_fail (E_IS_MSG_COMPOSER_ADDRESS_DIALOG (dialog)); + + gnome_dialog_constructv (GNOME_DIALOG (dialog), + _("Select recipients' addresses"), + buttons); + + dialog->gui = glade_xml_new + (E_GLADEDIR "/e-msg-composer-address-dialog.glade", + "main_table"); + if (dialog->gui == NULL) { + g_warning ("Cannot load `e-msg-composer-address-dialog.glade"); + return; + } + + gtk_container_add (GTK_CONTAINER (GNOME_DIALOG (dialog)->vbox), + glade_xml_get_widget (dialog->gui, "main_table")); + + setup_selection_targets (dialog); + load_addresses (dialog); + setup_signals (dialog); +} + +GtkWidget * +e_msg_composer_address_dialog_new (void) +{ + EMsgComposerAddressDialog *new; + + new = gtk_type_new (e_msg_composer_address_dialog_get_type ()); + e_msg_composer_address_dialog_construct (new); + + return GTK_WIDGET (new); +} + + +static void +set_list (EMsgComposerAddressDialog *dialog, + const gchar *list_name, + GList *list) +{ + GtkCList *clist; + GList *p; + gchar *text[2]; + + clist = GTK_CLIST (glade_xml_get_widget (dialog->gui, list_name)); + + gtk_clist_freeze (clist); + gtk_clist_clear (clist); + + text[1] = NULL; + for (p = list; p != NULL; p = p->next) { + text[0] = (gchar *) p->data; + gtk_clist_append (clist, text); + } + + gtk_clist_thaw (clist); +} + +void +e_msg_composer_address_dialog_set_to_list (EMsgComposerAddressDialog *dialog, + GList *to_list) +{ + g_return_if_fail (dialog != NULL); + g_return_if_fail (E_IS_MSG_COMPOSER_ADDRESS_DIALOG (dialog)); + + set_list (dialog, "to_clist", to_list); +} + +void +e_msg_composer_address_dialog_set_cc_list (EMsgComposerAddressDialog *dialog, + GList *cc_list) +{ + g_return_if_fail (dialog != NULL); + g_return_if_fail (E_IS_MSG_COMPOSER_ADDRESS_DIALOG (dialog)); + + set_list (dialog, "cc_clist", cc_list); +} + +void +e_msg_composer_address_dialog_set_bcc_list (EMsgComposerAddressDialog *dialog, + GList *bcc_list) +{ + g_return_if_fail (dialog != NULL); + g_return_if_fail (E_IS_MSG_COMPOSER_ADDRESS_DIALOG (dialog)); + + set_list (dialog, "bcc_clist", bcc_list); +} + + +static GList * +get_list (EMsgComposerAddressDialog *dialog, + const gchar *clist_name) +{ + GtkCList *address_clist; + GtkCList *clist; + GList *list; + guint i; + + clist = GTK_CLIST (glade_xml_get_widget (dialog->gui, clist_name)); + + list = NULL; + for (i = 0; i < clist->rows; i++) { + gchar *addr; + + gtk_clist_get_text (clist, i, 0, &addr); + list = g_list_prepend (list, g_strdup (addr)); + } + + return g_list_reverse (list); +} + +GList * +e_msg_composer_address_dialog_get_to_list (EMsgComposerAddressDialog *dialog) +{ + g_return_val_if_fail (dialog != NULL, NULL); + g_return_val_if_fail (E_IS_MSG_COMPOSER_ADDRESS_DIALOG (dialog), NULL); + + return get_list (dialog, "to_clist"); +} + +GList * +e_msg_composer_address_dialog_get_cc_list (EMsgComposerAddressDialog *dialog) +{ + g_return_val_if_fail (dialog != NULL, NULL); + g_return_val_if_fail (E_IS_MSG_COMPOSER_ADDRESS_DIALOG (dialog), NULL); + + return get_list (dialog, "cc_clist"); +} + +GList * +e_msg_composer_address_dialog_get_bcc_list (EMsgComposerAddressDialog *dialog) +{ + g_return_val_if_fail (dialog != NULL, NULL); + g_return_val_if_fail (E_IS_MSG_COMPOSER_ADDRESS_DIALOG (dialog), NULL); + + return get_list (dialog, "bcc_clist"); +} diff --git a/composer/e-msg-composer-address-dialog.glade b/composer/e-msg-composer-address-dialog.glade new file mode 100644 index 0000000000..2249c27daf --- /dev/null +++ b/composer/e-msg-composer-address-dialog.glade @@ -0,0 +1,575 @@ + + + + + address-composer + address-composer + + src + pixmaps + C + True + True + False + True + True + True + True + interface.c + interface.h + callbacks.c + callbacks.h + support.c + support.h + + + + + GnomeDialog + dialog1 + GTK_WINDOW_TOPLEVEL + GTK_WIN_POS_NONE + False + False + False + False + False + False + + + GtkVBox + GnomeDialog:vbox + dialog-vbox1 + False + 8 + + 4 + True + True + + + + GtkTable + main_table + 3 + 2 + False + 0 + 2 + + 0 + True + True + + + + GtkLabel + label3 + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + 1 + 2 + 2 + 3 + 0 + 0 + False + False + False + False + False + False + + + + + GtkLabel + label1 + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + 1 + 2 + 0 + 1 + 0 + 0 + True + True + False + False + True + True + + + + + GtkHBox + hbox1 + False + 5 + + 0 + 1 + 0 + 1 + 0 + 0 + False + False + False + False + False + False + + + + GtkLabel + label2 + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + 0 + False + False + + + + + GtkEntry + name_entry + True + True + True + 0 + + + 5 + True + True + + + + + GtkButton + search_button + 65 + True + + + 0 + False + False + + + + + + GtkScrolledWindow + scrolledwindow1 + GTK_POLICY_AUTOMATIC + GTK_POLICY_AUTOMATIC + GTK_UPDATE_CONTINUOUS + GTK_UPDATE_CONTINUOUS + + 0 + 1 + 1 + 2 + 0 + 5 + True + True + False + False + True + True + + + + GtkCList + address_clist + 180 + 200 + True + 2 + 128,107 + GTK_SELECTION_BROWSE + True + GTK_SHADOW_IN + + + GtkLabel + CList:title + label5 + 50 + + GTK_JUSTIFY_LEFT + False + 0.5 + 0.5 + 0 + 0 + + + + GtkLabel + CList:title + label6 + 100 + + GTK_JUSTIFY_LEFT + False + 0.5 + 0.5 + 0 + 0 + + + + + + GtkHBox + hbox2 + True + 10 + + 0 + 1 + 2 + 3 + 0 + 0 + False + False + False + False + True + True + + + + GtkButton + button5 + True + + + 0 + True + True + + + + + GtkButton + button6 + True + + + 0 + True + True + + + + + + GtkTable + table2 + 3 + 2 + False + 0 + 0 + + 1 + 2 + 1 + 2 + 0 + 5 + False + False + False + False + True + True + + + + GtkButton + to_add_button + 60 + True + + + 0 + 1 + 0 + 1 + 5 + 0 + True + True + False + False + True + False + + + + + GtkButton + cc_add_button + 60 + True + + + 0 + 1 + 1 + 2 + 5 + 0 + True + True + False + False + True + False + + + + + GtkButton + bcc_add_button + 60 + True + + + 0 + 1 + 2 + 3 + 5 + 0 + True + True + False + False + True + False + + + + + GtkScrolledWindow + scrolledwindow4 + GTK_POLICY_AUTOMATIC + GTK_POLICY_AUTOMATIC + GTK_UPDATE_CONTINUOUS + GTK_UPDATE_CONTINUOUS + + 1 + 2 + 2 + 3 + 2 + 0 + True + True + False + False + True + True + + + + GtkCList + bcc_clist + 180 + 100 + True + 1 + 80 + GTK_SELECTION_BROWSE + False + GTK_SHADOW_IN + + + GtkLabel + CList:title + label9 + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + + + + + GtkScrolledWindow + scrolledwindow2 + GTK_POLICY_AUTOMATIC + GTK_POLICY_AUTOMATIC + GTK_UPDATE_CONTINUOUS + GTK_UPDATE_CONTINUOUS + + 1 + 2 + 0 + 1 + 2 + 0 + True + True + False + False + True + True + + + + GtkCList + to_clist + 180 + 100 + True + 1 + 80 + GTK_SELECTION_BROWSE + False + GTK_SHADOW_IN + + + GtkLabel + CList:title + label7 + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + + + + + GtkScrolledWindow + scrolledwindow3 + GTK_POLICY_AUTOMATIC + GTK_POLICY_AUTOMATIC + GTK_UPDATE_CONTINUOUS + GTK_UPDATE_CONTINUOUS + + 1 + 2 + 1 + 2 + 2 + 4 + True + True + False + False + True + True + + + + GtkCList + cc_clist + 180 + 100 + True + 1 + 80 + GTK_SELECTION_BROWSE + False + GTK_SHADOW_IN + + + GtkLabel + CList:title + label8 + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + + + + + + + GtkHButtonBox + GnomeDialog:action_area + dialog-action_area1 + GTK_BUTTONBOX_END + 8 + 85 + 27 + 7 + 0 + + 0 + False + True + GTK_PACK_END + + + + GtkButton + button1 + True + True + True + GNOME_STOCK_BUTTON_OK + + + + GtkButton + button2 + True + True + GNOME_STOCK_BUTTON_APPLY + + + + GtkButton + button3 + True + True + GNOME_STOCK_BUTTON_CANCEL + + + + + + diff --git a/composer/e-msg-composer-address-dialog.h b/composer/e-msg-composer-address-dialog.h new file mode 100644 index 0000000000..19ffeda703 --- /dev/null +++ b/composer/e-msg-composer-address-dialog.h @@ -0,0 +1,75 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* e-msg-composer-address-dialog.h + * + * Copyright (C) 1999 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 __E_MSG_COMPOSER_ADDRESS_DIALOG_H__ +#define __E_MSG_COMPOSER_ADDRESS_DIALOG_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#pragma } +#endif /* __cplusplus */ + + +#define E_TYPE_MSG_COMPOSER_ADDRESS_DIALOG (e_msg_composer_address_dialog_get_type ()) +#define E_MSG_COMPOSER_ADDRESS_DIALOG(obj) (GTK_CHECK_CAST ((obj), E_TYPE_MSG_COMPOSER_ADDRESS_DIALOG, EMsgComposerAddressDialog)) +#define E_MSG_COMPOSER_ADDRESS_DIALOG_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_TYPE_MSG_COMPOSER_ADDRESS_DIALOG, EMsgComposerAddressDialogClass)) +#define E_IS_MSG_COMPOSER_ADDRESS_DIALOG(obj) (GTK_CHECK_TYPE ((obj), E_TYPE_MSG_COMPOSER_ADDRESS_DIALOG)) +#define E_IS_MSG_COMPOSER_ADDRESS_DIALOG_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), E_TYPE_MSG_COMPOSER_ADDRESS_DIALOG)) + + +typedef struct _EMsgComposerAddressDialog EMsgComposerAddressDialog; +typedef struct _EMsgComposerAddressDialogClass EMsgComposerAddressDialogClass; + +struct _EMsgComposerAddressDialog { + GnomeDialog parent; + + GladeXML *gui; + + gchar *cut_buffer; +}; + +struct _EMsgComposerAddressDialogClass { + GnomeDialogClass parent_class; + + void (* apply) (EMsgComposerAddressDialog *dialog); +}; + + +GtkType e_msg_composer_address_dialog_get_type (void); +GtkWidget *e_msg_composer_address_dialog_new (void); +void e_msg_composer_address_dialog_construct (EMsgComposerAddressDialog *dialog); +void e_msg_composer_address_dialog_set_to_list (EMsgComposerAddressDialog *dialog, GList *to_list); +void e_msg_composer_address_dialog_set_cc_list (EMsgComposerAddressDialog *dialog, GList *cc_list); +void e_msg_composer_address_dialog_set_bcc_list (EMsgComposerAddressDialog *dialog, GList *bcc_list); +GList *e_msg_composer_address_dialog_get_to_list (EMsgComposerAddressDialog *dialog); +GList *e_msg_composer_address_dialog_get_cc_list (EMsgComposerAddressDialog *dialog); +GList *e_msg_composer_address_dialog_get_bcc_list (EMsgComposerAddressDialog *dialog); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + +#endif /* __E_MSG_COMPOSER_ADDRESS_DIALOG_H__ */ diff --git a/composer/e-msg-composer-address-entry.c b/composer/e-msg-composer-address-entry.c new file mode 100644 index 0000000000..be63c815f5 --- /dev/null +++ b/composer/e-msg-composer-address-entry.c @@ -0,0 +1,175 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* e-msg-composer-address-entry.c + * + * Copyright (C) 1999 Helix Code, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: Ettore Perazzoli + */ + +/* This is a custom GtkEntry for entering address lists. For now, it does not + have any fancy features, but in the future we might want to make it + cooler. */ + +#include + +#include "e-msg-composer-address-entry.h" + + +static GtkEntryClass *parent_class = NULL; + + +/* Initialization. */ + +static void +class_init (EMsgComposerAddressEntryClass *klass) +{ + GtkObjectClass *object_class; + + object_class = (GtkObjectClass*) klass; + + parent_class = gtk_type_class (gtk_entry_get_type ()); +} + +static void +init (EMsgComposerAddressEntry *msg_composer_address_entry) +{ +} + +GtkType +e_msg_composer_address_entry_get_type (void) +{ + static GtkType type = 0; + + if (type == 0) { + static const GtkTypeInfo info = { + "EMsgComposerAddressEntry", + sizeof (EMsgComposerAddressEntry), + sizeof (EMsgComposerAddressEntryClass), + (GtkClassInitFunc) class_init, + (GtkObjectInitFunc) init, + /* reserved_1 */ NULL, + /* reserved_2 */ NULL, + (GtkClassInitFunc) NULL, + }; + + type = gtk_type_unique (gtk_entry_get_type (), &info); + } + + return type; +} + + +GtkWidget * +e_msg_composer_address_entry_new (void) +{ + GtkWidget *new; + + new = gtk_type_new (e_msg_composer_address_entry_get_type ()); + + return new; +} + + +/** + * e_msg_composer_address_entry_get_addresses: + * @entry: An address entry widget + * + * Retrieve the list of addresses stored in @entry. + * + * Return value: A GList of pointers to strings representing the addresses. + * Notice that the strings must be freed by the caller when not needed anymore. + **/ +GList * +e_msg_composer_address_entry_get_addresses (EMsgComposerAddressEntry *entry) +{ + GList *list; + const gchar *s; + const gchar *p, *oldp; + gboolean in_quotes; + + s = gtk_entry_get_text (GTK_ENTRY (entry)); + + in_quotes = FALSE; + list = NULL; + + p = s; + oldp = s; + + while (1) { + if (*p == '"') { + in_quotes = ! in_quotes; + p++; + } else if ((! in_quotes && *p == ',') || *p == 0) { + if (p != oldp) { + gchar *new_addr; + + new_addr = g_strndup (oldp, p - oldp); + new_addr = g_strstrip (new_addr); + if (*new_addr != '\0') + list = g_list_prepend (list, new_addr); + else + g_free (new_addr); + } + + while (*p == ',' || *p == ' ' || *p == '\t') + p++; + + if (*p == 0) + break; + + oldp = p; + } else { + p++; + } + } + + return g_list_reverse (list); +} + +/** + * e_msg_composer_address_entry_set_list: + * @entry: An address entry + * @list: List of pointers to strings representing the addresses that must + * appear in the entry + * + * Set the address list from @list. + **/ +void +e_msg_composer_address_entry_set_list (EMsgComposerAddressEntry *entry, + GList *list) +{ + GString *string; + GList *p; + + g_return_if_fail (entry != NULL); + + if (list == NULL) { + gtk_editable_delete_text (GTK_EDITABLE (entry), -1, -1); + return; + } + + string = g_string_new (NULL); + for (p = list; p != NULL; p = p->next) { + if (string->str[0] != '\0') + g_string_append (string, ", "); + g_string_append (string, p->data); + } + + gtk_entry_set_text (GTK_ENTRY (entry), string->str); + g_string_free (string, TRUE); +} diff --git a/composer/e-msg-composer-address-entry.h b/composer/e-msg-composer-address-entry.h new file mode 100644 index 0000000000..8e926272e4 --- /dev/null +++ b/composer/e-msg-composer-address-entry.h @@ -0,0 +1,63 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* e-msg-composer-address-entry.h + * + * Copyright (C) 1999 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 __E_MSG_COMPOSER_ADDRESS_ENTRY_H__ +#define __E_MSG_COMPOSER_ADDRESS_ENTRY_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#pragma } +#endif /* __cplusplus */ + +#define E_TYPE_MSG_COMPOSER_ADDRESS_ENTRY (e_msg_composer_address_entry_get_type ()) +#define E_MSG_COMPOSER_ADDRESS_ENTRY(obj) (GTK_CHECK_CAST ((obj), E_TYPE_MSG_COMPOSER_ADDRESS_ENTRY, EMsgComposerAddressEntry)) +#define E_MSG_COMPOSER_ADDRESS_ENTRY_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_TYPE_MSG_COMPOSER_ADDRESS_ENTRY, EMsgComposerAddressEntryClass)) +#define E_IS_MSG_COMPOSER_ADDRESS_ENTRY(obj) (GTK_CHECK_TYPE ((obj), E_TYPE_MSG_COMPOSER_ADDRESS_ENTRY)) +#define E_IS_MSG_COMPOSER_ADDRESS_ENTRY_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), E_TYPE_MSG_COMPOSER_ADDRESS_ENTRY)) + + +typedef struct _EMsgComposerAddressEntry EMsgComposerAddressEntry; +typedef struct _EMsgComposerAddressEntryClass EMsgComposerAddressEntryClass; + +struct _EMsgComposerAddressEntry { + GtkEntry parent; +}; + +struct _EMsgComposerAddressEntryClass { + GtkEntryClass parent_class; +}; + + +GtkType e_msg_composer_address_entry_get_type (void); +GtkWidget *e_msg_composer_address_entry_new (void); +GList *e_msg_composer_address_entry_get_addresses (EMsgComposerAddressEntry *entry); +void e_msg_composer_address_entry_set_list (EMsgComposerAddressEntry *entry, + GList *list); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __E_MSG_COMPOSER_ADDRESS_ENTRY_H__ */ diff --git a/composer/e-msg-composer-attachment-bar.c b/composer/e-msg-composer-attachment-bar.c new file mode 100644 index 0000000000..b55a4cbad4 --- /dev/null +++ b/composer/e-msg-composer-attachment-bar.c @@ -0,0 +1,665 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* e-msg-composer-attachment-bar.c + * + * Copyright (C) 1999 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 + */ + +#include +#include + +#include "e-msg-composer-attachment.h" +#include "e-msg-composer-attachment-bar.h" + + +#define ICON_WIDTH 64 +#define ICON_SEPARATORS " /-_" +#define ICON_SPACING 2 +#define ICON_ROW_SPACING ICON_SPACING +#define ICON_COL_SPACING ICON_SPACING +#define ICON_BORDER 2 +#define ICON_TEXT_SPACING 2 + + +static GnomeIconListClass *parent_class = NULL; + +struct _EMsgComposerAttachmentBarPrivate { + GList *attachments; + guint num_attachments; + + GtkWidget *context_menu; + GtkWidget *icon_context_menu; +}; + + +enum { + CHANGED, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + + +static void update (EMsgComposerAttachmentBar *bar); + + +static gchar * +size_to_string (gulong size) +{ + gchar *size_string; + + /* FIXME: The following should probably go into a separate module, as + we might have to do the same thing in other places as well. Also, + I am not sure this will be OK for all the languages. */ + + if (size < 1e3L) { + if (size == 1) + size_string = g_strdup (_("1 byte")); + else + size_string = g_strdup_printf (_("%u bytes"), + (guint) size); + } else { + gdouble displayed_size; + + if (size < 1e6L) { + displayed_size = (gdouble) size / 1.0e3; + size_string = g_strdup_printf (_("%.1fK"), + displayed_size); + } else if (size < 1e9L) { + displayed_size = (gdouble) size / 1.0e6; + size_string = g_strdup_printf (_("%.1fM"), + displayed_size); + } else { + displayed_size = (gdouble) size / 1.0e9; + size_string = g_strdup_printf (_("%.1fG"), + displayed_size); + } + } + + return size_string; +} + + +/* Sorting. */ + +static gint +attachment_sort_func (gconstpointer a, gconstpointer b) +{ + const EMsgComposerAttachment *attachment_a, *attachment_b; + + attachment_a = (EMsgComposerAttachment *) a; + attachment_b = (EMsgComposerAttachment *) b; + + return strcmp (attachment_a->description, attachment_b->description); +} + +static void +sort (EMsgComposerAttachmentBar *bar) +{ + EMsgComposerAttachmentBarPrivate *priv; + + priv = bar->priv; + + priv->attachments = g_list_sort (priv->attachments, + attachment_sort_func); +} + + +/* Attachment handling functions. */ + +static void +free_attachment_list (EMsgComposerAttachmentBar *bar) +{ + EMsgComposerAttachmentBarPrivate *priv; + GList *p; + + priv = bar->priv; + + for (p = priv->attachments; p != NULL; p = p->next) + gtk_object_unref (GTK_OBJECT (p->data)); +} + +static void +attachment_changed_cb (EMsgComposerAttachment *attachment, + gpointer data) +{ + update (E_MSG_COMPOSER_ATTACHMENT_BAR (data)); +} + +static void +add_from_file (EMsgComposerAttachmentBar *bar, + const gchar *file_name) +{ + EMsgComposerAttachment *attachment; + + attachment = e_msg_composer_attachment_new (file_name); + + gtk_signal_connect (GTK_OBJECT (attachment), "changed", + GTK_SIGNAL_FUNC (attachment_changed_cb), + bar); + + bar->priv->attachments = g_list_append (bar->priv->attachments, + attachment); + bar->priv->num_attachments++; + + sort (bar); + update (bar); + + gtk_signal_emit (GTK_OBJECT (bar), signals[CHANGED]); +} + +static void +remove_attachment (EMsgComposerAttachmentBar *bar, + EMsgComposerAttachment *attachment) +{ + bar->priv->attachments = g_list_remove (bar->priv->attachments, + attachment); + bar->priv->num_attachments--; + + gtk_object_unref (GTK_OBJECT (attachment)); + + gtk_signal_emit (GTK_OBJECT (bar), signals[CHANGED]); +} + + +/* Icon list contents handling. */ + +static void +update (EMsgComposerAttachmentBar *bar) +{ + EMsgComposerAttachmentBarPrivate *priv; + GnomeIconList *icon_list; + GList *p; + + priv = bar->priv; + icon_list = GNOME_ICON_LIST (bar); + + gnome_icon_list_freeze (icon_list); + + gnome_icon_list_clear (icon_list); + + /* FIXME could be faster, but we don't care. */ + + for (p = priv->attachments; p != NULL; p = p->next) { + EMsgComposerAttachment *attachment; + const gchar *icon_name; + gchar *size_string; + gchar *label; + + attachment = p->data; + icon_name = gnome_mime_get_value (attachment->mime_type, + "icon-filename"); + + /* FIXME we need some better default icon. */ + if (icon_name == NULL) + icon_name = gnome_mime_get_value ("text/plain", + "icon-filename"); + + size_string = size_to_string (attachment->size); + + /* FIXME: If GnomeIconList honoured "\n", the result would be a + lot better. */ + label = g_strconcat (attachment->description, "\n(", + size_string, ")", NULL); + + gnome_icon_list_append (icon_list, icon_name, label); + + g_free (label); + g_free (size_string); + } + + gnome_icon_list_thaw (icon_list); +} + +static void +remove_selected (EMsgComposerAttachmentBar *bar) +{ + GnomeIconList *icon_list; + EMsgComposerAttachment *attachment; + GList *attachment_list; + GList *p; + gint num; + + icon_list = GNOME_ICON_LIST (bar); + + /* Weee! I am especially proud of this piece of cheesy code: it is + truly awful. But unless one attaches a huge number of files, it + will not be as greedy as intended. FIXME of course. */ + + attachment_list = NULL; + for (p = icon_list->selection; p != NULL; p = p->next) { + num = GPOINTER_TO_INT (p->data); + attachment = E_MSG_COMPOSER_ATTACHMENT + (g_list_nth (bar->priv->attachments, num)->data); + attachment_list = g_list_prepend (attachment_list, attachment); + } + + for (p = attachment_list; p != NULL; p = p->next) + remove_attachment (bar, E_MSG_COMPOSER_ATTACHMENT (p->data)); + + g_list_free (attachment_list); + + update (bar); +} + +static void +edit_selected (EMsgComposerAttachmentBar *bar) +{ + GnomeIconList *icon_list; + EMsgComposerAttachment *attachment; + gint num; + + icon_list = GNOME_ICON_LIST (bar); + + num = GPOINTER_TO_INT (icon_list->selection->data); + attachment = g_list_nth (bar->priv->attachments, num)->data; + + e_msg_composer_attachment_edit (attachment, GTK_WIDGET (bar)); +} + + +/* "Attach" dialog. */ + +static void +attach_cb (GtkWidget *widget, + gpointer data) +{ + EMsgComposerAttachmentBar *bar; + GtkWidget *file_selection; + const gchar *file_name; + + file_selection = gtk_widget_get_toplevel (widget); + bar = E_MSG_COMPOSER_ATTACHMENT_BAR (data); + + file_name = gtk_file_selection_get_filename + (GTK_FILE_SELECTION (file_selection)); + add_from_file (bar, file_name); + + gtk_widget_hide (file_selection); +} + +static void +add_from_user (EMsgComposerAttachmentBar *bar) +{ + GtkWidget *file_selection; + GtkWidget *cancel_button; + GtkWidget *ok_button; + + file_selection = gtk_file_selection_new (_("Add attachment")); + gtk_window_set_position (GTK_WINDOW (file_selection), + GTK_WIN_POS_MOUSE); + + ok_button = GTK_FILE_SELECTION (file_selection)->ok_button; + gtk_signal_connect (GTK_OBJECT (ok_button), + "clicked", GTK_SIGNAL_FUNC (attach_cb), bar); + + cancel_button = GTK_FILE_SELECTION (file_selection)->cancel_button; + gtk_signal_connect_object (GTK_OBJECT (cancel_button), + "clicked", + GTK_SIGNAL_FUNC (gtk_widget_hide), + GTK_OBJECT (file_selection)); + + gtk_widget_show (GTK_WIDGET (file_selection)); +} + + +/* Callbacks. */ + +static void +add_cb (GtkWidget *widget, + gpointer data) +{ + g_return_if_fail (E_IS_MSG_COMPOSER_ATTACHMENT_BAR (data)); + + add_from_user (E_MSG_COMPOSER_ATTACHMENT_BAR (data)); +} + +static void +properties_cb (GtkWidget *widget, + gpointer data) +{ + EMsgComposerAttachmentBar *bar; + + g_return_if_fail (E_IS_MSG_COMPOSER_ATTACHMENT_BAR (data)); + + bar = E_MSG_COMPOSER_ATTACHMENT_BAR (data); + edit_selected (data); +} + +static void +remove_cb (GtkWidget *widget, + gpointer data) +{ + EMsgComposerAttachmentBar *bar; + + g_return_if_fail (E_IS_MSG_COMPOSER_ATTACHMENT_BAR (data)); + + bar = E_MSG_COMPOSER_ATTACHMENT_BAR (data); + remove_selected (bar); +} + + +/* Popup menu handling. */ + +static GnomeUIInfo icon_context_menu_info[] = { + GNOMEUIINFO_ITEM (N_("Remove"), + N_("Remove selected items from the attachment list"), + remove_cb, NULL), + GNOMEUIINFO_MENU_PROPERTIES_ITEM (properties_cb, NULL), + GNOMEUIINFO_END +}; + +static GtkWidget * +get_icon_context_menu (EMsgComposerAttachmentBar *bar) +{ + EMsgComposerAttachmentBarPrivate *priv; + + priv = bar->priv; + if (priv->icon_context_menu == NULL) + priv->icon_context_menu = gnome_popup_menu_new + (icon_context_menu_info); + + return priv->icon_context_menu; +} + +static void +popup_icon_context_menu (EMsgComposerAttachmentBar *bar, + gint num, + GdkEventButton *event) +{ + GtkWidget *menu; + + menu = get_icon_context_menu (bar); + gnome_popup_menu_do_popup (menu, NULL, NULL, event, bar); +} + +static GnomeUIInfo context_menu_info[] = { + GNOMEUIINFO_ITEM (N_("Add attachment..."), + N_("Attach a file to the message"), + add_cb, NULL), + GNOMEUIINFO_END +}; + +static GtkWidget * +get_context_menu (EMsgComposerAttachmentBar *bar) +{ + EMsgComposerAttachmentBarPrivate *priv; + + priv = bar->priv; + if (priv->context_menu == NULL) + priv->context_menu = gnome_popup_menu_new (context_menu_info); + + return priv->context_menu; +} + +static void +popup_context_menu (EMsgComposerAttachmentBar *bar, + GdkEventButton *event) +{ + GtkWidget *menu; + + menu = get_context_menu (bar); + gnome_popup_menu_do_popup (menu, NULL, NULL, event, bar); +} + + +/* GtkObject methods. */ + +static void +destroy (GtkObject *object) +{ + EMsgComposerAttachmentBar *bar; + + bar = E_MSG_COMPOSER_ATTACHMENT_BAR (object); + + free_attachment_list (bar); + + if (GTK_OBJECT_CLASS (parent_class)->destroy != NULL) + (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); +} + + +/* GtkWidget methods. */ + +static gint +button_press_event (GtkWidget *widget, + GdkEventButton *event) +{ + EMsgComposerAttachmentBar *bar; + GnomeIconList *icon_list; + gint icon_number; + + bar = E_MSG_COMPOSER_ATTACHMENT_BAR (widget); + icon_list = GNOME_ICON_LIST (widget); + + if (event->button != 3) + return GTK_WIDGET_CLASS (parent_class)->button_press_event + (widget, event); + + icon_number = gnome_icon_list_get_icon_at (icon_list, + event->x, event->y); + + if (icon_number >= 0) { + gnome_icon_list_select_icon (icon_list, icon_number); + popup_icon_context_menu (bar, icon_number, event); + } else { + popup_context_menu (bar, event); + } + + return TRUE; +} + + +/* GnomeIconList methods. */ + +static gboolean +text_changed (GnomeIconList *gil, + gint num, + const gchar *new_text) +{ + EMsgComposerAttachmentBar *bar; + EMsgComposerAttachment *attachment; + GList *p; + + bar = E_MSG_COMPOSER_ATTACHMENT_BAR (gil); + p = g_list_nth (bar->priv->attachments, num); + attachment = p->data; + + g_free (attachment->description); + attachment->description = g_strdup (new_text); + + return TRUE; +} + + +/* Initialization. */ + +static void +class_init (EMsgComposerAttachmentBarClass *class) +{ + GtkObjectClass *object_class; + GtkWidgetClass *widget_class; + GnomeIconListClass *icon_list_class; + + object_class = GTK_OBJECT_CLASS (class); + widget_class = GTK_WIDGET_CLASS (class); + icon_list_class = GNOME_ICON_LIST_CLASS (class); + + parent_class = gtk_type_class (gnome_icon_list_get_type ()); + + object_class->destroy = destroy; + + widget_class->button_press_event = button_press_event; + + icon_list_class->text_changed = text_changed; + + /* Setup signals. */ + + signals[CHANGED] = + gtk_signal_new ("changed", + GTK_RUN_LAST, + object_class->type, + GTK_SIGNAL_OFFSET (EMsgComposerAttachmentBarClass, + changed), + gtk_marshal_NONE__NONE, + GTK_TYPE_NONE, 0); + + gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL); +} + +static void +init (EMsgComposerAttachmentBar *bar) +{ + EMsgComposerAttachmentBarPrivate *priv; + guint icon_size; + + priv = g_new (EMsgComposerAttachmentBarPrivate, 1); + + priv->attachments = NULL; + priv->context_menu = NULL; + priv->icon_context_menu = NULL; + + priv->num_attachments = 0; + + bar->priv = priv; + + /* FIXME partly hardcoded. We should compute height from the font, and + allow at least 2 lines for every item. */ + icon_size = ICON_WIDTH + ICON_SPACING + ICON_BORDER + ICON_TEXT_SPACING; + icon_size += 24; + + gtk_widget_set_usize (GTK_WIDGET (bar), icon_size * 4, icon_size); +} + + +GtkType +e_msg_composer_attachment_bar_get_type (void) +{ + static GtkType type = 0; + + if (type == 0) { + static const GtkTypeInfo info = { + "EMsgComposerAttachmentBar", + sizeof (EMsgComposerAttachmentBar), + sizeof (EMsgComposerAttachmentBarClass), + (GtkClassInitFunc) class_init, + (GtkObjectInitFunc) init, + /* reserved_1 */ NULL, + /* reserved_2 */ NULL, + (GtkClassInitFunc) NULL, + }; + + type = gtk_type_unique (gnome_icon_list_get_type (), &info); + } + + return type; +} + +GtkWidget * +e_msg_composer_attachment_bar_new (GtkAdjustment *adj) +{ + EMsgComposerAttachmentBar *new; + GnomeIconList *icon_list; + + gtk_widget_push_visual (gdk_imlib_get_visual ()); + gtk_widget_push_colormap (gdk_imlib_get_colormap ()); + new = gtk_type_new (e_msg_composer_attachment_bar_get_type ()); + gtk_widget_pop_visual (); + gtk_widget_pop_colormap (); + + icon_list = GNOME_ICON_LIST (new); + + gnome_icon_list_construct (icon_list, ICON_WIDTH, adj, 0); + + gnome_icon_list_set_separators (icon_list, ICON_SEPARATORS); + gnome_icon_list_set_row_spacing (icon_list, ICON_ROW_SPACING); + gnome_icon_list_set_col_spacing (icon_list, ICON_COL_SPACING); + gnome_icon_list_set_icon_border (icon_list, ICON_BORDER); + gnome_icon_list_set_text_spacing (icon_list, ICON_TEXT_SPACING); + gnome_icon_list_set_selection_mode (icon_list, GTK_SELECTION_MULTIPLE); + + return GTK_WIDGET (new); +} + + +static void +attach_to_multipart (CamelMultipart *multipart, + EMsgComposerAttachment *attachment) +{ + CamelMimeBodyPart *part; + + /* FIXME encoding etc. etc. ? */ + /* FIXME I am not sure how to add an attachment through the Camel + API. :-/ */ + + part = camel_mime_body_part_new (); + camel_mime_part_set_disposition (CAMEL_MIME_PART (part), "attachment"); + camel_mime_part_set_filename (CAMEL_MIME_PART (part), + g_strdup (g_basename (attachment->file_name))); + camel_mime_part_set_description (CAMEL_MIME_PART (part), + g_strdup (attachment->description)); + camel_data_wrapper_set_mime_type (CAMEL_DATA_WRAPPER (part), + g_strdup (attachment->mime_type)); +} + +void +e_msg_composer_attachment_bar_to_multipart (EMsgComposerAttachmentBar *bar, + CamelMultipart *multipart) +{ + EMsgComposerAttachmentBarPrivate *priv; + GList *p; + + g_return_if_fail (bar != NULL); + g_return_if_fail (E_IS_MSG_COMPOSER_ATTACHMENT_BAR (bar)); + g_return_if_fail (multipart != NULL); + g_return_if_fail (CAMEL_IS_MULTIPART (multipart)); + + priv = bar->priv; + + for (p = priv->attachments; p != NULL; p = p->next) { + EMsgComposerAttachment *attachment; + + attachment = E_MSG_COMPOSER_ATTACHMENT (p->data); + attach_to_multipart (multipart, attachment); + } +} + + +guint +e_msg_composer_attachment_bar_get_num_attachments (EMsgComposerAttachmentBar *bar) +{ + g_return_val_if_fail (bar != NULL, 0); + g_return_val_if_fail (E_IS_MSG_COMPOSER_ATTACHMENT_BAR (bar), 0); + + return bar->priv->num_attachments; +} + + +void +e_msg_composer_attachment_bar_attach (EMsgComposerAttachmentBar *bar, + const gchar *file_name) +{ + g_return_if_fail (bar != NULL); + g_return_if_fail (E_IS_MSG_COMPOSER_ATTACHMENT_BAR (bar)); + + if (file_name == NULL) + add_from_user (bar); + else + add_from_file (bar, file_name); +} diff --git a/composer/e-msg-composer-attachment-bar.h b/composer/e-msg-composer-attachment-bar.h new file mode 100644 index 0000000000..803b51a954 --- /dev/null +++ b/composer/e-msg-composer-attachment-bar.h @@ -0,0 +1,74 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* msg-composer-attachment-bar.h + * + * Copyright (C) 1999 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 __E_MSG_COMPOSER_ATTACHMENT_BAR_H__ +#define __E_MSG_COMPOSER_ATTACHMENT_BAR_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#pragma } +#endif /* __cplusplus */ + +#define E_TYPE_MSG_COMPOSER_ATTACHMENT_BAR \ + (e_msg_composer_attachment_bar_get_type ()) +#define E_MSG_COMPOSER_ATTACHMENT_BAR(obj) \ + (GTK_CHECK_CAST ((obj), E_TYPE_MSG_COMPOSER_ATTACHMENT_BAR, EMsgComposerAttachmentBar)) +#define E_MSG_COMPOSER_ATTACHMENT_BAR_CLASS(klass) \ + (GTK_CHECK_CLASS_CAST ((klass), E_TYPE_MSG_COMPOSER_ATTACHMENT_BAR, EMsgComposerAttachmentBarClass)) +#define E_IS_MSG_COMPOSER_ATTACHMENT_BAR(obj) \ + (GTK_CHECK_TYPE ((obj), E_TYPE_MSG_COMPOSER_ATTACHMENT_BAR)) +#define E_IS_MSG_COMPOSER_ATTACHMENT_BAR_CLASS(klass) \ + (GTK_CHECK_CLASS_TYPE ((obj), E_TYPE_MSG_COMPOSER_ATTACHMENT_BAR)) + + +typedef struct _EMsgComposerAttachmentBarPrivate EMsgComposerAttachmentBarPrivate; + +struct _EMsgComposerAttachmentBar { + GnomeIconList parent; + + EMsgComposerAttachmentBarPrivate *priv; +}; +typedef struct _EMsgComposerAttachmentBar EMsgComposerAttachmentBar; + +struct _EMsgComposerAttachmentBarClass { + GnomeIconListClass parent_class; + + void (* changed) (EMsgComposerAttachmentBar *bar); +}; +typedef struct _EMsgComposerAttachmentBarClass EMsgComposerAttachmentBarClass; + + +GtkType e_msg_composer_attachment_bar_get_type (void); +GtkWidget *e_msg_composer_attachment_bar_new (GtkAdjustment *adj); +void e_msg_composer_attachment_bar_to_multipart (EMsgComposerAttachmentBar *bar, CamelMultipart *multipart); +guint e_msg_composer_attachment_bar_get_num_attachments (EMsgComposerAttachmentBar *bar); +void e_msg_composer_attachment_bar_attach (EMsgComposerAttachmentBar *bar, const gchar *file_name); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __E_MSG_COMPOSER_ATTACHMENT_BAR_H__ */ diff --git a/composer/e-msg-composer-attachment.c b/composer/e-msg-composer-attachment.c new file mode 100644 index 0000000000..f4741d987f --- /dev/null +++ b/composer/e-msg-composer-attachment.c @@ -0,0 +1,480 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* e-msg-composer-attachment.c + * + * Copyright (C) 1999 Helix Code, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: Ettore Perazzoli + */ + +/* This is the object representing an email attachment. It is implemented as a + GtkObject to make it easier for the application to handle it. For example, + the "changed" signal is emitted whenever something changes in the + attachment. Also, this contains the code to let users edit the + attachment manually. */ + +#include + +#include + +#include "e-msg-composer-attachment.h" + + +enum { + CHANGED, + LAST_SIGNAL +}; +static guint signals[LAST_SIGNAL] = { 0 }; + +static GtkObjectClass *parent_class = NULL; + + +/* Utility functions. */ + +static const gchar * +get_mime_type (const gchar *file_name) +{ + const gchar *mime_type; + + mime_type = gnome_mime_type_of_file (file_name); + if (mime_type == NULL) + mime_type = "application/octet-stream"; + + return mime_type; +} + +static void +init_mime_type (EMsgComposerAttachment *attachment) +{ + attachment->mime_type = g_strdup (get_mime_type (attachment->file_name)); +} + +static void +set_mime_type (EMsgComposerAttachment *attachment) +{ + g_free (attachment->mime_type); + init_mime_type (attachment); +} + +static void +changed (EMsgComposerAttachment *attachment) +{ + gtk_signal_emit (GTK_OBJECT (attachment), signals[CHANGED]); +} + + +/* GtkObject methods. */ + +static void +destroy (GtkObject *object) +{ + EMsgComposerAttachment *attachment; + + attachment = E_MSG_COMPOSER_ATTACHMENT (object); + + g_free (attachment->file_name); + g_free (attachment->description); + g_free (attachment->mime_type); +} + + +/* Signals. */ + +static void +real_changed (EMsgComposerAttachment *msg_composer_attachment) +{ + g_return_if_fail (msg_composer_attachment != NULL); + g_return_if_fail (E_IS_MSG_COMPOSER_ATTACHMENT (msg_composer_attachment)); +} + + +static void +class_init (EMsgComposerAttachmentClass *klass) +{ + GtkObjectClass *object_class; + + object_class = (GtkObjectClass*) klass; + + parent_class = gtk_type_class (gtk_object_get_type ()); + + object_class->destroy = destroy; + + signals[CHANGED] = gtk_signal_new ("changed", + GTK_RUN_FIRST, + object_class->type, + GTK_SIGNAL_OFFSET + (EMsgComposerAttachmentClass, + changed), + gtk_marshal_NONE__NONE, + GTK_TYPE_NONE, 0); + + + gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL); + + klass->changed = real_changed; +} + +static void +init (EMsgComposerAttachment *msg_composer_attachment) +{ + msg_composer_attachment->editor_gui = NULL; + msg_composer_attachment->file_name = NULL; + msg_composer_attachment->description = NULL; + msg_composer_attachment->mime_type = NULL; + msg_composer_attachment->size = 0; +} + +GtkType +e_msg_composer_attachment_get_type (void) +{ + static GtkType type = 0; + + if (type == 0) { + static const GtkTypeInfo info = { + "EMsgComposerAttachment", + sizeof (EMsgComposerAttachment), + sizeof (EMsgComposerAttachmentClass), + (GtkClassInitFunc) class_init, + (GtkObjectInitFunc) init, + /* reserved_1 */ NULL, + /* reserved_2 */ NULL, + (GtkClassInitFunc) NULL, + }; + + type = gtk_type_unique (gtk_object_get_type (), &info); + } + + return type; +} + + +/** + * e_msg_composer_attachment_new: + * @file_name: + * + * Return value: + **/ +EMsgComposerAttachment * +e_msg_composer_attachment_new (const gchar *file_name) +{ + EMsgComposerAttachment *new; + struct stat statbuf; + + g_return_val_if_fail (file_name != NULL, NULL); + + new = gtk_type_new (e_msg_composer_attachment_get_type ()); + + new->editor_gui = NULL; + + new->file_name = g_strdup (file_name); + new->description = g_strdup (g_basename (new->file_name)); + + if (stat (file_name, &statbuf) < 0) + new->size = 0; + else + new->size = statbuf.st_size; + + init_mime_type (new); + + return new; +} + + +/* The attachment property dialog. */ + +struct _DialogData { + GtkWidget *dialog; + GtkEntry *file_name_entry; + GtkEntry *description_entry; + GtkEntry *mime_type_entry; + GtkWidget *browse_widget; + EMsgComposerAttachment *attachment; +}; +typedef struct _DialogData DialogData; + +static void +destroy_dialog_data (DialogData *data) +{ + if (data->browse_widget != NULL) + gtk_widget_destroy (data->browse_widget); + g_free (data); +} + +static void +update_mime_type (DialogData *data) +{ + const gchar *mime_type; + const gchar *file_name; + + file_name = gtk_entry_get_text (data->file_name_entry); + mime_type = get_mime_type (file_name); + + gtk_entry_set_text (data->mime_type_entry, mime_type); +} + +static void +browse_ok_cb (GtkWidget *widget, + gpointer data) +{ + GtkWidget *file_selection; + DialogData *dialog_data; + const gchar *file_name; + + dialog_data = (DialogData *) data; + file_selection = gtk_widget_get_toplevel (widget); + + file_name = gtk_file_selection_get_filename + (GTK_FILE_SELECTION (file_selection)); + + gtk_entry_set_text (dialog_data->file_name_entry, file_name); + + update_mime_type (dialog_data); + + gtk_widget_hide (file_selection); +} + +static void +browse (DialogData *data) +{ + if (data->browse_widget == NULL) { + GtkWidget *file_selection; + GtkWidget *cancel_button; + GtkWidget *ok_button; + + file_selection + = gtk_file_selection_new (_("Select attachment")); + gtk_window_set_position (GTK_WINDOW (file_selection), + GTK_WIN_POS_MOUSE); + gtk_window_set_transient_for (GTK_WINDOW (file_selection), + GTK_WINDOW (data->dialog)); + + ok_button = GTK_FILE_SELECTION (file_selection)->ok_button; + gtk_signal_connect (GTK_OBJECT (ok_button), + "clicked", GTK_SIGNAL_FUNC (browse_ok_cb), + data); + + cancel_button + = GTK_FILE_SELECTION (file_selection)->cancel_button; + gtk_signal_connect_object (GTK_OBJECT (cancel_button), + "clicked", + GTK_SIGNAL_FUNC (gtk_widget_hide), + GTK_OBJECT (file_selection)); + + data->browse_widget = file_selection; + } + + gtk_widget_show (GTK_WIDGET (data->browse_widget)); +} + +static void +set_entry (GladeXML *xml, + const gchar *widget_name, + const gchar *value) +{ + GtkEntry *entry; + + entry = GTK_ENTRY (glade_xml_get_widget (xml, widget_name)); + if (entry == NULL) + g_warning ("Entry for `%s' not found.", widget_name); + gtk_entry_set_text (entry, value); +} + +static void +connect_entry_changed (GladeXML *gui, + const gchar *name, + GtkSignalFunc func, + gpointer data) +{ + GtkWidget *widget; + + widget = glade_xml_get_widget (gui, name); + gtk_signal_connect (GTK_OBJECT (widget), "changed", func, data); +} + +static void +connect_widget (GladeXML *gui, + const gchar *name, + const gchar *signal_name, + GtkSignalFunc func, + gpointer data) +{ + GtkWidget *widget; + + widget = glade_xml_get_widget (gui, name); + gtk_signal_connect (GTK_OBJECT (widget), signal_name, func, data); +} + +static void +apply (DialogData *data) +{ + EMsgComposerAttachment *attachment; + + attachment = data->attachment; + + g_free (attachment->file_name); + attachment->file_name = g_strdup (gtk_entry_get_text + (data->file_name_entry)); + + g_free (attachment->description); + attachment->description = g_strdup (gtk_entry_get_text + (data->description_entry)); + + g_free (attachment->mime_type); + attachment->mime_type = g_strdup (gtk_entry_get_text + (data->mime_type_entry)); + + changed (attachment); +} + +static void +entry_changed_cb (GtkWidget *widget, gpointer data) +{ + DialogData *dialog_data; + GladeXML *gui; + GtkWidget *apply_button; + + dialog_data = (DialogData *) data; + gui = dialog_data->attachment->editor_gui; + + apply_button = glade_xml_get_widget (gui, "apply_button"); + gtk_widget_set_sensitive (apply_button, TRUE); +} + +static void +close_cb (GtkWidget *widget, + gpointer data) +{ + EMsgComposerAttachment *attachment; + DialogData *dialog_data; + + dialog_data = (DialogData *) data; + attachment = dialog_data->attachment; + + gtk_widget_destroy (glade_xml_get_widget (attachment->editor_gui, + "dialog")); + gtk_object_unref (GTK_OBJECT (attachment->editor_gui)); + attachment->editor_gui = NULL; + + destroy_dialog_data (dialog_data); +} + +static void +apply_cb (GtkWidget *widget, + gpointer data) +{ + DialogData *dialog_data; + + dialog_data = (DialogData *) data; + apply (dialog_data); +} + +static void +ok_cb (GtkWidget *widget, + gpointer data) +{ + apply_cb (widget, data); + close_cb (widget, data); +} + +static void +browse_cb (GtkWidget *widget, + gpointer data) +{ + DialogData *dialog_data; + + dialog_data = (DialogData *) data; + browse (dialog_data); +} + +static void +file_name_focus_out_cb (GtkWidget *widget, + GdkEventFocus *event, + gpointer data) +{ + DialogData *dialog_data; + + dialog_data = (DialogData *) data; + update_mime_type (dialog_data); +} + + +void +e_msg_composer_attachment_edit (EMsgComposerAttachment *attachment, + GtkWidget *parent) +{ + DialogData *dialog_data; + GladeXML *editor_gui; + + g_return_if_fail (attachment != NULL); + g_return_if_fail (E_IS_MSG_COMPOSER_ATTACHMENT (attachment)); + + if (attachment->editor_gui != NULL) { + GtkWidget *window; + + window = glade_xml_get_widget (attachment->editor_gui, + "dialog"); + gdk_window_show (window->window); + return; + } + + editor_gui = glade_xml_new (E_GLADEDIR "/e-msg-composer-attachment.glade", + NULL); + if (editor_gui == NULL) { + g_warning ("Cannot load `e-msg-composer-attachment.glade'"); + return; + } + + attachment->editor_gui = editor_gui; + + gtk_window_set_transient_for + (GTK_WINDOW (glade_xml_get_widget (editor_gui, "dialog")), + GTK_WINDOW (gtk_widget_get_toplevel (parent))); + + dialog_data = g_new (DialogData, 1); + dialog_data->browse_widget = NULL; + dialog_data->attachment = attachment; + dialog_data->dialog = glade_xml_get_widget (editor_gui, "dialog"); + dialog_data->file_name_entry = GTK_ENTRY (glade_xml_get_widget + (editor_gui, + "file_name_entry")); + dialog_data->description_entry = GTK_ENTRY (glade_xml_get_widget + (editor_gui, + "description_entry")); + dialog_data->mime_type_entry = GTK_ENTRY (glade_xml_get_widget + (editor_gui, + "mime_type_entry")); + + if (attachment != NULL) { + set_entry (editor_gui, "file_name_entry", attachment->file_name); + set_entry (editor_gui, "description_entry", attachment->description); + set_entry (editor_gui, "mime_type_entry", attachment->mime_type); + } + + connect_entry_changed (editor_gui, "file_name_entry", + entry_changed_cb, dialog_data); + connect_entry_changed (editor_gui, "description_entry", + entry_changed_cb, dialog_data); + + connect_widget (editor_gui, "ok_button", "clicked", ok_cb, dialog_data); + connect_widget (editor_gui, "apply_button", "clicked", apply_cb, dialog_data); + connect_widget (editor_gui, "close_button", "clicked", close_cb, dialog_data); + + connect_widget (editor_gui, "browse_button", "clicked", browse_cb, dialog_data); + + connect_widget (editor_gui, "file_name_entry", "focus_out_event", + file_name_focus_out_cb, dialog_data); +} diff --git a/composer/e-msg-composer-attachment.glade b/composer/e-msg-composer-attachment.glade new file mode 100644 index 0000000000..72c0132639 --- /dev/null +++ b/composer/e-msg-composer-attachment.glade @@ -0,0 +1,290 @@ + + + + + e-msg-composer-attachment + e-msg-composer-attachment + + src + pixmaps + C + True + True + False + True + True + True + True + interface.c + interface.h + callbacks.c + callbacks.h + support.c + support.h + + + + + GnomeDialog + dialog + Attachment properties + GTK_WINDOW_TOPLEVEL + GTK_WIN_POS_NONE + False + False + False + False + False + False + + + GtkVBox + GnomeDialog:vbox + dialog-vbox1 + False + 8 + + 4 + True + True + + + + GtkTable + table1 + 3 + 2 + False + 10 + 5 + + 0 + True + True + + + + GtkLabel + label1 + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + 0 + 1 + 1 + 2 + 0 + 0 + False + False + False + False + False + False + + + + + GtkLabel + label3 + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + 0 + 1 + 2 + 3 + 0 + 0 + False + False + False + False + False + False + + + + + GtkEntry + description_entry + True + True + True + 0 + + + 1 + 2 + 1 + 2 + 0 + 0 + True + False + False + False + True + False + + + + + GtkLabel + label2 + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + 0 + 1 + 0 + 1 + 0 + 0 + False + False + False + False + False + False + + + + + GtkHBox + hbox3 + False + 10 + + 1 + 2 + 0 + 1 + 0 + 0 + True + True + True + True + True + True + + + + GtkEntry + file_name_entry + 290 + True + True + True + 0 + + + 0 + True + True + + + + + GtkButton + browse_button + 80 + True + + + 0 + False + False + + + + + + GtkEntry + mime_type_entry + False + True + False + True + 0 + + + 1 + 2 + 2 + 3 + 0 + 0 + True + False + False + False + True + False + + + + + + GtkHButtonBox + GnomeDialog:action_area + dialog-action_area1 + GTK_BUTTONBOX_END + 8 + 85 + 27 + 7 + 0 + + 0 + False + True + GTK_PACK_END + + + + GtkButton + ok_button + True + True + True + GNOME_STOCK_BUTTON_OK + + + + GtkButton + apply_button + False + True + True + GNOME_STOCK_BUTTON_APPLY + + + + GtkButton + close_button + True + True + GNOME_STOCK_BUTTON_CLOSE + + + + + + diff --git a/composer/e-msg-composer-attachment.h b/composer/e-msg-composer-attachment.h new file mode 100644 index 0000000000..7e3c88238b --- /dev/null +++ b/composer/e-msg-composer-attachment.h @@ -0,0 +1,72 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* e-msg-composer-attachment.h + * + * Copyright (C) 1999 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 __E_MSG_COMPOSER_ATTACHMENT_H__ +#define __E_MSG_COMPOSER_ATTACHMENT_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#pragma } +#endif /* __cplusplus */ + +#define E_TYPE_MSG_COMPOSER_ATTACHMENT (e_msg_composer_attachment_get_type ()) +#define E_MSG_COMPOSER_ATTACHMENT(obj) (GTK_CHECK_CAST ((obj), E_TYPE_MSG_COMPOSER_ATTACHMENT, EMsgComposerAttachment)) +#define E_MSG_COMPOSER_ATTACHMENT_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_TYPE_MSG_COMPOSER_ATTACHMENT, EMsgComposerAttachmentClass)) +#define E_IS_MSG_COMPOSER_ATTACHMENT(obj) (GTK_CHECK_TYPE ((obj), E_TYPE_MSG_COMPOSER_ATTACHMENT)) +#define E_IS_MSG_COMPOSER_ATTACHMENT_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), E_TYPE_MSG_COMPOSER_ATTACHMENT)) + + +typedef struct _EMsgComposerAttachment EMsgComposerAttachment; +typedef struct _EMsgComposerAttachmentClass EMsgComposerAttachmentClass; + +struct _EMsgComposerAttachment { + GtkObject parent; + + GladeXML *editor_gui; + + gchar *file_name; + gchar *description; + gchar *mime_type; + + gulong size; +}; + +struct _EMsgComposerAttachmentClass { + GtkObjectClass parent_class; + + void (*changed) (EMsgComposerAttachment *msg_composer_attachment); +}; + + +GtkType e_msg_composer_attachment_get_type (void); +EMsgComposerAttachment *e_msg_composer_attachment_new (const gchar *file_name); +void e_msg_composer_attachment_edit (EMsgComposerAttachment *attachment, + GtkWidget *parent); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __E_MSG_COMPOSER_ATTACHMENT_H__ */ diff --git a/composer/e-msg-composer-hdrs.c b/composer/e-msg-composer-hdrs.c new file mode 100644 index 0000000000..2c27531bb8 --- /dev/null +++ b/composer/e-msg-composer-hdrs.c @@ -0,0 +1,355 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* msg-composer-hdrs.c + * + * Copyright (C) 1999 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 + */ + +#ifdef _HAVE_CONFIG_H +#include +#endif + +#include +#include + +#include "e-msg-composer-address-entry.h" +#include "e-msg-composer-hdrs.h" + + +struct _EMsgComposerHdrsPrivate { + /* Total number of headers that we have. */ + guint num_hdrs; + + /* The tooltips. */ + GtkTooltips *tooltips; + + /* Standard headers. */ + GtkWidget *to_entry; + GtkWidget *cc_entry; + GtkWidget *bcc_entry; + GtkWidget *subject_entry; +}; + + +static GtkTableClass *parent_class = NULL; + +enum { + SHOW_ADDRESS_DIALOG, + LAST_SIGNAL +}; + +static gint signals[LAST_SIGNAL]; + + +static void +address_button_clicked_cb (GtkButton *button, + gpointer data) +{ + gtk_signal_emit (GTK_OBJECT (data), signals[SHOW_ADDRESS_DIALOG]); +} + +static GtkWidget * +add_header (EMsgComposerHdrs *hdrs, + const gchar *name, + const gchar *tip, + const gchar *tip_private, + gboolean addrbook_button) +{ + EMsgComposerHdrsPrivate *priv; + GtkWidget *label; + GtkWidget *entry; + guint pad; + + priv = hdrs->priv; + + if (addrbook_button) { + label = gtk_button_new_with_label (name); + gtk_signal_connect (GTK_OBJECT (label), "clicked", + GTK_SIGNAL_FUNC (address_button_clicked_cb), + hdrs); + pad = 2; + gtk_tooltips_set_tip (hdrs->priv->tooltips, label, + _("Click here for the address book"), + NULL); + } else { + label = gtk_label_new (name); + pad = GNOME_PAD; + } + + gtk_table_attach (GTK_TABLE (hdrs), label, + 0, 1, priv->num_hdrs, priv->num_hdrs + 1, + GTK_FILL, GTK_FILL, + pad, pad); + gtk_widget_show (label); + + entry = e_msg_composer_address_entry_new (); + gtk_table_attach (GTK_TABLE (hdrs), entry, + 1, 2, priv->num_hdrs, priv->num_hdrs + 1, + GTK_FILL | GTK_EXPAND, GTK_FILL, + 2, 2); + gtk_widget_show (entry); + + gtk_tooltips_set_tip (hdrs->priv->tooltips, entry, tip, tip_private); + + priv->num_hdrs++; + + return entry; +} + +static void +setup_headers (EMsgComposerHdrs *hdrs) +{ + EMsgComposerHdrsPrivate *priv; + + priv = hdrs->priv; + + priv->to_entry = add_header + (hdrs, _("To:"), + _("Enter the recipients of the message"), + NULL, + TRUE); + priv->cc_entry = add_header + (hdrs, _("Cc:"), + _("Enter the addresses that will receive a carbon copy of " + "the message"), + NULL, + TRUE); + priv->bcc_entry = add_header + (hdrs, _("Bcc:"), + _("Enter the addresses that will receive a carbon copy of " + "the message without appearing in the recipient list of " + "the message."), + NULL, + TRUE); + priv->subject_entry = add_header + (hdrs, _("Subject:"), + _("Enter the subject of the mail"), + NULL, + FALSE); +} + + +/* GtkObject methods. */ + +static void +destroy (GtkObject *object) +{ + EMsgComposerHdrs *hdrs; + EMsgComposerHdrsPrivate *priv; + + hdrs = E_MSG_COMPOSER_HDRS (object); + priv = hdrs->priv; + + gtk_object_destroy (GTK_OBJECT (priv->tooltips)); + + if (GTK_OBJECT_CLASS (parent_class)->destroy != NULL) + (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); +} + + +static void +class_init (EMsgComposerHdrsClass *class) +{ + GtkObjectClass *object_class; + + object_class = GTK_OBJECT_CLASS (class); + object_class->destroy = destroy; + + parent_class = gtk_type_class (gtk_table_get_type ()); + + signals[SHOW_ADDRESS_DIALOG] = + gtk_signal_new ("show_address_dialog", + GTK_RUN_LAST, + object_class->type, + GTK_SIGNAL_OFFSET (EMsgComposerHdrsClass, + show_address_dialog), + gtk_marshal_NONE__NONE, + GTK_TYPE_NONE, 0); + + gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL); +} + +static void +init (EMsgComposerHdrs *hdrs) +{ + EMsgComposerHdrsPrivate *priv; + + priv = g_new (EMsgComposerHdrsPrivate, 1); + + priv->to_entry = NULL; + priv->cc_entry = NULL; + priv->bcc_entry = NULL; + priv->subject_entry = NULL; + + priv->tooltips = gtk_tooltips_new (); + + priv->num_hdrs = 0; + + hdrs->priv = priv; +} + + +GtkType +e_msg_composer_hdrs_get_type (void) +{ + static GtkType type = 0; + + if (type == 0) { + static const GtkTypeInfo info = { + "EMsgComposerHdrs", + sizeof (EMsgComposerHdrs), + sizeof (EMsgComposerHdrsClass), + (GtkClassInitFunc) class_init, + (GtkObjectInitFunc) init, + /* reserved_1 */ NULL, + /* reserved_2 */ NULL, + (GtkClassInitFunc) NULL, + }; + + type = gtk_type_unique (gtk_table_get_type (), &info); + } + + return type; +} + +GtkWidget * +e_msg_composer_hdrs_new (void) +{ + EMsgComposerHdrs *new; + + new = gtk_type_new (e_msg_composer_hdrs_get_type ()); + + setup_headers (E_MSG_COMPOSER_HDRS (new)); + + return GTK_WIDGET (new); +} + + +static void +set_recipients (CamelMimeMessage *msg, + GtkWidget *entry_widget, + const gchar *type) +{ + EMsgComposerAddressEntry *entry; + GList *list; + GList *p; + + entry = E_MSG_COMPOSER_ADDRESS_ENTRY (entry_widget); + list = e_msg_composer_address_entry_get_addresses (entry); + + /* FIXME leak? */ + + for (p = list; p != NULL; p = p->next) { + printf ("Adding `%s:' header: %s\n", type, (gchar *) p->data); + camel_mime_message_add_recipient (msg, type, (gchar *) p->data); + } + + g_list_free (list); +} + +void +e_msg_composer_hdrs_to_message (EMsgComposerHdrs *hdrs, + CamelMimeMessage *msg) +{ + const gchar *s; + + g_return_if_fail (hdrs != NULL); + g_return_if_fail (E_IS_MSG_COMPOSER_HDRS (hdrs)); + g_return_if_fail (msg != NULL); + g_return_if_fail (CAMEL_IS_MIME_MESSAGE (msg)); + + s = gtk_entry_get_text (GTK_ENTRY (hdrs->priv->subject_entry)); + camel_mime_message_set_subject (msg, g_strdup (s)); + + set_recipients (msg, hdrs->priv->to_entry, CAMEL_RECIPIENT_TYPE_TO); + set_recipients (msg, hdrs->priv->cc_entry, CAMEL_RECIPIENT_TYPE_CC); + set_recipients (msg, hdrs->priv->bcc_entry, CAMEL_RECIPIENT_TYPE_BCC); +} + + +void +e_msg_composer_hdrs_set_to (EMsgComposerHdrs *hdrs, + GList *to_list) +{ + EMsgComposerAddressEntry *entry; + + g_return_if_fail (hdrs != NULL); + g_return_if_fail (E_IS_MSG_COMPOSER_HDRS (hdrs)); + + entry = E_MSG_COMPOSER_ADDRESS_ENTRY (hdrs->priv->to_entry); + e_msg_composer_address_entry_set_list (entry, to_list); +} + +void +e_msg_composer_hdrs_set_cc (EMsgComposerHdrs *hdrs, + GList *cc_list) +{ + EMsgComposerAddressEntry *entry; + + g_return_if_fail (hdrs != NULL); + g_return_if_fail (E_IS_MSG_COMPOSER_HDRS (hdrs)); + + entry = E_MSG_COMPOSER_ADDRESS_ENTRY (hdrs->priv->cc_entry); + e_msg_composer_address_entry_set_list (entry, cc_list); +} + +void +e_msg_composer_hdrs_set_bcc (EMsgComposerHdrs *hdrs, + GList *bcc_list) +{ + EMsgComposerAddressEntry *entry; + + g_return_if_fail (hdrs != NULL); + g_return_if_fail (E_IS_MSG_COMPOSER_HDRS (hdrs)); + + entry = E_MSG_COMPOSER_ADDRESS_ENTRY (hdrs->priv->bcc_entry); + e_msg_composer_address_entry_set_list (entry, bcc_list); +} + + +GList * +e_msg_composer_hdrs_get_to (EMsgComposerHdrs *hdrs) +{ + g_return_val_if_fail (hdrs != NULL, NULL); + g_return_val_if_fail (E_IS_MSG_COMPOSER_HDRS (hdrs), NULL); + + return e_msg_composer_address_entry_get_addresses + (E_MSG_COMPOSER_ADDRESS_ENTRY (hdrs->priv->to_entry)); +} + +GList * +e_msg_composer_hdrs_get_cc (EMsgComposerHdrs *hdrs) +{ + g_return_val_if_fail (hdrs != NULL, NULL); + g_return_val_if_fail (E_IS_MSG_COMPOSER_HDRS (hdrs), NULL); + + return e_msg_composer_address_entry_get_addresses + (E_MSG_COMPOSER_ADDRESS_ENTRY (hdrs->priv->cc_entry)); +} + +GList * +e_msg_composer_hdrs_get_bcc (EMsgComposerHdrs *hdrs) +{ + g_return_val_if_fail (hdrs != NULL, NULL); + g_return_val_if_fail (E_IS_MSG_COMPOSER_HDRS (hdrs), NULL); + + return e_msg_composer_address_entry_get_addresses + (E_MSG_COMPOSER_ADDRESS_ENTRY (hdrs->priv->bcc_entry)); +} + diff --git a/composer/e-msg-composer-hdrs.h b/composer/e-msg-composer-hdrs.h new file mode 100644 index 0000000000..d053573d85 --- /dev/null +++ b/composer/e-msg-composer-hdrs.h @@ -0,0 +1,80 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* msg-composer-hdrs.h + * + * Copyright (C) 1999 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 ___E_MSG_COMPOSER_HDRS_H__ +#define ___E_MSG_COMPOSER_HDRS_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#pragma } +#endif /* __cplusplus */ + +#define E_TYPE_MSG_COMPOSER_HDRS (e_msg_composer_hdrs_get_type ()) +#define E_MSG_COMPOSER_HDRS(obj) (GTK_CHECK_CAST ((obj), E_TYPE_MSG_COMPOSER_HDRS, EMsgComposerHdrs)) +#define E_MSG_COMPOSER_HDRS_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_TYPE_MSG_COMPOSER_HDRS, EMsgComposerHdrsClass)) +#define E_IS_MSG_COMPOSER_HDRS(obj) (GTK_CHECK_TYPE ((obj), E_TYPE_MSG_COMPOSER_HDRS)) +#define E_IS_MSG_COMPOSER_HDRS_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), E_TYPE_MSG_COMPOSER_HDRS)) + + +typedef struct _EMsgComposerHdrs EMsgComposerHdrs; +typedef struct _EMsgComposerHdrsClass EMsgComposerHdrsClass; +typedef struct _EMsgComposerHdrsPrivate EMsgComposerHdrsPrivate; + +struct _EMsgComposerHdrs { + GtkTable parent; + + EMsgComposerHdrsPrivate *priv; +}; + +struct _EMsgComposerHdrsClass { + GtkTableClass parent_class; + + void (* show_address_dialog) (EMsgComposerHdrs *hdrs); +}; + + +GtkType e_msg_composer_hdrs_get_type (void); +GtkWidget *e_msg_composer_hdrs_new (void); +void e_msg_composer_hdrs_to_message (EMsgComposerHdrs *hdrs, + CamelMimeMessage *msg); + +void e_msg_composer_hdrs_set_to (EMsgComposerHdrs *hdrs, + GList *to_list); +void e_msg_composer_hdrs_set_cc (EMsgComposerHdrs *hdrs, + GList *cc_list); +void e_msg_composer_hdrs_set_bcc (EMsgComposerHdrs *hdrs, + GList *bcc_list); + +GList *e_msg_composer_hdrs_get_to (EMsgComposerHdrs *hdrs); +GList *e_msg_composer_hdrs_get_cc (EMsgComposerHdrs *hdrs); +GList *e_msg_composer_hdrs_get_bcc (EMsgComposerHdrs *hdrs); + +#ifdef _cplusplus +} +#endif /* _cplusplus */ + + +#endif /* __E_MSG_COMPOSER_HDRS_H__ */ diff --git a/composer/e-msg-composer.c b/composer/e-msg-composer.c new file mode 100644 index 0000000000..f4271ea7e6 --- /dev/null +++ b/composer/e-msg-composer.c @@ -0,0 +1,564 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* e-msg-composer.c + * + * Copyright (C) 1999 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 + */ + +/* + + TODO + + - Somehow users should be able to see if any file(s) are attached even when + the attachment bar is not shown. + +*/ + +#ifdef _HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +#include "e-msg-composer.h" +#include "e-msg-composer-address-dialog.h" +#include "e-msg-composer-attachment-bar.h" +#include "e-msg-composer-hdrs.h" + + +#define DEFAULT_WIDTH 600 +#define DEFAULT_HEIGHT 500 + + +enum { + SEND, + POSTPONE, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +static GnomeAppClass *parent_class = NULL; + + +static void +free_string_list (GList *list) +{ + GList *p; + + if (list == NULL) + return; + + for (p = list; p != NULL; p = p->next) + g_free (p->data); + + g_list_free (list); +} + +/* This functions builds a CamelMimeMessage for the message that the user has + composed in `composer'. */ +static CamelMimeMessage * +build_message (EMsgComposer *composer) +{ + CamelMimeMessage *new; + CamelMimeBodyPart *body_part; + CamelMultipart *multipart; + gchar *text; + + new = camel_mime_message_new_with_session (NULL); + + e_msg_composer_hdrs_to_message (E_MSG_COMPOSER_HDRS (composer->hdrs), + new); + + multipart = camel_multipart_new (); + body_part = camel_mime_body_part_new (); + + text = gtk_editable_get_chars (GTK_EDITABLE (composer->text), 0, -1); + camel_mime_part_set_text (CAMEL_MIME_PART (body_part), text); + camel_multipart_add_part (multipart, body_part); + + e_msg_composer_attachment_bar_to_multipart + (E_MSG_COMPOSER_ATTACHMENT_BAR (composer->attachment_bar), + multipart); + + camel_medium_set_content_object (CAMEL_MEDIUM (new), + CAMEL_DATA_WRAPPER (multipart)); + + /* FIXME refcounting is most certainly wrong. We want all the stuff to + be destroyed when we unref() the message. */ + + return new; +} + + +static void +show_attachments (EMsgComposer *composer, + gboolean show) +{ + if (show) { + gtk_widget_show (composer->attachment_scrolled_window); + gtk_widget_show (composer->attachment_bar); + } else { + gtk_widget_hide (composer->attachment_scrolled_window); + gtk_widget_hide (composer->attachment_bar); + } + + composer->attachment_bar_visible = show; + + /* Update the GUI. */ + + gtk_check_menu_item_set_active + (GTK_CHECK_MENU_ITEM + (glade_xml_get_widget (composer->menubar_gui, + "menu_view_attachments")), + show); + + /* XXX we should update the toggle toolbar item as well. At + this point, it is not a toggle because Glade is broken. */ +} + + +/* Address dialog callbacks. */ + +static void +address_dialog_destroy_cb (GtkWidget *widget, + gpointer data) +{ + EMsgComposer *composer; + + composer = E_MSG_COMPOSER (data); + composer->address_dialog = NULL; +} + +static void +address_dialog_apply_cb (EMsgComposerAddressDialog *dialog, + gpointer data) +{ + EMsgComposerHdrs *hdrs; + GList *list; + + hdrs = E_MSG_COMPOSER_HDRS (E_MSG_COMPOSER (data)->hdrs); + + list = e_msg_composer_address_dialog_get_to_list (dialog); + e_msg_composer_hdrs_set_to (hdrs, list); + + list = e_msg_composer_address_dialog_get_cc_list (dialog); + e_msg_composer_hdrs_set_cc (hdrs, list); + + list = e_msg_composer_address_dialog_get_bcc_list (dialog); + e_msg_composer_hdrs_set_bcc (hdrs, list); +} + + +/* Message composer window callbacks. */ + +static void +send_cb (GtkWidget *widget, + gpointer data) +{ + gtk_signal_emit (GTK_OBJECT (data), signals[SEND]); +} + +static void +menu_view_attachments_activate_cb (GtkWidget *widget, + gpointer data) +{ + e_msg_composer_show_attachments (E_MSG_COMPOSER (data), + GTK_CHECK_MENU_ITEM (widget)->active); +} + +static void +toolbar_view_attachments_clicked_cb (GtkWidget *widget, + gpointer data) +{ + EMsgComposer *composer; + + composer = E_MSG_COMPOSER (data); + + e_msg_composer_show_attachments (composer, + ! composer->attachment_bar_visible); +} + +static void +add_attachment_cb (GtkWidget *widget, + gpointer data) +{ + EMsgComposer *composer; + + composer = E_MSG_COMPOSER (data); + + e_msg_composer_attachment_bar_attach + (E_MSG_COMPOSER_ATTACHMENT_BAR (composer->attachment_bar), + NULL); +} + +/* Create the address dialog if not created already. */ +static void +setup_address_dialog (EMsgComposer *composer) +{ + EMsgComposerAddressDialog *dialog; + EMsgComposerHdrs *hdrs; + GList *list; + + if (composer->address_dialog != NULL) + return; + + composer->address_dialog = e_msg_composer_address_dialog_new (); + dialog = E_MSG_COMPOSER_ADDRESS_DIALOG (composer->address_dialog); + hdrs = E_MSG_COMPOSER_HDRS (composer->hdrs); + + gtk_signal_connect (GTK_OBJECT (dialog), + "destroy", address_dialog_destroy_cb, composer); + gtk_signal_connect (GTK_OBJECT (dialog), + "apply", address_dialog_apply_cb, composer); + + list = e_msg_composer_hdrs_get_to (hdrs); + e_msg_composer_address_dialog_set_to_list (dialog, list); + + list = e_msg_composer_hdrs_get_cc (hdrs); + e_msg_composer_address_dialog_set_cc_list (dialog, list); + + list = e_msg_composer_hdrs_get_bcc (hdrs); + e_msg_composer_address_dialog_set_bcc_list (dialog, list); +} + +static void +address_dialog_cb (GtkWidget *widget, + gpointer data) +{ + EMsgComposer *composer; + + /* FIXME maybe we should hide the dialog on Cancel/OK instead of + destroying it. */ + + composer = E_MSG_COMPOSER (data); + + setup_address_dialog (composer); + + gtk_widget_show (composer->address_dialog); + gdk_window_show (composer->address_dialog->window); +} + +static void +glade_connect (GladeXML *gui, + const gchar *widget_name, + const gchar *signal_name, + GtkSignalFunc callback, + gpointer callback_data) +{ + GtkWidget *widget; + + widget = glade_xml_get_widget (gui, widget_name); + if (widget == NULL) + g_warning ("Widget `%s' was not found.", widget_name); + else + gtk_signal_connect (GTK_OBJECT (widget), signal_name, + GTK_SIGNAL_FUNC (callback), callback_data); +} + +static void +attachment_bar_changed (EMsgComposerAttachmentBar *bar, + gpointer data) +{ + EMsgComposer *composer; + + composer = E_MSG_COMPOSER (data); + + if (e_msg_composer_attachment_bar_get_num_attachments (bar) > 0) + e_msg_composer_show_attachments (composer, TRUE); + else + e_msg_composer_show_attachments (composer, FALSE); +} + +static void +setup_signals (EMsgComposer *composer) +{ + glade_connect (composer->menubar_gui, "menu_send", + "activate", GTK_SIGNAL_FUNC (send_cb), composer); + glade_connect (composer->toolbar_gui, "toolbar_send", + "clicked", GTK_SIGNAL_FUNC (send_cb), composer); + + glade_connect (composer->menubar_gui, "menu_view_attachments", + "activate", + GTK_SIGNAL_FUNC (menu_view_attachments_activate_cb), + composer); + glade_connect (composer->toolbar_gui, "toolbar_view_attachments", + "clicked", + GTK_SIGNAL_FUNC (toolbar_view_attachments_clicked_cb), + composer); + + glade_connect (composer->menubar_gui, "menu_add_attachment", + "activate", + GTK_SIGNAL_FUNC (add_attachment_cb), composer); + glade_connect (composer->toolbar_gui, "toolbar_add_attachment", + "clicked", + GTK_SIGNAL_FUNC (add_attachment_cb), composer); + + glade_connect (composer->menubar_gui, "menubar_address_dialog", + "activate", + GTK_SIGNAL_FUNC (address_dialog_cb), composer); + glade_connect (composer->toolbar_gui, "toolbar_address_dialog", + "clicked", + GTK_SIGNAL_FUNC (address_dialog_cb), composer); + + gtk_signal_connect (GTK_OBJECT (composer->attachment_bar), + "changed", + GTK_SIGNAL_FUNC (attachment_bar_changed), + composer); + + gtk_signal_connect (GTK_OBJECT (composer->hdrs), "show_address_dialog", + GTK_SIGNAL_FUNC (address_dialog_cb), + composer); +} + + +/* GtkObject methods. */ + +static void +destroy (GtkObject *object) +{ + EMsgComposer *composer; + + composer = E_MSG_COMPOSER (object); + + gtk_object_unref (GTK_OBJECT (composer->menubar_gui)); + gtk_object_unref (GTK_OBJECT (composer->toolbar_gui)); + gtk_object_unref (GTK_OBJECT (composer->appbar_gui)); + + if (composer->address_dialog != NULL) + gtk_widget_destroy (composer->address_dialog); + + if (GTK_OBJECT_CLASS (parent_class)->destroy != NULL) + (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); +} + + +static void +class_init (EMsgComposerClass *klass) +{ + GtkObjectClass *object_class; + + object_class = (GtkObjectClass *) klass; + + object_class->destroy = destroy; + + parent_class = gtk_type_class (gnome_app_get_type ()); + + signals[SEND] = + gtk_signal_new ("send", + GTK_RUN_LAST, + object_class->type, + GTK_SIGNAL_OFFSET (EMsgComposerClass, send), + gtk_marshal_NONE__NONE, + GTK_TYPE_NONE, 0); + + signals[POSTPONE] = + gtk_signal_new ("postpone", + GTK_RUN_LAST, + object_class->type, + GTK_SIGNAL_OFFSET (EMsgComposerClass, postpone), + gtk_marshal_NONE__NONE, + GTK_TYPE_NONE, 0); + + gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL); +} + +static void +init (EMsgComposer *composer) +{ + composer->menubar_gui = NULL; + composer->toolbar_gui = NULL; + composer->appbar_gui = NULL; + + composer->hdrs = NULL; + + composer->text = NULL; + composer->text_scrolled_window = NULL; + + composer->address_dialog = NULL; + + composer->attachment_bar = NULL; + composer->attachment_scrolled_window = NULL; +} + + +GtkType +e_msg_composer_get_type (void) +{ + static GtkType type = 0; + + if (type == 0) { + static const GtkTypeInfo info = { + "EMsgComposer", + sizeof (EMsgComposer), + sizeof (EMsgComposerClass), + (GtkClassInitFunc) class_init, + (GtkObjectInitFunc) init, + /* reserved_1 */ NULL, + /* reserved_2 */ NULL, + (GtkClassInitFunc) NULL, + }; + + type = gtk_type_unique (gnome_app_get_type (), &info); + } + + return type; +} + + +/** + * e_msg_composer_construct: + * @composer: A message composer widget + * + * Construct @composer. + **/ +void +e_msg_composer_construct (EMsgComposer *composer) +{ + GtkWidget *vbox; + + gtk_window_set_default_size (GTK_WINDOW (composer), + DEFAULT_WIDTH, DEFAULT_HEIGHT); + + gnome_app_construct (GNOME_APP (composer), "e-msg-composer", + "Compose a message"); + + composer->menubar_gui = glade_xml_new (E_GLADEDIR "/e-msg-composer.glade", + "menubar"); + gnome_app_set_menus (GNOME_APP (composer), + GTK_MENU_BAR (glade_xml_get_widget (composer->menubar_gui, + "menubar"))); + + composer->toolbar_gui = glade_xml_new (E_GLADEDIR "/e-msg-composer.glade", + "toolbar"); + gnome_app_set_toolbar (GNOME_APP (composer), + GTK_TOOLBAR (glade_xml_get_widget (composer->toolbar_gui, + "toolbar"))); + + composer->appbar_gui = glade_xml_new (E_GLADEDIR "/e-msg-composer.glade", + "appbar"); + gnome_app_set_statusbar (GNOME_APP (composer), + glade_xml_get_widget (composer->appbar_gui, + "appbar")); + + vbox = gtk_vbox_new (FALSE, 0); + + composer->hdrs = e_msg_composer_hdrs_new (); + gtk_box_pack_start (GTK_BOX (vbox), composer->hdrs, FALSE, TRUE, 0); + gtk_widget_show (composer->hdrs); + + /* GtkText for message body editing, wrapped into a + GtkScrolledWindow. */ + + composer->text_scrolled_window = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy + (GTK_SCROLLED_WINDOW (composer->text_scrolled_window), + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + composer->text = gtk_text_new (NULL, NULL); + gtk_text_set_word_wrap (GTK_TEXT (composer->text), FALSE); + gtk_text_set_editable (GTK_TEXT (composer->text), TRUE); + gtk_container_add (GTK_CONTAINER (composer->text_scrolled_window), + composer->text); + gtk_widget_show (composer->text); + gtk_box_pack_start (GTK_BOX (vbox), composer->text_scrolled_window, + TRUE, TRUE, 0); + gtk_widget_show (composer->text_scrolled_window); + + /* Attachment editor, wrapped into a GtkScrolledWindow. We don't + show it for now. */ + + composer->attachment_scrolled_window = gtk_scrolled_window_new (NULL, + NULL); + gtk_scrolled_window_set_policy + (GTK_SCROLLED_WINDOW (composer->attachment_scrolled_window), + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + composer->attachment_bar = e_msg_composer_attachment_bar_new (NULL); + GTK_WIDGET_SET_FLAGS (composer->attachment_bar, GTK_CAN_FOCUS); + gtk_container_add (GTK_CONTAINER (composer->attachment_scrolled_window), + composer->attachment_bar); + gtk_box_pack_start (GTK_BOX (vbox), + composer->attachment_scrolled_window, + FALSE, TRUE, GNOME_PAD_SMALL); + + gnome_app_set_contents (GNOME_APP (composer), vbox); + gtk_widget_show (vbox); + + e_msg_composer_show_attachments (composer, FALSE); + + setup_signals (composer); +} + +/** + * e_msg_composer_new: + * + * Create a new message composer widget. + * + * Return value: A pointer to the newly created widget + **/ +GtkWidget * +e_msg_composer_new (void) +{ + GtkWidget *new; + + new = gtk_type_new (e_msg_composer_get_type ()); + e_msg_composer_construct (E_MSG_COMPOSER (new)); + + return new; +} + + +/** + * e_msg_composer_show_attachments: + * @composer: A message composer widget + * @show: A boolean specifying whether the attachment bar should be shown or + * not + * + * If @show is %FALSE, hide the attachment bar. Otherwise, show it. + **/ +void +e_msg_composer_show_attachments (EMsgComposer *composer, + gboolean show) +{ + g_return_if_fail (composer != NULL); + g_return_if_fail (E_IS_MSG_COMPOSER (composer)); + + show_attachments (composer, show); +} + + +/** + * e_msg_composer_get_message: + * @composer: A message composer widget + * + * Retrieve the message edited by the user as a CamelMimeMessage. The + * CamelMimeMessage object is created on the fly; subsequent calls to this + * function will always create new objects from scratch. + * + * Return value: A pointer to the new CamelMimeMessage object + **/ +CamelMimeMessage * +e_msg_composer_get_message (EMsgComposer *composer) +{ + g_return_val_if_fail (composer != NULL, NULL); + g_return_val_if_fail (E_IS_MSG_COMPOSER (composer), NULL); + + return build_message (composer); +} diff --git a/composer/e-msg-composer.glade b/composer/e-msg-composer.glade new file mode 100644 index 0000000000..b747c6f979 --- /dev/null +++ b/composer/e-msg-composer.glade @@ -0,0 +1,587 @@ + + + + + Message Composer + e-msg-composer + + src + pixmaps + C + True + True + False + True + True + True + True + interface.c + interface.h + callbacks.c + callbacks.h + support.c + support.h + + + + + GnomeApp + app1 + Message Composer + GTK_WINDOW_TOPLEVEL + GTK_WIN_POS_NONE + False + False + True + False + True + + + GnomeDock + GnomeApp:dock + dock1 + True + + 0 + True + True + + + + GnomeDockItem + dockitem1 + 2 + GNOME_DOCK_TOP + 0 + 0 + 0 + False + True + False + True + False + GTK_SHADOW_OUT + + + GtkMenuBar + menubar + GTK_SHADOW_NONE + + + GtkMenuItem + file + GNOMEUIINFO_MENU_FILE_TREE + + + GtkMenu + file_menu + + + GtkPixmapMenuItem + open + + activate + on_open_activate + Wed, 27 Oct 1999 22:25:08 GMT + + GNOMEUIINFO_MENU_OPEN_ITEM + + + + GtkPixmapMenuItem + save + + activate + on_save_activate + Wed, 27 Oct 1999 22:25:13 GMT + + GNOMEUIINFO_MENU_SAVE_ITEM + + + + GtkPixmapMenuItem + save_as + + activate + on_save_as_activate + Wed, 27 Oct 1999 22:25:16 GMT + + GNOMEUIINFO_MENU_SAVE_AS_ITEM + + + + GtkPixmapMenuItem + save_in_folder + + activate + on_save_in_folder_activate + Wed, 27 Oct 1999 22:25:20 GMT + + + False + GNOME_STOCK_MENU_SAVE_AS + + + + GtkMenuItem + separator8 + False + + + + GtkPixmapMenuItem + menu_send + + activate + on_send_activate + Wed, 27 Oct 1999 22:25:29 GMT + + + False + GNOME_STOCK_MENU_MAIL_SND + + + + GtkMenuItem + postpone + + activate + on_postpone_activate + Wed, 27 Oct 1999 22:25:37 GMT + + + False + + + + GtkMenuItem + separator1 + False + + + + GtkPixmapMenuItem + exit + + activate + on_exit_activate + Wed, 27 Oct 1999 22:25:59 GMT + + GNOMEUIINFO_MENU_EXIT_ITEM + + + + + + GtkMenuItem + edit + GNOMEUIINFO_MENU_EDIT_TREE + + + GtkMenu + edit_menu + + + GtkPixmapMenuItem + undo + + activate + on_undo_activate + Wed, 27 Oct 1999 22:26:10 GMT + + GNOMEUIINFO_MENU_UNDO_ITEM + + + + GtkPixmapMenuItem + redo + + activate + on_redo_activate + Wed, 27 Oct 1999 22:26:15 GMT + + GNOMEUIINFO_MENU_REDO_ITEM + + + + GtkMenuItem + separator3 + False + + + + GtkPixmapMenuItem + cut + + activate + on_cut_activate + Wed, 27 Oct 1999 22:26:21 GMT + + GNOMEUIINFO_MENU_CUT_ITEM + + + + GtkPixmapMenuItem + copy + + activate + on_copy_activate + Wed, 27 Oct 1999 22:26:26 GMT + + GNOMEUIINFO_MENU_COPY_ITEM + + + + GtkPixmapMenuItem + paste + + activate + on_paste_activate + Wed, 27 Oct 1999 22:26:31 GMT + + GNOMEUIINFO_MENU_PASTE_ITEM + + + + GtkMenuItem + separator2 + False + + + + GtkPixmapMenuItem + select_all + + activate + on_select_all_activate + Wed, 27 Oct 1999 22:26:37 GMT + + GNOMEUIINFO_MENU_SELECT_ALL_ITEM + + + + GtkMenuItem + separator5 + False + + + + GtkPixmapMenuItem + find + + activate + on_find_activate + Wed, 27 Oct 1999 22:26:42 GMT + + GNOMEUIINFO_MENU_FIND_ITEM + + + + GtkPixmapMenuItem + find_again + + activate + on_find_again_activate + Wed, 27 Oct 1999 22:26:47 GMT + + GNOMEUIINFO_MENU_FIND_AGAIN_ITEM + + + + GtkPixmapMenuItem + replace + + activate + on_replace_activate + Wed, 27 Oct 1999 22:26:53 GMT + + GNOMEUIINFO_MENU_REPLACE_ITEM + + + + GtkMenuItem + separator6 + False + + + + GtkPixmapMenuItem + properties + + activate + on_properties_activate + Wed, 27 Oct 1999 22:26:58 GMT + + GNOMEUIINFO_MENU_PROPERTIES_ITEM + + + + + + GtkMenuItem + view1 + GNOMEUIINFO_MENU_VIEW_TREE + + + GtkMenu + view1_menu + + + GtkCheckMenuItem + menu_view_attachments + + activate + on_view_attachments_activate + Fri, 05 Nov 1999 18:31:16 GMT + + + False + False + + + + + + GtkMenuItem + insert + + False + + + GtkMenu + insert_menu + + + GtkMenuItem + menu_add_attachment + + activate + on_attachment_activate + Wed, 27 Oct 1999 22:27:05 GMT + + + False + + + + GtkMenuItem + text_from_file + + activate + on_text_from_file_activate + Wed, 27 Oct 1999 22:27:16 GMT + + + False + + + + GtkMenuItem + separator6 + False + + + + GtkMenuItem + hypertext_link + + activate + on_hypertext_link_activate + Wed, 27 Oct 1999 22:27:21 GMT + + + False + + + + + + GtkMenuItem + settings + GNOMEUIINFO_MENU_SETTINGS_TREE + + + GtkMenu + settings_menu + + + GtkPixmapMenuItem + preferences + + activate + on_preferences_activate + Wed, 27 Oct 1999 22:27:37 GMT + + GNOMEUIINFO_MENU_PREFERENCES_ITEM + + + + + + GtkMenuItem + tools + + False + + + GtkMenu + tools_menu + + + GtkPixmapMenuItem + spell_check1 + + activate + on_spell_check_activate + Wed, 27 Oct 1999 22:27:44 GMT + + + False + GNOME_STOCK_MENU_SPELLCHECK + + + + GtkMenuItem + separator7 + False + + + + GtkMenuItem + check_names + + activate + on_check_names_activate + Wed, 27 Oct 1999 22:27:49 GMT + + + False + + + + GtkPixmapMenuItem + menubar_address_dialog + + activate + on_address_book_activate + Wed, 27 Oct 1999 22:27:53 GMT + + + False + GNOME_STOCK_MENU_BOOK_RED + + + + + + GtkMenuItem + help + GNOMEUIINFO_MENU_HELP_TREE + + + GtkMenu + help_menu + + + GtkPixmapMenuItem + about + + activate + on_about_activate + Wed, 27 Oct 1999 22:28:01 GMT + + GNOMEUIINFO_MENU_ABOUT_ITEM + + + + + + + + GnomeDockItem + dockitem2 + 1 + GNOME_DOCK_TOP + 1 + 0 + 0 + False + True + False + False + False + GTK_SHADOW_OUT + + + GtkToolbar + toolbar + 1 + GTK_ORIENTATION_HORIZONTAL + GTK_TOOLBAR_BOTH + 16 + GTK_TOOLBAR_SPACE_LINE + GTK_RELIEF_NONE + True + + + GtkButton + Toolbar:button + toolbar_send + Send this message + + GNOME_STOCK_PIXMAP_MAIL_SND + + + + GtkToggleButton + Toolbar:button + toolbar_view_attachments + Show attachments for this message + + False + + + + GtkButton + Toolbar:button + toolbar_add_attachment + Attach a file + + + + + GtkButton + Toolbar:button + toolbar_address_dialog + Go to addressbook + + GNOME_STOCK_PIXMAP_BOOK_RED + + + + + + Placeholder + GnomeDock:contents + + + + + GnomeAppBar + GnomeApp:appbar + appbar + True + True + + 0 + True + True + + + + + diff --git a/composer/e-msg-composer.h b/composer/e-msg-composer.h new file mode 100644 index 0000000000..3028dedca3 --- /dev/null +++ b/composer/e-msg-composer.h @@ -0,0 +1,87 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* e-msg-composer.h + * + * Copyright (C) 1999 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 ___E_MSG_COMPOSER_H__ +#define ___E_MSG_COMPOSER_H__ + +#include +#include + +#include "e-msg-composer-attachment-bar.h" +#include "e-msg-composer-hdrs.h" + +#ifdef __cplusplus +extern "C" { +#pragma } +#endif /* __cplusplus */ + + +#define E_TYPE_MSG_COMPOSER (e_msg_composer_get_type ()) +#define E_MSG_COMPOSER(obj) (GTK_CHECK_CAST ((obj), E_TYPE_MSG_COMPOSER, EMsgComposer)) +#define E_MSG_COMPOSER_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_TYPE_MSG_COMPOSER, EMsgComposerClass)) +#define E_IS_MSG_COMPOSER(obj) (GTK_CHECK_TYPE ((obj), E_TYPE_MSG_COMPOSER)) +#define E_IS_MSG_COMPOSER_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), E_TYPE_MSG_COMPOSER)) + + +typedef struct _EMsgComposer EMsgComposer; +typedef struct _EMsgComposerClass EMsgComposerClass; + +struct _EMsgComposer { + GnomeApp parent; + + GladeXML *menubar_gui; + GladeXML *toolbar_gui; + GladeXML *appbar_gui; + + GtkWidget *hdrs; + + GtkWidget *text; + GtkWidget *text_scrolled_window; + + GtkWidget *attachment_bar; + GtkWidget *attachment_scrolled_window; + + GtkWidget *address_dialog; + + gboolean attachment_bar_visible : 1; +}; + +struct _EMsgComposerClass { + GnomeAppClass parent_class; + + void (* send) (EMsgComposer *composer); + void (* postpone) (EMsgComposer *composer); +}; + + +GtkType e_msg_composer_get_type (void); +void e_msg_composer_construct (EMsgComposer *composer); +GtkWidget *e_msg_composer_new (void); +void e_msg_composer_show_attachments (EMsgComposer *composer, gboolean show); +CamelMimeMessage *e_msg_composer_get_message (EMsgComposer *composer); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* ___E_MSG_COMPOSER_H__ */ diff --git a/composer/main.c b/composer/main.c new file mode 100644 index 0000000000..8fbf01b5e8 --- /dev/null +++ b/composer/main.c @@ -0,0 +1,52 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +#include + +#include +#include +#include + +#include "e-msg-composer.h" + +static void +send_cb (EMsgComposer *composer, + gpointer data) +{ + CamelMimeMessage *message; + CamelStream *stream; + gint stdout_dup; + + message = e_msg_composer_get_message (composer); + + stdout_dup = dup (1); + stream = camel_stream_fs_new_with_fd (stdout_dup); + camel_data_wrapper_write_to_stream (CAMEL_DATA_WRAPPER (message), + stream); + camel_stream_close (stream); + + gtk_object_unref (GTK_OBJECT (message)); + +#if 0 + gtk_widget_destroy (GTK_WIDGET (composer)); + gtk_main_quit (); +#endif +} + +int +main (int argc, char **argv) +{ + GtkWidget *composer; + + gnome_init ("test", "0.0", argc, argv); + glade_gnome_init (); + + composer = e_msg_composer_new (); + gtk_widget_show (composer); + + gtk_signal_connect (GTK_OBJECT (composer), "send", + GTK_SIGNAL_FUNC (send_cb), NULL); + + gtk_main (); + + return 0; +} diff --git a/configure.in b/configure.in index e59611e040..d81d21c411 100644 --- a/configure.in +++ b/configure.in @@ -102,6 +102,7 @@ camel/Makefile camel/providers/Makefile camel/providers/MH/Makefile camel/providers/maildir/Makefile +composer/Makefile devel-docs/Makefile devel-docs/camel/Makefile tests/Makefile diff --git a/tests/test1.c b/tests/test1.c index 1adaf0b163..5caac29c74 100644 --- a/tests/test1.c +++ b/tests/test1.c @@ -57,12 +57,18 @@ main (int argc, char**argv) camel_mime_message_set_reply_to (message, g_strdup ("toto@toto.com")); camel_mime_message_set_from (message, g_strdup ("Bertrand.Guiheneuf@aful.org")); - camel_mime_message_add_recipient (message, RECIPIENT_TYPE_TO, g_strdup ("franck.dechamps@alseve.fr")); - camel_mime_message_add_recipient (message, RECIPIENT_TYPE_TO, g_strdup ("mc@alseve.fr")); - camel_mime_message_add_recipient (message, RECIPIENT_TYPE_TO, g_strdup ("richard.lengagne@aful.org")); - camel_mime_message_add_recipient (message, RECIPIENT_TYPE_CC, g_strdup ("Francois.fleuret@aful.org")); - camel_mime_message_add_recipient (message, RECIPIENT_TYPE_CC, g_strdup ("maury@justmagic.com")); - camel_mime_message_add_recipient (message, RECIPIENT_TYPE_BCC, g_strdup ("Bertrand.Guiheneuf@aful.org")); + camel_mime_message_add_recipient (message, CAMEL_RECIPIENT_TYPE_TO, + g_strdup ("franck.dechamps@alseve.fr")); + camel_mime_message_add_recipient (message, CAMEL_RECIPIENT_TYPE_TO, + g_strdup ("mc@alseve.fr")); + camel_mime_message_add_recipient (message, CAMEL_RECIPIENT_TYPE_TO, + g_strdup ("richard.lengagne@aful.org")); + camel_mime_message_add_recipient (message, CAMEL_RECIPIENT_TYPE_CC, + g_strdup ("Francois.fleuret@aful.org")); + camel_mime_message_add_recipient (message, CAMEL_RECIPIENT_TYPE_CC, + g_strdup ("maury@justmagic.com")); + camel_mime_message_add_recipient (message, CAMEL_RECIPIENT_TYPE_BCC, + g_strdup ("Bertrand.Guiheneuf@aful.org")); multipart = camel_multipart_new (); body_part = camel_mime_body_part_new (); diff --git a/tests/ui-tests/Makefile.am b/tests/ui-tests/Makefile.am index 24d62047db..7c26399bbb 100644 --- a/tests/ui-tests/Makefile.am +++ b/tests/ui-tests/Makefile.am @@ -14,6 +14,3 @@ LDADD = \ $(INTLLIBS) \ $(EXTRA_GNOME_LIBS) \ $(PTHREAD_LIB) - -noinst_PROGRAMS = \ - msg-composer-test \ No newline at end of file diff --git a/widgets/ChangeLog b/widgets/ChangeLog index a2fa977553..01244d9674 100644 --- a/widgets/ChangeLog +++ b/widgets/ChangeLog @@ -1,3 +1,22 @@ +1999-11-17 Ettore Perazzoli + + * e-msg-composer-address-dialog.c: Moved to `$(srcdir)/composer'. + * e-msg-composer-address-dialog.h: Likewise. + * e-msg-composer-address-entry.c: Likewise. + * e-msg-composer-address-entry.h: Likewise. + * e-msg-composer-attachment-bar.c: Likewise. + * e-msg-composer-attachment-bar.h: Likewise. + * e-msg-composer-attachment.c: Likewise. + * e-msg-composer-attachment.h: Likewise. + * e-msg-composer-hdrs.c: Likewise. + * e-msg-composer-hdrs.h: Likewise. + * e-msg-composer.c: Likewise. + * e-msg-composer.h: Likewise. + * e-msg-composer-address-dialog.glade: Likewise. + * e-msg-composer-attachment.glade: Likewise. + * e-msg-composer.glade: Likewise. + * Makefile.am: Updated accordingly. + Nov 14 1999 Elliot Lee * Makefile.am: It's libevolutionwidgets.la, not .a diff --git a/widgets/Makefile.am b/widgets/Makefile.am index d7c28475d1..f4b3c111cd 100644 --- a/widgets/Makefile.am +++ b/widgets/Makefile.am @@ -1,36 +1,14 @@ -guidir = $(datadir)/evolution/gui - -gui_DATA = \ - e-msg-composer-address-dialog.glade \ - e-msg-composer-attachment.glade \ - e-msg-composer.glade - INCLUDES = \ -I$(top_srcdir)/camel \ -I$(top_builddir)/camel \ $(GNOME_INCLUDEDIR) -CPPFLAGS = \ - -DE_GUIDIR=\"$(guidir)\" - noinst_LIBRARIES = \ libevolutionwidgets.a libevolutionwidgets_a_SOURCES = \ e-cursors.c \ e-cursors.h \ - e-msg-composer-address-dialog.c \ - e-msg-composer-address-dialog.h \ - e-msg-composer-address-entry.c \ - e-msg-composer-address-entry.h \ - e-msg-composer-attachment-bar.c \ - e-msg-composer-attachment-bar.h \ - e-msg-composer-attachment.c \ - e-msg-composer-attachment.h \ - e-msg-composer-hdrs.c \ - e-msg-composer-hdrs.h \ - e-msg-composer.c \ - e-msg-composer.h \ e-table-col.c \ e-table-col.h \ e-table-group.c \ diff --git a/widgets/e-msg-composer-address-dialog.c b/widgets/e-msg-composer-address-dialog.c deleted file mode 100644 index 412ab987df..0000000000 --- a/widgets/e-msg-composer-address-dialog.c +++ /dev/null @@ -1,659 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* e-msg-composer-address-dialog.c - * - * Copyright (C) 1999 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 - */ - -#include -#include "e-msg-composer-address-dialog.h" - - -enum { - APPLY, - LAST_SIGNAL -}; -static guint signals[LAST_SIGNAL] = { 0 }; - -static GnomeDialogClass *parent_class = NULL; - - -/* This function should load the addresses we know of into the dialog. We - don't have a precise setup for the addressbook yet, so we will just put some - fake entries in. */ -static void -load_addresses (EMsgComposerAddressDialog *dialog) -{ - gchar *text[][3] = { - { "Bertrand Guiheneuf", "Bertrand.Guiheneuf@aful.org", NULL }, - { "Ettore Perazzoli", "ettore@gnu.org", NULL }, - { "Miguel de Icaza", "miguel@gnu.org", NULL }, - { "Nat Friedman", "nat@nat.org", NULL }, - { NULL, NULL, NULL } - }; - GtkCList *clist; - guint i; - - clist = GTK_CLIST (glade_xml_get_widget (dialog->gui, "address_clist")); - - for (i = 0; text[i][0] != NULL; i++) - gtk_clist_append (clist, text[i]); -} - -/* Combine name and email into an address, e.g. "Ettore Perazzoli - ". FIXME FIXME FIXME this does not handle quoting (commas - will cause troubles), but it should. */ -static gchar * -make_full_address (const gchar *name, - const gchar *email) -{ - return g_strconcat (name, " <", email, ">", NULL); -} - -/* This loads the selected address in the address GtkCList into the requested - GtkList. */ -static void -add_address (EMsgComposerAddressDialog *dialog, - const gchar *list_name) -{ - GtkCList *src_clist; - GtkCList *dest_clist; - gchar *name, *email; - gchar *text[2]; - guint row; - - src_clist = GTK_CLIST (glade_xml_get_widget (dialog->gui, - "address_clist")); - if (src_clist->selection == NULL) - return; - - dest_clist = GTK_CLIST (glade_xml_get_widget (dialog->gui, list_name)); - row = GPOINTER_TO_INT (src_clist->selection->data); - - gtk_clist_get_text (src_clist, row, 0, &name); - gtk_clist_get_text (src_clist, row, 1, &email); - - text[0] = make_full_address (name, email); - text[1] = NULL; - - gtk_clist_append (dest_clist, text); - - g_free (text[0]); -} - -static void -apply (EMsgComposerAddressDialog *dialog) -{ - gtk_signal_emit (GTK_OBJECT (dialog), signals[APPLY]); -} - - -/* Recipient list popup menu. */ - -struct _RecipientListInfo { - EMsgComposerAddressDialog *dialog; - GtkCList *clist; - gint row; /* -1 if menu was popped up in an empty - area. */ -}; -typedef struct _RecipientListInfo RecipientListInfo; - -static void -copy_recipient (RecipientListInfo *info, - gboolean remove) -{ - gchar *text; - gint row; - - if (info->clist->selection == NULL) - return; - - row = GPOINTER_TO_INT (info->clist->selection->data); - gtk_clist_get_text (info->clist, row, 0, &text); - - g_free (info->dialog->cut_buffer); - info->dialog->cut_buffer = g_strdup (text); - - if (remove) - gtk_clist_remove (info->clist, row); - - gtk_selection_owner_set (GTK_WIDGET (info->clist), - GDK_SELECTION_PRIMARY, - GDK_CURRENT_TIME); -} - -static void -copy_recipient_cb (GtkWidget *widget, - gpointer data) -{ - RecipientListInfo *info; - - info = (RecipientListInfo *) data; - copy_recipient (info, FALSE); - g_free (info); -} - -static void -cut_recipient_cb (GtkWidget *widget, - gpointer data) -{ - RecipientListInfo *info; - - info = (RecipientListInfo *) data; - copy_recipient (info, TRUE); - g_free (info); -} - -static void -paste_recipient_cb (GtkWidget *widget, - gpointer data) -{ - RecipientListInfo *info; - GdkAtom atom; - gchar *text[2]; - - info = (RecipientListInfo *) data; - - atom = gdk_atom_intern ("STRING", FALSE); - gtk_selection_convert (GTK_WIDGET (info->clist), - GDK_SELECTION_PRIMARY, - atom, - GDK_CURRENT_TIME); - - g_free (info); -} - -static GnomeUIInfo recipient_list_item_popup_info[] = { - GNOMEUIINFO_ITEM_STOCK (N_("Cut"), - N_("Cut selected item into clipboard"), - cut_recipient_cb, - GNOME_STOCK_MENU_CUT), - GNOMEUIINFO_ITEM_STOCK (N_("Copy"), - N_("Copy selected item into clipboard"), - copy_recipient_cb, - GNOME_STOCK_MENU_COPY), - GNOMEUIINFO_ITEM_STOCK (N_("Paste"), - N_("Paste item from clipboard"), - paste_recipient_cb, - GNOME_STOCK_MENU_PASTE), - GNOMEUIINFO_END -}; - -static GnomeUIInfo recipient_list_popup_info[] = { - GNOMEUIINFO_ITEM_STOCK (N_("Paste"), - N_("Paste item from clipboard"), - paste_recipient_cb, - GNOME_STOCK_MENU_PASTE), - GNOMEUIINFO_END -}; - - -/* Signals. */ - -static void -add_to_cb (GtkWidget *widget, - gpointer data) -{ - add_address (E_MSG_COMPOSER_ADDRESS_DIALOG (data), "to_clist"); -} - -static void -add_cc_cb (GtkWidget *widget, - gpointer data) -{ - add_address (E_MSG_COMPOSER_ADDRESS_DIALOG (data), "cc_clist"); -} - -static void -add_bcc_cb (GtkWidget *widget, - gpointer data) -{ - add_address (E_MSG_COMPOSER_ADDRESS_DIALOG (data), "bcc_clist"); -} - -static void -glade_connect (GladeXML *gui, - const gchar *widget_name, - const gchar *signal_name, - GtkSignalFunc callback, - gpointer callback_data) -{ - GtkWidget *widget; - - widget = glade_xml_get_widget (gui, widget_name); - if (widget == NULL) - g_warning ("Widget `%s' was not found.", widget_name); - else - gtk_signal_connect (GTK_OBJECT (widget), signal_name, - GTK_SIGNAL_FUNC (callback), callback_data); -} - -static gint -recipient_clist_button_press_cb (GtkWidget *widget, - GdkEventButton *event, - gpointer data) -{ - EMsgComposerAddressDialog *dialog; - RecipientListInfo *info; - GtkWidget *popup; - GtkCList *clist; - gboolean on_row; - gint row, column; - - dialog = E_MSG_COMPOSER_ADDRESS_DIALOG (data); - - clist = GTK_CLIST (widget); - - if (event->window != clist->clist_window || event->button != 3) - return FALSE; - - on_row = gtk_clist_get_selection_info (clist, event->x, event->y, - &row, &column); - - info = g_new (RecipientListInfo, 1); - info->dialog = dialog; - info->clist = clist; - - if (on_row) { - gtk_clist_unselect_all (clist); - gtk_clist_select_row (clist, row, 0); - info->row = row; - popup = gnome_popup_menu_new (recipient_list_item_popup_info); - } else { - info->row = -1; - popup = gnome_popup_menu_new (recipient_list_popup_info); - } - - gnome_popup_menu_do_popup_modal (popup, NULL, NULL, event, info); - - gtk_widget_destroy (popup); - - return TRUE; -} - -/* FIXME needs more work. */ -static void -recipient_clist_selection_received_cb (GtkWidget *widget, - GtkSelectionData *selection_data, - guint time, - gpointer data) -{ - GtkCList *clist; - gchar *text[2]; - gchar *p; - - puts (__FUNCTION__); - - if (selection_data->length < 0) - return; - - clist = GTK_CLIST (widget); - - /* FIXME quoting. */ - text[0] = g_strdup (selection_data->data); - text[1] = NULL; - - /* It is a common mistake to paste `\n's, let's work around that. */ - for (p = text[0]; *p != '\0'; p++) { - if (*p == '\n') { - *p = '\0'; - break; - } - } - - if (clist->selection != NULL) { - gint row; - - row = GPOINTER_TO_INT (clist->selection->data); - gtk_clist_insert (clist, row, text); - } else { - gtk_clist_append (clist, text); - } - - g_free (text[0]); -} - -static void -recipient_clist_selection_get_cb (GtkWidget *widget, - GtkSelectionData *selection_data, - guint info, - guint time, - gpointer data) -{ - EMsgComposerAddressDialog *dialog; - GdkAtom atom; - - puts (__FUNCTION__); - - dialog = E_MSG_COMPOSER_ADDRESS_DIALOG (data); - if (dialog->cut_buffer == NULL) - return; /* FIXME should I do something special? */ - - atom = gdk_atom_intern ("STRING", FALSE); - gtk_selection_data_set (selection_data, atom, 8, - dialog->cut_buffer, - strlen (dialog->cut_buffer)); -} - -static void -recipient_clist_selection_clear_event_cb (GtkWidget *widget, - GdkEventSelection *selection, - gpointer data) -{ - EMsgComposerAddressDialog *dialog; - - dialog = E_MSG_COMPOSER_ADDRESS_DIALOG (data); - g_free (dialog->cut_buffer); - dialog->cut_buffer = NULL; -} - -static void -setup_recipient_list_signals (EMsgComposerAddressDialog *dialog, - const gchar *name) -{ - glade_connect (dialog->gui, name, "button_press_event", - GTK_SIGNAL_FUNC (recipient_clist_button_press_cb), - dialog); - glade_connect (dialog->gui, name, "selection_received", - GTK_SIGNAL_FUNC (recipient_clist_selection_received_cb), - dialog); - glade_connect (dialog->gui, name, "selection_get", - GTK_SIGNAL_FUNC (recipient_clist_selection_get_cb), - dialog); - glade_connect (dialog->gui, name, "selection_clear_event", - GTK_SIGNAL_FUNC (recipient_clist_selection_clear_event_cb), - dialog); -} - -static void -setup_signals (EMsgComposerAddressDialog *dialog) -{ - glade_connect (dialog->gui, "to_add_button", "clicked", - GTK_SIGNAL_FUNC (add_to_cb), dialog); - glade_connect (dialog->gui, "cc_add_button", "clicked", - GTK_SIGNAL_FUNC (add_cc_cb), dialog); - glade_connect (dialog->gui, "bcc_add_button", "clicked", - GTK_SIGNAL_FUNC (add_bcc_cb), dialog); - - setup_recipient_list_signals (dialog, "to_clist"); - setup_recipient_list_signals (dialog, "cc_clist"); - setup_recipient_list_signals (dialog, "bcc_clist"); -} - - -static void -setup_selection_targets (EMsgComposerAddressDialog *dialog) -{ - gtk_selection_add_target (glade_xml_get_widget (dialog->gui, "to_clist"), - GDK_SELECTION_PRIMARY, - GDK_SELECTION_TYPE_STRING, 0); - gtk_selection_add_target (glade_xml_get_widget (dialog->gui, "cc_clist"), - GDK_SELECTION_PRIMARY, - GDK_SELECTION_TYPE_STRING, 0); - gtk_selection_add_target (glade_xml_get_widget (dialog->gui, "bcc_clist"), - GDK_SELECTION_PRIMARY, - GDK_SELECTION_TYPE_STRING, 0); -} - - -/* GnomeDialog methods. */ - -static void -clicked (GnomeDialog *dialog, - gint button_number) -{ - switch (button_number) { - case 0: /* OK */ - apply (E_MSG_COMPOSER_ADDRESS_DIALOG (dialog)); - gnome_dialog_close (dialog); - break; - case 1: /* Apply */ - apply (E_MSG_COMPOSER_ADDRESS_DIALOG (dialog)); - break; - case 2: /* Cancel */ - gnome_dialog_close (dialog); - break; - } -} - - -/* GtkObject methods. */ - -static void -destroy (GtkObject *object) -{ - EMsgComposerAddressDialog *dialog; - GtkCList *address_clist; - GList *p; - - dialog = E_MSG_COMPOSER_ADDRESS_DIALOG (object); - - gtk_object_unref (GTK_OBJECT (dialog->gui)); - g_free (dialog->cut_buffer); - - if (GTK_OBJECT_CLASS (parent_class)->destroy != NULL) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - - -/* Initialization. */ - -static void -class_init (EMsgComposerAddressDialogClass *class) -{ - GtkObjectClass *object_class; - GnomeDialogClass *gnome_dialog_class; - - object_class = GTK_OBJECT_CLASS (class); - object_class->destroy = destroy; - - gnome_dialog_class = GNOME_DIALOG_CLASS (class); - gnome_dialog_class->clicked = clicked; - - parent_class = gtk_type_class (gnome_dialog_get_type ()); - - signals[APPLY] - = gtk_signal_new ("apply", - GTK_RUN_FIRST, - object_class->type, - GTK_SIGNAL_OFFSET (EMsgComposerAddressDialogClass, - apply), - gtk_marshal_NONE__NONE, - GTK_TYPE_NONE, 0); - - gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL); -} - -static void -init (EMsgComposerAddressDialog *dialog) -{ - dialog->gui = NULL; - dialog->cut_buffer = NULL; -} - - -GtkType -e_msg_composer_address_dialog_get_type (void) -{ - static GtkType type = 0; - - if (type == 0) { - static const GtkTypeInfo info = { - "EMsgComposerAddressDialog", - sizeof (EMsgComposerAddressDialog), - sizeof (EMsgComposerAddressDialogClass), - (GtkClassInitFunc) class_init, - (GtkObjectInitFunc) init, - /* reserved_1 */ NULL, - /* reserved_2 */ NULL, - (GtkClassInitFunc) NULL, - }; - - type = gtk_type_unique (gnome_dialog_get_type (), &info); - } - - return type; -} - -void -e_msg_composer_address_dialog_construct (EMsgComposerAddressDialog *dialog) -{ - static const gchar *buttons[] = { - GNOME_STOCK_BUTTON_OK, - GNOME_STOCK_BUTTON_APPLY, - GNOME_STOCK_BUTTON_CANCEL, - NULL - }; - - g_return_if_fail (dialog != NULL); - g_return_if_fail (E_IS_MSG_COMPOSER_ADDRESS_DIALOG (dialog)); - - gnome_dialog_constructv (GNOME_DIALOG (dialog), - _("Select recipients' addresses"), - buttons); - - dialog->gui = glade_xml_new - (E_GUIDIR "/e-msg-composer-address-dialog.glade", "main_table"); - if (dialog->gui == NULL) { - g_warning ("Cannot load `e-msg-composer-address-dialog.glade"); - return; - } - - gtk_container_add (GTK_CONTAINER (GNOME_DIALOG (dialog)->vbox), - glade_xml_get_widget (dialog->gui, "main_table")); - - setup_selection_targets (dialog); - load_addresses (dialog); - setup_signals (dialog); -} - -GtkWidget * -e_msg_composer_address_dialog_new (void) -{ - EMsgComposerAddressDialog *new; - - new = gtk_type_new (e_msg_composer_address_dialog_get_type ()); - e_msg_composer_address_dialog_construct (new); - - return GTK_WIDGET (new); -} - - -static void -set_list (EMsgComposerAddressDialog *dialog, - const gchar *list_name, - GList *list) -{ - GtkCList *clist; - GList *p; - gchar *text[2]; - - clist = GTK_CLIST (glade_xml_get_widget (dialog->gui, list_name)); - - gtk_clist_freeze (clist); - gtk_clist_clear (clist); - - text[1] = NULL; - for (p = list; p != NULL; p = p->next) { - text[0] = (gchar *) p->data; - gtk_clist_append (clist, text); - } - - gtk_clist_thaw (clist); -} - -void -e_msg_composer_address_dialog_set_to_list (EMsgComposerAddressDialog *dialog, - GList *to_list) -{ - g_return_if_fail (dialog != NULL); - g_return_if_fail (E_IS_MSG_COMPOSER_ADDRESS_DIALOG (dialog)); - - set_list (dialog, "to_clist", to_list); -} - -void -e_msg_composer_address_dialog_set_cc_list (EMsgComposerAddressDialog *dialog, - GList *cc_list) -{ - g_return_if_fail (dialog != NULL); - g_return_if_fail (E_IS_MSG_COMPOSER_ADDRESS_DIALOG (dialog)); - - set_list (dialog, "cc_clist", cc_list); -} - -void -e_msg_composer_address_dialog_set_bcc_list (EMsgComposerAddressDialog *dialog, - GList *bcc_list) -{ - g_return_if_fail (dialog != NULL); - g_return_if_fail (E_IS_MSG_COMPOSER_ADDRESS_DIALOG (dialog)); - - set_list (dialog, "bcc_clist", bcc_list); -} - - -static GList * -get_list (EMsgComposerAddressDialog *dialog, - const gchar *clist_name) -{ - GtkCList *address_clist; - GtkCList *clist; - GList *list; - guint i; - - clist = GTK_CLIST (glade_xml_get_widget (dialog->gui, clist_name)); - - list = NULL; - for (i = 0; i < clist->rows; i++) { - gchar *addr; - - gtk_clist_get_text (clist, i, 0, &addr); - list = g_list_prepend (list, g_strdup (addr)); - } - - return g_list_reverse (list); -} - -GList * -e_msg_composer_address_dialog_get_to_list (EMsgComposerAddressDialog *dialog) -{ - g_return_val_if_fail (dialog != NULL, NULL); - g_return_val_if_fail (E_IS_MSG_COMPOSER_ADDRESS_DIALOG (dialog), NULL); - - return get_list (dialog, "to_clist"); -} - -GList * -e_msg_composer_address_dialog_get_cc_list (EMsgComposerAddressDialog *dialog) -{ - g_return_val_if_fail (dialog != NULL, NULL); - g_return_val_if_fail (E_IS_MSG_COMPOSER_ADDRESS_DIALOG (dialog), NULL); - - return get_list (dialog, "cc_clist"); -} - -GList * -e_msg_composer_address_dialog_get_bcc_list (EMsgComposerAddressDialog *dialog) -{ - g_return_val_if_fail (dialog != NULL, NULL); - g_return_val_if_fail (E_IS_MSG_COMPOSER_ADDRESS_DIALOG (dialog), NULL); - - return get_list (dialog, "bcc_clist"); -} diff --git a/widgets/e-msg-composer-address-dialog.glade b/widgets/e-msg-composer-address-dialog.glade deleted file mode 100644 index 2249c27daf..0000000000 --- a/widgets/e-msg-composer-address-dialog.glade +++ /dev/null @@ -1,575 +0,0 @@ - - - - - address-composer - address-composer - - src - pixmaps - C - True - True - False - True - True - True - True - interface.c - interface.h - callbacks.c - callbacks.h - support.c - support.h - - - - - GnomeDialog - dialog1 - GTK_WINDOW_TOPLEVEL - GTK_WIN_POS_NONE - False - False - False - False - False - False - - - GtkVBox - GnomeDialog:vbox - dialog-vbox1 - False - 8 - - 4 - True - True - - - - GtkTable - main_table - 3 - 2 - False - 0 - 2 - - 0 - True - True - - - - GtkLabel - label3 - - GTK_JUSTIFY_CENTER - False - 0.5 - 0.5 - 0 - 0 - - 1 - 2 - 2 - 3 - 0 - 0 - False - False - False - False - False - False - - - - - GtkLabel - label1 - - GTK_JUSTIFY_CENTER - False - 0.5 - 0.5 - 0 - 0 - - 1 - 2 - 0 - 1 - 0 - 0 - True - True - False - False - True - True - - - - - GtkHBox - hbox1 - False - 5 - - 0 - 1 - 0 - 1 - 0 - 0 - False - False - False - False - False - False - - - - GtkLabel - label2 - - GTK_JUSTIFY_CENTER - False - 0.5 - 0.5 - 0 - 0 - - 0 - False - False - - - - - GtkEntry - name_entry - True - True - True - 0 - - - 5 - True - True - - - - - GtkButton - search_button - 65 - True - - - 0 - False - False - - - - - - GtkScrolledWindow - scrolledwindow1 - GTK_POLICY_AUTOMATIC - GTK_POLICY_AUTOMATIC - GTK_UPDATE_CONTINUOUS - GTK_UPDATE_CONTINUOUS - - 0 - 1 - 1 - 2 - 0 - 5 - True - True - False - False - True - True - - - - GtkCList - address_clist - 180 - 200 - True - 2 - 128,107 - GTK_SELECTION_BROWSE - True - GTK_SHADOW_IN - - - GtkLabel - CList:title - label5 - 50 - - GTK_JUSTIFY_LEFT - False - 0.5 - 0.5 - 0 - 0 - - - - GtkLabel - CList:title - label6 - 100 - - GTK_JUSTIFY_LEFT - False - 0.5 - 0.5 - 0 - 0 - - - - - - GtkHBox - hbox2 - True - 10 - - 0 - 1 - 2 - 3 - 0 - 0 - False - False - False - False - True - True - - - - GtkButton - button5 - True - - - 0 - True - True - - - - - GtkButton - button6 - True - - - 0 - True - True - - - - - - GtkTable - table2 - 3 - 2 - False - 0 - 0 - - 1 - 2 - 1 - 2 - 0 - 5 - False - False - False - False - True - True - - - - GtkButton - to_add_button - 60 - True - - - 0 - 1 - 0 - 1 - 5 - 0 - True - True - False - False - True - False - - - - - GtkButton - cc_add_button - 60 - True - - - 0 - 1 - 1 - 2 - 5 - 0 - True - True - False - False - True - False - - - - - GtkButton - bcc_add_button - 60 - True - - - 0 - 1 - 2 - 3 - 5 - 0 - True - True - False - False - True - False - - - - - GtkScrolledWindow - scrolledwindow4 - GTK_POLICY_AUTOMATIC - GTK_POLICY_AUTOMATIC - GTK_UPDATE_CONTINUOUS - GTK_UPDATE_CONTINUOUS - - 1 - 2 - 2 - 3 - 2 - 0 - True - True - False - False - True - True - - - - GtkCList - bcc_clist - 180 - 100 - True - 1 - 80 - GTK_SELECTION_BROWSE - False - GTK_SHADOW_IN - - - GtkLabel - CList:title - label9 - - GTK_JUSTIFY_CENTER - False - 0.5 - 0.5 - 0 - 0 - - - - - - GtkScrolledWindow - scrolledwindow2 - GTK_POLICY_AUTOMATIC - GTK_POLICY_AUTOMATIC - GTK_UPDATE_CONTINUOUS - GTK_UPDATE_CONTINUOUS - - 1 - 2 - 0 - 1 - 2 - 0 - True - True - False - False - True - True - - - - GtkCList - to_clist - 180 - 100 - True - 1 - 80 - GTK_SELECTION_BROWSE - False - GTK_SHADOW_IN - - - GtkLabel - CList:title - label7 - - GTK_JUSTIFY_CENTER - False - 0.5 - 0.5 - 0 - 0 - - - - - - GtkScrolledWindow - scrolledwindow3 - GTK_POLICY_AUTOMATIC - GTK_POLICY_AUTOMATIC - GTK_UPDATE_CONTINUOUS - GTK_UPDATE_CONTINUOUS - - 1 - 2 - 1 - 2 - 2 - 4 - True - True - False - False - True - True - - - - GtkCList - cc_clist - 180 - 100 - True - 1 - 80 - GTK_SELECTION_BROWSE - False - GTK_SHADOW_IN - - - GtkLabel - CList:title - label8 - - GTK_JUSTIFY_CENTER - False - 0.5 - 0.5 - 0 - 0 - - - - - - - - GtkHButtonBox - GnomeDialog:action_area - dialog-action_area1 - GTK_BUTTONBOX_END - 8 - 85 - 27 - 7 - 0 - - 0 - False - True - GTK_PACK_END - - - - GtkButton - button1 - True - True - True - GNOME_STOCK_BUTTON_OK - - - - GtkButton - button2 - True - True - GNOME_STOCK_BUTTON_APPLY - - - - GtkButton - button3 - True - True - GNOME_STOCK_BUTTON_CANCEL - - - - - - diff --git a/widgets/e-msg-composer-address-dialog.h b/widgets/e-msg-composer-address-dialog.h deleted file mode 100644 index 19ffeda703..0000000000 --- a/widgets/e-msg-composer-address-dialog.h +++ /dev/null @@ -1,75 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* e-msg-composer-address-dialog.h - * - * Copyright (C) 1999 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 __E_MSG_COMPOSER_ADDRESS_DIALOG_H__ -#define __E_MSG_COMPOSER_ADDRESS_DIALOG_H__ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus */ - - -#define E_TYPE_MSG_COMPOSER_ADDRESS_DIALOG (e_msg_composer_address_dialog_get_type ()) -#define E_MSG_COMPOSER_ADDRESS_DIALOG(obj) (GTK_CHECK_CAST ((obj), E_TYPE_MSG_COMPOSER_ADDRESS_DIALOG, EMsgComposerAddressDialog)) -#define E_MSG_COMPOSER_ADDRESS_DIALOG_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_TYPE_MSG_COMPOSER_ADDRESS_DIALOG, EMsgComposerAddressDialogClass)) -#define E_IS_MSG_COMPOSER_ADDRESS_DIALOG(obj) (GTK_CHECK_TYPE ((obj), E_TYPE_MSG_COMPOSER_ADDRESS_DIALOG)) -#define E_IS_MSG_COMPOSER_ADDRESS_DIALOG_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), E_TYPE_MSG_COMPOSER_ADDRESS_DIALOG)) - - -typedef struct _EMsgComposerAddressDialog EMsgComposerAddressDialog; -typedef struct _EMsgComposerAddressDialogClass EMsgComposerAddressDialogClass; - -struct _EMsgComposerAddressDialog { - GnomeDialog parent; - - GladeXML *gui; - - gchar *cut_buffer; -}; - -struct _EMsgComposerAddressDialogClass { - GnomeDialogClass parent_class; - - void (* apply) (EMsgComposerAddressDialog *dialog); -}; - - -GtkType e_msg_composer_address_dialog_get_type (void); -GtkWidget *e_msg_composer_address_dialog_new (void); -void e_msg_composer_address_dialog_construct (EMsgComposerAddressDialog *dialog); -void e_msg_composer_address_dialog_set_to_list (EMsgComposerAddressDialog *dialog, GList *to_list); -void e_msg_composer_address_dialog_set_cc_list (EMsgComposerAddressDialog *dialog, GList *cc_list); -void e_msg_composer_address_dialog_set_bcc_list (EMsgComposerAddressDialog *dialog, GList *bcc_list); -GList *e_msg_composer_address_dialog_get_to_list (EMsgComposerAddressDialog *dialog); -GList *e_msg_composer_address_dialog_get_cc_list (EMsgComposerAddressDialog *dialog); -GList *e_msg_composer_address_dialog_get_bcc_list (EMsgComposerAddressDialog *dialog); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - - -#endif /* __E_MSG_COMPOSER_ADDRESS_DIALOG_H__ */ diff --git a/widgets/e-msg-composer-address-entry.c b/widgets/e-msg-composer-address-entry.c deleted file mode 100644 index be63c815f5..0000000000 --- a/widgets/e-msg-composer-address-entry.c +++ /dev/null @@ -1,175 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* e-msg-composer-address-entry.c - * - * Copyright (C) 1999 Helix Code, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: Ettore Perazzoli - */ - -/* This is a custom GtkEntry for entering address lists. For now, it does not - have any fancy features, but in the future we might want to make it - cooler. */ - -#include - -#include "e-msg-composer-address-entry.h" - - -static GtkEntryClass *parent_class = NULL; - - -/* Initialization. */ - -static void -class_init (EMsgComposerAddressEntryClass *klass) -{ - GtkObjectClass *object_class; - - object_class = (GtkObjectClass*) klass; - - parent_class = gtk_type_class (gtk_entry_get_type ()); -} - -static void -init (EMsgComposerAddressEntry *msg_composer_address_entry) -{ -} - -GtkType -e_msg_composer_address_entry_get_type (void) -{ - static GtkType type = 0; - - if (type == 0) { - static const GtkTypeInfo info = { - "EMsgComposerAddressEntry", - sizeof (EMsgComposerAddressEntry), - sizeof (EMsgComposerAddressEntryClass), - (GtkClassInitFunc) class_init, - (GtkObjectInitFunc) init, - /* reserved_1 */ NULL, - /* reserved_2 */ NULL, - (GtkClassInitFunc) NULL, - }; - - type = gtk_type_unique (gtk_entry_get_type (), &info); - } - - return type; -} - - -GtkWidget * -e_msg_composer_address_entry_new (void) -{ - GtkWidget *new; - - new = gtk_type_new (e_msg_composer_address_entry_get_type ()); - - return new; -} - - -/** - * e_msg_composer_address_entry_get_addresses: - * @entry: An address entry widget - * - * Retrieve the list of addresses stored in @entry. - * - * Return value: A GList of pointers to strings representing the addresses. - * Notice that the strings must be freed by the caller when not needed anymore. - **/ -GList * -e_msg_composer_address_entry_get_addresses (EMsgComposerAddressEntry *entry) -{ - GList *list; - const gchar *s; - const gchar *p, *oldp; - gboolean in_quotes; - - s = gtk_entry_get_text (GTK_ENTRY (entry)); - - in_quotes = FALSE; - list = NULL; - - p = s; - oldp = s; - - while (1) { - if (*p == '"') { - in_quotes = ! in_quotes; - p++; - } else if ((! in_quotes && *p == ',') || *p == 0) { - if (p != oldp) { - gchar *new_addr; - - new_addr = g_strndup (oldp, p - oldp); - new_addr = g_strstrip (new_addr); - if (*new_addr != '\0') - list = g_list_prepend (list, new_addr); - else - g_free (new_addr); - } - - while (*p == ',' || *p == ' ' || *p == '\t') - p++; - - if (*p == 0) - break; - - oldp = p; - } else { - p++; - } - } - - return g_list_reverse (list); -} - -/** - * e_msg_composer_address_entry_set_list: - * @entry: An address entry - * @list: List of pointers to strings representing the addresses that must - * appear in the entry - * - * Set the address list from @list. - **/ -void -e_msg_composer_address_entry_set_list (EMsgComposerAddressEntry *entry, - GList *list) -{ - GString *string; - GList *p; - - g_return_if_fail (entry != NULL); - - if (list == NULL) { - gtk_editable_delete_text (GTK_EDITABLE (entry), -1, -1); - return; - } - - string = g_string_new (NULL); - for (p = list; p != NULL; p = p->next) { - if (string->str[0] != '\0') - g_string_append (string, ", "); - g_string_append (string, p->data); - } - - gtk_entry_set_text (GTK_ENTRY (entry), string->str); - g_string_free (string, TRUE); -} diff --git a/widgets/e-msg-composer-address-entry.h b/widgets/e-msg-composer-address-entry.h deleted file mode 100644 index 8e926272e4..0000000000 --- a/widgets/e-msg-composer-address-entry.h +++ /dev/null @@ -1,63 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* e-msg-composer-address-entry.h - * - * Copyright (C) 1999 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 __E_MSG_COMPOSER_ADDRESS_ENTRY_H__ -#define __E_MSG_COMPOSER_ADDRESS_ENTRY_H__ - -#include - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus */ - -#define E_TYPE_MSG_COMPOSER_ADDRESS_ENTRY (e_msg_composer_address_entry_get_type ()) -#define E_MSG_COMPOSER_ADDRESS_ENTRY(obj) (GTK_CHECK_CAST ((obj), E_TYPE_MSG_COMPOSER_ADDRESS_ENTRY, EMsgComposerAddressEntry)) -#define E_MSG_COMPOSER_ADDRESS_ENTRY_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_TYPE_MSG_COMPOSER_ADDRESS_ENTRY, EMsgComposerAddressEntryClass)) -#define E_IS_MSG_COMPOSER_ADDRESS_ENTRY(obj) (GTK_CHECK_TYPE ((obj), E_TYPE_MSG_COMPOSER_ADDRESS_ENTRY)) -#define E_IS_MSG_COMPOSER_ADDRESS_ENTRY_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), E_TYPE_MSG_COMPOSER_ADDRESS_ENTRY)) - - -typedef struct _EMsgComposerAddressEntry EMsgComposerAddressEntry; -typedef struct _EMsgComposerAddressEntryClass EMsgComposerAddressEntryClass; - -struct _EMsgComposerAddressEntry { - GtkEntry parent; -}; - -struct _EMsgComposerAddressEntryClass { - GtkEntryClass parent_class; -}; - - -GtkType e_msg_composer_address_entry_get_type (void); -GtkWidget *e_msg_composer_address_entry_new (void); -GList *e_msg_composer_address_entry_get_addresses (EMsgComposerAddressEntry *entry); -void e_msg_composer_address_entry_set_list (EMsgComposerAddressEntry *entry, - GList *list); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __E_MSG_COMPOSER_ADDRESS_ENTRY_H__ */ diff --git a/widgets/e-msg-composer-attachment-bar.c b/widgets/e-msg-composer-attachment-bar.c deleted file mode 100644 index f30b953d2b..0000000000 --- a/widgets/e-msg-composer-attachment-bar.c +++ /dev/null @@ -1,665 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* e-msg-composer-attachment-bar.c - * - * Copyright (C) 1999 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 - */ - -#include -#include - -#include "e-msg-composer-attachment.h" -#include "e-msg-composer-attachment-bar.h" - - -#define ICON_WIDTH 64 -#define ICON_SEPARATORS " /-_" -#define ICON_SPACING 2 -#define ICON_ROW_SPACING ICON_SPACING -#define ICON_COL_SPACING ICON_SPACING -#define ICON_BORDER 2 -#define ICON_TEXT_SPACING 2 - - -static GnomeIconListClass *parent_class = NULL; - -struct _EMsgComposerAttachmentBarPrivate { - GList *attachments; - guint num_attachments; - - GtkWidget *context_menu; - GtkWidget *icon_context_menu; -}; - - -enum { - CHANGED, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = { 0 }; - - -static void update (EMsgComposerAttachmentBar *bar); - - -static gchar * -size_to_string (gulong size) -{ - gchar *size_string; - - /* FIXME: The following should probably go into a separate module, as - we might have to do the same thing in other places as well. Also, - I am not sure this will be OK for all the languages. */ - - if (size < 1e3L) { - if (size == 1) - size_string = g_strdup (_("1 byte")); - else - size_string = g_strdup_printf (_("%u bytes"), - (guint) size); - } else { - gdouble displayed_size; - - if (size < 1e6L) { - displayed_size = (gdouble) size / 1.0e3; - size_string = g_strdup_printf (_("%.1fK"), - displayed_size); - } else if (size < 1e9L) { - displayed_size = (gdouble) size / 1.0e6; - size_string = g_strdup_printf (_("%.1fM"), - displayed_size); - } else { - displayed_size = (gdouble) size / 1.0e9; - size_string = g_strdup_printf (_("%.1fG"), - displayed_size); - } - } - - return size_string; -} - - -/* Sorting. */ - -static gint -attachment_sort_func (gconstpointer a, gconstpointer b) -{ - const EMsgComposerAttachment *attachment_a, *attachment_b; - - attachment_a = (EMsgComposerAttachment *) a; - attachment_b = (EMsgComposerAttachment *) b; - - return strcmp (attachment_a->description, attachment_b->description); -} - -static void -sort (EMsgComposerAttachmentBar *bar) -{ - EMsgComposerAttachmentBarPrivate *priv; - - priv = bar->priv; - - priv->attachments = g_list_sort (priv->attachments, - attachment_sort_func); -} - - -/* Attachment handling functions. */ - -static void -free_attachment_list (EMsgComposerAttachmentBar *bar) -{ - EMsgComposerAttachmentBarPrivate *priv; - GList *p; - - priv = bar->priv; - - for (p = priv->attachments; p != NULL; p = p->next) - gtk_object_unref (GTK_OBJECT (p->data)); -} - -static void -attachment_changed_cb (EMsgComposerAttachment *attachment, - gpointer data) -{ - update (E_MSG_COMPOSER_ATTACHMENT_BAR (data)); -} - -static void -add_from_file (EMsgComposerAttachmentBar *bar, - const gchar *file_name) -{ - EMsgComposerAttachment *attachment; - - attachment = e_msg_composer_attachment_new (file_name); - - gtk_signal_connect (GTK_OBJECT (attachment), "changed", - GTK_SIGNAL_FUNC (attachment_changed_cb), - bar); - - bar->priv->attachments = g_list_append (bar->priv->attachments, - attachment); - bar->priv->num_attachments++; - - sort (bar); - update (bar); - - gtk_signal_emit (GTK_OBJECT (bar), signals[CHANGED]); -} - -static void -remove_attachment (EMsgComposerAttachmentBar *bar, - EMsgComposerAttachment *attachment) -{ - bar->priv->attachments = g_list_remove (bar->priv->attachments, - attachment); - bar->priv->num_attachments--; - - gtk_object_unref (GTK_OBJECT (attachment)); - - gtk_signal_emit (GTK_OBJECT (bar), signals[CHANGED]); -} - - -/* Icon list contents handling. */ - -static void -update (EMsgComposerAttachmentBar *bar) -{ - EMsgComposerAttachmentBarPrivate *priv; - GnomeIconList *icon_list; - GList *p; - - priv = bar->priv; - icon_list = GNOME_ICON_LIST (bar); - - gnome_icon_list_freeze (icon_list); - - gnome_icon_list_clear (icon_list); - - /* FIXME could be faster, but we don't care. */ - - for (p = priv->attachments; p != NULL; p = p->next) { - EMsgComposerAttachment *attachment; - const gchar *icon_name; - gchar *size_string; - gchar *label; - - attachment = p->data; - icon_name = gnome_mime_get_value (attachment->mime_type, - "icon-filename"); - - /* FIXME we need some better default icon. */ - if (icon_name == NULL) - icon_name = gnome_mime_get_value ("text/plain", - "icon-filename"); - - size_string = size_to_string (attachment->size); - - /* FIXME: If GnomeIconList honoured "\n", the result would be a - lot better. */ - label = g_strconcat (attachment->description, "\n(", - size_string, ")", NULL); - - gnome_icon_list_append (icon_list, icon_name, label); - - g_free (label); - g_free (size_string); - } - - gnome_icon_list_thaw (icon_list); -} - -static void -remove_selected (EMsgComposerAttachmentBar *bar) -{ - GnomeIconList *icon_list; - EMsgComposerAttachment *attachment; - GList *attachment_list; - GList *p; - gint num; - - icon_list = GNOME_ICON_LIST (bar); - - /* Weee! I am especially proud of this piece of cheesy code: it is - truly awful. But unless one attaches a huge number of files, it - will not be as greedy as intended. FIXME of course. */ - - attachment_list = NULL; - for (p = icon_list->selection; p != NULL; p = p->next) { - num = GPOINTER_TO_INT (p->data); - attachment = E_MSG_COMPOSER_ATTACHMENT - (g_list_nth (bar->priv->attachments, num)->data); - attachment_list = g_list_prepend (attachment_list, attachment); - } - - for (p = attachment_list; p != NULL; p = p->next) - remove_attachment (bar, E_MSG_COMPOSER_ATTACHMENT (p->data)); - - g_list_free (attachment_list); - - update (bar); -} - -static void -edit_selected (EMsgComposerAttachmentBar *bar) -{ - GnomeIconList *icon_list; - EMsgComposerAttachment *attachment; - gint num; - - icon_list = GNOME_ICON_LIST (bar); - - num = GPOINTER_TO_INT (icon_list->selection->data); - attachment = g_list_nth (bar->priv->attachments, num)->data; - - e_msg_composer_attachment_edit (attachment, GTK_WIDGET (bar)); -} - - -/* "Attach" dialog. */ - -static void -attach_cb (GtkWidget *widget, - gpointer data) -{ - EMsgComposerAttachmentBar *bar; - GtkWidget *file_selection; - const gchar *file_name; - - file_selection = gtk_widget_get_toplevel (widget); - bar = E_MSG_COMPOSER_ATTACHMENT_BAR (data); - - file_name = gtk_file_selection_get_filename - (GTK_FILE_SELECTION (file_selection)); - add_from_file (bar, file_name); - - gtk_widget_hide (file_selection); -} - -static void -add_from_user (EMsgComposerAttachmentBar *bar) -{ - GtkWidget *file_selection; - GtkWidget *cancel_button; - GtkWidget *ok_button; - - file_selection = gtk_file_selection_new (_("Add attachment")); - gtk_window_set_position (GTK_WINDOW (file_selection), - GTK_WIN_POS_MOUSE); - - ok_button = GTK_FILE_SELECTION (file_selection)->ok_button; - gtk_signal_connect (GTK_OBJECT (ok_button), - "clicked", GTK_SIGNAL_FUNC (attach_cb), bar); - - cancel_button = GTK_FILE_SELECTION (file_selection)->cancel_button; - gtk_signal_connect_object (GTK_OBJECT (cancel_button), - "clicked", - GTK_SIGNAL_FUNC (gtk_widget_hide), - GTK_OBJECT (file_selection)); - - gtk_widget_show (GTK_WIDGET (file_selection)); -} - - -/* Callbacks. */ - -static void -add_cb (GtkWidget *widget, - gpointer data) -{ - g_return_if_fail (E_IS_MSG_COMPOSER_ATTACHMENT_BAR (data)); - - add_from_user (E_MSG_COMPOSER_ATTACHMENT_BAR (data)); -} - -static void -properties_cb (GtkWidget *widget, - gpointer data) -{ - EMsgComposerAttachmentBar *bar; - - g_return_if_fail (E_IS_MSG_COMPOSER_ATTACHMENT_BAR (data)); - - bar = E_MSG_COMPOSER_ATTACHMENT_BAR (data); - edit_selected (data); -} - -static void -remove_cb (GtkWidget *widget, - gpointer data) -{ - EMsgComposerAttachmentBar *bar; - - g_return_if_fail (E_IS_MSG_COMPOSER_ATTACHMENT_BAR (data)); - - bar = E_MSG_COMPOSER_ATTACHMENT_BAR (data); - remove_selected (bar); -} - - -/* Popup menu handling. */ - -static GnomeUIInfo icon_context_menu_info[] = { - GNOMEUIINFO_ITEM (N_("Remove"), - N_("Remove selected items from the attachment list"), - remove_cb, NULL), - GNOMEUIINFO_MENU_PROPERTIES_ITEM (properties_cb, NULL), - GNOMEUIINFO_END -}; - -static GtkWidget * -get_icon_context_menu (EMsgComposerAttachmentBar *bar) -{ - EMsgComposerAttachmentBarPrivate *priv; - - priv = bar->priv; - if (priv->icon_context_menu == NULL) - priv->icon_context_menu = gnome_popup_menu_new - (icon_context_menu_info); - - return priv->icon_context_menu; -} - -static void -popup_icon_context_menu (EMsgComposerAttachmentBar *bar, - gint num, - GdkEventButton *event) -{ - GtkWidget *menu; - - menu = get_icon_context_menu (bar); - gnome_popup_menu_do_popup (menu, NULL, NULL, event, bar); -} - -static GnomeUIInfo context_menu_info[] = { - GNOMEUIINFO_ITEM (N_("Add attachment..."), - N_("Attach a file to the message"), - add_cb, NULL), - GNOMEUIINFO_END -}; - -static GtkWidget * -get_context_menu (EMsgComposerAttachmentBar *bar) -{ - EMsgComposerAttachmentBarPrivate *priv; - - priv = bar->priv; - if (priv->context_menu == NULL) - priv->context_menu = gnome_popup_menu_new (context_menu_info); - - return priv->context_menu; -} - -static void -popup_context_menu (EMsgComposerAttachmentBar *bar, - GdkEventButton *event) -{ - GtkWidget *menu; - - menu = get_context_menu (bar); - gnome_popup_menu_do_popup (menu, NULL, NULL, event, bar); -} - - -/* GtkObject methods. */ - -static void -destroy (GtkObject *object) -{ - EMsgComposerAttachmentBar *bar; - - bar = E_MSG_COMPOSER_ATTACHMENT_BAR (object); - - free_attachment_list (bar); - - if (GTK_OBJECT_CLASS (parent_class)->destroy != NULL) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - - -/* GtkWidget methods. */ - -static gint -button_press_event (GtkWidget *widget, - GdkEventButton *event) -{ - EMsgComposerAttachmentBar *bar; - GnomeIconList *icon_list; - gint icon_number; - - bar = E_MSG_COMPOSER_ATTACHMENT_BAR (widget); - icon_list = GNOME_ICON_LIST (widget); - - if (event->button != 3) - return GTK_WIDGET_CLASS (parent_class)->button_press_event - (widget, event); - - icon_number = gnome_icon_list_get_icon_at (icon_list, - event->x, event->y); - - if (icon_number >= 0) { - gnome_icon_list_select_icon (icon_list, icon_number); - popup_icon_context_menu (bar, icon_number, event); - } else { - popup_context_menu (bar, event); - } - - return TRUE; -} - - -/* GnomeIconList methods. */ - -static gboolean -text_changed (GnomeIconList *gil, - gint num, - const gchar *new_text) -{ - EMsgComposerAttachmentBar *bar; - EMsgComposerAttachment *attachment; - GList *p; - - bar = E_MSG_COMPOSER_ATTACHMENT_BAR (gil); - p = g_list_nth (bar->priv->attachments, num); - attachment = p->data; - - g_free (attachment->description); - attachment->description = g_strdup (new_text); - - return TRUE; -} - - -/* Initialization. */ - -static void -class_init (EMsgComposerAttachmentBarClass *class) -{ - GtkObjectClass *object_class; - GtkWidgetClass *widget_class; - GnomeIconListClass *icon_list_class; - - object_class = GTK_OBJECT_CLASS (class); - widget_class = GTK_WIDGET_CLASS (class); - icon_list_class = GNOME_ICON_LIST_CLASS (class); - - parent_class = gtk_type_class (gnome_icon_list_get_type ()); - - object_class->destroy = destroy; - - widget_class->button_press_event = button_press_event; - - icon_list_class->text_changed = text_changed; - - /* Setup signals. */ - - signals[CHANGED] = - gtk_signal_new ("changed", - GTK_RUN_LAST, - object_class->type, - GTK_SIGNAL_OFFSET (EMsgComposerAttachmentBarClass, - changed), - gtk_marshal_NONE__NONE, - GTK_TYPE_NONE, 0); - - gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL); -} - -static void -init (EMsgComposerAttachmentBar *bar) -{ - EMsgComposerAttachmentBarPrivate *priv; - guint icon_size; - - priv = g_new (EMsgComposerAttachmentBarPrivate, 1); - - priv->attachments = NULL; - priv->context_menu = NULL; - priv->icon_context_menu = NULL; - - priv->num_attachments = 0; - - bar->priv = priv; - - /* FIXME partly hardcoded. We should compute height from the font, and - allow at least 2 lines for every item. */ - icon_size = ICON_WIDTH + ICON_SPACING + ICON_BORDER + ICON_TEXT_SPACING; - icon_size += 24; - - gtk_widget_set_usize (GTK_WIDGET (bar), icon_size * 4, icon_size); -} - - -GtkType -e_msg_composer_attachment_bar_get_type (void) -{ - static GtkType type = 0; - - if (type == 0) { - static const GtkTypeInfo info = { - "EMsgComposerAttachmentBar", - sizeof (EMsgComposerAttachmentBar), - sizeof (EMsgComposerAttachmentBarClass), - (GtkClassInitFunc) class_init, - (GtkObjectInitFunc) init, - /* reserved_1 */ NULL, - /* reserved_2 */ NULL, - (GtkClassInitFunc) NULL, - }; - - type = gtk_type_unique (gnome_icon_list_get_type (), &info); - } - - return type; -} - -GtkWidget * -e_msg_composer_attachment_bar_new (GtkAdjustment *adj) -{ - EMsgComposerAttachmentBar *new; - GnomeIconList *icon_list; - - gtk_widget_push_visual (gdk_imlib_get_visual ()); - gtk_widget_push_colormap (gdk_imlib_get_colormap ()); - new = gtk_type_new (e_msg_composer_attachment_bar_get_type ()); - gtk_widget_pop_visual (); - gtk_widget_pop_colormap (); - - icon_list = GNOME_ICON_LIST (new); - - gnome_icon_list_construct (icon_list, ICON_WIDTH, adj, 0); - - gnome_icon_list_set_separators (icon_list, ICON_SEPARATORS); - gnome_icon_list_set_row_spacing (icon_list, ICON_ROW_SPACING); - gnome_icon_list_set_col_spacing (icon_list, ICON_COL_SPACING); - gnome_icon_list_set_icon_border (icon_list, ICON_BORDER); - gnome_icon_list_set_text_spacing (icon_list, ICON_TEXT_SPACING); - gnome_icon_list_set_selection_mode (icon_list, GTK_SELECTION_MULTIPLE); - - return GTK_WIDGET (new); -} - - -static void -attach_to_multipart (CamelMultipart *multipart, - EMsgComposerAttachment *attachment) -{ - CamelMimeBodyPart *part; - - /* FIXME encoding etc. etc. ? */ - /* FIXME I am not sure how to add an attachment through the Camel - API. :-/ */ - - part = camel_mime_body_part_new (); - camel_mime_part_set_disposition (CAMEL_MIME_PART (part), "attachment"); - camel_mime_part_set_filename (CAMEL_MIME_PART (part), - g_strdup (g_basename (attachment->file_name))); - camel_mime_part_set_description (CAMEL_MIME_PART (part), - g_strdup (attachment->description)); - camel_data_wrapper_set_mime_type (CAMEL_DATA_WRAPPER (part), - g_strdup (attachment->mime_type)); -} - -void -e_msg_composer_attachment_bar_to_multipart (EMsgComposerAttachmentBar *bar, - CamelMultipart *multipart) -{ - EMsgComposerAttachmentBarPrivate *priv; - GList *p; - - g_return_if_fail (bar != NULL); - g_return_if_fail (E_IS_MSG_COMPOSER_ATTACHMENT_BAR (bar)); - g_return_if_fail (multipart != NULL); - g_return_if_fail (IS_CAMEL_MULTIPART (multipart)); - - priv = bar->priv; - - for (p = priv->attachments; p != NULL; p = p->next) { - EMsgComposerAttachment *attachment; - - attachment = E_MSG_COMPOSER_ATTACHMENT (p->data); - attach_to_multipart (multipart, attachment); - } -} - - -guint -e_msg_composer_attachment_bar_get_num_attachments (EMsgComposerAttachmentBar *bar) -{ - g_return_val_if_fail (bar != NULL, 0); - g_return_val_if_fail (E_IS_MSG_COMPOSER_ATTACHMENT_BAR (bar), 0); - - return bar->priv->num_attachments; -} - - -void -e_msg_composer_attachment_bar_attach (EMsgComposerAttachmentBar *bar, - const gchar *file_name) -{ - g_return_if_fail (bar != NULL); - g_return_if_fail (E_IS_MSG_COMPOSER_ATTACHMENT_BAR (bar)); - - if (file_name == NULL) - add_from_user (bar); - else - add_from_file (bar, file_name); -} diff --git a/widgets/e-msg-composer-attachment-bar.h b/widgets/e-msg-composer-attachment-bar.h deleted file mode 100644 index 803b51a954..0000000000 --- a/widgets/e-msg-composer-attachment-bar.h +++ /dev/null @@ -1,74 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* msg-composer-attachment-bar.h - * - * Copyright (C) 1999 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 __E_MSG_COMPOSER_ATTACHMENT_BAR_H__ -#define __E_MSG_COMPOSER_ATTACHMENT_BAR_H__ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus */ - -#define E_TYPE_MSG_COMPOSER_ATTACHMENT_BAR \ - (e_msg_composer_attachment_bar_get_type ()) -#define E_MSG_COMPOSER_ATTACHMENT_BAR(obj) \ - (GTK_CHECK_CAST ((obj), E_TYPE_MSG_COMPOSER_ATTACHMENT_BAR, EMsgComposerAttachmentBar)) -#define E_MSG_COMPOSER_ATTACHMENT_BAR_CLASS(klass) \ - (GTK_CHECK_CLASS_CAST ((klass), E_TYPE_MSG_COMPOSER_ATTACHMENT_BAR, EMsgComposerAttachmentBarClass)) -#define E_IS_MSG_COMPOSER_ATTACHMENT_BAR(obj) \ - (GTK_CHECK_TYPE ((obj), E_TYPE_MSG_COMPOSER_ATTACHMENT_BAR)) -#define E_IS_MSG_COMPOSER_ATTACHMENT_BAR_CLASS(klass) \ - (GTK_CHECK_CLASS_TYPE ((obj), E_TYPE_MSG_COMPOSER_ATTACHMENT_BAR)) - - -typedef struct _EMsgComposerAttachmentBarPrivate EMsgComposerAttachmentBarPrivate; - -struct _EMsgComposerAttachmentBar { - GnomeIconList parent; - - EMsgComposerAttachmentBarPrivate *priv; -}; -typedef struct _EMsgComposerAttachmentBar EMsgComposerAttachmentBar; - -struct _EMsgComposerAttachmentBarClass { - GnomeIconListClass parent_class; - - void (* changed) (EMsgComposerAttachmentBar *bar); -}; -typedef struct _EMsgComposerAttachmentBarClass EMsgComposerAttachmentBarClass; - - -GtkType e_msg_composer_attachment_bar_get_type (void); -GtkWidget *e_msg_composer_attachment_bar_new (GtkAdjustment *adj); -void e_msg_composer_attachment_bar_to_multipart (EMsgComposerAttachmentBar *bar, CamelMultipart *multipart); -guint e_msg_composer_attachment_bar_get_num_attachments (EMsgComposerAttachmentBar *bar); -void e_msg_composer_attachment_bar_attach (EMsgComposerAttachmentBar *bar, const gchar *file_name); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __E_MSG_COMPOSER_ATTACHMENT_BAR_H__ */ diff --git a/widgets/e-msg-composer-attachment.c b/widgets/e-msg-composer-attachment.c deleted file mode 100644 index 4ab8de42c4..0000000000 --- a/widgets/e-msg-composer-attachment.c +++ /dev/null @@ -1,480 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* e-msg-composer-attachment.c - * - * Copyright (C) 1999 Helix Code, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: Ettore Perazzoli - */ - -/* This is the object representing an email attachment. It is implemented as a - GtkObject to make it easier for the application to handle it. For example, - the "changed" signal is emitted whenever something changes in the - attachment. Also, this contains the code to let users edit the - attachment manually. */ - -#include - -#include - -#include "e-msg-composer-attachment.h" - - -enum { - CHANGED, - LAST_SIGNAL -}; -static guint signals[LAST_SIGNAL] = { 0 }; - -static GtkObjectClass *parent_class = NULL; - - -/* Utility functions. */ - -static const gchar * -get_mime_type (const gchar *file_name) -{ - const gchar *mime_type; - - mime_type = gnome_mime_type_of_file (file_name); - if (mime_type == NULL) - mime_type = "application/octet-stream"; - - return mime_type; -} - -static void -init_mime_type (EMsgComposerAttachment *attachment) -{ - attachment->mime_type = g_strdup (get_mime_type (attachment->file_name)); -} - -static void -set_mime_type (EMsgComposerAttachment *attachment) -{ - g_free (attachment->mime_type); - init_mime_type (attachment); -} - -static void -changed (EMsgComposerAttachment *attachment) -{ - gtk_signal_emit (GTK_OBJECT (attachment), signals[CHANGED]); -} - - -/* GtkObject methods. */ - -static void -destroy (GtkObject *object) -{ - EMsgComposerAttachment *attachment; - - attachment = E_MSG_COMPOSER_ATTACHMENT (object); - - g_free (attachment->file_name); - g_free (attachment->description); - g_free (attachment->mime_type); -} - - -/* Signals. */ - -static void -real_changed (EMsgComposerAttachment *msg_composer_attachment) -{ - g_return_if_fail (msg_composer_attachment != NULL); - g_return_if_fail (E_IS_MSG_COMPOSER_ATTACHMENT (msg_composer_attachment)); -} - - -static void -class_init (EMsgComposerAttachmentClass *klass) -{ - GtkObjectClass *object_class; - - object_class = (GtkObjectClass*) klass; - - parent_class = gtk_type_class (gtk_object_get_type ()); - - object_class->destroy = destroy; - - signals[CHANGED] = gtk_signal_new ("changed", - GTK_RUN_FIRST, - object_class->type, - GTK_SIGNAL_OFFSET - (EMsgComposerAttachmentClass, - changed), - gtk_marshal_NONE__NONE, - GTK_TYPE_NONE, 0); - - - gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL); - - klass->changed = real_changed; -} - -static void -init (EMsgComposerAttachment *msg_composer_attachment) -{ - msg_composer_attachment->editor_gui = NULL; - msg_composer_attachment->file_name = NULL; - msg_composer_attachment->description = NULL; - msg_composer_attachment->mime_type = NULL; - msg_composer_attachment->size = 0; -} - -GtkType -e_msg_composer_attachment_get_type (void) -{ - static GtkType type = 0; - - if (type == 0) { - static const GtkTypeInfo info = { - "EMsgComposerAttachment", - sizeof (EMsgComposerAttachment), - sizeof (EMsgComposerAttachmentClass), - (GtkClassInitFunc) class_init, - (GtkObjectInitFunc) init, - /* reserved_1 */ NULL, - /* reserved_2 */ NULL, - (GtkClassInitFunc) NULL, - }; - - type = gtk_type_unique (gtk_object_get_type (), &info); - } - - return type; -} - - -/** - * e_msg_composer_attachment_new: - * @file_name: - * - * Return value: - **/ -EMsgComposerAttachment * -e_msg_composer_attachment_new (const gchar *file_name) -{ - EMsgComposerAttachment *new; - struct stat statbuf; - - g_return_val_if_fail (file_name != NULL, NULL); - - new = gtk_type_new (e_msg_composer_attachment_get_type ()); - - new->editor_gui = NULL; - - new->file_name = g_strdup (file_name); - new->description = g_strdup (g_basename (new->file_name)); - - if (stat (file_name, &statbuf) < 0) - new->size = 0; - else - new->size = statbuf.st_size; - - init_mime_type (new); - - return new; -} - - -/* The attachment property dialog. */ - -struct _DialogData { - GtkWidget *dialog; - GtkEntry *file_name_entry; - GtkEntry *description_entry; - GtkEntry *mime_type_entry; - GtkWidget *browse_widget; - EMsgComposerAttachment *attachment; -}; -typedef struct _DialogData DialogData; - -static void -destroy_dialog_data (DialogData *data) -{ - if (data->browse_widget != NULL) - gtk_widget_destroy (data->browse_widget); - g_free (data); -} - -static void -update_mime_type (DialogData *data) -{ - const gchar *mime_type; - const gchar *file_name; - - file_name = gtk_entry_get_text (data->file_name_entry); - mime_type = get_mime_type (file_name); - - gtk_entry_set_text (data->mime_type_entry, mime_type); -} - -static void -browse_ok_cb (GtkWidget *widget, - gpointer data) -{ - GtkWidget *file_selection; - DialogData *dialog_data; - const gchar *file_name; - - dialog_data = (DialogData *) data; - file_selection = gtk_widget_get_toplevel (widget); - - file_name = gtk_file_selection_get_filename - (GTK_FILE_SELECTION (file_selection)); - - gtk_entry_set_text (dialog_data->file_name_entry, file_name); - - update_mime_type (dialog_data); - - gtk_widget_hide (file_selection); -} - -static void -browse (DialogData *data) -{ - if (data->browse_widget == NULL) { - GtkWidget *file_selection; - GtkWidget *cancel_button; - GtkWidget *ok_button; - - file_selection - = gtk_file_selection_new (_("Select attachment")); - gtk_window_set_position (GTK_WINDOW (file_selection), - GTK_WIN_POS_MOUSE); - gtk_window_set_transient_for (GTK_WINDOW (file_selection), - GTK_WINDOW (data->dialog)); - - ok_button = GTK_FILE_SELECTION (file_selection)->ok_button; - gtk_signal_connect (GTK_OBJECT (ok_button), - "clicked", GTK_SIGNAL_FUNC (browse_ok_cb), - data); - - cancel_button - = GTK_FILE_SELECTION (file_selection)->cancel_button; - gtk_signal_connect_object (GTK_OBJECT (cancel_button), - "clicked", - GTK_SIGNAL_FUNC (gtk_widget_hide), - GTK_OBJECT (file_selection)); - - data->browse_widget = file_selection; - } - - gtk_widget_show (GTK_WIDGET (data->browse_widget)); -} - -static void -set_entry (GladeXML *xml, - const gchar *widget_name, - const gchar *value) -{ - GtkEntry *entry; - - entry = GTK_ENTRY (glade_xml_get_widget (xml, widget_name)); - if (entry == NULL) - g_warning ("Entry for `%s' not found.", widget_name); - gtk_entry_set_text (entry, value); -} - -static void -connect_entry_changed (GladeXML *gui, - const gchar *name, - GtkSignalFunc func, - gpointer data) -{ - GtkWidget *widget; - - widget = glade_xml_get_widget (gui, name); - gtk_signal_connect (GTK_OBJECT (widget), "changed", func, data); -} - -static void -connect_widget (GladeXML *gui, - const gchar *name, - const gchar *signal_name, - GtkSignalFunc func, - gpointer data) -{ - GtkWidget *widget; - - widget = glade_xml_get_widget (gui, name); - gtk_signal_connect (GTK_OBJECT (widget), signal_name, func, data); -} - -static void -apply (DialogData *data) -{ - EMsgComposerAttachment *attachment; - - attachment = data->attachment; - - g_free (attachment->file_name); - attachment->file_name = g_strdup (gtk_entry_get_text - (data->file_name_entry)); - - g_free (attachment->description); - attachment->description = g_strdup (gtk_entry_get_text - (data->description_entry)); - - g_free (attachment->mime_type); - attachment->mime_type = g_strdup (gtk_entry_get_text - (data->mime_type_entry)); - - changed (attachment); -} - -static void -entry_changed_cb (GtkWidget *widget, gpointer data) -{ - DialogData *dialog_data; - GladeXML *gui; - GtkWidget *apply_button; - - dialog_data = (DialogData *) data; - gui = dialog_data->attachment->editor_gui; - - apply_button = glade_xml_get_widget (gui, "apply_button"); - gtk_widget_set_sensitive (apply_button, TRUE); -} - -static void -close_cb (GtkWidget *widget, - gpointer data) -{ - EMsgComposerAttachment *attachment; - DialogData *dialog_data; - - dialog_data = (DialogData *) data; - attachment = dialog_data->attachment; - - gtk_widget_destroy (glade_xml_get_widget (attachment->editor_gui, - "dialog")); - gtk_object_unref (GTK_OBJECT (attachment->editor_gui)); - attachment->editor_gui = NULL; - - destroy_dialog_data (dialog_data); -} - -static void -apply_cb (GtkWidget *widget, - gpointer data) -{ - DialogData *dialog_data; - - dialog_data = (DialogData *) data; - apply (dialog_data); -} - -static void -ok_cb (GtkWidget *widget, - gpointer data) -{ - apply_cb (widget, data); - close_cb (widget, data); -} - -static void -browse_cb (GtkWidget *widget, - gpointer data) -{ - DialogData *dialog_data; - - dialog_data = (DialogData *) data; - browse (dialog_data); -} - -static void -file_name_focus_out_cb (GtkWidget *widget, - GdkEventFocus *event, - gpointer data) -{ - DialogData *dialog_data; - - dialog_data = (DialogData *) data; - update_mime_type (dialog_data); -} - - -void -e_msg_composer_attachment_edit (EMsgComposerAttachment *attachment, - GtkWidget *parent) -{ - DialogData *dialog_data; - GladeXML *editor_gui; - - g_return_if_fail (attachment != NULL); - g_return_if_fail (E_IS_MSG_COMPOSER_ATTACHMENT (attachment)); - - if (attachment->editor_gui != NULL) { - GtkWidget *window; - - window = glade_xml_get_widget (attachment->editor_gui, - "dialog"); - gdk_window_show (window->window); - return; - } - - editor_gui = glade_xml_new (E_GUIDIR "/e-msg-composer-attachment.glade", - NULL); - if (editor_gui == NULL) { - g_warning ("Cannot load `e-msg-composer-attachment.glade'"); - return; - } - - attachment->editor_gui = editor_gui; - - gtk_window_set_transient_for - (GTK_WINDOW (glade_xml_get_widget (editor_gui, "dialog")), - GTK_WINDOW (gtk_widget_get_toplevel (parent))); - - dialog_data = g_new (DialogData, 1); - dialog_data->browse_widget = NULL; - dialog_data->attachment = attachment; - dialog_data->dialog = glade_xml_get_widget (editor_gui, "dialog"); - dialog_data->file_name_entry = GTK_ENTRY (glade_xml_get_widget - (editor_gui, - "file_name_entry")); - dialog_data->description_entry = GTK_ENTRY (glade_xml_get_widget - (editor_gui, - "description_entry")); - dialog_data->mime_type_entry = GTK_ENTRY (glade_xml_get_widget - (editor_gui, - "mime_type_entry")); - - if (attachment != NULL) { - set_entry (editor_gui, "file_name_entry", attachment->file_name); - set_entry (editor_gui, "description_entry", attachment->description); - set_entry (editor_gui, "mime_type_entry", attachment->mime_type); - } - - connect_entry_changed (editor_gui, "file_name_entry", - entry_changed_cb, dialog_data); - connect_entry_changed (editor_gui, "description_entry", - entry_changed_cb, dialog_data); - - connect_widget (editor_gui, "ok_button", "clicked", ok_cb, dialog_data); - connect_widget (editor_gui, "apply_button", "clicked", apply_cb, dialog_data); - connect_widget (editor_gui, "close_button", "clicked", close_cb, dialog_data); - - connect_widget (editor_gui, "browse_button", "clicked", browse_cb, dialog_data); - - connect_widget (editor_gui, "file_name_entry", "focus_out_event", - file_name_focus_out_cb, dialog_data); -} diff --git a/widgets/e-msg-composer-attachment.glade b/widgets/e-msg-composer-attachment.glade deleted file mode 100644 index 72c0132639..0000000000 --- a/widgets/e-msg-composer-attachment.glade +++ /dev/null @@ -1,290 +0,0 @@ - - - - - e-msg-composer-attachment - e-msg-composer-attachment - - src - pixmaps - C - True - True - False - True - True - True - True - interface.c - interface.h - callbacks.c - callbacks.h - support.c - support.h - - - - - GnomeDialog - dialog - Attachment properties - GTK_WINDOW_TOPLEVEL - GTK_WIN_POS_NONE - False - False - False - False - False - False - - - GtkVBox - GnomeDialog:vbox - dialog-vbox1 - False - 8 - - 4 - True - True - - - - GtkTable - table1 - 3 - 2 - False - 10 - 5 - - 0 - True - True - - - - GtkLabel - label1 - - GTK_JUSTIFY_CENTER - False - 0.5 - 0.5 - 0 - 0 - - 0 - 1 - 1 - 2 - 0 - 0 - False - False - False - False - False - False - - - - - GtkLabel - label3 - - GTK_JUSTIFY_CENTER - False - 0.5 - 0.5 - 0 - 0 - - 0 - 1 - 2 - 3 - 0 - 0 - False - False - False - False - False - False - - - - - GtkEntry - description_entry - True - True - True - 0 - - - 1 - 2 - 1 - 2 - 0 - 0 - True - False - False - False - True - False - - - - - GtkLabel - label2 - - GTK_JUSTIFY_CENTER - False - 0.5 - 0.5 - 0 - 0 - - 0 - 1 - 0 - 1 - 0 - 0 - False - False - False - False - False - False - - - - - GtkHBox - hbox3 - False - 10 - - 1 - 2 - 0 - 1 - 0 - 0 - True - True - True - True - True - True - - - - GtkEntry - file_name_entry - 290 - True - True - True - 0 - - - 0 - True - True - - - - - GtkButton - browse_button - 80 - True - - - 0 - False - False - - - - - - GtkEntry - mime_type_entry - False - True - False - True - 0 - - - 1 - 2 - 2 - 3 - 0 - 0 - True - False - False - False - True - False - - - - - - GtkHButtonBox - GnomeDialog:action_area - dialog-action_area1 - GTK_BUTTONBOX_END - 8 - 85 - 27 - 7 - 0 - - 0 - False - True - GTK_PACK_END - - - - GtkButton - ok_button - True - True - True - GNOME_STOCK_BUTTON_OK - - - - GtkButton - apply_button - False - True - True - GNOME_STOCK_BUTTON_APPLY - - - - GtkButton - close_button - True - True - GNOME_STOCK_BUTTON_CLOSE - - - - - - diff --git a/widgets/e-msg-composer-attachment.h b/widgets/e-msg-composer-attachment.h deleted file mode 100644 index 7e3c88238b..0000000000 --- a/widgets/e-msg-composer-attachment.h +++ /dev/null @@ -1,72 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* e-msg-composer-attachment.h - * - * Copyright (C) 1999 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 __E_MSG_COMPOSER_ATTACHMENT_H__ -#define __E_MSG_COMPOSER_ATTACHMENT_H__ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus */ - -#define E_TYPE_MSG_COMPOSER_ATTACHMENT (e_msg_composer_attachment_get_type ()) -#define E_MSG_COMPOSER_ATTACHMENT(obj) (GTK_CHECK_CAST ((obj), E_TYPE_MSG_COMPOSER_ATTACHMENT, EMsgComposerAttachment)) -#define E_MSG_COMPOSER_ATTACHMENT_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_TYPE_MSG_COMPOSER_ATTACHMENT, EMsgComposerAttachmentClass)) -#define E_IS_MSG_COMPOSER_ATTACHMENT(obj) (GTK_CHECK_TYPE ((obj), E_TYPE_MSG_COMPOSER_ATTACHMENT)) -#define E_IS_MSG_COMPOSER_ATTACHMENT_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), E_TYPE_MSG_COMPOSER_ATTACHMENT)) - - -typedef struct _EMsgComposerAttachment EMsgComposerAttachment; -typedef struct _EMsgComposerAttachmentClass EMsgComposerAttachmentClass; - -struct _EMsgComposerAttachment { - GtkObject parent; - - GladeXML *editor_gui; - - gchar *file_name; - gchar *description; - gchar *mime_type; - - gulong size; -}; - -struct _EMsgComposerAttachmentClass { - GtkObjectClass parent_class; - - void (*changed) (EMsgComposerAttachment *msg_composer_attachment); -}; - - -GtkType e_msg_composer_attachment_get_type (void); -EMsgComposerAttachment *e_msg_composer_attachment_new (const gchar *file_name); -void e_msg_composer_attachment_edit (EMsgComposerAttachment *attachment, - GtkWidget *parent); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* __E_MSG_COMPOSER_ATTACHMENT_H__ */ diff --git a/widgets/e-msg-composer-hdrs.c b/widgets/e-msg-composer-hdrs.c deleted file mode 100644 index f686580fc5..0000000000 --- a/widgets/e-msg-composer-hdrs.c +++ /dev/null @@ -1,355 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* msg-composer-hdrs.c - * - * Copyright (C) 1999 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 - */ - -#ifdef _HAVE_CONFIG_H -#include -#endif - -#include -#include - -#include "e-msg-composer-address-entry.h" -#include "e-msg-composer-hdrs.h" - - -struct _EMsgComposerHdrsPrivate { - /* Total number of headers that we have. */ - guint num_hdrs; - - /* The tooltips. */ - GtkTooltips *tooltips; - - /* Standard headers. */ - GtkWidget *to_entry; - GtkWidget *cc_entry; - GtkWidget *bcc_entry; - GtkWidget *subject_entry; -}; - - -static GtkTableClass *parent_class = NULL; - -enum { - SHOW_ADDRESS_DIALOG, - LAST_SIGNAL -}; - -static gint signals[LAST_SIGNAL]; - - -static void -address_button_clicked_cb (GtkButton *button, - gpointer data) -{ - gtk_signal_emit (GTK_OBJECT (data), signals[SHOW_ADDRESS_DIALOG]); -} - -static GtkWidget * -add_header (EMsgComposerHdrs *hdrs, - const gchar *name, - const gchar *tip, - const gchar *tip_private, - gboolean addrbook_button) -{ - EMsgComposerHdrsPrivate *priv; - GtkWidget *label; - GtkWidget *entry; - guint pad; - - priv = hdrs->priv; - - if (addrbook_button) { - label = gtk_button_new_with_label (name); - gtk_signal_connect (GTK_OBJECT (label), "clicked", - GTK_SIGNAL_FUNC (address_button_clicked_cb), - hdrs); - pad = 2; - gtk_tooltips_set_tip (hdrs->priv->tooltips, label, - _("Click here for the address book"), - NULL); - } else { - label = gtk_label_new (name); - pad = GNOME_PAD; - } - - gtk_table_attach (GTK_TABLE (hdrs), label, - 0, 1, priv->num_hdrs, priv->num_hdrs + 1, - GTK_FILL, GTK_FILL, - pad, pad); - gtk_widget_show (label); - - entry = e_msg_composer_address_entry_new (); - gtk_table_attach (GTK_TABLE (hdrs), entry, - 1, 2, priv->num_hdrs, priv->num_hdrs + 1, - GTK_FILL | GTK_EXPAND, GTK_FILL, - 2, 2); - gtk_widget_show (entry); - - gtk_tooltips_set_tip (hdrs->priv->tooltips, entry, tip, tip_private); - - priv->num_hdrs++; - - return entry; -} - -static void -setup_headers (EMsgComposerHdrs *hdrs) -{ - EMsgComposerHdrsPrivate *priv; - - priv = hdrs->priv; - - priv->to_entry = add_header - (hdrs, _("To:"), - _("Enter the recipients of the message"), - NULL, - TRUE); - priv->cc_entry = add_header - (hdrs, _("Cc:"), - _("Enter the addresses that will receive a carbon copy of " - "the message"), - NULL, - TRUE); - priv->bcc_entry = add_header - (hdrs, _("Bcc:"), - _("Enter the addresses that will receive a carbon copy of " - "the message without appearing in the recipient list of " - "the message."), - NULL, - TRUE); - priv->subject_entry = add_header - (hdrs, _("Subject:"), - _("Enter the subject of the mail"), - NULL, - FALSE); -} - - -/* GtkObject methods. */ - -static void -destroy (GtkObject *object) -{ - EMsgComposerHdrs *hdrs; - EMsgComposerHdrsPrivate *priv; - - hdrs = E_MSG_COMPOSER_HDRS (object); - priv = hdrs->priv; - - gtk_object_destroy (GTK_OBJECT (priv->tooltips)); - - if (GTK_OBJECT_CLASS (parent_class)->destroy != NULL) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - - -static void -class_init (EMsgComposerHdrsClass *class) -{ - GtkObjectClass *object_class; - - object_class = GTK_OBJECT_CLASS (class); - object_class->destroy = destroy; - - parent_class = gtk_type_class (gtk_table_get_type ()); - - signals[SHOW_ADDRESS_DIALOG] = - gtk_signal_new ("show_address_dialog", - GTK_RUN_LAST, - object_class->type, - GTK_SIGNAL_OFFSET (EMsgComposerHdrsClass, - show_address_dialog), - gtk_marshal_NONE__NONE, - GTK_TYPE_NONE, 0); - - gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL); -} - -static void -init (EMsgComposerHdrs *hdrs) -{ - EMsgComposerHdrsPrivate *priv; - - priv = g_new (EMsgComposerHdrsPrivate, 1); - - priv->to_entry = NULL; - priv->cc_entry = NULL; - priv->bcc_entry = NULL; - priv->subject_entry = NULL; - - priv->tooltips = gtk_tooltips_new (); - - priv->num_hdrs = 0; - - hdrs->priv = priv; -} - - -GtkType -e_msg_composer_hdrs_get_type (void) -{ - static GtkType type = 0; - - if (type == 0) { - static const GtkTypeInfo info = { - "EMsgComposerHdrs", - sizeof (EMsgComposerHdrs), - sizeof (EMsgComposerHdrsClass), - (GtkClassInitFunc) class_init, - (GtkObjectInitFunc) init, - /* reserved_1 */ NULL, - /* reserved_2 */ NULL, - (GtkClassInitFunc) NULL, - }; - - type = gtk_type_unique (gtk_table_get_type (), &info); - } - - return type; -} - -GtkWidget * -e_msg_composer_hdrs_new (void) -{ - EMsgComposerHdrs *new; - - new = gtk_type_new (e_msg_composer_hdrs_get_type ()); - - setup_headers (E_MSG_COMPOSER_HDRS (new)); - - return GTK_WIDGET (new); -} - - -static void -set_recipients (CamelMimeMessage *msg, - GtkWidget *entry_widget, - const gchar *type) -{ - EMsgComposerAddressEntry *entry; - GList *list; - GList *p; - - entry = E_MSG_COMPOSER_ADDRESS_ENTRY (entry_widget); - list = e_msg_composer_address_entry_get_addresses (entry); - - /* FIXME leak? */ - - for (p = list; p != NULL; p = p->next) { - printf ("Adding `%s:' header: %s\n", type, (gchar *) p->data); - camel_mime_message_add_recipient (msg, type, (gchar *) p->data); - } - - g_list_free (list); -} - -void -e_msg_composer_hdrs_to_message (EMsgComposerHdrs *hdrs, - CamelMimeMessage *msg) -{ - const gchar *s; - - g_return_if_fail (hdrs != NULL); - g_return_if_fail (E_IS_MSG_COMPOSER_HDRS (hdrs)); - g_return_if_fail (msg != NULL); - g_return_if_fail (IS_CAMEL_MIME_MESSAGE (msg)); - - s = gtk_entry_get_text (GTK_ENTRY (hdrs->priv->subject_entry)); - camel_mime_message_set_subject (msg, g_strdup (s)); - - set_recipients (msg, hdrs->priv->to_entry, RECIPIENT_TYPE_TO); - set_recipients (msg, hdrs->priv->cc_entry, RECIPIENT_TYPE_CC); - set_recipients (msg, hdrs->priv->bcc_entry, RECIPIENT_TYPE_BCC); -} - - -void -e_msg_composer_hdrs_set_to (EMsgComposerHdrs *hdrs, - GList *to_list) -{ - EMsgComposerAddressEntry *entry; - - g_return_if_fail (hdrs != NULL); - g_return_if_fail (E_IS_MSG_COMPOSER_HDRS (hdrs)); - - entry = E_MSG_COMPOSER_ADDRESS_ENTRY (hdrs->priv->to_entry); - e_msg_composer_address_entry_set_list (entry, to_list); -} - -void -e_msg_composer_hdrs_set_cc (EMsgComposerHdrs *hdrs, - GList *cc_list) -{ - EMsgComposerAddressEntry *entry; - - g_return_if_fail (hdrs != NULL); - g_return_if_fail (E_IS_MSG_COMPOSER_HDRS (hdrs)); - - entry = E_MSG_COMPOSER_ADDRESS_ENTRY (hdrs->priv->cc_entry); - e_msg_composer_address_entry_set_list (entry, cc_list); -} - -void -e_msg_composer_hdrs_set_bcc (EMsgComposerHdrs *hdrs, - GList *bcc_list) -{ - EMsgComposerAddressEntry *entry; - - g_return_if_fail (hdrs != NULL); - g_return_if_fail (E_IS_MSG_COMPOSER_HDRS (hdrs)); - - entry = E_MSG_COMPOSER_ADDRESS_ENTRY (hdrs->priv->bcc_entry); - e_msg_composer_address_entry_set_list (entry, bcc_list); -} - - -GList * -e_msg_composer_hdrs_get_to (EMsgComposerHdrs *hdrs) -{ - g_return_val_if_fail (hdrs != NULL, NULL); - g_return_val_if_fail (E_IS_MSG_COMPOSER_HDRS (hdrs), NULL); - - return e_msg_composer_address_entry_get_addresses - (E_MSG_COMPOSER_ADDRESS_ENTRY (hdrs->priv->to_entry)); -} - -GList * -e_msg_composer_hdrs_get_cc (EMsgComposerHdrs *hdrs) -{ - g_return_val_if_fail (hdrs != NULL, NULL); - g_return_val_if_fail (E_IS_MSG_COMPOSER_HDRS (hdrs), NULL); - - return e_msg_composer_address_entry_get_addresses - (E_MSG_COMPOSER_ADDRESS_ENTRY (hdrs->priv->cc_entry)); -} - -GList * -e_msg_composer_hdrs_get_bcc (EMsgComposerHdrs *hdrs) -{ - g_return_val_if_fail (hdrs != NULL, NULL); - g_return_val_if_fail (E_IS_MSG_COMPOSER_HDRS (hdrs), NULL); - - return e_msg_composer_address_entry_get_addresses - (E_MSG_COMPOSER_ADDRESS_ENTRY (hdrs->priv->bcc_entry)); -} - diff --git a/widgets/e-msg-composer-hdrs.h b/widgets/e-msg-composer-hdrs.h deleted file mode 100644 index d053573d85..0000000000 --- a/widgets/e-msg-composer-hdrs.h +++ /dev/null @@ -1,80 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* msg-composer-hdrs.h - * - * Copyright (C) 1999 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 ___E_MSG_COMPOSER_HDRS_H__ -#define ___E_MSG_COMPOSER_HDRS_H__ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus */ - -#define E_TYPE_MSG_COMPOSER_HDRS (e_msg_composer_hdrs_get_type ()) -#define E_MSG_COMPOSER_HDRS(obj) (GTK_CHECK_CAST ((obj), E_TYPE_MSG_COMPOSER_HDRS, EMsgComposerHdrs)) -#define E_MSG_COMPOSER_HDRS_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_TYPE_MSG_COMPOSER_HDRS, EMsgComposerHdrsClass)) -#define E_IS_MSG_COMPOSER_HDRS(obj) (GTK_CHECK_TYPE ((obj), E_TYPE_MSG_COMPOSER_HDRS)) -#define E_IS_MSG_COMPOSER_HDRS_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), E_TYPE_MSG_COMPOSER_HDRS)) - - -typedef struct _EMsgComposerHdrs EMsgComposerHdrs; -typedef struct _EMsgComposerHdrsClass EMsgComposerHdrsClass; -typedef struct _EMsgComposerHdrsPrivate EMsgComposerHdrsPrivate; - -struct _EMsgComposerHdrs { - GtkTable parent; - - EMsgComposerHdrsPrivate *priv; -}; - -struct _EMsgComposerHdrsClass { - GtkTableClass parent_class; - - void (* show_address_dialog) (EMsgComposerHdrs *hdrs); -}; - - -GtkType e_msg_composer_hdrs_get_type (void); -GtkWidget *e_msg_composer_hdrs_new (void); -void e_msg_composer_hdrs_to_message (EMsgComposerHdrs *hdrs, - CamelMimeMessage *msg); - -void e_msg_composer_hdrs_set_to (EMsgComposerHdrs *hdrs, - GList *to_list); -void e_msg_composer_hdrs_set_cc (EMsgComposerHdrs *hdrs, - GList *cc_list); -void e_msg_composer_hdrs_set_bcc (EMsgComposerHdrs *hdrs, - GList *bcc_list); - -GList *e_msg_composer_hdrs_get_to (EMsgComposerHdrs *hdrs); -GList *e_msg_composer_hdrs_get_cc (EMsgComposerHdrs *hdrs); -GList *e_msg_composer_hdrs_get_bcc (EMsgComposerHdrs *hdrs); - -#ifdef _cplusplus -} -#endif /* _cplusplus */ - - -#endif /* __E_MSG_COMPOSER_HDRS_H__ */ diff --git a/widgets/e-msg-composer.c b/widgets/e-msg-composer.c deleted file mode 100644 index 8e83c3e11c..0000000000 --- a/widgets/e-msg-composer.c +++ /dev/null @@ -1,564 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* e-msg-composer.c - * - * Copyright (C) 1999 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 - */ - -/* - - TODO - - - Somehow users should be able to see if any file(s) are attached even when - the attachment bar is not shown. - -*/ - -#ifdef _HAVE_CONFIG_H -#include -#endif - -#include -#include -#include - -#include "e-msg-composer.h" -#include "e-msg-composer-address-dialog.h" -#include "e-msg-composer-attachment-bar.h" -#include "e-msg-composer-hdrs.h" - - -#define DEFAULT_WIDTH 600 -#define DEFAULT_HEIGHT 500 - - -enum { - SEND, - POSTPONE, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = { 0 }; - -static GnomeAppClass *parent_class = NULL; - - -static void -free_string_list (GList *list) -{ - GList *p; - - if (list == NULL) - return; - - for (p = list; p != NULL; p = p->next) - g_free (p->data); - - g_list_free (list); -} - -/* This functions builds a CamelMimeMessage for the message that the user has - composed in `composer'. */ -static CamelMimeMessage * -build_message (EMsgComposer *composer) -{ - CamelMimeMessage *new; - CamelMimeBodyPart *body_part; - CamelMultipart *multipart; - gchar *text; - - new = camel_mime_message_new_with_session (NULL); - - e_msg_composer_hdrs_to_message (E_MSG_COMPOSER_HDRS (composer->hdrs), - new); - - multipart = camel_multipart_new (); - body_part = camel_mime_body_part_new (); - - text = gtk_editable_get_chars (GTK_EDITABLE (composer->text), 0, -1); - camel_mime_part_set_text (CAMEL_MIME_PART (body_part), text); - camel_multipart_add_part (multipart, body_part); - - e_msg_composer_attachment_bar_to_multipart - (E_MSG_COMPOSER_ATTACHMENT_BAR (composer->attachment_bar), - multipart); - - camel_medium_set_content_object (CAMEL_MEDIUM (new), - CAMEL_DATA_WRAPPER (multipart)); - - /* FIXME refcounting is most certainly wrong. We want all the stuff to - be destroyed when we unref() the message. */ - - return new; -} - - -static void -show_attachments (EMsgComposer *composer, - gboolean show) -{ - if (show) { - gtk_widget_show (composer->attachment_scrolled_window); - gtk_widget_show (composer->attachment_bar); - } else { - gtk_widget_hide (composer->attachment_scrolled_window); - gtk_widget_hide (composer->attachment_bar); - } - - composer->attachment_bar_visible = show; - - /* Update the GUI. */ - - gtk_check_menu_item_set_active - (GTK_CHECK_MENU_ITEM - (glade_xml_get_widget (composer->menubar_gui, - "menu_view_attachments")), - show); - - /* XXX we should update the toggle toolbar item as well. At - this point, it is not a toggle because Glade is broken. */ -} - - -/* Address dialog callbacks. */ - -static void -address_dialog_destroy_cb (GtkWidget *widget, - gpointer data) -{ - EMsgComposer *composer; - - composer = E_MSG_COMPOSER (data); - composer->address_dialog = NULL; -} - -static void -address_dialog_apply_cb (EMsgComposerAddressDialog *dialog, - gpointer data) -{ - EMsgComposerHdrs *hdrs; - GList *list; - - hdrs = E_MSG_COMPOSER_HDRS (E_MSG_COMPOSER (data)->hdrs); - - list = e_msg_composer_address_dialog_get_to_list (dialog); - e_msg_composer_hdrs_set_to (hdrs, list); - - list = e_msg_composer_address_dialog_get_cc_list (dialog); - e_msg_composer_hdrs_set_cc (hdrs, list); - - list = e_msg_composer_address_dialog_get_bcc_list (dialog); - e_msg_composer_hdrs_set_bcc (hdrs, list); -} - - -/* Message composer window callbacks. */ - -static void -send_cb (GtkWidget *widget, - gpointer data) -{ - gtk_signal_emit (GTK_OBJECT (data), signals[SEND]); -} - -static void -menu_view_attachments_activate_cb (GtkWidget *widget, - gpointer data) -{ - e_msg_composer_show_attachments (E_MSG_COMPOSER (data), - GTK_CHECK_MENU_ITEM (widget)->active); -} - -static void -toolbar_view_attachments_clicked_cb (GtkWidget *widget, - gpointer data) -{ - EMsgComposer *composer; - - composer = E_MSG_COMPOSER (data); - - e_msg_composer_show_attachments (composer, - ! composer->attachment_bar_visible); -} - -static void -add_attachment_cb (GtkWidget *widget, - gpointer data) -{ - EMsgComposer *composer; - - composer = E_MSG_COMPOSER (data); - - e_msg_composer_attachment_bar_attach - (E_MSG_COMPOSER_ATTACHMENT_BAR (composer->attachment_bar), - NULL); -} - -/* Create the address dialog if not created already. */ -static void -setup_address_dialog (EMsgComposer *composer) -{ - EMsgComposerAddressDialog *dialog; - EMsgComposerHdrs *hdrs; - GList *list; - - if (composer->address_dialog != NULL) - return; - - composer->address_dialog = e_msg_composer_address_dialog_new (); - dialog = E_MSG_COMPOSER_ADDRESS_DIALOG (composer->address_dialog); - hdrs = E_MSG_COMPOSER_HDRS (composer->hdrs); - - gtk_signal_connect (GTK_OBJECT (dialog), - "destroy", address_dialog_destroy_cb, composer); - gtk_signal_connect (GTK_OBJECT (dialog), - "apply", address_dialog_apply_cb, composer); - - list = e_msg_composer_hdrs_get_to (hdrs); - e_msg_composer_address_dialog_set_to_list (dialog, list); - - list = e_msg_composer_hdrs_get_cc (hdrs); - e_msg_composer_address_dialog_set_cc_list (dialog, list); - - list = e_msg_composer_hdrs_get_bcc (hdrs); - e_msg_composer_address_dialog_set_bcc_list (dialog, list); -} - -static void -address_dialog_cb (GtkWidget *widget, - gpointer data) -{ - EMsgComposer *composer; - - /* FIXME maybe we should hide the dialog on Cancel/OK instead of - destroying it. */ - - composer = E_MSG_COMPOSER (data); - - setup_address_dialog (composer); - - gtk_widget_show (composer->address_dialog); - gdk_window_show (composer->address_dialog->window); -} - -static void -glade_connect (GladeXML *gui, - const gchar *widget_name, - const gchar *signal_name, - GtkSignalFunc callback, - gpointer callback_data) -{ - GtkWidget *widget; - - widget = glade_xml_get_widget (gui, widget_name); - if (widget == NULL) - g_warning ("Widget `%s' was not found.", widget_name); - else - gtk_signal_connect (GTK_OBJECT (widget), signal_name, - GTK_SIGNAL_FUNC (callback), callback_data); -} - -static void -attachment_bar_changed (EMsgComposerAttachmentBar *bar, - gpointer data) -{ - EMsgComposer *composer; - - composer = E_MSG_COMPOSER (data); - - if (e_msg_composer_attachment_bar_get_num_attachments (bar) > 0) - e_msg_composer_show_attachments (composer, TRUE); - else - e_msg_composer_show_attachments (composer, FALSE); -} - -static void -setup_signals (EMsgComposer *composer) -{ - glade_connect (composer->menubar_gui, "menu_send", - "activate", GTK_SIGNAL_FUNC (send_cb), composer); - glade_connect (composer->toolbar_gui, "toolbar_send", - "clicked", GTK_SIGNAL_FUNC (send_cb), composer); - - glade_connect (composer->menubar_gui, "menu_view_attachments", - "activate", - GTK_SIGNAL_FUNC (menu_view_attachments_activate_cb), - composer); - glade_connect (composer->toolbar_gui, "toolbar_view_attachments", - "clicked", - GTK_SIGNAL_FUNC (toolbar_view_attachments_clicked_cb), - composer); - - glade_connect (composer->menubar_gui, "menu_add_attachment", - "activate", - GTK_SIGNAL_FUNC (add_attachment_cb), composer); - glade_connect (composer->toolbar_gui, "toolbar_add_attachment", - "clicked", - GTK_SIGNAL_FUNC (add_attachment_cb), composer); - - glade_connect (composer->menubar_gui, "menubar_address_dialog", - "activate", - GTK_SIGNAL_FUNC (address_dialog_cb), composer); - glade_connect (composer->toolbar_gui, "toolbar_address_dialog", - "clicked", - GTK_SIGNAL_FUNC (address_dialog_cb), composer); - - gtk_signal_connect (GTK_OBJECT (composer->attachment_bar), - "changed", - GTK_SIGNAL_FUNC (attachment_bar_changed), - composer); - - gtk_signal_connect (GTK_OBJECT (composer->hdrs), "show_address_dialog", - GTK_SIGNAL_FUNC (address_dialog_cb), - composer); -} - - -/* GtkObject methods. */ - -static void -destroy (GtkObject *object) -{ - EMsgComposer *composer; - - composer = E_MSG_COMPOSER (object); - - gtk_object_unref (GTK_OBJECT (composer->menubar_gui)); - gtk_object_unref (GTK_OBJECT (composer->toolbar_gui)); - gtk_object_unref (GTK_OBJECT (composer->appbar_gui)); - - if (composer->address_dialog != NULL) - gtk_widget_destroy (composer->address_dialog); - - if (GTK_OBJECT_CLASS (parent_class)->destroy != NULL) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - - -static void -class_init (EMsgComposerClass *klass) -{ - GtkObjectClass *object_class; - - object_class = (GtkObjectClass *) klass; - - object_class->destroy = destroy; - - parent_class = gtk_type_class (gnome_app_get_type ()); - - signals[SEND] = - gtk_signal_new ("send", - GTK_RUN_LAST, - object_class->type, - GTK_SIGNAL_OFFSET (EMsgComposerClass, send), - gtk_marshal_NONE__NONE, - GTK_TYPE_NONE, 0); - - signals[POSTPONE] = - gtk_signal_new ("postpone", - GTK_RUN_LAST, - object_class->type, - GTK_SIGNAL_OFFSET (EMsgComposerClass, postpone), - gtk_marshal_NONE__NONE, - GTK_TYPE_NONE, 0); - - gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL); -} - -static void -init (EMsgComposer *composer) -{ - composer->menubar_gui = NULL; - composer->toolbar_gui = NULL; - composer->appbar_gui = NULL; - - composer->hdrs = NULL; - - composer->text = NULL; - composer->text_scrolled_window = NULL; - - composer->address_dialog = NULL; - - composer->attachment_bar = NULL; - composer->attachment_scrolled_window = NULL; -} - - -GtkType -e_msg_composer_get_type (void) -{ - static GtkType type = 0; - - if (type == 0) { - static const GtkTypeInfo info = { - "EMsgComposer", - sizeof (EMsgComposer), - sizeof (EMsgComposerClass), - (GtkClassInitFunc) class_init, - (GtkObjectInitFunc) init, - /* reserved_1 */ NULL, - /* reserved_2 */ NULL, - (GtkClassInitFunc) NULL, - }; - - type = gtk_type_unique (gnome_app_get_type (), &info); - } - - return type; -} - - -/** - * e_msg_composer_construct: - * @composer: A message composer widget - * - * Construct @composer. - **/ -void -e_msg_composer_construct (EMsgComposer *composer) -{ - GtkWidget *vbox; - - gtk_window_set_default_size (GTK_WINDOW (composer), - DEFAULT_WIDTH, DEFAULT_HEIGHT); - - gnome_app_construct (GNOME_APP (composer), "e-msg-composer", - "Compose a message"); - - composer->menubar_gui = glade_xml_new (E_GUIDIR "/e-msg-composer.glade", - "menubar"); - gnome_app_set_menus (GNOME_APP (composer), - GTK_MENU_BAR (glade_xml_get_widget (composer->menubar_gui, - "menubar"))); - - composer->toolbar_gui = glade_xml_new (E_GUIDIR "/e-msg-composer.glade", - "toolbar"); - gnome_app_set_toolbar (GNOME_APP (composer), - GTK_TOOLBAR (glade_xml_get_widget (composer->toolbar_gui, - "toolbar"))); - - composer->appbar_gui = glade_xml_new (E_GUIDIR "/e-msg-composer.glade", - "appbar"); - gnome_app_set_statusbar (GNOME_APP (composer), - glade_xml_get_widget (composer->appbar_gui, - "appbar")); - - vbox = gtk_vbox_new (FALSE, 0); - - composer->hdrs = e_msg_composer_hdrs_new (); - gtk_box_pack_start (GTK_BOX (vbox), composer->hdrs, FALSE, TRUE, 0); - gtk_widget_show (composer->hdrs); - - /* GtkText for message body editing, wrapped into a - GtkScrolledWindow. */ - - composer->text_scrolled_window = gtk_scrolled_window_new (NULL, NULL); - gtk_scrolled_window_set_policy - (GTK_SCROLLED_WINDOW (composer->text_scrolled_window), - GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - composer->text = gtk_text_new (NULL, NULL); - gtk_text_set_word_wrap (GTK_TEXT (composer->text), FALSE); - gtk_text_set_editable (GTK_TEXT (composer->text), TRUE); - gtk_container_add (GTK_CONTAINER (composer->text_scrolled_window), - composer->text); - gtk_widget_show (composer->text); - gtk_box_pack_start (GTK_BOX (vbox), composer->text_scrolled_window, - TRUE, TRUE, 0); - gtk_widget_show (composer->text_scrolled_window); - - /* Attachment editor, wrapped into a GtkScrolledWindow. We don't - show it for now. */ - - composer->attachment_scrolled_window = gtk_scrolled_window_new (NULL, - NULL); - gtk_scrolled_window_set_policy - (GTK_SCROLLED_WINDOW (composer->attachment_scrolled_window), - GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - composer->attachment_bar = e_msg_composer_attachment_bar_new (NULL); - GTK_WIDGET_SET_FLAGS (composer->attachment_bar, GTK_CAN_FOCUS); - gtk_container_add (GTK_CONTAINER (composer->attachment_scrolled_window), - composer->attachment_bar); - gtk_box_pack_start (GTK_BOX (vbox), - composer->attachment_scrolled_window, - FALSE, TRUE, GNOME_PAD_SMALL); - - gnome_app_set_contents (GNOME_APP (composer), vbox); - gtk_widget_show (vbox); - - e_msg_composer_show_attachments (composer, FALSE); - - setup_signals (composer); -} - -/** - * e_msg_composer_new: - * - * Create a new message composer widget. - * - * Return value: A pointer to the newly created widget - **/ -GtkWidget * -e_msg_composer_new (void) -{ - GtkWidget *new; - - new = gtk_type_new (e_msg_composer_get_type ()); - e_msg_composer_construct (E_MSG_COMPOSER (new)); - - return new; -} - - -/** - * e_msg_composer_show_attachments: - * @composer: A message composer widget - * @show: A boolean specifying whether the attachment bar should be shown or - * not - * - * If @show is %FALSE, hide the attachment bar. Otherwise, show it. - **/ -void -e_msg_composer_show_attachments (EMsgComposer *composer, - gboolean show) -{ - g_return_if_fail (composer != NULL); - g_return_if_fail (E_IS_MSG_COMPOSER (composer)); - - show_attachments (composer, show); -} - - -/** - * e_msg_composer_get_message: - * @composer: A message composer widget - * - * Retrieve the message edited by the user as a CamelMimeMessage. The - * CamelMimeMessage object is created on the fly; subsequent calls to this - * function will always create new objects from scratch. - * - * Return value: A pointer to the new CamelMimeMessage object - **/ -CamelMimeMessage * -e_msg_composer_get_message (EMsgComposer *composer) -{ - g_return_val_if_fail (composer != NULL, NULL); - g_return_val_if_fail (E_IS_MSG_COMPOSER (composer), NULL); - - return build_message (composer); -} diff --git a/widgets/e-msg-composer.glade b/widgets/e-msg-composer.glade deleted file mode 100644 index b747c6f979..0000000000 --- a/widgets/e-msg-composer.glade +++ /dev/null @@ -1,587 +0,0 @@ - - - - - Message Composer - e-msg-composer - - src - pixmaps - C - True - True - False - True - True - True - True - interface.c - interface.h - callbacks.c - callbacks.h - support.c - support.h - - - - - GnomeApp - app1 - Message Composer - GTK_WINDOW_TOPLEVEL - GTK_WIN_POS_NONE - False - False - True - False - True - - - GnomeDock - GnomeApp:dock - dock1 - True - - 0 - True - True - - - - GnomeDockItem - dockitem1 - 2 - GNOME_DOCK_TOP - 0 - 0 - 0 - False - True - False - True - False - GTK_SHADOW_OUT - - - GtkMenuBar - menubar - GTK_SHADOW_NONE - - - GtkMenuItem - file - GNOMEUIINFO_MENU_FILE_TREE - - - GtkMenu - file_menu - - - GtkPixmapMenuItem - open - - activate - on_open_activate - Wed, 27 Oct 1999 22:25:08 GMT - - GNOMEUIINFO_MENU_OPEN_ITEM - - - - GtkPixmapMenuItem - save - - activate - on_save_activate - Wed, 27 Oct 1999 22:25:13 GMT - - GNOMEUIINFO_MENU_SAVE_ITEM - - - - GtkPixmapMenuItem - save_as - - activate - on_save_as_activate - Wed, 27 Oct 1999 22:25:16 GMT - - GNOMEUIINFO_MENU_SAVE_AS_ITEM - - - - GtkPixmapMenuItem - save_in_folder - - activate - on_save_in_folder_activate - Wed, 27 Oct 1999 22:25:20 GMT - - - False - GNOME_STOCK_MENU_SAVE_AS - - - - GtkMenuItem - separator8 - False - - - - GtkPixmapMenuItem - menu_send - - activate - on_send_activate - Wed, 27 Oct 1999 22:25:29 GMT - - - False - GNOME_STOCK_MENU_MAIL_SND - - - - GtkMenuItem - postpone - - activate - on_postpone_activate - Wed, 27 Oct 1999 22:25:37 GMT - - - False - - - - GtkMenuItem - separator1 - False - - - - GtkPixmapMenuItem - exit - - activate - on_exit_activate - Wed, 27 Oct 1999 22:25:59 GMT - - GNOMEUIINFO_MENU_EXIT_ITEM - - - - - - GtkMenuItem - edit - GNOMEUIINFO_MENU_EDIT_TREE - - - GtkMenu - edit_menu - - - GtkPixmapMenuItem - undo - - activate - on_undo_activate - Wed, 27 Oct 1999 22:26:10 GMT - - GNOMEUIINFO_MENU_UNDO_ITEM - - - - GtkPixmapMenuItem - redo - - activate - on_redo_activate - Wed, 27 Oct 1999 22:26:15 GMT - - GNOMEUIINFO_MENU_REDO_ITEM - - - - GtkMenuItem - separator3 - False - - - - GtkPixmapMenuItem - cut - - activate - on_cut_activate - Wed, 27 Oct 1999 22:26:21 GMT - - GNOMEUIINFO_MENU_CUT_ITEM - - - - GtkPixmapMenuItem - copy - - activate - on_copy_activate - Wed, 27 Oct 1999 22:26:26 GMT - - GNOMEUIINFO_MENU_COPY_ITEM - - - - GtkPixmapMenuItem - paste - - activate - on_paste_activate - Wed, 27 Oct 1999 22:26:31 GMT - - GNOMEUIINFO_MENU_PASTE_ITEM - - - - GtkMenuItem - separator2 - False - - - - GtkPixmapMenuItem - select_all - - activate - on_select_all_activate - Wed, 27 Oct 1999 22:26:37 GMT - - GNOMEUIINFO_MENU_SELECT_ALL_ITEM - - - - GtkMenuItem - separator5 - False - - - - GtkPixmapMenuItem - find - - activate - on_find_activate - Wed, 27 Oct 1999 22:26:42 GMT - - GNOMEUIINFO_MENU_FIND_ITEM - - - - GtkPixmapMenuItem - find_again - - activate - on_find_again_activate - Wed, 27 Oct 1999 22:26:47 GMT - - GNOMEUIINFO_MENU_FIND_AGAIN_ITEM - - - - GtkPixmapMenuItem - replace - - activate - on_replace_activate - Wed, 27 Oct 1999 22:26:53 GMT - - GNOMEUIINFO_MENU_REPLACE_ITEM - - - - GtkMenuItem - separator6 - False - - - - GtkPixmapMenuItem - properties - - activate - on_properties_activate - Wed, 27 Oct 1999 22:26:58 GMT - - GNOMEUIINFO_MENU_PROPERTIES_ITEM - - - - - - GtkMenuItem - view1 - GNOMEUIINFO_MENU_VIEW_TREE - - - GtkMenu - view1_menu - - - GtkCheckMenuItem - menu_view_attachments - - activate - on_view_attachments_activate - Fri, 05 Nov 1999 18:31:16 GMT - - - False - False - - - - - - GtkMenuItem - insert - - False - - - GtkMenu - insert_menu - - - GtkMenuItem - menu_add_attachment - - activate - on_attachment_activate - Wed, 27 Oct 1999 22:27:05 GMT - - - False - - - - GtkMenuItem - text_from_file - - activate - on_text_from_file_activate - Wed, 27 Oct 1999 22:27:16 GMT - - - False - - - - GtkMenuItem - separator6 - False - - - - GtkMenuItem - hypertext_link - - activate - on_hypertext_link_activate - Wed, 27 Oct 1999 22:27:21 GMT - - - False - - - - - - GtkMenuItem - settings - GNOMEUIINFO_MENU_SETTINGS_TREE - - - GtkMenu - settings_menu - - - GtkPixmapMenuItem - preferences - - activate - on_preferences_activate - Wed, 27 Oct 1999 22:27:37 GMT - - GNOMEUIINFO_MENU_PREFERENCES_ITEM - - - - - - GtkMenuItem - tools - - False - - - GtkMenu - tools_menu - - - GtkPixmapMenuItem - spell_check1 - - activate - on_spell_check_activate - Wed, 27 Oct 1999 22:27:44 GMT - - - False - GNOME_STOCK_MENU_SPELLCHECK - - - - GtkMenuItem - separator7 - False - - - - GtkMenuItem - check_names - - activate - on_check_names_activate - Wed, 27 Oct 1999 22:27:49 GMT - - - False - - - - GtkPixmapMenuItem - menubar_address_dialog - - activate - on_address_book_activate - Wed, 27 Oct 1999 22:27:53 GMT - - - False - GNOME_STOCK_MENU_BOOK_RED - - - - - - GtkMenuItem - help - GNOMEUIINFO_MENU_HELP_TREE - - - GtkMenu - help_menu - - - GtkPixmapMenuItem - about - - activate - on_about_activate - Wed, 27 Oct 1999 22:28:01 GMT - - GNOMEUIINFO_MENU_ABOUT_ITEM - - - - - - - - GnomeDockItem - dockitem2 - 1 - GNOME_DOCK_TOP - 1 - 0 - 0 - False - True - False - False - False - GTK_SHADOW_OUT - - - GtkToolbar - toolbar - 1 - GTK_ORIENTATION_HORIZONTAL - GTK_TOOLBAR_BOTH - 16 - GTK_TOOLBAR_SPACE_LINE - GTK_RELIEF_NONE - True - - - GtkButton - Toolbar:button - toolbar_send - Send this message - - GNOME_STOCK_PIXMAP_MAIL_SND - - - - GtkToggleButton - Toolbar:button - toolbar_view_attachments - Show attachments for this message - - False - - - - GtkButton - Toolbar:button - toolbar_add_attachment - Attach a file - - - - - GtkButton - Toolbar:button - toolbar_address_dialog - Go to addressbook - - GNOME_STOCK_PIXMAP_BOOK_RED - - - - - - Placeholder - GnomeDock:contents - - - - - GnomeAppBar - GnomeApp:appbar - appbar - True - True - - 0 - True - True - - - - - diff --git a/widgets/e-msg-composer.h b/widgets/e-msg-composer.h deleted file mode 100644 index 3028dedca3..0000000000 --- a/widgets/e-msg-composer.h +++ /dev/null @@ -1,87 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* e-msg-composer.h - * - * Copyright (C) 1999 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 ___E_MSG_COMPOSER_H__ -#define ___E_MSG_COMPOSER_H__ - -#include -#include - -#include "e-msg-composer-attachment-bar.h" -#include "e-msg-composer-hdrs.h" - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus */ - - -#define E_TYPE_MSG_COMPOSER (e_msg_composer_get_type ()) -#define E_MSG_COMPOSER(obj) (GTK_CHECK_CAST ((obj), E_TYPE_MSG_COMPOSER, EMsgComposer)) -#define E_MSG_COMPOSER_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_TYPE_MSG_COMPOSER, EMsgComposerClass)) -#define E_IS_MSG_COMPOSER(obj) (GTK_CHECK_TYPE ((obj), E_TYPE_MSG_COMPOSER)) -#define E_IS_MSG_COMPOSER_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), E_TYPE_MSG_COMPOSER)) - - -typedef struct _EMsgComposer EMsgComposer; -typedef struct _EMsgComposerClass EMsgComposerClass; - -struct _EMsgComposer { - GnomeApp parent; - - GladeXML *menubar_gui; - GladeXML *toolbar_gui; - GladeXML *appbar_gui; - - GtkWidget *hdrs; - - GtkWidget *text; - GtkWidget *text_scrolled_window; - - GtkWidget *attachment_bar; - GtkWidget *attachment_scrolled_window; - - GtkWidget *address_dialog; - - gboolean attachment_bar_visible : 1; -}; - -struct _EMsgComposerClass { - GnomeAppClass parent_class; - - void (* send) (EMsgComposer *composer); - void (* postpone) (EMsgComposer *composer); -}; - - -GtkType e_msg_composer_get_type (void); -void e_msg_composer_construct (EMsgComposer *composer); -GtkWidget *e_msg_composer_new (void); -void e_msg_composer_show_attachments (EMsgComposer *composer, gboolean show); -CamelMimeMessage *e_msg_composer_get_message (EMsgComposer *composer); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* ___E_MSG_COMPOSER_H__ */ diff --git a/widgets/e-table/ChangeLog b/widgets/e-table/ChangeLog index a2fa977553..01244d9674 100644 --- a/widgets/e-table/ChangeLog +++ b/widgets/e-table/ChangeLog @@ -1,3 +1,22 @@ +1999-11-17 Ettore Perazzoli + + * e-msg-composer-address-dialog.c: Moved to `$(srcdir)/composer'. + * e-msg-composer-address-dialog.h: Likewise. + * e-msg-composer-address-entry.c: Likewise. + * e-msg-composer-address-entry.h: Likewise. + * e-msg-composer-attachment-bar.c: Likewise. + * e-msg-composer-attachment-bar.h: Likewise. + * e-msg-composer-attachment.c: Likewise. + * e-msg-composer-attachment.h: Likewise. + * e-msg-composer-hdrs.c: Likewise. + * e-msg-composer-hdrs.h: Likewise. + * e-msg-composer.c: Likewise. + * e-msg-composer.h: Likewise. + * e-msg-composer-address-dialog.glade: Likewise. + * e-msg-composer-attachment.glade: Likewise. + * e-msg-composer.glade: Likewise. + * Makefile.am: Updated accordingly. + Nov 14 1999 Elliot Lee * Makefile.am: It's libevolutionwidgets.la, not .a diff --git a/widgets/e-table/Makefile.am b/widgets/e-table/Makefile.am index d7c28475d1..f4b3c111cd 100644 --- a/widgets/e-table/Makefile.am +++ b/widgets/e-table/Makefile.am @@ -1,36 +1,14 @@ -guidir = $(datadir)/evolution/gui - -gui_DATA = \ - e-msg-composer-address-dialog.glade \ - e-msg-composer-attachment.glade \ - e-msg-composer.glade - INCLUDES = \ -I$(top_srcdir)/camel \ -I$(top_builddir)/camel \ $(GNOME_INCLUDEDIR) -CPPFLAGS = \ - -DE_GUIDIR=\"$(guidir)\" - noinst_LIBRARIES = \ libevolutionwidgets.a libevolutionwidgets_a_SOURCES = \ e-cursors.c \ e-cursors.h \ - e-msg-composer-address-dialog.c \ - e-msg-composer-address-dialog.h \ - e-msg-composer-address-entry.c \ - e-msg-composer-address-entry.h \ - e-msg-composer-attachment-bar.c \ - e-msg-composer-attachment-bar.h \ - e-msg-composer-attachment.c \ - e-msg-composer-attachment.h \ - e-msg-composer-hdrs.c \ - e-msg-composer-hdrs.h \ - e-msg-composer.c \ - e-msg-composer.h \ e-table-col.c \ e-table-col.h \ e-table-group.c \ -- cgit v1.2.3