Stop leaking all ScPostIt instances.
[LibreOffice.git] / sc / source / ui / collab / sendfunc.cxx
blobfb45e9d5ac3b76dcb77f00c3797a6373624e03b0
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 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 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( SCA_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 OUString aUndo( ScGlobal::GetRscString( nNameResId ) );
313 ScChangeOpWriter aOp( "enterListAction" );
314 aOp.appendInt( nNameResId ); // nasty but translate-able ...
315 SendMessage( aOp );
318 void ScDocFuncSend::EndListAction()
320 ScChangeOpWriter aOp( "endListAction" );
321 SendMessage( aOp );
324 sal_Bool ScDocFuncSend::SetNormalString( bool& o_rbNumFmtSet, const ScAddress& rPos, const OUString& rText, sal_Bool bApi )
326 ScChangeOpWriter aOp( "setNormalString" );
327 aOp.appendAddress( rPos );
328 aOp.appendString( rText );
329 aOp.appendBool( bApi );
330 SendMessage( aOp );
332 o_rbNumFmtSet = false;
334 if ( OUString( rText ) == "saveme" )
335 mpCollaboration->SaveAndSendFile( NULL );
337 if ( OUString( rText ) == "contacts" )
338 mpCollaboration->DisplayContacts();
340 return true; // needs some code auditing action
343 bool ScDocFuncSend::SetValueCell( const ScAddress& rPos, double fVal, bool bInteraction )
345 ScChangeOpWriter aOp("setValueCell");
346 aOp.appendAddress( rPos );
347 aOp.appendDouble( fVal );
348 aOp.appendBool( bInteraction );
349 SendMessage( aOp );
350 return true; // needs some code auditing action
353 bool ScDocFuncSend::SetStringCell( const ScAddress& rPos, const OUString& rStr, bool bInteraction )
355 ScChangeOpWriter aOp("setStringCell");
356 aOp.appendAddress( rPos );
357 aOp.appendString( rStr );
358 aOp.appendBool( bInteraction );
359 SendMessage( aOp );
360 return true; // needs some code auditing action
363 bool ScDocFuncSend::SetEditCell( const ScAddress& rPos, const EditTextObject& rStr, bool bInteraction )
365 ScChangeOpWriter aOp("setEditCell");
366 aOp.appendAddress( rPos );
367 aOp.appendEditText( rStr );
368 aOp.appendBool( bInteraction );
369 SendMessage( aOp );
370 return true; // needs some code auditing action
373 bool ScDocFuncSend::SetFormulaCell( const ScAddress& rPos, ScFormulaCell* pCell, bool bInteraction )
375 ScChangeOpWriter aOp("setFormulaCell");
376 aOp.appendAddress( rPos );
377 aOp.appendFormulaCell( pCell );
378 aOp.appendBool( bInteraction );
379 SendMessage( aOp );
380 delete pCell;
381 return true; // needs some code auditing action
384 bool ScDocFuncSend::PutData( const ScAddress& rPos, ScEditEngineDefaulter& rEngine, bool bApi )
386 SAL_INFO( "sc.tubes", "PutData not implemented!" );
387 return ScDocFunc::PutData( rPos, rEngine, bApi );
390 bool ScDocFuncSend::SetCellText(
391 const ScAddress& rPos, const OUString& rText, bool bInterpret, bool bEnglish, bool bApi,
392 const formula::FormulaGrammar::Grammar eGrammar )
394 SAL_INFO( "sc.tubes", "SetCellText not implemented!" );
395 return ScDocFunc::SetCellText( rPos, rText, bInterpret, bEnglish, bApi, eGrammar );
398 bool ScDocFuncSend::ShowNote( const ScAddress& rPos, bool bShow )
400 ScChangeOpWriter aOp( "showNote" );
401 aOp.appendAddress( rPos );
402 aOp.appendBool( bShow );
403 SendMessage( aOp );
404 return true; // needs some code auditing action
407 bool ScDocFuncSend::SetNoteText( const ScAddress& rPos, const OUString& rNoteText, sal_Bool bApi )
409 ScChangeOpWriter aOp( "setNoteText" );
410 aOp.appendAddress( rPos );
411 aOp.appendString( rNoteText );
412 aOp.appendBool( bApi );
413 SendMessage( aOp );
414 return true; // needs some code auditing action
417 sal_Bool ScDocFuncSend::RenameTable( SCTAB nTab, const OUString& rName,
418 sal_Bool bRecord, sal_Bool bApi )
420 ScChangeOpWriter aOp( "renameTable" );
421 aOp.appendInt( nTab );
422 aOp.appendString( rName );
423 aOp.appendBool( bRecord );
424 aOp.appendBool( bApi );
425 SendMessage( aOp );
426 return true; // needs some code auditing action
429 sal_Bool ScDocFuncSend::ApplyAttributes( const ScMarkData& rMark, const ScPatternAttr& rPattern,
430 sal_Bool bRecord, sal_Bool bApi )
432 SAL_INFO( "sc.tubes", "ApplyAttributes not implemented!" );
433 return ScDocFunc::ApplyAttributes( rMark, rPattern, bRecord, bApi );
436 sal_Bool ScDocFuncSend::ApplyStyle( const ScMarkData& rMark, const OUString& rStyleName,
437 sal_Bool bRecord, sal_Bool bApi )
439 SAL_INFO( "sc.tubes", "ApplyStyle not implemented!" );
440 return ScDocFunc::ApplyStyle( rMark, rStyleName, bRecord, bApi );
443 sal_Bool ScDocFuncSend::MergeCells( const ScCellMergeOption& rOption, sal_Bool bContents,
444 sal_Bool bRecord, sal_Bool bApi )
446 SAL_INFO( "sc.tubes", "MergeCells not implemented!" );
447 return ScDocFunc::MergeCells( rOption, bContents, bRecord, bApi );
450 ScDocFunc *ScDocShell::CreateDocFunc()
452 if (TeleManager::hasWaitingConference())
454 TeleConference* pConference = TeleManager::getConference();
455 if (pConference)
457 mpCollaboration->SetConference( pConference );
458 return new ScDocFuncSend( *this, new ScDocFuncDirect( *this ), mpCollaboration );
461 return new ScDocFuncDirect( *this );
464 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */