Bump version to 4.3-4
[LibreOffice.git] / sc / source / ui / unoobj / textuno.cxx
blob3211f4508e34e31c417a7afd27b0c8bf3963b233
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 static const SvxItemPropertySet * lcl_GetHdFtPropertySet()
54 static SfxItemPropertyMapEntry aHdFtPropertyMap_Impl[] =
56 SVX_UNOEDIT_CHAR_PROPERTIES,
57 SVX_UNOEDIT_FONT_PROPERTIES,
58 SVX_UNOEDIT_PARA_PROPERTIES,
59 SVX_UNOEDIT_NUMBERING_PROPERTIE, // for completeness of service ParagraphProperties
60 { OUString(), 0, css::uno::Type(), 0, 0 }
62 static bool bTwipsSet = false;
64 if (!bTwipsSet)
66 // modify PropertyMap to include CONVERT_TWIPS flag for font height
67 // (headers/footers are in twips)
69 SfxItemPropertyMapEntry* pEntry = aHdFtPropertyMap_Impl;
70 while (!pEntry->aName.isEmpty())
72 if ( ( pEntry->nWID == EE_CHAR_FONTHEIGHT ||
73 pEntry->nWID == EE_CHAR_FONTHEIGHT_CJK ||
74 pEntry->nWID == EE_CHAR_FONTHEIGHT_CTL ) &&
75 pEntry->nMemberId == MID_FONTHEIGHT )
77 pEntry->nMemberId |= CONVERT_TWIPS;
80 ++pEntry;
82 bTwipsSet = true;
84 static SvxItemPropertySet aHdFtPropertySet_Impl( aHdFtPropertyMap_Impl, SdrObject::GetGlobalDrawObjectItemPool() );
85 return &aHdFtPropertySet_Impl;
88 SC_SIMPLE_SERVICE_INFO( ScHeaderFooterContentObj, "ScHeaderFooterContentObj", "com.sun.star.sheet.HeaderFooterContent" )
89 SC_SIMPLE_SERVICE_INFO( ScHeaderFooterTextObj, "ScHeaderFooterTextObj", "stardiv.one.Text.Text" )
91 ScHeaderFooterContentObj::ScHeaderFooterContentObj( const EditTextObject* pLeft,
92 const EditTextObject* pCenter,
93 const EditTextObject* pRight ) :
94 mxLeftText(new ScHeaderFooterTextObj(*this, SC_HDFT_LEFT, pLeft)),
95 mxCenterText(new ScHeaderFooterTextObj(*this, SC_HDFT_CENTER, pCenter)),
96 mxRightText(new ScHeaderFooterTextObj(*this, SC_HDFT_RIGHT, pRight))
100 ScHeaderFooterContentObj::~ScHeaderFooterContentObj() {}
102 const EditTextObject* ScHeaderFooterContentObj::GetLeftEditObject() const
104 return mxLeftText->GetTextObject();
107 const EditTextObject* ScHeaderFooterContentObj::GetCenterEditObject() const
109 return mxCenterText->GetTextObject();
112 const EditTextObject* ScHeaderFooterContentObj::GetRightEditObject() const
114 return mxRightText->GetTextObject();
117 // XHeaderFooterContent
119 uno::Reference<text::XText> SAL_CALL ScHeaderFooterContentObj::getLeftText()
120 throw(uno::RuntimeException, std::exception)
122 SolarMutexGuard aGuard;
123 uno::Reference<text::XText> xInt(*mxLeftText, uno::UNO_QUERY);
124 return xInt;
127 uno::Reference<text::XText> SAL_CALL ScHeaderFooterContentObj::getCenterText()
128 throw(uno::RuntimeException, std::exception)
130 SolarMutexGuard aGuard;
131 uno::Reference<text::XText> xInt(*mxCenterText, uno::UNO_QUERY);
132 return xInt;
135 uno::Reference<text::XText> SAL_CALL ScHeaderFooterContentObj::getRightText()
136 throw(uno::RuntimeException, std::exception)
138 SolarMutexGuard aGuard;
139 uno::Reference<text::XText> xInt(*mxRightText, uno::UNO_QUERY);
140 return xInt;
143 // XUnoTunnel
145 sal_Int64 SAL_CALL ScHeaderFooterContentObj::getSomething(
146 const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException, std::exception)
148 if ( rId.getLength() == 16 &&
149 0 == memcmp( getUnoTunnelId().getConstArray(),
150 rId.getConstArray(), 16 ) )
152 return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
154 return 0;
157 namespace
159 class theScHeaderFooterContentObjUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theScHeaderFooterContentObjUnoTunnelId> {};
162 const uno::Sequence<sal_Int8>& ScHeaderFooterContentObj::getUnoTunnelId()
164 return theScHeaderFooterContentObjUnoTunnelId::get().getSeq();
167 ScHeaderFooterContentObj* ScHeaderFooterContentObj::getImplementation(
168 const uno::Reference<sheet::XHeaderFooterContent> xObj )
170 ScHeaderFooterContentObj* pRet = NULL;
171 uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY );
172 if (xUT.is())
173 pRet = reinterpret_cast<ScHeaderFooterContentObj*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
174 return pRet;
178 ScHeaderFooterTextData::ScHeaderFooterTextData(
179 ScHeaderFooterContentObj& rContent, sal_uInt16 nP, const EditTextObject* pTextObj) :
180 mpTextObj(pTextObj ? pTextObj->Clone() : NULL),
181 rContentObj( rContent ),
182 nPart( nP ),
183 pEditEngine( NULL ),
184 pForwarder( NULL ),
185 bDataValid(false)
189 ScHeaderFooterTextData::~ScHeaderFooterTextData()
191 SolarMutexGuard aGuard; // needed for EditEngine dtor
193 delete pForwarder;
194 delete pEditEngine;
195 delete mpTextObj;
198 SvxTextForwarder* ScHeaderFooterTextData::GetTextForwarder()
200 if (!pEditEngine)
202 SfxItemPool* pEnginePool = EditEngine::CreatePool();
203 pEnginePool->FreezeIdRanges();
204 ScHeaderEditEngine* pHdrEngine = new ScHeaderEditEngine( pEnginePool, true );
206 pHdrEngine->EnableUndo( false );
207 pHdrEngine->SetRefMapMode( MAP_TWIP );
209 // default font must be set, independently of document
210 // -> use global pool from module
212 SfxItemSet aDefaults( pHdrEngine->GetEmptyItemSet() );
213 const ScPatternAttr& rPattern = (const ScPatternAttr&)SC_MOD()->GetPool().GetDefaultItem(ATTR_PATTERN);
214 rPattern.FillEditItemSet( &aDefaults );
215 // FillEditItemSet adjusts font height to 1/100th mm,
216 // but for header/footer twips is needed, as in the PatternAttr:
217 aDefaults.Put( rPattern.GetItem(ATTR_FONT_HEIGHT), EE_CHAR_FONTHEIGHT );
218 aDefaults.Put( rPattern.GetItem(ATTR_CJK_FONT_HEIGHT), EE_CHAR_FONTHEIGHT_CJK );
219 aDefaults.Put( rPattern.GetItem(ATTR_CTL_FONT_HEIGHT), EE_CHAR_FONTHEIGHT_CTL );
220 pHdrEngine->SetDefaults( aDefaults );
222 ScHeaderFieldData aData;
223 ScHeaderFooterTextObj::FillDummyFieldData( aData );
224 pHdrEngine->SetData( aData );
226 pEditEngine = pHdrEngine;
227 pForwarder = new SvxEditEngineForwarder(*pEditEngine);
230 if (bDataValid)
231 return pForwarder;
233 if (mpTextObj)
234 pEditEngine->SetText(*mpTextObj);
236 bDataValid = true;
237 return pForwarder;
240 void ScHeaderFooterTextData::UpdateData()
242 if (pEditEngine)
244 delete mpTextObj;
245 mpTextObj = pEditEngine->CreateTextObject();
249 void ScHeaderFooterTextData::UpdateData(EditEngine& rEditEngine)
251 delete mpTextObj;
252 mpTextObj = rEditEngine.CreateTextObject();
253 bDataValid = false;
256 const EditTextObject* ScHeaderFooterTextData::GetTextObject() const
258 return mpTextObj;
261 ScHeaderFooterTextObj::ScHeaderFooterTextObj(
262 ScHeaderFooterContentObj& rContent, sal_uInt16 nP, const EditTextObject* pTextObj) :
263 aTextData(rContent, nP, pTextObj)
265 // ScHeaderFooterTextData acquires rContent
266 // pUnoText is created on demand (getString/setString work without it)
269 void ScHeaderFooterTextObj::CreateUnoText_Impl()
271 if (!mxUnoText.is())
273 // can't be aggregated because getString/setString is handled here
274 ScHeaderFooterEditSource aEditSrc(aTextData);
275 mxUnoText.set(new SvxUnoText(&aEditSrc, lcl_GetHdFtPropertySet(), uno::Reference<text::XText>()));
279 ScHeaderFooterTextObj::~ScHeaderFooterTextObj() {}
281 const EditTextObject* ScHeaderFooterTextObj::GetTextObject() const
283 return aTextData.GetTextObject();
286 const SvxUnoText& ScHeaderFooterTextObj::GetUnoText()
288 if (!mxUnoText.is())
289 CreateUnoText_Impl();
290 return *mxUnoText;
293 // XText
295 uno::Reference<text::XTextCursor> SAL_CALL ScHeaderFooterTextObj::createTextCursor()
296 throw(uno::RuntimeException, std::exception)
298 SolarMutexGuard aGuard;
299 return new ScHeaderFooterTextCursor( *this );
302 uno::Reference<text::XTextCursor> SAL_CALL ScHeaderFooterTextObj::createTextCursorByRange(
303 const uno::Reference<text::XTextRange>& aTextPosition )
304 throw(uno::RuntimeException, std::exception)
306 SolarMutexGuard aGuard;
307 if (!mxUnoText.is())
308 CreateUnoText_Impl();
309 return mxUnoText->createTextCursorByRange(aTextPosition);
310 //! wie ScCellObj::createTextCursorByRange, wenn SvxUnoTextRange_getReflection verfuegbar
313 void ScHeaderFooterTextObj::FillDummyFieldData( ScHeaderFieldData& rData )
315 OUString aDummy("???");
316 rData.aTitle = aDummy;
317 rData.aLongDocName = aDummy;
318 rData.aShortDocName = aDummy;
319 rData.aTabName = aDummy;
320 rData.nPageNo = 1;
321 rData.nTotalPages = 99;
324 OUString SAL_CALL ScHeaderFooterTextObj::getString() throw(uno::RuntimeException, std::exception)
326 SolarMutexGuard aGuard;
327 OUString aRet;
328 const EditTextObject* pData;
330 sal_uInt16 nPart = aTextData.GetPart();
331 ScHeaderFooterContentObj& rContentObj = aTextData.GetContentObj();
333 if (nPart == SC_HDFT_LEFT)
334 pData = rContentObj.GetLeftEditObject();
335 else if (nPart == SC_HDFT_CENTER)
336 pData = rContentObj.GetCenterEditObject();
337 else
338 pData = rContentObj.GetRightEditObject();
339 if (pData)
341 // for pure text, no font info is needed in pool defaults
342 ScHeaderEditEngine aEditEngine( EditEngine::CreatePool(), true );
344 ScHeaderFieldData aData;
345 FillDummyFieldData( aData );
346 aEditEngine.SetData( aData );
348 aEditEngine.SetText(*pData);
349 aRet = ScEditUtil::GetSpaceDelimitedString( aEditEngine );
351 return aRet;
354 void SAL_CALL ScHeaderFooterTextObj::setString( const OUString& aText ) throw(uno::RuntimeException, std::exception)
356 SolarMutexGuard aGuard;
357 OUString aString(aText);
359 // for pure text, no font info is needed in pool defaults
360 ScHeaderEditEngine aEditEngine(EditEngine::CreatePool(), true);
361 aEditEngine.SetText( aString );
362 aTextData.UpdateData(aEditEngine);
365 void SAL_CALL ScHeaderFooterTextObj::insertString( const uno::Reference<text::XTextRange>& xRange,
366 const OUString& aString, sal_Bool bAbsorb )
367 throw(uno::RuntimeException, std::exception)
369 SolarMutexGuard aGuard;
370 if (!mxUnoText.is())
371 CreateUnoText_Impl();
372 mxUnoText->insertString( xRange, aString, bAbsorb );
375 void SAL_CALL ScHeaderFooterTextObj::insertControlCharacter(
376 const uno::Reference<text::XTextRange>& xRange,
377 sal_Int16 nControlCharacter, sal_Bool bAbsorb )
378 throw(lang::IllegalArgumentException, uno::RuntimeException, std::exception)
380 SolarMutexGuard aGuard;
381 if (!mxUnoText.is())
382 CreateUnoText_Impl();
383 mxUnoText->insertControlCharacter( xRange, nControlCharacter, bAbsorb );
386 void SAL_CALL ScHeaderFooterTextObj::insertTextContent(
387 const uno::Reference<text::XTextRange >& xRange,
388 const uno::Reference<text::XTextContent >& xContent,
389 sal_Bool bAbsorb )
390 throw(lang::IllegalArgumentException, uno::RuntimeException, std::exception)
392 SolarMutexGuard aGuard;
393 if ( xContent.is() && xRange.is() )
395 ScEditFieldObj* pHeaderField = ScEditFieldObj::getImplementation( xContent );
397 SvxUnoTextRangeBase* pTextRange =
398 ScHeaderFooterTextCursor::getImplementation( xRange );
400 if ( pHeaderField && !pHeaderField->IsInserted() && pTextRange )
402 SvxEditSource* pEditSource = pTextRange->GetEditSource();
403 ESelection aSelection(pTextRange->GetSelection());
405 if (!bAbsorb)
407 // don't replace -> append at end
408 aSelection.Adjust();
409 aSelection.nStartPara = aSelection.nEndPara;
410 aSelection.nStartPos = aSelection.nEndPos;
413 SvxFieldItem aItem(pHeaderField->CreateFieldItem());
415 SvxTextForwarder* pForwarder = pEditSource->GetTextForwarder();
416 pForwarder->QuickInsertField( aItem, aSelection );
417 pEditSource->UpdateData();
419 // neue Selektion: ein Zeichen
420 aSelection.Adjust();
421 aSelection.nEndPara = aSelection.nStartPara;
422 aSelection.nEndPos = aSelection.nStartPos + 1;
424 uno::Reference<text::XTextRange> xTextRange;
425 switch (aTextData.GetPart())
427 case SC_HDFT_LEFT:
429 uno::Reference<text::XTextRange> xTemp(
430 aTextData.GetContentObj().getLeftText(), uno::UNO_QUERY);
431 xTextRange = xTemp;
433 break;
434 case SC_HDFT_CENTER:
436 uno::Reference<text::XTextRange> xTemp(
437 aTextData.GetContentObj().getCenterText(), uno::UNO_QUERY);
438 xTextRange = xTemp;
440 break;
441 case SC_HDFT_RIGHT:
443 uno::Reference<text::XTextRange> xTemp(
444 aTextData.GetContentObj().getRightText(), uno::UNO_QUERY);
445 xTextRange = xTemp;
447 break;
450 pHeaderField->InitDoc(xTextRange, new ScHeaderFooterEditSource(aTextData), aSelection);
452 // for bAbsorb=FALSE, the new selection must be behind the inserted content
453 // (the xml filter relies on this)
454 if (!bAbsorb)
455 aSelection.nStartPos = aSelection.nEndPos;
457 pTextRange->SetSelection( aSelection );
459 return;
463 if (!mxUnoText.is())
464 CreateUnoText_Impl();
465 mxUnoText->insertTextContent( xRange, xContent, bAbsorb );
468 void SAL_CALL ScHeaderFooterTextObj::removeTextContent(
469 const uno::Reference<text::XTextContent>& xContent )
470 throw(container::NoSuchElementException, uno::RuntimeException, std::exception)
472 SolarMutexGuard aGuard;
473 if ( xContent.is() )
475 ScEditFieldObj* pHeaderField = ScEditFieldObj::getImplementation(xContent);
476 if ( pHeaderField && pHeaderField->IsInserted() )
478 //! Testen, ob das Feld in dieser Zelle ist
479 pHeaderField->DeleteField();
480 return;
483 if (!mxUnoText.is())
484 CreateUnoText_Impl();
485 mxUnoText->removeTextContent( xContent );
488 uno::Reference<text::XText> SAL_CALL ScHeaderFooterTextObj::getText() throw(uno::RuntimeException, std::exception)
490 SolarMutexGuard aGuard;
491 if (!mxUnoText.is())
492 CreateUnoText_Impl();
493 return mxUnoText->getText();
496 uno::Reference<text::XTextRange> SAL_CALL ScHeaderFooterTextObj::getStart() throw(uno::RuntimeException, std::exception)
498 SolarMutexGuard aGuard;
499 if (!mxUnoText.is())
500 CreateUnoText_Impl();
501 return mxUnoText->getStart();
504 uno::Reference<text::XTextRange> SAL_CALL ScHeaderFooterTextObj::getEnd() throw(uno::RuntimeException, std::exception)
506 SolarMutexGuard aGuard;
507 if (!mxUnoText.is())
508 CreateUnoText_Impl();
509 return mxUnoText->getEnd();
512 // XTextFieldsSupplier
514 uno::Reference<container::XEnumerationAccess> SAL_CALL ScHeaderFooterTextObj::getTextFields()
515 throw(uno::RuntimeException, std::exception)
517 SolarMutexGuard aGuard;
518 // all fields
519 return new ScHeaderFieldsObj(aTextData);
522 uno::Reference<container::XNameAccess> SAL_CALL ScHeaderFooterTextObj::getTextFieldMasters()
523 throw(uno::RuntimeException, std::exception)
525 // sowas gibts nicht im Calc (?)
526 return NULL;
529 // XTextRangeMover
531 void SAL_CALL ScHeaderFooterTextObj::moveTextRange(
532 const uno::Reference<text::XTextRange>& xRange,
533 sal_Int16 nParagraphs )
534 throw(uno::RuntimeException, std::exception)
536 SolarMutexGuard aGuard;
537 if (!mxUnoText.is())
538 CreateUnoText_Impl();
539 mxUnoText->moveTextRange( xRange, nParagraphs );
542 // XEnumerationAccess
544 uno::Reference<container::XEnumeration> SAL_CALL ScHeaderFooterTextObj::createEnumeration()
545 throw(uno::RuntimeException, std::exception)
547 SolarMutexGuard aGuard;
548 if (!mxUnoText.is())
549 CreateUnoText_Impl();
550 return mxUnoText->createEnumeration();
553 // XElementAccess
555 uno::Type SAL_CALL ScHeaderFooterTextObj::getElementType() throw(uno::RuntimeException, std::exception)
557 SolarMutexGuard aGuard;
558 if (!mxUnoText.is())
559 CreateUnoText_Impl();
560 return mxUnoText->getElementType();
563 sal_Bool SAL_CALL ScHeaderFooterTextObj::hasElements() throw(uno::RuntimeException, std::exception)
565 SolarMutexGuard aGuard;
566 if (!mxUnoText.is())
567 CreateUnoText_Impl();
568 return mxUnoText->hasElements();
571 ScCellTextCursor::ScCellTextCursor(const ScCellTextCursor& rOther) :
572 SvxUnoTextCursor( rOther ),
573 rTextObj( rOther.rTextObj )
575 rTextObj.acquire();
578 ScCellTextCursor::ScCellTextCursor(ScCellObj& rText) :
579 SvxUnoTextCursor( rText.GetUnoText() ),
580 rTextObj( rText )
582 rTextObj.acquire();
585 ScCellTextCursor::~ScCellTextCursor() throw()
587 rTextObj.release();
590 // SvxUnoTextCursor methods reimplemented here to return the right objects:
592 uno::Reference<text::XText> SAL_CALL ScCellTextCursor::getText() throw(uno::RuntimeException, std::exception)
594 SolarMutexGuard aGuard;
595 return &rTextObj;
598 uno::Reference<text::XTextRange> SAL_CALL ScCellTextCursor::getStart() throw(uno::RuntimeException, std::exception)
600 SolarMutexGuard aGuard;
602 //! use other object for range than cursor?
604 ScCellTextCursor* pNew = new ScCellTextCursor( *this );
605 uno::Reference<text::XTextRange> xRange( static_cast<SvxUnoTextRangeBase*>(pNew) );
607 ESelection aNewSel(GetSelection());
608 aNewSel.nEndPara = aNewSel.nStartPara;
609 aNewSel.nEndPos = aNewSel.nStartPos;
610 pNew->SetSelection( aNewSel );
612 return xRange;
615 uno::Reference<text::XTextRange> SAL_CALL ScCellTextCursor::getEnd() throw(uno::RuntimeException, std::exception)
617 SolarMutexGuard aGuard;
619 //! use other object for range than cursor?
621 ScCellTextCursor* pNew = new ScCellTextCursor( *this );
622 uno::Reference<text::XTextRange> xRange( static_cast<SvxUnoTextRangeBase*>(pNew) );
624 ESelection aNewSel(GetSelection());
625 aNewSel.nStartPara = aNewSel.nEndPara;
626 aNewSel.nStartPos = aNewSel.nEndPos;
627 pNew->SetSelection( aNewSel );
629 return xRange;
632 // XUnoTunnel
634 sal_Int64 SAL_CALL ScCellTextCursor::getSomething(
635 const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException, std::exception)
637 if ( rId.getLength() == 16 &&
638 0 == memcmp( getUnoTunnelId().getConstArray(),
639 rId.getConstArray(), 16 ) )
641 return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
643 return SvxUnoTextCursor::getSomething( rId );
646 namespace
648 class theScCellTextCursorUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theScCellTextCursorUnoTunnelId> {};
651 const uno::Sequence<sal_Int8>& ScCellTextCursor::getUnoTunnelId()
653 return theScCellTextCursorUnoTunnelId::get().getSeq();
656 ScCellTextCursor* ScCellTextCursor::getImplementation( const uno::Reference<uno::XInterface> xObj )
658 ScCellTextCursor* pRet = NULL;
659 uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY );
660 if (xUT.is())
661 pRet = reinterpret_cast<ScCellTextCursor*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
662 return pRet;
665 ScHeaderFooterTextCursor::ScHeaderFooterTextCursor(const ScHeaderFooterTextCursor& rOther) :
666 SvxUnoTextCursor( rOther ),
667 rTextObj( rOther.rTextObj )
669 rTextObj.acquire();
672 ScHeaderFooterTextCursor::ScHeaderFooterTextCursor(ScHeaderFooterTextObj& rText) :
673 SvxUnoTextCursor( rText.GetUnoText() ),
674 rTextObj( rText )
676 rTextObj.acquire();
679 ScHeaderFooterTextCursor::~ScHeaderFooterTextCursor() throw()
681 rTextObj.release();
684 // SvxUnoTextCursor methods reimplemented here to return the right objects:
686 uno::Reference<text::XText> SAL_CALL ScHeaderFooterTextCursor::getText() throw(uno::RuntimeException, std::exception)
688 SolarMutexGuard aGuard;
689 return &rTextObj;
692 uno::Reference<text::XTextRange> SAL_CALL ScHeaderFooterTextCursor::getStart() throw(uno::RuntimeException, std::exception)
694 SolarMutexGuard aGuard;
696 //! use other object for range than cursor?
698 ScHeaderFooterTextCursor* pNew = new ScHeaderFooterTextCursor( *this );
699 uno::Reference<text::XTextRange> xRange( static_cast<SvxUnoTextRangeBase*>(pNew) );
701 ESelection aNewSel(GetSelection());
702 aNewSel.nEndPara = aNewSel.nStartPara;
703 aNewSel.nEndPos = aNewSel.nStartPos;
704 pNew->SetSelection( aNewSel );
706 return xRange;
709 uno::Reference<text::XTextRange> SAL_CALL ScHeaderFooterTextCursor::getEnd() throw(uno::RuntimeException, std::exception)
711 SolarMutexGuard aGuard;
713 //! use other object for range than cursor?
715 ScHeaderFooterTextCursor* pNew = new ScHeaderFooterTextCursor( *this );
716 uno::Reference<text::XTextRange> xRange( static_cast<SvxUnoTextRangeBase*>(pNew) );
718 ESelection aNewSel(GetSelection());
719 aNewSel.nStartPara = aNewSel.nEndPara;
720 aNewSel.nStartPos = aNewSel.nEndPos;
721 pNew->SetSelection( aNewSel );
723 return xRange;
726 // XUnoTunnel
728 sal_Int64 SAL_CALL ScHeaderFooterTextCursor::getSomething(
729 const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException, std::exception)
731 if ( rId.getLength() == 16 &&
732 0 == memcmp( getUnoTunnelId().getConstArray(),
733 rId.getConstArray(), 16 ) )
735 return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
737 return SvxUnoTextCursor::getSomething( rId );
740 namespace
742 class theScHeaderFooterTextCursorUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theScHeaderFooterTextCursorUnoTunnelId> {};
745 const uno::Sequence<sal_Int8>& ScHeaderFooterTextCursor::getUnoTunnelId()
747 return theScHeaderFooterTextCursorUnoTunnelId::get().getSeq();
750 ScHeaderFooterTextCursor* ScHeaderFooterTextCursor::getImplementation(
751 const uno::Reference<uno::XInterface> xObj )
753 ScHeaderFooterTextCursor* pRet = NULL;
754 uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY );
755 if (xUT.is())
756 pRet = reinterpret_cast<ScHeaderFooterTextCursor*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
757 return pRet;
760 ScDrawTextCursor::ScDrawTextCursor(const ScDrawTextCursor& rOther) :
761 SvxUnoTextCursor( rOther ),
762 xParentText( rOther.xParentText )
766 ScDrawTextCursor::ScDrawTextCursor( const uno::Reference<text::XText>& xParent,
767 const SvxUnoTextBase& rText ) :
768 SvxUnoTextCursor( rText ),
769 xParentText( xParent )
774 ScDrawTextCursor::~ScDrawTextCursor() throw()
778 // SvxUnoTextCursor methods reimplemented here to return the right objects:
780 uno::Reference<text::XText> SAL_CALL ScDrawTextCursor::getText() throw(uno::RuntimeException, std::exception)
782 SolarMutexGuard aGuard;
783 return xParentText;
786 uno::Reference<text::XTextRange> SAL_CALL ScDrawTextCursor::getStart() throw(uno::RuntimeException, std::exception)
788 SolarMutexGuard aGuard;
790 //! use other object for range than cursor?
792 ScDrawTextCursor* pNew = new ScDrawTextCursor( *this );
793 uno::Reference<text::XTextRange> xRange( static_cast<SvxUnoTextRangeBase*>(pNew) );
795 ESelection aNewSel(GetSelection());
796 aNewSel.nEndPara = aNewSel.nStartPara;
797 aNewSel.nEndPos = aNewSel.nStartPos;
798 pNew->SetSelection( aNewSel );
800 return xRange;
803 uno::Reference<text::XTextRange> SAL_CALL ScDrawTextCursor::getEnd() throw(uno::RuntimeException, std::exception)
805 SolarMutexGuard aGuard;
807 //! use other object for range than cursor?
809 ScDrawTextCursor* pNew = new ScDrawTextCursor( *this );
810 uno::Reference<text::XTextRange> xRange( static_cast<SvxUnoTextRangeBase*>(pNew) );
812 ESelection aNewSel(GetSelection());
813 aNewSel.nStartPara = aNewSel.nEndPara;
814 aNewSel.nStartPos = aNewSel.nEndPos;
815 pNew->SetSelection( aNewSel );
817 return xRange;
820 // XUnoTunnel
822 sal_Int64 SAL_CALL ScDrawTextCursor::getSomething(
823 const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException, std::exception)
825 if ( rId.getLength() == 16 &&
826 0 == memcmp( getUnoTunnelId().getConstArray(),
827 rId.getConstArray(), 16 ) )
829 return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
831 return SvxUnoTextCursor::getSomething( rId );
834 namespace
836 class theScDrawTextCursorUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theScDrawTextCursorUnoTunnelId> {};
839 const uno::Sequence<sal_Int8>& ScDrawTextCursor::getUnoTunnelId()
841 return theScDrawTextCursorUnoTunnelId::get().getSeq();
844 ScDrawTextCursor* ScDrawTextCursor::getImplementation( const uno::Reference<uno::XInterface> xObj )
846 ScDrawTextCursor* pRet = NULL;
847 uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY );
848 if (xUT.is())
849 pRet = reinterpret_cast<ScDrawTextCursor*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
850 return pRet;
853 ScSimpleEditSourceHelper::ScSimpleEditSourceHelper()
855 SfxItemPool* pEnginePool = EditEngine::CreatePool();
856 pEnginePool->SetDefaultMetric( SFX_MAPUNIT_100TH_MM );
857 pEnginePool->FreezeIdRanges();
859 pEditEngine = new ScFieldEditEngine(NULL, pEnginePool, NULL, true); // TRUE: become owner of pool
860 pForwarder = new SvxEditEngineForwarder( *pEditEngine );
861 pOriginalSource = new ScSimpleEditSource( pForwarder );
864 ScSimpleEditSourceHelper::~ScSimpleEditSourceHelper()
866 SolarMutexGuard aGuard; // needed for EditEngine dtor
868 delete pOriginalSource;
869 delete pForwarder;
870 delete pEditEngine;
873 ScEditEngineTextObj::ScEditEngineTextObj() :
874 SvxUnoText( GetOriginalSource(), ScCellObj::GetEditPropertySet(), uno::Reference<text::XText>() )
878 ScEditEngineTextObj::~ScEditEngineTextObj() throw()
882 void ScEditEngineTextObj::SetText( const EditTextObject& rTextObject )
884 GetEditEngine()->SetText( rTextObject );
886 ESelection aSel;
887 ::GetSelection( aSel, GetEditSource()->GetTextForwarder() );
888 SetSelection( aSel );
891 EditTextObject* ScEditEngineTextObj::CreateTextObject()
893 return GetEditEngine()->CreateTextObject();
896 ScCellTextData::ScCellTextData(ScDocShell* pDocSh, const ScAddress& rP) :
897 pDocShell( pDocSh ),
898 aCellPos( rP ),
899 pEditEngine( NULL ),
900 pForwarder( NULL ),
901 pOriginalSource( NULL ),
902 bDataValid( false ),
903 bInUpdate( false ),
904 bDirty( false ),
905 bDoUpdate( true )
907 if (pDocShell)
908 pDocShell->GetDocument()->AddUnoObject(*this);
911 ScCellTextData::~ScCellTextData()
913 SolarMutexGuard aGuard; // needed for EditEngine dtor
915 if (pDocShell)
917 pDocShell->GetDocument()->RemoveUnoObject(*this);
918 pDocShell->GetDocument()->DisposeFieldEditEngine(pEditEngine);
920 else
921 delete pEditEngine;
923 delete pForwarder;
925 delete pOriginalSource;
928 ScCellEditSource* ScCellTextData::GetOriginalSource()
930 if (!pOriginalSource)
931 pOriginalSource = new ScCellEditSource(pDocShell, aCellPos);
932 return pOriginalSource;
935 void ScCellTextData::GetCellText(const ScAddress& rCellPos, OUString& rText)
937 if (pDocShell)
939 ScDocument* pDoc = pDocShell->GetDocument();
940 pDoc->GetInputString( rCellPos.Col(), rCellPos.Row(), rCellPos.Tab(), rText );
944 SvxTextForwarder* ScCellTextData::GetTextForwarder()
946 if (!pEditEngine)
948 if ( pDocShell )
950 ScDocument* pDoc = pDocShell->GetDocument();
951 pEditEngine = pDoc->CreateFieldEditEngine();
953 else
955 SfxItemPool* pEnginePool = EditEngine::CreatePool();
956 pEnginePool->FreezeIdRanges();
957 pEditEngine = new ScFieldEditEngine(NULL, pEnginePool, NULL, true);
959 // currently, GetPortions doesn't work if UpdateMode is sal_False,
960 // this will be fixed (in EditEngine) by src600
961 // pEditEngine->SetUpdateMode( sal_False );
962 pEditEngine->EnableUndo( false );
963 if (pDocShell)
964 pEditEngine->SetRefDevice(pDocShell->GetRefDevice());
965 else
966 pEditEngine->SetRefMapMode( MAP_100TH_MM );
967 pForwarder = new SvxEditEngineForwarder(*pEditEngine);
970 if (bDataValid)
971 return pForwarder;
973 OUString aText;
975 if (pDocShell)
977 ScDocument* pDoc = pDocShell->GetDocument();
979 SfxItemSet aDefaults( pEditEngine->GetEmptyItemSet() );
980 if( const ScPatternAttr* pPattern =
981 pDoc->GetPattern( aCellPos.Col(), aCellPos.Row(), aCellPos.Tab() ) )
983 pPattern->FillEditItemSet( &aDefaults );
984 pPattern->FillEditParaItems( &aDefaults ); // including alignment etc. (for reading)
987 if (pDoc->GetCellType(aCellPos) == CELLTYPE_EDIT)
989 const EditTextObject* pObj = pDoc->GetEditText(aCellPos);
990 if (pObj)
991 pEditEngine->SetTextNewDefaults(*pObj, aDefaults);
993 else
995 GetCellText(aCellPos, aText);
996 if (!aText.isEmpty())
997 pEditEngine->SetTextNewDefaults(aText, aDefaults);
998 else
999 pEditEngine->SetDefaults(aDefaults);
1003 bDataValid = true;
1004 return pForwarder;
1007 void ScCellTextData::UpdateData()
1009 if ( bDoUpdate )
1011 OSL_ENSURE(pEditEngine != NULL, "no EditEngine for UpdateData()");
1012 if ( pDocShell && pEditEngine )
1014 // during the own UpdateData call, bDataValid must not be reset,
1015 // or things like attributes after the text would be lost
1016 // (are not stored in the cell)
1017 bInUpdate = true; // prevents bDataValid from being reset
1018 pDocShell->GetDocFunc().PutData(aCellPos, *pEditEngine, true); // always as text
1020 bInUpdate = false;
1021 bDirty = false;
1024 else
1025 bDirty = true;
1028 void ScCellTextData::Notify( SfxBroadcaster&, const SfxHint& rHint )
1030 if ( rHint.ISA( ScUpdateRefHint ) )
1032 // const ScUpdateRefHint& rRef = (const ScUpdateRefHint&)rHint;
1034 //! Ref-Update
1036 else if ( rHint.ISA( SfxSimpleHint ) )
1038 sal_uLong nId = ((const SfxSimpleHint&)rHint).GetId();
1039 if ( nId == SFX_HINT_DYING )
1041 pDocShell = NULL; // invalid now
1043 DELETEZ( pForwarder );
1044 DELETEZ( pEditEngine ); // EditEngine uses document's pool
1046 else if ( nId == SFX_HINT_DATACHANGED )
1048 if (!bInUpdate) // not for own UpdateData calls
1049 bDataValid = false; // text has to be read from the cell again
1054 ScCellTextObj::ScCellTextObj(ScDocShell* pDocSh, const ScAddress& rP) :
1055 ScCellTextData( pDocSh, rP ),
1056 SvxUnoText( GetOriginalSource(), ScCellObj::GetEditPropertySet(), uno::Reference<text::XText>() )
1060 ScCellTextObj::~ScCellTextObj() throw()
1064 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */