LibreOffice Module svx (master) 1
unoshtxt.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <sal/config.h>
21
22#include <memory>
23
24#include <vcl/svapp.hxx>
25
26#include <svx/unoshtxt.hxx>
27#include <editeng/unoedhlp.hxx>
28#include <svl/lstner.hxx>
29#include <rtl/ref.hxx>
30#include <tools/debug.hxx>
31#include <svl/hint.hxx>
32#include <svl/style.hxx>
33#include <svx/svdmodel.hxx>
34#include <svx/svdoutl.hxx>
35#include <svx/svdobj.hxx>
36#include <svx/svdview.hxx>
37#include <editeng/outliner.hxx>
38#include <editeng/unoforou.hxx>
39#include <editeng/unoviwou.hxx>
40#include <editeng/outlobj.hxx>
41#include <svx/svdotext.hxx>
42#include <svx/svdpage.hxx>
43#include <editeng/editeng.hxx>
44
45#include <editeng/unotext.hxx>
46#include <com/sun/star/linguistic2/LinguServiceManager.hpp>
48#include <svx/svdotable.hxx>
49#include <cell.hxx>
51
52
53// SvxTextEditSourceImpl
54
55
77{
78private:
79 oslInterlockedCount maRefCount;
80
81 SdrObject* mpObject; // TTTT could be reference (?)
85 SdrModel* mpModel; // TTTT probably not needed -> use SdrModel from SdrObject (?)
86 std::unique_ptr<SdrOutliner> mpOutliner;
87 std::unique_ptr<SvxOutlinerForwarder> mpTextForwarder;
88 std::unique_ptr<SvxDrawOutlinerViewForwarder> mpViewForwarder; // if non-NULL, use GetViewModeTextForwarder text forwarder
89 css::uno::Reference< css::linguistic2::XLinguServiceManager2 > m_xLinguServiceManager;
95 bool mbForwarderIsEditMode; // have to reflect that, since ENDEDIT can happen more often
96 bool mbShapeIsEditMode; // only true, if SdrHintKind::BeginEdit was received
97 bool mbNotificationsDisabled; // prevent EditEngine/Outliner notifications (e.g. when setting up forwarder)
99
101
104 std::unique_ptr<SvxDrawOutlinerViewForwarder> CreateViewForwarder();
105
106 void SetupOutliner();
107
108 bool HasView() const { return mpView != nullptr; }
109 bool IsEditMode() const
110 {
112 return false;
114 return pTextObj && pTextObj->IsTextEditActive();
115 }
116
117 void dispose();
118
119public:
120 SvxTextEditSourceImpl( SdrObject* pObject, SdrText* pText );
121 SvxTextEditSourceImpl( SdrObject& rObject, SdrText* pText, SdrView& rView, const OutputDevice& rWindow );
122 virtual ~SvxTextEditSourceImpl() override;
123
124 void acquire();
125 void release();
126
127 virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) override;
128
131 void UpdateData();
132
133 void addRange( SvxUnoTextRangeBase* pNewRange );
134 void removeRange( SvxUnoTextRangeBase* pOldRange );
136
137 void lock();
138 void unlock();
139
140 bool IsValid() const;
141
142 Point LogicToPixel( const Point&, const MapMode& rMapMode );
143 Point PixelToLogic( const Point&, const MapMode& rMapMode );
144
145 DECL_LINK( NotifyHdl, EENotify&, void );
146
147 virtual void ObjectInDestruction(const SdrObject& rObject) override;
148
149 void UpdateOutliner();
150};
151
152
154 : maRefCount ( 0 ),
155 mpObject ( pObject ),
156 mpText ( pText ),
157 mpView ( nullptr ),
158 mpWindow ( nullptr ),
159 mpModel ( pObject ? &pObject->getSdrModelFromSdrObject() : nullptr ), // TTTT should be reference
160 mbDataValid ( false ),
161 mbIsLocked ( false ),
162 mbNeedsUpdate ( false ),
163 mbOldUndoMode ( false ),
164 mbForwarderIsEditMode ( false ),
165 mbShapeIsEditMode ( false ),
166 mbNotificationsDisabled ( false ),
167 mbNotifyEditOutlinerSet ( false )
168{
169 DBG_ASSERT( mpObject, "invalid pObject!" );
170
171 if( !mpText )
172 {
174 if( pTextObj )
175 mpText = pTextObj->getText( 0 );
176 }
177
178 if( mpModel )
180
181 if( mpObject )
182 mpObject->AddObjectUser( *this );
183}
184
185
187 : maRefCount ( 0 ),
188 mpObject ( &rObject ),
189 mpText ( pText ),
190 mpView ( &rView ),
191 mpWindow ( &rWindow ),
192 mpModel ( &rObject.getSdrModelFromSdrObject() ), // TTTT should be reference
193 mbDataValid ( false ),
194 mbIsLocked ( false ),
195 mbNeedsUpdate ( false ),
196 mbOldUndoMode ( false ),
197 mbForwarderIsEditMode ( false ),
198 mbShapeIsEditMode ( true ),
199 mbNotificationsDisabled ( false ),
200 mbNotifyEditOutlinerSet ( false )
201{
202 if( !mpText )
203 {
205 if( pTextObj )
206 mpText = pTextObj->getText( 0 );
207 }
208
211 mpObject->AddObjectUser( *this );
212
213 // Init edit mode state from shape info (IsTextEditActive())
215}
216
217
219{
220 DBG_ASSERT( !mbIsLocked, "text edit source was not unlocked before dispose!" );
221 if( mpObject )
222 mpObject->RemoveObjectUser( *this );
223
224 dispose();
225}
226
227
228void SvxTextEditSourceImpl::addRange( SvxUnoTextRangeBase* pNewRange )
229{
230 if( pNewRange )
231 if( std::find( mvTextRanges.begin(), mvTextRanges.end(), pNewRange ) == mvTextRanges.end() )
232 mvTextRanges.push_back( pNewRange );
233}
234
235
236void SvxTextEditSourceImpl::removeRange( SvxUnoTextRangeBase* pOldRange )
237{
238 if( pOldRange )
239 mvTextRanges.erase( std::remove(mvTextRanges.begin(), mvTextRanges.end(), pOldRange), mvTextRanges.end() );
240}
241
242
244{
245 osl_atomic_increment( &maRefCount );
246}
247
248
250{
251 if( ! osl_atomic_decrement( &maRefCount ) )
252 delete this;
253}
254
256{
257 // #i105988 keep reference to this object
259
260 if (SfxHintId::Dying == rHint.GetId())
261 {
262 if (&rBC == mpView)
263 {
264 mpView = nullptr;
265 mpViewForwarder.reset();
266 }
267 }
268 else if (rHint.GetId() == SfxHintId::ThisIsAnSdrHint)
269 {
270 const SdrHint* pSdrHint = static_cast<const SdrHint*>(&rHint);
271 switch( pSdrHint->GetKind() )
272 {
274 {
275 mbDataValid = false; // Text has to be get again
276
277 if( HasView() )
278 {
279 // Update maTextOffset, object has changed
280 // Cannot call that here, since TakeTextRect() (called from there)
281 // changes outliner content.
282 // UpdateOutliner();
283
284 // Broadcast object changes, as they might change visible attributes
285 SvxViewChangedHint aHint;
286 Broadcast( aHint );
287 }
288 break;
289 }
290
292 if( mpObject == pSdrHint->GetObject() )
293 {
294 // Once SdrHintKind::BeginEdit is broadcast, each EditSource of
295 // AccessibleCell will handle it here and call below:
296 // mpView->GetTextEditOutliner()->SetNotifyHdl(), which
297 // will replace the Notifier for current editable cell. It
298 // is totally wrong. So add check here to avoid the
299 // incorrect replacement of notifier.
300
301 // Currently it only happens on the editsource of
302 // AccessibleCell
303 if (mpObject && mpText)
304 {
305 sdr::table::SdrTableObj* pTableObj = dynamic_cast< sdr::table::SdrTableObj* >( mpObject );
306 if(pTableObj)
307 {
308 const sdr::table::CellRef& xCell = pTableObj->getActiveCell();
309 if (xCell.is())
310 {
311 sdr::table::Cell* pCellObj = dynamic_cast< sdr::table::Cell* >( mpText );
312 if (pCellObj && xCell.get() != pCellObj)
313 break;
314 }
315 }
316 }
317 // invalidate old forwarder
319 {
320 mpTextForwarder.reset();
321 }
322
323 // register as listener - need to broadcast state change messages
325 {
328 }
329
330 // Only now we're really in edit mode
331 mbShapeIsEditMode = true;
332
333 Broadcast( *pSdrHint );
334 }
335 break;
336
338 if( mpObject == pSdrHint->GetObject() )
339 {
340 Broadcast( *pSdrHint );
341
342 // We're no longer in edit mode
343 mbShapeIsEditMode = false;
344
345 // remove as listener - outliner might outlive ourselves
347 {
350 }
351
352 // destroy view forwarder, OutlinerView no longer
353 // valid (no need for UpdateData(), it's been
354 // synched on SdrEndTextEdit)
355 mpViewForwarder.reset();
356
357 // Invalidate text forwarder, we might
358 // not be called again before entering edit mode a
359 // second time! Then, the old outliner might be
360 // invalid.
362 {
363 mbForwarderIsEditMode = false;
364 mpTextForwarder.reset();
365 }
366 }
367 break;
368
370 dispose();
371 break;
372 default:
373 break;
374 }
375 }
376 else if (rHint.GetId() == SfxHintId::SvxViewChanged)
377 {
378 const SvxViewChangedHint* pViewHint = static_cast<const SvxViewChangedHint*>(&rHint);
379 Broadcast( *pViewHint );
380 }
381}
382
383/* this is a callback from the attached SdrObject when it is actually deleted */
385{
386 mpObject = nullptr;
387 dispose();
388 Broadcast( SfxHint( SfxHintId::Dying ) );
389}
390
391/* unregister at all objects and set all references to 0 */
393{
394 mpTextForwarder.reset();
395 mpViewForwarder.reset();
396
397 if( mpOutliner )
398 {
399 if( mpModel )
400 {
401 mpModel->disposeOutliner( std::move(mpOutliner) );
402 }
403 else
404 {
405 mpOutliner.reset();
406 }
407 }
408
409 if( mpModel )
410 {
412 mpModel = nullptr;
413 }
414
415 if( mpView )
416 {
417 // remove as listener - outliner might outlive ourselves
419 {
422 }
424 mpView = nullptr;
425 }
426
427 if( mpObject )
428 {
429 mpObject->RemoveObjectUser( *this );
430 mpObject = nullptr;
431 }
432 mpWindow = nullptr;
433}
434
435
437{
438 // only for UAA edit source: setup outliner equivalently as in
439 // SdrTextObj::Paint(), such that formatting equals screen
440 // layout
441 if( !(mpObject && mpOutliner) )
442 return;
443
445 if( pTextObj )
446 {
447 tools::Rectangle aPaintRect;
448 tools::Rectangle aBoundRect( pTextObj->GetCurrentBoundRect() );
449 pTextObj->SetupOutlinerFormatting( *mpOutliner, aPaintRect );
450
451 // calc text offset from shape anchor
452 maTextOffset = aPaintRect.TopLeft() - aBoundRect.TopLeft();
453 }
454}
455
456
458{
459 // only for UAA edit source: update outliner equivalently as in
460 // SdrTextObj::Paint(), such that formatting equals screen
461 // layout
462 if( !(mpObject && mpOutliner) )
463 return;
464
466 if( pTextObj )
467 {
468 tools::Rectangle aPaintRect;
469 tools::Rectangle aBoundRect( pTextObj->GetCurrentBoundRect() );
470 pTextObj->UpdateOutlinerFormatting( *mpOutliner, aPaintRect );
471
472 // calc text offset from shape anchor
473 maTextOffset = aPaintRect.TopLeft() - aBoundRect.TopLeft();
474 }
475}
476
477
479{
480 bool bCreated = false;
481
482 // prevent EE/Outliner notifications during setup
484
485 if (!mpTextForwarder)
486 {
487 if( mpOutliner == nullptr )
488 {
490 OutlinerMode nOutlMode = OutlinerMode::TextObject;
491 if( pTextObj && pTextObj->IsTextFrame() && pTextObj->GetTextKind() == SdrObjKind::OutlineText )
492 nOutlMode = OutlinerMode::OutlineObject;
493
494 mpOutliner = mpModel->createOutliner( nOutlMode );
495
496 // Do the setup after outliner creation, would be useless otherwise
497 if( HasView() )
498 {
499 // Setup outliner _before_ filling it
501 }
502
503 mpOutliner->SetTextObjNoInit( pTextObj );
504 if( mbIsLocked )
505 {
506 const_cast<EditEngine*>(&(mpOutliner->GetEditEngine()))->SetUpdateLayout( false );
507 mbOldUndoMode = mpOutliner->GetEditEngine().IsUndoEnabled();
508 const_cast<EditEngine*>(&(mpOutliner->GetEditEngine()))->EnableUndo( false );
509 }
510
512 {
513 if ( !m_xLinguServiceManager.is() )
514 {
515 css::uno::Reference< css::uno::XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
516 m_xLinguServiceManager.set(css::linguistic2::LinguServiceManager::create(xContext));
517 }
518
519 css::uno::Reference< css::linguistic2::XHyphenator > xHyphenator = m_xLinguServiceManager->getHyphenator();
520 if( xHyphenator.is() )
521 mpOutliner->SetHyphenator( xHyphenator );
522 }
523 }
524
525
527 // delay listener subscription and UAA initialization until Outliner is fully setup
528 bCreated = true;
529
530 mbForwarderIsEditMode = false;
531 mbDataValid = false;
532 }
533
535 {
536 mpTextForwarder->flushCache();
537
538 std::optional<OutlinerParaObject> pOutlinerParaObject;
540 if( pTextObj && pTextObj->getActiveText() == mpText )
541 pOutlinerParaObject = pTextObj->CreateEditOutlinerParaObject(); // Get the OutlinerParaObject if text edit is active
542 bool bOwnParaObj(false);
543
544 if( pOutlinerParaObject )
545 bOwnParaObj = true; // text edit active
546 else if (mpText->GetOutlinerParaObject())
547 pOutlinerParaObject = *mpText->GetOutlinerParaObject();
548
549 if( pOutlinerParaObject && ( bOwnParaObj || !mpObject->IsEmptyPresObj() || mpObject->getSdrPageFromSdrObject()->IsMasterPage() ) )
550 {
551 mpOutliner->SetText( *pOutlinerParaObject );
552
553 // put text to object and set EmptyPresObj to FALSE
554 if (mpText && bOwnParaObj && mpObject->IsEmptyPresObj() && pTextObj && pTextObj->IsReallyEdited())
555 {
556 mpObject->SetEmptyPresObj( false );
557 static_cast< SdrTextObj* >( mpObject)->NbcSetOutlinerParaObjectForText( pOutlinerParaObject, mpText );
558
559 // #i103982# Here, due to mpObject->NbcSetOutlinerParaObjectForText, we LOSE ownership of the
560 // OPO, so do NOT delete it when leaving this method (!)
561 bOwnParaObj = false;
562 }
563 }
564 else
565 {
566 bool bVertical = pOutlinerParaObject && pOutlinerParaObject->IsEffectivelyVertical();
567
568 // set objects style sheet on empty outliner
570 if( pPool )
571 mpOutliner->SetStyleSheetPool( pPool );
572
574 if( pStyleSheet )
575 mpOutliner->SetStyleSheet( 0, pStyleSheet );
576
577 if( bVertical )
578 {
579 mpOutliner->SetVertical( pOutlinerParaObject->GetVertical());
580 mpOutliner->SetRotation( pOutlinerParaObject->GetRotation());
581 }
582 }
583
584 // maybe we have to set the border attributes
585 if (mpOutliner->GetParagraphCount()==1)
586 {
587 // if we only have one paragraph we check if it is empty
588 OUString aStr(mpOutliner->GetText(mpOutliner->GetParagraph(0)));
589
590 if (aStr.isEmpty())
591 {
592 // its empty, so we have to force the outliner to initialise itself
593 mpOutliner->SetText( "", mpOutliner->GetParagraph( 0 ) );
594
596 mpOutliner->SetStyleSheet( 0, mpObject->GetStyleSheet());
597 }
598 }
599
600 mbDataValid = true;
601 }
602
603 if( bCreated && mpOutliner && HasView() )
604 {
605 // register as listener - need to broadcast state change messages
606 // registration delayed until outliner is completely set up
607 mpOutliner->SetNotifyHdl( LINK(this, SvxTextEditSourceImpl, NotifyHdl) );
608 }
609
610 // prevent EE/Outliner notifications during setup
612
613 return mpTextForwarder.get();
614}
615
616
618{
619 if( !mpTextForwarder && HasView() )
620 {
621 SdrOutliner* pEditOutliner = mpView->GetTextEditOutliner();
622
623 if( pEditOutliner )
624 {
627 }
628 }
629
630 return mpTextForwarder.get();
631}
632
633
635{
636 if( mpObject == nullptr )
637 return nullptr;
638
639 if( mpModel == nullptr )
641
642 // distinguish the cases
643 // a) connected to view, maybe edit mode is active, can work directly on the EditOutliner
644 // b) background Outliner, reflect changes into ParaOutlinerObject (this is exactly the old UNO code)
645 if( HasView() )
646 {
648 {
649 // forwarder mismatch - create new
650 mpTextForwarder.reset();
651 }
652
653 if( IsEditMode() )
655 else
657 }
658 else
659 {
660 // tdf#123470 if the text edit mode of the shape is active, then we
661 // cannot trust a previously cached TextForwarder state as the text may
662 // be out of date, so force a refetch in that case, unless locked against
663 // changes
665 {
666 assert(!mbForwarderIsEditMode); // because without a view there is no other option except !mbForwarderIsEditMode
667 bool bTextEditActive = false;
669 // similar to the GetBackgroundTextForwarder check, see if the text edit is active
670 if (pTextObj && pTextObj->getActiveText() == mpText && pTextObj->CanCreateEditOutlinerParaObject())
671 bTextEditActive = true; // text edit active
672 if (bTextEditActive)
673 mbDataValid = false;
674 }
675
677 }
678}
679
680std::unique_ptr<SvxDrawOutlinerViewForwarder> SvxTextEditSourceImpl::CreateViewForwarder()
681{
683 {
684 // register as listener - need to broadcast state change messages
687
689 if( pTextObj )
690 {
691 tools::Rectangle aBoundRect( pTextObj->GetCurrentBoundRect() );
693
694 return std::unique_ptr<SvxDrawOutlinerViewForwarder>(new SvxDrawOutlinerViewForwarder( rOutlView, aBoundRect.TopLeft() ));
695 }
696 }
697
698 return nullptr;
699}
700
702{
703 if( mpObject == nullptr )
704 return nullptr;
705
706 if( mpModel == nullptr )
708
709 // shall we delete?
710 if( mpViewForwarder )
711 {
712 if( !IsEditMode() )
713 {
714 // destroy all forwarders (no need for UpdateData(),
715 // it's been synched on SdrEndTextEdit)
716 mpViewForwarder.reset();
717 }
718 }
719 // which to create? Directly in edit mode, create new, or none?
720 else if( mpView )
721 {
722 if( IsEditMode() )
723 {
724 // create new view forwarder
726 }
727 else if( bCreate )
728 {
729 // dispose old text forwarder
730 UpdateData();
731
732 mpTextForwarder.reset();
733
734 // enter edit mode
736
738 {
740 if (pTextObj && pTextObj->IsTextEditActive())
741 {
742 // create new view forwarder
744 }
745 else
746 {
747 // failure. Somehow, SdrBeginTextEdit did not set
748 // our SdrTextObj into edit mode
750 }
751 }
752 }
753 }
754
755 return mpViewForwarder.get();
756}
757
758
760{
761 // if we have a view and in edit mode, we're working with the
762 // DrawOutliner. Thus, all changes made on the text forwarder are
763 // reflected on the view and committed to the model on
764 // SdrEndTextEdit(). Thus, no need for explicit updates here.
765 if( HasView() && IsEditMode() )
766 return;
767
768 if( mbIsLocked )
769 {
770 mbNeedsUpdate = true;
771 }
772 else
773 {
774 if( mpOutliner && mpObject && mpText )
775 {
777 if( pTextObj )
778 {
779 if( (mpOutliner->GetParagraphCount() == 1 && mpOutliner->GetEditEngine().GetTextLen( 0 ) == 0 )
780 || (mpOutliner->GetParagraphCount() == 2 && mpOutliner->GetEditEngine().GetTextLen( 0 ) == 0
781 && mpOutliner->GetEditEngine().GetTextLen( 1 ) == 0) )
782 {
783 pTextObj->NbcSetOutlinerParaObjectForText( std::nullopt, mpText );
784 }
785 else
786 {
787 pTextObj->NbcSetOutlinerParaObjectForText( mpOutliner->CreateParaObject(), mpText );
788 }
789 }
790
791 if( mpObject->IsEmptyPresObj() )
793 }
794 }
795}
796
798{
799 // if this assert ever fires, we will need to make this a counter instead of a boolean
800 assert(!mbIsLocked && "cannot nest these loc() calls");
801 mbIsLocked = true;
802 if( mpOutliner )
803 {
804 const_cast<EditEngine*>(&(mpOutliner->GetEditEngine()))->SetUpdateLayout( false );
805 mbOldUndoMode = mpOutliner->GetEditEngine().IsUndoEnabled();
806 const_cast<EditEngine*>(&(mpOutliner->GetEditEngine()))->EnableUndo( false );
807 }
808}
809
811{
812 mbIsLocked = false;
813
814 if( mbNeedsUpdate )
815 {
816 UpdateData();
817 mbNeedsUpdate = false;
818 }
819
820 if( mpOutliner )
821 {
822 const_cast<EditEngine*>(&(mpOutliner->GetEditEngine()))->SetUpdateLayout( true );
823 const_cast<EditEngine*>(&(mpOutliner->GetEditEngine()))->EnableUndo( mbOldUndoMode );
824 }
825}
826
828{
829 return mpView && mpWindow;
830}
831
832Point SvxTextEditSourceImpl::LogicToPixel( const Point& rPoint, const MapMode& rMapMode )
833{
834 // The responsibilities of ViewForwarder happen to be
835 // somewhat mixed in this case. On the one hand, we need the
836 // different interface queries on the SvxEditSource interface,
837 // since we need both VisAreas. On the other hand, if an
838 // EditViewForwarder exists, maTextOffset does not remain static,
839 // but may change with every key press.
840 if( IsEditMode() )
841 {
842 SvxEditViewForwarder* pForwarder = GetEditViewForwarder(false);
843
844 if( pForwarder )
845 return pForwarder->LogicToPixel( rPoint, rMapMode );
846 }
847 else if( IsValid() && mpModel )
848 {
849 Point aPoint1( rPoint );
850 aPoint1.AdjustX(maTextOffset.X() );
851 aPoint1.AdjustY(maTextOffset.Y() );
852
853 Point aPoint2( OutputDevice::LogicToLogic( aPoint1, rMapMode,
855 MapMode aMapMode(mpWindow->GetMapMode());
856 aMapMode.SetOrigin(Point());
857 return mpWindow->LogicToPixel( aPoint2, aMapMode );
858 }
859
860 return Point();
861}
862
863Point SvxTextEditSourceImpl::PixelToLogic( const Point& rPoint, const MapMode& rMapMode )
864{
865 // The responsibilities of ViewForwarder happen to be
866 // somewhat mixed in this case. On the one hand, we need the
867 // different interface queries on the SvxEditSource interface,
868 // since we need both VisAreas. On the other hand, if an
869 // EditViewForwarder exists, maTextOffset does not remain static,
870 // but may change with every key press.
871 if( IsEditMode() )
872 {
873 SvxEditViewForwarder* pForwarder = GetEditViewForwarder(false);
874
875 if( pForwarder )
876 return pForwarder->PixelToLogic( rPoint, rMapMode );
877 }
878 else if( IsValid() && mpModel )
879 {
880 MapMode aMapMode(mpWindow->GetMapMode());
881 aMapMode.SetOrigin(Point());
882 Point aPoint1( mpWindow->PixelToLogic( rPoint, aMapMode ) );
883 Point aPoint2( OutputDevice::LogicToLogic( aPoint1,
885 rMapMode ) );
886 aPoint2.AdjustX( -(maTextOffset.X()) );
887 aPoint2.AdjustY( -(maTextOffset.Y()) );
888
889 return aPoint2;
890 }
891
892 return Point();
893}
894
895IMPL_LINK(SvxTextEditSourceImpl, NotifyHdl, EENotify&, rNotify, void)
896{
897 if( !mbNotificationsDisabled )
898 {
899 std::unique_ptr< SfxHint > aHint( SvxEditSourceHelper::EENotification2Hint( &rNotify) );
900
901 if (aHint)
902 Broadcast(*aHint);
903 }
904}
905
907{
908 mpImpl = new SvxTextEditSourceImpl( pObject, pText );
909}
910
911
913{
914 mpImpl = new SvxTextEditSourceImpl( rObj, pText, rView, rWindow );
915}
916
917
919{
920 mpImpl = pImpl;
921}
922
923
925{
926 ::SolarMutexGuard aGuard;
927 mpImpl.clear();
928}
929
930
931std::unique_ptr<SvxEditSource> SvxTextEditSource::Clone() const
932{
933 return std::unique_ptr<SvxEditSource>(new SvxTextEditSource( mpImpl.get() ));
934}
935
936
938{
939 return mpImpl->GetTextForwarder();
940}
941
942
944{
945 return mpImpl->GetEditViewForwarder( bCreate );
946}
947
948
950{
951 return this;
952}
953
954
956{
957 mpImpl->UpdateData();
958}
959
961{
962 return *mpImpl;
963}
964
966{
967 mpImpl->lock();
968}
969
971{
972 mpImpl->unlock();
973}
974
976{
977 return mpImpl->IsValid();
978}
979
980Point SvxTextEditSource::LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const
981{
982 return mpImpl->LogicToPixel( rPoint, rMapMode );
983}
984
985Point SvxTextEditSource::PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const
986{
987 return mpImpl->PixelToLogic( rPoint, rMapMode );
988}
989
990void SvxTextEditSource::addRange( SvxUnoTextRangeBase* pNewRange )
991{
992 mpImpl->addRange( pNewRange );
993}
994
995void SvxTextEditSource::removeRange( SvxUnoTextRangeBase* pOldRange )
996{
997 mpImpl->removeRange( pOldRange );
998}
999
1001{
1002 return mpImpl->getRanges();
1003}
1004
1006{
1007 mpImpl->UpdateOutliner();
1008}
1009
1010/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SbxObjectRef mpObject
bool SetUpdateLayout(bool bUpdate, bool bRestoring=false)
void EnableUndo(bool bEnable)
void SetOrigin(const Point &rOrigin)
bool GetVertical() const
bool IsEffectivelyVertical() const
TextRotation GetRotation() const
void SetNotifyHdl(const Link< EENotify &, void > &rLink)
SAL_WARN_UNUSED_RESULT Point LogicToLogic(const Point &rPtSource, const MapMode *pMapModeSource, const MapMode *pMapModeDest) const
SdrHintKind GetKind() const
Definition: svdmodel.hxx:132
const SdrObject * GetObject() const
Definition: svdmodel.hxx:131
std::unique_ptr< SdrOutliner > createOutliner(OutlinerMode nOutlinerMode)
Definition: svdmodel.cxx:1741
MapUnit GetScaleUnit() const
Definition: svdmodel.hxx:371
SfxStyleSheetBasePool * GetStyleSheetPool() const
Definition: svdmodel.hxx:542
void disposeOutliner(std::unique_ptr< SdrOutliner > pOutliner)
Definition: svdmodel.cxx:1758
virtual SdrEndTextEditKind SdrEndTextEdit(bool bDontDeleteReally=false)
Definition: svdedxv.cxx:1570
const OutlinerView * GetTextEditOutlinerView() const
Definition: svdedxv.hxx:252
virtual bool SdrBeginTextEdit(SdrObject *pObj, SdrPageView *pPV=nullptr, vcl::Window *pWin=nullptr, bool bIsNewObj=false, SdrOutliner *pGivenOutliner=nullptr, OutlinerView *pGivenOutlinerView=nullptr, bool bDontDeleteOutliner=false, bool bOnlyOneView=false, bool bGrabFocus=true)
Definition: svdedxv.cxx:1223
const SdrOutliner * GetTextEditOutliner() const
Definition: svdedxv.hxx:244
Abstract DrawObject.
Definition: svdobj.hxx:261
void SetEmptyPresObj(bool bEpt)
Definition: svdobj.cxx:2571
virtual SdrInventor GetObjInventor() const
Definition: svdobj.cxx:621
bool IsEmptyPresObj() const
Definition: svdobj.hxx:840
virtual const tools::Rectangle & GetCurrentBoundRect() const
Definition: svdobj.cxx:926
SdrModel & getSdrModelFromSdrObject() const
Definition: svdobj.cxx:289
SfxStyleSheet * GetStyleSheet() const
Definition: svdobj.cxx:2247
void AddObjectUser(sdr::ObjectUser &rNewUser)
Definition: svdobj.cxx:238
virtual SdrObjKind GetObjIdentifier() const
Definition: svdobj.cxx:626
SdrPage * getSdrPageFromSdrObject() const
Definition: svdobj.cxx:279
bool IsInserted() const
Definition: svdobj.hxx:750
void RemoveObjectUser(sdr::ObjectUser &rOldUser)
Definition: svdobj.cxx:243
bool IsMasterPage() const
Definition: svdpage.hxx:462
virtual SfxStyleSheet * GetTextStyleSheetForObject(SdrObject *pObj) const
Definition: svdpage.cxx:1795
void UpdateOutlinerFormatting(SdrOutliner &rOutl, tools::Rectangle &rPaintRect) const
Update given Outliner equivalently to SdrTextObj::Paint()
Definition: svdotext.cxx:1320
bool IsTextEditActive() const
Definition: svdotext.hxx:352
bool CanCreateEditOutlinerParaObject() const
Definition: svdotext.cxx:847
virtual SdrText * getActiveText() const
returns the currently active text.
Definition: svdotext.cxx:2079
void NbcSetOutlinerParaObjectForText(std::optional< OutlinerParaObject > pTextObject, SdrText *pText)
Definition: svdotext.cxx:1367
virtual bool IsReallyEdited() const
returns true only if we are in edit mode and the user actually changed anything
Definition: svdotext.cxx:1701
std::optional< OutlinerParaObject > CreateEditOutlinerParaObject() const
Definition: svdotext.cxx:856
SdrObjKind GetTextKind() const
Definition: svdotext.hxx:347
bool IsTextFrame() const
Definition: svdotext.hxx:332
virtual SdrText * getText(sal_Int32 nIndex) const override
returns the nth available text.
Definition: svdotext.cxx:2088
void SetupOutlinerFormatting(SdrOutliner &rOutl, tools::Rectangle &rPaintRect) const
Setup given Outliner equivalently to SdrTextObj::Paint()
Definition: svdotext.cxx:1314
OutlinerParaObject * GetOutlinerParaObject()
Definition: svdtext.cxx:88
void Broadcast(const SfxHint &rHint)
SfxHintId GetId() const
void StartListening(SfxBroadcaster &rBroadcaster, DuplicateHandling eDuplicateHanding=DuplicateHandling::Unexpected)
void EndListening(SfxBroadcaster &rBroadcaster, bool bRemoveAllDuplicates=false)
static ::std::unique_ptr< SfxHint > EENotification2Hint(EENotify const *aNotify)
virtual ~SvxTextEditSourceImpl() override
Definition: unoshtxt.cxx:218
SdrObject * mpObject
Definition: unoshtxt.cxx:81
oslInterlockedCount maRefCount
Definition: unoshtxt.cxx:79
SvxEditViewForwarder * GetEditViewForwarder(bool)
Definition: unoshtxt.cxx:701
SvxTextForwarder * GetTextForwarder()
Definition: unoshtxt.cxx:634
virtual void ObjectInDestruction(const SdrObject &rObject) override
Definition: unoshtxt.cxx:384
DECL_LINK(NotifyHdl, EENotify &, void)
void removeRange(SvxUnoTextRangeBase *pOldRange)
Definition: unoshtxt.cxx:236
virtual void Notify(SfxBroadcaster &rBC, const SfxHint &rHint) override
Definition: unoshtxt.cxx:255
SvxTextEditSourceImpl(SdrObject *pObject, SdrText *pText)
Definition: unoshtxt.cxx:153
std::unique_ptr< SvxDrawOutlinerViewForwarder > mpViewForwarder
Definition: unoshtxt.cxx:88
SvxTextForwarder * GetEditModeTextForwarder()
Definition: unoshtxt.cxx:617
bool IsEditMode() const
Definition: unoshtxt.cxx:109
SvxUnoTextRangeBaseVec mvTextRanges
Definition: unoshtxt.cxx:100
std::unique_ptr< SdrOutliner > mpOutliner
Definition: unoshtxt.cxx:86
std::unique_ptr< SvxOutlinerForwarder > mpTextForwarder
Definition: unoshtxt.cxx:87
void addRange(SvxUnoTextRangeBase *pNewRange)
Definition: unoshtxt.cxx:228
SdrModel * mpModel
Definition: unoshtxt.cxx:85
VclPtr< const OutputDevice > mpWindow
Definition: unoshtxt.cxx:84
Point PixelToLogic(const Point &, const MapMode &rMapMode)
Definition: unoshtxt.cxx:863
Point LogicToPixel(const Point &, const MapMode &rMapMode)
Definition: unoshtxt.cxx:832
bool IsValid() const
Definition: unoshtxt.cxx:827
bool HasView() const
Definition: unoshtxt.cxx:108
const SvxUnoTextRangeBaseVec & getRanges() const
Definition: unoshtxt.cxx:135
css::uno::Reference< css::linguistic2::XLinguServiceManager2 > m_xLinguServiceManager
Definition: unoshtxt.cxx:89
SvxTextForwarder * GetBackgroundTextForwarder()
Definition: unoshtxt.cxx:478
std::unique_ptr< SvxDrawOutlinerViewForwarder > CreateViewForwarder()
Definition: unoshtxt.cxx:680
virtual SvxTextForwarder * GetTextForwarder() override
Definition: unoshtxt.cxx:937
virtual SvxViewForwarder * GetViewForwarder() override
Definition: unoshtxt.cxx:949
virtual void removeRange(SvxUnoTextRangeBase *pOldRange) override
Definition: unoshtxt.cxx:995
virtual Point PixelToLogic(const Point &, const MapMode &) const override
Definition: unoshtxt.cxx:985
virtual std::unique_ptr< SvxEditSource > Clone() const override
Definition: unoshtxt.cxx:931
virtual ~SvxTextEditSource() override
Definition: unoshtxt.cxx:924
virtual SfxBroadcaster & GetBroadcaster() const override
Definition: unoshtxt.cxx:960
SvxTextEditSource(SdrObject *pObj, SdrText *pText)
Definition: unoshtxt.cxx:906
virtual const SvxUnoTextRangeBaseVec & getRanges() const override
Definition: unoshtxt.cxx:1000
virtual void UpdateData() override
Definition: unoshtxt.cxx:955
virtual SvxEditViewForwarder * GetEditViewForwarder(bool bCreate=false) override
Definition: unoshtxt.cxx:943
virtual Point LogicToPixel(const Point &, const MapMode &) const override
Definition: unoshtxt.cxx:980
virtual void addRange(SvxUnoTextRangeBase *pNewRange) override
Definition: unoshtxt.cxx:990
virtual bool IsValid() const override
Definition: unoshtxt.cxx:975
rtl::Reference< SvxTextEditSourceImpl > mpImpl
Definition: unoshtxt.hxx:84
virtual Point LogicToPixel(const Point &rPoint, const MapMode &rMapMode) const=0
virtual Point PixelToLogic(const Point &rPoint, const MapMode &rMapMode) const=0
const sdr::table::CellRef & getActiveCell() const
The active table has the focus or is currently edited.
Definition: svdotable.cxx:1534
constexpr Point TopLeft() const
static bool IsFuzzing()
#define DBG_ASSERT(sCon, aError)
EmbeddedObjectRef * pObject
aStr
OutlinerMode
UnoViewSharedPtr mpView
SdrTextObj * DynCastSdrTextObj(SdrObject *pObj)
Definition: svdobj.cxx:3217
@ OutlineText
TitleText, special text object for StarDraw.
std::vector< SvxUnoTextRangeBase * > SvxUnoTextRangeBaseVec
IMPL_LINK(SvxTextEditSourceImpl, NotifyHdl, EENotify &, rNotify, void)
Definition: unoshtxt.cxx:895
VclPtr< vcl::Window > mpWindow