1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sc.hxx"
26
27
28
29 #include "scitems.hxx"
30 #include <editeng/eeitem.hxx>
31 #include <svx/svdpool.hxx>
32 #include <svx/svdobj.hxx>
33 #include <editeng/editeng.hxx>
34 #include <editeng/editobj.hxx>
35 #include <editeng/flditem.hxx>
36 #include <svx/unomid.hxx>
37 #include <editeng/unoprnms.hxx>
38 #include <editeng/unofored.hxx>
39 #include <rtl/uuid.h>
40 #include <vcl/virdev.hxx>
41 #include <com/sun/star/awt/FontSlant.hpp>
42
43 #include <com/sun/star/beans/PropertyAttribute.hpp>
44 #include <editeng/unoipset.hxx>
45 #include "textuno.hxx"
46 #include "fielduno.hxx"
47 #include "servuno.hxx"
48 #include "editsrc.hxx"
49 #include "docsh.hxx"
50 #include "editutil.hxx"
51 #include "unoguard.hxx"
52 #include "miscuno.hxx"
53 #include "cellsuno.hxx"
54 #include "hints.hxx"
55 #include "patattr.hxx"
56 #include "cell.hxx"
57 #include "docfunc.hxx"
58 #include "scmod.hxx"
59
60 using namespace com::sun::star;
61
62 //------------------------------------------------------------------------
63
lcl_GetHdFtPropertySet()64 const SvxItemPropertySet * lcl_GetHdFtPropertySet()
65 {
66 static SfxItemPropertyMapEntry aHdFtPropertyMap_Impl[] =
67 {
68 SVX_UNOEDIT_CHAR_PROPERTIES,
69 SVX_UNOEDIT_FONT_PROPERTIES,
70 SVX_UNOEDIT_PARA_PROPERTIES,
71 SVX_UNOEDIT_NUMBERING_PROPERTIE, // for completeness of service ParagraphProperties
72 {0,0,0,0,0,0}
73 };
74 static sal_Bool bTwipsSet = sal_False;
75
76 if (!bTwipsSet)
77 {
78 // modify PropertyMap to include CONVERT_TWIPS flag for font height
79 // (headers/footers are in twips)
80
81 SfxItemPropertyMapEntry* pEntry = aHdFtPropertyMap_Impl;
82 while (pEntry->pName)
83 {
84 if ( ( pEntry->nWID == EE_CHAR_FONTHEIGHT ||
85 pEntry->nWID == EE_CHAR_FONTHEIGHT_CJK ||
86 pEntry->nWID == EE_CHAR_FONTHEIGHT_CTL ) &&
87 pEntry->nMemberId == MID_FONTHEIGHT )
88 {
89 pEntry->nMemberId |= CONVERT_TWIPS;
90 }
91
92 ++pEntry;
93 }
94 bTwipsSet = sal_True;
95 }
96 static SvxItemPropertySet aHdFtPropertySet_Impl( aHdFtPropertyMap_Impl, SdrObject::GetGlobalDrawObjectItemPool() );
97 return &aHdFtPropertySet_Impl;
98 }
99
100 //------------------------------------------------------------------------
101
102 SC_SIMPLE_SERVICE_INFO( ScHeaderFooterContentObj, "ScHeaderFooterContentObj", "com.sun.star.sheet.HeaderFooterContent" )
103 SC_SIMPLE_SERVICE_INFO( ScHeaderFooterTextObj, "ScHeaderFooterTextObj", "stardiv.one.Text.Text" )
104
105 //------------------------------------------------------------------------
106
ScHeaderFooterContentObj(const EditTextObject * pLeft,const EditTextObject * pCenter,const EditTextObject * pRight)107 ScHeaderFooterContentObj::ScHeaderFooterContentObj( const EditTextObject* pLeft,
108 const EditTextObject* pCenter,
109 const EditTextObject* pRight ) :
110 pLeftText ( NULL ),
111 pCenterText ( NULL ),
112 pRightText ( NULL )
113 {
114 if ( pLeft )
115 pLeftText = pLeft->Clone();
116 if ( pCenter )
117 pCenterText = pCenter->Clone();
118 if ( pRight )
119 pRightText = pRight->Clone();
120 }
121
~ScHeaderFooterContentObj()122 ScHeaderFooterContentObj::~ScHeaderFooterContentObj()
123 {
124 delete pLeftText;
125 delete pCenterText;
126 delete pRightText;
127 }
128
AddListener(SfxListener & rListener)129 void ScHeaderFooterContentObj::AddListener( SfxListener& rListener )
130 {
131 rListener.StartListening( aBC );
132 }
133
RemoveListener(SfxListener & rListener)134 void ScHeaderFooterContentObj::RemoveListener( SfxListener& rListener )
135 {
136 rListener.EndListening( aBC );
137 }
138
UpdateText(sal_uInt16 nPart,EditEngine & rSource)139 void ScHeaderFooterContentObj::UpdateText( sal_uInt16 nPart, EditEngine& rSource )
140 {
141 EditTextObject* pNew = rSource.CreateTextObject();
142 switch (nPart)
143 {
144 case SC_HDFT_LEFT:
145 delete pLeftText;
146 pLeftText = pNew;
147 break;
148 case SC_HDFT_CENTER:
149 delete pCenterText;
150 pCenterText = pNew;
151 break;
152 default: // SC_HDFT_RIGHT
153 delete pRightText;
154 pRightText = pNew;
155 break;
156 }
157
158 aBC.Broadcast( ScHeaderFooterChangedHint( nPart ) );
159 }
160
161 // XHeaderFooterContent
162
getLeftText()163 uno::Reference<text::XText> SAL_CALL ScHeaderFooterContentObj::getLeftText()
164 {
165 ScUnoGuard aGuard;
166 return new ScHeaderFooterTextObj( *this, SC_HDFT_LEFT );
167 }
168
getCenterText()169 uno::Reference<text::XText> SAL_CALL ScHeaderFooterContentObj::getCenterText()
170 {
171 ScUnoGuard aGuard;
172 return new ScHeaderFooterTextObj( *this, SC_HDFT_CENTER );
173 }
174
getRightText()175 uno::Reference<text::XText> SAL_CALL ScHeaderFooterContentObj::getRightText()
176 {
177 ScUnoGuard aGuard;
178 return new ScHeaderFooterTextObj( *this, SC_HDFT_RIGHT );
179 }
180
181 // XUnoTunnel
182
getSomething(const uno::Sequence<sal_Int8> & rId)183 sal_Int64 SAL_CALL ScHeaderFooterContentObj::getSomething(
184 const uno::Sequence<sal_Int8 >& rId )
185 {
186 if ( rId.getLength() == 16 &&
187 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
188 rId.getConstArray(), 16 ) )
189 {
190 return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
191 }
192 return 0;
193 }
194
195 // static
getUnoTunnelId()196 const uno::Sequence<sal_Int8>& ScHeaderFooterContentObj::getUnoTunnelId()
197 {
198 static uno::Sequence<sal_Int8> * pSeq = 0;
199 if( !pSeq )
200 {
201 osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
202 if( !pSeq )
203 {
204 static uno::Sequence< sal_Int8 > aSeq( 16 );
205 rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
206 pSeq = &aSeq;
207 }
208 }
209 return *pSeq;
210 }
211
212 // static
getImplementation(const uno::Reference<sheet::XHeaderFooterContent> xObj)213 ScHeaderFooterContentObj* ScHeaderFooterContentObj::getImplementation(
214 const uno::Reference<sheet::XHeaderFooterContent> xObj )
215 {
216 ScHeaderFooterContentObj* pRet = NULL;
217 uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY );
218 if (xUT.is())
219 pRet = reinterpret_cast<ScHeaderFooterContentObj*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
220 return pRet;
221 }
222
223
224 //------------------------------------------------------------------------
225
ScHeaderFooterTextData(ScHeaderFooterContentObj & rContent,sal_uInt16 nP)226 ScHeaderFooterTextData::ScHeaderFooterTextData( ScHeaderFooterContentObj& rContent,
227 sal_uInt16 nP ) :
228 rContentObj( rContent ),
229 nPart( nP ),
230 pEditEngine( NULL ),
231 pForwarder( NULL ),
232 bDataValid( sal_False ),
233 bInUpdate( sal_False )
234 {
235 rContentObj.acquire(); // must not go away
236 rContentObj.AddListener( *this );
237 }
238
~ScHeaderFooterTextData()239 ScHeaderFooterTextData::~ScHeaderFooterTextData()
240 {
241 ScUnoGuard aGuard; // needed for EditEngine dtor
242
243 rContentObj.RemoveListener( *this );
244
245 delete pForwarder;
246 delete pEditEngine;
247
248 rContentObj.release();
249 }
250
Notify(SfxBroadcaster &,const SfxHint & rHint)251 void ScHeaderFooterTextData::Notify( SfxBroadcaster&, const SfxHint& rHint )
252 {
253 if ( rHint.ISA( ScHeaderFooterChangedHint ) )
254 {
255 if ( ((const ScHeaderFooterChangedHint&)rHint).GetPart() == nPart )
256 {
257 if (!bInUpdate) // not for own updates
258 bDataValid = sal_False; // text has to be fetched again
259 }
260 }
261 }
262
GetTextForwarder()263 SvxTextForwarder* ScHeaderFooterTextData::GetTextForwarder()
264 {
265 if (!pEditEngine)
266 {
267 SfxItemPool* pEnginePool = EditEngine::CreatePool();
268 pEnginePool->FreezeIdRanges();
269 ScHeaderEditEngine* pHdrEngine = new ScHeaderEditEngine( pEnginePool, sal_True );
270
271 pHdrEngine->EnableUndo( sal_False );
272 pHdrEngine->SetRefMapMode( MAP_TWIP );
273
274 // default font must be set, independently of document
275 // -> use global pool from module
276
277 SfxItemSet aDefaults( pHdrEngine->GetEmptyItemSet() );
278 const ScPatternAttr& rPattern = (const ScPatternAttr&)SC_MOD()->GetPool().GetDefaultItem(ATTR_PATTERN);
279 rPattern.FillEditItemSet( &aDefaults );
280 // FillEditItemSet adjusts font height to 1/100th mm,
281 // but for header/footer twips is needed, as in the PatternAttr:
282 aDefaults.Put( rPattern.GetItem(ATTR_FONT_HEIGHT), EE_CHAR_FONTHEIGHT );
283 aDefaults.Put( rPattern.GetItem(ATTR_CJK_FONT_HEIGHT), EE_CHAR_FONTHEIGHT_CJK );
284 aDefaults.Put( rPattern.GetItem(ATTR_CTL_FONT_HEIGHT), EE_CHAR_FONTHEIGHT_CTL );
285 pHdrEngine->SetDefaults( aDefaults );
286
287 ScHeaderFieldData aData;
288 ScHeaderFooterTextObj::FillDummyFieldData( aData );
289 pHdrEngine->SetData( aData );
290
291 pEditEngine = pHdrEngine;
292 pForwarder = new SvxEditEngineForwarder(*pEditEngine);
293 }
294
295 if (bDataValid)
296 return pForwarder;
297
298 const EditTextObject* pData;
299 if (nPart == SC_HDFT_LEFT)
300 pData = rContentObj.GetLeftEditObject();
301 else if (nPart == SC_HDFT_CENTER)
302 pData = rContentObj.GetCenterEditObject();
303 else
304 pData = rContentObj.GetRightEditObject();
305
306 if (pData)
307 pEditEngine->SetText(*pData);
308
309 bDataValid = sal_True;
310 return pForwarder;
311 }
312
UpdateData()313 void ScHeaderFooterTextData::UpdateData()
314 {
315 if ( pEditEngine )
316 {
317 bInUpdate = sal_True; // don't reset bDataValid during UpdateText
318
319 rContentObj.UpdateText( nPart, *pEditEngine );
320
321 bInUpdate = sal_False;
322 }
323 }
324
325 //------------------------------------------------------------------------
326
ScHeaderFooterTextObj(ScHeaderFooterContentObj & rContent,sal_uInt16 nP)327 ScHeaderFooterTextObj::ScHeaderFooterTextObj( ScHeaderFooterContentObj& rContent,
328 sal_uInt16 nP ) :
329 aTextData( rContent, nP ),
330 pUnoText( NULL )
331 {
332 // ScHeaderFooterTextData acquires rContent
333 // pUnoText is created on demand (getString/setString work without it)
334 }
335
CreateUnoText_Impl()336 void ScHeaderFooterTextObj::CreateUnoText_Impl()
337 {
338 if ( !pUnoText )
339 {
340 // can't be aggregated because getString/setString is handled here
341 ScSharedHeaderFooterEditSource aEditSource( &aTextData );
342 pUnoText = new SvxUnoText( &aEditSource, lcl_GetHdFtPropertySet(), uno::Reference<text::XText>() );
343 pUnoText->acquire();
344 }
345 }
346
~ScHeaderFooterTextObj()347 ScHeaderFooterTextObj::~ScHeaderFooterTextObj()
348 {
349 if (pUnoText)
350 pUnoText->release();
351 }
352
GetUnoText()353 const SvxUnoText& ScHeaderFooterTextObj::GetUnoText()
354 {
355 if (!pUnoText)
356 CreateUnoText_Impl();
357 return *pUnoText;
358 }
359
360 // XText
361
createTextCursor()362 uno::Reference<text::XTextCursor> SAL_CALL ScHeaderFooterTextObj::createTextCursor()
363 {
364 ScUnoGuard aGuard;
365 return new ScHeaderFooterTextCursor( *this );
366 }
367
createTextCursorByRange(const uno::Reference<text::XTextRange> & aTextPosition)368 uno::Reference<text::XTextCursor> SAL_CALL ScHeaderFooterTextObj::createTextCursorByRange(
369 const uno::Reference<text::XTextRange>& aTextPosition )
370 {
371 ScUnoGuard aGuard;
372 if (!pUnoText)
373 CreateUnoText_Impl();
374 return pUnoText->createTextCursorByRange(aTextPosition);
375 //! wie ScCellObj::createTextCursorByRange, wenn SvxUnoTextRange_getReflection verfuegbar
376 }
377
FillDummyFieldData(ScHeaderFieldData & rData)378 void ScHeaderFooterTextObj::FillDummyFieldData( ScHeaderFieldData& rData ) // static
379 {
380 String aDummy(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM( "???" )));
381 rData.aTitle = aDummy;
382 rData.aLongDocName = aDummy;
383 rData.aShortDocName = aDummy;
384 rData.aTabName = aDummy;
385 rData.nPageNo = 1;
386 rData.nTotalPages = 99;
387 }
388
getString()389 rtl::OUString SAL_CALL ScHeaderFooterTextObj::getString()
390 {
391 ScUnoGuard aGuard;
392 rtl::OUString aRet;
393 const EditTextObject* pData;
394
395 sal_uInt16 nPart = aTextData.GetPart();
396 ScHeaderFooterContentObj& rContentObj = aTextData.GetContentObj();
397
398 if (nPart == SC_HDFT_LEFT)
399 pData = rContentObj.GetLeftEditObject();
400 else if (nPart == SC_HDFT_CENTER)
401 pData = rContentObj.GetCenterEditObject();
402 else
403 pData = rContentObj.GetRightEditObject();
404 if (pData)
405 {
406 // for pure text, no font info is needed in pool defaults
407 ScHeaderEditEngine aEditEngine( EditEngine::CreatePool(), sal_True );
408
409 ScHeaderFieldData aData;
410 FillDummyFieldData( aData );
411 aEditEngine.SetData( aData );
412
413 aEditEngine.SetText(*pData);
414 aRet = ScEditUtil::GetSpaceDelimitedString( aEditEngine );
415 }
416 return aRet;
417 }
418
setString(const rtl::OUString & aText)419 void SAL_CALL ScHeaderFooterTextObj::setString( const rtl::OUString& aText )
420 {
421 ScUnoGuard aGuard;
422 String aString(aText);
423
424 // for pure text, no font info is needed in pool defaults
425 ScHeaderEditEngine aEditEngine( EditEngine::CreatePool(), sal_True );
426 aEditEngine.SetText( aString );
427
428 aTextData.GetContentObj().UpdateText( aTextData.GetPart(), aEditEngine );
429 }
430
insertString(const uno::Reference<text::XTextRange> & xRange,const rtl::OUString & aString,sal_Bool bAbsorb)431 void SAL_CALL ScHeaderFooterTextObj::insertString( const uno::Reference<text::XTextRange>& xRange,
432 const rtl::OUString& aString, sal_Bool bAbsorb )
433 {
434 ScUnoGuard aGuard;
435 if (!pUnoText)
436 CreateUnoText_Impl();
437 pUnoText->insertString( xRange, aString, bAbsorb );
438 }
439
insertControlCharacter(const uno::Reference<text::XTextRange> & xRange,sal_Int16 nControlCharacter,sal_Bool bAbsorb)440 void SAL_CALL ScHeaderFooterTextObj::insertControlCharacter(
441 const uno::Reference<text::XTextRange>& xRange,
442 sal_Int16 nControlCharacter, sal_Bool bAbsorb )
443 {
444 ScUnoGuard aGuard;
445 if (!pUnoText)
446 CreateUnoText_Impl();
447 pUnoText->insertControlCharacter( xRange, nControlCharacter, bAbsorb );
448 }
449
insertTextContent(const uno::Reference<text::XTextRange> & xRange,const uno::Reference<text::XTextContent> & xContent,sal_Bool bAbsorb)450 void SAL_CALL ScHeaderFooterTextObj::insertTextContent(
451 const uno::Reference<text::XTextRange >& xRange,
452 const uno::Reference<text::XTextContent >& xContent,
453 sal_Bool bAbsorb )
454 {
455 ScUnoGuard aGuard;
456 if ( xContent.is() && xRange.is() )
457 {
458 ScHeaderFieldObj* pHeaderField = ScHeaderFieldObj::getImplementation( xContent );
459
460 SvxUnoTextRangeBase* pTextRange =
461 ScHeaderFooterTextCursor::getImplementation( xRange );
462
463 #if 0
464 if (!pTextRange)
465 pTextRange = (SvxUnoTextRange*)xRange->getImplementation(
466 SvxUnoTextRange_getReflection() );
467 //! bei SvxUnoTextRange testen, ob in passendem Objekt !!!
468 #endif
469
470 if ( pHeaderField && !pHeaderField->IsInserted() && pTextRange )
471 {
472 SvxEditSource* pEditSource = pTextRange->GetEditSource();
473 ESelection aSelection(pTextRange->GetSelection());
474
475 if (!bAbsorb)
476 {
477 // don't replace -> append at end
478 aSelection.Adjust();
479 aSelection.nStartPara = aSelection.nEndPara;
480 aSelection.nStartPos = aSelection.nEndPos;
481 }
482
483 SvxFieldItem aItem(pHeaderField->CreateFieldItem());
484
485 SvxTextForwarder* pForwarder = pEditSource->GetTextForwarder();
486 pForwarder->QuickInsertField( aItem, aSelection );
487 pEditSource->UpdateData();
488
489 // neue Selektion: ein Zeichen
490 aSelection.Adjust();
491 aSelection.nEndPara = aSelection.nStartPara;
492 aSelection.nEndPos = aSelection.nStartPos + 1;
493 pHeaderField->InitDoc( &aTextData.GetContentObj(), aTextData.GetPart(), aSelection );
494
495 // #91431# for bAbsorb=sal_False, the new selection must be behind the inserted content
496 // (the xml filter relies on this)
497 if (!bAbsorb)
498 aSelection.nStartPos = aSelection.nEndPos;
499
500 pTextRange->SetSelection( aSelection );
501
502 return;
503 }
504 }
505
506 if (!pUnoText)
507 CreateUnoText_Impl();
508 pUnoText->insertTextContent( xRange, xContent, bAbsorb );
509 }
510
removeTextContent(const uno::Reference<text::XTextContent> & xContent)511 void SAL_CALL ScHeaderFooterTextObj::removeTextContent(
512 const uno::Reference<text::XTextContent>& xContent )
513 {
514 ScUnoGuard aGuard;
515 if ( xContent.is() )
516 {
517 ScHeaderFieldObj* pHeaderField = ScHeaderFieldObj::getImplementation( xContent );
518 if ( pHeaderField && pHeaderField->IsInserted() )
519 {
520 //! Testen, ob das Feld in dieser Zelle ist
521 pHeaderField->DeleteField();
522 return;
523 }
524 }
525 if (!pUnoText)
526 CreateUnoText_Impl();
527 pUnoText->removeTextContent( xContent );
528 }
529
getText()530 uno::Reference<text::XText> SAL_CALL ScHeaderFooterTextObj::getText()
531 {
532 ScUnoGuard aGuard;
533 if (!pUnoText)
534 CreateUnoText_Impl();
535 return pUnoText->getText();
536 }
537
getStart()538 uno::Reference<text::XTextRange> SAL_CALL ScHeaderFooterTextObj::getStart()
539 {
540 ScUnoGuard aGuard;
541 if (!pUnoText)
542 CreateUnoText_Impl();
543 return pUnoText->getStart();
544 }
545
getEnd()546 uno::Reference<text::XTextRange> SAL_CALL ScHeaderFooterTextObj::getEnd()
547 {
548 ScUnoGuard aGuard;
549 if (!pUnoText)
550 CreateUnoText_Impl();
551 return pUnoText->getEnd();
552 }
553
554 // XTextFieldsSupplier
555
getTextFields()556 uno::Reference<container::XEnumerationAccess> SAL_CALL ScHeaderFooterTextObj::getTextFields()
557 {
558 ScUnoGuard aGuard;
559 // all fields
560 return new ScHeaderFieldsObj( &aTextData.GetContentObj(), aTextData.GetPart(), SC_SERVICE_INVALID );
561 }
562
getTextFieldMasters()563 uno::Reference<container::XNameAccess> SAL_CALL ScHeaderFooterTextObj::getTextFieldMasters()
564 {
565 // sowas gibts nicht im Calc (?)
566 return NULL;
567 }
568
569 // XTextRangeMover
570
moveTextRange(const uno::Reference<text::XTextRange> & xRange,sal_Int16 nParagraphs)571 void SAL_CALL ScHeaderFooterTextObj::moveTextRange(
572 const uno::Reference<text::XTextRange>& xRange,
573 sal_Int16 nParagraphs )
574 {
575 ScUnoGuard aGuard;
576 if (!pUnoText)
577 CreateUnoText_Impl();
578 pUnoText->moveTextRange( xRange, nParagraphs );
579 }
580
581 // XEnumerationAccess
582
createEnumeration()583 uno::Reference<container::XEnumeration> SAL_CALL ScHeaderFooterTextObj::createEnumeration()
584 {
585 ScUnoGuard aGuard;
586 if (!pUnoText)
587 CreateUnoText_Impl();
588 return pUnoText->createEnumeration();
589 }
590
591 // XElementAccess
592
getElementType()593 uno::Type SAL_CALL ScHeaderFooterTextObj::getElementType()
594 {
595 ScUnoGuard aGuard;
596 if (!pUnoText)
597 CreateUnoText_Impl();
598 return pUnoText->getElementType();
599 }
600
hasElements()601 sal_Bool SAL_CALL ScHeaderFooterTextObj::hasElements()
602 {
603 ScUnoGuard aGuard;
604 if (!pUnoText)
605 CreateUnoText_Impl();
606 return pUnoText->hasElements();
607 }
608
609 //------------------------------------------------------------------------
610
ScCellTextCursor(const ScCellTextCursor & rOther)611 ScCellTextCursor::ScCellTextCursor(const ScCellTextCursor& rOther) :
612 SvxUnoTextCursor( rOther ),
613 rTextObj( rOther.rTextObj )
614 {
615 rTextObj.acquire();
616 }
617
ScCellTextCursor(ScCellObj & rText)618 ScCellTextCursor::ScCellTextCursor(ScCellObj& rText) :
619 SvxUnoTextCursor( rText.GetUnoText() ),
620 rTextObj( rText )
621 {
622 rTextObj.acquire();
623 }
624
~ScCellTextCursor()625 ScCellTextCursor::~ScCellTextCursor() throw()
626 {
627 rTextObj.release();
628 }
629
630 // SvxUnoTextCursor methods reimplemented here to return the right objects:
631
getText()632 uno::Reference<text::XText> SAL_CALL ScCellTextCursor::getText()
633 {
634 ScUnoGuard aGuard;
635 return &rTextObj;
636 }
637
getStart()638 uno::Reference<text::XTextRange> SAL_CALL ScCellTextCursor::getStart()
639 {
640 ScUnoGuard aGuard;
641
642 //! use other object for range than cursor?
643
644 ScCellTextCursor* pNew = new ScCellTextCursor( *this );
645 uno::Reference<text::XTextRange> xRange( static_cast<SvxUnoTextRangeBase*>(pNew) );
646
647 ESelection aNewSel(GetSelection());
648 aNewSel.nEndPara = aNewSel.nStartPara;
649 aNewSel.nEndPos = aNewSel.nStartPos;
650 pNew->SetSelection( aNewSel );
651
652 return xRange;
653 }
654
getEnd()655 uno::Reference<text::XTextRange> SAL_CALL ScCellTextCursor::getEnd()
656 {
657 ScUnoGuard aGuard;
658
659 //! use other object for range than cursor?
660
661 ScCellTextCursor* pNew = new ScCellTextCursor( *this );
662 uno::Reference<text::XTextRange> xRange( static_cast<SvxUnoTextRangeBase*>(pNew) );
663
664 ESelection aNewSel(GetSelection());
665 aNewSel.nStartPara = aNewSel.nEndPara;
666 aNewSel.nStartPos = aNewSel.nEndPos;
667 pNew->SetSelection( aNewSel );
668
669 return xRange;
670 }
671
672 // XUnoTunnel
673
getSomething(const uno::Sequence<sal_Int8> & rId)674 sal_Int64 SAL_CALL ScCellTextCursor::getSomething(
675 const uno::Sequence<sal_Int8 >& rId )
676 {
677 if ( rId.getLength() == 16 &&
678 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
679 rId.getConstArray(), 16 ) )
680 {
681 return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
682 }
683 return SvxUnoTextCursor::getSomething( rId );
684 }
685
686 // static
getUnoTunnelId()687 const uno::Sequence<sal_Int8>& ScCellTextCursor::getUnoTunnelId()
688 {
689 static uno::Sequence<sal_Int8> * pSeq = 0;
690 if( !pSeq )
691 {
692 osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
693 if( !pSeq )
694 {
695 static uno::Sequence< sal_Int8 > aSeq( 16 );
696 rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
697 pSeq = &aSeq;
698 }
699 }
700 return *pSeq;
701 }
702
703 // static
getImplementation(const uno::Reference<uno::XInterface> xObj)704 ScCellTextCursor* ScCellTextCursor::getImplementation( const uno::Reference<uno::XInterface> xObj )
705 {
706 ScCellTextCursor* pRet = NULL;
707 uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY );
708 if (xUT.is())
709 pRet = reinterpret_cast<ScCellTextCursor*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
710 return pRet;
711 }
712
713 //------------------------------------------------------------------------
714
ScHeaderFooterTextCursor(const ScHeaderFooterTextCursor & rOther)715 ScHeaderFooterTextCursor::ScHeaderFooterTextCursor(const ScHeaderFooterTextCursor& rOther) :
716 SvxUnoTextCursor( rOther ),
717 rTextObj( rOther.rTextObj )
718 {
719 rTextObj.acquire();
720 }
721
ScHeaderFooterTextCursor(ScHeaderFooterTextObj & rText)722 ScHeaderFooterTextCursor::ScHeaderFooterTextCursor(ScHeaderFooterTextObj& rText) :
723 SvxUnoTextCursor( rText.GetUnoText() ),
724 rTextObj( rText )
725 {
726 rTextObj.acquire();
727 }
728
~ScHeaderFooterTextCursor()729 ScHeaderFooterTextCursor::~ScHeaderFooterTextCursor() throw()
730 {
731 rTextObj.release();
732 }
733
734 // SvxUnoTextCursor methods reimplemented here to return the right objects:
735
getText()736 uno::Reference<text::XText> SAL_CALL ScHeaderFooterTextCursor::getText()
737 {
738 ScUnoGuard aGuard;
739 return &rTextObj;
740 }
741
getStart()742 uno::Reference<text::XTextRange> SAL_CALL ScHeaderFooterTextCursor::getStart()
743 {
744 ScUnoGuard aGuard;
745
746 //! use other object for range than cursor?
747
748 ScHeaderFooterTextCursor* pNew = new ScHeaderFooterTextCursor( *this );
749 uno::Reference<text::XTextRange> xRange( static_cast<SvxUnoTextRangeBase*>(pNew) );
750
751 ESelection aNewSel(GetSelection());
752 aNewSel.nEndPara = aNewSel.nStartPara;
753 aNewSel.nEndPos = aNewSel.nStartPos;
754 pNew->SetSelection( aNewSel );
755
756 return xRange;
757 }
758
getEnd()759 uno::Reference<text::XTextRange> SAL_CALL ScHeaderFooterTextCursor::getEnd()
760 {
761 ScUnoGuard aGuard;
762
763 //! use other object for range than cursor?
764
765 ScHeaderFooterTextCursor* pNew = new ScHeaderFooterTextCursor( *this );
766 uno::Reference<text::XTextRange> xRange( static_cast<SvxUnoTextRangeBase*>(pNew) );
767
768 ESelection aNewSel(GetSelection());
769 aNewSel.nStartPara = aNewSel.nEndPara;
770 aNewSel.nStartPos = aNewSel.nEndPos;
771 pNew->SetSelection( aNewSel );
772
773 return xRange;
774 }
775
776 // XUnoTunnel
777
getSomething(const uno::Sequence<sal_Int8> & rId)778 sal_Int64 SAL_CALL ScHeaderFooterTextCursor::getSomething(
779 const uno::Sequence<sal_Int8 >& rId )
780 {
781 if ( rId.getLength() == 16 &&
782 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
783 rId.getConstArray(), 16 ) )
784 {
785 return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
786 }
787 return SvxUnoTextCursor::getSomething( rId );
788 }
789
790 // static
getUnoTunnelId()791 const uno::Sequence<sal_Int8>& ScHeaderFooterTextCursor::getUnoTunnelId()
792 {
793 static uno::Sequence<sal_Int8> * pSeq = 0;
794 if( !pSeq )
795 {
796 osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
797 if( !pSeq )
798 {
799 static uno::Sequence< sal_Int8 > aSeq( 16 );
800 rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
801 pSeq = &aSeq;
802 }
803 }
804 return *pSeq;
805 }
806
807 // static
getImplementation(const uno::Reference<uno::XInterface> xObj)808 ScHeaderFooterTextCursor* ScHeaderFooterTextCursor::getImplementation(
809 const uno::Reference<uno::XInterface> xObj )
810 {
811 ScHeaderFooterTextCursor* pRet = NULL;
812 uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY );
813 if (xUT.is())
814 pRet = reinterpret_cast<ScHeaderFooterTextCursor*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
815 return pRet;
816 }
817
818 //------------------------------------------------------------------------
819
ScDrawTextCursor(const ScDrawTextCursor & rOther)820 ScDrawTextCursor::ScDrawTextCursor(const ScDrawTextCursor& rOther) :
821 SvxUnoTextCursor( rOther ),
822 xParentText( rOther.xParentText )
823 {
824 }
825
ScDrawTextCursor(const uno::Reference<text::XText> & xParent,const SvxUnoTextBase & rText)826 ScDrawTextCursor::ScDrawTextCursor( const uno::Reference<text::XText>& xParent,
827 const SvxUnoTextBase& rText ) :
828 SvxUnoTextCursor( rText ),
829 xParentText( xParent )
830
831 {
832 }
833
~ScDrawTextCursor()834 ScDrawTextCursor::~ScDrawTextCursor() throw()
835 {
836 }
837
838 // SvxUnoTextCursor methods reimplemented here to return the right objects:
839
getText()840 uno::Reference<text::XText> SAL_CALL ScDrawTextCursor::getText()
841 {
842 ScUnoGuard aGuard;
843 return xParentText;
844 }
845
getStart()846 uno::Reference<text::XTextRange> SAL_CALL ScDrawTextCursor::getStart()
847 {
848 ScUnoGuard aGuard;
849
850 //! use other object for range than cursor?
851
852 ScDrawTextCursor* pNew = new ScDrawTextCursor( *this );
853 uno::Reference<text::XTextRange> xRange( static_cast<SvxUnoTextRangeBase*>(pNew) );
854
855 ESelection aNewSel(GetSelection());
856 aNewSel.nEndPara = aNewSel.nStartPara;
857 aNewSel.nEndPos = aNewSel.nStartPos;
858 pNew->SetSelection( aNewSel );
859
860 return xRange;
861 }
862
getEnd()863 uno::Reference<text::XTextRange> SAL_CALL ScDrawTextCursor::getEnd()
864 {
865 ScUnoGuard aGuard;
866
867 //! use other object for range than cursor?
868
869 ScDrawTextCursor* pNew = new ScDrawTextCursor( *this );
870 uno::Reference<text::XTextRange> xRange( static_cast<SvxUnoTextRangeBase*>(pNew) );
871
872 ESelection aNewSel(GetSelection());
873 aNewSel.nStartPara = aNewSel.nEndPara;
874 aNewSel.nStartPos = aNewSel.nEndPos;
875 pNew->SetSelection( aNewSel );
876
877 return xRange;
878 }
879
880 // XUnoTunnel
881
getSomething(const uno::Sequence<sal_Int8> & rId)882 sal_Int64 SAL_CALL ScDrawTextCursor::getSomething(
883 const uno::Sequence<sal_Int8 >& rId )
884 {
885 if ( rId.getLength() == 16 &&
886 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
887 rId.getConstArray(), 16 ) )
888 {
889 return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
890 }
891 return SvxUnoTextCursor::getSomething( rId );
892 }
893
894 // static
getUnoTunnelId()895 const uno::Sequence<sal_Int8>& ScDrawTextCursor::getUnoTunnelId()
896 {
897 static uno::Sequence<sal_Int8> * pSeq = 0;
898 if( !pSeq )
899 {
900 osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
901 if( !pSeq )
902 {
903 static uno::Sequence< sal_Int8 > aSeq( 16 );
904 rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
905 pSeq = &aSeq;
906 }
907 }
908 return *pSeq;
909 }
910
911 // static
getImplementation(const uno::Reference<uno::XInterface> xObj)912 ScDrawTextCursor* ScDrawTextCursor::getImplementation( const uno::Reference<uno::XInterface> xObj )
913 {
914 ScDrawTextCursor* pRet = NULL;
915 uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY );
916 if (xUT.is())
917 pRet = reinterpret_cast<ScDrawTextCursor*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
918 return pRet;
919 }
920
921 //------------------------------------------------------------------------
922
ScSimpleEditSourceHelper()923 ScSimpleEditSourceHelper::ScSimpleEditSourceHelper()
924 {
925 SfxItemPool* pEnginePool = EditEngine::CreatePool();
926 pEnginePool->SetDefaultMetric( SFX_MAPUNIT_100TH_MM );
927 pEnginePool->FreezeIdRanges();
928
929 pEditEngine = new ScFieldEditEngine( pEnginePool, NULL, sal_True ); // TRUE: become owner of pool
930 pForwarder = new SvxEditEngineForwarder( *pEditEngine );
931 pOriginalSource = new ScSimpleEditSource( pForwarder );
932 }
933
~ScSimpleEditSourceHelper()934 ScSimpleEditSourceHelper::~ScSimpleEditSourceHelper()
935 {
936 ScUnoGuard aGuard; // needed for EditEngine dtor
937
938 delete pOriginalSource;
939 delete pForwarder;
940 delete pEditEngine;
941 }
942
ScEditEngineTextObj()943 ScEditEngineTextObj::ScEditEngineTextObj() :
944 SvxUnoText( GetOriginalSource(), ScCellObj::GetEditPropertySet(), uno::Reference<text::XText>() )
945 {
946 }
947
~ScEditEngineTextObj()948 ScEditEngineTextObj::~ScEditEngineTextObj() throw()
949 {
950 }
951
SetText(const EditTextObject & rTextObject)952 void ScEditEngineTextObj::SetText( const EditTextObject& rTextObject )
953 {
954 GetEditEngine()->SetText( rTextObject );
955
956 ESelection aSel;
957 ::GetSelection( aSel, GetEditSource()->GetTextForwarder() );
958 SetSelection( aSel );
959 }
960
CreateTextObject()961 EditTextObject* ScEditEngineTextObj::CreateTextObject()
962 {
963 return GetEditEngine()->CreateTextObject();
964 }
965
966 //------------------------------------------------------------------------
967
ScCellTextData(ScDocShell * pDocSh,const ScAddress & rP)968 ScCellTextData::ScCellTextData(ScDocShell* pDocSh, const ScAddress& rP) :
969 pDocShell( pDocSh ),
970 aCellPos( rP ),
971 pEditEngine( NULL ),
972 pForwarder( NULL ),
973 pOriginalSource( NULL ),
974 bDataValid( sal_False ),
975 bInUpdate( sal_False ),
976 bDirty( sal_False ),
977 bDoUpdate( sal_True )
978 {
979 if (pDocShell)
980 pDocShell->GetDocument()->AddUnoObject(*this);
981 }
982
~ScCellTextData()983 ScCellTextData::~ScCellTextData()
984 {
985 ScUnoGuard aGuard; // needed for EditEngine dtor
986
987 if (pDocShell)
988 {
989 pDocShell->GetDocument()->RemoveUnoObject(*this);
990 pDocShell->GetDocument()->DisposeFieldEditEngine(pEditEngine);
991 }
992 else
993 delete pEditEngine;
994
995 delete pForwarder;
996
997 delete pOriginalSource;
998 }
999
GetOriginalSource()1000 ScSharedCellEditSource* ScCellTextData::GetOriginalSource()
1001 {
1002 if (!pOriginalSource)
1003 pOriginalSource = new ScSharedCellEditSource( this );
1004 return pOriginalSource;
1005 }
1006
GetCellText(const ScAddress & rCellPos,String & rText)1007 void ScCellTextData::GetCellText(const ScAddress& rCellPos, String& rText)
1008 {
1009 if (pDocShell)
1010 {
1011 ScDocument* pDoc = pDocShell->GetDocument();
1012 pDoc->GetInputString( rCellPos.Col(), rCellPos.Row(), rCellPos.Tab(), rText );
1013 }
1014 }
1015
GetTextForwarder()1016 SvxTextForwarder* ScCellTextData::GetTextForwarder()
1017 {
1018 if (!pEditEngine)
1019 {
1020 if ( pDocShell )
1021 {
1022 ScDocument* pDoc = pDocShell->GetDocument();
1023 pEditEngine = pDoc->CreateFieldEditEngine();
1024 }
1025 else
1026 {
1027 SfxItemPool* pEnginePool = EditEngine::CreatePool();
1028 pEnginePool->FreezeIdRanges();
1029 pEditEngine = new ScFieldEditEngine( pEnginePool, NULL, sal_True );
1030 }
1031 // currently, GetPortions doesn't work if UpdateMode is sal_False,
1032 // this will be fixed (in EditEngine) by src600
1033 // pEditEngine->SetUpdateMode( sal_False );
1034 pEditEngine->EnableUndo( sal_False );
1035 if (pDocShell)
1036 pEditEngine->SetRefDevice(pDocShell->GetRefDevice());
1037 else
1038 pEditEngine->SetRefMapMode( MAP_100TH_MM );
1039 pForwarder = new SvxEditEngineForwarder(*pEditEngine);
1040 }
1041
1042 if (bDataValid)
1043 return pForwarder;
1044
1045 String aText;
1046
1047 if (pDocShell)
1048 {
1049 ScDocument* pDoc = pDocShell->GetDocument();
1050
1051 SfxItemSet aDefaults( pEditEngine->GetEmptyItemSet() );
1052 if( const ScPatternAttr* pPattern =
1053 pDoc->GetPattern( aCellPos.Col(), aCellPos.Row(), aCellPos.Tab() ) )
1054 {
1055 pPattern->FillEditItemSet( &aDefaults );
1056 pPattern->FillEditParaItems( &aDefaults ); // including alignment etc. (for reading)
1057 }
1058
1059 const ScBaseCell* pCell = pDoc->GetCell( aCellPos );
1060 if ( pCell && pCell->GetCellType() == CELLTYPE_EDIT )
1061 pEditEngine->SetTextNewDefaults( *((const ScEditCell*)pCell)->GetData(), aDefaults );
1062 else
1063 {
1064 GetCellText( aCellPos, aText );
1065 if (aText.Len())
1066 pEditEngine->SetTextNewDefaults( aText, aDefaults );
1067 else
1068 pEditEngine->SetDefaults(aDefaults);
1069 }
1070 }
1071
1072 bDataValid = sal_True;
1073 return pForwarder;
1074 }
1075
UpdateData()1076 void ScCellTextData::UpdateData()
1077 {
1078 if ( bDoUpdate )
1079 {
1080 DBG_ASSERT(pEditEngine != NULL, "no EditEngine for UpdateData()");
1081 if ( pDocShell && pEditEngine )
1082 {
1083 // during the own UpdateData call, bDataValid must not be reset,
1084 // or things like attributes after the text would be lost
1085 // (are not stored in the cell)
1086
1087 bInUpdate = sal_True; // prevents bDataValid from being reset
1088
1089 ScDocFunc aFunc(*pDocShell);
1090 aFunc.PutData( aCellPos, *pEditEngine, sal_False, sal_True ); // always as text
1091
1092 bInUpdate = sal_False;
1093 bDirty = sal_False;
1094 }
1095 }
1096 else
1097 bDirty = sal_True;
1098 }
1099
Notify(SfxBroadcaster &,const SfxHint & rHint)1100 void ScCellTextData::Notify( SfxBroadcaster&, const SfxHint& rHint )
1101 {
1102 if ( rHint.ISA( ScUpdateRefHint ) )
1103 {
1104 // const ScUpdateRefHint& rRef = (const ScUpdateRefHint&)rHint;
1105
1106 //! Ref-Update
1107 }
1108 else if ( rHint.ISA( SfxSimpleHint ) )
1109 {
1110 sal_uLong nId = ((const SfxSimpleHint&)rHint).GetId();
1111 if ( nId == SFX_HINT_DYING )
1112 {
1113 pDocShell = NULL; // invalid now
1114
1115 DELETEZ( pForwarder );
1116 DELETEZ( pEditEngine ); // EditEngine uses document's pool
1117 }
1118 else if ( nId == SFX_HINT_DATACHANGED )
1119 {
1120 if (!bInUpdate) // not for own UpdateData calls
1121 bDataValid = sal_False; // text has to be read from the cell again
1122 }
1123 }
1124 }
1125
ScCellTextObj(ScDocShell * pDocSh,const ScAddress & rP)1126 ScCellTextObj::ScCellTextObj(ScDocShell* pDocSh, const ScAddress& rP) :
1127 ScCellTextData( pDocSh, rP ),
1128 SvxUnoText( GetOriginalSource(), ScCellObj::GetEditPropertySet(), uno::Reference<text::XText>() )
1129 {
1130 }
1131
~ScCellTextObj()1132 ScCellTextObj::~ScCellTextObj() throw()
1133 {
1134 }
1135