2007-04-24 Murray Cumming <murrayc@murrayc.com>
+ * src/dbus_api/modest-dbus-api.h:
+ * src/dbus_api/modest-dbus-callbacks.c:
+ Use an idle callback to execute the modest code in the application's own thread.
+ Remove the helloworld example method.
+ Handle mail-to and open-message D-Bus methods, though the mail-to format needs to be
+ parsed, and the open-message method is not implemented because this is not yet implemented in
+ modest itself.
+ * libmodest-dbus-client/libmodest-dbus-client.c:
+ (libmodest_dbus_client_send_mail), (libmodest_dbus_client_mail_to),
+ (libmodest_dbus_client_open_message):
+ * libmodest-dbus-client/libmodest-dbus-client.h: New functions for the new methods.
+
+ * src/modest-tny-msg.c: (modest_tny_msg_new), (add_body_part): Handle NULLs for subject and
+ body without crashing.
+
+ * tests/dbus_api/Makefile.am:
+ * tests/dbus_api/test_mail_to.c:
+ * tests/dbus_api/test_open_message.c: New tests for the new methods.
+
+2007-04-24 Murray Cumming <murrayc@murrayc.com>
+
* libmodest-dbus-client/libmodest-dbus-client-1.0.pc.in:
Added file to fix the build. Sorry.
#include "libmodest-dbus-client.h"
#include <dbus_api/modest-dbus-api.h> /* For the API strings. */
-
gboolean
-libmodest_dbus_client_call_helloworld(osso_context_t *osso_context)
+libmodest_dbus_client_send_mail (osso_context_t *osso_context, const gchar *to, const gchar *cc,
+ const gchar *bcc, const gchar* subject, const gchar* body, GSList *attachments)
{
osso_rpc_t retval;
const osso_return_t ret = osso_rpc_run_with_defaults(osso_context,
MODEST_DBUS_NAME,
- MODEST_DBUS_EXAMPLE_MESSAGE, &retval,
+ MODEST_DBUS_METHOD_SEND_MAIL, &retval,
+ DBUS_TYPE_STRING, to,
+ DBUS_TYPE_STRING, cc,
+ DBUS_TYPE_STRING, bcc,
+ DBUS_TYPE_STRING, subject,
+ DBUS_TYPE_STRING, body,
DBUS_TYPE_INVALID);
if (ret != OSSO_OK) {
return TRUE;
}
-
-gboolean
-libmodfest_dbus_client_send_mail (osso_context_t *osso_context, const gchar *to, const gchar *cc,
- const gchar *bcc, const gchar* subject, const gchar* body, GSList *attachments)
+
+gboolean
+libmodest_dbus_client_mail_to (osso_context_t *osso_context, const gchar *mailto_uri)
{
osso_rpc_t retval;
const osso_return_t ret = osso_rpc_run_with_defaults(osso_context,
MODEST_DBUS_NAME,
- MODEST_DBUS_METHOD_SEND_MAIL, &retval,
- DBUS_TYPE_STRING, to,
- DBUS_TYPE_STRING, cc,
- DBUS_TYPE_STRING, bcc,
- DBUS_TYPE_STRING, subject,
- DBUS_TYPE_STRING, body,
+ MODEST_DBUS_METHOD_MAIL_TO, &retval,
+ DBUS_TYPE_STRING, mailto_uri,
DBUS_TYPE_INVALID);
if (ret != OSSO_OK) {
return TRUE;
}
-
-gboolean
-libmodfest_dbus_client_mailto (osso_context_t *osso_context, const gchar *mailto_uri)
-{
- return FALSE;
-}
gboolean
-libmodfest_dbus_client_open_message (osso_context_t *osso_context, const gchar *mail_uri)
+libmodest_dbus_client_open_message (osso_context_t *osso_context, const gchar *mail_uri)
{
- return FALSE;
+ osso_rpc_t retval;
+ const osso_return_t ret = osso_rpc_run_with_defaults(osso_context,
+ MODEST_DBUS_NAME,
+ MODEST_DBUS_METHOD_OPEN_MESSAGE, &retval,
+ DBUS_TYPE_STRING, mail_uri,
+ DBUS_TYPE_INVALID);
+
+ if (ret != OSSO_OK) {
+ printf("debug: osso_rpc_run() failed.\n");
+ return FALSE;
+ } else {
+ printf("debug: osso_rpc_run() succeeded.\n");
+ }
+
+ osso_rpc_free_val(&retval);
+
+ return TRUE;
}
#include <stdio.h>
gboolean
-libmodest_dbus_client_call_helloworld (osso_context_t *osso_context);
-
-gboolean
-libmodfest_dbus_client_send_mail (osso_context_t *osso_context, const gchar *to, const gchar *cc,
+libmodest_dbus_client_send_mail (osso_context_t *osso_context, const gchar *to, const gchar *cc,
const gchar *bcc, const gchar* subject, const gchar* body, GSList *attachments);
gboolean
-libmodfest_dbus_client_mailto (osso_context_t *osso_context, const gchar *mailto_uri);
+libmodest_dbus_client_mail_to (osso_context_t *osso_context, const gchar *mailto_uri);
gboolean
-libmodfest_dbus_client_open_message (osso_context_t *osso_context, const gchar *mail_uri);
+libmodest_dbus_client_open_message (osso_context_t *osso_context, const gchar *mail_uri);
#endif /* __LIBMODEST_DBUS_CLIENT_H__ */
* are what is assumed by the, bizarrely named, osso_rpc_run_with_defaults() function,
* so they are probably a good choice. */
#define MODEST_DBUS_NAME "modestemail"
-#define MODEST_DBUS_EXAMPLE_SERVICE "com.nokia."MODEST_DBUS_NAME
-#define MODEST_DBUS_EXAMPLE_OBJECT "/com/nokia/"MODEST_DBUS_NAME
-#define MODEST_DBUS_EXAMPLE_IFACE "com.nokia."MODEST_DBUS_NAME
-
-#define MODEST_DBUS_EXAMPLE_MESSAGE "HelloWorld"
+#define MODEST_DBUS_SERVICE "com.nokia."MODEST_DBUS_NAME
+#define MODEST_DBUS_OBJECT "/com/nokia/"MODEST_DBUS_NAME
+#define MODEST_DBUS_IFACE "com.nokia."MODEST_DBUS_NAME
#define MODEST_DBUS_METHOD_SEND_MAIL "SendMail"
enum ModestDbusSendMailArguments
MODEST_DEBUS_SEND_MAIL_ARGS_COUNT
};
+#define MODEST_DBUS_METHOD_MAIL_TO "MailTo"
+enum ModestDbusMailToArguments
+{
+ MODEST_DEBUS_MAIL_TO_ARG_URI,
+ MODEST_DEBUS_MAIL_TO_ARGS_COUNT
+};
+
+#define MODEST_DBUS_METHOD_OPEN_MESSAGE "OpenMessage"
+enum ModestDbusOpenMessageArguments
+{
+ MODEST_DEBUS_OPEN_MESSAGE_ARG_URI,
+ MODEST_DEBUS_OPEN_MESSAGE_ARGS_COUNT
+};
+
#endif /* __MODEST_DBUS_API__ */
#include "modest-runtime.h"
#include "modest-account-mgr.h"
#include "modest-account-mgr-helpers.h"
+#include "modest-tny-account.h"
+#include "widgets/modest-msg-edit-window.h"
+#include "modest-tny-msg.h"
#include <stdio.h>
-/* Callback for normal D-BUS messages */
+typedef struct
+{
+ gchar *to;
+ gchar *cc;
+ gchar *bcc;
+ gchar *subject;
+ gchar *body;
+} SendMailIdleData;
+
+static gboolean
+on_idle_send_mail(gpointer user_data)
+{
+ SendMailIdleData *idle_data = (SendMailIdleData*)user_data;
+
+ /* Get the TnyTransportAccount so we can instantiate a mail operation: */
+ ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
+ gchar *account_name = modest_account_mgr_get_default_account (account_mgr);
+ if (!account_name) {
+ g_printerr ("modest: no account found\n");
+ }
+
+ TnyTransportAccount *transport_account = NULL;
+ if (account_mgr) {
+ transport_account = TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_tny_account_by_account
+ (modest_runtime_get_account_store(),
+ account_name,
+ TNY_ACCOUNT_TYPE_TRANSPORT));
+ }
+
+ if (!transport_account) {
+ g_printerr ("modest: no transport account found for '%s'\n", account_name);
+ }
+
+ /* Create the mail operation: */
+ if (transport_account) {
+ /* Use the mail operation: */
+ gchar * from = modest_account_mgr_get_from_string (account_mgr,
+ account_name);
+ if (!from) {
+ g_printerr ("modest: no from address for account '%s'\n", account_name);
+ } else {
+ ModestMailOperation *mail_operation = modest_mail_operation_new ();
+ modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
+
+ modest_mail_operation_send_new_mail (mail_operation,
+ transport_account,
+ from, /* from */
+ idle_data->to, idle_data->cc, idle_data->bcc, idle_data->subject,
+ idle_data->body, /* plain_body */
+ NULL, /* html_body */
+ NULL, /* attachments_list, GSList of TnyMimePart. */
+ (TnyHeaderFlags)0);
+
+ g_free (from);
+ g_object_unref (G_OBJECT (mail_operation));
+ }
+
+ g_object_unref (G_OBJECT (transport_account));
+ }
+
+ g_free (account_name);
+
+ /* Free the idle data: */
+ g_free (idle_data->to);
+ g_free (idle_data->cc);
+ g_free (idle_data->bcc);
+ g_free (idle_data->subject);
+ g_free (idle_data->body);
+ g_free (idle_data);
+
+ return FALSE; /* Do not call this callback again. */
+}
+
static gint on_send_mail(GArray * arguments, gpointer data, osso_rpc_t * retval)
{
if (arguments->len != MODEST_DEBUS_SEND_MAIL_ARGS_COUNT)
return OSSO_ERROR;
+ /* Use g_idle to context-switch into the application's thread: */
+ SendMailIdleData *idle_data = g_new0(SendMailIdleData, 1); /* Freed in the idle callback. */
+
/* Get the arguments: */
osso_rpc_t val = g_array_index(arguments, osso_rpc_t, MODEST_DEBUS_SEND_MAIL_ARG_TO);
- gchar *to = val.value.s;
+ idle_data->to = g_strdup (val.value.s);
val = g_array_index(arguments, osso_rpc_t, MODEST_DEBUS_SEND_MAIL_ARG_CC);
- gchar *cc = val.value.s;
+ idle_data->cc = g_strdup (val.value.s);
val = g_array_index(arguments, osso_rpc_t, MODEST_DEBUS_SEND_MAIL_ARG_BCC);
- gchar *bcc = val.value.s;
+ idle_data->bcc = g_strdup (val.value.s);
val = g_array_index(arguments, osso_rpc_t, MODEST_DEBUS_SEND_MAIL_ARG_SUBJECT);
- gchar *subject = val.value.s;
+ idle_data->subject = g_strdup (val.value.s);
val = g_array_index(arguments, osso_rpc_t, MODEST_DEBUS_SEND_MAIL_ARG_BODY);
- gchar *body = val.value.s;
+ idle_data->body = g_strdup (val.value.s);
- printf(" debug: to=%s\n", to);
+ /* printf(" debug: to=%s\n", idle_data->to); */
+ g_idle_add(on_idle_send_mail, (gpointer)idle_data);
- /* Get the TnyTransportAccount so we can instantiate a mail operation: */
+ /* Note that we cannot report failures during sending,
+ * because that would be asynchronous. */
+ return OSSO_OK;
+}
+
+
+static gboolean
+on_idle_mail_to(gpointer user_data)
+{
+ /* This is based on the implemenation of main.c:start_uil(): */
+
+ gchar *uri = (gchar*)user_data;
+
+ /* Get the TnyTransportAccount so we can instantiate a mail operation: */
ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
gchar *account_name = modest_account_mgr_get_default_account (account_mgr);
if (!account_name) {
g_printerr ("modest: no account found\n");
- return OSSO_ERROR;
}
- TnyTransportAccount *transport_account =
- TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_tny_account_by_account
- (modest_runtime_get_account_store(),
- account_name,
- TNY_ACCOUNT_TYPE_TRANSPORT));
- if (!transport_account) {
- g_printerr ("modest: no transport account found for '%s'\n", account_name);
- g_free (account_name);
- return OSSO_ERROR;
+ TnyAccount *account = NULL;
+ if (account_mgr) {
+ account = modest_tny_account_store_get_tny_account_by_account (
+ modest_runtime_get_account_store(), account_name,
+ TNY_ACCOUNT_TYPE_TRANSPORT);
}
- /* Create the mail operation: */
- ModestMailOperation *mail_operation = modest_mail_operation_new ();
- modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
+ if (!account) {
+ g_printerr ("modest: failed to get tny account folder'\n", account_name);
+ } else {
+ gchar * from = modest_account_mgr_get_from_string (account_mgr,
+ account_name);
+ if (!from) {
+ g_printerr ("modest: no from address for account '%s'\n", account_name);
+ } else {
+ TnyMsg *msg = modest_tny_msg_new (uri /* mailto */, from,
+ NULL /* cc */, NULL /* bcc */,
+ NULL /* subject */, NULL /* body */, NULL /* attachments */);
+ if (!msg) {
+ g_printerr ("modest: failed to create message\n");
+ } else
+ {
+ TnyFolder *folder = modest_tny_account_get_special_folder (account,
+ TNY_FOLDER_TYPE_DRAFTS);
+ if (!folder) {
+ g_printerr ("modest: failed to find Drafts folder\n");
+ } else {
+
+ tny_folder_add_msg (folder, msg, NULL); /* TODO: check err */
+
+ ModestWindow *win = modest_msg_edit_window_new (msg, account_name);
+ gtk_widget_show_all (GTK_WIDGET (win));
+
+ g_object_unref (G_OBJECT(folder));
+ }
+
+ g_object_unref (G_OBJECT(msg));
+ }
+ g_object_unref (G_OBJECT(account));
+
+ }
+ }
+
+ g_free (account_name);
+
+ g_free(uri);
+ return FALSE; /* Do not call this callback again. */
+}
+
+static gint on_mail_to(GArray * arguments, gpointer data, osso_rpc_t * retval)
+{
+ if (arguments->len != MODEST_DEBUS_MAIL_TO_ARGS_COUNT)
+ return OSSO_ERROR;
+
+ /* Use g_idle to context-switch into the application's thread: */
+
+ /* Get the arguments: */
+ osso_rpc_t val = g_array_index(arguments, osso_rpc_t, MODEST_DEBUS_MAIL_TO_ARG_URI);
+ gchar *uri = g_strdup (val.value.s);
+
+ /* printf(" debug: to=%s\n", idle_data->to); */
+ g_idle_add(on_idle_mail_to, (gpointer)uri);
+
+ /* Note that we cannot report failures during sending,
+ * because that would be asynchronous. */
+ return OSSO_OK;
+}
+
+
+static gboolean
+on_idle_open_message(gpointer user_data)
+{
+ gchar *uri = (gchar*)user_data;
+
+ g_message ("not implemented yet %s", __FUNCTION__);
- /* Use the mail operation: */
- gchar * from = modest_account_mgr_get_from_string (account_mgr,
- account_name);
- modest_mail_operation_send_new_mail (mail_operation,
- transport_account,
- from, /* from */
- to, cc, bcc, subject,
- body, /* plain_body */
- NULL, /* html_body */
- NULL, /* attachments_list, GSList of TnyMimePart. */
- (TnyHeaderFlags)0);
-
- g_object_unref (G_OBJECT (transport_account));
- g_object_unref (G_OBJECT (mail_operation));
- g_free (from);
- g_free (account_name);
+ g_free(uri);
+ return FALSE; /* Do not call this callback again. */
+}
+
+static gint on_open_message(GArray * arguments, gpointer data, osso_rpc_t * retval)
+{
+ if (arguments->len != MODEST_DEBUS_OPEN_MESSAGE_ARGS_COUNT)
+ return OSSO_ERROR;
+
+ /* Use g_idle to context-switch into the application's thread: */
+
+ /* Get the arguments: */
+ osso_rpc_t val = g_array_index(arguments, osso_rpc_t, MODEST_DEBUS_OPEN_MESSAGE_ARG_URI);
+ gchar *uri = g_strdup (val.value.s);
+
+ /* printf(" debug: to=%s\n", idle_data->to); */
+ g_idle_add(on_idle_open_message, (gpointer)uri);
+
+ /* Note that we cannot report failures during sending,
+ * because that would be asynchronous. */
+ return OSSO_OK;
}
/* Callback for normal D-BUS messages */
GArray * arguments, gpointer data,
osso_rpc_t * retval)
{
+ /*
printf("debug: modest_dbus_req_handler()\n");
printf("debug: method received: %s\n", method);
-
- if (g_ascii_strcasecmp(method, MODEST_DBUS_EXAMPLE_MESSAGE) == 0) {
-
- } else if (g_ascii_strcasecmp(method, MODEST_DBUS_METHOD_SEND_MAIL) == 0) {
- return on_send_mail (arguments, data, retval);
- }
-
- return OSSO_OK;
+ */
+ if (g_ascii_strcasecmp(method, MODEST_DBUS_METHOD_SEND_MAIL) == 0) {
+ return on_send_mail (arguments, data, retval);
+ } else if (g_ascii_strcasecmp(method, MODEST_DBUS_METHOD_MAIL_TO) == 0) {
+ return on_mail_to (arguments, data, retval);
+ } else if (g_ascii_strcasecmp(method, MODEST_DBUS_METHOD_OPEN_MESSAGE) == 0) {
+ return on_open_message (arguments, data, retval);
+ }
+ else
+ return OSSO_ERROR;
}
/* Register our D-Bus callbacks, via the osso API: */
osso_return_t result = osso_rpc_set_cb_f(osso_context,
- MODEST_DBUS_EXAMPLE_SERVICE,
- MODEST_DBUS_EXAMPLE_OBJECT,
- MODEST_DBUS_EXAMPLE_IFACE,
+ MODEST_DBUS_SERVICE,
+ MODEST_DBUS_OBJECT,
+ MODEST_DBUS_IFACE,
modest_dbus_req_handler, NULL /* user_data */);
if (result != OSSO_OK) {
g_print("Error setting D-BUS callback (%d)\n", result);
tny_header_set_to (TNY_HEADER (header), mailto);
tny_header_set_cc (TNY_HEADER (header), cc);
tny_header_set_bcc (TNY_HEADER (header), bcc);
- tny_header_set_subject (TNY_HEADER (header), subject);
+
+ if (subject)
+ tny_header_set_subject (TNY_HEADER (header), subject);
content_type = get_content_type(body);
- /* Add the body of the new mail */
+ /* Add the body of the new mail */
+ /* This is needed even if body is NULL or empty. */
add_body_part (new_msg, body, content_type, (attachments ? TRUE: FALSE));
g_free (content_type);
/* Add attachments */
- add_attachments (new_msg, (GList*) attachments);
+ if (attachments)
+ add_attachments (new_msg, (GList*) attachments);
return new_msg;
}
/* Create the stream */
text_body_stream = TNY_STREAM (tny_camel_stream_new
(camel_stream_mem_new_with_buffer
- (body, strlen(body))));
+ (body, (body ? strlen(body) : 0))));
/* Create body part if needed */
if (has_attachments)
$(MODEST_LIBTINYMAIL_MAEMO_LIBS) \
${top_srcdir}/libmodest-dbus-client/libmodest-dbus-client-1.0.la
-noinst_PROGRAMS = test_hello test_send_mail
-
-test_hello_SOURCES = test_hello.c
-test_hello_LDADD = $(objects)
+noinst_PROGRAMS = test_send_mail test_mail_to test_open_message
test_send_mail_SOURCES = test_send_mail.c
test_send_mail_LDADD = $(objects)
+test_mail_to_SOURCES = test_mail_to.c
+test_mail_to_LDADD = $(objects)
+
+test_open_message_SOURCES = test_open_message.c
+test_open_message_LDADD = $(objects)
+
+++ /dev/null
-#include <libmodest-dbus-client/libmodest-dbus-client.h>
-#include <stdio.h>
-
-int main(int argc, char *argv[])
-{
- /* Initialize maemo application */
- osso_context_t * osso_context = osso_initialize(
- "test_hello", "0.0.1", TRUE, NULL);
-
- /* Check that initialization was ok */
- if (osso_context == NULL)
- {
- printf("osso_initialize() failed.\n");
- return OSSO_ERROR;
- }
-
- /* Call the function in libmodest-dbus-client: */
- const gboolean ret = libmodest_dbus_client_call_helloworld (osso_context);
- if (!ret) {
- printf("libmodest_dbus_client_call_helloworld() failed.\n");
- return OSSO_ERROR;
- } else {
- printf("libmodest_dbus_client_call_helloworld() succeeded.\n");
- }
-
- /* Exit */
- return 0;
-}
--- /dev/null
+#include <libmodest-dbus-client/libmodest-dbus-client.h>
+#include <stdio.h>
+
+int main(int argc, char *argv[])
+{
+ /* Initialize maemo application */
+ osso_context_t * osso_context = osso_initialize(
+ "test_hello", "0.0.1", TRUE, NULL);
+
+ /* Check that initialization was ok */
+ if (osso_context == NULL)
+ {
+ printf("osso_initialize() failed.\n");
+ return OSSO_ERROR;
+ }
+
+ /* Call the function in libmodest-dbus-client: */
+ const gboolean ret = libmodest_dbus_client_mail_to (osso_context,
+ "mailto://murrayc@murrayc.com");
+ if (!ret) {
+ printf("libmodest_dbus_client_mail_to() failed.\n");
+ return OSSO_ERROR;
+ } else {
+ printf("libmodest_dbus_client_mail_to() succeeded.\n");
+ }
+
+ /* Exit */
+ return 0;
+}
--- /dev/null
+#include <libmodest-dbus-client/libmodest-dbus-client.h>
+#include <stdio.h>
+
+int main(int argc, char *argv[])
+{
+ /* Initialize maemo application */
+ osso_context_t * osso_context = osso_initialize(
+ "test_hello", "0.0.1", TRUE, NULL);
+
+ /* Check that initialization was ok */
+ if (osso_context == NULL)
+ {
+ printf("osso_initialize() failed.\n");
+ return OSSO_ERROR;
+ }
+
+ /* Call the function in libmodest-dbus-client: */
+ /* TODO: The Message URI system is not yet implemented. */
+ const gboolean ret = libmodest_dbus_client_open_message (osso_context,
+ "http://todo_some_message_uri");
+ if (!ret) {
+ printf("libmodest_dbus_client_open_message() failed.\n");
+ return OSSO_ERROR;
+ } else {
+ printf("libmodest_dbus_client_open_message() succeeded.\n");
+ }
+
+ /* Exit */
+ return 0;
+}
}
/* Call the function in libmodest-dbus-client: */
- const gboolean ret = libmodfest_dbus_client_send_mail (osso_context,
+ const gboolean ret = libmodest_dbus_client_send_mail (osso_context,
"murrayc@murrayc.com", /* to */
NULL, /* cc */
NULL, /* bcc */