]> git.0d.be Git - empathy.git/blob - libempathy/empathy-ft-factory.c
Document EmpathyFTFactory
[empathy.git] / libempathy / empathy-ft-factory.c
1 /*
2  * empathy-ft-factory.c - Source for EmpathyFTFactory
3  * Copyright (C) 2009 Collabora Ltd.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18  *
19  * Author: Cosimo Cecchi <cosimo.cecchi@collabora.co.uk>
20  */
21  
22 /* empathy-ft-factory.c */
23
24 #include <glib.h>
25
26 #include "empathy-ft-factory.h"
27 #include "empathy-ft-handler.h"
28 #include "empathy-marshal.h"
29 #include "empathy-utils.h"
30
31 /**
32  * SECTION:empathy-ft-factory
33  * @title:EmpathyFTFactory
34  * @short_description: creates #EmpathyFTHandler objects
35  * @include: libempathy/empathy-ft-factory.h
36  *
37  * #EmpathyFTFactory takes care of the creation of the #EmpathyFTHandler
38  * objects used for file transfer. As the creation of the handlers is
39  * async, a client will have to connect to the ::new-ft-handler signal
40  * to receive the handler.
41  * In case of an incoming file transfer, the handler will need the destination
42  * file before being useful; as this is usually decided by the user (e.g. with
43  * a file selector), a ::new-incoming-transfer is emitted by the factory when
44  * a destination file is needed, which can be set later with
45  * empathy_ft_factory_set_destination_for_incoming_handler().
46  */
47
48 G_DEFINE_TYPE (EmpathyFTFactory, empathy_ft_factory, G_TYPE_OBJECT);
49
50 #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyFTFactory)
51
52 enum {
53   NEW_FT_HANDLER,
54   NEW_INCOMING_TRANSFER,
55   LAST_SIGNAL
56 };
57
58 static EmpathyFTFactory *factory_singleton = NULL;
59 static guint signals[LAST_SIGNAL] = { 0 };
60
61 static GObject *
62 do_constructor (GType type,
63     guint n_props,
64     GObjectConstructParam *props)
65 {
66         GObject *retval;
67
68         if (factory_singleton != NULL) {
69                 retval = g_object_ref (factory_singleton);
70         } else {
71                 retval = G_OBJECT_CLASS (empathy_ft_factory_parent_class)->constructor
72                         (type, n_props, props);
73
74                 factory_singleton = EMPATHY_FT_FACTORY (retval);
75                 g_object_add_weak_pointer (retval, (gpointer *) &factory_singleton);
76         }
77
78         return retval;
79 }
80
81 static void
82 empathy_ft_factory_class_init (EmpathyFTFactoryClass *klass)
83 {
84   GObjectClass *object_class = G_OBJECT_CLASS (klass);
85
86   object_class->constructor = do_constructor;
87
88   /**
89    * EmpathyFTFactory::new-ft-handler
90    * @factory: the object which received the signal
91    * @handler: the handler made available by the factory
92    * @error: a #GError or %NULL
93    *
94    * The signal is emitted when a new #EmpathyFTHandler is available.
95    * Note that @handler is never %NULL even if @error is set, as you might want
96    * to display the error in an UI; in that case, the handler won't support
97    * any transfer.
98    */
99   signals[NEW_FT_HANDLER] =
100     g_signal_new ("new-ft-handler",
101       G_TYPE_FROM_CLASS (klass),
102       G_SIGNAL_RUN_LAST, 0,
103       NULL, NULL,
104       _empathy_marshal_VOID__OBJECT_POINTER,
105       G_TYPE_NONE, 2, EMPATHY_TYPE_FT_HANDLER, G_TYPE_POINTER);
106
107   /**
108    * EmpathyFTFactory::new-incoming-transfer
109    * @factory: the object which received the signal
110    * @handler: the incoming handler being constructed
111    * @error: a #GError or %NULL
112    *
113    * The signal is emitted when a new incoming #EmpathyFTHandler is being
114    * constructed, and needs a destination #GFile to be useful.
115    * Clients that connect to this signal will have to call
116    * empathy_ft_factory_set_destination_for_incoming_handler() when they
117    * have a #GFile.
118    * Note that @handler is never %NULL even if @error is set, as you might want
119    * to display the error in an UI; in that case, the handler won't support
120    * any transfer.
121    */
122   signals[NEW_INCOMING_TRANSFER] =
123     g_signal_new ("new-incoming-transfer",
124       G_TYPE_FROM_CLASS (klass),
125       G_SIGNAL_RUN_LAST, 0,
126       NULL, NULL,
127       _empathy_marshal_VOID__OBJECT_POINTER,
128       G_TYPE_NONE, 2, EMPATHY_TYPE_FT_HANDLER, G_TYPE_POINTER);
129 }
130
131 static void
132 empathy_ft_factory_init (EmpathyFTFactory *self)
133 {
134   /* do nothing */
135 }
136
137 static void
138 ft_handler_outgoing_ready_cb (EmpathyFTHandler *handler,
139     GError *error,
140     gpointer user_data)
141 {
142   EmpathyFTFactory *factory = user_data;
143
144   g_signal_emit (factory, signals[NEW_FT_HANDLER], 0, handler, error);
145 }
146
147 static void
148 ft_handler_incoming_ready_cb (EmpathyFTHandler *handler,
149     GError *error,
150     gpointer user_data)
151 {
152   EmpathyFTFactory *factory = user_data;
153
154   g_signal_emit (factory, signals[NEW_INCOMING_TRANSFER], 0, handler, error);
155 }
156
157 /* public methods */
158
159 /**
160  * empathy_ft_factory_dup_singleton:
161  *
162  * Gives the caller a reference to the #EmpathyFTFactory singleton,
163  * (creating it if necessary).
164  *
165  * Return value: an #EmpathyFTFactory object
166  */
167 EmpathyFTFactory*
168 empathy_ft_factory_dup_singleton (void)
169 {
170   return g_object_new (EMPATHY_TYPE_FT_FACTORY, NULL);
171 }
172
173 /**
174  * empathy_ft_factory_new_transfer_outgoing:
175  * @factory: an #EmpathyFTFactory
176  * @contact: the #EmpathyContact destination of the transfer
177  * @source: the #GFile to be transferred to @contact
178  * @use_hash: whether the handler should try to use checksum to validate
179  * the transfer
180  *
181  * Trigger the creation of an #EmpathyFTHandler object to send @source to
182  * the specified @contact. Note that it's not guaranteed that setting
183  * @use_hash to TRUE will trigger checksumming, as that is not supported
184  * by all the underlying connection managers.
185  */
186 void
187 empathy_ft_factory_new_transfer_outgoing (EmpathyFTFactory *factory,
188     EmpathyContact *contact,
189     GFile *source,
190     gboolean use_hash)
191 {
192   g_return_if_fail (EMPATHY_IS_FT_FACTORY (factory));
193   g_return_if_fail (EMPATHY_IS_CONTACT (contact));
194   g_return_if_fail (G_IS_FILE (source));
195
196   empathy_ft_handler_new_outgoing (contact, source, use_hash,
197       ft_handler_outgoing_ready_cb, factory);
198 }
199
200 /**
201  * empathy_ft_factory_claim_channel:
202  * @factory: an #EmpathyFTFactory
203  * @operation: the #EmpathyDispatchOperation wrapping the channel
204  *
205  * Let the @factory claim the channel, starting the creation of a new
206  * incoming #EmpathyFTHandler.
207  */
208 void
209 empathy_ft_factory_claim_channel (EmpathyFTFactory *factory,
210     EmpathyDispatchOperation *operation)
211 {
212   EmpathyTpFile *tp_file;
213
214   g_return_if_fail (EMPATHY_IS_FT_FACTORY (factory));
215   g_return_if_fail (EMPATHY_IS_DISPATCH_OPERATION (operation));
216
217   /* own a reference to the EmpathyTpFile */
218   tp_file = EMPATHY_TP_FILE
219       ((empathy_dispatch_operation_get_channel_wrapper (operation)));
220
221   empathy_ft_handler_new_incoming (tp_file, ft_handler_incoming_ready_cb,
222       factory);
223
224   empathy_dispatch_operation_claim (operation);
225 }
226
227 /**
228  * empathy_ft_factory_set_destination_for_incoming_handler:
229  * @factory: an #EmpathyFTFactory
230  * @handler: the #EmpathyFTHandler to set the destination of
231  * @destination: the #GFile destination of the transfer
232  * @use_hash: whether the handler should try to use checksum to validate
233  * the transfer
234  *
235  * Sets @destination as destination file for the transfer. After the call of
236  * this method, the ::new-ft-handler will be emitted for the incoming handler.
237  */
238 void
239 empathy_ft_factory_set_destination_for_incoming_handler (
240     EmpathyFTFactory *factory,
241     EmpathyFTHandler *handler,
242     GFile *destination,
243     gboolean use_hash)
244 {
245   g_return_if_fail (EMPATHY_IS_FT_FACTORY (factory));
246   g_return_if_fail (EMPATHY_IS_FT_HANDLER (handler));
247   g_return_if_fail (G_IS_FILE (destination));
248
249   empathy_ft_handler_incoming_set_destination (handler, destination, use_hash);
250
251   g_signal_emit (factory, signals[NEW_FT_HANDLER], 0, handler, FALSE);
252 }