summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatúš Kukan <matus.kukan@gmail.com>2012-07-20 00:12:19 +0200
committerMatúš Kukan <matus.kukan@gmail.com>2012-07-20 12:46:59 +0200
commit37c67a137882cc1a9e113552dcab42a7d6337358 (patch)
tree5c1fa1c471f1719e70240a61689e8c9672771326
parentd41903eb7b6936bbf98639d39ddc7558409d63be (diff)
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
-rw-r--r--sc/source/ui/collab/contacts.cxx9
-rw-r--r--sc/source/ui/collab/sendfunc.cxx28
-rw-r--r--sc/source/ui/collab/sendfunc.hxx3
-rw-r--r--sc/source/ui/docshell/docsh.cxx2
-rw-r--r--tubes/inc/tubes/conference.hxx4
-rw-r--r--tubes/inc/tubes/constants.h4
-rw-r--r--tubes/inc/tubes/manager.hxx12
-rw-r--r--tubes/source/conference.cxx13
-rw-r--r--tubes/source/manager.cxx42
9 files changed, 93 insertions, 24 deletions
diff --git a/sc/source/ui/collab/contacts.cxx b/sc/source/ui/collab/contacts.cxx
index d81ff9a65b58..c2cc8b6488ef 100644
--- a/sc/source/ui/collab/contacts.cxx
+++ b/sc/source/ui/collab/contacts.cxx
@@ -98,11 +98,6 @@ class TubeContacts : public ModelessDialog
// Receiving file is not related to any document.
mpManager->sigFileReceived.connect( boost::bind(
&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
fprintf( stderr, "could not start session with %s\n",
tp_contact_get_identifier( pContact ) );
else
+ {
mpSender->SetCollaboration( pConference );
+ mpSender->SendFile( OStringToOUString(
+ pConference->getUuid(), RTL_TEXTENCODING_UTF8 ) );
+ }
}
}
diff --git a/sc/source/ui/collab/sendfunc.cxx b/sc/source/ui/collab/sendfunc.cxx
index d22e4ba3b143..4b3d1c92f769 100644
--- a/sc/source/ui/collab/sendfunc.cxx
+++ b/sc/source/ui/collab/sendfunc.cxx
@@ -39,6 +39,7 @@
#include <tubes/manager.hxx>
#include <tubes/conference.hxx>
#include <tubes/contact-list.hxx>
+#include <tubes/constants.h>
// new file send/recv fun ...
#include <com/sun/star/uno/Sequence.hxx>
@@ -232,12 +233,13 @@ void ScDocFuncSend::SendMessage( ScChangeOpWriter &rOp )
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();
- aTmpPath.Append( rtl::OUString( ".ods" ) );
+ aTmpPath.Append( OUString("_") );
+ aTmpPath.Append( sUuid );
+ aTmpPath.Append( OUString("_") );
+ aTmpPath.Append( OUString(".ods") );
rtl::OUString aFileURL;
::utl::LocalFileHelper::ConvertPhysicalNameToURL( aTmpPath, aFileURL );
@@ -416,22 +418,30 @@ sal_Bool ScDocFuncSend::MergeCells( const ScCellMergeOption& rOption, sal_Bool b
return ScDocFunc::MergeCells( rOption, bContents, bRecord, bApi );
}
-#ifdef INTERCEPT
-SC_DLLPRIVATE ScDocFunc *ScDocShell::CreateDocFunc()
+ScDocFunc *ScDocShell::CreateDocFunc()
{
if (getenv ("INTERCEPT"))
{
- boost::shared_ptr<ScDocFuncDirect> pDirect( new ScDocFuncDirect( *this ) );
+ ScDocFuncDirect* pDirect = new ScDocFuncDirect( *this );
boost::shared_ptr<ScDocFuncRecv> pReceiver( new ScDocFuncRecv( pDirect ) );
static boost::shared_ptr<ScDocFuncDemo> aDemoBus( new ScDocFuncDemo() );
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
return new ScDocFuncDirect( *this );
}
-#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/collab/sendfunc.hxx b/sc/source/ui/collab/sendfunc.hxx
index 981363358065..f9c2bcfaa239 100644
--- a/sc/source/ui/collab/sendfunc.hxx
+++ b/sc/source/ui/collab/sendfunc.hxx
@@ -229,7 +229,6 @@ class ScDocFuncSend : public ScDocFunc
TeleConference *mpConference;
void SendMessage( ScChangeOpWriter &rOp );
- void SendFile( const rtl::OUString &rURL );
public:
// FIXME: really ScDocFunc should be an abstract base, so
@@ -240,6 +239,8 @@ public:
void SetCollaboration( TeleConference* pConference );
TeleConference* GetConference();
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 EndListAction();
diff --git a/sc/source/ui/docshell/docsh.cxx b/sc/source/ui/docshell/docsh.cxx
index cfdd45590a46..2c3d5ac0c445 100644
--- a/sc/source/ui/docshell/docsh.cxx
+++ b/sc/source/ui/docshell/docsh.cxx
@@ -2500,10 +2500,12 @@ sal_Bool ScDocShell::HasAutomaticTableName( const String& rFilter )
|| rFilter.EqualsAscii( pFilterRtf );
}
+#ifndef ENABLE_TELEPATHY
ScDocFunc *ScDocShell::CreateDocFunc()
{
return new ScDocFuncDirect( *this );
}
+#endif
ScDocShell::ScDocShell( const ScDocShell& rShell ) :
SvRefBase(),
diff --git a/tubes/inc/tubes/conference.hxx b/tubes/inc/tubes/conference.hxx
index b35fddc4c5bb..29d4cefa2b04 100644
--- a/tubes/inc/tubes/conference.hxx
+++ b/tubes/inc/tubes/conference.hxx
@@ -47,7 +47,7 @@ class TeleConference
{
public:
- TeleConference( TeleManager* pManager, TpAccount *pAccount, TpDBusTubeChannel* pChannel );
+ TeleConference( TeleManager* pManager, TpAccount *pAccount, TpDBusTubeChannel* pChannel, const OString sUuid = OString() );
~TeleConference();
/// Close channel and call finalize()
@@ -77,6 +77,7 @@ public:
typedef void (*FileSentCallback)( bool aSuccess, 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 ---
// TODO: make friends instead
@@ -112,6 +113,7 @@ private:
TeleManager* mpManager;
TpAccount* mpAccount;
TpDBusTubeChannel* mpChannel;
+ OString msUuid;
gchar* mpAddress;
GDBusConnection* mpTube;
guint maObjectRegistrationId;
diff --git a/tubes/inc/tubes/constants.h b/tubes/inc/tubes/constants.h
index 447910ecec34..5c34534c8e37 100644
--- a/tubes/inc/tubes/constants.h
+++ b/tubes/inc/tubes/constants.h
@@ -45,6 +45,10 @@
* tp_simple_handler_new_with_am(). */
#define LIBO_CLIENT_SUFFIX "LibreOffice"
+/* Key value storing UUID for TeleConference
+ */
+#define LIBO_TUBES_UUID "LIBO_TUBES_UUID"
+
#endif // INCLUDED_TUBES_CONSTANTS_H
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/tubes/inc/tubes/manager.hxx b/tubes/inc/tubes/manager.hxx
index 4e0e3b42bced..9f1689148ac3 100644
--- a/tubes/inc/tubes/manager.hxx
+++ b/tubes/inc/tubes/manager.hxx
@@ -40,6 +40,7 @@
#include <tools/link.hxx>
#include <telepathy-glib/telepathy-glib.h>
#include <tubes/warnings_guard_boost_signals2.hpp>
+#include <map>
// For testing purposes, we might need more in future.
#define LIBO_TUBES_DBUS_INTERFACE "org.libreoffice.calc"
@@ -131,12 +132,16 @@ public:
*/
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();
boost::signals2::signal<void ( const rtl::OUString &localUri )> sigFileReceived;
- boost::signals2::signal<void (TeleConference*)> sigConferenceCreated;
-
/// Only for use with MainLoopFlusher
GMainLoop* getMainLoop() const;
@@ -184,7 +189,7 @@ public:
is something like org.libreoffice.calc, this modifies the names to
"LibreOffice"+pName and "org.libreoffice.calc"+pName to make tests not
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.
*/
static void addSuffixToNames( const char* pName );
@@ -205,6 +210,7 @@ public:
gpointer pUserData);
private:
+ void addConference( TeleConference* );
void ensureLegacyChannel( TpAccount* pAccount, TpContact* pBuddy );
bool mbChannelReadyHandlerInvoked : 1;
diff --git a/tubes/source/conference.cxx b/tubes/source/conference.cxx
index 97da5cfe0d80..da182098385b 100644
--- a/tubes/source/conference.cxx
+++ b/tubes/source/conference.cxx
@@ -28,6 +28,7 @@
#include <tubes/conference.hxx>
#include <tubes/manager.hxx>
+#include <tubes/constants.h>
#if defined SAL_LOG_INFO
@@ -196,16 +197,20 @@ void TeleConference::TubeAcceptedHandler(
g_error_free( pError);
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);
}
-TeleConference::TeleConference( TeleManager* pManager, TpAccount* pAccount, TpDBusTubeChannel* pChannel )
+TeleConference::TeleConference( TeleManager* pManager, TpAccount* pAccount, TpDBusTubeChannel* pChannel, const OString sUuid )
:
mpManager( pManager),
mpAccount( NULL),
mpChannel( NULL),
+ msUuid( sUuid),
mpAddress( NULL),
mpTube( NULL),
mbTubeOfferedHandlerInvoked( false)
@@ -272,9 +277,13 @@ bool TeleConference::offerTube()
if (!mpChannel)
return false;
+ GHashTable* pParameters = tp_asv_new (
+ LIBO_TUBES_UUID, G_TYPE_STRING, msUuid.getStr(),
+ NULL);
+
tp_dbus_tube_channel_offer_async(
mpChannel,
- NULL, // no parameters for now
+ pParameters,
&TeleConference::TubeOfferedHandler,
this);
diff --git a/tubes/source/manager.cxx b/tubes/source/manager.cxx
index 399e6743930a..4f6a6a8c00c4 100644
--- a/tubes/source/manager.cxx
+++ b/tubes/source/manager.cxx
@@ -86,6 +86,9 @@ public:
TeleManager::AccountManagerStatus meAccountManagerStatus;
bool mbAccountManagerReadyHandlerInvoked;
ContactList* mpContactList;
+ OString msCurrentUUID;
+ typedef std::map< OString, TeleConference* > MapStringConference;
+ MapStringConference maAcceptedConferences;
TeleManagerImpl();
~TeleManagerImpl();
@@ -124,9 +127,9 @@ void TeleManager::DBusChannelHandler(
SAL_INFO( "tubes", "accepting");
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();
- pManager->sigConferenceCreated( pConference );
+ pManager->addConference( pConference );
}
else
{
@@ -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)
{
TeleManager* pManager = reinterpret_cast<TeleManager*>(pUserData);
@@ -156,6 +182,11 @@ void TeleManager::TransferDone( EmpathyFTHandler *handler, TpFileTransferChannel
rtl::OUString aUri( uri, strlen( uri), RTL_TEXTENCODING_UTF8);
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 );
g_object_unref( handler);
@@ -616,7 +647,7 @@ TeleConference* TeleManager::startBuddySession( TpAccount *pAccount, TpContact *
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(
pChannelRequest, NULL, TeleManager_ChannelReadyHandler, pConference );
@@ -881,6 +912,11 @@ 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)
g_object_unref( mpFactory);
if (mpClient)