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