Version 5.2.6.1, tag libreoffice-5.2.6.1
[LibreOffice.git] / sc / source / ui / collab / sendfunc.cxx
blobfca719e593d02253e25698c3149175d2de84e53a
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
10 #include "sendfunc.hxx"
12 #include "formulacell.hxx"
13 #include "docsh.hxx"
14 #include "docfunc.hxx"
15 #include "sccollaboration.hxx"
16 #include <editeng/editeng.hxx>
17 #include <editeng/editobj.hxx>
18 #include <tubes/manager.hxx>
20 namespace {
22 OUString formulaCellToString( ScFormulaCell *pCell )
24 (void)pCell; // FIXME: implement me
25 return OUString();
28 OUString editToString( const EditTextObject& /*rEditText*/ )
30 // FIXME: implement me.
31 return OUString();
34 EditTextObject stringToEdit( const OUString& /* rStr */ )
36 // FIXME: implement me.
37 // The code here only serves to make this file compilable.
38 EditEngine aEditEngine(0);
39 return *aEditEngine.CreateTextObject();
42 ScFormulaCell* stringToFormulaCell( const OUString &rString )
44 (void)rString; // FIXME: implement me
45 return NULL;
48 struct ProtocolError {
49 const char *message;
52 class ScChangeOpReader {
53 std::vector< OUString > maArgs;
55 public:
56 explicit ScChangeOpReader(const OUString &rString)
58 // will need to handle escaping etc.
59 // Surely someone else wrote this before ! [!?]
60 enum {
61 IN_TEXT, CHECK_QUOTE, FIND_LAST_QUOTE, SKIP_SEMI
62 } eState = CHECK_QUOTE;
64 sal_Int32 nStart = 0;
65 for (sal_Int32 n = 0; n < rString.getLength(); n++)
67 if (rString[n] == '\\')
69 n++; // skip next char
70 continue;
72 switch (eState) {
73 case CHECK_QUOTE:
74 if (rString[n] == '"')
76 nStart = n + 1;
77 eState = FIND_LAST_QUOTE;
78 break;
80 // else drop through
81 case IN_TEXT:
82 if (rString[n] == ';')
84 maArgs.push_back( rString.copy( nStart, n - nStart ) );
85 nStart = n + 1;
86 eState = CHECK_QUOTE;
88 break;
89 case FIND_LAST_QUOTE:
90 if (rString[n] == '"')
92 maArgs.push_back( rString.copy( nStart, n - nStart ) );
93 eState = SKIP_SEMI;
94 break;
96 break;
97 case SKIP_SEMI:
98 if (rString[n] == ';')
100 nStart = n + 1;
101 eState = CHECK_QUOTE;
103 break;
106 if ( nStart < rString.getLength())
107 maArgs.push_back( rString.copy( nStart, rString.getLength() - nStart ) );
109 ~ScChangeOpReader() {}
111 OUString getMethod()
113 return maArgs[0];
116 size_t getArgCount() { return maArgs.size(); }
118 OUString getString( sal_Int32 n )
120 if (n > 0 && (size_t)n < getArgCount() )
122 OUString aUStr( maArgs[ n ] );
123 ScGlobal::EraseQuotes( aUStr );
124 return aUStr;
125 } else
126 return OUString();
129 ScAddress getAddress( sal_Int32 n )
131 ScAddress aAddr;
132 OUString aToken( getString( n ) );
133 aAddr.Parse( aToken );
134 return aAddr;
137 sal_Int32 getInt( sal_Int32 n )
139 return getString( n ).toInt32();
142 bool getBool( sal_Int32 n )
144 return getString( n ).equalsIgnoreAsciiCase( "true" );
147 ScFormulaCell* getFormulaCell( sal_Int32 n )
149 return stringToFormulaCell( getString( n ) );
152 double getDouble( sal_Int32 n )
154 return getString(n).toDouble();
157 EditTextObject getEdit( sal_Int32 n )
159 return stringToEdit(getString(n));
164 } // anonymous namespace
166 // Ye noddy mangling - needs improvement ...
167 // method name ';' then arguments ; separated
168 class ScChangeOpWriter
170 OUStringBuffer aMessage;
171 void appendSeparator()
173 aMessage.append( ';' );
176 public:
177 explicit ScChangeOpWriter( const char *pName )
179 aMessage.appendAscii( pName );
180 appendSeparator();
183 void appendString( const OUString &rStr )
185 if ( rStr.indexOf( '"' ) >= 0 ||
186 rStr.indexOf( ';' ) >= 0 )
188 OUString aQuoted( rStr );
189 ScGlobal::AddQuotes( aQuoted, '"' );
190 aMessage.append( aQuoted );
192 else
193 aMessage.append( rStr );
194 appendSeparator();
197 void appendAddress( const ScAddress &rPos )
199 aMessage.append( rPos.Format( ScRefFlags::VALID ) );
200 appendSeparator();
203 void appendInt( sal_Int32 i )
205 aMessage.append( i );
206 appendSeparator();
209 void appendBool( sal_Bool b )
211 aMessage.appendAscii( b ? "true" : "false" );
212 appendSeparator();
215 void appendFormulaCell( ScFormulaCell *pCell )
217 appendString( formulaCellToString( pCell ) );
220 void appendEditText( const EditTextObject& rStr )
222 appendString( editToString(rStr) );
225 void appendDouble( double fVal )
227 aMessage.append(fVal);
228 appendSeparator();
231 OString toString()
233 return OUStringToOString( aMessage.toString(), RTL_TEXTENCODING_UTF8 );
237 void ScDocFuncSend::RecvMessage( const OString &rString )
239 try {
240 ScChangeOpReader aReader( OUString( rString.getStr(),
241 rString.getLength(),
242 RTL_TEXTENCODING_UTF8 ) );
243 // FIXME: have some hash to enumeration mapping here
244 if ( aReader.getMethod() == "setNormalString" )
246 bool bNumFmtSet = false;
247 mpDirect->SetNormalString( bNumFmtSet, aReader.getAddress( 1 ), aReader.getString( 2 ),
248 aReader.getBool( 3 ) );
250 else if (aReader.getMethod() == "setValueCell")
252 mpDirect->SetValueCell(
253 aReader.getAddress(1), aReader.getDouble(2), aReader.getBool(3));
255 else if (aReader.getMethod() == "setStringCell")
257 mpDirect->SetStringCell(
258 aReader.getAddress(1), aReader.getString(2), aReader.getBool(3));
260 else if (aReader.getMethod() == "setEditCell")
262 mpDirect->SetEditCell(
263 aReader.getAddress(1), aReader.getEdit(2), aReader.getBool(3));
265 else if (aReader.getMethod() == "setFormulaCell")
267 mpDirect->SetFormulaCell(
268 aReader.getAddress(1), aReader.getFormulaCell(2), aReader.getBool(3));
270 else if ( aReader.getMethod() == "enterListAction" )
271 mpDirect->EnterListAction( aReader.getInt( 1 ) );
272 else if ( aReader.getMethod() == "endListAction" )
273 mpDirect->EndListAction();
274 else if ( aReader.getMethod() == "showNote" )
275 mpDirect->ShowNote( aReader.getAddress( 1 ), aReader.getBool( 2 ) );
276 else if ( aReader.getMethod() == "setNoteText" )
277 mpDirect->SetNoteText( aReader.getAddress( 1 ), aReader.getString( 2 ),
278 aReader.getBool( 3 ) );
279 else if ( aReader.getMethod() == "renameTable" )
280 mpDirect->RenameTable( aReader.getInt( 1 ), aReader.getString( 2 ),
281 aReader.getBool( 3 ), aReader.getBool( 4 ) );
282 else
283 SAL_WARN( "sc.tubes", "Error: unknown message '" << rString.getStr()
284 << "' (" << aReader.getArgCount() << ")" );
285 } catch (const ProtocolError &e) {
286 SAL_WARN( "sc.tubes", "Error: protocol twisting: " << e.message );
290 void ScDocFuncSend::SendMessage( ScChangeOpWriter &rOp )
292 mpCollaboration->SendPacket( rOp.toString() );
295 // FIXME: really ScDocFunc should be an abstract base, so
296 // we don't need the rDocSh hack/pointer
297 ScDocFuncSend::ScDocFuncSend( ScDocShell& rDocSh, ScDocFuncDirect *pDirect, ScCollaboration* pCollaboration )
298 : ScDocFunc( rDocSh ),
299 mpDirect( pDirect ),
300 mpCollaboration( pCollaboration )
304 ScDocFuncSend::~ScDocFuncSend()
306 delete mpDirect;
309 void ScDocFuncSend::EnterListAction( sal_uInt16 nNameResId )
311 // Want to group these operations for the other side ...
312 ScChangeOpWriter aOp( "enterListAction" );
313 aOp.appendInt( nNameResId ); // nasty but translate-able ...
314 SendMessage( aOp );
317 void ScDocFuncSend::EndListAction()
319 ScChangeOpWriter aOp( "endListAction" );
320 SendMessage( aOp );
323 sal_Bool ScDocFuncSend::SetNormalString( bool& o_rbNumFmtSet, const ScAddress& rPos, const OUString& rText, sal_Bool bApi )
325 ScChangeOpWriter aOp( "setNormalString" );
326 aOp.appendAddress( rPos );
327 aOp.appendString( rText );
328 aOp.appendBool( bApi );
329 SendMessage( aOp );
331 o_rbNumFmtSet = false;
333 if ( OUString( rText ) == "saveme" )
334 mpCollaboration->SaveAndSendFile( NULL );
336 if ( OUString( rText ) == "contacts" )
337 mpCollaboration->DisplayContacts();
339 return true; // needs some code auditing action
342 bool ScDocFuncSend::SetValueCell( const ScAddress& rPos, double fVal, bool bInteraction )
344 ScChangeOpWriter aOp("setValueCell");
345 aOp.appendAddress( rPos );
346 aOp.appendDouble( fVal );
347 aOp.appendBool( bInteraction );
348 SendMessage( aOp );
349 return true; // needs some code auditing action
352 bool ScDocFuncSend::SetValueCells(
353 const ScAddress& /*rPos*/, const std::vector<double>& /*aVals*/, bool /*bInteraction*/ )
355 // TODO : Implement this.
356 return true;
359 bool ScDocFuncSend::SetStringCell( const ScAddress& rPos, const OUString& rStr, bool bInteraction )
361 ScChangeOpWriter aOp("setStringCell");
362 aOp.appendAddress( rPos );
363 aOp.appendString( rStr );
364 aOp.appendBool( bInteraction );
365 SendMessage( aOp );
366 return true; // needs some code auditing action
369 bool ScDocFuncSend::SetEditCell( const ScAddress& rPos, const EditTextObject& rStr, bool bInteraction )
371 ScChangeOpWriter aOp("setEditCell");
372 aOp.appendAddress( rPos );
373 aOp.appendEditText( rStr );
374 aOp.appendBool( bInteraction );
375 SendMessage( aOp );
376 return true; // needs some code auditing action
379 bool ScDocFuncSend::SetFormulaCell( const ScAddress& rPos, ScFormulaCell* pCell, bool bInteraction )
381 ScChangeOpWriter aOp("setFormulaCell");
382 aOp.appendAddress( rPos );
383 aOp.appendFormulaCell( pCell );
384 aOp.appendBool( bInteraction );
385 SendMessage( aOp );
386 delete pCell;
387 return true; // needs some code auditing action
390 void ScDocFuncSend::PutData( const ScAddress& rPos, ScEditEngineDefaulter& rEngine, bool bApi )
392 SAL_INFO( "sc.tubes", "PutData not implemented!" );
393 ScDocFunc::PutData( rPos, rEngine, bApi );
396 bool ScDocFuncSend::SetCellText(
397 const ScAddress& rPos, const OUString& rText, bool bInterpret, bool bEnglish, bool bApi,
398 const formula::FormulaGrammar::Grammar eGrammar )
400 SAL_INFO( "sc.tubes", "SetCellText not implemented!" );
401 return ScDocFunc::SetCellText( rPos, rText, bInterpret, bEnglish, bApi, eGrammar );
404 bool ScDocFuncSend::ShowNote( const ScAddress& rPos, bool bShow )
406 ScChangeOpWriter aOp( "showNote" );
407 aOp.appendAddress( rPos );
408 aOp.appendBool( bShow );
409 SendMessage( aOp );
410 return true; // needs some code auditing action
413 bool ScDocFuncSend::SetNoteText( const ScAddress& rPos, const OUString& rNoteText, sal_Bool bApi )
415 ScChangeOpWriter aOp( "setNoteText" );
416 aOp.appendAddress( rPos );
417 aOp.appendString( rNoteText );
418 aOp.appendBool( bApi );
419 SendMessage( aOp );
420 return true; // needs some code auditing action
423 sal_Bool ScDocFuncSend::RenameTable( SCTAB nTab, const OUString& rName,
424 sal_Bool bRecord, sal_Bool bApi )
426 ScChangeOpWriter aOp( "renameTable" );
427 aOp.appendInt( nTab );
428 aOp.appendString( rName );
429 aOp.appendBool( bRecord );
430 aOp.appendBool( bApi );
431 SendMessage( aOp );
432 return true; // needs some code auditing action
435 sal_Bool ScDocFuncSend::ApplyAttributes( const ScMarkData& rMark, const ScPatternAttr& rPattern,
436 sal_Bool bRecord, sal_Bool bApi )
438 SAL_INFO( "sc.tubes", "ApplyAttributes not implemented!" );
439 return ScDocFunc::ApplyAttributes( rMark, rPattern, bRecord, bApi );
442 sal_Bool ScDocFuncSend::ApplyStyle( const ScMarkData& rMark, const OUString& rStyleName,
443 sal_Bool bRecord, sal_Bool bApi )
445 SAL_INFO( "sc.tubes", "ApplyStyle not implemented!" );
446 return ScDocFunc::ApplyStyle( rMark, rStyleName, bRecord, bApi );
449 sal_Bool ScDocFuncSend::MergeCells( const ScCellMergeOption& rOption, sal_Bool bContents,
450 sal_Bool bRecord, sal_Bool bApi )
452 SAL_INFO( "sc.tubes", "MergeCells not implemented!" );
453 return ScDocFunc::MergeCells( rOption, bContents, bRecord, bApi );
456 ScDocFunc *ScDocShell::CreateDocFunc()
458 if (TeleManager::hasWaitingConference())
460 TeleConference* pConference = TeleManager::getConference();
461 if (pConference)
463 mpCollaboration->SetConference( pConference );
464 return new ScDocFuncSend( *this, new ScDocFuncDirect( *this ), mpCollaboration );
467 return new ScDocFuncDirect( *this );
470 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */