1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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/.
10 #include "sendfunc.hxx"
12 #include "formulacell.hxx"
14 #include "docfunc.hxx"
15 #include "sccollaboration.hxx"
16 #include <editeng/editeng.hxx>
17 #include <editeng/editobj.hxx>
18 #include <tubes/manager.hxx>
22 OUString
formulaCellToString( ScFormulaCell
*pCell
)
24 (void)pCell
; // FIXME: implement me
28 OUString
editToString( const EditTextObject
& /*rEditText*/ )
30 // FIXME: implement me.
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
48 struct ProtocolError
{
52 class ScChangeOpReader
{
53 std::vector
< OUString
> maArgs
;
56 ScChangeOpReader( const OUString
&rString
)
58 // will need to handle escaping etc.
59 // Surely someone else wrote this before ! [!?]
61 IN_TEXT
, CHECK_QUOTE
, FIND_LAST_QUOTE
, SKIP_SEMI
62 } eState
= CHECK_QUOTE
;
65 for (sal_Int32 n
= 0; n
< rString
.getLength(); n
++)
67 if (rString
[n
] == '\\')
69 n
++; // skip next char
74 if (rString
[n
] == '"')
77 eState
= FIND_LAST_QUOTE
;
82 if (rString
[n
] == ';')
84 maArgs
.push_back( rString
.copy( nStart
, n
- nStart
) );
90 if (rString
[n
] == '"')
92 maArgs
.push_back( rString
.copy( nStart
, n
- nStart
) );
98 if (rString
[n
] == ';')
101 eState
= CHECK_QUOTE
;
106 if ( nStart
< rString
.getLength())
107 maArgs
.push_back( rString
.copy( nStart
, rString
.getLength() - nStart
) );
109 ~ScChangeOpReader() {}
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
);
129 ScAddress
getAddress( sal_Int32 n
)
132 OUString
aToken( getString( n
) );
133 aAddr
.Parse( aToken
);
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( ';' );
177 ScChangeOpWriter( const char *pName
)
179 aMessage
.appendAscii( pName
);
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
);
193 aMessage
.append( rStr
);
197 void appendAddress( const ScAddress
&rPos
)
199 aMessage
.append( rPos
.Format( SCA_VALID
) );
203 void appendInt( sal_Int32 i
)
205 aMessage
.append( i
);
209 void appendBool( sal_Bool b
)
211 aMessage
.appendAscii( b
? "true" : "false" );
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
);
233 return OUStringToOString( aMessage
.toString(), RTL_TEXTENCODING_UTF8
);
237 void ScDocFuncSend::RecvMessage( const OString
&rString
)
240 ScChangeOpReader
aReader( OUString( rString
.getStr(),
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 ) );
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
),
300 mpCollaboration( pCollaboration
)
304 ScDocFuncSend::~ScDocFuncSend()
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 ...
318 void ScDocFuncSend::EndListAction()
320 ScChangeOpWriter
aOp( "endListAction" );
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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();
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: */