]> git.0d.be Git - empathy.git/blob - nautilus-sendto-plugin/empathy-nautilus-sendto.c
Add nautilus-sendto plugin
[empathy.git] / nautilus-sendto-plugin / empathy-nautilus-sendto.c
1 /*
2  * Copyright (C) 2008, 2009 Collabora Ltd.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more av.
13  *
14  * You should have received a copy of the GNU General Public
15  * License along with this program; if not, write to the
16  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA 02110-1301  USA.
18  *
19  * Authors: Jonny Lamb <jonny.lamb@collabora.co.uk>
20  *          Cosimo Cecchi <cosimo.cecchi@collabora.co.uk>
21  */
22
23 #include "config.h"
24
25 #include <glib.h>
26 #include <glib/gi18n-lib.h>
27 #include <gtk/gtk.h>
28 #include <gio/gio.h>
29
30 #include <telepathy-glib/enums.h>
31
32 #include <libempathy/empathy-contact.h>
33 #include <libempathy/empathy-debug.h>
34 #include <libempathy/empathy-contact-manager.h>
35 #include <libempathy/empathy-ft-factory.h>
36 #include <libempathy/empathy-ft-handler.h>
37 #include <libempathy/empathy-tp-file.h>
38 #include <libempathy/empathy-account-manager.h>
39
40 #include <libempathy-gtk/empathy-contact-selector.h>
41 #include <libempathy-gtk/empathy-ui-utils.h>
42
43 #include "nautilus-sendto-plugin.h"
44
45 static EmpathyAccountManager *acc_manager = NULL;
46 static EmpathyFTFactory *factory = NULL;
47 static guint transfers = 0;
48
49 static gboolean destroy (NstPlugin *plugin);
50
51 static void
52 handle_account_manager_ready ()
53 {
54   TpConnectionPresenceType presence;
55
56   presence = empathy_account_manager_get_global_presence (acc_manager,
57       NULL, NULL);
58
59   if (presence < TP_CONNECTION_PRESENCE_TYPE_AVAILABLE)
60     return;
61 }
62
63 static void
64 acc_manager_ready_cb (EmpathyAccountManager *am,
65     GParamSpec *pspec,
66     gpointer _user_data)
67 {
68   if (!empathy_account_manager_is_ready (am))
69     return;
70
71   handle_account_manager_ready ();
72 }
73
74 static gboolean
75 init (NstPlugin *plugin)
76 {
77   g_print ("Init %s plugin\n", plugin->info->id);
78
79   empathy_gtk_init ();
80
81   acc_manager = empathy_account_manager_dup_singleton ();
82
83   if (empathy_account_manager_is_ready (acc_manager))
84     handle_account_manager_ready ();
85   else
86     g_signal_connect (acc_manager, "notify::ready",
87         G_CALLBACK (acc_manager_ready_cb), NULL);
88
89   return TRUE;
90 }
91
92 static GtkWidget *
93 get_contacts_widget (NstPlugin *plugin)
94 {
95   EmpathyContactManager *manager;
96   GtkWidget *selector;
97
98   manager = empathy_contact_manager_dup_singleton ();
99   selector = empathy_contact_selector_new (EMPATHY_CONTACT_LIST (manager));
100
101   empathy_contact_selector_set_visible (EMPATHY_CONTACT_SELECTOR (selector),
102       (EmpathyContactSelectorFilterFunc) empathy_contact_can_send_files, NULL);
103
104   g_object_unref (manager);
105
106   return selector;
107 }
108
109 static EmpathyContact *
110 get_selected_contact (GtkWidget *contact_widget)
111 {
112   EmpathyContact *contact;
113   GtkTreeModel *model;
114   GtkTreeIter iter;
115
116   if (!gtk_combo_box_get_active_iter (GTK_COMBO_BOX (contact_widget), &iter))
117     return NULL;
118
119   model = gtk_combo_box_get_model (GTK_COMBO_BOX (contact_widget));
120   gtk_tree_model_get (model, &iter,
121       EMPATHY_CONTACT_LIST_STORE_COL_CONTACT, &contact, -1);
122
123   return contact;
124 }
125
126 static gboolean
127 validate_destination (NstPlugin *plugin,
128                       GtkWidget *contact_widget,
129                       gchar **error)
130 {
131   EmpathyContact *contact = NULL;
132   gboolean ret = TRUE;
133
134   contact = get_selected_contact (contact_widget);
135
136   if (!contact)
137     return FALSE;
138
139   if (!empathy_contact_can_send_files (contact))
140     {
141       *error = g_strdup (_("The contact selected cannot receive files."));
142       ret = FALSE;
143     }
144
145   if (ret && !empathy_contact_is_online (contact))
146     {
147       *error = g_strdup (_("The contact selected is offline."));
148       ret = FALSE;
149     }
150
151   g_object_unref (contact);
152
153   return ret;
154 }
155
156 static void
157 quit (void)
158 {
159   if (--transfers > 0)
160     return;
161
162   destroy (NULL);
163   gtk_main_quit ();
164 }
165
166 static void
167 transfer_done_cb (EmpathyFTHandler *handler,
168                   EmpathyTpFile *tp_file,
169                   NstPlugin *plugin)
170 {
171   quit ();
172 }
173
174 static void
175 transfer_error_cb (EmpathyFTHandler *handler,
176                    GError *error,
177                    NstPlugin *plugin)
178 {
179   quit ();
180 }
181
182 static void
183 error_dialog_cb (GtkDialog *dialog,
184                  gint arg,
185                  gpointer user_data)
186 {
187   gtk_widget_destroy (GTK_WIDGET (dialog));
188   quit ();
189 }
190
191 static void
192 handler_ready_cb (EmpathyFTFactory *factory,
193                   EmpathyFTHandler *handler,
194                   GError *error,
195                   NstPlugin *plugin)
196 {
197   if (error != NULL)
198     {
199       GtkWidget *dialog;
200       dialog = gtk_message_dialog_new (NULL, 0, GTK_MESSAGE_ERROR,
201           GTK_BUTTONS_CLOSE, "%s",
202           error->message ? error->message : _("No error message"));
203
204       g_signal_connect (dialog, "response", G_CALLBACK (error_dialog_cb), NULL);
205       gtk_widget_show (dialog);
206     }
207   else
208     {
209       g_signal_connect (handler, "transfer-done",
210           G_CALLBACK (transfer_done_cb), plugin);
211       g_signal_connect (handler, "transfer-error",
212           G_CALLBACK (transfer_error_cb), plugin);
213
214       empathy_ft_handler_start_transfer (handler);
215     }
216 }
217
218 static gboolean
219 send_files (NstPlugin *plugin,
220             GtkWidget *contact_widget,
221             GList *file_list)
222 {
223   EmpathyContact *contact;
224   GList *l;
225
226   contact = get_selected_contact (contact_widget);
227
228   if (!contact)
229     return FALSE;
230
231   factory = empathy_ft_factory_dup_singleton ();
232
233   g_signal_connect (factory, "new-ft-handler",
234       G_CALLBACK (handler_ready_cb), plugin);
235
236   for (l = file_list; l; l = l->next)
237     {
238       gchar *path = l->data;
239       GFile *file;
240
241       file = g_file_new_for_uri (path);
242
243       ++transfers;
244
245       empathy_ft_factory_new_transfer_outgoing (factory,
246           contact, file);
247
248       g_object_unref (file);
249     }
250
251   g_object_unref (contact);
252
253   if (transfers == 0)
254     {
255       destroy (NULL);
256       return TRUE;
257     }
258
259   return FALSE;
260 }
261
262 static gboolean
263 destroy (NstPlugin *plugin)
264 {
265   if (acc_manager)
266     g_object_unref (acc_manager);
267
268   if (factory)
269     g_object_unref (factory);
270
271   return TRUE;
272 }
273
274 static
275 NstPluginInfo plugin_info = {
276   "im",
277   "empathy",
278   N_("Instant Message (Empathy)"),
279   GETTEXT_PACKAGE,
280   TRUE,
281   NAUTILUS_CAPS_NONE,
282   init,
283   get_contacts_widget,
284   validate_destination,
285   send_files,
286   destroy
287 };
288
289 NST_INIT_PLUGIN (plugin_info)
290