AC_SUBST(MODEST_PLATFORM)
if test "x$with_platform" = "xmaemo"; then
- PKG_CHECK_MODULES(MODEST_LIBTINYMAIL_MAEMO,libtinymail-maemo-1.0 hildon-libs libosso libossomime)
+ PKG_CHECK_MODULES(MODEST_LIBTINYMAIL_MAEMO,libtinymail-maemo-1.0 hildon-libs libosso libossomime osso-addressbook-1.0)
AC_SUBST(MODEST_LIBTINYMAIL_MAEMO_CFLAGS)
AC_SUBST(MODEST_LIBTINYMAIL_MAEMO_LIBS)
modest-account-mgr-priv.h\
modest-account-mgr.c\
modest-account-mgr.h\
+ modest-address-book.h\
modest-cache-mgr.c\
modest-cache-mgr.h\
modest-conf.c\
modest-account-assistant.c \
modest-account-assistant.h \
modest-account-view-window.c \
+ modest-address-book.c \
modest-msg-edit-window.c \
modest-icon-names.h \
modest-main-window.c \
--- /dev/null
+/* Copyright (c) 2007, Nokia Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the Nokia Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* modest-address-book.c */
+
+#include <modest-address-book.h>
+
+void
+modest_address_book_add_address (const gchar *address)
+{
+ g_message (__FUNCTION__);
+}
+
+gchar *
+modest_address_book_select_addresses (void)
+{
+ g_message (__FUNCTION__);
+ return NULL;
+}
{ "GotoNext", GTK_STOCK_GO_FORWARD, N_("Next"), NULL, N_("Go to next message"), G_CALLBACK (modest_ui_actions_on_next) },
/* OPTIONS */
+ { "OptionsAddToContacts", NULL, N_("A_dd to accounts"), NULL, N_("Add selection to accounts"), G_CALLBACK (modest_ui_actions_on_add_to_contacts) },
{ "OptionsAccounts", NULL, N_("_Accounts"), NULL, N_("Manage accounts"), G_CALLBACK (modest_ui_actions_on_accounts) },
{ "OptionsContacts", NULL, N_("_Contacts"), NULL, N_("Manage contacts"), NULL },
</menu>
<menu name="OptionsMenu" action="Options">
+ <menuitem name="OptionsAddToContactsMenu" action="OptionsAddToContacts"/>
<menuitem name="OptionsAccountsMenu" action="OptionsAccounts"/>
+ <separator/>
<menuitem name="OptionsContactsMenu" action="OptionsContacts"/>
</menu>
<menuitem action="ActionsFolderMoveToTrash"/>
</popup>
-</ui>
\ No newline at end of file
+</ui>
libmodest_ui_la_SOURCES= \
modest-account-view-window.c \
+ modest-address-book.c \
modest-icon-names.h \
modest-main-window.c \
modest-main-window-ui.h \
--- /dev/null
+/* Copyright (c) 2007, Nokia Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the Nokia Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* modest-address-book.c */
+
+#include <modest-address-book.h>
+#include <libebook/e-book.h>
+#include <libebook/e-book-view.h>
+#include <libosso-abook/osso-abook.h>
+
+static OssoABookContactModel *contact_model = NULL;
+static EBook *book = NULL;
+static EBookView * book_view = NULL;
+
+
+static void
+get_book_view_cb (EBook *book, EBookStatus status, EBookView *bookview, gpointer data)
+{
+ if (status != E_BOOK_ERROR_OK) {
+ g_object_unref (book);
+ book = NULL;
+ return;
+ }
+ book_view = bookview;
+
+ if (contact_model)
+ osso_abook_tree_model_set_book_view (OSSO_ABOOK_TREE_MODEL (contact_model),
+ book_view);
+
+ e_book_view_start (book_view);
+}
+
+static void
+book_open_cb (EBook *view, EBookStatus status, gpointer data)
+{
+ EBookQuery *query = NULL;
+
+ if (status != E_BOOK_ERROR_OK) {
+ g_object_unref (book);
+ book = NULL;
+ return;
+ }
+ query = e_book_query_any_field_contains ("");
+ e_book_async_get_book_view (book, query, NULL, -1, get_book_view_cb, NULL);
+ e_book_query_unref (query);
+}
+
+static gboolean
+open_addressbook ()
+{
+ book = e_book_new_system_addressbook (NULL);
+ if (!book)
+ return FALSE;
+
+ e_book_async_open (book, FALSE, book_open_cb, NULL);
+
+}
+
+void
+modest_address_book_add_address (const gchar *address)
+{
+ OssoABookAccount *account = NULL;
+ GtkWidget *dialog = NULL;
+
+ contact_model = osso_abook_contact_model_new ();
+ if (!open_addressbook ()) {
+ if (contact_model) {
+ g_object_unref (contact_model);
+ contact_model = NULL;
+ }
+ return;
+ }
+
+ account = osso_abook_account_get (EVC_EMAIL, NULL, address);
+ dialog = osso_abook_add_to_contacts_dialog_new (contact_model, account);
+ g_object_unref (account);
+ gtk_dialog_run (GTK_DIALOG (dialog));
+
+ if (contact_model) {
+ g_object_unref (contact_model);
+ contact_model = NULL;
+ }
+
+ gtk_widget_destroy (dialog);
+
+}
+
+gchar *
+modest_address_book_select_addresses (void)
+{
+ g_message (__FUNCTION__);
+}
+
/* Tools */
{ "ToolsSettings", NULL, N_("Settings..."), NULL, NULL, NULL },
+ { "ToolsAddToContacts", NULL, N_("Add to contact..."), NULL, NULL, G_CALLBACK (modest_ui_actions_on_add_to_contacts) },
{ "ToolsContacts", NULL, N_("Contact..."), NULL, NULL, NULL },
{ "ToolsFontSettings", NULL, N_("Font settings..."), NULL, NULL, NULL },
{ "ToolsSearchMessages", NULL, N_("Search messages..."), NULL, NULL, NULL },
<menu name="ToolsMenu" action="Tools">
<menuitem name="ToolsSettingsMenu" action="ToolsSettings"/>
<separator/>
+ <menuitem name="ToolsAddToContactsMenu" action="ToolsAddToContacts"/>
<menuitem name="ToolsContactsMenu" action="ToolsContacts"/>
<menuitem name="ToolsFontSettingsMenu" action="ToolsFontSettings"/>
<separator/>
<menuitem name="EditMoveToMenu" action="EditMoveTo"/>
</menu>
+ <menu name="ToolsMenu" action="Tools">
+ <menuitem name="ToolsAddToContactsMenu" action="ToolsAddToContacts"/>
+ </menu>
+
<menu name="CloseMenu" action="Close">
<menuitem name="CloseWindowMenu" action="CloseWindow"/>
</menu>
--- /dev/null
+/* Copyright (c) 2007, Nokia Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the Nokia Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* modest-address-book.h */
+
+#ifndef __MODEST_ADDRESS_BOOK_H__
+#define __MODEST_ADDRESS_BOOK_H__
+
+#include <glib.h>
+
+/**
+ * modest_address_book_add_address:
+ * @address: a string
+ *
+ * launches the UI for adding @address to the addressbook
+ */
+void
+modest_address_book_add_address (const gchar *address);
+
+/**
+ * modest_address_book_select_addresses:
+ *
+ * Shows a dialog to select some addresses from the
+ * address book.
+ *
+ * Returns: a string with the addresses
+ */
+gchar *
+modest_address_book_select_addresses (void);
+
+
+#endif /* __MODEST_ADDRESS_BOOK_H__ */
}
+void
+modest_text_utils_address_range_at_position (const gchar *recipients_list,
+ gint position,
+ gint *start,
+ gint *end)
+{
+ gchar *current = NULL;
+ gint range_start = 0;
+ gint range_end = 0;
+ gint index;
+ gboolean is_quoted = FALSE;
+
+ index = 0;
+ for (current = (gchar *) recipients_list; *current != '\0'; current = g_utf8_find_next_char (current, NULL)) {
+ gunichar c = g_utf8_get_char (current);
+
+ if ((c == ',') && (!is_quoted)) {
+ if (index < position) {
+ range_start = index + 1;
+ } else {
+ break;
+ }
+ } else if (c == '\"') {
+ is_quoted = !is_quoted;
+ } else if ((c == ' ') &&(range_start == index)) {
+ range_start ++;
+ }
+ index ++;
+ range_end = index;
+ }
+
+ if (start)
+ *start = range_start;
+ if (end)
+ *end = range_end;
+}
+
/* ******************************************************************* */
/* ************************* UTILIY FUNCTIONS ************************ */
const gchar *address);
/**
+ * modest_text_utils_address_range_at_position:
+ * @address_list: utf8 string containing a list of addresses
+ * @position: a gint
+ * @start: a gint pointer
+ * @end: a gint pointer
+ *
+ * Finds the start and end positions of the address at @position,
+ * in @recipients_list, a list of addresses in the format of a
+ * recipient list in email. It stores the results in @start and
+ * @end
+ */
+void modest_text_utils_address_range_at_position (const gchar *recipients_list,
+ gint position,
+ gint *start,
+ gint *end);
+
+
+/**
* modest_text_utils_convert_to_html:
* @txt: a string which contains the message to quote
*
#include <modest-runtime.h>
#include <modest-tny-msg.h>
#include <modest-tny-account.h>
+#include <modest-address-book.h>
#include "modest-ui-actions.h"
}
void
+modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
+{
+ GtkClipboard *clipboard = NULL;
+ gchar *selection = NULL;
+
+ clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
+ selection = gtk_clipboard_wait_for_text (clipboard);
+
+ modest_address_book_add_address (selection);
+ g_free (selection);
+}
+
+void
modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win)
{
/* GtkDialog *account_win; */
void
modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
- ModestRecptView *recpt_view,
+ const gchar *address,
ModestWindow *win)
{
- gint start, end;
- gchar *utf_start, *utf_end;
- gchar *full_string = NULL;
- gchar *substring;
-
- gtk_label_get_selection_bounds (GTK_LABEL (recpt_view), &start, &end);
- full_string = (gchar *) gtk_label_get_text (GTK_LABEL (recpt_view));
- utf_start = g_utf8_offset_to_pointer (full_string, start);
- utf_end = g_utf8_offset_to_pointer (full_string, end);
- substring = g_strndup (utf_start, utf_end - utf_start);
- g_message ("%s %s", __FUNCTION__, substring);
-
- g_free (substring);
-
+ g_message ("%s %s", __FUNCTION__, address);
}
void
void modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win);
+void modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win);
+
void modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win);
void modest_ui_actions_on_open (GtkAction *action, ModestWindow *win);
void modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, int index,
ModestWindow *win);
-void modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview, ModestRecptView *recpt_view,
+void modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview, const gchar *address,
ModestWindow *win);
void modest_ui_actions_on_send (GtkWidget *widget,
static guint signals[LAST_SIGNAL] = {0};
static void
-activate_recpt (GtkWidget *recpt_view, gpointer user_data)
+activate_recpt (GtkWidget *recpt_view, const gchar *address, gpointer user_data)
{
ModestMailHeaderView * view = MODEST_MAIL_HEADER_VIEW (user_data);
- g_signal_emit (G_OBJECT (view), signals[RECPT_ACTIVATED_SIGNAL], 0, recpt_view);
+ g_signal_emit (G_OBJECT (view), signals[RECPT_ACTIVATED_SIGNAL], 0, address);
}
static void
gtk_label_set_markup (GTK_LABEL (label_field), field);
gtk_misc_set_alignment (GTK_MISC (label_field), 0.0, 0.0);
label_value = modest_recpt_view_new ();
- gtk_label_set_text (GTK_LABEL (label_value), value);
- gtk_label_set_selectable (GTK_LABEL (label_value), TRUE);
- gtk_misc_set_alignment (GTK_MISC (label_value), 0.0, 0.0);
+ modest_recpt_view_set_recipients (MODEST_RECPT_VIEW(label_value), value);
g_signal_connect (G_OBJECT (label_value), "activate", G_CALLBACK (activate_recpt), widget);
gtk_box_pack_start (GTK_BOX (hbox), label_field, FALSE, FALSE, 0);
gchar *sent = modest_text_utils_get_display_date (tny_header_get_date_sent (header));
gtk_label_set_markup (GTK_LABEL (priv->fromto_label), _("<b>To:</b>"));
if (to)
- gtk_label_set_text (GTK_LABEL (priv->fromto_contents), to);
+ modest_recpt_view_set_recipients (MODEST_RECPT_VIEW (priv->fromto_contents), to);
add_header (MODEST_MAIL_HEADER_VIEW (self), _("<b>Sent:</b>"), sent);
g_free (sent);
} else {
gchar *received = modest_text_utils_get_display_date (tny_header_get_date_received (header));
gtk_label_set_markup (GTK_LABEL (priv->fromto_label), _("<b>From:</b>"));
if (from)
- gtk_label_set_text (GTK_LABEL (priv->fromto_contents), from);
+ modest_recpt_view_set_recipients (MODEST_RECPT_VIEW (priv->fromto_contents), from);
add_header (MODEST_MAIL_HEADER_VIEW (self), _("<b>Received:</b>"), received);
g_free (received);
}
clean_headers (priv->headers_vbox);
gtk_label_set_text (GTK_LABEL (priv->fromto_label), "");
- gtk_label_set_text (GTK_LABEL (priv->fromto_contents), "");
+ modest_recpt_view_set_recipients (MODEST_RECPT_VIEW (priv->fromto_contents), "");
gtk_widget_hide (GTK_WIDGET(self));
{
ModestMailHeaderViewPriv *priv = MODEST_MAIL_HEADER_VIEW_GET_PRIVATE (header_view);
+ gtk_widget_queue_resize (GTK_WIDGET (header_view));
+ gtk_widget_queue_draw (GTK_WIDGET (header_view));
+
if (gtk_expander_get_expanded (GTK_EXPANDER (expander))) {
if (gtk_widget_get_parent (priv->headers_vbox) == NULL) {
gtk_box_pack_start (GTK_BOX(priv->main_vbox), priv->headers_vbox, TRUE, TRUE, 0);
gtk_container_remove (GTK_CONTAINER (priv->main_vbox), priv->headers_vbox);
}
}
- gtk_widget_queue_resize (GTK_WIDGET (header_view));
- gtk_widget_queue_draw (GTK_WIDGET (header_view));
+ gtk_widget_queue_resize (GTK_WIDGET (priv->expander));
+ gtk_widget_queue_draw (GTK_WIDGET (priv->expander));
}
/**
fromto_hbox = gtk_hbox_new (FALSE, 12);
priv->fromto_label = gtk_label_new (NULL);
- priv->fromto_contents = modest_recpt_view_new ();
- gtk_label_set_selectable (GTK_LABEL (priv->fromto_contents), TRUE);
gtk_misc_set_alignment (GTK_MISC (priv->fromto_label), 0.0, 0.0);
- gtk_misc_set_alignment (GTK_MISC (priv->fromto_contents), 0.0, 0.0);
+ priv->fromto_contents = modest_recpt_view_new ();
g_signal_connect (G_OBJECT (priv->fromto_contents), "activate", G_CALLBACK (activate_recpt), instance);
gtk_box_pack_start (GTK_BOX (fromto_hbox), priv->fromto_label, FALSE, FALSE, 0);
priv->labels_size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
gtk_size_group_add_widget (priv->labels_size_group, priv->fromto_label);
- priv->headers_vbox = gtk_vbox_new (FALSE, 1);
+ priv->headers_vbox = gtk_vbox_new (FALSE, 0);
g_object_ref (priv->headers_vbox);
expander_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
gtk_size_group_add_widget (expander_group, fromto_hbox);
g_object_unref (expander_group);
+ gtk_container_set_reallocate_redraws (GTK_CONTAINER (instance), TRUE);
+
priv->is_sent = FALSE;
return;
G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
G_STRUCT_OFFSET(ModestMailHeaderViewClass, recpt_activated),
NULL, NULL,
- g_cclosure_marshal_VOID__POINTER,
+ g_cclosure_marshal_VOID__STRING,
G_TYPE_NONE, 1,
- MODEST_TYPE_RECPT_VIEW);
+ G_TYPE_STRING);
return;
void (*clear_func) (TnyHeaderView *self);
/* signals */
- void (*recpt_activated) (ModestRecptView *recpt_view);
+ void (*recpt_activated) (const gchar *address);
};
GType modest_mail_header_view_get_type (void);
static void modest_msg_view_init (ModestMsgView *obj);
static void modest_msg_view_finalize (GObject *obj);
-static void on_recpt_activated (ModestMailHeaderView *header_view, ModestRecptView *recpt_view, ModestMsgView *msg_view);
+static void on_recpt_activated (ModestMailHeaderView *header_view, const gchar *address, ModestMsgView *msg_view);
static gboolean on_link_clicked (GtkWidget *widget, const gchar *uri, ModestMsgView *msg_view);
static gboolean on_url_requested (GtkWidget *widget, const gchar *uri, GtkHTMLStream *stream,
ModestMsgView *msg_view);
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET(ModestMsgViewClass, recpt_activated),
NULL, NULL,
- g_cclosure_marshal_VOID__POINTER,
- G_TYPE_NONE, 1, MODEST_TYPE_RECPT_VIEW);
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE, 1, G_TYPE_STRING);
}
static void
static void
on_recpt_activated (ModestMailHeaderView *header_view,
- ModestRecptView *recpt_view,
+ const gchar *address,
ModestMsgView * view)
{
- g_signal_emit (G_OBJECT (view), signals[RECPT_ACTIVATED_SIGNAL], 0, recpt_view);
+ g_signal_emit (G_OBJECT (view), signals[RECPT_ACTIVATED_SIGNAL], 0, address);
}
static gboolean
gpointer user_data);
void (*attachment_clicked) (ModestMsgView *msgview, int index,
gpointer user_data);
- void (*recpt_activated) (ModestMsgView *msgview, ModestRecptView *recpt_view,
+ void (*recpt_activated) (ModestMsgView *msgview, const gchar *address,
gpointer user_data);
};
#include <string.h>
#include <gtk/gtk.h>
-#include "modest-recpt-view.h"
+#include <modest-text-utils.h>
+#include <modest-recpt-view.h>
static GObjectClass *parent_class = NULL;
struct _ModestRecptViewPriv
{
+ GtkWidget *text_view;
gboolean button_pressed;
gdouble pressed_x, pressed_y;
+ gint line_height;
};
#define MODEST_RECPT_VIEW_GET_PRIVATE(o) \
static guint signals[LAST_SIGNAL] = {0};
+
/**
* modest_recpt_view_new:
*
return GTK_WIDGET (self);
}
-static void
-address_bounds_at_position (const gchar *recipients_list, gint position, gint *start, gint *end)
+void
+modest_recpt_view_set_recipients (ModestRecptView *recpt_view, const gchar *recipients)
{
- gchar *current = NULL;
- gint range_start = 0;
- gint range_end = 0;
- gint index;
- gboolean is_quoted = FALSE;
-
- index = 0;
- for (current = (gchar *) recipients_list; *current != '\0'; current = g_utf8_find_next_char (current, NULL)) {
- gunichar c = g_utf8_get_char (current);
-
- if ((c == ',') && (!is_quoted)) {
- if (index < position) {
- range_start = index + 1;
- } else {
- break;
- }
- } else if (c == '\"') {
- is_quoted = !is_quoted;
- } else if ((c == ' ') &&(range_start == index)) {
- range_start ++;
- }
- index ++;
- range_end = index;
- }
+ GtkTextBuffer *buffer = NULL;
+ ModestRecptViewPriv *priv = MODEST_RECPT_VIEW_GET_PRIVATE (recpt_view);
+
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->text_view));
+ gtk_text_buffer_set_text (buffer, recipients, -1);
+ gtk_widget_queue_resize (GTK_WIDGET (recpt_view));
- if (start)
- *start = range_start;
- if (end)
- *end = range_end;
}
-static gboolean
+static gint
button_press_event (GtkWidget *widget,
GdkEventButton *event,
gpointer user_data)
{
- ModestRecptViewPriv *priv = MODEST_RECPT_VIEW_GET_PRIVATE (MODEST_RECPT_VIEW (widget));
-
- if (!gtk_label_get_selectable (GTK_LABEL (widget)))
- return FALSE;
+ ModestRecptViewPriv *priv = MODEST_RECPT_VIEW_GET_PRIVATE (MODEST_RECPT_VIEW (user_data));
- if (event->type == GDK_BUTTON_PRESS) {
+ if (event->type == GDK_BUTTON_PRESS && event->button == 1) {
priv->button_pressed = TRUE;
priv->pressed_x = event->x;
priv->pressed_y = event->y;
}
- return FALSE;
+ return TRUE;
}
-static gboolean
+static gint
button_release_event (GtkWidget *widget,
- GdkEventButton *event,
- gpointer user_data)
+ GdkEventButton *event,
+ gpointer user_data)
{
- ModestRecptViewPriv *priv = MODEST_RECPT_VIEW_GET_PRIVATE (MODEST_RECPT_VIEW (widget));
-
- if (!gtk_label_get_selectable (GTK_LABEL (widget)))
- return TRUE;
+ ModestRecptViewPriv *priv = MODEST_RECPT_VIEW_GET_PRIVATE (MODEST_RECPT_VIEW (user_data));
if (event->type != GDK_BUTTON_RELEASE)
return TRUE;
if ((priv->button_pressed) &&
- (event->type == GDK_BUTTON_RELEASE) &&
+ (event->type == GDK_BUTTON_RELEASE) &&
(priv->pressed_x == event->x) &&
(priv->pressed_y == event->y)) {
priv->button_pressed = FALSE;
if (event->button == 1) {
- PangoLayout *layout = NULL;
+ gint buffer_x, buffer_y;
int index;
- layout = gtk_label_get_layout (GTK_LABEL (widget));
- if (pango_layout_xy_to_index (layout, event->x*PANGO_SCALE, event->y*PANGO_SCALE, &index, NULL)) {
+ GtkTextIter iter;
+ gtk_text_view_window_to_buffer_coords (GTK_TEXT_VIEW (priv->text_view), GTK_TEXT_WINDOW_WIDGET,
+ event->x, event->y, &buffer_x, &buffer_y);
+ gtk_text_view_get_iter_at_location (GTK_TEXT_VIEW (priv->text_view), &iter, buffer_x, buffer_y);
+ index = gtk_text_iter_get_offset (&iter);
+
+ if (!gtk_text_iter_is_end (&iter)) {
int selection_start, selection_end;
gboolean selected = FALSE;
- if (gtk_label_get_selection_bounds (GTK_LABEL (widget),
- &selection_start,
- &selection_end) &&
- (index >= selection_start)&&(index < selection_end)) {
+ GtkTextIter start_iter, end_iter;
+ GtkTextBuffer *buffer;
+
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->text_view));
+ if (gtk_text_buffer_get_selection_bounds (buffer, &start_iter, &end_iter) &&
+ gtk_text_iter_in_range (&iter, &start_iter, &end_iter)) {
selected = TRUE;
+ } else {
+ gchar *text = NULL;
+ GtkTextIter start_iter, end_iter;
+
+ gtk_text_buffer_get_start_iter (buffer, &start_iter);
+ gtk_text_buffer_get_end_iter (buffer, &end_iter);
+ text = gtk_text_buffer_get_text (buffer, &start_iter, &end_iter, FALSE);
+
+ modest_text_utils_address_range_at_position (text,
+ index,
+ &selection_start, &selection_end);
+ /* TODO: now gtk label tries to select more than the label as usual,
+ * and we force it to recover the selected region for the defined area.
+ * It should be fixed (maybe preventing gtklabel to manage selections
+ * in parallel with us
+ */
+ gtk_text_buffer_get_iter_at_offset (buffer, &start_iter, selection_start);
+ gtk_text_buffer_get_iter_at_offset (buffer, &end_iter, selection_end);
+ gtk_text_buffer_select_range (buffer, &start_iter, &end_iter);
+
+ if (text)
+ g_free (text);
+
+ }
+
+ if (selected) {
+ gchar *selection;
+
+ gtk_text_buffer_get_selection_bounds (buffer, &start_iter, &end_iter);
+ selection = gtk_text_buffer_get_text (buffer, &start_iter, &end_iter, FALSE);
+ g_signal_emit (G_OBJECT (user_data), signals[ACTIVATE_SIGNAL], 0, selection);
+ g_free (selection);
}
- address_bounds_at_position (gtk_label_get_text (GTK_LABEL (widget)),
- index,
- &selection_start, &selection_end);
- /* TODO: now gtk label tries to select more than the label as usual,
- * and we force it to recover the selected region for the defined area.
- * It should be fixed (maybe preventing gtklabel to manage selections
- * in parallel with us
- */
- gtk_label_select_region (GTK_LABEL (widget),
- selection_start,
- selection_end);
-
- if (selected)
- g_signal_emit (G_OBJECT (widget), signals[ACTIVATE_SIGNAL], 0);
-
- return TRUE;
}
+ return TRUE;
}
}
priv->button_pressed = FALSE;
}
static void
+text_view_size_request (GtkWidget *widget,
+ GtkRequisition *requisition,
+ gpointer user_data)
+{
+ GtkTextBuffer *buffer = NULL;
+ GtkTextIter iter;
+ int line;
+ GdkRectangle iter_rectangle;
+ GtkWidget *text_view = GTK_WIDGET (user_data);
+ GtkAdjustment *adj = NULL;
+ ModestRecptViewPriv *priv = MODEST_RECPT_VIEW_GET_PRIVATE (widget);
+
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view));
+
+ gtk_text_buffer_get_start_iter (buffer, &iter);
+ gtk_text_view_get_iter_location (GTK_TEXT_VIEW (text_view), &iter, &iter_rectangle);
+
+ for (line = 0; line < 2; line++) {
+ if (!gtk_text_view_forward_display_line (GTK_TEXT_VIEW (text_view), &iter))
+ break;
+ }
+
+ gtk_text_buffer_get_start_iter (buffer, &iter);
+
+ gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (text_view), &iter, 0.0, TRUE, 0.0, 0.0);
+
+ adj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (widget));
+ if (adj != NULL) {
+ g_object_set (G_OBJECT (adj), "page-increment", (gdouble) iter_rectangle.height, "step-increment", (gdouble) iter_rectangle.height, NULL);
+ gtk_adjustment_changed (adj);
+ }
+
+ if (line > 0) {
+ requisition->height = iter_rectangle.height * 2;
+ } else {
+ requisition->height = iter_rectangle.height;
+ }
+
+ priv->line_height = iter_rectangle.height;
+
+}
+
+static void
+view_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation,
+ gpointer user_data)
+{
+ GtkAdjustment *adj = NULL;
+ ModestRecptViewPriv *priv = MODEST_RECPT_VIEW_GET_PRIVATE (widget);
+
+ adj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (widget));
+ if (adj != NULL) {
+ g_object_set (G_OBJECT (adj), "page-increment", (gdouble) priv->line_height, "step-increment", (gdouble) priv->line_height, NULL);
+ }
+ gtk_adjustment_changed (adj);
+}
+
+static void
modest_recpt_view_instance_init (GTypeInstance *instance, gpointer g_class)
{
+ ModestRecptViewPriv *priv = MODEST_RECPT_VIEW_GET_PRIVATE (instance);
+
+ priv->text_view = gtk_text_view_new ();
+
+ gtk_text_view_set_editable (GTK_TEXT_VIEW (priv->text_view), FALSE);
+ gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (priv->text_view), GTK_WRAP_WORD_CHAR);
+ gtk_text_view_set_pixels_above_lines (GTK_TEXT_VIEW (priv->text_view), 0);
+ gtk_text_view_set_pixels_below_lines (GTK_TEXT_VIEW (priv->text_view), 0);
+ gtk_text_view_set_justification (GTK_TEXT_VIEW (priv->text_view), GTK_JUSTIFY_LEFT);
+ gtk_text_view_set_left_margin (GTK_TEXT_VIEW (priv->text_view), 0);
+ gtk_text_view_set_right_margin (GTK_TEXT_VIEW (priv->text_view), 0);
+ gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (priv->text_view), FALSE);
+ gtk_drag_dest_unset (priv->text_view);
+
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (instance), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
- gtk_label_set_justify (GTK_LABEL (instance), GTK_JUSTIFY_LEFT);
- gtk_label_set_line_wrap (GTK_LABEL (instance), TRUE);
- gtk_label_set_selectable (GTK_LABEL (instance), TRUE);
+ gtk_container_add (GTK_CONTAINER (instance), priv->text_view);
- g_signal_connect (G_OBJECT (instance), "button-press-event", G_CALLBACK(button_press_event), NULL);
- g_signal_connect (G_OBJECT (instance), "button-release-event", G_CALLBACK(button_release_event), NULL);
+ g_signal_connect (G_OBJECT (instance), "size-request", G_CALLBACK (text_view_size_request), priv->text_view);
+ g_signal_connect (G_OBJECT (instance), "size-allocate", G_CALLBACK (view_size_allocate), NULL);
+ g_signal_connect (G_OBJECT (priv->text_view), "button-press-event", G_CALLBACK (button_press_event), instance);
+ g_signal_connect (G_OBJECT (priv->text_view), "button-release-event", G_CALLBACK (button_release_event), instance);
return;
}
modest_recpt_view_class_init (ModestRecptViewClass *klass)
{
GObjectClass *object_class;
+ GtkWidgetClass *widget_class;
parent_class = g_type_class_peek_parent (klass);
object_class = (GObjectClass*) klass;
+ widget_class = GTK_WIDGET_CLASS (klass);
object_class->finalize = modest_recpt_view_finalize;
G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
G_STRUCT_OFFSET(ModestRecptViewClass, activate),
NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE, 1, G_TYPE_STRING);
return;
}
modest_recpt_view_instance_init /* instance_init */
};
- type = g_type_register_static (GTK_TYPE_LABEL,
+ type = g_type_register_static (GTK_TYPE_SCROLLED_WINDOW,
"ModestRecptView",
&info, 0);
struct _ModestRecptView
{
- GtkLabel parent;
+ GtkScrolledWindow parent;
};
struct _ModestRecptViewClass
{
- GtkLabelClass parent_class;
+ GtkScrolledWindowClass parent_class;
- void (*activate) (ModestRecptView *recpt_view);
+ void (*activate) (ModestRecptView *recpt_view, const gchar *address);
};
GType modest_recpt_view_get_type (void);
GtkWidget* modest_recpt_view_new (void);
+void modest_recpt_view_set_recipients (ModestRecptView *recpt_view, const gchar *recipients);
+
G_END_DECLS
#endif