2 * empathy-ft-factory.c - Source for EmpathyFTFactory
3 * Copyright (C) 2009 Collabora Ltd.
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.
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.
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
19 * Author: Cosimo Cecchi <cosimo.cecchi@collabora.co.uk>
22 /* empathy-ft-factory.c */
25 #include "empathy-ft-factory.h"
27 #include <telepathy-glib/telepathy-glib-dbus.h>
29 #include "empathy-request-util.h"
30 #include "empathy-utils.h"
33 * SECTION:empathy-ft-factory
34 * @title:EmpathyFTFactory
35 * @short_description: creates #EmpathyFTHandler objects
36 * @include: libempathy/empathy-ft-factory.h
38 * #EmpathyFTFactory takes care of the creation of the #EmpathyFTHandler
39 * objects used for file transfer. As the creation of the handlers is
40 * async, a client will have to connect to the ::new-ft-handler signal
41 * to receive the handler.
42 * In case of an incoming file transfer, the handler will need the destination
43 * file before being useful; as this is usually decided by the user (e.g. with
44 * a file selector), a ::new-incoming-transfer is emitted by the factory when
45 * a destination file is needed, which can be set later with
46 * empathy_ft_factory_set_destination_for_incoming_handler().
49 G_DEFINE_TYPE (EmpathyFTFactory
, empathy_ft_factory
, G_TYPE_OBJECT
);
53 NEW_INCOMING_TRANSFER
,
57 static EmpathyFTFactory
*factory_singleton
= NULL
;
58 static guint signals
[LAST_SIGNAL
] = { 0 };
60 /* private structure */
62 TpBaseClient
*handler
;
63 } EmpathyFTFactoryPriv
;
65 #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyFTFactory)
68 do_constructor (GType type
,
70 GObjectConstructParam
*props
)
74 if (factory_singleton
!= NULL
)
76 retval
= g_object_ref (factory_singleton
);
80 retval
= G_OBJECT_CLASS (empathy_ft_factory_parent_class
)->constructor
81 (type
, n_props
, props
);
83 factory_singleton
= EMPATHY_FT_FACTORY (retval
);
84 g_object_add_weak_pointer (retval
, (gpointer
*) &factory_singleton
);
91 empathy_ft_factory_dispose (GObject
*object
)
93 EmpathyFTFactory
*self
= (EmpathyFTFactory
*) object
;
94 EmpathyFTFactoryPriv
*priv
= GET_PRIV (self
);
96 tp_clear_object (&priv
->handler
);
98 (G_OBJECT_CLASS (empathy_ft_factory_parent_class
)->dispose
) (object
);
102 empathy_ft_factory_class_init (EmpathyFTFactoryClass
*klass
)
104 GObjectClass
*object_class
= G_OBJECT_CLASS (klass
);
106 g_type_class_add_private (klass
, sizeof (EmpathyFTFactoryPriv
));
108 object_class
->constructor
= do_constructor
;
109 object_class
->dispose
= empathy_ft_factory_dispose
;
112 * EmpathyFTFactory::new-ft-handler
113 * @factory: the object which received the signal
114 * @handler: the handler made available by the factory
115 * @error: a #GError or %NULL
117 * The signal is emitted when a new #EmpathyFTHandler is available.
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
122 signals
[NEW_FT_HANDLER
] =
123 g_signal_new ("new-ft-handler",
124 G_TYPE_FROM_CLASS (klass
),
125 G_SIGNAL_RUN_LAST
, 0,
127 g_cclosure_marshal_generic
,
128 G_TYPE_NONE
, 2, EMPATHY_TYPE_FT_HANDLER
, G_TYPE_POINTER
);
131 * EmpathyFTFactory::new-incoming-transfer
132 * @factory: the object which received the signal
133 * @handler: the incoming handler being constructed
134 * @error: a #GError or %NULL
136 * The signal is emitted when a new incoming #EmpathyFTHandler is being
137 * constructed, and needs a destination #GFile to be useful.
138 * Clients that connect to this signal will have to call
139 * empathy_ft_factory_set_destination_for_incoming_handler() when they
141 * Note that @handler is never %NULL even if @error is set, as you might want
142 * to display the error in an UI; in that case, the handler won't support
145 signals
[NEW_INCOMING_TRANSFER
] =
146 g_signal_new ("new-incoming-transfer",
147 G_TYPE_FROM_CLASS (klass
),
148 G_SIGNAL_RUN_LAST
, 0,
150 g_cclosure_marshal_generic
,
151 G_TYPE_NONE
, 2, EMPATHY_TYPE_FT_HANDLER
, G_TYPE_POINTER
);
155 ft_handler_incoming_ready_cb (EmpathyFTHandler
*handler
,
159 EmpathyFTFactory
*factory
= user_data
;
161 g_signal_emit (factory
, signals
[NEW_INCOMING_TRANSFER
], 0, handler
, error
);
165 handle_channels_cb (TpSimpleHandler
*handler
,
167 TpConnection
*connection
,
169 GList
*requests_satisfied
,
170 gint64 user_action_time
,
171 TpHandleChannelsContext
*context
,
174 EmpathyFTFactory
*self
= user_data
;
177 for (l
= channels
; l
!= NULL
; l
= g_list_next (l
))
179 TpChannel
*channel
= l
->data
;
181 if (tp_proxy_get_invalidated (channel
) != NULL
)
184 if (!TP_IS_FILE_TRANSFER_CHANNEL (channel
))
187 /* We handle only incoming FT */
188 empathy_ft_handler_new_incoming ((TpFileTransferChannel
*) channel
,
189 ft_handler_incoming_ready_cb
, self
);
193 tp_handle_channels_context_accept (context
);
197 empathy_ft_factory_init (EmpathyFTFactory
*self
)
199 EmpathyFTFactoryPriv
*priv
= G_TYPE_INSTANCE_GET_PRIVATE (self
,
200 EMPATHY_TYPE_FT_FACTORY
, EmpathyFTFactoryPriv
);
201 TpAccountManager
*am
;
205 am
= tp_account_manager_dup ();
207 priv
->handler
= tp_simple_handler_new_with_am (am
, FALSE
, FALSE
,
208 EMPATHY_FT_TP_BUS_NAME_SUFFIX
, FALSE
, handle_channels_cb
, self
, NULL
);
210 tp_base_client_take_handler_filter (priv
->handler
, tp_asv_new (
211 TP_PROP_CHANNEL_CHANNEL_TYPE
, G_TYPE_STRING
,
212 TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER
,
213 TP_PROP_CHANNEL_TARGET_HANDLE_TYPE
, G_TYPE_UINT
, TP_HANDLE_TYPE_CONTACT
,
214 /* Only handle *incoming* channels as outgoing FT channels has to be
215 * handled by the requester. */
216 TP_PROP_CHANNEL_REQUESTED
, G_TYPE_BOOLEAN
, FALSE
,
223 ft_handler_outgoing_ready_cb (EmpathyFTHandler
*handler
,
227 EmpathyFTFactory
*factory
= EMPATHY_FT_FACTORY (user_data
);
229 g_signal_emit (factory
, signals
[NEW_FT_HANDLER
], 0, handler
, error
);
231 g_object_unref (factory
);
237 * empathy_ft_factory_dup_singleton:
239 * Gives the caller a reference to the #EmpathyFTFactory singleton,
240 * (creating it if necessary).
242 * Return value: an #EmpathyFTFactory object
245 empathy_ft_factory_dup_singleton (void)
247 return g_object_new (EMPATHY_TYPE_FT_FACTORY
, NULL
);
251 * empathy_ft_factory_new_transfer_outgoing:
252 * @factory: an #EmpathyFTFactory
253 * @contact: the #EmpathyContact destination of the transfer
254 * @source: the #GFile to be transferred to @contact
256 * Trigger the creation of an #EmpathyFTHandler object to send @source to
257 * the specified @contact.
260 empathy_ft_factory_new_transfer_outgoing (EmpathyFTFactory
*factory
,
261 EmpathyContact
*contact
,
265 g_return_if_fail (EMPATHY_IS_FT_FACTORY (factory
));
266 g_return_if_fail (EMPATHY_IS_CONTACT (contact
));
267 g_return_if_fail (G_IS_FILE (source
));
269 empathy_ft_handler_new_outgoing (contact
, source
, action_time
,
270 ft_handler_outgoing_ready_cb
, g_object_ref (factory
));
274 * empathy_ft_factory_set_destination_for_incoming_handler:
275 * @factory: an #EmpathyFTFactory
276 * @handler: the #EmpathyFTHandler to set the destination of
277 * @destination: the #GFile destination of the transfer
279 * Sets @destination as destination file for the transfer. After the call of
280 * this method, the ::new-ft-handler will be emitted for the incoming handler.
283 empathy_ft_factory_set_destination_for_incoming_handler (
284 EmpathyFTFactory
*factory
,
285 EmpathyFTHandler
*handler
,
288 g_return_if_fail (EMPATHY_IS_FT_FACTORY (factory
));
289 g_return_if_fail (EMPATHY_IS_FT_HANDLER (handler
));
290 g_return_if_fail (G_IS_FILE (destination
));
292 empathy_ft_handler_incoming_set_destination (handler
, destination
);
294 g_signal_emit (factory
, signals
[NEW_FT_HANDLER
], 0, handler
, NULL
);
298 empathy_ft_factory_register (EmpathyFTFactory
*self
,
301 EmpathyFTFactoryPriv
*priv
= GET_PRIV (self
);
303 return tp_base_client_register (priv
->handler
, error
);