[Libreoffice-commits] .: Branch 'feature/tubes2' - 6 commits - officecfg/registry sc/inc sc/sdi sc/source sc/uiconfig

Matus Kukan mkukan at kemper.freedesktop.org
Wed Jun 27 08:21:52 PDT 2012


 officecfg/registry/data/org/openoffice/Office/UI/CalcCommands.xcu |    5 
 sc/inc/sc.hrc                                                     |    1 
 sc/sdi/cellsh.sdi                                                 |    1 
 sc/sdi/scalc.sdi                                                  |   25 
 sc/source/ui/collab/contacts.cxx                                  |   76 +
 sc/source/ui/collab/contacts.hrc                                  |    2 
 sc/source/ui/collab/contacts.src                                  |   14 
 sc/source/ui/collab/sendfunc.cxx                                  |  627 +++-------
 sc/source/ui/collab/sendfunc.hxx                                  |  267 ++++
 sc/source/ui/view/cellsh3.cxx                                     |   13 
 sc/uiconfig/scalc/menubar/menubar.xml                             |    2 
 11 files changed, 605 insertions(+), 428 deletions(-)

New commits:
commit b711bcff8a93ff751d555e49f73b424a4e7ab1b4
Author: Matúš Kukan <matus.kukan at gmail.com>
Date:   Sat Jun 16 22:52:18 2012 +0200

    tubes: add listen button to start TeleManager
    
    No more need to run soffice with LIBO_TUBES set.

diff --git a/sc/source/ui/collab/contacts.cxx b/sc/source/ui/collab/contacts.cxx
index 44821a5..085237b 100644
--- a/sc/source/ui/collab/contacts.cxx
+++ b/sc/source/ui/collab/contacts.cxx
@@ -30,6 +30,8 @@
 
 #include <vector>
 #include "contacts.hrc"
+#include "sendfunc.hxx"
+#include "docsh.hxx"
 #include "scresid.hxx"
 #include <svtools/filter.hxx>
 #include <tubes/manager.hxx>
@@ -45,10 +47,12 @@ class TubeContacts : public ModelessDialog
 {
     FixedLine               maLabel;
     PushButton              maBtnConnect;
+    PushButton              maBtnListen;
     SvxSimpleTableContainer maListContainer;
     SvxSimpleTable          maList;
 
     DECL_LINK( BtnConnectHdl, void * );
+    DECL_LINK( BtnListenHdl, void * );
 
     struct AccountContact
     {
@@ -59,6 +63,22 @@ class TubeContacts : public ModelessDialog
     };
     boost::ptr_vector<AccountContact> maACs;
 
+    void Listen()
+    {
+        ScDocShell *pScDocShell = reinterpret_cast<ScDocShell*> (SfxObjectShell::Current());
+        ScDocFunc *pDocFunc = pScDocShell ? &pScDocShell->GetDocFunc() : NULL;
+        ScDocFuncSend *pSender = reinterpret_cast<ScDocFuncSend*> (pDocFunc);
+        if (!pSender)
+        {
+            delete pDocFunc;
+            boost::shared_ptr<ScDocFuncDirect> pDirect( new ScDocFuncDirect( *pScDocShell ) );
+            boost::shared_ptr<ScDocFuncRecv> pReceiver( new ScDocFuncRecv( pDirect ) );
+            pSender = new ScDocFuncSend( *pScDocShell, pReceiver );
+            pDocFunc = pSender;
+        }
+        pSender->InitTeleManager( false );
+    }
+
     void StartBuddySession()
     {
         AccountContact *pAC = NULL;
@@ -83,10 +103,12 @@ public:
         ModelessDialog( NULL, ScResId( RID_SCDLG_CONTACTS ) ),
         maLabel( this, ScResId( FL_LABEL ) ),
         maBtnConnect( this, ScResId( BTN_CONNECT ) ),
+        maBtnListen( this, ScResId( BTN_LISTEN ) ),
         maListContainer( this, ScResId( CTL_LIST ) ),
         maList( maListContainer )
     {
         maBtnConnect.SetClickHdl( LINK( this, TubeContacts, BtnConnectHdl ) );
+        maBtnListen.SetClickHdl( LINK( this, TubeContacts, BtnListenHdl ) );
 
         static long aStaticTabs[]=
         {
@@ -160,6 +182,13 @@ IMPL_LINK_NOARG( TubeContacts, BtnConnectHdl )
     return 0;
 }
 
+IMPL_LINK_NOARG( TubeContacts, BtnListenHdl )
+{
+    Listen();
+    Close();
+    return 0;
+}
+
 } // anonymous namespace
 #endif
 
diff --git a/sc/source/ui/collab/contacts.hrc b/sc/source/ui/collab/contacts.hrc
index dd3fcc4..cb69916 100644
--- a/sc/source/ui/collab/contacts.hrc
+++ b/sc/source/ui/collab/contacts.hrc
@@ -3,6 +3,7 @@
 #define FL_LABEL             1
 #define CTL_LIST             2
 #define BTN_CONNECT          3
+#define BTN_LISTEN           4
 
 #define STR_HEADER_ALIAS     20
 #define STR_HEADER_NAME      21
diff --git a/sc/source/ui/collab/contacts.src b/sc/source/ui/collab/contacts.src
index 1689823..0de2849 100644
--- a/sc/source/ui/collab/contacts.src
+++ b/sc/source/ui/collab/contacts.src
@@ -21,10 +21,16 @@ ModelessDialog RID_SCDLG_CONTACTS
     };
     PushButton BTN_CONNECT
     {
-        Pos = MAP_APPFONT( 8 , 200 );
+        Pos = MAP_APPFONT( 70 , 200 );
         Size = MAP_APPFONT( 50 , 10 );
         Text [ en-US ] = "Collaborate";
     };
+    PushButton BTN_LISTEN
+    {
+        Pos = MAP_APPFONT( 8 , 200 );
+        Size = MAP_APPFONT( 50 , 10 );
+        Text [ en-US ] = "Listen";
+    };
     Control CTL_LIST
     {
         Pos = MAP_APPFONT ( 8 , 10 ) ;
commit 6d74d44900a8dfb80a78fb81af4dccdf11cc47fd
Author: Matúš Kukan <matus.kukan at gmail.com>
Date:   Mon Jun 18 23:15:04 2012 +0200

    tubes: create InitTeleManager method

diff --git a/sc/source/ui/collab/sendfunc.cxx b/sc/source/ui/collab/sendfunc.cxx
index ee623e4..262273d 100644
--- a/sc/source/ui/collab/sendfunc.cxx
+++ b/sc/source/ui/collab/sendfunc.cxx
@@ -287,6 +287,29 @@ void ScDocFuncSend::SetCollaboration( TeleManager *pManager )
     mpManager = pManager;
 }
 
+bool ScDocFuncSend::InitTeleManager( bool bIsMaster )
+{
+    if (mpManager)
+    {
+        fprintf( stderr, "TeleManager is already connected.\n" );
+        return true;
+    }
+    TeleManager *pManager = TeleManager::get( !bIsMaster );
+    pManager->sigPacketReceived.connect( boost::bind(
+            &ScDocFuncRecv::packetReceived, mpDirect.get(), _1, _2 ));
+    pManager->sigFileReceived.connect( boost::bind(
+            &ScDocFuncRecv::fileReceived, mpDirect.get(), _1 ));
+
+    if (pManager->connect())
+    {
+        pManager->prepareAccountManager();
+        mpManager = pManager;
+        return true;
+    }
+    fprintf( stderr, "Could not connect.\n" );
+    return false;
+}
+
 void ScDocFuncSend::EnterListAction( sal_uInt16 nNameResId )
 {
     // Want to group these operations for the other side ...
@@ -422,22 +445,7 @@ SC_DLLPRIVATE ScDocFunc *ScDocShell::CreateDocFunc()
         boost::shared_ptr<ScDocFuncDirect> pDirect( new ScDocFuncDirect( *this ) );
         boost::shared_ptr<ScDocFuncRecv> pReceiver( new ScDocFuncRecv( pDirect ) );
         ScDocFuncSend* pSender = new ScDocFuncSend( *this, pReceiver );
-        TeleManager *pManager = TeleManager::get( !bIsMaster );
-
-        pManager->sigPacketReceived.connect(
-                boost::bind( &ScDocFuncRecv::packetReceived, pReceiver.get(), _1, _2 ));
-        pManager->sigFileReceived.connect(
-                boost::bind( &ScDocFuncRecv::fileReceived, pReceiver.get(), _1 ));
-
-        if (pManager->connect())
-        {
-            pManager->prepareAccountManager();
-            pSender->SetCollaboration( pManager );
-        }
-        else
-        {
-            fprintf( stderr, "Could not connect.\n");
-        }
+        pSender->InitTeleManager( bIsMaster );
         return pSender;
     }
     else
diff --git a/sc/source/ui/collab/sendfunc.hxx b/sc/source/ui/collab/sendfunc.hxx
index bd388dd..dcb30aa 100644
--- a/sc/source/ui/collab/sendfunc.hxx
+++ b/sc/source/ui/collab/sendfunc.hxx
@@ -238,6 +238,7 @@ public:
     virtual ~ScDocFuncSend() {}
 
     void                SetCollaboration( TeleManager *pManager );
+    bool                InitTeleManager( bool bIsMaster );
 
     virtual void        EnterListAction( sal_uInt16 nNameResId );
     virtual void        EndListAction();
commit 7dd3e11f36a246023ba52dbb73f4022dbb28c1fd
Author: Matúš Kukan <matus.kukan at gmail.com>
Date:   Sat Jun 16 22:39:35 2012 +0200

    tubes: extract class definitions to sendfunc.hxx

diff --git a/sc/source/ui/collab/sendfunc.cxx b/sc/source/ui/collab/sendfunc.cxx
index a4a8e23..ee623e4 100644
--- a/sc/source/ui/collab/sendfunc.cxx
+++ b/sc/source/ui/collab/sendfunc.cxx
@@ -35,6 +35,7 @@
 #include "contacts.hxx"
 #include "docsh.hxx"
 #include "docfunc.hxx"
+#include "sendfunc.hxx"
 #include <tubes/manager.hxx>
 #include <tubes/conference.hxx>
 #include <tubes/contact-list.hxx>
@@ -57,18 +58,6 @@ namespace css = ::com::sun::star;
 
 namespace {
 
-rtl::OUString cellToString( ScBaseCell *pCell )
-{
-    (void)pCell; // FIXME: implement me
-    return rtl::OUString();
-}
-
-ScBaseCell *stringToCell( const rtl::OUString &rString )
-{
-    (void)rString; // FIXME: implement me
-    return NULL;
-}
-
 bool isCollabMode( bool& rbMaster )
 {
     const char* pEnv = getenv ("LIBO_TUBES");
@@ -81,234 +70,50 @@ bool isCollabMode( bool& rbMaster )
     return false;
 }
 
+}
 
-// Ye noddy mangling - needs improvement ...
-// method name ';' then arguments ; separated
-class ScChangeOpWriter
+// FIXME: really ScDocFunc should be an abstract base
+ScDocFuncRecv::ScDocFuncRecv( boost::shared_ptr<ScDocFuncDirect>& pChain )
+    : mpChain( pChain )
 {
-  rtl::OUStringBuffer aMessage;
-  void appendSeparator()
-  {
-      aMessage.append( sal_Unicode( ';' ) );
-  }
-public:
-
-  ScChangeOpWriter( const char *pName )
-  {
-      aMessage.appendAscii( pName );
-      appendSeparator();
-  }
-
-  void appendString( const rtl::OUString &rStr )
-  {
-      if ( rStr.indexOf( sal_Unicode( '"' ) ) >= 0 ||
-           rStr.indexOf( sal_Unicode( ';' ) ) >= 0 )
-      {
-          String aQuoted( rStr );
-          ScGlobal::AddQuotes( aQuoted, sal_Unicode( '"' ) );
-          aMessage.append( aQuoted );
-      }
-      else
-          aMessage.append( rStr );
-      appendSeparator();
-  }
-
-  void appendAddress( const ScAddress &rPos )
-  {
-      rtl::OUString aStr;
-      rPos.Format( aStr, SCA_VALID );
-      aMessage.append( aStr );
-      appendSeparator();
-  }
-
-  void appendInt( sal_Int32 i )
-  {
-      aMessage.append( i );
-      appendSeparator();
-  }
-
-  void appendBool( sal_Bool b )
-  {
-      aMessage.appendAscii( b ? "true" : "false" );
-      appendSeparator();
-  }
-
-  void appendCell( ScBaseCell *pCell )
-  {
-      appendString( cellToString( pCell ) );
-  }
-
-  rtl::OString toString()
-  {
-      return rtl::OUStringToOString( aMessage.toString(), RTL_TEXTENCODING_UTF8 );
-  }
-};
-
-struct ProtocolError {
-    const char *message;
-};
-
-class ScChangeOpReader {
-    std::vector< rtl::OUString > maArgs;
-
-public:
-
-    ScChangeOpReader( const rtl::OUString &rString)
-    {
-        // will need to handle escaping etc.
-        // Surely someone else wrote this before ! [!?]
-        enum {
-            IN_TEXT, CHECK_QUOTE, FIND_LAST_QUOTE, SKIP_SEMI
-        } eState = CHECK_QUOTE;
-
-        sal_Int32 nStart = 0;
-        for (sal_Int32 n = 0; n < rString.getLength(); n++)
-        {
-            if (rString[n] == '\\')
-            {
-                n++; // skip next char
-                continue;
-            }
-            switch (eState) {
-            case CHECK_QUOTE:
-                if (rString[n] == '"')
-                {
-                    nStart = n + 1;
-                    eState = FIND_LAST_QUOTE;
-                    break;
-                }
-                // else drop through
-            case IN_TEXT:
-                if (rString[n] == ';')
-                {
-                    maArgs.push_back( rString.copy( nStart, n - nStart ) );
-                    nStart = n + 1;
-                    eState = CHECK_QUOTE;
-                }
-                break;
-            case FIND_LAST_QUOTE:
-                if (rString[n] == '"')
-                {
-                    maArgs.push_back( rString.copy( nStart, n - nStart ) );
-                    eState = SKIP_SEMI;
-                    break;
-                }
-                break;
-            case SKIP_SEMI:
-                if (rString[n] == ';')
-                {
-                    nStart = n + 1;
-                    eState = CHECK_QUOTE;
-                }
-                break;
-            }
-        }
-        if ( nStart < rString.getLength())
-            maArgs.push_back( rString.copy( nStart, rString.getLength() - nStart ) );
-
-        for (size_t i = 0; i < maArgs.size(); i++)
-            fprintf( stderr, "arg %d: '%s'\n", (int)i,
-                     rtl::OUStringToOString( maArgs[i], RTL_TEXTENCODING_UTF8).getStr() );
-    }
-    ~ScChangeOpReader() {}
-
-    rtl::OUString getMethod()
-    {
-        return maArgs[0];
-    }
-
-    size_t getArgCount() { return maArgs.size(); }
-
-    rtl::OUString getString( sal_Int32 n )
-    {
-        if (n > 0 && (size_t)n < getArgCount() )
-        {
-            String aUStr( maArgs[ n ] );
-            ScGlobal::EraseQuotes( aUStr );
-            return aUStr;
-        } else
-            return rtl::OUString();
-    }
-
-    ScAddress getAddress( sal_Int32 n )
-    {
-        ScAddress aAddr;
-        rtl::OUString aToken( getString( n ) );
-        aAddr.Parse( aToken );
-        return aAddr;
-    }
-
-    sal_Int32 getInt( sal_Int32 n )
-    {
-        return getString( n ).toInt32();
-    }
-
-    bool getBool( sal_Int32 n )
-    {
-        return getString( n ).equalsIgnoreAsciiCase( "true" );
-    }
-
-    ScBaseCell *getCell( sal_Int32 n )
-    {
-        return stringToCell( getString( n ) );
-    }
-};
-
+    fprintf( stderr, "Receiver created !\n" );
+}
 
-class ScDocFuncRecv
+void ScDocFuncRecv::RecvMessage( const rtl::OString &rString )
 {
-    boost::shared_ptr<ScDocFuncDirect>  mpChain;
-
-protected:
-    ScDocFuncRecv() {}
-public:
-    // FIXME: really ScDocFunc should be an abstract base
-    ScDocFuncRecv( boost::shared_ptr<ScDocFuncDirect>& pChain )
-        : mpChain( pChain )
-    {
-        fprintf( stderr, "Receiver created !\n" );
-    }
-    virtual ~ScDocFuncRecv() {}
-
-    void packetReceived( TeleConference*, TelePacket &rPacket );
-
-    virtual void fileReceived( const rtl::OUString &rStr );
-    virtual void RecvMessage( const rtl::OString &rString )
-    {
-        try {
-            ScChangeOpReader aReader( rtl::OUString( rString.getStr(),
-                                                     rString.getLength(),
-                                                     RTL_TEXTENCODING_UTF8 ) );
-            // FIXME: have some hash to enumeration mapping here
-            if ( aReader.getMethod() == "setNormalString" )
-                mpChain->SetNormalString( aReader.getAddress( 1 ), aReader.getString( 2 ),
-                                          aReader.getBool( 3 ) );
-            else if ( aReader.getMethod() == "putCell" )
-            {
-                ScBaseCell *pNewCell = aReader.getCell( 2 );
-                if ( pNewCell )
-                    mpChain->PutCell( aReader.getAddress( 1 ), pNewCell, aReader.getBool( 3 ) );
-            }
-            else if ( aReader.getMethod() == "enterListAction" )
-                mpChain->EnterListAction( aReader.getInt( 1 ) );
-            else if ( aReader.getMethod() == "endListAction" )
-                mpChain->EndListAction();
-            else if ( aReader.getMethod() == "showNote" )
-                mpChain->ShowNote( aReader.getAddress( 1 ), aReader.getBool( 2 ) );
-            else if ( aReader.getMethod() == "setNoteText" )
-                mpChain->SetNoteText( aReader.getAddress( 1 ), aReader.getString( 2 ),
+    try {
+        ScChangeOpReader aReader( rtl::OUString( rString.getStr(),
+                                                 rString.getLength(),
+                                                 RTL_TEXTENCODING_UTF8 ) );
+        // FIXME: have some hash to enumeration mapping here
+        if ( aReader.getMethod() == "setNormalString" )
+            mpChain->SetNormalString( aReader.getAddress( 1 ), aReader.getString( 2 ),
                                       aReader.getBool( 3 ) );
-            else if ( aReader.getMethod() == "renameTable" )
-                mpChain->RenameTable( aReader.getInt( 1 ), aReader.getString( 2 ),
-                                      aReader.getBool( 3 ), aReader.getBool( 4 ) );
-            else
-                fprintf( stderr, "Error: unknown message '%s' (%d)\n",
-                         rString.getStr(), (int)aReader.getArgCount() );
-        } catch (const ProtocolError &e) {
-            fprintf( stderr, "Error: protocol twisting '%s'\n", e.message );
+        else if ( aReader.getMethod() == "putCell" )
+        {
+            ScBaseCell *pNewCell = aReader.getCell( 2 );
+            if ( pNewCell )
+                mpChain->PutCell( aReader.getAddress( 1 ), pNewCell, aReader.getBool( 3 ) );
         }
+        else if ( aReader.getMethod() == "enterListAction" )
+            mpChain->EnterListAction( aReader.getInt( 1 ) );
+        else if ( aReader.getMethod() == "endListAction" )
+            mpChain->EndListAction();
+        else if ( aReader.getMethod() == "showNote" )
+            mpChain->ShowNote( aReader.getAddress( 1 ), aReader.getBool( 2 ) );
+        else if ( aReader.getMethod() == "setNoteText" )
+            mpChain->SetNoteText( aReader.getAddress( 1 ), aReader.getString( 2 ),
+                                  aReader.getBool( 3 ) );
+        else if ( aReader.getMethod() == "renameTable" )
+            mpChain->RenameTable( aReader.getInt( 1 ), aReader.getString( 2 ),
+                                  aReader.getBool( 3 ), aReader.getBool( 4 ) );
+        else
+            fprintf( stderr, "Error: unknown message '%s' (%d)\n",
+                     rString.getStr(), (int)aReader.getArgCount() );
+    } catch (const ProtocolError &e) {
+        fprintf( stderr, "Error: protocol twisting '%s'\n", e.message );
     }
-};
+}
 
 void ScDocFuncRecv::packetReceived( TeleConference*, TelePacket &rPacket )
 {
@@ -422,187 +227,178 @@ extern "C"
     }
 }
 
-class ScDocFuncSend : public ScDocFunc
+void ScDocFuncSend::SendMessage( ScChangeOpWriter &rOp )
 {
-    boost::shared_ptr<ScDocFuncRecv>    mpDirect;
-    TeleManager                         *mpManager;
-
-    void SendMessage( ScChangeOpWriter &rOp )
+    fprintf( stderr, "Op: '%s'\n", rOp.toString().getStr() );
+    if (mpManager)
     {
-        fprintf( stderr, "Op: '%s'\n", rOp.toString().getStr() );
-        if (mpManager)
-        {
-            TelePacket aPacket( "sender", rOp.toString().getStr(), rOp.toString().getLength() );
-            mpManager->sendPacket( aPacket );
-        }
-        else // local demo mode
-            mpDirect->RecvMessage( rOp.toString() );
+        TelePacket aPacket( "sender", rOp.toString().getStr(), rOp.toString().getLength() );
+        mpManager->sendPacket( aPacket );
     }
+    else // local demo mode
+        mpDirect->RecvMessage( rOp.toString() );
+}
 
-    void SendFile( const rtl::OUString &rURL )
-    {
-        (void)rURL;
+void ScDocFuncSend::SendFile( const rtl::OUString &rURL )
+{
+    (void)rURL;
 
-        String aTmpPath = utl::TempFile::CreateTempName();
-        aTmpPath.Append( rtl::OUString( ".ods" ) );
+    String aTmpPath = utl::TempFile::CreateTempName();
+    aTmpPath.Append( rtl::OUString( ".ods" ) );
 
-        rtl::OUString aFileURL;
-        ::utl::LocalFileHelper::ConvertPhysicalNameToURL( aTmpPath, aFileURL );
+    rtl::OUString aFileURL;
+    ::utl::LocalFileHelper::ConvertPhysicalNameToURL( aTmpPath, aFileURL );
 
-        ::comphelper::MediaDescriptor aDescriptor;
-        // some issue with hyperlinks:
-        aDescriptor[::comphelper::MediaDescriptor::PROP_DOCUMENTBASEURL()] <<= ::rtl::OUString();
-        try {
-            css::uno::Reference< css::document::XDocumentRecovery > xDocRecovery(
-                        rDocShell.GetBaseModel(), css::uno::UNO_QUERY_THROW);
+    ::comphelper::MediaDescriptor aDescriptor;
+    // some issue with hyperlinks:
+    aDescriptor[::comphelper::MediaDescriptor::PROP_DOCUMENTBASEURL()] <<= ::rtl::OUString();
+    try {
+        css::uno::Reference< css::document::XDocumentRecovery > xDocRecovery(
+                    rDocShell.GetBaseModel(), css::uno::UNO_QUERY_THROW);
 
-            xDocRecovery->storeToRecoveryFile( aFileURL, aDescriptor.getAsConstPropertyValueList() );
-        } catch (const css::uno::Exception &ex) {
-            fprintf( stderr, "exception foo !\n" );
-        }
+        xDocRecovery->storeToRecoveryFile( aFileURL, aDescriptor.getAsConstPropertyValueList() );
+    } catch (const css::uno::Exception &ex) {
+        fprintf( stderr, "exception foo !\n" );
+    }
 
-        fprintf( stderr, "Temp file is '%s'\n",
-                 rtl::OUStringToOString( aFileURL, RTL_TEXTENCODING_UTF8 ).getStr() );
+    fprintf( stderr, "Temp file is '%s'\n",
+             rtl::OUStringToOString( aFileURL, RTL_TEXTENCODING_UTF8 ).getStr() );
 
-        if (mpManager)
-            mpManager->sendFile( aFileURL, file_sent_cb, NULL );
-        else
-            mpDirect->fileReceived( aFileURL );
+    if (mpManager)
+        mpManager->sendFile( aFileURL, file_sent_cb, NULL );
+    else
+        mpDirect->fileReceived( aFileURL );
 
-        // FIXME: unlink the file after send ...
-    }
+    // FIXME: unlink the file after send ...
+}
 
-public:
-    // FIXME: really ScDocFunc should be an abstract base, so
-    // we don't need the rDocSh hack/pointer
-    ScDocFuncSend( ScDocShell& rDocSh, boost::shared_ptr<ScDocFuncRecv> pDirect )
-            : ScDocFunc( rDocSh ),
-            mpDirect( pDirect ),
-            mpManager( NULL )
-    {
-        fprintf( stderr, "Sender created !\n" );
-    }
-    virtual ~ScDocFuncSend() {}
+// FIXME: really ScDocFunc should be an abstract base, so
+// we don't need the rDocSh hack/pointer
+ScDocFuncSend::ScDocFuncSend( ScDocShell& rDocSh, boost::shared_ptr<ScDocFuncRecv> pDirect )
+        : ScDocFunc( rDocSh ),
+        mpDirect( pDirect ),
+        mpManager( NULL )
+{
+    fprintf( stderr, "Sender created !\n" );
+}
 
-    void SetCollaboration( TeleManager *pManager )
-    {
-        mpManager = pManager;
-    }
+void ScDocFuncSend::SetCollaboration( TeleManager *pManager )
+{
+    mpManager = pManager;
+}
 
-    virtual void EnterListAction( sal_uInt16 nNameResId )
-    {
-        // Want to group these operations for the other side ...
-        String aUndo( ScGlobal::GetRscString( nNameResId ) );
-        ScChangeOpWriter aOp( "enterListAction" );
-        aOp.appendInt( nNameResId ); // nasty but translate-able ...
-        SendMessage( aOp );
-    }
-    virtual void EndListAction()
-    {
-        ScChangeOpWriter aOp( "endListAction" );
-        SendMessage( aOp );
-    }
+void ScDocFuncSend::EnterListAction( sal_uInt16 nNameResId )
+{
+    // Want to group these operations for the other side ...
+    String aUndo( ScGlobal::GetRscString( nNameResId ) );
+    ScChangeOpWriter aOp( "enterListAction" );
+    aOp.appendInt( nNameResId ); // nasty but translate-able ...
+    SendMessage( aOp );
+}
 
-    virtual sal_Bool SetNormalString( const ScAddress& rPos, const String& rText, sal_Bool bApi )
-    {
-        ScChangeOpWriter aOp( "setNormalString" );
-        aOp.appendAddress( rPos );
-        aOp.appendString( rText );
-        aOp.appendBool( bApi );
-        SendMessage( aOp );
+void ScDocFuncSend::EndListAction()
+{
+    ScChangeOpWriter aOp( "endListAction" );
+    SendMessage( aOp );
+}
 
-        if ( rtl::OUString( rText ) == "saveme" )
-            SendFile( rText );
+sal_Bool ScDocFuncSend::SetNormalString( const ScAddress& rPos, const String& rText, sal_Bool bApi )
+{
+    ScChangeOpWriter aOp( "setNormalString" );
+    aOp.appendAddress( rPos );
+    aOp.appendString( rText );
+    aOp.appendBool( bApi );
+    SendMessage( aOp );
 
-        if ( rtl::OUString( rText ) == "contacts" )
-            tubes::createContacts( mpManager );
+    if ( rtl::OUString( rText ) == "saveme" )
+        SendFile( rText );
 
-        return true; // needs some code auditing action
-    }
+    if ( rtl::OUString( rText ) == "contacts" )
+        tubes::createContacts( mpManager );
 
-    virtual sal_Bool PutCell( const ScAddress& rPos, ScBaseCell* pNewCell, sal_Bool bApi )
-    {
-        fprintf( stderr, "put cell '%p' type %d %d\n", pNewCell, pNewCell->GetCellType(), bApi );
-        ScChangeOpWriter aOp( "putCell" );
-        aOp.appendAddress( rPos );
-        aOp.appendCell( pNewCell );
-        aOp.appendBool( bApi );
-        SendMessage( aOp );
-        return true; // needs some code auditing action
-    }
+    return true; // needs some code auditing action
+}
 
-    virtual sal_Bool PutData( const ScAddress& rPos, ScEditEngineDefaulter& rEngine,
-                              sal_Bool bInterpret, sal_Bool bApi )
-    {
-        fprintf( stderr, "put data\n" );
-        return ScDocFunc::PutData( rPos, rEngine, bInterpret, bApi );
-    }
+sal_Bool ScDocFuncSend::PutCell( const ScAddress& rPos, ScBaseCell* pNewCell, sal_Bool bApi )
+{
+    fprintf( stderr, "put cell '%p' type %d %d\n", pNewCell, pNewCell->GetCellType(), bApi );
+    ScChangeOpWriter aOp( "putCell" );
+    aOp.appendAddress( rPos );
+    aOp.appendCell( pNewCell );
+    aOp.appendBool( bApi );
+    SendMessage( aOp );
+    return true; // needs some code auditing action
+}
 
-    virtual sal_Bool SetCellText( const ScAddress& rPos, const String& rText,
-                                  sal_Bool bInterpret, sal_Bool bEnglish, sal_Bool bApi,
-                                  const String& rFormulaNmsp,
-                                  const formula::FormulaGrammar::Grammar eGrammar )
-    {
-        fprintf( stderr, "set cell text '%s'\n",
-                 rtl::OUStringToOString( rText, RTL_TEXTENCODING_UTF8 ).getStr() );
-        return ScDocFunc::SetCellText( rPos, rText, bInterpret, bEnglish, bApi, rFormulaNmsp, eGrammar );
-    }
+sal_Bool ScDocFuncSend::PutData( const ScAddress& rPos, ScEditEngineDefaulter& rEngine,
+                          sal_Bool bInterpret, sal_Bool bApi )
+{
+    fprintf( stderr, "put data\n" );
+    return ScDocFunc::PutData( rPos, rEngine, bInterpret, bApi );
+}
 
-    virtual bool ShowNote( const ScAddress& rPos, bool bShow = true )
-    {
-        ScChangeOpWriter aOp( "showNote" );
-        aOp.appendAddress( rPos );
-        aOp.appendBool( bShow );
-        SendMessage( aOp );
-        return true; // needs some code auditing action
-    }
+sal_Bool ScDocFuncSend::SetCellText( const ScAddress& rPos, const String& rText,
+                              sal_Bool bInterpret, sal_Bool bEnglish, sal_Bool bApi,
+                              const String& rFormulaNmsp,
+                              const formula::FormulaGrammar::Grammar eGrammar )
+{
+    fprintf( stderr, "set cell text '%s'\n",
+             rtl::OUStringToOString( rText, RTL_TEXTENCODING_UTF8 ).getStr() );
+    return ScDocFunc::SetCellText( rPos, rText, bInterpret, bEnglish, bApi, rFormulaNmsp, eGrammar );
+}
 
-    virtual bool SetNoteText( const ScAddress& rPos, const String& rNoteText, sal_Bool bApi )
-    {
-        ScChangeOpWriter aOp( "setNoteText" );
-        aOp.appendAddress( rPos );
-        aOp.appendString( rNoteText );
-        aOp.appendBool( bApi );
-        SendMessage( aOp );
-        return true; // needs some code auditing action
-    }
+bool ScDocFuncSend::ShowNote( const ScAddress& rPos, bool bShow )
+{
+    ScChangeOpWriter aOp( "showNote" );
+    aOp.appendAddress( rPos );
+    aOp.appendBool( bShow );
+    SendMessage( aOp );
+    return true; // needs some code auditing action
+}
 
-    virtual sal_Bool RenameTable( SCTAB nTab, const String& rName,
-                                  sal_Bool bRecord, sal_Bool bApi )
-    {
-        ScChangeOpWriter aOp( "renameTable" );
-        aOp.appendInt( nTab );
-        aOp.appendString( rName );
-        aOp.appendBool( bRecord );
-        aOp.appendBool( bApi );
-        SendMessage( aOp );
-        return true; // needs some code auditing action
-    }
+bool ScDocFuncSend::SetNoteText( const ScAddress& rPos, const String& rNoteText, sal_Bool bApi )
+{
+    ScChangeOpWriter aOp( "setNoteText" );
+    aOp.appendAddress( rPos );
+    aOp.appendString( rNoteText );
+    aOp.appendBool( bApi );
+    SendMessage( aOp );
+    return true; // needs some code auditing action
+}
 
-    virtual sal_Bool ApplyAttributes( const ScMarkData& rMark, const ScPatternAttr& rPattern,
-                                      sal_Bool bRecord, sal_Bool bApi )
-    {
-        fprintf( stderr, "Apply Attributes\n" );
-        return ScDocFunc::ApplyAttributes( rMark, rPattern, bRecord, bApi );
-    }
+sal_Bool ScDocFuncSend::RenameTable( SCTAB nTab, const String& rName,
+                              sal_Bool bRecord, sal_Bool bApi )
+{
+    ScChangeOpWriter aOp( "renameTable" );
+    aOp.appendInt( nTab );
+    aOp.appendString( rName );
+    aOp.appendBool( bRecord );
+    aOp.appendBool( bApi );
+    SendMessage( aOp );
+    return true; // needs some code auditing action
+}
 
-    virtual sal_Bool ApplyStyle( const ScMarkData& rMark, const String& rStyleName,
-                                 sal_Bool bRecord, sal_Bool bApi )
-    {
-        fprintf( stderr, "Apply Style '%s'\n",
-                 rtl::OUStringToOString( rStyleName, RTL_TEXTENCODING_UTF8 ).getStr() );
-        return ScDocFunc::ApplyStyle( rMark, rStyleName, bRecord, bApi );
-    }
+sal_Bool ScDocFuncSend::ApplyAttributes( const ScMarkData& rMark, const ScPatternAttr& rPattern,
+                                  sal_Bool bRecord, sal_Bool bApi )
+{
+    fprintf( stderr, "Apply Attributes\n" );
+    return ScDocFunc::ApplyAttributes( rMark, rPattern, bRecord, bApi );
+}
 
-    virtual sal_Bool MergeCells( const ScCellMergeOption& rOption, sal_Bool bContents,
-                                 sal_Bool bRecord, sal_Bool bApi )
-    {
-        fprintf( stderr, "Merge cells\n" );
-        return ScDocFunc::MergeCells( rOption, bContents, bRecord, bApi );
-    }
-};
+sal_Bool ScDocFuncSend::ApplyStyle( const ScMarkData& rMark, const String& rStyleName,
+                             sal_Bool bRecord, sal_Bool bApi )
+{
+    fprintf( stderr, "Apply Style '%s'\n",
+             rtl::OUStringToOString( rStyleName, RTL_TEXTENCODING_UTF8 ).getStr() );
+    return ScDocFunc::ApplyStyle( rMark, rStyleName, bRecord, bApi );
+}
 
-} // anonymous namespace
+sal_Bool ScDocFuncSend::MergeCells( const ScCellMergeOption& rOption, sal_Bool bContents,
+                             sal_Bool bRecord, sal_Bool bApi )
+{
+    fprintf( stderr, "Merge cells\n" );
+    return ScDocFunc::MergeCells( rOption, bContents, bRecord, bApi );
+}
 
 SC_DLLPRIVATE ScDocFunc *ScDocShell::CreateDocFunc()
 {
diff --git a/sc/source/ui/collab/sendfunc.hxx b/sc/source/ui/collab/sendfunc.hxx
new file mode 100644
index 0000000..bd388dd
--- /dev/null
+++ b/sc/source/ui/collab/sendfunc.hxx
@@ -0,0 +1,266 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef _SENDFUNC_HXX_
+#define _SENDFUNC_HXX_
+
+#include <sal/config.h>
+
+#include "cell.hxx"
+#include "docfunc.hxx"
+#include <tubes/conference.hxx>
+#include <tubes/manager.hxx>
+#include <tubes/packet.hxx>
+
+namespace {
+
+rtl::OUString cellToString( ScBaseCell *pCell )
+{
+    (void)pCell; // FIXME: implement me
+    return rtl::OUString();
+}
+
+ScBaseCell *stringToCell( const rtl::OUString &rString )
+{
+    (void)rString; // FIXME: implement me
+    return NULL;
+}
+
+// Ye noddy mangling - needs improvement ...
+// method name ';' then arguments ; separated
+class ScChangeOpWriter
+{
+    rtl::OUStringBuffer aMessage;
+    void appendSeparator()
+    {
+        aMessage.append( sal_Unicode( ';' ) );
+    }
+
+public:
+    ScChangeOpWriter( const char *pName )
+    {
+        aMessage.appendAscii( pName );
+        appendSeparator();
+    }
+
+    void appendString( const rtl::OUString &rStr )
+    {
+        if ( rStr.indexOf( sal_Unicode( '"' ) ) >= 0 ||
+             rStr.indexOf( sal_Unicode( ';' ) ) >= 0 )
+        {
+            String aQuoted( rStr );
+            ScGlobal::AddQuotes( aQuoted, sal_Unicode( '"' ) );
+            aMessage.append( aQuoted );
+        }
+        else
+            aMessage.append( rStr );
+        appendSeparator();
+    }
+
+    void appendAddress( const ScAddress &rPos )
+    {
+        rtl::OUString aStr;
+        rPos.Format( aStr, SCA_VALID );
+        aMessage.append( aStr );
+        appendSeparator();
+    }
+
+    void appendInt( sal_Int32 i )
+    {
+        aMessage.append( i );
+        appendSeparator();
+    }
+
+    void appendBool( sal_Bool b )
+    {
+        aMessage.appendAscii( b ? "true" : "false" );
+        appendSeparator();
+    }
+
+    void appendCell( ScBaseCell *pCell )
+    {
+        appendString( cellToString( pCell ) );
+    }
+
+    rtl::OString toString()
+    {
+        return rtl::OUStringToOString( aMessage.toString(), RTL_TEXTENCODING_UTF8 );
+    }
+};
+
+struct ProtocolError {
+    const char *message;
+};
+
+class ScChangeOpReader {
+    std::vector< rtl::OUString > maArgs;
+
+public:
+    ScChangeOpReader( const rtl::OUString &rString)
+    {
+        // will need to handle escaping etc.
+        // Surely someone else wrote this before ! [!?]
+        enum {
+            IN_TEXT, CHECK_QUOTE, FIND_LAST_QUOTE, SKIP_SEMI
+        } eState = CHECK_QUOTE;
+
+        sal_Int32 nStart = 0;
+        for (sal_Int32 n = 0; n < rString.getLength(); n++)
+        {
+            if (rString[n] == '\\')
+            {
+                n++; // skip next char
+                continue;
+            }
+            switch (eState) {
+            case CHECK_QUOTE:
+                if (rString[n] == '"')
+                {
+                    nStart = n + 1;
+                    eState = FIND_LAST_QUOTE;
+                    break;
+                }
+                // else drop through
+            case IN_TEXT:
+                if (rString[n] == ';')
+                {
+                    maArgs.push_back( rString.copy( nStart, n - nStart ) );
+                    nStart = n + 1;
+                    eState = CHECK_QUOTE;
+                }
+                break;
+            case FIND_LAST_QUOTE:
+                if (rString[n] == '"')
+                {
+                    maArgs.push_back( rString.copy( nStart, n - nStart ) );
+                    eState = SKIP_SEMI;
+                    break;
+                }
+                break;
+            case SKIP_SEMI:
+                if (rString[n] == ';')
+                {
+                    nStart = n + 1;
+                    eState = CHECK_QUOTE;
+                }
+                break;
+            }
+        }
+        if ( nStart < rString.getLength())
+            maArgs.push_back( rString.copy( nStart, rString.getLength() - nStart ) );
+
+        for (size_t i = 0; i < maArgs.size(); i++)
+            fprintf( stderr, "arg %d: '%s'\n", (int)i,
+                     rtl::OUStringToOString( maArgs[i], RTL_TEXTENCODING_UTF8).getStr() );
+    }
+    ~ScChangeOpReader() {}
+
+    rtl::OUString getMethod()
+    {
+        return maArgs[0];
+    }
+
+    size_t getArgCount() { return maArgs.size(); }
+
+    rtl::OUString getString( sal_Int32 n )
+    {
+        if (n > 0 && (size_t)n < getArgCount() )
+        {
+            String aUStr( maArgs[ n ] );
+            ScGlobal::EraseQuotes( aUStr );
+            return aUStr;
+        } else
+            return rtl::OUString();
+    }
+
+    ScAddress getAddress( sal_Int32 n )
+    {
+        ScAddress aAddr;
+        rtl::OUString aToken( getString( n ) );
+        aAddr.Parse( aToken );
+        return aAddr;
+    }
+
+    sal_Int32 getInt( sal_Int32 n )
+    {
+        return getString( n ).toInt32();
+    }
+
+    bool getBool( sal_Int32 n )
+    {
+        return getString( n ).equalsIgnoreAsciiCase( "true" );
+    }
+
+    ScBaseCell *getCell( sal_Int32 n )
+    {
+        return stringToCell( getString( n ) );
+    }
+};
+
+} // anonymous namespace
+
+class ScDocFuncRecv
+{
+    boost::shared_ptr<ScDocFuncDirect> mpChain;
+
+protected:
+    ScDocFuncRecv() {}
+
+public:
+    // FIXME: really ScDocFunc should be an abstract base
+    ScDocFuncRecv( boost::shared_ptr<ScDocFuncDirect>& pChain );
+    virtual ~ScDocFuncRecv() {}
+
+    void packetReceived( TeleConference*, TelePacket &rPacket );
+
+    virtual void fileReceived( const rtl::OUString &rStr );
+    virtual void RecvMessage( const rtl::OString &rString );
+};
+
+class ScDocFuncSend : public ScDocFunc
+{
+    boost::shared_ptr<ScDocFuncRecv>    mpDirect;
+    TeleManager                         *mpManager;
+
+    void SendMessage( ScChangeOpWriter &rOp );
+    void SendFile( const rtl::OUString &rURL );
+
+public:
+    // FIXME: really ScDocFunc should be an abstract base, so
+    // we don't need the rDocSh hack/pointer
+    ScDocFuncSend( ScDocShell& rDocSh, boost::shared_ptr<ScDocFuncRecv> pDirect );
+    virtual ~ScDocFuncSend() {}
+
+    void                SetCollaboration( TeleManager *pManager );
+
+    virtual void        EnterListAction( sal_uInt16 nNameResId );
+    virtual void        EndListAction();
+
+    virtual sal_Bool    SetNormalString( const ScAddress& rPos, const String& rText, sal_Bool bApi );
+    virtual sal_Bool    PutCell( const ScAddress& rPos, ScBaseCell* pNewCell, sal_Bool bApi );
+    virtual sal_Bool    PutData( const ScAddress& rPos, ScEditEngineDefaulter& rEngine,
+                                sal_Bool bInterpret, sal_Bool bApi );
+    virtual sal_Bool    SetCellText( const ScAddress& rPos, const String& rText,
+                                sal_Bool bInterpret, sal_Bool bEnglish, sal_Bool bApi,
+                                const String& rFormulaNmsp,
+                                const formula::FormulaGrammar::Grammar eGrammar );
+    virtual bool        ShowNote( const ScAddress& rPos, bool bShow = true );
+    virtual bool        SetNoteText( const ScAddress& rPos, const String& rNoteText, sal_Bool bApi );
+    virtual sal_Bool    RenameTable( SCTAB nTab, const String& rName, sal_Bool bRecord, sal_Bool bApi );
+    virtual sal_Bool    ApplyAttributes( const ScMarkData& rMark, const ScPatternAttr& rPattern,
+                                sal_Bool bRecord, sal_Bool bApi );
+    virtual sal_Bool    ApplyStyle( const ScMarkData& rMark, const String& rStyleName,
+                                sal_Bool bRecord, sal_Bool bApi );
+    virtual sal_Bool    MergeCells( const ScCellMergeOption& rOption, sal_Bool bContents,
+                                sal_Bool bRecord, sal_Bool bApi );
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 809e1014f554175083d0b965c6744854a240f5b3
Author: Matúš Kukan <matus.kukan at gmail.com>
Date:   Sat Jun 16 23:42:03 2012 +0200

    tubes: start collaboration from the contacts widget

diff --git a/sc/source/ui/collab/contacts.cxx b/sc/source/ui/collab/contacts.cxx
index c029105..44821a5 100644
--- a/sc/source/ui/collab/contacts.cxx
+++ b/sc/source/ui/collab/contacts.cxx
@@ -44,16 +44,50 @@ namespace {
 class TubeContacts : public ModelessDialog
 {
     FixedLine               maLabel;
+    PushButton              maBtnConnect;
     SvxSimpleTableContainer maListContainer;
     SvxSimpleTable          maList;
 
+    DECL_LINK( BtnConnectHdl, void * );
+
+    struct AccountContact
+    {
+        TpAccount* mpAccount;
+        TpContact* mpContact;
+        AccountContact( TpAccount* pAccount, TpContact* pContact ):
+            mpAccount(pAccount), mpContact(pContact) {}
+    };
+    boost::ptr_vector<AccountContact> maACs;
+
+    void StartBuddySession()
+    {
+        AccountContact *pAC = NULL;
+        if (maList.FirstSelected())
+            pAC = reinterpret_cast<AccountContact*> (maList.FirstSelected()->GetUserData());
+        if (pAC)
+        {
+            TpAccount* pAccount = pAC->mpAccount;
+            TpContact* pContact = pAC->mpContact;
+            fprintf( stderr, "picked %s\n", tp_contact_get_identifier( pContact ) );
+            // TeleManager has to exist already, false will be ignored:
+            TeleManager *pManager = TeleManager::get( false );
+            if (!pManager->startBuddySession( pAccount, pContact ))
+                fprintf( stderr, "could not start session with %s\n",
+                        tp_contact_get_identifier( pContact ) );
+            pManager->unref();
+        }
+    }
+
 public:
     TubeContacts() :
         ModelessDialog( NULL, ScResId( RID_SCDLG_CONTACTS ) ),
         maLabel( this, ScResId( FL_LABEL ) ),
+        maBtnConnect( this, ScResId( BTN_CONNECT ) ),
         maListContainer( this, ScResId( CTL_LIST ) ),
         maList( maListContainer )
     {
+        maBtnConnect.SetClickHdl( LINK( this, TubeContacts, BtnConnectHdl ) );
+
         static long aStaticTabs[]=
         {
             3 /* count */, 0, 20, 100, 150, 200
@@ -111,12 +145,21 @@ public:
                 aEntry.append( fromUTF8 ( tp_contact_get_identifier( it->second ) ) );
                 aEntry.append( sal_Unicode( '\t' ) );
                 SvLBoxEntry* pEntry = maList.InsertEntry( aEntry.makeStringAndClear(), aImage, aImage );
-                // FIXME: ref the TpContact ...
-                pEntry->SetUserData( it->second );
+                // FIXME: ref the TpAccount, TpContact ...
+                maACs.push_back( new AccountContact( it->first, it->second ) );
+                pEntry->SetUserData( &maACs.back() );
             }
         }
     }
 };
+
+IMPL_LINK_NOARG( TubeContacts, BtnConnectHdl )
+{
+    StartBuddySession();
+    Close();
+    return 0;
+}
+
 } // anonymous namespace
 #endif
 
diff --git a/sc/source/ui/collab/contacts.hrc b/sc/source/ui/collab/contacts.hrc
index c6e38d3..dd3fcc4 100644
--- a/sc/source/ui/collab/contacts.hrc
+++ b/sc/source/ui/collab/contacts.hrc
@@ -2,6 +2,7 @@
 
 #define FL_LABEL             1
 #define CTL_LIST             2
+#define BTN_CONNECT          3
 
 #define STR_HEADER_ALIAS     20
 #define STR_HEADER_NAME      21
diff --git a/sc/source/ui/collab/contacts.src b/sc/source/ui/collab/contacts.src
index 878c1ae..1689823 100644
--- a/sc/source/ui/collab/contacts.src
+++ b/sc/source/ui/collab/contacts.src
@@ -9,7 +9,7 @@ ModelessDialog RID_SCDLG_CONTACTS
     Hide = FALSE ;
     Moveable = TRUE ;
     Closeable = TRUE ;
-    Size = MAP_APPFONT ( 220 , 200 ) ;
+    Size = MAP_APPFONT ( 220 , 215 ) ;
     OutputSize = TRUE ;
     Text [ en-US ] = "Contacts" ;
 
@@ -19,6 +19,12 @@ ModelessDialog RID_SCDLG_CONTACTS
         Size = MAP_APPFONT ( 198 , 8 ) ;
         Text [ en-US ] = "Select a contact to collaborate with" ;
     };
+    PushButton BTN_CONNECT
+    {
+        Pos = MAP_APPFONT( 8 , 200 );
+        Size = MAP_APPFONT( 50 , 10 );
+        Text [ en-US ] = "Collaborate";
+    };
     Control CTL_LIST
     {
         Pos = MAP_APPFONT ( 8 , 10 ) ;
diff --git a/sc/source/ui/collab/sendfunc.cxx b/sc/source/ui/collab/sendfunc.cxx
index eba6029..a4a8e23 100644
--- a/sc/source/ui/collab/sendfunc.cxx
+++ b/sc/source/ui/collab/sendfunc.cxx
@@ -627,40 +627,20 @@ SC_DLLPRIVATE ScDocFunc *ScDocShell::CreateDocFunc()
         boost::shared_ptr<ScDocFuncRecv> pReceiver( new ScDocFuncRecv( pDirect ) );
         ScDocFuncSend* pSender = new ScDocFuncSend( *this, pReceiver );
         TeleManager *pManager = TeleManager::get( !bIsMaster );
-        bool bOk = true;
 
         pManager->sigPacketReceived.connect(
                 boost::bind( &ScDocFuncRecv::packetReceived, pReceiver.get(), _1, _2 ));
         pManager->sigFileReceived.connect(
                 boost::bind( &ScDocFuncRecv::fileReceived, pReceiver.get(), _1 ));
 
-        bOk = bOk && pManager->connect();
-        pManager->prepareAccountManager();
-
-        if (bIsMaster)
-        {
-            ContactList* pContactList = pManager->getContactList();
-            AccountContactPairV aVec( pContactList->getContacts());
-
-            fprintf( stderr, "%u contacts\n", (int) aVec.size() );
-            if (aVec.empty())
-                bOk = false;
-            else
-            {
-                /* TODO: select a pair, for now just take the first */
-                TpAccount* pAccount = aVec[0].first;
-                TpContact* pContact = aVec[0].second;
-                fprintf( stderr, "picked %s\n", tp_contact_get_identifier( pContact ) );
-                bOk = bOk && pManager->startBuddySession( pAccount, pContact );
-            }
-        }
-        if (bOk)
+        if (pManager->connect())
         {
+            pManager->prepareAccountManager();
             pSender->SetCollaboration( pManager );
         }
         else
         {
-            fprintf( stderr, "Could not start collaboration.\n");
+            fprintf( stderr, "Could not connect.\n");
         }
         return pSender;
     }
commit d10de145d37c65a849ab33fe9ae83c2e9e677ec9
Author: Matúš Kukan <matus.kukan at gmail.com>
Date:   Sat Jun 16 23:29:03 2012 +0200

    tubes: ScDocFuncSend: store pointer to TeleManager

diff --git a/sc/source/ui/collab/sendfunc.cxx b/sc/source/ui/collab/sendfunc.cxx
index 9c04e0d..eba6029 100644
--- a/sc/source/ui/collab/sendfunc.cxx
+++ b/sc/source/ui/collab/sendfunc.cxx
@@ -484,9 +484,9 @@ public:
     }
     virtual ~ScDocFuncSend() {}
 
-    void SetCollaboration( bool bIsMaster )
+    void SetCollaboration( TeleManager *pManager )
     {
-        mpManager = TeleManager::get( !bIsMaster );
+        mpManager = pManager;
     }
 
     virtual void EnterListAction( sal_uInt16 nNameResId )
@@ -515,14 +515,7 @@ public:
             SendFile( rText );
 
         if ( rtl::OUString( rText ) == "contacts" )
-        {
-            // For TeleManager::get() use the same master/slave mode we have
-            // for collaboration, if any. This is a hack anyway so don't care
-            // whether we really are in collab mode or not.
-            bool bIsMaster = false;
-            isCollabMode( bIsMaster );
-            tubes::createContacts( TeleManager::get( bIsMaster ) );
-        }
+            tubes::createContacts( mpManager );
 
         return true; // needs some code auditing action
     }
@@ -663,7 +656,7 @@ SC_DLLPRIVATE ScDocFunc *ScDocShell::CreateDocFunc()
         }
         if (bOk)
         {
-            pSender->SetCollaboration( bIsMaster );
+            pSender->SetCollaboration( pManager );
         }
         else
         {
commit 5aa02da23e24879e1b1a18df0f66a292b1c8b01d
Author: Matúš Kukan <matus.kukan at gmail.com>
Date:   Wed Jun 13 20:03:26 2012 +0200

    tubes: add File -> Collaborate menu entry to launch contacts widget

diff --git a/officecfg/registry/data/org/openoffice/Office/UI/CalcCommands.xcu b/officecfg/registry/data/org/openoffice/Office/UI/CalcCommands.xcu
index c41b805..79449dd 100644
--- a/officecfg/registry/data/org/openoffice/Office/UI/CalcCommands.xcu
+++ b/officecfg/registry/data/org/openoffice/Office/UI/CalcCommands.xcu
@@ -753,6 +753,11 @@
                     <value xml:lang="en-US">Sheet Area Input Field</value>
                 </prop>
             </node>
+            <node oor:name=".uno:Collaborate" oor:op="replace">
+                <prop oor:name="Label" oor:type="xs:string">
+                    <value xml:lang="en-US">Collaborate...</value>
+                </prop>
+            </node>
             <node oor:name=".uno:UnderlineNone" oor:op="replace">
                 <prop oor:name="Label" oor:type="xs:string">
                     <value xml:lang="en-US">Underline: Off</value>
diff --git a/sc/inc/sc.hrc b/sc/inc/sc.hrc
index 0651c41..75202e0 100644
--- a/sc/inc/sc.hrc
+++ b/sc/inc/sc.hrc
@@ -198,6 +198,7 @@
 
 #define SID_CHOOSE_DESIGN       (SC_VIEW_START + 82)
 #define SID_EURO_CONVERTER      (SC_VIEW_START + 83)
+#define SID_COLLABORATION       (SC_VIEW_START + 84)
 #define SID_EXTERNAL_SOURCE     (SC_VIEW_START + 85)
 
 #define SID_SC_INPUT_TEXTWYSIWYG        (SC_VIEW_START + 86)
diff --git a/sc/sdi/cellsh.sdi b/sc/sdi/cellsh.sdi
index ce942e2..2471ed3 100644
--- a/sc/sdi/cellsh.sdi
+++ b/sc/sdi/cellsh.sdi
@@ -177,6 +177,7 @@ interface CellSelection
 
     SID_INSERT_POSTIT   [ ExecMethod = ExecuteEdit; StateMethod = GetCellState; ]
 
+    SID_COLLABORATION       [ ExecMethod = Execute; ]
     SID_TABOP               [ ExecMethod = ExecuteEdit; StateMethod = GetState; ]
     SID_CONSOLIDATE         [ ExecMethod = ExecuteEdit; StateMethod = GetState; ]
     FID_INSERT_NAME [ ExecMethod = ExecuteEdit; StateMethod = GetState; ]
diff --git a/sc/sdi/scalc.sdi b/sc/sdi/scalc.sdi
index 99976ec..86fde47 100644
--- a/sc/sdi/scalc.sdi
+++ b/sc/sdi/scalc.sdi
@@ -2598,6 +2598,31 @@ SfxVoidItem FocusCellAddress FID_FOCUS_POSWND
 ]
 
 //--------------------------------------------------------------------------
+SfxVoidItem Collaborate SID_COLLABORATION
+()
+[
+    /* flags: */
+    AutoUpdate = FALSE,
+    Cachable = Cachable,
+    FastCall = FALSE,
+    HasCoreId = FALSE,
+    HasDialog = TRUE,
+    ReadOnlyDoc = TRUE,
+    Toggle = FALSE,
+    Container = FALSE,
+    RecordAbsolute = FALSE,
+    RecordPerSet;
+    Synchron;
+
+    /* config: */
+    AccelConfig = TRUE,
+    MenuConfig = TRUE,
+    StatusBarConfig = FALSE,
+    ToolBoxConfig = TRUE,
+    GroupId = GID_FORMAT;
+]
+
+//--------------------------------------------------------------------------
 SfxVoidItem FormatCellDialog FID_CELL_FORMAT
 ()
 [
diff --git a/sc/source/ui/view/cellsh3.cxx b/sc/source/ui/view/cellsh3.cxx
index 7dca36a..6d3fcf3 100644
--- a/sc/source/ui/view/cellsh3.cxx
+++ b/sc/source/ui/view/cellsh3.cxx
@@ -57,6 +57,13 @@
 #include "markdata.hxx"
 #include "scabstdlg.hxx"
 
+#ifdef ENABLE_TELEPATHY
+#include <tubes/manager.hxx>
+namespace tubes {
+    void createContacts( const TeleManager &rContacts );
+}
+#endif
+
 #define IS_EDITMODE() GetViewData()->HasEditView( GetViewData()->GetActivePart() )
 
 using sc::HMMToTwips;
@@ -116,6 +123,12 @@ void ScCellShell::Execute( SfxRequest& rReq )
         case SID_ATTR_SIZE://XXX ???
             break;
 
+        case SID_COLLABORATION:
+#ifdef ENABLE_TELEPATHY
+            tubes::createContacts( TeleManager::get( true ) );
+#endif
+            break;
+
         case SID_STATUS_SELMODE:
             if ( pReqArgs )
             {
diff --git a/sc/uiconfig/scalc/menubar/menubar.xml b/sc/uiconfig/scalc/menubar/menubar.xml
index 45bafb9..7bf1066 100644
--- a/sc/uiconfig/scalc/menubar/menubar.xml
+++ b/sc/uiconfig/scalc/menubar/menubar.xml
@@ -16,6 +16,8 @@
             <menu:menuitem menu:id=".uno:Reload"/>
             <menu:menuitem menu:id=".uno:VersionDialog"/>
             <menu:menuseparator/>
+            <menu:menuitem menu:id=".uno:Collaborate"/>
+            <menu:menuseparator/>
             <menu:menuitem menu:id=".uno:ExportTo"/>
             <menu:menuitem menu:id=".uno:ExportToPDF"/>
             <menu:menu menu:id=".uno:SendTo">


More information about the Libreoffice-commits mailing list