tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / sc / source / ui / unoobj / textuno.cxx
blob4e4070502dc26d8757458844d9320c6109b7cd5f
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 <memory>
21 #include <sal/config.h>
22 #include <sal/log.hxx>
24 #include <scitems.hxx>
25 #include <editeng/eeitem.hxx>
26 #include <svx/svdpool.hxx>
27 #include <svx/svdobj.hxx>
28 #include <editeng/editeng.hxx>
29 #include <editeng/editobj.hxx>
30 #include <editeng/flditem.hxx>
31 #include <editeng/fhgtitem.hxx>
32 #include <editeng/unoprnms.hxx>
33 #include <editeng/unofored.hxx>
34 #include <utility>
35 #include <vcl/svapp.hxx>
37 #include <editeng/unoipset.hxx>
38 #include <textuno.hxx>
39 #include <fielduno.hxx>
40 #include <editsrc.hxx>
41 #include <docsh.hxx>
42 #include <editutil.hxx>
43 #include <miscuno.hxx>
44 #include <cellsuno.hxx>
45 #include <cellvalue.hxx>
46 #include <cellform.hxx>
47 #include <patattr.hxx>
48 #include <docfunc.hxx>
49 #include <scmod.hxx>
51 using namespace com::sun::star;
53 static const SvxItemPropertySet * lcl_GetHdFtPropertySet()
55 static const SvxItemPropertySet aHdFtPropertySet_Impl = [] {
56 static SfxItemPropertyMapEntry aHdFtPropertyMap_Impl[] =
58 SVX_UNOEDIT_CHAR_PROPERTIES,
59 SVX_UNOEDIT_FONT_PROPERTIES,
60 SVX_UNOEDIT_PARA_PROPERTIES,
61 SVX_UNOEDIT_NUMBERING_PROPERTY, // for completeness of service ParagraphProperties
64 // modify PropertyMap to include CONVERT_TWIPS flag for font height
65 // (headers/footers are in twips)
67 for (auto & rEntry : aHdFtPropertyMap_Impl)
69 if ( ( rEntry.nWID == EE_CHAR_FONTHEIGHT ||
70 rEntry.nWID == EE_CHAR_FONTHEIGHT_CJK ||
71 rEntry.nWID == EE_CHAR_FONTHEIGHT_CTL ) &&
72 rEntry.nMemberId == MID_FONTHEIGHT )
74 rEntry.nMemberId |= CONVERT_TWIPS;
78 return SvxItemPropertySet(aHdFtPropertyMap_Impl, SdrObject::GetGlobalDrawObjectItemPool());
79 }();
80 return &aHdFtPropertySet_Impl;
83 SC_SIMPLE_SERVICE_INFO( ScHeaderFooterContentObj, u"ScHeaderFooterContentObj"_ustr, u"com.sun.star.sheet.HeaderFooterContent"_ustr )
84 SC_SIMPLE_SERVICE_INFO( ScHeaderFooterTextObj, u"ScHeaderFooterTextObj"_ustr, u"stardiv.one.Text.Text"_ustr )
86 ScHeaderFooterContentObj::ScHeaderFooterContentObj()
90 ScHeaderFooterContentObj::~ScHeaderFooterContentObj() {}
92 const EditTextObject* ScHeaderFooterContentObj::GetLeftEditObject() const
94 return mxLeftText->GetTextObject();
97 const EditTextObject* ScHeaderFooterContentObj::GetCenterEditObject() const
99 return mxCenterText->GetTextObject();
102 const EditTextObject* ScHeaderFooterContentObj::GetRightEditObject() const
104 return mxRightText->GetTextObject();
107 // XHeaderFooterContent
109 uno::Reference<text::XText> SAL_CALL ScHeaderFooterContentObj::getLeftText()
111 SolarMutexGuard aGuard;
112 uno::Reference<text::XText> xInt(*mxLeftText, uno::UNO_QUERY);
113 return xInt;
116 uno::Reference<text::XText> SAL_CALL ScHeaderFooterContentObj::getCenterText()
118 SolarMutexGuard aGuard;
119 uno::Reference<text::XText> xInt(*mxCenterText, uno::UNO_QUERY);
120 return xInt;
123 uno::Reference<text::XText> SAL_CALL ScHeaderFooterContentObj::getRightText()
125 SolarMutexGuard aGuard;
126 uno::Reference<text::XText> xInt(*mxRightText, uno::UNO_QUERY);
127 return xInt;
130 rtl::Reference<ScHeaderFooterContentObj> ScHeaderFooterContentObj::getImplementation(
131 const uno::Reference<sheet::XHeaderFooterContent>& rObj)
133 return dynamic_cast<ScHeaderFooterContentObj*>(rObj.get());
136 void ScHeaderFooterContentObj::Init( const EditTextObject* pLeft,
137 const EditTextObject* pCenter,
138 const EditTextObject* pRight )
140 mxLeftText = rtl::Reference<ScHeaderFooterTextObj>(new ScHeaderFooterTextObj(this, ScHeaderFooterPart::LEFT, pLeft));
141 mxCenterText = rtl::Reference<ScHeaderFooterTextObj>(new ScHeaderFooterTextObj(this, ScHeaderFooterPart::CENTER, pCenter));
142 mxRightText = rtl::Reference<ScHeaderFooterTextObj>(new ScHeaderFooterTextObj(this, ScHeaderFooterPart::RIGHT, pRight));
145 ScHeaderFooterTextData::ScHeaderFooterTextData(
146 unotools::WeakReference<ScHeaderFooterContentObj> xContent, ScHeaderFooterPart nP, const EditTextObject* pTextObj) :
147 mpTextObj(pTextObj ? pTextObj->Clone() : nullptr),
148 xContentObj(std::move( xContent )),
149 nPart( nP ),
150 bDataValid(false)
154 ScHeaderFooterTextData::~ScHeaderFooterTextData()
156 SolarMutexGuard aGuard; // needed for EditEngine dtor
158 pForwarder.reset();
159 pEditEngine.reset();
162 SvxTextForwarder* ScHeaderFooterTextData::GetTextForwarder()
164 if (!pEditEngine)
166 rtl::Reference<SfxItemPool> pEnginePool = EditEngine::CreatePool();
167 std::unique_ptr<ScHeaderEditEngine> pHdrEngine(new ScHeaderEditEngine( pEnginePool.get() ));
169 pHdrEngine->EnableUndo( false );
170 pHdrEngine->SetRefMapMode(MapMode(MapUnit::MapTwip));
172 // default font must be set, independently of document
173 ScDocShell* pDocSh(dynamic_cast<ScDocShell*>(SfxObjectShell::Current()));
174 std::unique_ptr<CellAttributeHelper> pTmp;
175 const ScPatternAttr* pCellAttributeDefault(nullptr);
177 if (nullptr != pDocSh)
179 // we can use default CellAttribute from ScDocument
180 pCellAttributeDefault = &pDocSh->GetDocument().getCellAttributeHelper().getDefaultCellAttribute();
182 else
184 // no access to ScDocument, use temporary default CellAttributeHelper
185 // was: "use global pool from module" which is usually ScMessagePool
186 // and gets set in ScTabViewObj::SelectionChanged() by
187 // ScFormatShell::ScFormatShell which calls
188 // SetPool( &pTabViewShell->GetPool() );
189 pTmp.reset(new CellAttributeHelper(ScModule::get()->GetPool()));
190 pCellAttributeDefault = &pTmp->getDefaultCellAttribute();
193 auto pDefaults = std::make_unique<SfxItemSet>(pHdrEngine->GetEmptyItemSet());
194 pCellAttributeDefault->FillEditItemSet(pDefaults.get());
195 // FillEditItemSet adjusts font height to 1/100th mm,
196 // but for header/footer twips is needed, as in the PatternAttr:
197 pDefaults->Put( pCellAttributeDefault->GetItem(ATTR_FONT_HEIGHT).CloneSetWhich(EE_CHAR_FONTHEIGHT) );
198 pDefaults->Put( pCellAttributeDefault->GetItem(ATTR_CJK_FONT_HEIGHT).CloneSetWhich(EE_CHAR_FONTHEIGHT_CJK) ) ;
199 pDefaults->Put( pCellAttributeDefault->GetItem(ATTR_CTL_FONT_HEIGHT).CloneSetWhich(EE_CHAR_FONTHEIGHT_CTL) );
200 pHdrEngine->SetDefaults(std::move(pDefaults));
202 ScHeaderFieldData aData;
203 ScHeaderFooterTextObj::FillDummyFieldData( aData );
204 pHdrEngine->SetData( aData );
206 pEditEngine = std::move(pHdrEngine);
207 pForwarder.reset( new SvxEditEngineForwarder(*pEditEngine) );
210 if (bDataValid)
211 return pForwarder.get();
213 if (mpTextObj)
214 pEditEngine->SetTextCurrentDefaults(*mpTextObj);
216 bDataValid = true;
217 return pForwarder.get();
220 void ScHeaderFooterTextData::UpdateData()
222 if (pEditEngine)
224 mpTextObj = pEditEngine->CreateTextObject();
228 void ScHeaderFooterTextData::UpdateData(EditEngine& rEditEngine)
230 mpTextObj = rEditEngine.CreateTextObject();
231 bDataValid = false;
234 ScHeaderFooterTextObj::ScHeaderFooterTextObj(
235 const unotools::WeakReference<ScHeaderFooterContentObj>& xContent, ScHeaderFooterPart nP, const EditTextObject* pTextObj) :
236 aTextData(xContent, nP, pTextObj)
238 // ScHeaderFooterTextData acquires rContent
239 // pUnoText is created on demand (getString/setString work without it)
242 void ScHeaderFooterTextObj::CreateUnoText_Impl()
244 if (!mxUnoText.is())
246 // can't be aggregated because getString/setString is handled here
247 ScHeaderFooterEditSource aEditSrc(aTextData);
248 mxUnoText.set(new SvxUnoText(&aEditSrc, lcl_GetHdFtPropertySet(), uno::Reference<text::XText>()));
252 ScHeaderFooterTextObj::~ScHeaderFooterTextObj() {}
254 const EditTextObject* ScHeaderFooterTextObj::GetTextObject() const
256 return aTextData.GetTextObject();
259 const SvxUnoText& ScHeaderFooterTextObj::GetUnoText()
261 if (!mxUnoText.is())
262 CreateUnoText_Impl();
263 return *mxUnoText;
266 // XText
268 uno::Reference<text::XTextCursor> SAL_CALL ScHeaderFooterTextObj::createTextCursor()
270 SolarMutexGuard aGuard;
271 return new ScHeaderFooterTextCursor( this );
274 uno::Reference<text::XTextCursor> SAL_CALL ScHeaderFooterTextObj::createTextCursorByRange(
275 const uno::Reference<text::XTextRange>& aTextPosition )
277 SolarMutexGuard aGuard;
278 if (!mxUnoText.is())
279 CreateUnoText_Impl();
280 return mxUnoText->createTextCursorByRange(aTextPosition);
281 //! like ScCellObj::createTextCursorByRange, if SvxUnoTextRange_getReflection available
284 void ScHeaderFooterTextObj::FillDummyFieldData( ScHeaderFieldData& rData )
286 OUString aDummy(u"???"_ustr);
287 rData.aTitle = aDummy;
288 rData.aLongDocName = aDummy;
289 rData.aShortDocName = aDummy;
290 rData.aTabName = aDummy;
291 rData.nPageNo = 1;
292 rData.nTotalPages = 99;
295 OUString SAL_CALL ScHeaderFooterTextObj::getString()
297 SolarMutexGuard aGuard;
298 OUString aRet;
299 const EditTextObject* pData;
301 rtl::Reference<ScHeaderFooterContentObj> xContentObj = aTextData.GetContentObj();
302 if (!xContentObj.is())
303 throw css::uno::RuntimeException(
304 u"ScHeaderFooterTextObj::getString: no ContentObj"_ustr);
306 switch ( aTextData.GetPart() )
308 case ScHeaderFooterPart::LEFT:
309 pData = xContentObj->GetLeftEditObject();
310 break;
311 case ScHeaderFooterPart::CENTER:
312 pData = xContentObj->GetCenterEditObject();
313 break;
314 case ScHeaderFooterPart::RIGHT:
315 pData = xContentObj->GetRightEditObject();
316 break;
317 default:
318 SAL_WARN("sc.ui","unexpected enum value of ScHeaderFooterPart");
319 pData = nullptr;
322 if (pData)
324 // for pure text, no font info is needed in pool defaults
325 ScHeaderEditEngine aEditEngine( EditEngine::CreatePool().get() );
327 ScHeaderFieldData aData;
328 FillDummyFieldData( aData );
329 aEditEngine.SetData( aData );
331 aEditEngine.SetTextCurrentDefaults(*pData);
332 aRet = ScEditUtil::GetSpaceDelimitedString( aEditEngine );
334 return aRet;
337 void SAL_CALL ScHeaderFooterTextObj::setString( const OUString& aText )
339 SolarMutexGuard aGuard;
341 // for pure text, no font info is needed in pool defaults
342 ScHeaderEditEngine aEditEngine(EditEngine::CreatePool().get());
343 aEditEngine.SetTextCurrentDefaults( aText );
344 aTextData.UpdateData(aEditEngine);
347 void SAL_CALL ScHeaderFooterTextObj::insertString( const uno::Reference<text::XTextRange>& xRange,
348 const OUString& aString, sal_Bool bAbsorb )
350 SolarMutexGuard aGuard;
351 if (!mxUnoText.is())
352 CreateUnoText_Impl();
353 mxUnoText->insertString( xRange, aString, bAbsorb );
356 void SAL_CALL ScHeaderFooterTextObj::insertControlCharacter(
357 const uno::Reference<text::XTextRange>& xRange,
358 sal_Int16 nControlCharacter, sal_Bool bAbsorb )
360 SolarMutexGuard aGuard;
361 if (!mxUnoText.is())
362 CreateUnoText_Impl();
363 mxUnoText->insertControlCharacter( xRange, nControlCharacter, bAbsorb );
366 void SAL_CALL ScHeaderFooterTextObj::insertTextContent(
367 const uno::Reference<text::XTextRange >& xRange,
368 const uno::Reference<text::XTextContent >& xContent,
369 sal_Bool bAbsorb )
371 SolarMutexGuard aGuard;
372 if ( xContent.is() && xRange.is() )
374 ScEditFieldObj* pHeaderField = dynamic_cast<ScEditFieldObj*>( xContent.get() );
376 SvxUnoTextRangeBase* pTextRange =
377 comphelper::getFromUnoTunnel<ScHeaderFooterTextCursor>( xRange );
379 if ( pHeaderField && !pHeaderField->IsInserted() && pTextRange )
381 SvxEditSource* pEditSource = pTextRange->GetEditSource();
382 ESelection aSelection(pTextRange->GetSelection());
384 if (!bAbsorb)
386 // don't replace -> append at end
387 aSelection.Adjust();
388 aSelection.CollapseToEnd();
391 SvxFieldItem aItem(pHeaderField->CreateFieldItem());
393 SvxTextForwarder* pForwarder = pEditSource->GetTextForwarder();
394 pForwarder->QuickInsertField( aItem, aSelection );
395 pEditSource->UpdateData();
397 // new selection: a digit
398 aSelection.Adjust();
399 aSelection.end.nPara = aSelection.start.nPara;
400 aSelection.end.nIndex = aSelection.start.nIndex + 1;
402 uno::Reference<text::XTextRange> xTextRange;
403 switch ( aTextData.GetPart() )
405 case ScHeaderFooterPart::LEFT:
406 xTextRange = aTextData.GetContentObj()->getLeftText();
407 break;
408 case ScHeaderFooterPart::CENTER:
409 xTextRange = aTextData.GetContentObj()->getCenterText();
410 break;
411 case ScHeaderFooterPart::RIGHT:
412 xTextRange = aTextData.GetContentObj()->getRightText();
413 break;
416 pHeaderField->InitDoc(xTextRange, std::make_unique<ScHeaderFooterEditSource>(aTextData), aSelection);
418 // for bAbsorb=FALSE, the new selection must be behind the inserted content
419 // (the xml filter relies on this)
420 if (!bAbsorb)
421 aSelection.start.nIndex = aSelection.end.nIndex;
423 pTextRange->SetSelection( aSelection );
425 return;
429 if (!mxUnoText.is())
430 CreateUnoText_Impl();
431 mxUnoText->insertTextContent( xRange, xContent, bAbsorb );
434 void SAL_CALL ScHeaderFooterTextObj::removeTextContent(
435 const uno::Reference<text::XTextContent>& xContent )
437 SolarMutexGuard aGuard;
438 if ( xContent.is() )
440 ScEditFieldObj* pHeaderField = dynamic_cast<ScEditFieldObj*>(xContent.get());
441 if ( pHeaderField && pHeaderField->IsInserted() )
443 //! check if the field is in this cell
444 pHeaderField->DeleteField();
445 return;
448 if (!mxUnoText.is())
449 CreateUnoText_Impl();
450 mxUnoText->removeTextContent( xContent );
453 uno::Reference<text::XText> SAL_CALL ScHeaderFooterTextObj::getText()
455 SolarMutexGuard aGuard;
456 if (!mxUnoText.is())
457 CreateUnoText_Impl();
458 return mxUnoText->getText();
461 uno::Reference<text::XTextRange> SAL_CALL ScHeaderFooterTextObj::getStart()
463 SolarMutexGuard aGuard;
464 if (!mxUnoText.is())
465 CreateUnoText_Impl();
466 return mxUnoText->getStart();
469 uno::Reference<text::XTextRange> SAL_CALL ScHeaderFooterTextObj::getEnd()
471 SolarMutexGuard aGuard;
472 if (!mxUnoText.is())
473 CreateUnoText_Impl();
474 return mxUnoText->getEnd();
477 // XTextFieldsSupplier
479 uno::Reference<container::XEnumerationAccess> SAL_CALL ScHeaderFooterTextObj::getTextFields()
481 SolarMutexGuard aGuard;
482 // all fields
483 return new ScHeaderFieldsObj(aTextData);
486 uno::Reference<container::XNameAccess> SAL_CALL ScHeaderFooterTextObj::getTextFieldMasters()
488 // this does not exists in Calc (?)
489 return nullptr;
492 // XTextRangeMover
494 void SAL_CALL ScHeaderFooterTextObj::moveTextRange(
495 const uno::Reference<text::XTextRange>& xRange,
496 sal_Int16 nParagraphs )
498 SolarMutexGuard aGuard;
499 if (!mxUnoText.is())
500 CreateUnoText_Impl();
501 mxUnoText->moveTextRange( xRange, nParagraphs );
504 // XEnumerationAccess
506 uno::Reference<container::XEnumeration> SAL_CALL ScHeaderFooterTextObj::createEnumeration()
508 SolarMutexGuard aGuard;
509 if (!mxUnoText.is())
510 CreateUnoText_Impl();
511 return mxUnoText->createEnumeration();
514 // XElementAccess
516 uno::Type SAL_CALL ScHeaderFooterTextObj::getElementType()
518 SolarMutexGuard aGuard;
519 if (!mxUnoText.is())
520 CreateUnoText_Impl();
521 return mxUnoText->getElementType();
524 sal_Bool SAL_CALL ScHeaderFooterTextObj::hasElements()
526 SolarMutexGuard aGuard;
527 if (!mxUnoText.is())
528 CreateUnoText_Impl();
529 return mxUnoText->hasElements();
532 ScCellTextCursor::ScCellTextCursor(ScCellObj& rText) :
533 SvxUnoTextCursor( rText.GetUnoText() ),
534 mxTextObj( &rText )
538 ScCellTextCursor::~ScCellTextCursor() noexcept
542 // SvxUnoTextCursor methods reimplemented here to return the right objects:
544 uno::Reference<text::XText> SAL_CALL ScCellTextCursor::getText()
546 return mxTextObj;
549 uno::Reference<text::XTextRange> SAL_CALL ScCellTextCursor::getStart()
551 SolarMutexGuard aGuard;
553 //! use other object for range than cursor?
555 rtl::Reference<ScCellTextCursor> pNew = new ScCellTextCursor( *this );
557 ESelection aNewSel(GetSelection());
558 aNewSel.CollapseToStart();
559 pNew->SetSelection( aNewSel );
561 return static_cast<SvxUnoTextRangeBase*>(pNew.get());
564 uno::Reference<text::XTextRange> SAL_CALL ScCellTextCursor::getEnd()
566 SolarMutexGuard aGuard;
568 //! use other object for range than cursor?
570 rtl::Reference<ScCellTextCursor> pNew = new ScCellTextCursor( *this );
572 ESelection aNewSel(GetSelection());
573 aNewSel.CollapseToEnd();
574 pNew->SetSelection( aNewSel );
576 return static_cast<SvxUnoTextRangeBase*>(pNew.get());
579 // XUnoTunnel
581 UNO3_GETIMPLEMENTATION2_IMPL(ScCellTextCursor, SvxUnoTextCursor);
583 ScHeaderFooterTextCursor::ScHeaderFooterTextCursor(rtl::Reference<ScHeaderFooterTextObj> const & rText) :
584 SvxUnoTextCursor( rText->GetUnoText() ),
585 rTextObj( rText )
588 ScHeaderFooterTextCursor::~ScHeaderFooterTextCursor() noexcept {};
590 // SvxUnoTextCursor methods reimplemented here to return the right objects:
592 uno::Reference<text::XText> SAL_CALL ScHeaderFooterTextCursor::getText()
594 SolarMutexGuard aGuard;
595 return rTextObj;
598 uno::Reference<text::XTextRange> SAL_CALL ScHeaderFooterTextCursor::getStart()
600 SolarMutexGuard aGuard;
602 //! use other object for range than cursor?
604 rtl::Reference<ScHeaderFooterTextCursor> pNew = new ScHeaderFooterTextCursor( *this );
606 ESelection aNewSel(GetSelection());
607 aNewSel.CollapseToStart();
608 pNew->SetSelection( aNewSel );
610 return static_cast<SvxUnoTextRangeBase*>(pNew.get());
613 uno::Reference<text::XTextRange> SAL_CALL ScHeaderFooterTextCursor::getEnd()
615 SolarMutexGuard aGuard;
617 //! use other object for range than cursor?
619 rtl::Reference<ScHeaderFooterTextCursor> pNew = new ScHeaderFooterTextCursor( *this );
621 ESelection aNewSel(GetSelection());
622 aNewSel.CollapseToEnd();
623 pNew->SetSelection( aNewSel );
625 return static_cast<SvxUnoTextRangeBase*>(pNew.get());
628 // XUnoTunnel
630 UNO3_GETIMPLEMENTATION2_IMPL(ScHeaderFooterTextCursor, SvxUnoTextCursor);
632 ScDrawTextCursor::ScDrawTextCursor( uno::Reference<text::XText> xParent,
633 const SvxUnoTextBase& rText ) :
634 SvxUnoTextCursor( rText ),
635 xParentText(std::move( xParent ))
640 ScDrawTextCursor::~ScDrawTextCursor() noexcept
644 // SvxUnoTextCursor methods reimplemented here to return the right objects:
646 uno::Reference<text::XText> SAL_CALL ScDrawTextCursor::getText()
648 SolarMutexGuard aGuard;
649 return xParentText;
652 uno::Reference<text::XTextRange> SAL_CALL ScDrawTextCursor::getStart()
654 SolarMutexGuard aGuard;
656 //! use other object for range than cursor?
658 rtl::Reference<ScDrawTextCursor> pNew = new ScDrawTextCursor( *this );
660 ESelection aNewSel(GetSelection());
661 aNewSel.CollapseToStart();
662 pNew->SetSelection( aNewSel );
664 return static_cast<SvxUnoTextRangeBase*>(pNew.get());
667 uno::Reference<text::XTextRange> SAL_CALL ScDrawTextCursor::getEnd()
669 SolarMutexGuard aGuard;
671 //! use other object for range than cursor?
673 rtl::Reference<ScDrawTextCursor> pNew = new ScDrawTextCursor( *this );
675 ESelection aNewSel(GetSelection());
676 aNewSel.CollapseToEnd();
677 pNew->SetSelection( aNewSel );
679 return static_cast<SvxUnoTextRangeBase*>(pNew.get());
682 // XUnoTunnel
684 UNO3_GETIMPLEMENTATION2_IMPL(ScDrawTextCursor, SvxUnoTextCursor);
686 ScSimpleEditSourceHelper::ScSimpleEditSourceHelper()
688 rtl::Reference<SfxItemPool> pEnginePool = EditEngine::CreatePool();
689 pEnginePool->SetDefaultMetric( MapUnit::Map100thMM );
690 pEditEngine.reset( new ScFieldEditEngine(nullptr, pEnginePool.get(), nullptr, true) ); // TRUE: become owner of pool
691 pForwarder.reset( new SvxEditEngineForwarder( *pEditEngine ) );
692 pOriginalSource.reset( new ScSimpleEditSource( pForwarder.get() ) );
695 ScSimpleEditSourceHelper::~ScSimpleEditSourceHelper()
697 SolarMutexGuard aGuard; // needed for EditEngine dtor
699 pOriginalSource.reset();
700 pForwarder.reset();
701 pEditEngine.reset();
704 ScEditEngineTextObj::ScEditEngineTextObj() :
705 SvxUnoText( GetOriginalSource(), ScCellObj::GetEditPropertySet(), uno::Reference<text::XText>() )
709 ScEditEngineTextObj::~ScEditEngineTextObj() noexcept
713 void ScEditEngineTextObj::SetText( const EditTextObject& rTextObject )
715 GetEditEngine()->SetTextCurrentDefaults( rTextObject );
717 ESelection aSel;
718 ::GetSelection( aSel, GetEditSource()->GetTextForwarder() );
719 SetSelection( aSel );
722 std::unique_ptr<EditTextObject> ScEditEngineTextObj::CreateTextObject()
724 return GetEditEngine()->CreateTextObject();
727 ScCellTextData::ScCellTextData(ScDocShell* pDocSh, const ScAddress& rP) :
728 pDocShell( pDocSh ),
729 aCellPos( rP ),
730 bDataValid( false ),
731 bInUpdate( false ),
732 bDirty( false ),
733 bDoUpdate( true )
735 if (pDocShell)
736 pDocShell->GetDocument().AddUnoObject(*this);
739 ScCellTextData::~ScCellTextData()
741 SolarMutexGuard aGuard; // needed for EditEngine dtor
743 if (pDocShell)
745 pDocShell->GetDocument().RemoveUnoObject(*this);
746 pDocShell->GetDocument().DisposeFieldEditEngine(pEditEngine);
748 else
749 pEditEngine.reset();
751 pForwarder.reset();
753 pOriginalSource.reset();
756 ScCellEditSource* ScCellTextData::GetOriginalSource()
758 if (!pOriginalSource)
759 pOriginalSource.reset( new ScCellEditSource(pDocShell, aCellPos) );
760 return pOriginalSource.get();
763 SvxTextForwarder* ScCellTextData::GetTextForwarder()
765 if (!pEditEngine)
767 if ( pDocShell )
769 ScDocument& rDoc = pDocShell->GetDocument();
770 pEditEngine = rDoc.CreateFieldEditEngine();
772 else
774 rtl::Reference<SfxItemPool> pEnginePool = EditEngine::CreatePool();
775 pEditEngine.reset( new ScFieldEditEngine(nullptr, pEnginePool.get(), nullptr, true) );
777 // currently, GetPortions doesn't work if UpdateMode is sal_False,
778 // this will be fixed (in EditEngine) by src600
779 // pEditEngine->SetUpdateMode( sal_False );
780 pEditEngine->EnableUndo( false );
781 if (pDocShell)
782 pEditEngine->SetRefDevice(pDocShell->GetRefDevice());
783 else
784 pEditEngine->SetRefMapMode(MapMode(MapUnit::Map100thMM));
785 pForwarder.reset( new SvxEditEngineForwarder(*pEditEngine) );
788 if (bDataValid)
789 return pForwarder.get();
791 if (pDocShell)
793 ScDocument& rDoc = pDocShell->GetDocument();
795 auto pDefaults = std::make_unique<SfxItemSet>(pEditEngine->GetEmptyItemSet());
796 if( const ScPatternAttr* pPattern =
797 rDoc.GetPattern( aCellPos.Col(), aCellPos.Row(), aCellPos.Tab() ) )
799 pPattern->FillEditItemSet(pDefaults.get());
800 pPattern->FillEditParaItems(pDefaults.get()); // including alignment etc. (for reading)
803 ScRefCellValue aCell(rDoc, aCellPos);
804 if (aCell.getType() == CELLTYPE_EDIT)
806 const EditTextObject* pObj = aCell.getEditText();
807 pEditEngine->SetTextNewDefaults(*pObj, std::move(pDefaults));
809 else
811 sal_uInt32 nFormat = rDoc.GetNumberFormat(ScRange(aCellPos));
812 OUString aText = ScCellFormat::GetInputString(aCell, nFormat, nullptr, rDoc);
813 // tdf#157568 check if edit engine already has text
814 // If the input string is empty but the edit engine's existing
815 // text is not empty, force update of the edit engine's text.
816 // Otherwise, the edit engine will still to be set to its
817 // existing text.
818 // Note: CppunitTest_sc_macros_test testTdf116127 will fail if
819 // pEditEngine->SetTextNewDefaults() is passed an empty string
820 // and pEditEngine->GetText() is empty string.
821 if (!aText.isEmpty() || pEditEngine->HasText())
822 pEditEngine->SetTextNewDefaults(aText, std::move(pDefaults));
823 else
824 pEditEngine->SetDefaults(std::move(pDefaults));
828 bDataValid = true;
829 return pForwarder.get();
832 void ScCellTextData::UpdateData()
834 if ( bDoUpdate )
836 OSL_ENSURE(pEditEngine != nullptr, "no EditEngine for UpdateData()");
837 if ( pDocShell && pEditEngine )
839 // during the own UpdateData call, bDataValid must not be reset,
840 // or things like attributes after the text would be lost
841 // (are not stored in the cell)
842 bInUpdate = true; // prevents bDataValid from being reset
843 pDocShell->GetDocFunc().PutData(aCellPos, *pEditEngine, true); // always as text
845 bInUpdate = false;
846 bDirty = false;
849 else
850 bDirty = true;
853 void ScCellTextData::Notify( SfxBroadcaster&, const SfxHint& rHint )
855 const SfxHintId nId = rHint.GetId();
856 if ( nId == SfxHintId::Dying )
858 pDocShell = nullptr; // invalid now
860 pForwarder.reset();
861 pEditEngine.reset(); // EditEngine uses document's pool
863 else if ( nId == SfxHintId::DataChanged )
865 if (!bInUpdate) // not for own UpdateData calls
866 bDataValid = false; // text has to be read from the cell again
870 ScCellTextObj::ScCellTextObj(ScDocShell* pDocSh, const ScAddress& rP) :
871 ScCellTextData( pDocSh, rP ),
872 SvxUnoText( GetOriginalSource(), ScCellObj::GetEditPropertySet(), uno::Reference<text::XText>() )
876 ScCellTextObj::~ScCellTextObj() COVERITY_NOEXCEPT_FALSE
880 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */