Kaydet (Commit) 37c67a13 authored tarafından Matúš Kukan's avatar Matúš Kukan

tubes: send a file for collaboration when buddy session starts

Channels for file and for tube are independent in telepathy,
so let sender create UUID and pass it to receiver, who then can
bind the document to the channel.
UUID for tube channel goes through telepathy.
UUID for file channel is encoded in the filename for now.

Tubes specific CreateDocFunc is re-introduced, so we could set
current UUID after file is received and when the document is being
constructed, get channel from TeleManager with this UUID.
This is not immune to constructing other documents in the middle of binding
proccess.

Change-Id: I57c7e57a5d7d3ccd7d94677a8cf2719c78baa2fd
üst d41903eb
...@@ -98,11 +98,6 @@ class TubeContacts : public ModelessDialog ...@@ -98,11 +98,6 @@ class TubeContacts : public ModelessDialog
// Receiving file is not related to any document. // Receiving file is not related to any document.
mpManager->sigFileReceived.connect( boost::bind( mpManager->sigFileReceived.connect( boost::bind(
&ScDocFuncRecv::fileReceived, mpSender->GetReceiver(), _1 ) ); &ScDocFuncRecv::fileReceived, mpSender->GetReceiver(), _1 ) );
// TODO: It's still not clear to me who should take care of this signal
// and what exactly it is supposed to happen.
mpManager->sigConferenceCreated.connect( boost::bind(
&ScDocFuncSend::SetCollaboration, mpSender, _1 ) );
} }
} }
...@@ -124,7 +119,11 @@ class TubeContacts : public ModelessDialog ...@@ -124,7 +119,11 @@ class TubeContacts : public ModelessDialog
fprintf( stderr, "could not start session with %s\n", fprintf( stderr, "could not start session with %s\n",
tp_contact_get_identifier( pContact ) ); tp_contact_get_identifier( pContact ) );
else else
{
mpSender->SetCollaboration( pConference ); mpSender->SetCollaboration( pConference );
mpSender->SendFile( OStringToOUString(
pConference->getUuid(), RTL_TEXTENCODING_UTF8 ) );
}
} }
} }
......
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#include <tubes/manager.hxx> #include <tubes/manager.hxx>
#include <tubes/conference.hxx> #include <tubes/conference.hxx>
#include <tubes/contact-list.hxx> #include <tubes/contact-list.hxx>
#include <tubes/constants.h>
// new file send/recv fun ... // new file send/recv fun ...
#include <com/sun/star/uno/Sequence.hxx> #include <com/sun/star/uno/Sequence.hxx>
...@@ -232,12 +233,13 @@ void ScDocFuncSend::SendMessage( ScChangeOpWriter &rOp ) ...@@ -232,12 +233,13 @@ void ScDocFuncSend::SendMessage( ScChangeOpWriter &rOp )
mpDirect->RecvMessage( rOp.toString() ); mpDirect->RecvMessage( rOp.toString() );
} }
void ScDocFuncSend::SendFile( const rtl::OUString &rURL ) void ScDocFuncSend::SendFile( const rtl::OUString &sUuid )
{ {
(void)rURL;
String aTmpPath = utl::TempFile::CreateTempName(); String aTmpPath = utl::TempFile::CreateTempName();
aTmpPath.Append( rtl::OUString( ".ods" ) ); aTmpPath.Append( OUString("_") );
aTmpPath.Append( sUuid );
aTmpPath.Append( OUString("_") );
aTmpPath.Append( OUString(".ods") );
rtl::OUString aFileURL; rtl::OUString aFileURL;
::utl::LocalFileHelper::ConvertPhysicalNameToURL( aTmpPath, aFileURL ); ::utl::LocalFileHelper::ConvertPhysicalNameToURL( aTmpPath, aFileURL );
...@@ -416,22 +418,30 @@ sal_Bool ScDocFuncSend::MergeCells( const ScCellMergeOption& rOption, sal_Bool b ...@@ -416,22 +418,30 @@ sal_Bool ScDocFuncSend::MergeCells( const ScCellMergeOption& rOption, sal_Bool b
return ScDocFunc::MergeCells( rOption, bContents, bRecord, bApi ); return ScDocFunc::MergeCells( rOption, bContents, bRecord, bApi );
} }
#ifdef INTERCEPT ScDocFunc *ScDocShell::CreateDocFunc()
SC_DLLPRIVATE ScDocFunc *ScDocShell::CreateDocFunc()
{ {
if (getenv ("INTERCEPT")) if (getenv ("INTERCEPT"))
{ {
boost::shared_ptr<ScDocFuncDirect> pDirect( new ScDocFuncDirect( *this ) ); ScDocFuncDirect* pDirect = new ScDocFuncDirect( *this );
boost::shared_ptr<ScDocFuncRecv> pReceiver( new ScDocFuncRecv( pDirect ) ); boost::shared_ptr<ScDocFuncRecv> pReceiver( new ScDocFuncRecv( pDirect ) );
static boost::shared_ptr<ScDocFuncDemo> aDemoBus( new ScDocFuncDemo() ); static boost::shared_ptr<ScDocFuncDemo> aDemoBus( new ScDocFuncDemo() );
aDemoBus->add_client( pReceiver ); // a lifecycle horror no doubt. aDemoBus->add_client( pReceiver ); // a lifecycle horror no doubt.
return new ScDocFuncSend( *this, boost::shared_ptr<ScDocFuncRecv>( aDemoBus.get() ) ); return new ScDocFuncSend( *this, aDemoBus.get() );
}
else if (TeleManager::hasWaitingConference())
{
ScDocFuncDirect *pDirect = new ScDocFuncDirect( *this );
ScDocFuncRecv *pReceiver = new ScDocFuncRecv( pDirect );
ScDocFuncSend *pSender = new ScDocFuncSend( *this, pReceiver );
TeleManager *pManager = TeleManager::get();
pSender->SetCollaboration( pManager->getConference() );
pManager->unref();
return pSender;
} }
else else
return new ScDocFuncDirect( *this ); return new ScDocFuncDirect( *this );
} }
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
...@@ -229,7 +229,6 @@ class ScDocFuncSend : public ScDocFunc ...@@ -229,7 +229,6 @@ class ScDocFuncSend : public ScDocFunc
TeleConference *mpConference; TeleConference *mpConference;
void SendMessage( ScChangeOpWriter &rOp ); void SendMessage( ScChangeOpWriter &rOp );
void SendFile( const rtl::OUString &rURL );
public: public:
// FIXME: really ScDocFunc should be an abstract base, so // FIXME: really ScDocFunc should be an abstract base, so
...@@ -240,6 +239,8 @@ public: ...@@ -240,6 +239,8 @@ public:
void SetCollaboration( TeleConference* pConference ); void SetCollaboration( TeleConference* pConference );
TeleConference* GetConference(); TeleConference* GetConference();
ScDocFuncRecv* GetReceiver(); ScDocFuncRecv* GetReceiver();
// TODO: I think this could be moved to TeleManager later.
void SendFile( const rtl::OUString &rURL );
virtual void EnterListAction( sal_uInt16 nNameResId ); virtual void EnterListAction( sal_uInt16 nNameResId );
virtual void EndListAction(); virtual void EndListAction();
......
...@@ -2500,10 +2500,12 @@ sal_Bool ScDocShell::HasAutomaticTableName( const String& rFilter ) ...@@ -2500,10 +2500,12 @@ sal_Bool ScDocShell::HasAutomaticTableName( const String& rFilter )
|| rFilter.EqualsAscii( pFilterRtf ); || rFilter.EqualsAscii( pFilterRtf );
} }
#ifndef ENABLE_TELEPATHY
ScDocFunc *ScDocShell::CreateDocFunc() ScDocFunc *ScDocShell::CreateDocFunc()
{ {
return new ScDocFuncDirect( *this ); return new ScDocFuncDirect( *this );
} }
#endif
ScDocShell::ScDocShell( const ScDocShell& rShell ) : ScDocShell::ScDocShell( const ScDocShell& rShell ) :
SvRefBase(), SvRefBase(),
......
...@@ -47,7 +47,7 @@ class TeleConference ...@@ -47,7 +47,7 @@ class TeleConference
{ {
public: public:
TeleConference( TeleManager* pManager, TpAccount *pAccount, TpDBusTubeChannel* pChannel ); TeleConference( TeleManager* pManager, TpAccount *pAccount, TpDBusTubeChannel* pChannel, const OString sUuid = OString() );
~TeleConference(); ~TeleConference();
/// Close channel and call finalize() /// Close channel and call finalize()
...@@ -77,6 +77,7 @@ public: ...@@ -77,6 +77,7 @@ public:
typedef void (*FileSentCallback)( bool aSuccess, void* pUserData); typedef void (*FileSentCallback)( bool aSuccess, void* pUserData);
TUBES_DLLPUBLIC void sendFile( rtl::OUString &localUri, FileSentCallback pCallback, void* pUserData); TUBES_DLLPUBLIC void sendFile( rtl::OUString &localUri, FileSentCallback pCallback, void* pUserData);
TUBES_DLLPUBLIC const OString& getUuid() const { return msUuid; }
// --- following only to be called only by manager's callbacks --- // --- following only to be called only by manager's callbacks ---
// TODO: make friends instead // TODO: make friends instead
...@@ -112,6 +113,7 @@ private: ...@@ -112,6 +113,7 @@ private:
TeleManager* mpManager; TeleManager* mpManager;
TpAccount* mpAccount; TpAccount* mpAccount;
TpDBusTubeChannel* mpChannel; TpDBusTubeChannel* mpChannel;
OString msUuid;
gchar* mpAddress; gchar* mpAddress;
GDBusConnection* mpTube; GDBusConnection* mpTube;
guint maObjectRegistrationId; guint maObjectRegistrationId;
......
...@@ -45,6 +45,10 @@ ...@@ -45,6 +45,10 @@
* tp_simple_handler_new_with_am(). */ * tp_simple_handler_new_with_am(). */
#define LIBO_CLIENT_SUFFIX "LibreOffice" #define LIBO_CLIENT_SUFFIX "LibreOffice"
/* Key value storing UUID for TeleConference
*/
#define LIBO_TUBES_UUID "LIBO_TUBES_UUID"
#endif // INCLUDED_TUBES_CONSTANTS_H #endif // INCLUDED_TUBES_CONSTANTS_H
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
#include <tools/link.hxx> #include <tools/link.hxx>
#include <telepathy-glib/telepathy-glib.h> #include <telepathy-glib/telepathy-glib.h>
#include <tubes/warnings_guard_boost_signals2.hpp> #include <tubes/warnings_guard_boost_signals2.hpp>
#include <map>
// For testing purposes, we might need more in future. // For testing purposes, we might need more in future.
#define LIBO_TUBES_DBUS_INTERFACE "org.libreoffice.calc" #define LIBO_TUBES_DBUS_INTERFACE "org.libreoffice.calc"
...@@ -131,12 +132,16 @@ public: ...@@ -131,12 +132,16 @@ public:
*/ */
TUBES_DLLPUBLIC TeleConference* startBuddySession( TpAccount *pAccount, TpContact *pBuddy ); TUBES_DLLPUBLIC TeleConference* startBuddySession( TpAccount *pAccount, TpContact *pBuddy );
/** Get a conference with current UUID to set a session. */
TUBES_DLLPUBLIC TeleConference* getConference();
/** True if there has been tube channel received and is still not used. */
TUBES_DLLPUBLIC static bool hasWaitingConference();
void disconnect(); void disconnect();
boost::signals2::signal<void ( const rtl::OUString &localUri )> sigFileReceived; boost::signals2::signal<void ( const rtl::OUString &localUri )> sigFileReceived;
boost::signals2::signal<void (TeleConference*)> sigConferenceCreated;
/// Only for use with MainLoopFlusher /// Only for use with MainLoopFlusher
GMainLoop* getMainLoop() const; GMainLoop* getMainLoop() const;
...@@ -184,7 +189,7 @@ public: ...@@ -184,7 +189,7 @@ public:
is something like org.libreoffice.calc, this modifies the names to is something like org.libreoffice.calc, this modifies the names to
"LibreOffice"+pName and "org.libreoffice.calc"+pName to make tests not "LibreOffice"+pName and "org.libreoffice.calc"+pName to make tests not
interfere with the real world. This is not to be used otherwise. If interfere with the real world. This is not to be used otherwise. If
used it must be called before the first TeleManager is instanciated and used it must be called before the first TeleManager is instanciated and
connects. connects.
*/ */
static void addSuffixToNames( const char* pName ); static void addSuffixToNames( const char* pName );
...@@ -205,6 +210,7 @@ public: ...@@ -205,6 +210,7 @@ public:
gpointer pUserData); gpointer pUserData);
private: private:
void addConference( TeleConference* );
void ensureLegacyChannel( TpAccount* pAccount, TpContact* pBuddy ); void ensureLegacyChannel( TpAccount* pAccount, TpContact* pBuddy );
bool mbChannelReadyHandlerInvoked : 1; bool mbChannelReadyHandlerInvoked : 1;
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include <tubes/conference.hxx> #include <tubes/conference.hxx>
#include <tubes/manager.hxx> #include <tubes/manager.hxx>
#include <tubes/constants.h>
#if defined SAL_LOG_INFO #if defined SAL_LOG_INFO
...@@ -196,16 +197,20 @@ void TeleConference::TubeAcceptedHandler( ...@@ -196,16 +197,20 @@ void TeleConference::TubeAcceptedHandler(
g_error_free( pError); g_error_free( pError);
return; return;
} }
GHashTable* pParameters = tp_dbus_tube_channel_get_parameters( pChannel);
const char* sUuid = tp_asv_get_string( pParameters, LIBO_TUBES_UUID);
pConference->msUuid = OString( sUuid);
pConference->setTube( pTube); pConference->setTube( pTube);
} }
TeleConference::TeleConference( TeleManager* pManager, TpAccount* pAccount, TpDBusTubeChannel* pChannel ) TeleConference::TeleConference( TeleManager* pManager, TpAccount* pAccount, TpDBusTubeChannel* pChannel, const OString sUuid )
: :
mpManager( pManager), mpManager( pManager),
mpAccount( NULL), mpAccount( NULL),
mpChannel( NULL), mpChannel( NULL),
msUuid( sUuid),
mpAddress( NULL), mpAddress( NULL),
mpTube( NULL), mpTube( NULL),
mbTubeOfferedHandlerInvoked( false) mbTubeOfferedHandlerInvoked( false)
...@@ -272,9 +277,13 @@ bool TeleConference::offerTube() ...@@ -272,9 +277,13 @@ bool TeleConference::offerTube()
if (!mpChannel) if (!mpChannel)
return false; return false;
GHashTable* pParameters = tp_asv_new (
LIBO_TUBES_UUID, G_TYPE_STRING, msUuid.getStr(),
NULL);
tp_dbus_tube_channel_offer_async( tp_dbus_tube_channel_offer_async(
mpChannel, mpChannel,
NULL, // no parameters for now pParameters,
&TeleConference::TubeOfferedHandler, &TeleConference::TubeOfferedHandler,
this); this);
......
...@@ -86,6 +86,9 @@ public: ...@@ -86,6 +86,9 @@ public:
TeleManager::AccountManagerStatus meAccountManagerStatus; TeleManager::AccountManagerStatus meAccountManagerStatus;
bool mbAccountManagerReadyHandlerInvoked; bool mbAccountManagerReadyHandlerInvoked;
ContactList* mpContactList; ContactList* mpContactList;
OString msCurrentUUID;
typedef std::map< OString, TeleConference* > MapStringConference;
MapStringConference maAcceptedConferences;
TeleManagerImpl(); TeleManagerImpl();
~TeleManagerImpl(); ~TeleManagerImpl();
...@@ -124,9 +127,9 @@ void TeleManager::DBusChannelHandler( ...@@ -124,9 +127,9 @@ void TeleManager::DBusChannelHandler(
SAL_INFO( "tubes", "accepting"); SAL_INFO( "tubes", "accepting");
aAccepted = true; aAccepted = true;
TeleConference* pConference = new TeleConference( pManager, pAccount, TP_DBUS_TUBE_CHANNEL( pChannel ) ); TeleConference* pConference = new TeleConference( pManager, pAccount, TP_DBUS_TUBE_CHANNEL( pChannel ), createUuid() );
pConference->acceptTube(); pConference->acceptTube();
pManager->sigConferenceCreated( pConference ); pManager->addConference( pConference );
} }
else else
{ {
...@@ -146,6 +149,29 @@ void TeleManager::DBusChannelHandler( ...@@ -146,6 +149,29 @@ void TeleManager::DBusChannelHandler(
} }
} }
void TeleManager::addConference( TeleConference* pConference )
{
pImpl->maAcceptedConferences[ pConference->getUuid() ] = pConference;
}
TeleConference* TeleManager::getConference()
{
TeleManagerImpl::MapStringConference::iterator it =
pImpl->maAcceptedConferences.find( pImpl->msCurrentUUID );
TeleConference* pConference = NULL;
if (it != pImpl->maAcceptedConferences.end())
pConference = it->second;
SAL_WARN_IF( !pConference, "tubes", "TeleManager::getConference: "
<< pImpl->msCurrentUUID.getStr() << " not found!" );
pImpl->msCurrentUUID = OString();
return pConference;
}
bool TeleManager::hasWaitingConference()
{
return !pImpl->msCurrentUUID.isEmpty();
}
void TeleManager::TransferDone( EmpathyFTHandler *handler, TpFileTransferChannel *, gpointer pUserData) void TeleManager::TransferDone( EmpathyFTHandler *handler, TpFileTransferChannel *, gpointer pUserData)
{ {
TeleManager* pManager = reinterpret_cast<TeleManager*>(pUserData); TeleManager* pManager = reinterpret_cast<TeleManager*>(pUserData);
...@@ -156,6 +182,11 @@ void TeleManager::TransferDone( EmpathyFTHandler *handler, TpFileTransferChannel ...@@ -156,6 +182,11 @@ void TeleManager::TransferDone( EmpathyFTHandler *handler, TpFileTransferChannel
rtl::OUString aUri( uri, strlen( uri), RTL_TEXTENCODING_UTF8); rtl::OUString aUri( uri, strlen( uri), RTL_TEXTENCODING_UTF8);
g_free( uri); g_free( uri);
sal_Int32 first = aUri.indexOf('_');
sal_Int32 last = aUri.lastIndexOf('_');
OString sUuid( OUStringToOString( aUri.copy( first + 1, last - first - 1),
RTL_TEXTENCODING_UTF8));
pImpl->msCurrentUUID = sUuid;
pManager->sigFileReceived( aUri ); pManager->sigFileReceived( aUri );
g_object_unref( handler); g_object_unref( handler);
...@@ -616,7 +647,7 @@ TeleConference* TeleManager::startBuddySession( TpAccount *pAccount, TpContact * ...@@ -616,7 +647,7 @@ TeleConference* TeleManager::startBuddySession( TpAccount *pAccount, TpContact *
setChannelReadyHandlerInvoked( false); setChannelReadyHandlerInvoked( false);
TeleConference* pConference = new TeleConference( this, NULL, NULL ); TeleConference* pConference = new TeleConference( this, NULL, NULL, createUuid() );
tp_account_channel_request_create_and_handle_channel_async( tp_account_channel_request_create_and_handle_channel_async(
pChannelRequest, NULL, TeleManager_ChannelReadyHandler, pConference ); pChannelRequest, NULL, TeleManager_ChannelReadyHandler, pConference );
...@@ -881,6 +912,11 @@ TeleManagerImpl::TeleManagerImpl() ...@@ -881,6 +912,11 @@ TeleManagerImpl::TeleManagerImpl()
TeleManagerImpl::~TeleManagerImpl() TeleManagerImpl::~TeleManagerImpl()
{ {
// There may be unused conferences left opened, so close them.
// It should not make a problem to close already closed conference.
for (MapStringConference::iterator it = maAcceptedConferences.begin();
it != maAcceptedConferences.end(); ++it)
it->second->close();
if (mpFactory) if (mpFactory)
g_object_unref( mpFactory); g_object_unref( mpFactory);
if (mpClient) if (mpClient)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment