From: Dirk-Jan C. Binnema Date: Fri, 21 Jul 2006 16:19:19 +0000 (+0000) Subject: * implement status bar messages X-Git-Tag: git_migration_finished~4469 X-Git-Url: http://git.maemo.org/git/?p=modest;a=commitdiff_plain;h=863ef6ddca26d35008666611cb12b8266c8c305f * implement status bar messages pmo-trunk-r407 --- diff --git a/src/modest-widget-factory.c b/src/modest-widget-factory.c index e15b913..35bbafe 100644 --- a/src/modest-widget-factory.c +++ b/src/modest-widget-factory.c @@ -35,10 +35,21 @@ static void modest_widget_factory_class_init (ModestWidgetFactoryClass *klass static void modest_widget_factory_init (ModestWidgetFactory *obj); static void modest_widget_factory_finalize (GObject *obj); -static void on_folder_clicked (ModestFolderView *folder_view, TnyMsgFolderIface *folder, - ModestWidgetFactory *self); -static void on_message_selected (ModestFolderView *folder_view, TnyMsgIface *msg, - ModestWidgetFactory *self); + +/* callbacks */ +static void on_folder_selected (ModestFolderView *folder_view, + TnyMsgFolderIface *folder, + ModestWidgetFactory *self); +static void on_message_selected (ModestHeaderView *header_view, TnyMsgIface *msg, + ModestWidgetFactory *self); +static void on_header_status_update (ModestHeaderView *header_view, const gchar *msg, + gint status_id, ModestWidgetFactory *self); +static void on_msg_link_hover (ModestMsgView *msgview, const gchar* link, + ModestWidgetFactory *self); +static void on_msg_link_clicked (ModestMsgView *msgview, const gchar* link, + ModestWidgetFactory *self); +static void on_msg_attachment_clicked (ModestMsgView *msgview, int index, + ModestWidgetFactory *self); /* list my signals */ enum { @@ -47,6 +58,16 @@ enum { LAST_SIGNAL }; + +enum _StatusID { + STATUS_ID_HEADER, + STATUS_ID_FOLDER, + STATUS_ID_MESSAGE, + + STATUS_ID_NUM +}; +typedef enum _StatusID StatusID; + typedef struct _ModestWidgetFactoryPrivate ModestWidgetFactoryPrivate; struct _ModestWidgetFactoryPrivate { @@ -54,12 +75,17 @@ struct _ModestWidgetFactoryPrivate { ModestAccountMgr *account_mgr; ModestConf *conf; - ModestHeaderView *header_view; - ModestFolderView *folder_view; - ModestMsgView *msg_preview; - ModestAccountView *account_view; + ModestHeaderView *header_view; + ModestFolderView *folder_view; + ModestMsgView *msg_preview; + + GtkWidget *progress_bar; + GtkWidget *status_bar; + + gboolean auto_connect; - gboolean auto_connect; + StatusID status_bar_ctx[STATUS_ID_NUM]; + }; #define MODEST_WIDGET_FACTORY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \ MODEST_TYPE_WIDGET_FACTORY, \ @@ -121,6 +147,23 @@ modest_widget_factory_init (ModestWidgetFactory *obj) priv->conf = NULL; priv->account_mgr = NULL; priv->account_store = NULL; + + priv->progress_bar = gtk_progress_bar_new (); + gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR(priv->progress_bar), + 1.0); + priv->status_bar = gtk_statusbar_new (); + gtk_statusbar_set_has_resize_grip (GTK_STATUSBAR(priv->status_bar), + FALSE); + + priv->status_bar_ctx[STATUS_ID_HEADER] = + gtk_statusbar_get_context_id (GTK_STATUSBAR(priv->status_bar), + "header"); + priv->status_bar_ctx[STATUS_ID_MESSAGE] = + gtk_statusbar_get_context_id (GTK_STATUSBAR(priv->status_bar), + "message"); + priv->status_bar_ctx[STATUS_ID_FOLDER] = + gtk_statusbar_get_context_id (GTK_STATUSBAR(priv->status_bar), + "folder"); } static void @@ -145,6 +188,54 @@ modest_widget_factory_finalize (GObject *obj) } } + +static gboolean +init_widgets (ModestWidgetFactory *self) +{ + ModestWidgetFactoryPrivate *priv; + priv = MODEST_WIDGET_FACTORY_GET_PRIVATE(self); + + /* folder view */ + if (!(priv->folder_view = + MODEST_FOLDER_VIEW(modest_folder_view_new + (TNY_ACCOUNT_STORE_IFACE(priv->account_store))))) { + g_printerr ("modest: cannot instantiate folder view\n"); + return FALSE; + } + + /* header view */ + if (!(priv->header_view = + MODEST_HEADER_VIEW(modest_header_view_new + (NULL, NULL,MODEST_HEADER_VIEW_STYLE_NORMAL)))) { + g_printerr ("modest: cannot instantiate header view\n"); + return FALSE; + } + + /* msg preview */ + if (!(priv->msg_preview = MODEST_MSG_VIEW(modest_msg_view_new (NULL)))) { + g_printerr ("modest: cannot instantiate header view\n"); + return FALSE; + } + + if (priv->auto_connect) { + g_signal_connect (G_OBJECT(priv->header_view), "message_selected", + G_CALLBACK(on_message_selected), self); + g_signal_connect (G_OBJECT(priv->folder_view), "folder_selected", + G_CALLBACK(on_folder_selected), self); + g_signal_connect (G_OBJECT(priv->header_view), "status_update", + G_CALLBACK(on_header_status_update), self); + g_signal_connect (G_OBJECT(priv->msg_preview), "link_clicked", + G_CALLBACK(on_msg_link_clicked), self); + g_signal_connect (G_OBJECT(priv->msg_preview), "link_hover", + G_CALLBACK(on_msg_link_hover), self); + g_signal_connect (G_OBJECT(priv->msg_preview), "attachment_clicked", + G_CALLBACK(on_msg_attachment_clicked), self); + } + + return TRUE; +} + + ModestWidgetFactory* modest_widget_factory_new (ModestConf *conf, ModestTnyAccountStore *account_store, @@ -171,6 +262,12 @@ modest_widget_factory_new (ModestConf *conf, g_object_ref (G_OBJECT(account_store)); priv->account_store = account_store; + + if (!init_widgets (MODEST_WIDGET_FACTORY(obj))) { + g_printerr ("modest: widget factory failed to init widgets\n"); + g_object_unref (obj); + return NULL; + } return MODEST_WIDGET_FACTORY(obj); } @@ -181,76 +278,58 @@ modest_widget_factory_new (ModestConf *conf, ModestFolderView* modest_widget_factory_get_folder_view (ModestWidgetFactory *self) { - ModestWidgetFactoryPrivate *priv; - g_return_val_if_fail (self, NULL); - - priv = MODEST_WIDGET_FACTORY_GET_PRIVATE(self); - - if (!priv->folder_view) { - priv->folder_view = - MODEST_FOLDER_VIEW(modest_folder_view_new - (TNY_ACCOUNT_STORE_IFACE(priv->account_store))); - if (priv->folder_view && priv->auto_connect) - g_signal_connect (G_OBJECT(priv->folder_view), "folder_selected", - G_CALLBACK(on_folder_clicked), self); - } - - if (!priv->folder_view) - g_printerr ("modest: cannot instantiate folder view\n"); - - return priv->folder_view; + return MODEST_WIDGET_FACTORY_GET_PRIVATE(self)->folder_view; } ModestHeaderView* modest_widget_factory_get_header_view (ModestWidgetFactory *self) { - ModestWidgetFactoryPrivate *priv; - g_return_val_if_fail (self, NULL); - - priv = MODEST_WIDGET_FACTORY_GET_PRIVATE(self); - - if (!priv->header_view) { - priv->header_view = - MODEST_HEADER_VIEW(modest_header_view_new - (NULL, NULL, - MODEST_HEADER_VIEW_STYLE_NORMAL)); - if (priv->header_view && priv->auto_connect) - g_signal_connect (G_OBJECT(priv->header_view), "message_selected", - G_CALLBACK(on_message_selected), self); - } - - if (!priv->header_view) - g_printerr ("modest: cannot instantiate header view\n"); - - return priv->header_view; + return MODEST_WIDGET_FACTORY_GET_PRIVATE(self)->header_view; } ModestMsgView* modest_widget_factory_get_msg_preview (ModestWidgetFactory *self) { + g_return_val_if_fail (self, NULL); + return MODEST_WIDGET_FACTORY_GET_PRIVATE(self)->msg_preview; +} + + +ModestAccountView* +modest_widget_factory_get_account_view (ModestWidgetFactory *self) +{ ModestWidgetFactoryPrivate *priv; g_return_val_if_fail (self, NULL); - priv = MODEST_WIDGET_FACTORY_GET_PRIVATE(self); + return modest_account_view_new (priv->account_mgr); +} - if (!priv->msg_preview) - priv->msg_preview = MODEST_MSG_VIEW(modest_msg_view_new (NULL)); - - if (!priv->msg_preview) - g_printerr ("modest: cannot instantiate header view\n"); - - return priv->msg_preview; + + +GtkWidget* +modest_widget_factory_get_progress_bar (ModestWidgetFactory *self) +{ + g_return_val_if_fail (self, NULL); + return MODEST_WIDGET_FACTORY_GET_PRIVATE(self)->progress_bar; +} + + +GtkWidget* +modest_widget_factory_get_status_bar (ModestWidgetFactory *self) +{ + g_return_val_if_fail (self, NULL); + return MODEST_WIDGET_FACTORY_GET_PRIVATE(self)->status_bar; } static void -on_folder_clicked (ModestFolderView *folder_view, TnyMsgFolderIface *folder, - ModestWidgetFactory *self) +on_folder_selected (ModestFolderView *folder_view, TnyMsgFolderIface *folder, + ModestWidgetFactory *self) { ModestWidgetFactoryPrivate *priv; priv = MODEST_WIDGET_FACTORY_GET_PRIVATE(self); @@ -260,31 +339,83 @@ on_folder_clicked (ModestFolderView *folder_view, TnyMsgFolderIface *folder, static void -on_message_selected (ModestFolderView *folder_view, TnyMsgIface *msg, +on_message_selected (ModestHeaderView *folder_view, TnyMsgIface *msg, ModestWidgetFactory *self) { ModestWidgetFactoryPrivate *priv; priv = MODEST_WIDGET_FACTORY_GET_PRIVATE(self); - + modest_msg_view_set_message (priv->msg_preview, msg); } -ModestAccountView* -modest_widget_factory_get_account_view (ModestWidgetFactory *self) +static void +on_header_status_update (ModestHeaderView *header_view, const gchar *msg, + gint status_id, ModestWidgetFactory *self) { ModestWidgetFactoryPrivate *priv; + priv = MODEST_WIDGET_FACTORY_GET_PRIVATE(self); - g_return_val_if_fail (self, NULL); + if (msg && status_id) { + gchar *msg = g_strdup_printf ("%s", msg); + gtk_progress_bar_pulse (GTK_PROGRESS_BAR(priv->progress_bar)); + gtk_statusbar_push (GTK_STATUSBAR(priv->status_bar), + priv->status_bar_ctx[STATUS_ID_HEADER], + msg); + g_free (msg); + } else { + gtk_statusbar_pop (GTK_STATUSBAR(priv->status_bar), + priv->status_bar_ctx[STATUS_ID_HEADER]); + gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR(priv->progress_bar), + 1.0); + } +} + +static void +on_msg_link_hover (ModestMsgView *msgview, const gchar* link, + ModestWidgetFactory *self) +{ + ModestWidgetFactoryPrivate *priv; priv = MODEST_WIDGET_FACTORY_GET_PRIVATE(self); - if (!priv->account_view) - priv->account_view = - MODEST_ACCOUNT_VIEW(modest_account_view_new (priv->account_mgr)); + if (link) + gtk_statusbar_push (GTK_STATUSBAR(priv->status_bar), + priv->status_bar_ctx[STATUS_ID_MESSAGE], + link); + else + gtk_statusbar_pop (GTK_STATUSBAR(priv->status_bar), + priv->status_bar_ctx[STATUS_ID_MESSAGE]); + +} - if (!priv->account_view) - g_printerr ("modest: cannot create account view widget\n"); - return priv->account_view; +static void +on_msg_link_clicked (ModestMsgView *msgview, const gchar* link, + ModestWidgetFactory *self) +{ + ModestWidgetFactoryPrivate *priv; + priv = MODEST_WIDGET_FACTORY_GET_PRIVATE(self); + + if (link) { + gchar *msg = g_strdup_printf (_("Opening %s..."), link); + gtk_statusbar_push (GTK_STATUSBAR(priv->status_bar), + priv->status_bar_ctx[STATUS_ID_MESSAGE], + msg); + g_free (msg); + } +} + +static void +on_msg_attachment_clicked (ModestMsgView *msgview, int index, + ModestWidgetFactory *self) +{ + ModestWidgetFactoryPrivate *priv; + priv = MODEST_WIDGET_FACTORY_GET_PRIVATE(self); + + gchar *msg = g_strdup_printf (_("Opening attachment %d..."), index); + gtk_statusbar_push (GTK_STATUSBAR(priv->status_bar), + priv->status_bar_ctx[STATUS_ID_MESSAGE], + msg); + g_free (msg); } diff --git a/src/modest-widget-factory.h b/src/modest-widget-factory.h index a8a72b3..ffaa1dc 100644 --- a/src/modest-widget-factory.h +++ b/src/modest-widget-factory.h @@ -145,6 +145,43 @@ ModestMsgView* modest_widget_factory_get_msg_preview (ModestWidgetFact ModestAccountView* modest_widget_factory_get_account_view (ModestWidgetFactory *self); +/** + * modest_widget_factory_get_progress_bar + * @self: a ModestWidgetFactory instance + * + * return an progress bar widget + * if the widget factory was created with 'auto_connect', then this progress bar + * will automatically update for changes in the other widgets + * NOTE the naming inconsistency: GtkProgressBar vs GtkStatusbar + * + * This factory will always return the + * same widget, and takes care of its lifetime - users should *not* destroy it. + * + * Returns: the progress bar widget + */ +GtkWidget* modest_widget_factory_get_progress_bar (ModestWidgetFactory *self); + + + +/** + * modest_widget_factory_get_status_bar + * @self: a ModestWidgetFactory instance + * + * return an status bar widget + * if the widget factory was created with 'auto_connect', then this status bar + * will automatically update for changes in the other widgets + * NOTE the naming inconsistency: GtkProgressBar vs GtkStatusbar + * + * This factory will always return the + * same widget, and takes care of its lifetime - users should *not* destroy it. + * + * Returns: the status bar widget + */ +GtkWidget* modest_widget_factory_get_status_bar (ModestWidgetFactory *self); + + + + G_END_DECLS #endif /* __MODEST_WIDGET_FACTORY_H__ */ diff --git a/src/widgets/modest-msg-view.c b/src/widgets/modest-msg-view.c index 5a16918..dcdcba5 100644 --- a/src/widgets/modest-msg-view.c +++ b/src/widgets/modest-msg-view.c @@ -54,6 +54,8 @@ static gboolean on_link_clicked (GtkWidget *widget, const gchar *uri, static gboolean on_url_requested (GtkWidget *widget, const gchar *uri, GtkHTMLStream *stream, ModestMsgView *msg_view); +static gboolean on_link_hover (GtkWidget *widget, const gchar *uri, + ModestMsgView *msg_view); /* * we need these regexps to find URLs in plain text e-mails @@ -69,7 +71,7 @@ struct _UrlMatchPattern { #define ATT_PREFIX "att:" #define MAIL_VIEWER_URL_MATCH_PATTERNS { \ - { "(file|http|ftp|https)://[-A-Za-z0-9_$.+!*(),;:@%&=?/~#]+[-A-Za-z0-9_$%&=?/~#]",\ + { "(file|rtsp|http|ftp|https)://[-A-Za-z0-9_$.+!*(),;:@%&=?/~#]+[-A-Za-z0-9_$%&=?/~#]",\ NULL, NULL },\ { "www\\.[-a-z0-9.]+[-a-z0-9](:[0-9]*)?(/[-A-Za-z0-9_$.+!*(),;:@%&=?/~#]*[^]}\\),?!;:\"]?)?",\ NULL, "http://" },\ @@ -87,6 +89,7 @@ struct _UrlMatchPattern { /* list my signals */ enum { LINK_CLICKED_SIGNAL, + LINK_HOVER_SIGNAL, ATTACHMENT_CLICKED_SIGNAL, LAST_SIGNAL }; @@ -158,6 +161,14 @@ modest_msg_view_class_init (ModestMsgViewClass *klass) g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_INT); + signals[LINK_HOVER_SIGNAL] = + g_signal_new ("link_hover", + G_TYPE_FROM_CLASS (gobject_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET(ModestMsgViewClass, link_hover), + NULL, NULL, + g_cclosure_marshal_VOID__STRING, + G_TYPE_NONE, 1, G_TYPE_STRING); } static void @@ -181,6 +192,9 @@ modest_msg_view_init (ModestMsgView *obj) g_signal_connect (G_OBJECT(priv->gtkhtml), "url_requested", G_CALLBACK(on_url_requested), obj); + + g_signal_connect (G_OBJECT(priv->gtkhtml), "on_url", + G_CALLBACK(on_link_hover), obj); } @@ -219,7 +233,6 @@ modest_msg_view_new (const TnyMsgIface *msg) static gboolean on_link_clicked (GtkWidget *widget, const gchar *uri, ModestMsgView *msg_view) { - int index; g_return_val_if_fail (msg_view, FALSE); @@ -240,12 +253,28 @@ on_link_clicked (GtkWidget *widget, const gchar *uri, ModestMsgView *msg_view) return FALSE; } - g_signal_emit (G_OBJECT(msg_view), signals[LINK_CLICKED_SIGNAL], 0, uri); + g_signal_emit (G_OBJECT(msg_view), signals[LINK_CLICKED_SIGNAL], + 0, uri); + + return FALSE; +} + + + +static gboolean +on_link_hover (GtkWidget *widget, const gchar *uri, ModestMsgView *msg_view) +{ + if (uri && g_str_has_prefix (uri, ATT_PREFIX)) + return FALSE; + + g_signal_emit (G_OBJECT(msg_view), signals[LINK_HOVER_SIGNAL], + 0, uri); return FALSE; } + static TnyMsgMimePartIface * find_cid_image (const TnyMsgIface *msg, const gchar *cid) { diff --git a/src/widgets/modest-msg-view.h b/src/widgets/modest-msg-view.h index fe92c7a..40cc531 100644 --- a/src/widgets/modest-msg-view.h +++ b/src/widgets/modest-msg-view.h @@ -59,8 +59,12 @@ struct _ModestMsgView { struct _ModestMsgViewClass { GtkScrolledWindowClass parent_class; - void (*link_clicked) (GtkWidget *widget, const gchar* link, gpointer user_data); - void (*attachment_clicked) (GtkWidget *widget, int index, gpointer user_data); + void (*link_hover) (ModestMsgView *msgview, const gchar* link, + gpointer user_data); + void (*link_clicked) (ModestMsgView *msgview, const gchar* link, + gpointer user_data); + void (*attachment_clicked) (ModestMsgView *msgview, int index, + gpointer user_data); };