Reviewing Mailer's API
This commit is contained in:
parent
2c93657cc6
commit
3ea562e600
|
@ -59,6 +59,45 @@ typedef struct _AccountConfig
|
|||
} AccountConfig;
|
||||
|
||||
|
||||
/* AccountStatus */
|
||||
typedef enum _AccountStatus
|
||||
{
|
||||
AS_CONNECTING = 0,
|
||||
AS_CONNECTED,
|
||||
AS_DISCONNECTED,
|
||||
AS_AUTHENTICATED,
|
||||
AS_READY
|
||||
} AccountStatus;
|
||||
|
||||
|
||||
/* AccountEvent */
|
||||
typedef enum _AccountEventType
|
||||
{
|
||||
AET_ERROR = 0,
|
||||
AET_STATUS
|
||||
} AccountEventType;
|
||||
|
||||
typedef union _AccountEvent
|
||||
{
|
||||
AccountEventType type;
|
||||
|
||||
/* AET_ERROR */
|
||||
struct
|
||||
{
|
||||
AccountEventType type;
|
||||
char const * message;
|
||||
} error;
|
||||
|
||||
/* AET_STATUS */
|
||||
struct
|
||||
{
|
||||
AccountEventType type;
|
||||
AccountStatus status;
|
||||
char const * message;
|
||||
} status;
|
||||
} AccountEvent;
|
||||
|
||||
|
||||
/* AccountPlugin */
|
||||
typedef struct _AccountPluginHelper
|
||||
{
|
||||
|
@ -67,7 +106,7 @@ typedef struct _AccountPluginHelper
|
|||
SSL_CTX * (*get_ssl_context)(Account * account);
|
||||
/* useful */
|
||||
int (*error)(Account * account, char const * message, int ret);
|
||||
void (*status)(Account * account, char const * format, ...);
|
||||
void (*event)(Account * account, AccountEvent * event);
|
||||
/* authentication */
|
||||
char * (*authenticate)(Account * account, char const * message);
|
||||
int (*confirm)(Account * account, char const * message);
|
||||
|
|
|
@ -69,7 +69,7 @@ static SSL_CTX * _account_helper_get_ssl_context(Account * account);
|
|||
/* useful */
|
||||
static int _account_helper_error(Account * account, char const * message,
|
||||
int ret);
|
||||
static void _account_helper_status(Account * account, char const * format, ...);
|
||||
static void _account_helper_event(Account * account, AccountEvent * event);
|
||||
static char * _account_helper_authenticate(Account * account,
|
||||
char const * message);
|
||||
static int _account_helper_confirm(Account * account, char const * message);
|
||||
|
@ -90,7 +90,7 @@ static const AccountPluginHelper _account_plugin_helper =
|
|||
NULL,
|
||||
_account_helper_get_ssl_context,
|
||||
_account_helper_error,
|
||||
_account_helper_status,
|
||||
_account_helper_event,
|
||||
_account_helper_authenticate,
|
||||
_account_helper_confirm,
|
||||
_account_helper_folder_new,
|
||||
|
@ -187,7 +187,7 @@ void account_delete(Account * account)
|
|||
|
||||
/* accessors */
|
||||
/* account_get_config */
|
||||
AccountConfig * account_get_config(Account * account)
|
||||
AccountConfig const * account_get_config(Account * account)
|
||||
{
|
||||
if(account->account == NULL)
|
||||
return account->definition->config;
|
||||
|
@ -436,28 +436,20 @@ static int _account_helper_error(Account * account, char const * message,
|
|||
}
|
||||
|
||||
|
||||
/* account_helper_status */
|
||||
static void _account_helper_status(Account * account, char const * format, ...)
|
||||
/* account_helper_event */
|
||||
static void _account_helper_event(Account * account, AccountEvent * event)
|
||||
{
|
||||
va_list ap;
|
||||
int res;
|
||||
size_t size;
|
||||
char * p = NULL;
|
||||
Mailer * mailer = account->mailer;
|
||||
|
||||
va_start(ap, format);
|
||||
res = vsprintf(NULL, format, ap);
|
||||
va_end(ap);
|
||||
if(res >= 0)
|
||||
switch(event->type)
|
||||
{
|
||||
va_start(ap, format);
|
||||
size = res;
|
||||
if((p = malloc(++size)) != NULL)
|
||||
vsnprintf(p, size, format, ap);
|
||||
va_end(ap);
|
||||
case AET_ERROR:
|
||||
mailer_error(mailer, event->error.message, 1);
|
||||
break;
|
||||
case AET_STATUS:
|
||||
mailer_set_status(mailer, event->status.message);
|
||||
break;
|
||||
}
|
||||
if(p != NULL)
|
||||
mailer_set_status(account->mailer, p);
|
||||
free(p);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ void account_delete(Account * account);
|
|||
int account_get_enabled(Account * account);
|
||||
void account_set_enabled(Account * account, int enabled);
|
||||
|
||||
AccountConfig * account_get_config(Account * account);
|
||||
AccountConfig const * account_get_config(Account * account);
|
||||
char const * account_get_name(Account * account);
|
||||
char const * account_get_title(Account * account);
|
||||
char const * account_get_type(Account * account);
|
||||
|
|
|
@ -943,11 +943,13 @@ static gboolean _on_connect(gpointer data)
|
|||
{
|
||||
IMAP4 * imap4 = data;
|
||||
AccountPluginHelper * helper = imap4->helper;
|
||||
AccountEvent event;
|
||||
char const * hostname;
|
||||
char const * p;
|
||||
uint16_t port;
|
||||
struct sockaddr_in sa;
|
||||
int res;
|
||||
char buf[128];
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "DEBUG: %s()\n", __func__);
|
||||
|
@ -956,7 +958,7 @@ static gboolean _on_connect(gpointer data)
|
|||
/* get the hostname and port */
|
||||
if((hostname = imap4->config[I4CV_HOSTNAME].value) == NULL)
|
||||
{
|
||||
helper->error(NULL, "No hostname set", 1);
|
||||
helper->error(helper->account, "No hostname set", 1);
|
||||
return FALSE;
|
||||
}
|
||||
if((p = imap4->config[I4CV_PORT].value) == NULL)
|
||||
|
@ -978,9 +980,15 @@ static gboolean _on_connect(gpointer data)
|
|||
&& fcntl(imap4->fd, F_SETFL, res | O_NONBLOCK) == -1)
|
||||
/* ignore this error */
|
||||
helper->error(NULL, strerror(errno), 1);
|
||||
/* connect to the remote host */
|
||||
helper->status(helper->account, "Connecting to %s (%s:%u)", hostname,
|
||||
/* report the current status */
|
||||
memset(&event, 0, sizeof(event));
|
||||
event.status.type = AET_STATUS;
|
||||
event.status.status = AS_CONNECTING;
|
||||
snprintf(buf, sizeof(buf), "Connecting to %s (%s:%u)", hostname,
|
||||
inet_ntoa(sa.sin_addr), port);
|
||||
event.status.message = buf;
|
||||
helper->event(helper->account, &event);
|
||||
/* connect to the remote host */
|
||||
if((connect(imap4->fd, (struct sockaddr *)&sa, sizeof(sa)) != 0
|
||||
&& errno != EINPROGRESS)
|
||||
|| _connect_channel(imap4) != 0)
|
||||
|
@ -1050,6 +1058,7 @@ static gboolean _on_watch_can_connect(GIOChannel * source,
|
|||
{
|
||||
IMAP4 * imap4 = data;
|
||||
AccountPluginHelper * helper = imap4->helper;
|
||||
AccountEvent event;
|
||||
char const * hostname = imap4->config[I4CV_HOSTNAME].value;
|
||||
uint16_t port = (unsigned long)imap4->config[I4CV_PORT].value;
|
||||
struct sockaddr_in sa;
|
||||
|
@ -1063,8 +1072,16 @@ static gboolean _on_watch_can_connect(GIOChannel * source,
|
|||
#endif
|
||||
/* XXX remember the address instead */
|
||||
if(_imap4_lookup(imap4, hostname, port, &sa) == 0)
|
||||
helper->status(helper->account, "Connected to %s (%s:%u)",
|
||||
{
|
||||
/* report the current status */
|
||||
memset(&event, 0, sizeof(event));
|
||||
event.status.type = AET_STATUS;
|
||||
event.status.status = AS_CONNECTED;
|
||||
snprintf(buf, sizeof(buf), "Connected to %s (%s:%u)",
|
||||
hostname, inet_ntoa(sa.sin_addr), port);
|
||||
event.status.message = buf;
|
||||
helper->event(helper->account, &event);
|
||||
}
|
||||
imap4->wr_source = 0;
|
||||
/* setup SSL */
|
||||
if(imap4->config[I4CV_SSL].value != NULL)
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include <sys/socket.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
@ -155,7 +156,7 @@ static int _pop3_refresh(POP3 * pop3, AccountFolder * folder,
|
|||
/* useful */
|
||||
static POP3Command * _pop3_command(POP3 * pop3, POP3Context context,
|
||||
char const * command);
|
||||
static int _pop3_lookup(POP3 * pop3, char const * hostname, unsigned short port,
|
||||
static int _pop3_lookup(POP3 * pop3, char const * hostname, uint16_t port,
|
||||
struct sockaddr_in * sa);
|
||||
static int _pop3_parse(POP3 * pop3);
|
||||
static void _pop3_reset(POP3 * pop3);
|
||||
|
@ -316,7 +317,7 @@ static POP3Command * _pop3_command(POP3 * pop3, POP3Context context,
|
|||
|
||||
|
||||
/* pop3_lookup */
|
||||
static int _pop3_lookup(POP3 * pop3, char const * hostname, unsigned short port,
|
||||
static int _pop3_lookup(POP3 * pop3, char const * hostname, uint16_t port,
|
||||
struct sockaddr_in * sa)
|
||||
{
|
||||
struct hostent * he;
|
||||
|
@ -587,11 +588,13 @@ static gboolean _on_connect(gpointer data)
|
|||
{
|
||||
POP3 * pop3 = data;
|
||||
AccountPluginHelper * helper = pop3->helper;
|
||||
AccountEvent event;
|
||||
char const * hostname;
|
||||
char const * p;
|
||||
unsigned short port;
|
||||
uint16_t port;
|
||||
struct sockaddr_in sa;
|
||||
int res;
|
||||
char buf[128];
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "DEBUG: %s()\n", __func__);
|
||||
|
@ -612,6 +615,7 @@ static gboolean _on_connect(gpointer data)
|
|||
helper->error(NULL, error_get(), 1);
|
||||
return FALSE;
|
||||
}
|
||||
/* create the socket */
|
||||
if((pop3->fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
|
||||
{
|
||||
helper->error(NULL, strerror(errno), 1);
|
||||
|
@ -621,9 +625,15 @@ static gboolean _on_connect(gpointer data)
|
|||
&& fcntl(pop3->fd, F_SETFL, res | O_NONBLOCK) == -1)
|
||||
/* ignore this error */
|
||||
helper->error(NULL, strerror(errno), 1);
|
||||
/* connect to the remote host */
|
||||
helper->status(helper->account, "Connecting to %s (%s:%u)", hostname,
|
||||
/* report the current status */
|
||||
memset(&event, 0, sizeof(event));
|
||||
event.status.type = AET_STATUS;
|
||||
event.status.status = AS_CONNECTING;
|
||||
snprintf(buf, sizeof(buf), "Connecting to %s (%s:%u)", hostname,
|
||||
inet_ntoa(sa.sin_addr), port);
|
||||
event.status.message = buf;
|
||||
helper->event(helper->account, &event);
|
||||
/* connect to the remote host */
|
||||
if((connect(pop3->fd, (struct sockaddr *)&sa, sizeof(sa)) != 0
|
||||
&& errno != EINPROGRESS)
|
||||
|| _connect_channel(pop3) != 0)
|
||||
|
@ -691,8 +701,9 @@ static gboolean _on_watch_can_connect(GIOChannel * source,
|
|||
{
|
||||
POP3 * pop3 = data;
|
||||
AccountPluginHelper * helper = pop3->helper;
|
||||
AccountEvent event;
|
||||
char const * hostname = pop3->config[P3CV_HOSTNAME].value;
|
||||
unsigned short port = (unsigned long)pop3->config[P3CV_PORT].value;
|
||||
uint16_t port = (unsigned long)pop3->config[P3CV_PORT].value;
|
||||
struct sockaddr_in sa;
|
||||
SSL_CTX * ssl_ctx;
|
||||
char buf[128];
|
||||
|
@ -704,8 +715,16 @@ static gboolean _on_watch_can_connect(GIOChannel * source,
|
|||
#endif
|
||||
/* XXX remember the address instead */
|
||||
if(_pop3_lookup(pop3, hostname, port, &sa) == 0)
|
||||
helper->status(helper->account, "Connected to %s (%s:%u)",
|
||||
{
|
||||
/* report the current status */
|
||||
memset(&event, 0, sizeof(event));
|
||||
event.status.type = AET_STATUS;
|
||||
event.status.status = AS_CONNECTED;
|
||||
snprintf(buf, sizeof(buf), "Connected to %s (%s:%u)",
|
||||
hostname, inet_ntoa(sa.sin_addr), port);
|
||||
event.status.message = buf;
|
||||
helper->event(helper->account, &event);
|
||||
}
|
||||
pop3->wr_source = 0;
|
||||
/* setup SSL */
|
||||
if(pop3->config[P3CV_SSL].value != NULL)
|
||||
|
|
42
src/mailer.c
42
src/mailer.c
|
@ -92,6 +92,10 @@ struct _Mailer
|
|||
/* widgets */
|
||||
/* folders */
|
||||
GtkWidget * fo_window;
|
||||
#if GTK_CHECK_VERSION(2, 18, 0)
|
||||
GtkWidget * fo_infobar;
|
||||
GtkWidget * fo_infobar_label;
|
||||
#endif
|
||||
GtkTreeStore * fo_store;
|
||||
GtkWidget * fo_view;
|
||||
/* headers */
|
||||
|
@ -397,6 +401,25 @@ Mailer * mailer_new(void)
|
|||
/* toolbar */
|
||||
widget = desktop_toolbar_create(_mailer_fo_toolbar, mailer, group);
|
||||
gtk_box_pack_start(GTK_BOX(vbox), widget, FALSE, TRUE, 0);
|
||||
#if GTK_CHECK_VERSION(2, 18, 0)
|
||||
/* infobar */
|
||||
mailer->fo_infobar = gtk_info_bar_new_with_buttons(GTK_STOCK_CLOSE,
|
||||
GTK_RESPONSE_CLOSE, NULL);
|
||||
gtk_info_bar_set_message_type(GTK_INFO_BAR(mailer->fo_infobar),
|
||||
GTK_MESSAGE_ERROR);
|
||||
g_signal_connect(mailer->fo_infobar, "close", G_CALLBACK(
|
||||
gtk_widget_hide), NULL);
|
||||
g_signal_connect(mailer->fo_infobar, "response", G_CALLBACK(
|
||||
gtk_widget_hide), NULL);
|
||||
widget = gtk_info_bar_get_content_area(GTK_INFO_BAR(
|
||||
mailer->fo_infobar));
|
||||
mailer->fo_infobar_label = gtk_label_new(NULL);
|
||||
gtk_widget_show(mailer->fo_infobar_label);
|
||||
gtk_box_pack_start(GTK_BOX(widget), mailer->fo_infobar_label, TRUE,
|
||||
TRUE, 0);
|
||||
gtk_widget_set_no_show_all(mailer->fo_infobar, TRUE);
|
||||
gtk_box_pack_start(GTK_BOX(vbox), mailer->fo_infobar, FALSE, TRUE, 0);
|
||||
#endif
|
||||
/* folders */
|
||||
widget = gtk_scrolled_window_new(NULL, NULL);
|
||||
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(widget),
|
||||
|
@ -457,9 +480,9 @@ Mailer * mailer_new(void)
|
|||
mailer->bo_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_add_accel_group(GTK_WINDOW(mailer->bo_window), group);
|
||||
gtk_window_set_default_size(GTK_WINDOW(mailer->bo_window), 200, 300);
|
||||
#if GTK_CHECK_VERSION(2, 6, 0)
|
||||
# if GTK_CHECK_VERSION(2, 6, 0)
|
||||
gtk_window_set_icon_name(GTK_WINDOW(mailer->bo_window), "mailer");
|
||||
#endif
|
||||
# endif
|
||||
gtk_window_set_title(GTK_WINDOW(mailer->bo_window), _("Message"));
|
||||
g_signal_connect_swapped(G_OBJECT(mailer->bo_window), "delete-event",
|
||||
G_CALLBACK(on_body_closex), mailer);
|
||||
|
@ -992,17 +1015,25 @@ void mailer_set_status(Mailer * mailer, char const * status)
|
|||
/* mailer_error */
|
||||
int mailer_error(Mailer * mailer, char const * message, int ret)
|
||||
{
|
||||
#if !GTK_CHECK_VERSION(2, 18, 0)
|
||||
GtkWidget * dialog;
|
||||
#endif
|
||||
|
||||
if(mailer == NULL)
|
||||
return error_set_print("mailer", ret, "%s", message);
|
||||
#if GTK_CHECK_VERSION(2, 18, 0)
|
||||
/* info bar */
|
||||
gtk_label_set_text(GTK_LABEL(mailer->fo_infobar_label), message);
|
||||
gtk_widget_show(mailer->fo_infobar);
|
||||
#else
|
||||
/* dialog window */
|
||||
dialog = gtk_message_dialog_new(GTK_WINDOW(mailer->fo_window),
|
||||
GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||
GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
|
||||
#if GTK_CHECK_VERSION(2, 6, 0)
|
||||
# if GTK_CHECK_VERSION(2, 6, 0)
|
||||
"%s", _("Error"));
|
||||
gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),
|
||||
#endif
|
||||
# endif
|
||||
"%s", message);
|
||||
gtk_window_set_title(GTK_WINDOW(dialog), _("Error"));
|
||||
gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(
|
||||
|
@ -1010,6 +1041,7 @@ int mailer_error(Mailer * mailer, char const * message, int ret)
|
|||
g_signal_connect(G_OBJECT(dialog), "response", G_CALLBACK(
|
||||
gtk_widget_destroy), NULL);
|
||||
gtk_widget_show(dialog);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -2058,6 +2090,8 @@ static GtkWidget * _assistant_account_select(AccountData * ad)
|
|||
_on_account_name_changed), ad);
|
||||
gtk_box_pack_start(GTK_BOX(hbox), widget, TRUE, TRUE, 0);
|
||||
gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
|
||||
/* default identity */
|
||||
/* FIXME seems to not be remembered */
|
||||
hbox = gtk_hbox_new(FALSE, 4);
|
||||
_account_add_label(hbox, NULL, group, _("Your name"));
|
||||
widget = gtk_entry_new();
|
||||
|
|
Loading…
Reference in New Issue
Block a user