Stop leaking all ScPostIt instances.
[LibreOffice.git] / sc / source / ui / unoobj / textuno.cxx
blobb8328207ed11f91f9b549b72c45e54114e49c6a4
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/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "scitems.hxx"
21 #include <editeng/eeitem.hxx>
22 #include <svx/svdpool.hxx>
23 #include <svx/svdobj.hxx>
24 #include <editeng/editeng.hxx>
25 #include <editeng/editobj.hxx>
26 #include <editeng/flditem.hxx>
27 #include <svx/unomid.hxx>
28 #include <editeng/unoprnms.hxx>
29 #include <editeng/unofored.hxx>
30 #include <vcl/virdev.hxx>
31 #include <vcl/svapp.hxx>
32 #include <com/sun/star/awt/FontSlant.hpp>
34 #include <com/sun/star/beans/PropertyAttribute.hpp>
35 #include <editeng/unoipset.hxx>
36 #include "textuno.hxx"
37 #include "fielduno.hxx"
38 #include "servuno.hxx"
39 #include "editsrc.hxx"
40 #include "docsh.hxx"
41 #include "editutil.hxx"
42 #include "miscuno.hxx"
43 #include "cellsuno.hxx"
44 #include "hints.hxx"
45 #include "patattr.hxx"
46 #include "formulacell.hxx"
47 #include "docfunc.hxx"
48 #include "scmod.hxx"
50 using namespace com::sun::star;
52 //------------------------------------------------------------------------
54 static const SvxItemPropertySet * lcl_GetHdFtPropertySet()
56 static SfxItemPropertyMapEntry aHdFtPropertyMap_Impl[] =
58 SVX_UNOEDIT_CHAR_PROPERTIES,
59 SVX_UNOEDIT_FONT_PROPERTIES,
60 SVX_UNOEDIT_PARA_PROPERTIES,
61 SVX_UNOEDIT_NUMBERING_PROPERTIE, // for completeness of service ParagraphProperties
62 {0,0,0,0,0,0}
64 static sal_Bool bTwipsSet = false;
66 if (!bTwipsSet)
68 // modify PropertyMap to include CONVERT_TWIPS flag for font height
69 // (headers/footers are in twips)
71 SfxItemPropertyMapEntry* pEntry = aHdFtPropertyMap_Impl;
72 while (pEntry->pName)
74 if ( ( pEntry->nWID == EE_CHAR_FONTHEIGHT ||
75 pEntry->nWID == EE_CHAR_FONTHEIGHT_CJK ||
76 pEntry->nWID == EE_CHAR_FONTHEIGHT_CTL ) &&
77 pEntry->nMemberId == MID_FONTHEIGHT )
79 pEntry->nMemberId |= CONVERT_TWIPS;
82 ++pEntry;
84 bTwipsSet = sal_True;
86 static SvxItemPropertySet aHdFtPropertySet_Impl( aHdFtPropertyMap_Impl, SdrObject::GetGlobalDrawObjectItemPool() );
87 return &aHdFtPropertySet_Impl;
90 //------------------------------------------------------------------------
92 SC_SIMPLE_SERVICE_INFO( ScHeaderFooterContentObj, "ScHeaderFooterContentObj", "com.sun.star.sheet.HeaderFooterContent" )
93 SC_SIMPLE_SERVICE_INFO( ScHeaderFooterTextObj, "ScHeaderFooterTextObj", "stardiv.one.Text.Text" )
95 //------------------------------------------------------------------------
97 ScHeaderFooterContentObj::ScHeaderFooterContentObj( const EditTextObject* pLeft,
98 const EditTextObject* pCenter,
99 const EditTextObject* pRight ) :
100 mxLeftText(new ScHeaderFooterTextObj(*this, SC_HDFT_LEFT, pLeft)),
101 mxCenterText(new ScHeaderFooterTextObj(*this, SC_HDFT_CENTER, pCenter)),
102 mxRightText(new ScHeaderFooterTextObj(*this, SC_HDFT_RIGHT, pRight))
106 ScHeaderFooterContentObj::~ScHeaderFooterContentObj() {}
108 const EditTextObject* ScHeaderFooterContentObj::GetLeftEditObject() const
110 return mxLeftText->GetTextObject();
113 const EditTextObject* ScHeaderFooterContentObj::GetCenterEditObject() const
115 return mxCenterText->GetTextObject();
118 const EditTextObject* ScHeaderFooterContentObj::GetRightEditObject() const
120 return mxRightText->GetTextObject();
123 // XHeaderFooterContent
125 uno::Reference<text::XText> SAL_CALL ScHeaderFooterContentObj::getLeftText()
126 throw(uno::RuntimeException)
128 SolarMutexGuard aGuard;
129 uno::Reference<text::XText> xInt(*mxLeftText, uno::UNO_QUERY);
130 return xInt;
133 uno::Reference<text::XText> SAL_CALL ScHeaderFooterContentObj::getCenterText()
134 throw(uno::RuntimeException)
136 SolarMutexGuard aGuard;
137 uno::Reference<text::XText> xInt(*mxCenterText, uno::UNO_QUERY);
138 return xInt;
141 uno::Reference<text::XText> SAL_CALL ScHeaderFooterContentObj::getRightText()
142 throw(uno::RuntimeException)
144 SolarMutexGuard aGuard;
145 uno::Reference<text::XText> xInt(*mxRightText, uno::UNO_QUERY);
146 return xInt;
149 // XUnoTunnel
151 sal_Int64 SAL_CALL ScHeaderFooterContentObj::getSomething(
152 const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException)
154 if ( rId.getLength() == 16 &&
155 0 == memcmp( getUnoTunnelId().getConstArray(),
156 rId.getConstArray(), 16 ) )
158 return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
160 return 0;
163 namespace
165 class theScHeaderFooterContentObjUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theScHeaderFooterContentObjUnoTunnelId> {};
168 const uno::Sequence<sal_Int8>& ScHeaderFooterContentObj::getUnoTunnelId()
170 return theScHeaderFooterContentObjUnoTunnelId::get().getSeq();
173 ScHeaderFooterContentObj* ScHeaderFooterContentObj::getImplementation(
174 const uno::Reference<sheet::XHeaderFooterContent> xObj )
176 ScHeaderFooterContentObj* pRet = NULL;
177 uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY );
178 if (xUT.is())
179 pRet = reinterpret_cast<ScHeaderFooterContentObj*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
180 return pRet;
184 //------------------------------------------------------------------------
186 ScHeaderFooterTextData::ScHeaderFooterTextData(
187 ScHeaderFooterContentObj& rContent, sal_uInt16 nP, const EditTextObject* pTextObj) :
188 mpTextObj(pTextObj ? pTextObj->Clone() : NULL),
189 rContentObj( rContent ),
190 nPart( nP ),
191 pEditEngine( NULL ),
192 pForwarder( NULL ),
193 bDataValid(false)
197 ScHeaderFooterTextData::~ScHeaderFooterTextData()
199 SolarMutexGuard aGuard; // needed for EditEngine dtor
201 delete pForwarder;
202 delete pEditEngine;
203 delete mpTextObj;
206 SvxTextForwarder* ScHeaderFooterTextData::GetTextForwarder()
208 if (!pEditEngine)
210 SfxItemPool* pEnginePool = EditEngine::CreatePool();
211 pEnginePool->FreezeIdRanges();
212 ScHeaderEditEngine* pHdrEngine = new ScHeaderEditEngine( pEnginePool, sal_True );
214 pHdrEngine->EnableUndo( false );
215 pHdrEngine->SetRefMapMode( MAP_TWIP );
217 // default font must be set, independently of document
218 // -> use global pool from module
220 SfxItemSet aDefaults( pHdrEngine->GetEmptyItemSet() );
221 const ScPatternAttr& rPattern = (const ScPatternAttr&)SC_MOD()->GetPool().GetDefaultItem(ATTR_PATTERN);
222 rPattern.FillEditItemSet( &aDefaults );
223 // FillEditItemSet adjusts font height to 1/100th mm,
224 // but for header/footer twips is needed, as in the PatternAttr:
225 aDefaults.Put( rPattern.GetItem(ATTR_FONT_HEIGHT), EE_CHAR_FONTHEIGHT );
226 aDefaults.Put( rPattern.GetItem(ATTR_CJK_FONT_HEIGHT), EE_CHAR_FONTHEIGHT_CJK );
227 aDefaults.Put( rPattern.GetItem(ATTR_CTL_FONT_HEIGHT), EE_CHAR_FONTHEIGHT_CTL );
228 pHdrEngine->SetDefaults( aDefaults );
230 ScHeaderFieldData aData;
231 ScHeaderFooterTextObj::FillDummyFieldData( aData );
232 pHdrEngine->SetData( aData );
234 pEditEngine = pHdrEngine;
235 pForwarder = new SvxEditEngineForwarder(*pEditEngine);
238 if (bDataValid)
239 return pForwarder;
241 if (mpTextObj)
242 pEditEngine->SetText(*mpTextObj);
244 bDataValid = true;
245 return pForwarder;
248 void ScHeaderFooterTextData::UpdateData()
250 if (pEditEngine)
252 delete mpTextObj;
253 mpTextObj = pEditEngine->CreateTextObject();
257 void ScHeaderFooterTextData::UpdateData(EditEngine& rEditEngine)
259 delete mpTextObj;
260 mpTextObj = rEditEngine.CreateTextObject();
261 bDataValid = false;
264 const EditTextObject* ScHeaderFooterTextData::GetTextObject() const
266 return mpTextObj;
269 //------------------------------------------------------------------------
271 ScHeaderFooterTextObj::ScHeaderFooterTextObj(
272 ScHeaderFooterContentObj& rContent, sal_uInt16 nP, const EditTextObject* pTextObj) :
273 aTextData(rContent, nP, pTextObj)
275 // ScHeaderFooterTextData acquires rContent
276 // pUnoText is created on demand (getString/setString work without it)
279 void ScHeaderFooterTextObj::CreateUnoText_Impl()
281 if (!mxUnoText.is())
283 // can't be aggregated because getString/setString is handled here
284 ScHeaderFooterEditSource aEditSrc(aTextData);
285 mxUnoText.set(new SvxUnoText(&aEditSrc, lcl_GetHdFtPropertySet(), uno::Reference<text::XText>()));
289 ScHeaderFooterTextObj::~ScHeaderFooterTextObj() {}
291 const EditTextObject* ScHeaderFooterTextObj::GetTextObject() const
293 return aTextData.GetTextObject();
296 const SvxUnoText& ScHeaderFooterTextObj::GetUnoText()
298 if (!mxUnoText.is())
299 CreateUnoText_Impl();
300 return *mxUnoText;
303 // XText
305 uno::Reference<text::XTextCursor> SAL_CALL ScHeaderFooterTextObj::createTextCursor()
306 throw(uno::RuntimeException)
308 SolarMutexGuard aGuard;
309 return new ScHeaderFooterTextCursor( *this );
312 uno::Reference<text::XTextCursor> SAL_CALL ScHeaderFooterTextObj::createTextCursorByRange(
313 const uno::Reference<text::XTextRange>& aTextPosition )
314 throw(uno::RuntimeException)
316 SolarMutexGuard aGuard;
317 if (!mxUnoText.is())
318 CreateUnoText_Impl();
319 return mxUnoText->createTextCursorByRange(aTextPosition);
320 //! wie ScCellObj::createTextCursorByRange, wenn SvxUnoTextRange_getReflection verfuegbar
323 void ScHeaderFooterTextObj::FillDummyFieldData( ScHeaderFieldData& rData )
325 OUString aDummy("???");
326 rData.aTitle = aDummy;
327 rData.aLongDocName = aDummy;
328 rData.aShortDocName = aDummy;
329 rData.aTabName = aDummy;
330 rData.nPageNo = 1;
331 rData.nTotalPages = 99;
334 OUString SAL_CALL ScHeaderFooterTextObj::getString() throw(uno::RuntimeException)
336 SolarMutexGuard aGuard;
337 OUString aRet;
338 const EditTextObject* pData;
340 sal_uInt16 nPart = aTextData.GetPart();
341 ScHeaderFooterContentObj& rContentObj = aTextData.GetContentObj();
343 if (nPart == SC_HDFT_LEFT)
344 pData = rContentObj.GetLeftEditObject();
345 else if (nPart == SC_HDFT_CENTER)
346 pData = rContentObj.GetCenterEditObject();
347 else
348 pData = rContentObj.GetRightEditObject();
349 if (pData)
351 // for pure text, no font info is needed in pool defaults
352 ScHeaderEditEngine aEditEngine( EditEngine::CreatePool(), sal_True );
354 ScHeaderFieldData aData;
355 FillDummyFieldData( aData );
356 aEditEngine.SetData( aData );
358 aEditEngine.SetText(*pData);
359 aRet = ScEditUtil::GetSpaceDelimitedString( aEditEngine );
361 return aRet;
364 void SAL_CALL ScHeaderFooterTextObj::setString( const OUString& aText ) throw(uno::RuntimeException)
366 SolarMutexGuard aGuard;
367 OUString aString(aText);
369 // for pure text, no font info is needed in pool defaults
370 ScHeaderEditEngine aEditEngine(EditEngine::CreatePool(), true);
371 aEditEngine.SetText( aString );
372 aTextData.UpdateData(aEditEngine);
375 void SAL_CALL ScHeaderFooterTextObj::insertString( const uno::Reference<text::XTextRange>& xRange,
376 const OUString& aString, sal_Bool bAbsorb )
377 throw(uno::RuntimeException)
379 SolarMutexGuard aGuard;
380 if (!mxUnoText.is())
381 CreateUnoText_Impl();
382 mxUnoText->insertString( xRange, aString, bAbsorb );
385 void SAL_CALL ScHeaderFooterTextObj::insertControlCharacter(
386 const uno::Reference<text::XTextRange>& xRange,
387 sal_Int16 nControlCharacter, sal_Bool bAbsorb )
388 throw(lang::IllegalArgumentException, uno::RuntimeException)
390 SolarMutexGuard aGuard;
391 if (!mxUnoText.is())
392 CreateUnoText_Impl();
393 mxUnoText->insertControlCharacter( xRange, nControlCharacter, bAbsorb );
396 void SAL_CALL ScHeaderFooterTextObj::insertTextContent(
397 const uno::Reference<text::XTextRange >& xRange,
398 const uno::Reference<text::XTextContent >& xContent,
399 sal_Bool bAbsorb )
400 throw(lang::IllegalArgumentException, uno::RuntimeException)
402 SolarMutexGuard aGuard;
403 if ( xContent.is() && xRange.is() )
405 ScEditFieldObj* pHeaderField = ScEditFieldObj::getImplementation( xContent );
407 SvxUnoTextRangeBase* pTextRange =
408 ScHeaderFooterTextCursor::getImplementation( xRange );
410 if ( pHeaderField && !pHeaderField->IsInserted() && pTextRange )
412 SvxEditSource* pEditSource = pTextRange->GetEditSource();
413 ESelection aSelection(pTextRange->GetSelection());
415 if (!bAbsorb)
417 // don't replace -> append at end
418 aSelection.Adjust();
419 aSelection.nStartPara = aSelection.nEndPara;
420 aSelection.nStartPos = aSelection.nEndPos;
423 SvxFieldItem aItem(pHeaderField->CreateFieldItem());
425 SvxTextForwarder* pForwarder = pEditSource->GetTextForwarder();
426 pForwarder->QuickInsertField( aItem, aSelection );
427 pEditSource->UpdateData();
429 // neue Selektion: ein Zeichen
430 aSelection.Adjust();
431 aSelection.nEndPara = aSelection.nStartPara;
432 aSelection.nEndPos = aSelection.nStartPos + 1;
434 uno::Reference<text::XTextRange> xTextRange;
435 switch (aTextData.GetPart())
437 case SC_HDFT_LEFT:
439 uno::Reference<text::XTextRange> xTemp(
440 aTextData.GetContentObj().getLeftText(), uno::UNO_QUERY);
441 xTextRange = xTemp;
443 break;
444 case SC_HDFT_CENTER:
446 uno::Reference<text::XTextRange> xTemp(
447 aTextData.GetContentObj().getCenterText(), uno::UNO_QUERY);
448 xTextRange = xTemp;
450 break;
451 case SC_HDFT_RIGHT:
453 uno::Reference<text::XTextRange> xTemp(
454 aTextData.GetContentObj().getRightText(), uno::UNO_QUERY);
455 xTextRange = xTemp;
457 break;
460 pHeaderField->InitDoc(xTextRange, new ScHeaderFooterEditSource(aTextData), aSelection);
462 // for bAbsorb=FALSE, the new selection must be behind the inserted content
463 // (the xml filter relies on this)
464 if (!bAbsorb)
465 aSelection.nStartPos = aSelection.nEndPos;
467 pTextRange->SetSelection( aSelection );
469 return;
473 if (!mxUnoText.is())
474 CreateUnoText_Impl();
475 mxUnoText->insertTextContent( xRange, xContent, bAbsorb );
478 void SAL_CALL ScHeaderFooterTextObj::removeTextContent(
479 const uno::Reference<text::XTextContent>& xContent )
480 throw(container::NoSuchElementException, uno::RuntimeException)
482 SolarMutexGuard aGuard;
483 if ( xContent.is() )
485 ScEditFieldObj* pHeaderField = ScEditFieldObj::getImplementation(xContent);
486 if ( pHeaderField && pHeaderField->IsInserted() )
488 //! Testen, ob das Feld in dieser Zelle ist
489 pHeaderField->DeleteField();
490 return;
493 if (!mxUnoText.is())
494 CreateUnoText_Impl();
495 mxUnoText->removeTextContent( xContent );
498 uno::Reference<text::XText> SAL_CALL ScHeaderFooterTextObj::getText() throw(uno::RuntimeException)
500 SolarMutexGuard aGuard;
501 if (!mxUnoText.is())
502 CreateUnoText_Impl();
503 return mxUnoText->getText();
506 uno::Reference<text::XTextRange> SAL_CALL ScHeaderFooterTextObj::getStart() throw(uno::RuntimeException)
508 SolarMutexGuard aGuard;
509 if (!mxUnoText.is())
510 CreateUnoText_Impl();
511 return mxUnoText->getStart();
514 uno::Reference<text::XTextRange> SAL_CALL ScHeaderFooterTextObj::getEnd() throw(uno::RuntimeException)
516 SolarMutexGuard aGuard;
517 if (!mxUnoText.is())
518 CreateUnoText_Impl();
519 return mxUnoText->getEnd();
522 // XTextFieldsSupplier
524 uno::Reference<container::XEnumerationAccess> SAL_CALL ScHeaderFooterTextObj::getTextFields()
525 throw(uno::RuntimeException)
527 SolarMutexGuard aGuard;
528 // all fields
529 return new ScHeaderFieldsObj(aTextData);
532 uno::Reference<container::XNameAccess> SAL_CALL ScHeaderFooterTextObj::getTextFieldMasters()
533 throw(uno::RuntimeException)
535 // sowas gibts nicht im Calc (?)
536 return NULL;
539 // XTextRangeMover
541 void SAL_CALL ScHeaderFooterTextObj::moveTextRange(
542 const uno::Reference<text::XTextRange>& xRange,
543 sal_Int16 nParagraphs )
544 throw(uno::RuntimeException)
546 SolarMutexGuard aGuard;
547 if (!mxUnoText.is())
548 CreateUnoText_Impl();
549 mxUnoText->moveTextRange( xRange, nParagraphs );
552 // XEnumerationAccess
554 uno::Reference<container::XEnumeration> SAL_CALL ScHeaderFooterTextObj::createEnumeration()
555 throw(uno::RuntimeException)
557 SolarMutexGuard aGuard;
558 if (!mxUnoText.is())
559 CreateUnoText_Impl();
560 return mxUnoText->createEnumeration();
563 // XElementAccess
565 uno::Type SAL_CALL ScHeaderFooterTextObj::getElementType() throw(uno::RuntimeException)
567 SolarMutexGuard aGuard;
568 if (!mxUnoText.is())
569 CreateUnoText_Impl();
570 return mxUnoText->getElementType();
573 sal_Bool SAL_CALL ScHeaderFooterTextObj::hasElements() throw(uno::RuntimeException)
575 SolarMutexGuard aGuard;
576 if (!mxUnoText.is())
577 CreateUnoText_Impl();
578 return mxUnoText->hasElements();
581 //------------------------------------------------------------------------
583 ScCellTextCursor::ScCellTextCursor(const ScCellTextCursor& rOther) :
584 SvxUnoTextCursor( rOther ),
585 rTextObj( rOther.rTextObj )
587 rTextObj.acquire();
590 ScCellTextCursor::ScCellTextCursor(ScCellObj& rText) :
591 SvxUnoTextCursor( rText.GetUnoText() ),
592 rTextObj( rText )
594 rTextObj.acquire();
597 ScCellTextCursor::~ScCellTextCursor() throw()
599 rTextObj.release();
602 // SvxUnoTextCursor methods reimplemented here to return the right objects:
604 uno::Reference<text::XText> SAL_CALL ScCellTextCursor::getText() throw(uno::RuntimeException)
606 SolarMutexGuard aGuard;
607 return &rTextObj;
610 uno::Reference<text::XTextRange> SAL_CALL ScCellTextCursor::getStart() throw(uno::RuntimeException)
612 SolarMutexGuard aGuard;
614 //! use other object for range than cursor?
616 ScCellTextCursor* pNew = new ScCellTextCursor( *this );
617 uno::Reference<text::XTextRange> xRange( static_cast<SvxUnoTextRangeBase*>(pNew) );
619 ESelection aNewSel(GetSelection());
620 aNewSel.nEndPara = aNewSel.nStartPara;
621 aNewSel.nEndPos = aNewSel.nStartPos;
622 pNew->SetSelection( aNewSel );
624 return xRange;
627 uno::Reference<text::XTextRange> SAL_CALL ScCellTextCursor::getEnd() throw(uno::RuntimeException)
629 SolarMutexGuard aGuard;
631 //! use other object for range than cursor?
633 ScCellTextCursor* pNew = new ScCellTextCursor( *this );
634 uno::Reference<text::XTextRange> xRange( static_cast<SvxUnoTextRangeBase*>(pNew) );
636 ESelection aNewSel(GetSelection());
637 aNewSel.nStartPara = aNewSel.nEndPara;
638 aNewSel.nStartPos = aNewSel.nEndPos;
639 pNew->SetSelection( aNewSel );
641 return xRange;
644 // XUnoTunnel
646 sal_Int64 SAL_CALL ScCellTextCursor::getSomething(
647 const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException)
649 if ( rId.getLength() == 16 &&
650 0 == memcmp( getUnoTunnelId().getConstArray(),
651 rId.getConstArray(), 16 ) )
653 return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
655 return SvxUnoTextCursor::getSomething( rId );
658 namespace
660 class theScCellTextCursorUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theScCellTextCursorUnoTunnelId> {};
663 const uno::Sequence<sal_Int8>& ScCellTextCursor::getUnoTunnelId()
665 return theScCellTextCursorUnoTunnelId::get().getSeq();
668 ScCellTextCursor* ScCellTextCursor::getImplementation( const uno::Reference<uno::XInterface> xObj )
670 ScCellTextCursor* pRet = NULL;
671 uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY );
672 if (xUT.is())
673 pRet = reinterpret_cast<ScCellTextCursor*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
674 return pRet;
677 //------------------------------------------------------------------------
679 ScHeaderFooterTextCursor::ScHeaderFooterTextCursor(const ScHeaderFooterTextCursor& rOther) :
680 SvxUnoTextCursor( rOther ),
681 rTextObj( rOther.rTextObj )
683 rTextObj.acquire();
686 ScHeaderFooterTextCursor::ScHeaderFooterTextCursor(ScHeaderFooterTextObj& rText) :
687 SvxUnoTextCursor( rText.GetUnoText() ),
688 rTextObj( rText )
690 rTextObj.acquire();
693 ScHeaderFooterTextCursor::~ScHeaderFooterTextCursor() throw()
695 rTextObj.release();
698 // SvxUnoTextCursor methods reimplemented here to return the right objects:
700 uno::Reference<text::XText> SAL_CALL ScHeaderFooterTextCursor::getText() throw(uno::RuntimeException)
702 SolarMutexGuard aGuard;
703 return &rTextObj;
706 uno::Reference<text::XTextRange> SAL_CALL ScHeaderFooterTextCursor::getStart() throw(uno::RuntimeException)
708 SolarMutexGuard aGuard;
710 //! use other object for range than cursor?
712 ScHeaderFooterTextCursor* pNew = new ScHeaderFooterTextCursor( *this );
713 uno::Reference<text::XTextRange> xRange( static_cast<SvxUnoTextRangeBase*>(pNew) );
715 ESelection aNewSel(GetSelection());
716 aNewSel.nEndPara = aNewSel.nStartPara;
717 aNewSel.nEndPos = aNewSel.nStartPos;
718 pNew->SetSelection( aNewSel );
720 return xRange;
723 uno::Reference<text::XTextRange> SAL_CALL ScHeaderFooterTextCursor::getEnd() throw(uno::RuntimeException)
725 SolarMutexGuard aGuard;
727 //! use other object for range than cursor?
729 ScHeaderFooterTextCursor* pNew = new ScHeaderFooterTextCursor( *this );
730 uno::Reference<text::XTextRange> xRange( static_cast<SvxUnoTextRangeBase*>(pNew) );
732 ESelection aNewSel(GetSelection());
733 aNewSel.nStartPara = aNewSel.nEndPara;
734 aNewSel.nStartPos = aNewSel.nEndPos;
735 pNew->SetSelection( aNewSel );
737 return xRange;
740 // XUnoTunnel
742 sal_Int64 SAL_CALL ScHeaderFooterTextCursor::getSomething(
743 const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException)
745 if ( rId.getLength() == 16 &&
746 0 == memcmp( getUnoTunnelId().getConstArray(),
747 rId.getConstArray(), 16 ) )
749 return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
751 return SvxUnoTextCursor::getSomething( rId );
754 namespace
756 class theScHeaderFooterTextCursorUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theScHeaderFooterTextCursorUnoTunnelId> {};
759 const uno::Sequence<sal_Int8>& ScHeaderFooterTextCursor::getUnoTunnelId()
761 return theScHeaderFooterTextCursorUnoTunnelId::get().getSeq();
764 ScHeaderFooterTextCursor* ScHeaderFooterTextCursor::getImplementation(
765 const uno::Reference<uno::XInterface> xObj )
767 ScHeaderFooterTextCursor* pRet = NULL;
768 uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY );
769 if (xUT.is())
770 pRet = reinterpret_cast<ScHeaderFooterTextCursor*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
771 return pRet;
774 //------------------------------------------------------------------------
776 ScDrawTextCursor::ScDrawTextCursor(const ScDrawTextCursor& rOther) :
777 SvxUnoTextCursor( rOther ),
778 xParentText( rOther.xParentText )
782 ScDrawTextCursor::ScDrawTextCursor( const uno::Reference<text::XText>& xParent,
783 const SvxUnoTextBase& rText ) :
784 SvxUnoTextCursor( rText ),
785 xParentText( xParent )
790 ScDrawTextCursor::~ScDrawTextCursor() throw()
794 // SvxUnoTextCursor methods reimplemented here to return the right objects:
796 uno::Reference<text::XText> SAL_CALL ScDrawTextCursor::getText() throw(uno::RuntimeException)
798 SolarMutexGuard aGuard;
799 return xParentText;
802 uno::Reference<text::XTextRange> SAL_CALL ScDrawTextCursor::getStart() throw(uno::RuntimeException)
804 SolarMutexGuard aGuard;
806 //! use other object for range than cursor?
808 ScDrawTextCursor* pNew = new ScDrawTextCursor( *this );
809 uno::Reference<text::XTextRange> xRange( static_cast<SvxUnoTextRangeBase*>(pNew) );
811 ESelection aNewSel(GetSelection());
812 aNewSel.nEndPara = aNewSel.nStartPara;
813 aNewSel.nEndPos = aNewSel.nStartPos;
814 pNew->SetSelection( aNewSel );
816 return xRange;
819 uno::Reference<text::XTextRange> SAL_CALL ScDrawTextCursor::getEnd() throw(uno::RuntimeException)
821 SolarMutexGuard aGuard;
823 //! use other object for range than cursor?
825 ScDrawTextCursor* pNew = new ScDrawTextCursor( *this );
826 uno::Reference<text::XTextRange> xRange( static_cast<SvxUnoTextRangeBase*>(pNew) );
828 ESelection aNewSel(GetSelection());
829 aNewSel.nStartPara = aNewSel.nEndPara;
830 aNewSel.nStartPos = aNewSel.nEndPos;
831 pNew->SetSelection( aNewSel );
833 return xRange;
836 // XUnoTunnel
838 sal_Int64 SAL_CALL ScDrawTextCursor::getSomething(
839 const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException)
841 if ( rId.getLength() == 16 &&
842 0 == memcmp( getUnoTunnelId().getConstArray(),
843 rId.getConstArray(), 16 ) )
845 return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
847 return SvxUnoTextCursor::getSomething( rId );
850 namespace
852 class theScDrawTextCursorUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theScDrawTextCursorUnoTunnelId> {};
855 const uno::Sequence<sal_Int8>& ScDrawTextCursor::getUnoTunnelId()
857 return theScDrawTextCursorUnoTunnelId::get().getSeq();
860 ScDrawTextCursor* ScDrawTextCursor::getImplementation( const uno::Reference<uno::XInterface> xObj )
862 ScDrawTextCursor* pRet = NULL;
863 uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY );
864 if (xUT.is())
865 pRet = reinterpret_cast<ScDrawTextCursor*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
866 return pRet;
869 //------------------------------------------------------------------------
871 ScSimpleEditSourceHelper::ScSimpleEditSourceHelper()
873 SfxItemPool* pEnginePool = EditEngine::CreatePool();
874 pEnginePool->SetDefaultMetric( SFX_MAPUNIT_100TH_MM );
875 pEnginePool->FreezeIdRanges();
877 pEditEngine = new ScFieldEditEngine(NULL, pEnginePool, NULL, true); // TRUE: become owner of pool
878 pForwarder = new SvxEditEngineForwarder( *pEditEngine );
879 pOriginalSource = new ScSimpleEditSource( pForwarder );
882 ScSimpleEditSourceHelper::~ScSimpleEditSourceHelper()
884 SolarMutexGuard aGuard; // needed for EditEngine dtor
886 delete pOriginalSource;
887 delete pForwarder;
888 delete pEditEngine;
891 ScEditEngineTextObj::ScEditEngineTextObj() :
892 SvxUnoText( GetOriginalSource(), ScCellObj::GetEditPropertySet(), uno::Reference<text::XText>() )
896 ScEditEngineTextObj::~ScEditEngineTextObj() throw()
900 void ScEditEngineTextObj::SetText( const EditTextObject& rTextObject )
902 GetEditEngine()->SetText( rTextObject );
904 ESelection aSel;
905 ::GetSelection( aSel, GetEditSource()->GetTextForwarder() );
906 SetSelection( aSel );
909 EditTextObject* ScEditEngineTextObj::CreateTextObject()
911 return GetEditEngine()->CreateTextObject();
914 //------------------------------------------------------------------------
916 ScCellTextData::ScCellTextData(ScDocShell* pDocSh, const ScAddress& rP) :
917 pDocShell( pDocSh ),
918 aCellPos( rP ),
919 pEditEngine( NULL ),
920 pForwarder( NULL ),
921 pOriginalSource( NULL ),
922 bDataValid( false ),
923 bInUpdate( false ),
924 bDirty( false ),
925 bDoUpdate( sal_True )
927 if (pDocShell)
928 pDocShell->GetDocument()->AddUnoObject(*this);
931 ScCellTextData::~ScCellTextData()
933 SolarMutexGuard aGuard; // needed for EditEngine dtor
935 if (pDocShell)
937 pDocShell->GetDocument()->RemoveUnoObject(*this);
938 pDocShell->GetDocument()->DisposeFieldEditEngine(pEditEngine);
940 else
941 delete pEditEngine;
943 delete pForwarder;
945 delete pOriginalSource;
948 ScCellEditSource* ScCellTextData::GetOriginalSource()
950 if (!pOriginalSource)
951 pOriginalSource = new ScCellEditSource(pDocShell, aCellPos);
952 return pOriginalSource;
955 void ScCellTextData::GetCellText(const ScAddress& rCellPos, OUString& rText)
957 if (pDocShell)
959 ScDocument* pDoc = pDocShell->GetDocument();
960 pDoc->GetInputString( rCellPos.Col(), rCellPos.Row(), rCellPos.Tab(), rText );
964 SvxTextForwarder* ScCellTextData::GetTextForwarder()
966 if (!pEditEngine)
968 if ( pDocShell )
970 ScDocument* pDoc = pDocShell->GetDocument();
971 pEditEngine = pDoc->CreateFieldEditEngine();
973 else
975 SfxItemPool* pEnginePool = EditEngine::CreatePool();
976 pEnginePool->FreezeIdRanges();
977 pEditEngine = new ScFieldEditEngine(NULL, pEnginePool, NULL, true);
979 // currently, GetPortions doesn't work if UpdateMode is sal_False,
980 // this will be fixed (in EditEngine) by src600
981 // pEditEngine->SetUpdateMode( sal_False );
982 pEditEngine->EnableUndo( false );
983 if (pDocShell)
984 pEditEngine->SetRefDevice(pDocShell->GetRefDevice());
985 else
986 pEditEngine->SetRefMapMode( MAP_100TH_MM );
987 pForwarder = new SvxEditEngineForwarder(*pEditEngine);
990 if (bDataValid)
991 return pForwarder;
993 OUString aText;
995 if (pDocShell)
997 ScDocument* pDoc = pDocShell->GetDocument();
999 SfxItemSet aDefaults( pEditEngine->GetEmptyItemSet() );
1000 if( const ScPatternAttr* pPattern =
1001 pDoc->GetPattern( aCellPos.Col(), aCellPos.Row(), aCellPos.Tab() ) )
1003 pPattern->FillEditItemSet( &aDefaults );
1004 pPattern->FillEditParaItems( &aDefaults ); // including alignment etc. (for reading)
1007 if (pDoc->GetCellType(aCellPos) == CELLTYPE_EDIT)
1009 const EditTextObject* pObj = pDoc->GetEditText(aCellPos);
1010 if (pObj)
1011 pEditEngine->SetTextNewDefaults(*pObj, aDefaults);
1013 else
1015 GetCellText(aCellPos, aText);
1016 if (!aText.isEmpty())
1017 pEditEngine->SetTextNewDefaults(aText, aDefaults);
1018 else
1019 pEditEngine->SetDefaults(aDefaults);
1023 bDataValid = true;
1024 return pForwarder;
1027 void ScCellTextData::UpdateData()
1029 if ( bDoUpdate )
1031 OSL_ENSURE(pEditEngine != NULL, "no EditEngine for UpdateData()");
1032 if ( pDocShell && pEditEngine )
1034 // during the own UpdateData call, bDataValid must not be reset,
1035 // or things like attributes after the text would be lost
1036 // (are not stored in the cell)
1037 bInUpdate = sal_True; // prevents bDataValid from being reset
1038 pDocShell->GetDocFunc().PutData(aCellPos, *pEditEngine, true); // always as text
1040 bInUpdate = false;
1041 bDirty = false;
1044 else
1045 bDirty = sal_True;
1048 void ScCellTextData::Notify( SfxBroadcaster&, const SfxHint& rHint )
1050 if ( rHint.ISA( ScUpdateRefHint ) )
1052 // const ScUpdateRefHint& rRef = (const ScUpdateRefHint&)rHint;
1054 //! Ref-Update
1056 else if ( rHint.ISA( SfxSimpleHint ) )
1058 sal_uLong nId = ((const SfxSimpleHint&)rHint).GetId();
1059 if ( nId == SFX_HINT_DYING )
1061 pDocShell = NULL; // invalid now
1063 DELETEZ( pForwarder );
1064 DELETEZ( pEditEngine ); // EditEngine uses document's pool
1066 else if ( nId == SFX_HINT_DATACHANGED )
1068 if (!bInUpdate) // not for own UpdateData calls
1069 bDataValid = false; // text has to be read from the cell again
1074 ScCellTextObj::ScCellTextObj(ScDocShell* pDocSh, const ScAddress& rP) :
1075 ScCellTextData( pDocSh, rP ),
1076 SvxUnoText( GetOriginalSource(), ScCellObj::GetEditPropertySet(), uno::Reference<text::XText>() )
1080 ScCellTextObj::~ScCellTextObj() throw()
1084 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */