Merge lp:~dobey/ubuntuone-client-gnome/no-more-eds into lp:ubuntuone-client-gnome

Proposed by dobey
Status: Merged
Approved by: dobey
Approved revision: 25
Merged at revision: 19
Proposed branch: lp:~dobey/ubuntuone-client-gnome/no-more-eds
Merge into: lp:ubuntuone-client-gnome
Diff against target: 2122 lines (+55/-1919)
14 files modified
configure.ac (+1/-1)
nautilus/Makefile.am (+0/-31)
nautilus/add-contact-dialog.c (+0/-137)
nautilus/add-contact-dialog.h (+0/-50)
nautilus/contacts-view.c (+0/-855)
nautilus/contacts-view.h (+0/-81)
nautilus/highlight.c (+0/-162)
nautilus/highlight.h (+0/-29)
nautilus/share-dialog.c (+54/-52)
nautilus/test-contacts-picker.c (+0/-98)
nautilus/test-highlight.c (+0/-90)
nautilus/u1-contacts-picker.c (+0/-269)
nautilus/u1-contacts-picker.h (+0/-61)
po/POTFILES.in (+0/-3)
To merge this branch: bzr merge lp:~dobey/ubuntuone-client-gnome/no-more-eds
Reviewer Review Type Date Requested Status
Brian Curtin (community) Approve
Roberto Alsina (community) Approve
Review via email: mp+122080@code.launchpad.net

Commit message

Remove usage of libebook and e-d-s for contact lookup.
Use a simple entry field for sharing to e-mail addresses.

Description of the change

This updates the Nautilus extension to no longer have the large contact picker that was empty for most people, and removes the usage of e-d-s for contacts lookup, as the new version in 12.10 has broken API/ABI compatibility. Instead, there is now a simple entry for entering one or more e-mail addresses (using comma separation of course).

In testing this branch, I discovered a crash in libsyncdaemon when entering multiple e-mail addresses, and so to share with multiple addresses successfully, lp:~dobey/ubuntuone-client/fix-1043868 will also be needed.

A screen shot of this change is at http://ubuntuone.com/4SPMPsP5FysA55FQK5MU8V

To post a comment you must log in.
Revision history for this message
Roberto Alsina (ralsina) wrote :

Design suggests changing the text to "Email addresses, comma separated" so users know what to enter.

review: Needs Fixing
Revision history for this message
Roberto Alsina (ralsina) :
review: Approve
Revision history for this message
Brian Curtin (brian.curtin) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'configure.ac'
2--- configure.ac 2012-05-24 18:41:26 +0000
3+++ configure.ac 2012-08-30 19:02:18 +0000
4@@ -62,7 +62,7 @@
5 fi
6 AM_CONDITIONAL([HAVE_NAUTILUS_30], [test "x$have_nautilus_30" = "xyes"])
7
8-PKG_CHECK_MODULES(NAUTILUS, [libnautilus-extension >= 2.6.0 libebook-1.2 libsyncdaemon-1.0 >= 1.7 $NAUTILUS_GCONF_DEP])
9+PKG_CHECK_MODULES(NAUTILUS, [libnautilus-extension >= 2.6.0 libsyncdaemon-1.0 >= 1.7 $NAUTILUS_GCONF_DEP])
10 AC_SUBST(NAUTILUS_CFLAGS)
11 AC_SUBST(NAUTILUS_LIBS)
12
13
14=== modified file 'nautilus/Makefile.am'
15--- nautilus/Makefile.am 2012-02-20 16:45:35 +0000
16+++ nautilus/Makefile.am 2012-08-30 19:02:18 +0000
17@@ -33,21 +33,13 @@
18 ubuntuone-nautilus.c: ubuntuone-marshallers.h
19
20 libnautilus_ubuntuone_la_SOURCES = \
21- add-contact-dialog.c \
22- add-contact-dialog.h \
23- contacts-view.c \
24- contacts-view.h \
25 context-menu.c \
26 context-menu.h \
27 error-dialog.c \
28 file-watcher.c \
29 file-watcher.h \
30- highlight.c \
31- highlight.h \
32 share-dialog.c \
33 share-dialog.h \
34- u1-contacts-picker.c \
35- u1-contacts-picker.h \
36 ubuntuone-marshallers.c \
37 ubuntuone-marshallers.h \
38 ubuntuone-nautilus.c \
39@@ -59,29 +51,6 @@
40 $(DBUS_LIBS) \
41 $(NAUTILUS_LIBS)
42
43-noinst_PROGRAMS = test-contacts-picker test-highlight
44-
45-test_contacts_picker_CFLAGS = \
46- $(NAUTILUS_CFLAGS)
47-test_contacts_picker_SOURCES = \
48- test-contacts-picker.c \
49- add-contact-dialog.c \
50- add-contact-dialog.h \
51- contacts-view.c \
52- contacts-view.h \
53- highlight.c \
54- highlight.h \
55- u1-contacts-picker.c \
56- u1-contacts-picker.h
57-test_contacts_picker_LDADD = $(NAUTILUS_LIBS)
58-
59-test_highlight_CFLAGS = $(NAUTILUS_CFLAGS)
60-test_highlight_SOURCES = \
61- highlight.c \
62- highlight.h \
63- test-highlight.c
64-test_highlight_LDADD = $(NAUTILUS_LIBS)
65-
66 EXTRA_DIST = \
67 $(gschema_in_files) \
68 ubuntuone-marshallers.list
69
70=== removed file 'nautilus/add-contact-dialog.c'
71--- nautilus/add-contact-dialog.c 2011-07-20 20:44:39 +0000
72+++ nautilus/add-contact-dialog.c 1970-01-01 00:00:00 +0000
73@@ -1,137 +0,0 @@
74-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
75-/*
76- * Copyright (C) 2009 Canonical Services Ltd (www.canonical.com)
77- *
78- * Authors: Rodrigo Moya <rodrigo.moya@canonical.com>
79- *
80- * This library is free software; you can redistribute it and/or
81- * modify it under the terms of version 2 of the GNU Lesser General Public
82- * License as published by the Free Software Foundation.
83- *
84- * This program is distributed in the hope that it will be useful,
85- * but WITHOUT ANY WARRANTY; without even the implied warranty of
86- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
87- * General Public License for more details.
88- *
89- * You should have received a copy of the GNU Lesser General Public
90- * License along with this library; if not, write to the
91- * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
92- * Boston, MA 02110-1301, USA.
93- */
94-
95-#include <string.h>
96-#ifdef HAVE_CONFIG_H
97-#include <config.h>
98-#endif
99-
100-#include <glib/gi18n-lib.h>
101-#include "add-contact-dialog.h"
102-
103-G_DEFINE_TYPE(AddContactDialog, add_contact_dialog, GTK_TYPE_DIALOG)
104-
105-static void
106-add_contact_dialog_finalize (GObject *object)
107-{
108- G_OBJECT_CLASS (add_contact_dialog_parent_class)->finalize (object);
109-}
110-
111-static void
112-add_contact_dialog_class_init (AddContactDialogClass *klass)
113-{
114- GObjectClass *object_class = G_OBJECT_CLASS (klass);
115-
116- object_class->finalize = add_contact_dialog_finalize;
117-}
118-
119-static void
120-entry_changed_cb (GtkEditable *entry, gpointer user_data)
121-{
122- const gchar *text_name, *text_email;
123- AddContactDialog *dialog = (AddContactDialog *) user_data;
124-
125- text_name = gtk_entry_get_text (GTK_ENTRY (dialog->name_entry));
126- text_email = gtk_entry_get_text (GTK_ENTRY (dialog->email_entry));
127- if (strlen (text_name) > 0 && strlen (text_email) > 0)
128- gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, TRUE);
129- else
130- gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, FALSE);
131-}
132-
133-static void
134-entry_activated_cb (GtkEntry *entry, gpointer user_data)
135-{
136- const gchar *text_name, *text_email;
137- AddContactDialog *dialog = (AddContactDialog *) user_data;
138-
139- text_name = gtk_entry_get_text (GTK_ENTRY (dialog->name_entry));
140- text_email = gtk_entry_get_text (GTK_ENTRY (dialog->email_entry));
141- if (strlen (text_name) > 0 && strlen (text_email) > 0)
142- gtk_dialog_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
143-}
144-
145-static void
146-add_contact_dialog_init (AddContactDialog *dialog)
147-{
148- GtkWidget *table, *label;
149-
150- /* Build the dialog */
151- gtk_window_set_title (GTK_WINDOW (dialog), _("Add contact"));
152- gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
153- gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_ADD, GTK_RESPONSE_OK);
154-
155- gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
156- gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, FALSE);
157-
158- table = gtk_table_new (2, 2, FALSE);
159- gtk_widget_show (table);
160- gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
161- table, TRUE, TRUE, 3);
162-
163- label = gtk_label_new (_("Contact name"));
164- gtk_widget_show (label);
165- gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1, GTK_FILL, GTK_FILL, 3, 3);
166-
167- dialog->name_entry = gtk_entry_new ();
168- g_signal_connect (G_OBJECT (dialog->name_entry), "changed", G_CALLBACK (entry_changed_cb), dialog);
169- g_signal_connect (G_OBJECT (dialog->name_entry), "activate", G_CALLBACK (entry_activated_cb), dialog);
170- gtk_widget_show (dialog->name_entry);
171- gtk_table_attach (GTK_TABLE (table), dialog->name_entry, 1, 2, 0, 1, GTK_FILL, GTK_FILL, 3, 3);
172-
173- label = gtk_label_new (_("Email address"));
174- gtk_widget_show (label);
175- gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2, GTK_FILL, GTK_FILL, 3, 3);
176-
177- dialog->email_entry = gtk_entry_new ();
178- g_signal_connect (G_OBJECT (dialog->email_entry), "changed", G_CALLBACK (entry_changed_cb), dialog);
179- g_signal_connect (G_OBJECT (dialog->email_entry), "activate", G_CALLBACK (entry_activated_cb), dialog);
180- gtk_widget_show (dialog->email_entry);
181- gtk_table_attach (GTK_TABLE (table), dialog->email_entry, 1, 2, 1, 2, GTK_FILL, GTK_FILL, 3, 3);
182-}
183-
184-GtkWidget *
185-add_contact_dialog_new (GtkWindow *parent, const gchar *initial_text)
186-{
187- AddContactDialog *dialog;
188-
189- dialog = g_object_new (TYPE_ADD_CONTACT_DIALOG, NULL);
190- if (g_strrstr (initial_text, "@") != NULL)
191- gtk_entry_set_text (GTK_ENTRY (dialog->email_entry), initial_text);
192- else
193- gtk_entry_set_text (GTK_ENTRY (dialog->name_entry), initial_text);
194-
195- gtk_window_set_transient_for (GTK_WINDOW (dialog), parent);
196-
197- return GTK_WIDGET (dialog);
198-}
199-
200-const gchar *
201-add_contact_dialog_get_name_text (AddContactDialog *dialog)
202-{
203- return gtk_entry_get_text (GTK_ENTRY (dialog->name_entry));
204-}
205-
206-const gchar *
207-add_contact_dialog_get_email_text (AddContactDialog *dialog)
208-{
209- return gtk_entry_get_text (GTK_ENTRY (dialog->email_entry));
210-}
211
212=== removed file 'nautilus/add-contact-dialog.h'
213--- nautilus/add-contact-dialog.h 2011-07-20 20:44:39 +0000
214+++ nautilus/add-contact-dialog.h 1970-01-01 00:00:00 +0000
215@@ -1,50 +0,0 @@
216-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
217-/*
218- * Copyright (C) 2009 Canonical Services Ltd (www.canonical.com)
219- *
220- * Authors: Rodrigo Moya <rodrigo.moya@canonical.com>
221- *
222- * This library is free software; you can redistribute it and/or
223- * modify it under the terms of version 2 of the GNU Lesser General Public
224- * License as published by the Free Software Foundation.
225- *
226- * This program is distributed in the hope that it will be useful,
227- * but WITHOUT ANY WARRANTY; without even the implied warranty of
228- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
229- * General Public License for more details.
230- *
231- * You should have received a copy of the GNU Lesser General Public
232- * License along with this library; if not, write to the
233- * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
234- * Boston, MA 02110-1301, USA.
235- */
236-
237-#ifndef __ADD_CONTACT_DIALOG_H__
238-#define __ADD_CONTACT_DIALOG_H__
239-
240-#include <gtk/gtk.h>
241-
242-#define TYPE_ADD_CONTACT_DIALOG (add_contact_dialog_get_type ())
243-#define ADD_CONTACT_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_ADD_CONTACT_DIALOG, AddContactDialog))
244-#define IS_ADD_CONTACT_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_ADD_CONTACT_DIALOG))
245-#define ADD_CONTACT_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_ADD_CONTACT_DIALOG, AddContactDialogClass))
246-#define IS_ADD_CONTACT_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_ADD_CONTACT_DIALOG))
247-#define ADD_CONTACT_DIALOG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_ADD_CONTACT_DIALOG, AddContactDialogClass))
248-
249-typedef struct {
250- GtkDialog parent;
251-
252- GtkWidget *name_entry;
253- GtkWidget *email_entry;
254-} AddContactDialog;
255-
256-typedef struct {
257- GtkDialogClass parent_class;
258-} AddContactDialogClass;
259-
260-GType add_contact_dialog_get_type (void);
261-GtkWidget *add_contact_dialog_new (GtkWindow *parent, const gchar *initial_text);
262-const gchar *add_contact_dialog_get_name_text (AddContactDialog *dialog);
263-const gchar *add_contact_dialog_get_email_text (AddContactDialog *dialog);
264-
265-#endif
266
267=== removed file 'nautilus/contacts-view.c'
268--- nautilus/contacts-view.c 2011-09-23 16:01:11 +0000
269+++ nautilus/contacts-view.c 1970-01-01 00:00:00 +0000
270@@ -1,855 +0,0 @@
271-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
272-/*
273- * Copyright (C) 2009 Canonical Services Ltd (www.canonical.com)
274- *
275- * Authors: Rodrigo Moya <rodrigo.moya@canonical.com>
276- *
277- * This library is free software; you can redistribute it and/or
278- * modify it under the terms of version 2 of the GNU Lesser General Public
279- * License as published by the Free Software Foundation.
280- *
281- * This program is distributed in the hope that it will be useful,
282- * but WITHOUT ANY WARRANTY; without even the implied warranty of
283- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
284- * General Public License for more details.
285- *
286- * You should have received a copy of the GNU Lesser General Public
287- * License along with this library; if not, write to the
288- * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
289- * Boston, MA 02110-1301, USA.
290- */
291-
292-#ifdef HAVE_CONFIG_H
293-#include <config.h>
294-#endif
295-
296-#include <glib/gi18n-lib.h>
297-#include "contacts-view.h"
298-#include "highlight.h"
299-
300-#ifdef BUILD_GRID_VIEW
301-#define AVATAR_SIZE 64
302-#else
303-#define AVATAR_SIZE 24
304-#endif
305-
306-static void contacts_view_init (ContactsView *cv);
307-static void contacts_view_class_init (ContactsViewClass *klass);
308-
309-G_DEFINE_TYPE(ContactsView, contacts_view, GTK_TYPE_SCROLLED_WINDOW)
310-
311-#ifdef HAVE_NAUTILUS_30
312-#define SETTINGS_DOMAIN "org.gnome.nautilus.extensions.ubuntuone"
313-#define SETTINGS_CONTACTS_KEY "recently-used-contacts"
314-#else
315-#define RECENTLY_USED_CONTACTS_KEY "/apps/libubuntuone/recently-used"
316-#endif
317-
318-#define CONTACTS_VIEW_COLUMN_NAME 0
319-#define CONTACTS_VIEW_COLUMN_MARKUP 1
320-#define CONTACTS_VIEW_COLUMN_EMAIL 2
321-#define CONTACTS_VIEW_COLUMN_PIXBUF 3
322-#define CONTACTS_VIEW_COLUMN_RECENT 4
323-
324-typedef struct {
325- gchar *name;
326- gchar *markedup_name;
327- gchar *email;
328- GdkPixbuf *pixbuf;
329-} SelectedContactInfo;
330-
331-enum {
332- SELECTION_CHANGED_SIGNAL,
333- CONTACTS_COUNT_CHANGED_SIGNAL,
334- LAST_SIGNAL
335-};
336-static guint contacts_view_signals[LAST_SIGNAL];
337-
338-static void
339-contacts_view_finalize (GObject *object)
340-{
341- ContactsView *cv = CONTACTS_VIEW (object);
342-
343- if (cv->selection != NULL) {
344- g_hash_table_destroy (cv->selection);
345- cv->selection = NULL;
346- }
347-
348- if (cv->recently_used != NULL) {
349- g_hash_table_destroy (cv->recently_used);
350- cv->recently_used = NULL;
351- }
352-
353-#ifdef HAVE_NAUTILUS_30
354- if (cv->settings != NULL) {
355- g_object_unref (G_OBJECT (cv->settings));
356- cv->settings = NULL;
357- }
358-#else
359- if (cv->config_client != NULL) {
360- g_object_unref (G_OBJECT (cv->config_client));
361- cv->config_client = NULL;
362- }
363-#endif
364-
365- if (cv->source_list != NULL) {
366- g_object_unref (G_OBJECT (cv->source_list));
367- cv->source_list = NULL;
368- }
369-
370- if (cv->added_contacts != NULL) {
371- g_hash_table_destroy (cv->added_contacts);
372- cv->added_contacts = NULL;
373- }
374-
375- while (cv->books != NULL) {
376- EBook *book = (EBook *) cv->books->data;
377- cv->books = g_slist_remove (cv->books, book);
378- g_object_unref (G_OBJECT (book));
379- }
380-
381- G_OBJECT_CLASS (contacts_view_parent_class)->finalize (object);
382-}
383-
384-static void
385-contacts_view_class_init (ContactsViewClass *klass)
386-{
387- GObjectClass *object_class = G_OBJECT_CLASS (klass);
388-
389- object_class->finalize = contacts_view_finalize;
390-
391- /* Signals */
392- contacts_view_signals[SELECTION_CHANGED_SIGNAL] =
393- g_signal_new ("selection-changed",
394- G_OBJECT_CLASS_TYPE (object_class),
395- G_SIGNAL_RUN_LAST,
396- G_STRUCT_OFFSET (ContactsViewClass, selection_changed),
397- NULL, NULL,
398- g_cclosure_marshal_VOID__VOID,
399- G_TYPE_NONE,
400- 0);
401- contacts_view_signals[CONTACTS_COUNT_CHANGED_SIGNAL] =
402- g_signal_new ("contacts-count-changed",
403- G_OBJECT_CLASS_TYPE (object_class),
404- G_SIGNAL_RUN_LAST,
405- G_STRUCT_OFFSET (ContactsViewClass, contacts_count_changed),
406- NULL, NULL,
407- g_cclosure_marshal_VOID__INT,
408- G_TYPE_NONE, 1,
409- G_TYPE_INT);
410-}
411-
412-static void
413-recently_used_to_list_cb (gpointer key, gpointer value, gpointer user_data)
414-{
415- GSList **list = (GSList **) user_data;
416-
417- *list = g_slist_append (*list, key);
418-}
419-
420-static void
421-save_recently_used_list (ContactsView *cv)
422-{
423- GSList *list = NULL;
424-
425- g_hash_table_foreach (cv->recently_used, (GHFunc) recently_used_to_list_cb, &list);
426-
427-#ifdef HAVE_NAUTILUS_30
428- {
429- gchar **strv = e_client_util_slist_to_strv (list);
430- g_settings_set_strv (cv->settings, SETTINGS_CONTACTS_KEY,
431- (const gchar * const *) strv);
432- g_strfreev (strv);
433- }
434-#else
435- gconf_client_set_list (cv->config_client, RECENTLY_USED_CONTACTS_KEY, GCONF_VALUE_STRING, list, NULL);
436-#endif
437-
438- g_slist_free (list);
439-}
440-
441-static void
442-selection_changed_cb (GtkWidget *view, gpointer data)
443-{
444- GtkTreeModel *model;
445- GList *selected_items, *l;
446- ContactsView *cv = CONTACTS_VIEW (data);
447-
448- /* We first remove all the previous selected items */
449- g_hash_table_remove_all (cv->selection);
450-
451- /* Now add the new selection */
452-#ifdef BUILD_GRID_VIEW
453- model = gtk_icon_view_get_model (GTK_ICON_VIEW (view));
454- selected_items = gtk_icon_view_get_selected_items (GTK_ICON_VIEW (view));
455-#else
456- selected_items = gtk_tree_selection_get_selected_rows (
457- GTK_TREE_SELECTION (view),
458- &model);
459-#endif
460-
461- for (l = selected_items; l != NULL; l = l->next) {
462- GtkTreeIter iter;
463-
464- if (gtk_tree_model_get_iter (model, &iter, (GtkTreePath *) l->data)) {
465- gchar *name, *email, *s;
466- GdkPixbuf *icon;
467- SelectedContactInfo *sci;
468-
469- gtk_tree_model_get (model, &iter,
470- CONTACTS_VIEW_COLUMN_NAME, &name,
471- CONTACTS_VIEW_COLUMN_EMAIL, &email,
472- CONTACTS_VIEW_COLUMN_PIXBUF, &icon,
473- -1);
474-
475- sci = g_new0 (SelectedContactInfo, 1);
476- sci->name = g_strdup (name);
477- sci->markedup_name = g_markup_escape_text (name, -1);
478- sci->email = g_strdup (email);
479- sci->pixbuf = g_object_ref (icon);
480- g_hash_table_insert (cv->selection, g_strdup (name), sci);
481-
482- /* Add it to the recently used list */
483- s = g_strdup (sci->name);
484- g_hash_table_insert (cv->recently_used, s, s);
485- save_recently_used_list (cv);
486- }
487- }
488-
489- /* Free memory */
490- g_list_foreach (selected_items, (GFunc) gtk_tree_path_free, NULL);
491- g_list_free (selected_items);
492-
493- /* Notify listeners the selection has changed */
494- g_signal_emit_by_name (cv, "selection-changed", NULL);
495-}
496-
497-static void
498-add_one_contact (ContactsView *cv,
499- const gchar *name,
500- const gchar *markedup_name,
501- const gchar *email,
502- EContact *contact,
503- GHashTable *selection_hash)
504-{
505- GtkTreeIter new_row, current_row;
506- EContactPhoto *photo = NULL;
507- GtkTreeModel *model;
508- GdkPixbuf *pixbuf;
509- gboolean new_is_recent;
510-
511- /* Get the pixbuf for this contact */
512- if (contact != NULL) {
513- photo = e_contact_get (contact, E_CONTACT_PHOTO);
514- if (photo == NULL)
515- photo = e_contact_get (contact, E_CONTACT_LOGO);
516- }
517-
518- if (photo) {
519- gint width, height;
520- GdkPixbufLoader *loader = gdk_pixbuf_loader_new ();
521-
522- gdk_pixbuf_loader_write (loader, photo->data.inlined.data, photo->data.inlined.length, NULL);
523- gdk_pixbuf_loader_close (loader, NULL);
524- pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
525-
526- if (pixbuf != NULL) {
527- g_object_ref (G_OBJECT (pixbuf));
528-
529- /* Scale the image if it's too big */
530- width = gdk_pixbuf_get_width (pixbuf);
531- height = gdk_pixbuf_get_height (pixbuf);
532- if (width > AVATAR_SIZE || height > AVATAR_SIZE) {
533- GdkPixbuf *scaled;
534-
535- scaled = gdk_pixbuf_scale_simple ((const GdkPixbuf *) pixbuf,
536- AVATAR_SIZE, AVATAR_SIZE, GDK_INTERP_NEAREST);
537- g_object_unref (G_OBJECT (pixbuf));
538- pixbuf = scaled;
539- }
540- } else {
541- GtkIconTheme *icon_theme = gtk_icon_theme_get_default ();
542-
543- pixbuf = gtk_icon_theme_load_icon (icon_theme, "avatar-default", AVATAR_SIZE, 0, NULL);
544- }
545-
546- g_object_unref (G_OBJECT (loader));
547- } else {
548- GtkIconTheme *icon_theme = gtk_icon_theme_get_default ();
549-
550- pixbuf = gtk_icon_theme_load_icon (icon_theme, "avatar-default", AVATAR_SIZE, 0, NULL);
551- }
552-
553- /* Add the contact to the contacts view */
554-#ifdef BUILD_GRID_VIEW
555- model = gtk_icon_view_get_model (GTK_ICON_VIEW (cv->contacts_list));
556-#else
557- model = gtk_tree_view_get_model (GTK_TREE_VIEW (cv->contacts_list));
558-#endif
559-
560- new_is_recent = g_hash_table_lookup (cv->recently_used, name) != NULL;
561-
562- if (gtk_tree_model_get_iter_first (model, &current_row)) {
563- gchar *current_name;
564- gboolean added = FALSE;
565-
566-#ifdef BUILD_GRID_VIEW
567- gtk_icon_view_scroll_to_path (GTK_ICON_VIEW (cv->contacts_list),
568- gtk_tree_model_get_path (GTK_TREE_MODEL (model), &current_row),
569- TRUE, 0.0, 0.0);
570-#endif
571-
572- do {
573- gboolean current_is_recent, insert_before = FALSE;
574-
575- gtk_tree_model_get (model, &current_row,
576- CONTACTS_VIEW_COLUMN_NAME, &current_name,
577- -1);
578-
579- current_is_recent = g_hash_table_lookup (cv->recently_used, current_name) != NULL;
580-
581- if (g_hash_table_lookup (selection_hash, current_name) != NULL)
582- continue;
583- else if (new_is_recent) {
584- if (current_is_recent) {
585- if (g_ascii_strcasecmp (name, (const gchar *) current_name) < 0)
586- insert_before = TRUE;
587- } else
588- insert_before = TRUE;
589- } else if (!current_is_recent &&
590- g_ascii_strcasecmp (name, (const gchar *) current_name) < 0)
591- insert_before = TRUE;
592-
593- if (insert_before) {
594- gtk_list_store_insert_before (GTK_LIST_STORE (model), &new_row, &current_row);
595- added = TRUE;
596-
597- break;
598- }
599- } while (gtk_tree_model_iter_next (model, &current_row));
600-
601- if (!added)
602- gtk_list_store_append (GTK_LIST_STORE (model), &new_row);
603- } else
604- gtk_list_store_append (GTK_LIST_STORE (model), &new_row);
605-
606- gtk_list_store_set (GTK_LIST_STORE (model), &new_row,
607- CONTACTS_VIEW_COLUMN_NAME, name,
608- CONTACTS_VIEW_COLUMN_MARKUP, markedup_name,
609- CONTACTS_VIEW_COLUMN_EMAIL, email,
610- CONTACTS_VIEW_COLUMN_PIXBUF, pixbuf,
611- CONTACTS_VIEW_COLUMN_RECENT, new_is_recent,
612- -1);
613-}
614-
615-static void
616-add_contacts (ContactsView *cv, GList *contacts, GHashTable *selection_hash, gchar *search_string)
617-{
618- GList *l;
619- GtkTreeModel *model;
620-
621- for (l = contacts; l != NULL; l = l->next) {
622- EContact *contact = l->data;
623- const gchar *email = NULL;
624- GList *emails_list, *al;
625- EContactName *contact_name;
626- gchar *full_name = NULL;
627- gchar *markedup_name = NULL;
628-
629- contact_name = (EContactName *) e_contact_get (contact, E_CONTACT_NAME);
630- if (contact_name != NULL)
631- full_name = e_contact_name_to_string (contact_name);
632- else
633- full_name = e_contact_get (contact, E_CONTACT_NAME_OR_ORG);
634-
635- emails_list = e_contact_get_attributes (contact, E_CONTACT_EMAIL);
636- for (al = emails_list; al != NULL; al = al->next) {
637- EVCardAttribute *attr = (EVCardAttribute *) al->data;
638-
639- email = e_vcard_attribute_get_value (attr);
640- if (email != NULL)
641- break;
642- }
643-
644- if (full_name == NULL) {
645- if (email != NULL)
646- full_name = g_strdup (email);
647- else
648- g_warning ("Contact without name or email addresses");
649- }
650-
651- markedup_name = highlight_result (search_string, full_name);
652-
653- /* We add the selected items when searching, so ignore them here */
654- if (!g_hash_table_lookup (selection_hash, (gconstpointer) full_name)) {
655- if (email != NULL) {
656- add_one_contact (cv, full_name, markedup_name, email, contact, selection_hash);
657- cv->matched_contacts += 1;
658- }
659- }
660-
661- g_list_foreach (emails_list, (GFunc) e_vcard_attribute_free, NULL);
662- g_list_free (emails_list);
663- e_contact_name_free (contact_name);
664- g_free (markedup_name);
665- g_free (full_name);
666- }
667-
668-#ifdef BUILD_GRID_VIEW
669- model = gtk_icon_view_get_model (GTK_ICON_VIEW (cv->contacts_list));
670-#else
671- model = gtk_tree_view_get_model (GTK_TREE_VIEW (cv->contacts_list));
672-#endif
673-
674- g_signal_emit_by_name (cv, "contacts-count-changed",
675- gtk_tree_model_iter_n_children (model, NULL));
676-}
677-
678-static void
679-append_selected_to_model (GtkWidget *view,
680- const gchar *contact_name,
681- const gchar *contact_markedup_name,
682- const gchar *contact_email,
683- GdkPixbuf *pixbuf)
684-{
685- GtkTreeIter new_row;
686- GtkListStore *model;
687-
688-#ifdef BUILD_GRID_VIEW
689- model = GTK_LIST_STORE (gtk_icon_view_get_model (GTK_ICON_VIEW (view)));
690-#else
691- model = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (view)));
692-#endif
693-
694- gtk_list_store_prepend (model, &new_row);
695- gtk_list_store_set (model, &new_row,
696- CONTACTS_VIEW_COLUMN_NAME, contact_name,
697- CONTACTS_VIEW_COLUMN_MARKUP, contact_markedup_name,
698- CONTACTS_VIEW_COLUMN_EMAIL, contact_email,
699- CONTACTS_VIEW_COLUMN_PIXBUF, pixbuf,
700- CONTACTS_VIEW_COLUMN_RECENT, TRUE,
701- -1);
702-
703-#ifdef BUILD_GRID_VIEW
704- gtk_icon_view_select_path (GTK_ICON_VIEW (view),
705- gtk_tree_model_get_path (GTK_TREE_MODEL (model), &new_row));
706-#else
707- gtk_tree_selection_select_path (
708- gtk_tree_view_get_selection (GTK_TREE_VIEW (view)),
709- gtk_tree_model_get_path (GTK_TREE_MODEL (model), &new_row));
710-#endif
711-}
712-
713-static void
714-foreach_selected_to_model_cb (gpointer key, gpointer value, gpointer user_data)
715-{
716- SelectedContactInfo *sci = (SelectedContactInfo *) value;
717- ContactsView *cv = CONTACTS_VIEW (user_data);
718-
719- if (g_hash_table_lookup (cv->selection, sci->name) != NULL)
720- return;
721-
722- append_selected_to_model (cv->contacts_list, sci->name, sci->markedup_name, sci->email, sci->pixbuf);
723-}
724-
725-typedef struct {
726- ContactsView *cv;
727- GHashTable *selection_hash;
728- EBookQuery *query;
729- gchar *search_string;
730-} GetContactsCallbackData;
731-
732-static void
733-got_contacts_cb (EBook *book, EBookStatus status, GList *contacts, gpointer user_data)
734-{
735- GetContactsCallbackData *gccd = user_data;
736-
737- if (status == E_BOOK_ERROR_OK) {
738- add_contacts (gccd->cv, contacts, gccd->selection_hash, gccd->search_string);
739- if (gccd->selection_hash != gccd->cv->selection) {
740- /* If it's a separate selection, add all contacts to the views */
741- g_hash_table_foreach (gccd->selection_hash, (GHFunc) foreach_selected_to_model_cb, gccd->cv);
742- g_hash_table_unref (gccd->selection_hash);
743- }
744- } else {
745- g_warning ("Error retrieving contacts from addressbook %s: %d",
746- e_book_get_uri (book), status);
747- }
748-
749- e_book_query_unref (gccd->query);
750- g_free (gccd->search_string);
751- g_free (gccd);
752-}
753-
754-static void
755-retrieve_contacts (ContactsView *cv, EBook *book, const gchar *search_string, GHashTable *selection_hash)
756-{
757- GetContactsCallbackData *gccd;
758-
759- gccd = g_new0 (GetContactsCallbackData, 1);
760- gccd->cv = cv;
761- gccd->query = e_book_query_any_field_contains (search_string);
762- gccd->search_string = g_strdup (search_string);
763- if (selection_hash == cv->selection)
764- gccd->selection_hash = selection_hash;
765- else
766- gccd->selection_hash = g_hash_table_ref (selection_hash);
767-
768- e_book_async_get_contacts (book, gccd->query, (EBookListCallback) got_contacts_cb, gccd);
769-}
770-
771-static void
772-book_opened_cb (EBook *book, EBookStatus status, gpointer user_data)
773-{
774- ContactsView *cv = CONTACTS_VIEW (user_data);
775-
776- if (status != E_BOOK_ERROR_OK) {
777- g_warning ("Error opening addressbook %s: %d", e_book_get_uri (book), status);
778- g_object_unref (G_OBJECT (book));
779- return;
780- }
781-
782- /* Add the book to the list of opened books */
783- cv->books = g_slist_append (cv->books, book);
784-
785- /* Get all contacts for this book */
786- retrieve_contacts (cv, book, "", cv->selection);
787-}
788-
789-static void
790-free_selected_contact_info (gpointer data)
791-{
792- SelectedContactInfo *sci = (SelectedContactInfo *) data;
793-
794- if (sci != NULL) {
795- if (sci->name != NULL)
796- g_free (sci->name);
797- if (sci->markedup_name != NULL)
798- g_free (sci->markedup_name);
799- if (sci->email != NULL)
800- g_free (sci->email);
801- if (sci->pixbuf != NULL)
802- g_object_unref (sci->pixbuf);
803-
804- g_free (sci);
805- }
806-}
807-
808-static gboolean
809-row_separator_func (GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
810-{
811- gboolean current_is_recent, other_is_recent;
812- GtkTreePath *path;
813- gboolean result = FALSE;
814-
815- gtk_tree_model_get (model, iter,
816- CONTACTS_VIEW_COLUMN_RECENT, &current_is_recent,
817- -1);
818-
819- path = gtk_tree_model_get_path (model, iter);
820- if (path != NULL) {
821- if (gtk_tree_path_prev (path)) {
822- GtkTreeIter previous;
823-
824- if (gtk_tree_model_get_iter (model, &previous, path)) {
825- gtk_tree_model_get (model, &previous,
826- CONTACTS_VIEW_COLUMN_RECENT, &other_is_recent,
827- -1);
828- if (other_is_recent && !current_is_recent)
829- result = TRUE;
830- }
831- }
832-
833- gtk_tree_path_free (path);
834- }
835-
836- return result;
837-}
838-
839-static void
840-contacts_view_init (ContactsView *cv)
841-{
842- GtkTreeModel *model;
843- GError *error = NULL;
844- GSList *gl;
845-
846- cv->matched_contacts = 0;
847- cv->selection = g_hash_table_new_full (g_str_hash, g_str_equal,
848- (GDestroyNotify) g_free,
849- (GDestroyNotify) free_selected_contact_info);
850- cv->added_contacts = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
851-
852- /* Get recently used contacts */
853- cv->recently_used = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) g_free, NULL);
854-
855-#ifdef HAVE_NAUTILUS_30
856- cv->settings = g_settings_new (SETTINGS_DOMAIN);
857- {
858- gchar **strv;
859-
860- strv = g_settings_get_strv (cv->settings, SETTINGS_CONTACTS_KEY);
861- gl = e_client_util_strv_to_slist ((const gchar * const *) strv);
862- g_strfreev (strv);
863- }
864-#else
865- cv->config_client = gconf_client_get_default ();
866- gl = gconf_client_get_list (cv->config_client, RECENTLY_USED_CONTACTS_KEY, GCONF_VALUE_STRING, NULL);
867-#endif
868- for (; gl != NULL; gl = gl->next) {
869- g_hash_table_insert (cv->recently_used, g_strdup (gl->data), g_strdup (gl->data));
870- }
871- g_slist_free (gl);
872-
873- /* Set up the scrolled window */
874- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (cv),
875- GTK_POLICY_AUTOMATIC,
876- GTK_POLICY_AUTOMATIC);
877-
878- /* Create the contacts list */
879- model = GTK_TREE_MODEL (gtk_list_store_new (5, G_TYPE_STRING,
880- G_TYPE_STRING,
881- G_TYPE_STRING,
882- GDK_TYPE_PIXBUF,
883- G_TYPE_BOOLEAN,
884- NULL));
885-
886-#ifdef BUILD_GRID_VIEW
887- cv->contacts_list = gtk_icon_view_new_with_model (model);
888- gtk_icon_view_set_text_column (GTK_ICON_VIEW (cv->contacts_list), CONTACTS_VIEW_COLUMN_NAME);
889- gtk_icon_view_set_markup_column (GTK_ICON_VIEW (cv->contacts_list), CONTACTS_VIEW_COLUMN_MARKUP);
890- gtk_icon_view_set_pixbuf_column (GTK_ICON_VIEW (cv->contacts_list), CONTACTS_VIEW_COLUMN_PIXBUF);
891- gtk_icon_view_set_selection_mode (GTK_ICON_VIEW (cv->contacts_list), GTK_SELECTION_MULTIPLE);
892- gtk_icon_view_set_item_width (GTK_ICON_VIEW (cv->contacts_list), 90);
893-
894- g_signal_connect (G_OBJECT (cv->contacts_list), "selection-changed",
895- G_CALLBACK (selection_changed_cb), cv);
896-#else
897- cv->contacts_list = gtk_tree_view_new_with_model (model);
898- gtk_tree_view_set_row_separator_func (GTK_TREE_VIEW (cv->contacts_list),
899- (GtkTreeViewRowSeparatorFunc) row_separator_func,
900- cv, NULL);
901- gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (cv->contacts_list), FALSE);
902- gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (cv->contacts_list), -1,
903- "Avatar",
904- gtk_cell_renderer_pixbuf_new (),
905- "pixbuf", CONTACTS_VIEW_COLUMN_PIXBUF,
906- NULL);
907- gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (cv->contacts_list), -1,
908- "Name",
909- gtk_cell_renderer_text_new (),
910- "markup", CONTACTS_VIEW_COLUMN_MARKUP,
911- NULL);
912- gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (cv->contacts_list)),
913- GTK_SELECTION_MULTIPLE);
914-
915- g_signal_connect (G_OBJECT (gtk_tree_view_get_selection (GTK_TREE_VIEW (cv->contacts_list))), "changed",
916- G_CALLBACK (selection_changed_cb), cv);
917-#endif
918-
919- gtk_widget_show (cv->contacts_list);
920- gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (cv), cv->contacts_list);
921-
922- /* Open all addressbooks */
923- if (!e_book_get_addressbooks (&cv->source_list, &error)) {
924- g_warning ("Could not get list of addressbooks: %s", error->message);
925- g_error_free (error);
926-
927- return;
928- }
929-
930- for (gl = e_source_list_peek_groups (cv->source_list); gl != NULL; gl = gl->next) {
931- GSList *sl;
932-
933- for (sl = e_source_group_peek_sources ((ESourceGroup *) gl->data); sl != NULL; sl = sl->next) {
934- EBook *book;
935-
936- error = NULL;
937-
938- /* Open this addressbook asynchronously */
939- book = e_book_new ((ESource *) sl->data, &error);
940- if (book != NULL) {
941- e_book_async_open (book, FALSE, (EBookCallback) book_opened_cb, cv);
942- } else {
943- g_warning ("Could not open addressbook %s: %s", e_source_get_uri (sl->data), error->message);
944- g_error_free (error);
945- }
946- }
947- }
948-}
949-
950-GtkWidget *
951-contacts_view_new (void)
952-{
953- return g_object_new (TYPE_CONTACTS_VIEW, NULL);
954-}
955-
956-void
957-contacts_view_search (ContactsView *cv, const gchar *search_string)
958-{
959- GSList *l;
960- GHashTable *tmp_selection;
961- GHashTableIter hash_iter;
962- gpointer key, value;
963- GtkTreeModel *model;
964-
965- /* Make a copy of the selected items before changing the models */
966- tmp_selection = g_hash_table_new_full (g_str_hash, g_str_equal,
967- (GDestroyNotify) g_free,
968- (GDestroyNotify) free_selected_contact_info);
969- g_hash_table_iter_init (&hash_iter, cv->selection);
970- while (g_hash_table_iter_next (&hash_iter, &key, &value)) {
971- SelectedContactInfo *new_sci, *old_sci;
972-
973- old_sci = (SelectedContactInfo *) value;
974-
975- new_sci = g_new0 (SelectedContactInfo, 1);
976- new_sci->name = g_strdup (old_sci->name);
977- new_sci->markedup_name = g_markup_escape_text (old_sci->name, -1);
978- new_sci->email = g_strdup (old_sci->email);
979- new_sci->pixbuf = g_object_ref (old_sci->pixbuf);
980- g_hash_table_insert (tmp_selection, g_strdup (old_sci->name), new_sci);
981- }
982-
983- /* Reset the contact views */
984-#ifdef BUILD_GRID_VIEW
985- model = gtk_icon_view_get_model (GTK_ICON_VIEW (cv->contacts_list));
986-#else
987- model = gtk_tree_view_get_model (GTK_TREE_VIEW (cv->contacts_list));
988- gtk_tree_view_scroll_to_point (GTK_TREE_VIEW (cv->contacts_list), 0, 0);
989-#endif
990- gtk_list_store_clear (GTK_LIST_STORE (model));
991- cv->matched_contacts = 0;
992-
993- g_signal_emit_by_name (cv, "contacts-count-changed",
994- gtk_tree_model_iter_n_children (model, NULL));
995-
996- /* Traverse all books */
997- for (l = cv->books; l != NULL; l = l->next) {
998- EBook *book = E_BOOK (l->data);
999-
1000- if (!e_book_is_opened (book))
1001- continue;
1002-
1003- /* Cancel any pending operation before starting the new one*/
1004- e_book_cancel (book, NULL);
1005- retrieve_contacts (cv, book, search_string, tmp_selection);
1006- }
1007-
1008- /* If we added contacts in-memory, add them to the model now */
1009- g_hash_table_iter_init (&hash_iter, cv->added_contacts);
1010- while (g_hash_table_iter_next (&hash_iter, &key, &value)) {
1011- gchar *markup;
1012-
1013- /* We only add it if it's not on the other lists */
1014- if (!g_hash_table_lookup (tmp_selection, key)) {
1015- markup = g_markup_escape_text ((const gchar *) key, -1);
1016- add_one_contact (cv, (const gchar *) key,
1017- (const gchar *) markup,
1018- (const gchar *) value,
1019- NULL, tmp_selection);
1020- g_free (markup);
1021- }
1022- }
1023-
1024- g_hash_table_unref (tmp_selection);
1025-}
1026-
1027-static void
1028-add_selection_to_list_cb (gpointer key, gpointer value, gpointer user_data)
1029-{
1030- SelectedContactInfo *sci = (SelectedContactInfo *) value;
1031- GSList **selection = (GSList **) user_data;
1032-
1033- *selection = g_slist_append (*selection, g_strdup (sci->email));
1034-}
1035-
1036-GSList *
1037-contacts_view_get_selected_emails (ContactsView *cv)
1038-{
1039- GSList *selection = NULL;
1040-
1041- g_hash_table_foreach (cv->selection, (GHFunc) add_selection_to_list_cb, &selection);
1042- return selection;
1043-}
1044-
1045-guint
1046-contacts_view_get_contacts_count (ContactsView *cv)
1047-{
1048- GtkTreeModel *model;
1049-
1050-#ifdef BUILD_GRID_VIEW
1051- model = gtk_icon_view_get_model (GTK_ICON_VIEW (cv->contacts_list));
1052-#else
1053- model = gtk_tree_view_get_model (GTK_TREE_VIEW (cv->contacts_list));
1054-#endif
1055-
1056- return gtk_tree_model_iter_n_children (model, NULL);
1057-}
1058-
1059-guint
1060-contacts_view_get_matched_contacts_count (ContactsView *cv)
1061-{
1062- return cv->matched_contacts;
1063-}
1064-
1065-void
1066-contacts_view_add_contact (ContactsView *cv, const gchar *contact_name, const gchar *contact_email)
1067-{
1068- SelectedContactInfo *sci;
1069- GtkIconTheme *icon_theme;
1070- GSList *l;
1071- gchar *s;
1072- GdkPixbuf *pixbuf;
1073- gboolean added = FALSE;
1074-
1075- icon_theme = gtk_icon_theme_get_default ();
1076-
1077- /* First add the new contact to the list of selected ones */
1078- sci = g_new0 (SelectedContactInfo, 1);
1079- sci->name = g_strdup (contact_name);
1080- sci->markedup_name = g_markup_escape_text (contact_name, -1);
1081- sci->email = g_strdup (contact_email);
1082- pixbuf = gtk_icon_theme_load_icon (icon_theme, "avatar-default", AVATAR_SIZE, 0, NULL);
1083- sci->pixbuf = g_object_ref (pixbuf);
1084- g_hash_table_insert (cv->selection, g_strdup (contact_name), sci);
1085-
1086- /* Add it to the recently used list */
1087- s = g_strdup (sci->name);
1088- g_hash_table_insert (cv->recently_used, s, s);
1089- save_recently_used_list (cv);
1090-
1091- /* And now add it to the icon views */
1092- append_selected_to_model (cv->contacts_list, contact_name, sci->markedup_name, contact_email, pixbuf);
1093-
1094- g_object_unref (pixbuf);
1095-
1096- /* Add the contact to the CouchDB addressbook, if possible */
1097- for (l = cv->books; l != NULL; l = l->next) {
1098- const gchar *uri;
1099-
1100- uri = e_book_get_uri (E_BOOK (l->data));
1101- if (g_str_has_prefix (uri, "couchdb://127.0.0.1")) {
1102- EContact *contact;
1103- GError *error = NULL;
1104-
1105- contact = e_contact_new ();
1106- e_contact_set (contact, E_CONTACT_FULL_NAME, (gconstpointer) contact_name);
1107- e_contact_set (contact, E_CONTACT_EMAIL_1, (gconstpointer) contact_email);
1108-
1109- if (e_book_add_contact (E_BOOK (l->data), contact, &error))
1110- added = TRUE;
1111- else {
1112- g_warning ("Could not add contact to %s: %s", uri, error->message);
1113- g_error_free (error);
1114- }
1115-
1116- g_object_unref (G_OBJECT (contact));
1117-
1118- break;
1119- }
1120- }
1121-
1122- /* If the contact was not added, keep a copy of it so that it shows */
1123- if (!added)
1124- g_hash_table_insert (cv->added_contacts, g_strdup (contact_name), g_strdup (contact_email));
1125-}
1126
1127=== removed file 'nautilus/contacts-view.h'
1128--- nautilus/contacts-view.h 2011-09-23 15:31:01 +0000
1129+++ nautilus/contacts-view.h 1970-01-01 00:00:00 +0000
1130@@ -1,81 +0,0 @@
1131-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
1132-/*
1133- * Copyright (C) 2009 Canonical Services Ltd (www.canonical.com)
1134- *
1135- * Authors: Rodrigo Moya <rodrigo.moya@canonical.com>
1136- *
1137- * This library is free software; you can redistribute it and/or
1138- * modify it under the terms of version 2 of the GNU Lesser General Public
1139- * License as published by the Free Software Foundation.
1140- *
1141- * This program is distributed in the hope that it will be useful,
1142- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1143- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1144- * General Public License for more details.
1145- *
1146- * You should have received a copy of the GNU Lesser General Public
1147- * License along with this library; if not, write to the
1148- * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
1149- * Boston, MA 02110-1301, USA.
1150- */
1151-
1152-#ifndef __CONTACTS_VIEW_H__
1153-#define __CONTACTS_VIEW_H__
1154-
1155-#include <gtk/gtk.h>
1156-#include <libedataserver/e-source-list.h>
1157-#include <libebook/e-book.h>
1158-#ifdef HAVE_NAUTILUS_30
1159-#include <gio/gio.h>
1160-#include <libedataserver/e-client.h>
1161-#else
1162-#include <gconf/gconf-client.h>
1163-#endif
1164-
1165-#define TYPE_CONTACTS_VIEW (contacts_view_get_type ())
1166-#define CONTACTS_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_CONTACTS_VIEW, ContactsView))
1167-#define IS_CONTACTS_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_CONTACTS_VIEW))
1168-#define CONTACTS_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_CONTACTS_VIEW, ContactsViewClass))
1169-#define IS_CONTACTS_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_CONTACTS_VIEW))
1170-#define CONTACTS_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_CONTACTS_VIEW, ContactsViewClass))
1171-
1172-typedef struct {
1173- GtkScrolledWindow parent;
1174-
1175-#ifdef HAVE_NAUTILUS_30
1176- GSettings *settings;
1177-#else
1178- GConfClient *config_client;
1179-#endif
1180-
1181- /* Data from addressbooks */
1182- ESourceList *source_list;
1183- GSList *books;
1184- GHashTable *selection;
1185- GHashTable *recently_used;
1186- GHashTable *added_contacts;
1187-
1188- /* Widgets */
1189- GtkWidget *contacts_list;
1190-
1191- guint matched_contacts;
1192-} ContactsView;
1193-
1194-typedef struct {
1195- GtkScrolledWindowClass parent_class;
1196-
1197- /* Signals */
1198- void (* selection_changed) (ContactsView *cv);
1199- void (* contacts_count_changed) (ContactsView *cv, gint total);
1200-} ContactsViewClass;
1201-
1202-GType contacts_view_get_type (void);
1203-
1204-GtkWidget *contacts_view_new (void);
1205-void contacts_view_search (ContactsView *cv, const gchar *search_string);
1206-GSList *contacts_view_get_selected_emails (ContactsView *cv);
1207-guint contacts_view_get_contacts_count (ContactsView *cv);
1208-guint contacts_view_get_matched_contacts_count (ContactsView *cv);
1209-void contacts_view_add_contact (ContactsView *cv, const gchar *contact_name, const gchar *contact_email);
1210-
1211-#endif
1212
1213=== removed file 'nautilus/highlight.c'
1214--- nautilus/highlight.c 2011-07-20 20:44:39 +0000
1215+++ nautilus/highlight.c 1970-01-01 00:00:00 +0000
1216@@ -1,162 +0,0 @@
1217-/*
1218- * Ubuntu One Nautilus plugin
1219- *
1220- * Authors: Alejandro J. Cura <alecu@canonical.com>
1221- *
1222- * Copyright 2010 Canonical Ltd.
1223- *
1224- * This program is free software: you can redistribute it and/or modify it
1225- * under the terms of the GNU General Public License version 3, as published
1226- * by the Free Software Foundation.
1227- *
1228- * This program is distributed in the hope that it will be useful, but
1229- * WITHOUT ANY WARRANTY; without even the implied warranties of
1230- * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
1231- * PURPOSE. See the GNU General Public License for more details.
1232- *
1233- * You should have received a copy of the GNU General Public License along
1234- * with this program. If not, see <http://www.gnu.org/licenses/>.
1235- *
1236- */
1237-
1238-#include <string.h>
1239-#include <glib.h>
1240-
1241-static gint
1242-compare_glongs (gconstpointer a,
1243- gconstpointer b,
1244- gpointer user_data)
1245-{
1246- return (glong) a - (glong) b;
1247-}
1248-
1249-
1250-static void
1251-tree_of_arrays_insert (GTree *tree,
1252- gpointer key,
1253- gpointer value)
1254-{
1255- GPtrArray *array = g_tree_lookup (tree, key);
1256- if (array == NULL) {
1257- array = g_ptr_array_new ();
1258- g_tree_insert (tree, key, array);
1259- }
1260- g_ptr_array_add (array, value);
1261-}
1262-
1263-
1264-static void
1265-destroy_tree_array (gpointer data)
1266-{
1267- g_ptr_array_free (data, TRUE);
1268-}
1269-
1270-typedef struct {
1271- GString *built_string;
1272- gchar *source_string;
1273- gchar *source_cursor;
1274-} BuildResultsData;
1275-
1276-
1277-static void
1278-append_array_strings (gpointer data,
1279- gpointer user_data)
1280-{
1281- g_string_append (user_data, data);
1282-}
1283-
1284-
1285-static gboolean
1286-build_results (gpointer key,
1287- gpointer value,
1288- gpointer data)
1289-{
1290- BuildResultsData* results_data = data;
1291- glong tag_start = (glong)key;
1292- gchar *tag_start_ptr = g_utf8_offset_to_pointer (results_data->source_string,
1293- tag_start);
1294- glong len = tag_start_ptr - results_data->source_cursor;
1295-
1296- gchar *escaped_str = g_markup_escape_text (results_data->source_cursor,
1297- len);
1298-
1299- g_string_append (results_data->built_string,
1300- escaped_str);
1301- g_free (escaped_str);
1302- results_data->source_cursor += len;
1303-
1304- g_ptr_array_foreach (value,
1305- append_array_strings,
1306- results_data->built_string);
1307- return FALSE;
1308-}
1309-
1310-
1311-gchar *
1312-highlight_result(gchar *needles, gchar *haystack)
1313-{
1314- gchar **split_needles;
1315- GTree *result_parts;
1316- gchar *folded_needles;
1317- gchar *folded_haystack;
1318- gchar **needle;
1319- gchar *escaped_str;
1320- BuildResultsData results_data;
1321-
1322- folded_needles = g_utf8_casefold (needles, -1);
1323- folded_haystack = g_utf8_casefold (haystack, -1);
1324-
1325- results_data.built_string = g_string_new ("");
1326- results_data.source_string = haystack;
1327- results_data.source_cursor = haystack;
1328-
1329- result_parts = g_tree_new_full (compare_glongs,
1330- NULL,
1331- NULL,
1332- destroy_tree_array);
1333-
1334- split_needles = g_strsplit (folded_needles, " ", 0);
1335- needle = split_needles;
1336- while (*needle != NULL) {
1337- gchar *search_start;
1338- gchar *start_ptr;
1339- glong needle_len = g_utf8_strlen (*needle, -1);
1340- if (needle_len < 1) {
1341- needle++;
1342- continue;
1343- }
1344- search_start = folded_haystack;
1345- start_ptr = g_strstr_len (search_start, -1, *needle);
1346- while (start_ptr != NULL) {
1347- glong start = g_utf8_pointer_to_offset (folded_haystack,
1348- start_ptr);
1349- glong end = start + g_utf8_strlen (*needle, -1);
1350- tree_of_arrays_insert (result_parts,
1351- (gpointer) start,
1352- "<b>");
1353- tree_of_arrays_insert (result_parts,
1354- (gpointer) end,
1355- "</b>");
1356- search_start = g_utf8_next_char (start_ptr);
1357- start_ptr = g_strstr_len (search_start,
1358- -1,
1359- *needle);
1360- }
1361- needle++;
1362- }
1363- g_free (folded_needles);
1364- g_free (folded_haystack);
1365-
1366-
1367- g_tree_foreach (result_parts, build_results, &results_data);
1368-
1369- escaped_str = g_markup_escape_text (results_data.source_cursor, -1);
1370- g_string_append (results_data.built_string,
1371- escaped_str);
1372- g_free (escaped_str);
1373-
1374- g_tree_destroy (result_parts);
1375- g_strfreev (split_needles);
1376- return g_string_free (results_data.built_string,
1377- FALSE);
1378-}
1379
1380=== removed file 'nautilus/highlight.h'
1381--- nautilus/highlight.h 2011-07-20 20:44:39 +0000
1382+++ nautilus/highlight.h 1970-01-01 00:00:00 +0000
1383@@ -1,29 +0,0 @@
1384-/*
1385- * Ubuntu One Nautilus plugin
1386- *
1387- * Authors: Alejandro J. Cura <alecu@canonical.com>
1388- *
1389- * Copyright 2010 Canonical Ltd.
1390- *
1391- * This program is free software: you can redistribute it and/or modify it
1392- * under the terms of the GNU General Public License version 3, as published
1393- * by the Free Software Foundation.
1394- *
1395- * This program is distributed in the hope that it will be useful, but
1396- * WITHOUT ANY WARRANTY; without even the implied warranties of
1397- * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
1398- * PURPOSE. See the GNU General Public License for more details.
1399- *
1400- * You should have received a copy of the GNU General Public License along
1401- * with this program. If not, see <http://www.gnu.org/licenses/>.
1402- *
1403- */
1404-
1405-#ifndef __HIGHLIGHT_H__
1406-#define __HIGHLIGHT_H__
1407-
1408-#include <glib.h>
1409-
1410-gchar *highlight_result(gchar *search_string, gchar *result);
1411-
1412-#endif
1413
1414=== modified file 'nautilus/share-dialog.c'
1415--- nautilus/share-dialog.c 2011-09-21 19:19:18 +0000
1416+++ nautilus/share-dialog.c 2012-08-30 19:02:18 +0000
1417@@ -26,7 +26,6 @@
1418 #include <glib/gi18n-lib.h>
1419 #include <libsyncdaemon/libsyncdaemon.h>
1420 #include "share-dialog.h"
1421-#include "u1-contacts-picker.h"
1422
1423 G_DEFINE_TYPE(ShareDialog, share_dialog, GTK_TYPE_DIALOG)
1424
1425@@ -50,54 +49,45 @@
1426 }
1427
1428 static void
1429-picker_selection_changed_cb (U1ContactsPicker *picker, gpointer user_data)
1430-{
1431- GSList *selection;
1432- GtkWidget * dialog = (GtkWidget *) user_data;
1433-
1434- selection = u1_contacts_picker_get_selected_emails (picker);
1435- if (selection != NULL) {
1436- gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT, TRUE);
1437- u1_contacts_picker_free_selection_list (selection);
1438- } else
1439- gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT, FALSE);
1440-}
1441-
1442-static void
1443 dialog_response_cb (GtkDialog *gtk_dialog,
1444- gint response,
1445- gpointer user_data)
1446+ gint response,
1447+ gpointer user_data)
1448 {
1449 ShareDialog *dialog = SHARE_DIALOG (gtk_dialog);
1450
1451 switch (response) {
1452 case GTK_RESPONSE_ACCEPT: {
1453- GSList *emails;
1454- SyncdaemonSharesInterface *interface;
1455- gboolean allow_mods = FALSE;
1456-
1457- emails = u1_contacts_picker_get_selected_emails (U1_CONTACTS_PICKER (dialog->user_picker));
1458- if (emails == NULL) {
1459- ubuntuone_show_error_dialog (dialog->uon,
1460- _("Error"),
1461- _("You need to select at least one contact to share this folder with"));
1462-
1463- return;
1464- }
1465-
1466- allow_mods = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->allow_mods));
1467-
1468- interface = SYNCDAEMON_SHARES_INTERFACE (syncdaemon_daemon_get_shares_interface (dialog->uon->syncdaemon));
1469- if (interface != NULL) {
1470- syncdaemon_shares_interface_create (interface,
1471- dialog->path,
1472- emails,
1473- g_path_get_basename (dialog->path),
1474- allow_mods);
1475- }
1476-
1477- u1_contacts_picker_free_selection_list (emails);
1478- }
1479+ const gchar *entry_data;
1480+
1481+ entry_data = gtk_entry_get_text (GTK_ENTRY (dialog->user_picker));
1482+ if (entry_data != NULL && strlen (entry_data) > 0) {
1483+ SyncdaemonSharesInterface *interface;
1484+ gchar **email_entries;
1485+ GSList *emails = NULL;
1486+ gboolean allow_mods = FALSE;
1487+ gint i;
1488+
1489+ email_entries = g_strsplit (entry_data, ",", -1);
1490+ for (i = 0; email_entries[i] != NULL; i++) {
1491+ const gchar *email = g_strstrip (email_entries[i]);
1492+ emails = g_slist_prepend (emails, g_strdup (email));
1493+ }
1494+ g_strfreev (email_entries);
1495+
1496+ if (emails != NULL && g_slist_length (emails) > 0) {
1497+ allow_mods = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->allow_mods));
1498+
1499+ interface = SYNCDAEMON_SHARES_INTERFACE (syncdaemon_daemon_get_shares_interface (dialog->uon->syncdaemon));
1500+ if (interface != NULL) {
1501+ syncdaemon_shares_interface_create (interface,
1502+ dialog->path,
1503+ emails,
1504+ g_path_get_basename (dialog->path),
1505+ allow_mods);
1506+ }
1507+ }
1508+ }
1509+ }
1510 default:
1511 gtk_widget_destroy (GTK_WIDGET (dialog));
1512 break;
1513@@ -107,7 +97,7 @@
1514 static void
1515 share_dialog_init (ShareDialog *dialog)
1516 {
1517- GtkWidget *area, *table;
1518+ GtkWidget *area, *table, *hbox, *label;
1519
1520 gtk_window_set_title (GTK_WINDOW (dialog), _("Share on Ubuntu One"));
1521 gtk_window_set_destroy_with_parent (GTK_WINDOW (dialog), TRUE);
1522@@ -116,8 +106,6 @@
1523 (_("Share")), GTK_RESPONSE_ACCEPT,
1524 NULL);
1525 gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
1526- gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog),
1527- GTK_RESPONSE_ACCEPT, FALSE);
1528 gtk_window_set_icon_name (GTK_WINDOW (dialog), "ubuntuone");
1529 g_signal_connect (G_OBJECT (dialog), "response",
1530 G_CALLBACK (dialog_response_cb), NULL);
1531@@ -129,11 +117,25 @@
1532 gtk_box_pack_start (GTK_BOX (area), table, TRUE, TRUE, 0);
1533 gtk_widget_show (table);
1534
1535- dialog->user_picker = u1_contacts_picker_new ();
1536- g_signal_connect (G_OBJECT (dialog->user_picker), "selection-changed",
1537- G_CALLBACK (picker_selection_changed_cb), dialog);
1538- gtk_box_pack_start (GTK_BOX (table), dialog->user_picker, TRUE, TRUE, 0);
1539- gtk_widget_show (dialog->user_picker);
1540+ /* entry here maybe */
1541+ hbox = gtk_hbox_new (FALSE, 12);
1542+ gtk_box_pack_start (GTK_BOX (table), hbox, FALSE, FALSE, 0);
1543+ gtk_widget_show (hbox);
1544+
1545+ label = gtk_label_new_with_mnemonic (_("_Email:"));
1546+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
1547+ gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
1548+ gtk_widget_show (label);
1549+
1550+ dialog->user_picker = gtk_entry_new ();
1551+ gtk_widget_set_tooltip_text (dialog->user_picker,
1552+ _("Type an email address to share this "
1553+ "folder with. Use a comma to separate "
1554+ "multiple addresses."));
1555+ gtk_label_set_mnemonic_widget (GTK_LABEL (label), dialog->user_picker);
1556+ gtk_entry_set_activates_default (GTK_ENTRY (dialog->user_picker), TRUE);
1557+ gtk_box_pack_start (GTK_BOX (hbox), dialog->user_picker, TRUE, TRUE, 0);
1558+ gtk_widget_show (dialog->user_picker);
1559
1560 dialog->allow_mods = gtk_check_button_new_with_mnemonic (_("_Allow Modification"));
1561 /* Default to RW */
1562@@ -142,7 +144,7 @@
1563 gtk_box_pack_end (GTK_BOX (table), dialog->allow_mods, FALSE, FALSE, 0);
1564 gtk_widget_show (dialog->allow_mods);
1565
1566- gtk_widget_set_size_request (GTK_WIDGET (dialog), 500, 450);
1567+ gtk_widget_set_size_request (GTK_WIDGET (dialog), 320, -1);
1568 }
1569
1570 GtkWidget *
1571
1572=== removed file 'nautilus/test-contacts-picker.c'
1573--- nautilus/test-contacts-picker.c 2011-12-12 08:54:39 +0000
1574+++ nautilus/test-contacts-picker.c 1970-01-01 00:00:00 +0000
1575@@ -1,98 +0,0 @@
1576-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
1577-/*
1578- * Copyright (C) 2009 Canonical Services Ltd (www.canonical.com)
1579- *
1580- * Authors: Rodrigo Moya <rodrigo.moya@canonical.com>
1581- *
1582- * This library is free software; you can redistribute it and/or
1583- * modify it under the terms of version 2 of the GNU Lesser General Public
1584- * License as published by the Free Software Foundation.
1585- *
1586- * This program is distributed in the hope that it will be useful,
1587- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1588- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1589- * General Public License for more details.
1590- *
1591- * You should have received a copy of the GNU Lesser General Public
1592- * License along with this library; if not, write to the
1593- * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
1594- * Boston, MA 02110-1301, USA.
1595- */
1596-
1597-#include "u1-contacts-picker.h"
1598-
1599-static void
1600-dialog_response_cb (GtkDialog *dialog, gint response_id, gpointer data)
1601-{
1602- GtkWidget *picker = GTK_WIDGET (data);
1603-
1604- if (response_id == GTK_RESPONSE_OK) {
1605- GSList *selection, *l;
1606- GtkWidget *msg_dialog;
1607- GString *str = NULL;
1608-
1609- selection = u1_contacts_picker_get_selected_emails (U1_CONTACTS_PICKER (picker));
1610- for (l = selection; l != NULL; l = l->next) {
1611- if (str == NULL) {
1612- str = g_string_new ("Selected items:\n\t");
1613- str = g_string_append (str, (const gchar *) l->data);
1614- } else {
1615- str = g_string_append (str, "\n\t");
1616- str = g_string_append (str, (const gchar *) l->data);
1617- }
1618- }
1619-
1620- u1_contacts_picker_free_selection_list (selection);
1621-
1622- /* Display selection to the user */
1623- if (str != NULL) {
1624- msg_dialog = gtk_message_dialog_new (GTK_WINDOW (dialog),
1625- 0,
1626- GTK_MESSAGE_INFO,
1627- GTK_BUTTONS_OK,
1628- "%s", str->str);
1629- g_string_free (str, FALSE);
1630- } else {
1631- msg_dialog = gtk_message_dialog_new (GTK_WINDOW (dialog),
1632- 0,
1633- GTK_MESSAGE_INFO,
1634- GTK_BUTTONS_OK,
1635- "Nothing has been selected");
1636- }
1637-
1638- gtk_dialog_run (GTK_DIALOG (msg_dialog));
1639- }
1640-
1641- gtk_main_quit ();
1642-}
1643-
1644-int
1645-main (int argc, char *argv[])
1646-{
1647- GtkWidget *window, *picker;
1648-
1649- gtk_init (&argc, &argv);
1650- g_type_init();
1651-
1652- /* Create the main window */
1653- window = gtk_dialog_new_with_buttons ("Test contacts picker",
1654- NULL,
1655- 0,
1656- GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
1657- GTK_STOCK_OK, GTK_RESPONSE_OK,
1658- NULL);
1659- gtk_dialog_set_default_response (GTK_DIALOG (window), GTK_RESPONSE_OK);
1660-
1661- picker = u1_contacts_picker_new ();
1662- gtk_widget_show (picker);
1663- gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (window))), picker, TRUE, TRUE, 6);
1664-
1665- g_signal_connect (G_OBJECT (window), "response", G_CALLBACK (dialog_response_cb), picker);
1666-
1667- /* Run the application */
1668- gtk_widget_show (window);
1669- gtk_widget_set_size_request (window, 400, 250);
1670- gtk_main ();
1671-
1672- return 0;
1673-}
1674
1675=== removed file 'nautilus/test-highlight.c'
1676--- nautilus/test-highlight.c 2011-07-20 20:44:39 +0000
1677+++ nautilus/test-highlight.c 1970-01-01 00:00:00 +0000
1678@@ -1,90 +0,0 @@
1679-/*
1680- * Authors: Alejandro J. Cura <alecu@canonical.com>
1681- *
1682- * Copyright 2010 Canonical Ltd.
1683- *
1684- * This program is free software: you can redistribute it and/or modify it
1685- * under the terms of the GNU General Public License version 3, as published
1686- * by the Free Software Foundation.
1687- *
1688- * This program is distributed in the hope that it will be useful, but
1689- * WITHOUT ANY WARRANTY; without even the implied warranties of
1690- * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
1691- * PURPOSE. See the GNU General Public License for more details.
1692- *
1693- * You should have received a copy of the GNU General Public License along
1694- * with this program. If not, see <http://www.gnu.org/licenses/>.
1695- *
1696- */
1697-
1698-#include "highlight.h"
1699-
1700-#include <glib.h>
1701-
1702-#define ASSERT_HIGHLIGHT(a,b,c) \
1703- ret = highlight_result (a, b); \
1704- g_assert_cmpstr (ret, ==, c); \
1705- g_free (ret);
1706-
1707-static void
1708-test_highlight_matches (void)
1709-{
1710- gchar *ret = NULL;
1711- /* match at beginning */
1712- ASSERT_HIGHLIGHT ("john", "john q. public", "<b>john</b> q. public");
1713-
1714- /* match in the middle */
1715- ASSERT_HIGHLIGHT ("john", "andrew john q. public", "andrew <b>john</b> q. public");
1716-
1717- /* no match */
1718- ASSERT_HIGHLIGHT ("john", "andrew q. public", "andrew q. public");
1719-
1720- /* double match */
1721- ASSERT_HIGHLIGHT ("jo sm", "john smith", "<b>jo</b>hn <b>sm</b>ith");
1722- ASSERT_HIGHLIGHT ("john", "john johnson", "<b>john</b> <b>john</b>son");
1723-
1724- /* empty search */
1725- ASSERT_HIGHLIGHT ("", "john q. public", "john q. public");
1726-
1727- /* empty search with entities */
1728- ASSERT_HIGHLIGHT ("", "john & public", "john &amp; public");
1729-
1730- /* empty search term */
1731- ASSERT_HIGHLIGHT (" ", "john q. public", "john q. public");
1732-
1733- /* empty result */
1734- ASSERT_HIGHLIGHT ("john", "", "");
1735-
1736- /* case insensitive match */
1737- ASSERT_HIGHLIGHT ("john", "John Smith", "<b>John</b> Smith");
1738- ASSERT_HIGHLIGHT ("john", "Brian JOHNSON", "Brian <b>JOHN</b>SON");
1739- ASSERT_HIGHLIGHT ("br jo", "Brian JOHNSON", "<b>Br</b>ian <b>JO</b>HNSON");
1740-
1741- /* nested match */
1742- ASSERT_HIGHLIGHT ("edward wa", "edward wall", "<b>ed<b>wa</b>rd</b> <b>wa</b>ll");
1743-
1744- /* utf-8 strings */
1745- ASSERT_HIGHLIGHT ("ñandÚ", "Ñandú", "<b>Ñandú</b>");
1746-
1747- /* xml entities in the search */
1748- ASSERT_HIGHLIGHT ("john &", "john sons", "<b>john</b> sons");
1749-
1750- /* xml entities in the result */
1751- ASSERT_HIGHLIGHT ("john sons", "john & sons", "<b>john</b> &amp; <b>sons</b>");
1752-
1753- /* xml entities everywhere */
1754- ASSERT_HIGHLIGHT ("john & sons", "john & sons", "<b>john</b> <b>&amp;</b> <b>sons</b>");
1755-
1756- /* make sure the name of the entities is not highlighted */
1757- ASSERT_HIGHLIGHT ("john amp sons", "john & sons", "<b>john</b> &amp; <b>sons</b>");
1758-}
1759-
1760-int
1761-main (int argc, gchar *argv[])
1762-{
1763- g_test_init (&argc, &argv, NULL);
1764-
1765- g_test_add_func ("/testcontacts/TestHighlightMatches", test_highlight_matches);
1766-
1767- return g_test_run ();
1768-}
1769
1770=== removed file 'nautilus/u1-contacts-picker.c'
1771--- nautilus/u1-contacts-picker.c 2011-08-19 13:36:42 +0000
1772+++ nautilus/u1-contacts-picker.c 1970-01-01 00:00:00 +0000
1773@@ -1,269 +0,0 @@
1774-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
1775-/*
1776- * Copyright (C) 2009 Canonical Services Ltd (www.canonical.com)
1777- *
1778- * Authors: Rodrigo Moya <rodrigo.moya@canonical.com>
1779- *
1780- * This library is free software; you can redistribute it and/or
1781- * modify it under the terms of version 2 of the GNU Lesser General Public
1782- * License as published by the Free Software Foundation.
1783- *
1784- * This program is distributed in the hope that it will be useful,
1785- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1786- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1787- * General Public License for more details.
1788- *
1789- * You should have received a copy of the GNU Lesser General Public
1790- * License along with this library; if not, write to the
1791- * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
1792- * Boston, MA 02110-1301, USA.
1793- */
1794-
1795-#ifdef HAVE_CONFIG_H
1796-#include <config.h>
1797-#endif
1798-
1799-#include <glib/gi18n-lib.h>
1800-#include "u1-contacts-picker.h"
1801-#include "add-contact-dialog.h"
1802-#include "contacts-view.h"
1803-
1804-struct _U1ContactsPickerPrivate {
1805- GtkWidget *search_entry;
1806- GtkWidget *total_label;
1807- GtkWidget *contacts_view;
1808-
1809- /* Hidden widgets to add a new contact */
1810- GtkWidget *add_contact_button;
1811-};
1812-
1813-enum {
1814- SELECTION_CHANGED_SIGNAL,
1815- LAST_SIGNAL
1816-};
1817-
1818-static guint u1_contacts_picker_signals[LAST_SIGNAL] = { 0, };
1819-
1820-G_DEFINE_TYPE(U1ContactsPicker, u1_contacts_picker, GTK_TYPE_VBOX)
1821-
1822-static void
1823-u1_contacts_picker_finalize (GObject *object)
1824-{
1825- U1ContactsPicker *picker = U1_CONTACTS_PICKER (object);
1826-
1827- if (picker->priv != NULL) {
1828- g_free (picker->priv);
1829- picker->priv = NULL;
1830- }
1831-
1832- G_OBJECT_CLASS (u1_contacts_picker_parent_class)->finalize (object);
1833-}
1834-
1835-static void
1836-u1_contacts_picker_class_init (U1ContactsPickerClass *klass)
1837-{
1838- GObjectClass *object_class = G_OBJECT_CLASS (klass);
1839-
1840- object_class->finalize = u1_contacts_picker_finalize;
1841-
1842- /* Register object signals */
1843- u1_contacts_picker_signals[SELECTION_CHANGED_SIGNAL] =
1844- g_signal_new ("selection-changed",
1845- G_TYPE_FROM_CLASS (klass),
1846- (GSignalFlags) G_SIGNAL_RUN_LAST,
1847- G_STRUCT_OFFSET (U1ContactsPickerClass, selection_changed),
1848- NULL,
1849- NULL,
1850- g_cclosure_marshal_VOID__VOID,
1851- G_TYPE_NONE,
1852- 0);
1853-}
1854-
1855-static void
1856-search_activated_cb (GtkEditable *entry, gpointer data)
1857-{
1858- const gchar *text;
1859- U1ContactsPicker *picker = (U1ContactsPicker *) data;
1860-
1861- text = gtk_entry_get_text (GTK_ENTRY (entry));
1862- contacts_view_search (CONTACTS_VIEW (picker->priv->contacts_view), text);
1863-
1864- /* If no contacts, offer the user to add it to the contacts database */
1865- if (contacts_view_get_matched_contacts_count (CONTACTS_VIEW (picker->priv->contacts_view)) == 0 &&
1866- g_strrstr (text, "@") != NULL)
1867- gtk_widget_show (picker->priv->add_contact_button);
1868- else
1869- gtk_widget_hide (picker->priv->add_contact_button);
1870-}
1871-
1872-static void
1873-view_selection_changed_cb (ContactsView *cv, gpointer user_data)
1874-{
1875- U1ContactsPicker *picker = U1_CONTACTS_PICKER (user_data);
1876-
1877- g_signal_emit (picker, u1_contacts_picker_signals[SELECTION_CHANGED_SIGNAL], 0);
1878-}
1879-
1880-static void
1881-contacts_count_changed_cb (ContactsView *cv, gint total, gpointer user_data)
1882-{
1883- gchar *label;
1884- U1ContactsPicker *picker = U1_CONTACTS_PICKER (user_data);
1885-
1886- if (strlen (gtk_entry_get_text (GTK_ENTRY (picker->priv->search_entry))) > 0)
1887- label = g_strdup_printf (g_dngettext (GETTEXT_PACKAGE, "Found %d match", "Found %d matches", total), total);
1888- else
1889- label = g_strdup_printf (g_dngettext (GETTEXT_PACKAGE, "%d contact", "%d contacts", total), total);
1890- gtk_label_set_text (GTK_LABEL (picker->priv->total_label), label);
1891-
1892- g_free (label);
1893-}
1894-
1895-static void
1896-entry_icon_pressed_cb (GtkEntry *entry, GtkEntryIconPosition icon_pos, GdkEventButton *event, gpointer user_data)
1897-{
1898- U1ContactsPicker *picker = U1_CONTACTS_PICKER (user_data);
1899-
1900- if (icon_pos == GTK_ENTRY_ICON_SECONDARY)
1901- gtk_entry_set_text (GTK_ENTRY (picker->priv->search_entry), "");
1902-}
1903-
1904-static void
1905-add_contact_cb (GtkButton *button, gpointer user_data)
1906-{
1907- GtkWidget *dialog;
1908- const gchar *search_text;
1909- U1ContactsPicker *picker = (U1ContactsPicker *) user_data;
1910-
1911- /* Create the dialog */
1912- search_text = gtk_entry_get_text (GTK_ENTRY (picker->priv->search_entry));
1913- dialog = add_contact_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (picker))), search_text);
1914-
1915- /* Run the dialog */
1916- if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
1917- contacts_view_add_contact (CONTACTS_VIEW (picker->priv->contacts_view),
1918- add_contact_dialog_get_name_text (ADD_CONTACT_DIALOG (dialog)),
1919- add_contact_dialog_get_email_text (ADD_CONTACT_DIALOG (dialog)));
1920- gtk_entry_set_text (GTK_ENTRY (picker->priv->search_entry), "");
1921- }
1922-
1923- gtk_widget_destroy (dialog);
1924- gtk_widget_hide (picker->priv->add_contact_button);
1925-}
1926-
1927-static void
1928-u1_contacts_picker_init (U1ContactsPicker *picker)
1929-{
1930- GtkWidget *table;
1931-
1932- picker->priv = g_new0 (U1ContactsPickerPrivate, 1);
1933-
1934- /* Create the table to contain the layout */
1935- table = gtk_table_new (4, 3, FALSE);
1936- gtk_widget_show (table);
1937- gtk_box_pack_start (GTK_BOX (picker), table, TRUE, TRUE, 3);
1938-
1939- /* Create the search area */
1940- picker->priv->search_entry = gtk_entry_new ();
1941- gtk_entry_set_text (GTK_ENTRY (picker->priv->search_entry), _("Type here to search"));
1942- gtk_entry_set_icon_from_stock (GTK_ENTRY (picker->priv->search_entry), GTK_ENTRY_ICON_PRIMARY, GTK_STOCK_FIND);
1943- gtk_entry_set_icon_activatable (GTK_ENTRY (picker->priv->search_entry), GTK_ENTRY_ICON_PRIMARY, FALSE);
1944- gtk_entry_set_icon_tooltip_text (GTK_ENTRY (picker->priv->search_entry),
1945- GTK_ENTRY_ICON_PRIMARY,
1946- _("Type here to search for contacts"));
1947- gtk_entry_set_icon_from_stock (GTK_ENTRY (picker->priv->search_entry), GTK_ENTRY_ICON_SECONDARY, GTK_STOCK_CLEAR);
1948- gtk_entry_set_icon_activatable (GTK_ENTRY (picker->priv->search_entry), GTK_ENTRY_ICON_SECONDARY, TRUE);
1949- gtk_entry_set_icon_tooltip_text (GTK_ENTRY (picker->priv->search_entry),
1950- GTK_ENTRY_ICON_SECONDARY,
1951- _("Click here to clear the search field"));
1952- g_signal_connect (G_OBJECT (picker->priv->search_entry), "icon_press",
1953- G_CALLBACK (entry_icon_pressed_cb), picker);
1954- g_signal_connect (G_OBJECT (picker->priv->search_entry), "changed",
1955- G_CALLBACK (search_activated_cb), picker);
1956- gtk_widget_show (picker->priv->search_entry);
1957- gtk_table_attach (GTK_TABLE (table), picker->priv->search_entry, 0, 1, 0, 1, GTK_FILL, GTK_FILL, 3, 3);
1958-
1959- picker->priv->add_contact_button = gtk_button_new_from_stock (GTK_STOCK_ADD);
1960- g_signal_connect (G_OBJECT (picker->priv->add_contact_button), "clicked",
1961- G_CALLBACK (add_contact_cb), picker);
1962- gtk_table_attach (GTK_TABLE (table), picker->priv->add_contact_button, 1, 2, 0, 1, GTK_FILL, GTK_FILL, 3, 3);
1963-
1964- picker->priv->total_label = gtk_label_new (g_dngettext (GETTEXT_PACKAGE, "0 contact", "0 contacts", 0));
1965- gtk_widget_show (picker->priv->total_label);
1966- gtk_table_attach (GTK_TABLE (table), picker->priv->total_label, 2, 3, 0, 1, GTK_FILL, GTK_FILL, 3, 3);
1967-
1968- /* Create the contacts view */
1969- picker->priv->contacts_view = contacts_view_new ();
1970- g_signal_connect (G_OBJECT (picker->priv->contacts_view), "selection-changed",
1971- G_CALLBACK (view_selection_changed_cb), picker);
1972- g_signal_connect (G_OBJECT (picker->priv->contacts_view), "contacts-count-changed",
1973- G_CALLBACK (contacts_count_changed_cb), picker);
1974- gtk_widget_show (picker->priv->contacts_view);
1975- gtk_table_attach (GTK_TABLE (table), picker->priv->contacts_view, 0, 3, 2, 4,
1976- GTK_FILL | GTK_EXPAND | GTK_SHRINK,
1977- GTK_FILL | GTK_EXPAND | GTK_SHRINK,
1978- 3, 3);
1979-}
1980-
1981-/**
1982- * u1_contacts_picker_new:
1983- *
1984- * Create a new contacts picker widget.
1985- *
1986- * Return value: the newly created widget.
1987- */
1988-GtkWidget *
1989-u1_contacts_picker_new (void)
1990-{
1991- U1ContactsPicker *picker;
1992-
1993- picker = g_object_new (U1_TYPE_CONTACTS_PICKER, NULL);
1994-
1995- return (GtkWidget *) picker;
1996-}
1997-
1998-/**
1999- * u1_contacts_picker_get_contacts_count:
2000- * @picker: A #U1ContactsPicker widget
2001- *
2002- * Return the number of contacts being displayed by the contacts picker.
2003- *
2004- * Return value: Number of contacts being displayed.
2005- */
2006-guint
2007-u1_contacts_picker_get_contacts_count (U1ContactsPicker *picker)
2008-{
2009- g_return_val_if_fail (U1_IS_CONTACTS_PICKER (picker), 0);
2010-
2011- //FIXME: return gtk_tree_model_iter_n_children (gtk_icon_view_get_model (GTK_ICON_VIEW (picker->priv->icon_view)), NULL);
2012- return 0;
2013-}
2014-
2015-/**
2016- * u1_contacts_picker_get_selected_emails:
2017- * @picker: A #U1ContactsPicker widget
2018- *
2019- * Return the list of selected emails in the contacts picker.
2020- *
2021- * Return value: A list of strings containing the email addresses selected.
2022- */
2023-GSList *
2024-u1_contacts_picker_get_selected_emails (U1ContactsPicker *picker)
2025-{
2026- g_return_val_if_fail (U1_IS_CONTACTS_PICKER (picker), NULL);
2027-
2028- return contacts_view_get_selected_emails (CONTACTS_VIEW (picker->priv->contacts_view));
2029-}
2030-
2031-/**
2032- * u1_contacts_picker_free_selection_list:
2033- * @list: The list to free memory of
2034- *
2035- * Free a list returned by @u1_contacts_picker_get_selected_emails.
2036- */
2037-void
2038-u1_contacts_picker_free_selection_list (GSList *list)
2039-{
2040- g_slist_foreach (list, (GFunc) g_free, NULL);
2041- g_slist_free (list);
2042-}
2043
2044=== removed file 'nautilus/u1-contacts-picker.h'
2045--- nautilus/u1-contacts-picker.h 2011-07-20 20:44:39 +0000
2046+++ nautilus/u1-contacts-picker.h 1970-01-01 00:00:00 +0000
2047@@ -1,61 +0,0 @@
2048-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2049-/*
2050- * Copyright (C) 2009 Canonical Services Ltd (www.canonical.com)
2051- *
2052- * Authors: Rodrigo Moya <rodrigo.moya@canonical.com>
2053- *
2054- * This library is free software; you can redistribute it and/or
2055- * modify it under the terms of version 2 of the GNU Lesser General Public
2056- * License as published by the Free Software Foundation.
2057- *
2058- * This program is distributed in the hope that it will be useful,
2059- * but WITHOUT ANY WARRANTY; without even the implied warranty of
2060- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2061- * General Public License for more details.
2062- *
2063- * You should have received a copy of the GNU Lesser General Public
2064- * License along with this library; if not, write to the
2065- * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
2066- * Boston, MA 02110-1301, USA.
2067- */
2068-
2069-#ifndef __U1_CONTACTS_PICKER_H__
2070-#define __U1_CONTACTS_PICKER_H__
2071-
2072-#include <gtk/gtk.h>
2073-
2074-G_BEGIN_DECLS
2075-
2076-#define U1_TYPE_CONTACTS_PICKER (u1_contacts_picker_get_type ())
2077-#define U1_CONTACTS_PICKER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), U1_TYPE_CONTACTS_PICKER, U1ContactsPicker))
2078-#define U1_IS_CONTACTS_PICKER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), U1_TYPE_CONTACTS_PICKER))
2079-#define U1_CONTACTS_PICKER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), U1_TYPE_CONTACTS_PICKER, U1ContactsPickerClass))
2080-#define U1_IS_CONTACTS_PICKER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), U1_TYPE_CONTACTS_PICKER))
2081-#define U1_CONTACTS_PICKER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), U1_TYPE_CONTACTS_PICKER, U1ContactsPickerClass))
2082-
2083-typedef struct _U1ContactsPicker U1ContactsPicker;
2084-typedef struct _U1ContactsPickerClass U1ContactsPickerClass;
2085-typedef struct _U1ContactsPickerPrivate U1ContactsPickerPrivate;
2086-
2087-struct _U1ContactsPicker {
2088- GtkVBox parent;
2089- U1ContactsPickerPrivate *priv;
2090-};
2091-
2092-struct _U1ContactsPickerClass {
2093- GtkVBoxClass parent_class;
2094-
2095- /* Signals */
2096- void (* selection_changed) (U1ContactsPicker *picker);
2097-};
2098-
2099-GType u1_contacts_picker_get_type (void);
2100-
2101-GtkWidget *u1_contacts_picker_new (void);
2102-guint u1_contacts_picker_get_contacts_count (U1ContactsPicker *picker);
2103-GSList *u1_contacts_picker_get_selected_emails (U1ContactsPicker *picker);
2104-void u1_contacts_picker_free_selection_list (GSList *list);
2105-
2106-G_END_DECLS
2107-
2108-#endif
2109
2110=== modified file 'po/POTFILES.in'
2111--- po/POTFILES.in 2012-02-20 16:45:35 +0000
2112+++ po/POTFILES.in 2012-08-30 19:02:18 +0000
2113@@ -1,9 +1,6 @@
2114-nautilus/add-contact-dialog.c
2115 nautilus/ubuntuone-nautilus.c
2116-nautilus/contacts-view.c
2117 nautilus/context-menu.c
2118 nautilus/file-watcher.c
2119-nautilus/u1-contacts-picker.c
2120 nautilus/share-dialog.c
2121 nautilus/utils.c
2122 gsd/gsd-ubuntuone.c

Subscribers

People subscribed via source and target branches

to all changes: