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;
113 SdrTextObj* pTextObj = dynamic_cast<SdrTextObj*>( mpObject );
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 {
173 SdrTextObj* pTextObj = dynamic_cast< SdrTextObj* >( mpObject );
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 {
204 SdrTextObj* pTextObj = dynamic_cast< SdrTextObj* >( mpObject );
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
229{
230 if( pNewRange )
231 if( std::find( mvTextRanges.begin(), mvTextRanges.end(), pNewRange ) == mvTextRanges.end() )
232 mvTextRanges.push_back( pNewRange );
233}
234
235
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 (const SvxViewChangedHint* pViewHint = dynamic_cast<const SvxViewChangedHint*>(&rHint))
377 {
378 Broadcast( *pViewHint );
379 }
380}
381
382/* this is a callback from the attached SdrObject when it is actually deleted */
384{
385 mpObject = nullptr;
386 dispose();
387 Broadcast( SfxHint( SfxHintId::Dying ) );
388}
389
390/* unregister at all objects and set all references to 0 */
392{
393 mpTextForwarder.reset();
394 mpViewForwarder.reset();
395
396 if( mpOutliner )
397 {
398 if( mpModel )
399 {
400 mpModel->disposeOutliner( std::move(mpOutliner) );
401 }
402 else
403 {
404 mpOutliner.reset();
405 }
406 }
407
408 if( mpModel )
409 {
411 mpModel = nullptr;
412 }
413
414 if( mpView )
415 {
416 // remove as listener - outliner might outlive ourselves
418 {
421 }
423 mpView = nullptr;
424 }
425
426 if( mpObject )
427 {
428 mpObject->RemoveObjectUser( *this );
429 mpObject = nullptr;
430 }
431 mpWindow = nullptr;
432}
433
434
436{
437 // only for UAA edit source: setup outliner equivalently as in
438 // SdrTextObj::Paint(), such that formatting equals screen
439 // layout
440 if( !(mpObject && mpOutliner) )
441 return;
442
443 SdrTextObj* pTextObj = dynamic_cast<SdrTextObj*>( mpObject );
444 if( pTextObj )
445 {
446 tools::Rectangle aPaintRect;
447 tools::Rectangle aBoundRect( pTextObj->GetCurrentBoundRect() );
448 pTextObj->SetupOutlinerFormatting( *mpOutliner, aPaintRect );
449
450 // calc text offset from shape anchor
451 maTextOffset = aPaintRect.TopLeft() - aBoundRect.TopLeft();
452 }
453}
454
455
457{
458 // only for UAA edit source: update outliner equivalently as in
459 // SdrTextObj::Paint(), such that formatting equals screen
460 // layout
461 if( !(mpObject && mpOutliner) )
462 return;
463
464 SdrTextObj* pTextObj = dynamic_cast<SdrTextObj*>( mpObject );
465 if( pTextObj )
466 {
467 tools::Rectangle aPaintRect;
468 tools::Rectangle aBoundRect( pTextObj->GetCurrentBoundRect() );
469 pTextObj->UpdateOutlinerFormatting( *mpOutliner, aPaintRect );
470
471 // calc text offset from shape anchor
472 maTextOffset = aPaintRect.TopLeft() - aBoundRect.TopLeft();
473 }
474}
475
476
478{
479 bool bCreated = false;
480
481 // prevent EE/Outliner notifications during setup
483
484 if (!mpTextForwarder)
485 {
486 if( mpOutliner == nullptr )
487 {
488 SdrTextObj* pTextObj = dynamic_cast<SdrTextObj*>( mpObject );
489 OutlinerMode nOutlMode = OutlinerMode::TextObject;
490 if( pTextObj && pTextObj->IsTextFrame() && pTextObj->GetTextKind() == SdrObjKind::OutlineText )
491 nOutlMode = OutlinerMode::OutlineObject;
492
493 mpOutliner = mpModel->createOutliner( nOutlMode );
494
495 // Do the setup after outliner creation, would be useless otherwise
496 if( HasView() )
497 {
498 // Setup outliner _before_ filling it
500 }
501
502 mpOutliner->SetTextObjNoInit( pTextObj );
503 if( mbIsLocked )
504 {
505 const_cast<EditEngine*>(&(mpOutliner->GetEditEngine()))->SetUpdateLayout( false );
506 mbOldUndoMode = mpOutliner->GetEditEngine().IsUndoEnabled();
507 const_cast<EditEngine*>(&(mpOutliner->GetEditEngine()))->EnableUndo( false );
508 }
509
511 {
512 if ( !m_xLinguServiceManager.is() )
513 {
514 css::uno::Reference< css::uno::XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
515 m_xLinguServiceManager.set(css::linguistic2::LinguServiceManager::create(xContext));
516 }
517
518 css::uno::Reference< css::linguistic2::XHyphenator > xHyphenator = m_xLinguServiceManager->getHyphenator();
519 if( xHyphenator.is() )
520 mpOutliner->SetHyphenator( xHyphenator );
521 }
522 }
523
524
526 // delay listener subscription and UAA initialization until Outliner is fully setup
527 bCreated = true;
528
529 mbForwarderIsEditMode = false;
530 mbDataValid = false;
531 }
532
534 {
535 mpTextForwarder->flushCache();
536
537 std::optional<OutlinerParaObject> pOutlinerParaObject;
538 SdrTextObj* pTextObj = dynamic_cast<SdrTextObj*>( mpObject );
539 if( pTextObj && pTextObj->getActiveText() == mpText )
540 pOutlinerParaObject = pTextObj->CreateEditOutlinerParaObject(); // Get the OutlinerParaObject if text edit is active
541 bool bOwnParaObj(false);
542
543 if( pOutlinerParaObject )
544 bOwnParaObj = true; // text edit active
545 else if (mpText->GetOutlinerParaObject())
546 pOutlinerParaObject = *mpText->GetOutlinerParaObject();
547
548 if( pOutlinerParaObject && ( bOwnParaObj || !mpObject->IsEmptyPresObj() || mpObject->getSdrPageFromSdrObject()->IsMasterPage() ) )
549 {
550 mpOutliner->SetText( *pOutlinerParaObject );
551
552 // put text to object and set EmptyPresObj to FALSE
553 if( mpText && bOwnParaObj && mpObject->IsEmptyPresObj() && pTextObj->IsReallyEdited() )
554 {
555 mpObject->SetEmptyPresObj( false );
556 static_cast< SdrTextObj* >( mpObject)->NbcSetOutlinerParaObjectForText( pOutlinerParaObject, mpText );
557
558 // #i103982# Here, due to mpObject->NbcSetOutlinerParaObjectForText, we LOSE ownership of the
559 // OPO, so do NOT delete it when leaving this method (!)
560 bOwnParaObj = false;
561 }
562 }
563 else
564 {
565 bool bVertical = pOutlinerParaObject && pOutlinerParaObject->IsEffectivelyVertical();
566
567 // set objects style sheet on empty outliner
569 if( pPool )
570 mpOutliner->SetStyleSheetPool( pPool );
571
573 if( pStyleSheet )
574 mpOutliner->SetStyleSheet( 0, pStyleSheet );
575
576 if( bVertical )
577 {
578 mpOutliner->SetVertical( pOutlinerParaObject->GetVertical());
579 mpOutliner->SetRotation( pOutlinerParaObject->GetRotation());
580 }
581 }
582
583 // maybe we have to set the border attributes
584 if (mpOutliner->GetParagraphCount()==1)
585 {
586 // if we only have one paragraph we check if it is empty
587 OUString aStr(mpOutliner->GetText(mpOutliner->GetParagraph(0)));
588
589 if (aStr.isEmpty())
590 {
591 // its empty, so we have to force the outliner to initialise itself
592 mpOutliner->SetText( "", mpOutliner->GetParagraph( 0 ) );
593
595 mpOutliner->SetStyleSheet( 0, mpObject->GetStyleSheet());
596 }
597 }
598
599 mbDataValid = true;
600 }
601
602 if( bCreated && mpOutliner && HasView() )
603 {
604 // register as listener - need to broadcast state change messages
605 // registration delayed until outliner is completely set up
606 mpOutliner->SetNotifyHdl( LINK(this, SvxTextEditSourceImpl, NotifyHdl) );
607 }
608
609 // prevent EE/Outliner notifications during setup
611
612 return mpTextForwarder.get();
613}
614
615
617{
618 if( !mpTextForwarder && HasView() )
619 {
620 SdrOutliner* pEditOutliner = mpView->GetTextEditOutliner();
621
622 if( pEditOutliner )
623 {
626 }
627 }
628
629 return mpTextForwarder.get();
630}
631
632
634{
635 if( mpObject == nullptr )
636 return nullptr;
637
638 if( mpModel == nullptr )
640
641 // distinguish the cases
642 // a) connected to view, maybe edit mode is active, can work directly on the EditOutliner
643 // b) background Outliner, reflect changes into ParaOutlinerObject (this is exactly the old UNO code)
644 if( HasView() )
645 {
647 {
648 // forwarder mismatch - create new
649 mpTextForwarder.reset();
650 }
651
652 if( IsEditMode() )
654 else
656 }
657 else
658 {
659 // tdf#123470 if the text edit mode of the shape is active, then we
660 // cannot trust a previously cached TextForwarder state as the text may
661 // be out of date, so force a refetch in that case, unless locked against
662 // changes
664 {
665 assert(!mbForwarderIsEditMode); // because without a view there is no other option except !mbForwarderIsEditMode
666 bool bTextEditActive = false;
667 SdrTextObj* pTextObj = dynamic_cast<SdrTextObj*>(mpObject);
668 // similar to the GetBackgroundTextForwarder check, see if the text edit is active
669 if (pTextObj && pTextObj->getActiveText() == mpText && pTextObj->CanCreateEditOutlinerParaObject())
670 bTextEditActive = true; // text edit active
671 if (bTextEditActive)
672 mbDataValid = false;
673 }
674
676 }
677}
678
679std::unique_ptr<SvxDrawOutlinerViewForwarder> SvxTextEditSourceImpl::CreateViewForwarder()
680{
682 {
683 // register as listener - need to broadcast state change messages
686
687 SdrTextObj* pTextObj = dynamic_cast<SdrTextObj*>( mpObject );
688 if( pTextObj )
689 {
690 tools::Rectangle aBoundRect( pTextObj->GetCurrentBoundRect() );
692
693 return std::unique_ptr<SvxDrawOutlinerViewForwarder>(new SvxDrawOutlinerViewForwarder( rOutlView, aBoundRect.TopLeft() ));
694 }
695 }
696
697 return nullptr;
698}
699
701{
702 if( mpObject == nullptr )
703 return nullptr;
704
705 if( mpModel == nullptr )
707
708 // shall we delete?
709 if( mpViewForwarder )
710 {
711 if( !IsEditMode() )
712 {
713 // destroy all forwarders (no need for UpdateData(),
714 // it's been synched on SdrEndTextEdit)
715 mpViewForwarder.reset();
716 }
717 }
718 // which to create? Directly in edit mode, create new, or none?
719 else if( mpView )
720 {
721 if( IsEditMode() )
722 {
723 // create new view forwarder
725 }
726 else if( bCreate )
727 {
728 // dispose old text forwarder
729 UpdateData();
730
731 mpTextForwarder.reset();
732
733 // enter edit mode
735
737 {
738 SdrTextObj* pTextObj = dynamic_cast<SdrTextObj*>( mpObject );
739 if (pTextObj && pTextObj->IsTextEditActive())
740 {
741 // create new view forwarder
743 }
744 else
745 {
746 // failure. Somehow, SdrBeginTextEdit did not set
747 // our SdrTextObj into edit mode
749 }
750 }
751 }
752 }
753
754 return mpViewForwarder.get();
755}
756
757
759{
760 // if we have a view and in edit mode, we're working with the
761 // DrawOutliner. Thus, all changes made on the text forwarder are
762 // reflected on the view and committed to the model on
763 // SdrEndTextEdit(). Thus, no need for explicit updates here.
764 if( HasView() && IsEditMode() )
765 return;
766
767 if( mbIsLocked )
768 {
769 mbNeedsUpdate = true;
770 }
771 else
772 {
773 if( mpOutliner && mpObject && mpText )
774 {
775 SdrTextObj* pTextObj = dynamic_cast< SdrTextObj* >( mpObject );
776 if( pTextObj )
777 {
778 if( (mpOutliner->GetParagraphCount() == 1 && mpOutliner->GetEditEngine().GetTextLen( 0 ) == 0 )
779 || (mpOutliner->GetParagraphCount() == 2 && mpOutliner->GetEditEngine().GetTextLen( 0 ) == 0
780 && mpOutliner->GetEditEngine().GetTextLen( 1 ) == 0) )
781 {
782 pTextObj->NbcSetOutlinerParaObjectForText( std::nullopt, mpText );
783 }
784 else
785 {
786 pTextObj->NbcSetOutlinerParaObjectForText( mpOutliner->CreateParaObject(), mpText );
787 }
788 }
789
790 if( mpObject->IsEmptyPresObj() )
792 }
793 }
794}
795
797{
798 // if this assert ever fires, we will need to make this a counter instead of a boolean
799 assert(!mbIsLocked && "cannot nest these loc() calls");
800 mbIsLocked = true;
801 if( mpOutliner )
802 {
803 const_cast<EditEngine*>(&(mpOutliner->GetEditEngine()))->SetUpdateLayout( false );
804 mbOldUndoMode = mpOutliner->GetEditEngine().IsUndoEnabled();
805 const_cast<EditEngine*>(&(mpOutliner->GetEditEngine()))->EnableUndo( false );
806 }
807}
808
810{
811 mbIsLocked = false;
812
813 if( mbNeedsUpdate )
814 {
815 UpdateData();
816 mbNeedsUpdate = false;
817 }
818
819 if( mpOutliner )
820 {
821 const_cast<EditEngine*>(&(mpOutliner->GetEditEngine()))->SetUpdateLayout( true );
822 const_cast<EditEngine*>(&(mpOutliner->GetEditEngine()))->EnableUndo( mbOldUndoMode );
823 }
824}
825
827{
828 return mpView && mpWindow;
829}
830
831Point SvxTextEditSourceImpl::LogicToPixel( const Point& rPoint, const MapMode& rMapMode )
832{
833 // The responsibilities of ViewForwarder happen to be
834 // somewhat mixed in this case. On the one hand, we need the
835 // different interface queries on the SvxEditSource interface,
836 // since we need both VisAreas. On the other hand, if an
837 // EditViewForwarder exists, maTextOffset does not remain static,
838 // but may change with every key press.
839 if( IsEditMode() )
840 {
841 SvxEditViewForwarder* pForwarder = GetEditViewForwarder(false);
842
843 if( pForwarder )
844 return pForwarder->LogicToPixel( rPoint, rMapMode );
845 }
846 else if( IsValid() && mpModel )
847 {
848 Point aPoint1( rPoint );
849 aPoint1.AdjustX(maTextOffset.X() );
850 aPoint1.AdjustY(maTextOffset.Y() );
851
852 Point aPoint2( OutputDevice::LogicToLogic( aPoint1, rMapMode,
854 MapMode aMapMode(mpWindow->GetMapMode());
855 aMapMode.SetOrigin(Point());
856 return mpWindow->LogicToPixel( aPoint2, aMapMode );
857 }
858
859 return Point();
860}
861
862Point SvxTextEditSourceImpl::PixelToLogic( const Point& rPoint, const MapMode& rMapMode )
863{
864 // The responsibilities of ViewForwarder happen to be
865 // somewhat mixed in this case. On the one hand, we need the
866 // different interface queries on the SvxEditSource interface,
867 // since we need both VisAreas. On the other hand, if an
868 // EditViewForwarder exists, maTextOffset does not remain static,
869 // but may change with every key press.
870 if( IsEditMode() )
871 {
872 SvxEditViewForwarder* pForwarder = GetEditViewForwarder(false);
873
874 if( pForwarder )
875 return pForwarder->PixelToLogic( rPoint, rMapMode );
876 }
877 else if( IsValid() && mpModel )
878 {
879 MapMode aMapMode(mpWindow->GetMapMode());
880 aMapMode.SetOrigin(Point());
881 Point aPoint1( mpWindow->PixelToLogic( rPoint, aMapMode ) );
882 Point aPoint2( OutputDevice::LogicToLogic( aPoint1,
884 rMapMode ) );
885 aPoint2.AdjustX( -(maTextOffset.X()) );
886 aPoint2.AdjustY( -(maTextOffset.Y()) );
887
888 return aPoint2;
889 }
890
891 return Point();
892}
893
894IMPL_LINK(SvxTextEditSourceImpl, NotifyHdl, EENotify&, rNotify, void)
895{
896 if( !mbNotificationsDisabled )
897 {
898 std::unique_ptr< SfxHint > aHint( SvxEditSourceHelper::EENotification2Hint( &rNotify) );
899
900 if (aHint)
901 Broadcast(*aHint);
902 }
903}
904
906{
907 mpImpl = new SvxTextEditSourceImpl( pObject, pText );
908}
909
910
912{
913 mpImpl = new SvxTextEditSourceImpl( rObj, pText, rView, rWindow );
914}
915
916
918{
919 mpImpl = pImpl;
920}
921
922
924{
925 ::SolarMutexGuard aGuard;
926 mpImpl.clear();
927}
928
929
930std::unique_ptr<SvxEditSource> SvxTextEditSource::Clone() const
931{
932 return std::unique_ptr<SvxEditSource>(new SvxTextEditSource( mpImpl.get() ));
933}
934
935
937{
938 return mpImpl->GetTextForwarder();
939}
940
941
943{
944 return mpImpl->GetEditViewForwarder( bCreate );
945}
946
947
949{
950 return this;
951}
952
953
955{
956 mpImpl->UpdateData();
957}
958
960{
961 return *mpImpl;
962}
963
965{
966 mpImpl->lock();
967}
968
970{
971 mpImpl->unlock();
972}
973
975{
976 return mpImpl->IsValid();
977}
978
979Point SvxTextEditSource::LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const
980{
981 return mpImpl->LogicToPixel( rPoint, rMapMode );
982}
983
984Point SvxTextEditSource::PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const
985{
986 return mpImpl->PixelToLogic( rPoint, rMapMode );
987}
988
990{
991 mpImpl->addRange( pNewRange );
992}
993
995{
996 mpImpl->removeRange( pOldRange );
997}
998
1000{
1001 return mpImpl->getRanges();
1002}
1003
1005{
1006 mpImpl->UpdateOutliner();
1007}
1008
1009/* 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:1734
MapUnit GetScaleUnit() const
Definition: svdmodel.hxx:370
SfxStyleSheetBasePool * GetStyleSheetPool() const
Definition: svdmodel.hxx:541
void disposeOutliner(std::unique_ptr< SdrOutliner > pOutliner)
Definition: svdmodel.cxx:1751
virtual SdrEndTextEditKind SdrEndTextEdit(bool bDontDeleteReally=false)
Definition: svdedxv.cxx:1426
const OutlinerView * GetTextEditOutlinerView() const
Definition: svdedxv.hxx:251
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:1074
const SdrOutliner * GetTextEditOutliner() const
Definition: svdedxv.hxx:243
Abstract DrawObject.
Definition: svdobj.hxx:261
void SetEmptyPresObj(bool bEpt)
Definition: svdobj.cxx:2572
virtual SdrInventor GetObjInventor() const
Definition: svdobj.cxx:649
bool IsEmptyPresObj() const
Definition: svdobj.hxx:833
virtual const tools::Rectangle & GetCurrentBoundRect() const
Definition: svdobj.cxx:954
SdrModel & getSdrModelFromSdrObject() const
Definition: svdobj.cxx:284
SfxStyleSheet * GetStyleSheet() const
Definition: svdobj.cxx:2247
void AddObjectUser(sdr::ObjectUser &rNewUser)
Definition: svdobj.cxx:233
virtual SdrObjKind GetObjIdentifier() const
Definition: svdobj.cxx:654
SdrPage * getSdrPageFromSdrObject() const
Definition: svdobj.cxx:274
bool IsInserted() const
Definition: svdobj.hxx:745
void RemoveObjectUser(sdr::ObjectUser &rOldUser)
Definition: svdobj.cxx:238
bool IsMasterPage() const
Definition: svdpage.hxx:459
virtual SfxStyleSheet * GetTextStyleSheetForObject(SdrObject *pObj) const
Definition: svdpage.cxx:1778
void UpdateOutlinerFormatting(SdrOutliner &rOutl, tools::Rectangle &rPaintRect) const
Update given Outliner equivalently to SdrTextObj::Paint()
Definition: svdotext.cxx:1306
bool IsTextEditActive() const
Definition: svdotext.hxx:354
bool CanCreateEditOutlinerParaObject() const
Definition: svdotext.cxx:864
virtual SdrText * getActiveText() const
returns the currently active text.
Definition: svdotext.cxx:2065
void NbcSetOutlinerParaObjectForText(std::optional< OutlinerParaObject > pTextObject, SdrText *pText)
Definition: svdotext.cxx:1353
virtual bool IsReallyEdited() const
returns true only if we are in edit mode and the user actually changed anything
Definition: svdotext.cxx:1687
std::optional< OutlinerParaObject > CreateEditOutlinerParaObject() const
Definition: svdotext.cxx:873
SdrObjKind GetTextKind() const
Definition: svdotext.hxx:349
bool IsTextFrame() const
Definition: svdotext.hxx:334
virtual SdrText * getText(sal_Int32 nIndex) const override
returns the nth available text.
Definition: svdotext.cxx:2074
void SetupOutlinerFormatting(SdrOutliner &rOutl, tools::Rectangle &rPaintRect) const
Setup given Outliner equivalently to SdrTextObj::Paint()
Definition: svdotext.cxx:1300
OutlinerParaObject * GetOutlinerParaObject()
Definition: svdtext.cxx:89
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:700
SvxTextForwarder * GetTextForwarder()
Definition: unoshtxt.cxx:633
virtual void ObjectInDestruction(const SdrObject &rObject) override
Definition: unoshtxt.cxx:383
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:616
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:862
Point LogicToPixel(const Point &, const MapMode &rMapMode)
Definition: unoshtxt.cxx:831
bool IsValid() const
Definition: unoshtxt.cxx:826
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:477
std::unique_ptr< SvxDrawOutlinerViewForwarder > CreateViewForwarder()
Definition: unoshtxt.cxx:679
virtual SvxTextForwarder * GetTextForwarder() override
Definition: unoshtxt.cxx:936
virtual SvxViewForwarder * GetViewForwarder() override
Definition: unoshtxt.cxx:948
virtual void removeRange(SvxUnoTextRangeBase *pOldRange) override
Definition: unoshtxt.cxx:994
virtual Point PixelToLogic(const Point &, const MapMode &) const override
Definition: unoshtxt.cxx:984
virtual std::unique_ptr< SvxEditSource > Clone() const override
Definition: unoshtxt.cxx:930
virtual ~SvxTextEditSource() override
Definition: unoshtxt.cxx:923
virtual SfxBroadcaster & GetBroadcaster() const override
Definition: unoshtxt.cxx:959
SvxTextEditSource(SdrObject *pObj, SdrText *pText)
Definition: unoshtxt.cxx:905
virtual const SvxUnoTextRangeBaseVec & getRanges() const override
Definition: unoshtxt.cxx:999
virtual void UpdateData() override
Definition: unoshtxt.cxx:954
virtual SvxEditViewForwarder * GetEditViewForwarder(bool bCreate=false) override
Definition: unoshtxt.cxx:942
virtual Point LogicToPixel(const Point &, const MapMode &) const override
Definition: unoshtxt.cxx:979
virtual void addRange(SvxUnoTextRangeBase *pNewRange) override
Definition: unoshtxt.cxx:989
virtual bool IsValid() const override
Definition: unoshtxt.cxx:974
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:1570
constexpr Point TopLeft() const
static bool IsFuzzing()
#define DBG_ASSERT(sCon, aError)
EmbeddedObjectRef * pObject
aStr
OutlinerMode
UnoViewSharedPtr mpView
@ OutlineText
TitleText, special text object for StarDraw.
std::vector< SvxUnoTextRangeBase * > SvxUnoTextRangeBaseVec
IMPL_LINK(SvxTextEditSourceImpl, NotifyHdl, EENotify &, rNotify, void)
Definition: unoshtxt.cxx:894
VclPtr< vcl::Window > mpWindow