1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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>
24 #include <AccessibleText.hxx>
25 #include <AccessibleCell.hxx>
27 #include <tabvwsh.hxx>
28 #include <editutil.hxx>
29 #include <document.hxx>
31 #include <prevwsh.hxx>
33 #include <prevloc.hxx>
34 #include <patattr.hxx>
35 #include <inputwin.hxx>
36 #include <editeng/unofored.hxx>
37 #include <editeng/editview.hxx>
38 #include <editeng/unoedhlp.hxx>
39 #include <editeng/fhgtitem.hxx>
40 #include <editeng/adjustitem.hxx>
41 #include <editeng/justifyitem.hxx>
42 #include <svx/svdmodel.hxx>
43 #include <svx/algitem.hxx>
45 #include <vcl/svapp.hxx>
47 class ScViewForwarder
: public SvxViewForwarder
49 ScTabViewShell
* mpViewShell
;
50 ScSplitPos meSplitPos
;
52 ScViewForwarder(ScTabViewShell
* pViewShell
, ScSplitPos eSplitPos
);
54 virtual bool IsValid() const override
;
55 virtual Point
LogicToPixel( const Point
& rPoint
, const MapMode
& rMapMode
) const override
;
56 virtual Point
PixelToLogic( const Point
& rPoint
, const MapMode
& rMapMode
) const override
;
61 ScViewForwarder::ScViewForwarder(ScTabViewShell
* pViewShell
, ScSplitPos eSplitPos
)
63 mpViewShell(pViewShell
),
68 bool ScViewForwarder::IsValid() const
70 return mpViewShell
!= nullptr;
73 Point
ScViewForwarder::LogicToPixel( const Point
& rPoint
, const MapMode
& rMapMode
) const
77 vcl::Window
* pWindow
= mpViewShell
->GetWindowByPos(meSplitPos
);
79 return pWindow
->LogicToPixel( rPoint
, rMapMode
);
83 OSL_FAIL("this ViewForwarder is not valid");
88 Point
ScViewForwarder::PixelToLogic( const Point
& rPoint
, const MapMode
& rMapMode
) const
92 vcl::Window
* pWindow
= mpViewShell
->GetWindowByPos(meSplitPos
);
94 return pWindow
->PixelToLogic( rPoint
, rMapMode
);
98 OSL_FAIL("this ViewForwarder is not valid");
103 void ScViewForwarder::SetInvalid()
105 mpViewShell
= nullptr;
108 class ScEditObjectViewForwarder
: public SvxViewForwarder
110 VclPtr
<OutputDevice
> mpWindow
;
111 // #i49561# EditView needed for access to its visible area.
112 const EditView
* mpEditView
;
114 ScEditObjectViewForwarder( OutputDevice
* pWindow
,
115 const EditView
* _pEditView
);
117 virtual bool IsValid() const override
;
118 virtual Point
LogicToPixel( const Point
& rPoint
, const MapMode
& rMapMode
) const override
;
119 virtual Point
PixelToLogic( const Point
& rPoint
, const MapMode
& rMapMode
) const override
;
124 ScEditObjectViewForwarder::ScEditObjectViewForwarder( OutputDevice
* pWindow
,
125 const EditView
* _pEditView
)
127 , mpEditView( _pEditView
)
131 bool ScEditObjectViewForwarder::IsValid() const
133 return (mpWindow
!= nullptr);
136 Point
ScEditObjectViewForwarder::LogicToPixel( const Point
& rPoint
, const MapMode
& rMapMode
) const
140 // #i49561# - consider offset of the visible area
141 // of the EditView before converting point to pixel.
142 Point
aPoint( rPoint
);
145 tools::Rectangle
aEditViewVisArea( mpEditView
->GetVisArea() );
146 aPoint
+= aEditViewVisArea
.TopLeft();
148 return mpWindow
->LogicToPixel( aPoint
, rMapMode
);
152 OSL_FAIL("this ViewForwarder is not valid");
157 Point
ScEditObjectViewForwarder::PixelToLogic( const Point
& rPoint
, const MapMode
& rMapMode
) const
161 // #i49561# - consider offset of the visible area
162 // of the EditView after converting point to logic.
163 Point
aPoint( mpWindow
->PixelToLogic( rPoint
, rMapMode
) );
166 tools::Rectangle
aEditViewVisArea( mpEditView
->GetVisArea() );
167 aPoint
-= aEditViewVisArea
.TopLeft();
173 OSL_FAIL("this ViewForwarder is not valid");
178 void ScEditObjectViewForwarder::SetInvalid()
183 class ScPreviewViewForwarder
: public SvxViewForwarder
186 ScPreviewShell
* mpViewShell
;
188 explicit ScPreviewViewForwarder(ScPreviewShell
* pViewShell
);
190 virtual bool IsValid() const override
;
191 virtual Point
LogicToPixel( const Point
& rPoint
, const MapMode
& rMapMode
) const override
;
192 virtual Point
PixelToLogic( const Point
& rPoint
, const MapMode
& rMapMode
) const override
;
197 ScPreviewViewForwarder::ScPreviewViewForwarder(ScPreviewShell
* pViewShell
)
198 : mpViewShell(pViewShell
)
202 bool ScPreviewViewForwarder::IsValid() const
204 return mpViewShell
!= nullptr;
207 Point
ScPreviewViewForwarder::LogicToPixel( const Point
& rPoint
, const MapMode
& rMapMode
) const
211 vcl::Window
* pWindow
= mpViewShell
->GetWindow();
214 MapMode
aMapMode(pWindow
->GetMapMode().GetMapUnit());
215 Point
aPoint2( OutputDevice::LogicToLogic( rPoint
, rMapMode
, aMapMode
) );
216 return pWindow
->LogicToPixel(aPoint2
);
221 OSL_FAIL("this ViewForwarder is not valid");
226 Point
ScPreviewViewForwarder::PixelToLogic( const Point
& rPoint
, const MapMode
& rMapMode
) const
230 vcl::Window
* pWindow
= mpViewShell
->GetWindow();
233 MapMode
aMapMode(pWindow
->GetMapMode());
234 aMapMode
.SetOrigin(Point());
235 Point
aPoint1( pWindow
->PixelToLogic( rPoint
) );
236 Point
aPoint2( OutputDevice::LogicToLogic( aPoint1
,
237 MapMode(aMapMode
.GetMapUnit()),
244 OSL_FAIL("this ViewForwarder is not valid");
249 void ScPreviewViewForwarder::SetInvalid()
251 mpViewShell
= nullptr;
256 class ScPreviewHeaderFooterViewForwarder
: public ScPreviewViewForwarder
259 ScPreviewHeaderFooterViewForwarder(ScPreviewShell
* pViewShell
);
264 ScPreviewHeaderFooterViewForwarder::ScPreviewHeaderFooterViewForwarder(ScPreviewShell
* pViewShell
)
266 ScPreviewViewForwarder(pViewShell
)
272 class ScPreviewCellViewForwarder
: public ScPreviewViewForwarder
275 ScPreviewCellViewForwarder(ScPreviewShell
* pViewShell
);
280 ScPreviewCellViewForwarder::ScPreviewCellViewForwarder(ScPreviewShell
* pViewShell
)
282 ScPreviewViewForwarder(pViewShell
)
288 class ScPreviewHeaderCellViewForwarder
: public ScPreviewViewForwarder
291 ScPreviewHeaderCellViewForwarder(ScPreviewShell
* pViewShell
);
296 ScPreviewHeaderCellViewForwarder::ScPreviewHeaderCellViewForwarder(ScPreviewShell
* pViewShell
)
298 ScPreviewViewForwarder(pViewShell
)
304 class ScPreviewNoteViewForwarder
: public ScPreviewViewForwarder
307 ScPreviewNoteViewForwarder(ScPreviewShell
* pViewShell
);
312 ScPreviewNoteViewForwarder::ScPreviewNoteViewForwarder(ScPreviewShell
* pViewShell
)
314 ScPreviewViewForwarder(pViewShell
)
318 class ScEditViewForwarder
: public SvxEditViewForwarder
320 EditView
* mpEditView
;
321 VclPtr
<OutputDevice
> mpWindow
;
323 ScEditViewForwarder(EditView
* pEditView
, OutputDevice
* pWin
);
325 virtual bool IsValid() const override
;
326 virtual Point
LogicToPixel( const Point
& rPoint
, const MapMode
& rMapMode
) const override
;
327 virtual Point
PixelToLogic( const Point
& rPoint
, const MapMode
& rMapMode
) const override
;
328 virtual bool GetSelection( ESelection
& rSelection
) const override
;
329 virtual bool SetSelection( const ESelection
& rSelection
) override
;
330 virtual bool Copy() override
;
331 virtual bool Cut() override
;
332 virtual bool Paste() override
;
337 ScEditViewForwarder::ScEditViewForwarder(EditView
* pEditView
, OutputDevice
* pWin
)
338 : mpEditView(pEditView
)
343 bool ScEditViewForwarder::IsValid() const
345 return mpWindow
&& mpEditView
;
348 Point
ScEditViewForwarder::LogicToPixel( const Point
& rPoint
, const MapMode
& rMapMode
) const
351 return mpWindow
->LogicToPixel( rPoint
, rMapMode
);
354 OSL_FAIL("this ViewForwarder is not valid");
359 Point
ScEditViewForwarder::PixelToLogic( const Point
& rPoint
, const MapMode
& rMapMode
) const
362 return mpWindow
->PixelToLogic( rPoint
, rMapMode
);
365 OSL_FAIL("this ViewForwarder is not valid");
370 bool ScEditViewForwarder::GetSelection( ESelection
& rSelection
) const
375 rSelection
= mpEditView
->GetSelection();
380 OSL_FAIL("this ViewForwarder is not valid");
385 bool ScEditViewForwarder::SetSelection( const ESelection
& rSelection
)
390 mpEditView
->SetSelection(rSelection
);
395 OSL_FAIL("this ViewForwarder is not valid");
400 bool ScEditViewForwarder::Copy()
410 OSL_FAIL("this ViewForwarder is not valid");
415 bool ScEditViewForwarder::Cut()
425 OSL_FAIL("this ViewForwarder is not valid");
430 bool ScEditViewForwarder::Paste()
440 OSL_FAIL("this ViewForwarder is not valid");
445 void ScEditViewForwarder::SetInvalid()
448 mpEditView
= nullptr;
451 // ScAccessibleCellTextData: shared data between sub objects of an accessible cell text object
453 ScAccessibleCellTextData::ScAccessibleCellTextData(ScTabViewShell
* pViewShell
,
454 const ScAddress
& rP
, ScSplitPos eSplitPos
, ScAccessibleCell
* pAccCell
)
455 : ScAccessibleCellBaseTextData(GetDocShell(pViewShell
), rP
),
456 mpViewShell(pViewShell
),
457 meSplitPos(eSplitPos
),
458 mpAccessibleCell( pAccCell
)
462 ScAccessibleCellTextData::~ScAccessibleCellTextData()
465 pEditEngine
->SetNotifyHdl(Link
<EENotify
&,void>());
466 mpViewForwarder
.reset();
469 void ScAccessibleCellTextData::Notify( SfxBroadcaster
& rBC
, const SfxHint
& rHint
)
471 if ( rHint
.GetId() == SfxHintId::Dying
)
473 mpViewShell
= nullptr; // invalid now
475 mpViewForwarder
->SetInvalid();
477 ScAccessibleCellBaseTextData::Notify(rBC
, rHint
);
480 ScAccessibleTextData
* ScAccessibleCellTextData::Clone() const
482 return new ScAccessibleCellTextData( mpViewShell
, aCellPos
, meSplitPos
, mpAccessibleCell
);
485 SvxTextForwarder
* ScAccessibleCellTextData::GetTextForwarder()
487 ScCellTextData::GetTextForwarder(); // creates Forwarder and EditEngine
489 if ( pDocShell
&& pEditEngine
&& mpViewShell
)
491 ScDocument
& rDoc
= pDocShell
->GetDocument();
492 tools::Long nSizeX
, nSizeY
;
493 mpViewShell
->GetViewData().GetMergeSizePixel(
494 aCellPos
.Col(), aCellPos
.Row(), nSizeX
, nSizeY
);
496 Size
aSize(nSizeX
, nSizeY
);
498 // #i92143# text getRangeExtents reports incorrect 'x' values for spreadsheet cells
499 tools::Long nIndent
= 0;
500 const SvxHorJustifyItem
* pHorJustifyItem
= rDoc
.GetAttr( aCellPos
, ATTR_HOR_JUSTIFY
);
501 SvxCellHorJustify eHorJust
= pHorJustifyItem
? pHorJustifyItem
->GetValue() : SvxCellHorJustify::Standard
;
502 if ( eHorJust
== SvxCellHorJustify::Left
)
504 const ScIndentItem
* pIndentItem
= rDoc
.GetAttr( aCellPos
, ATTR_INDENT
);
507 nIndent
= static_cast< tools::Long
>( pIndentItem
->GetValue() );
511 const SvxMarginItem
* pMarginItem
= rDoc
.GetAttr( aCellPos
, ATTR_MARGIN
);
512 ScViewData
& rViewData
= mpViewShell
->GetViewData();
513 double nPPTX
= rViewData
.GetPPTX();
514 double nPPTY
= rViewData
.GetPPTY();
515 tools::Long nLeftM
= ( pMarginItem
? static_cast< tools::Long
>( ( pMarginItem
->GetLeftMargin() + nIndent
) * nPPTX
) : 0 );
516 tools::Long nTopM
= ( pMarginItem
? static_cast< tools::Long
>( pMarginItem
->GetTopMargin() * nPPTY
) : 0 );
517 tools::Long nRightM
= ( pMarginItem
? static_cast< tools::Long
>( pMarginItem
->GetRightMargin() * nPPTX
) : 0 );
518 tools::Long nBottomM
= ( pMarginItem
? static_cast< tools::Long
>( pMarginItem
->GetBottomMargin() * nPPTY
) : 0 );
519 tools::Long nWidth
= aSize
.getWidth() - nLeftM
- nRightM
;
520 aSize
.setWidth( nWidth
);
521 aSize
.setHeight( aSize
.getHeight() - nTopM
- nBottomM
);
523 vcl::Window
* pWin
= mpViewShell
->GetWindowByPos( meSplitPos
);
526 aSize
= pWin
->PixelToLogic( aSize
, pEditEngine
->GetRefMapMode() );
529 /* #i19430# Gnopernicus reads text partly if it sticks out of the cell
530 boundaries. This leads to wrong results in cases where the cell text
531 is rotated, because rotation is not taken into account when calcu-
532 lating the visible part of the text. In these cases we will expand
533 the cell size passed as paper size to the edit engine. The function
534 accessibility::AccessibleStaticTextBase::GetParagraphBoundingBox()
535 (see svx/source/accessibility/AccessibleStaticTextBase.cxx) will
536 return the size of the complete text then, which is used to expand
537 the cell bounding box in ScAccessibleCell::GetBoundingBox()
538 (see sc/source/ui/Accessibility/AccessibleCell.cxx). */
539 const ScRotateValueItem
* pItem
= rDoc
.GetAttr( aCellPos
, ATTR_ROTATE_VALUE
);
540 if( pItem
&& (pItem
->GetValue() != 0_deg100
) )
542 pEditEngine
->SetPaperSize( Size( LONG_MAX
, aSize
.getHeight() ) );
543 tools::Long nTxtWidth
= static_cast< tools::Long
>( pEditEngine
->CalcTextWidth() );
544 aSize
.setWidth( std::max( aSize
.getWidth(), nTxtWidth
+ 2 ) );
548 // #i92143# text getRangeExtents reports incorrect 'x' values for spreadsheet cells
549 const ScLineBreakCell
* pLineBreakItem
= rDoc
.GetAttr( aCellPos
, ATTR_LINEBREAK
);
550 bool bLineBreak
= ( pLineBreakItem
&& pLineBreakItem
->GetValue() );
553 tools::Long nTxtWidth
= static_cast< tools::Long
>( pEditEngine
->CalcTextWidth() );
554 aSize
.setWidth( ::std::max( aSize
.getWidth(), nTxtWidth
) );
558 pEditEngine
->SetPaperSize( aSize
);
560 // #i92143# text getRangeExtents reports incorrect 'x' values for spreadsheet cells
561 if ( eHorJust
== SvxCellHorJustify::Standard
&& rDoc
.HasValueData( aCellPos
.Col(), aCellPos
.Row(), aCellPos
.Tab() ) )
563 pEditEngine
->SetDefaultItem( SvxAdjustItem( SvxAdjust::Right
, EE_PARA_JUST
) );
569 aTextSize
= pWin
->LogicToPixel( Size( pEditEngine
->CalcTextWidth(), pEditEngine
->GetTextHeight() ), pEditEngine
->GetRefMapMode() );
571 tools::Long nTextWidth
= aTextSize
.Width();
572 tools::Long nTextHeight
= aTextSize
.Height();
574 tools::Long nOffsetX
= nLeftM
;
575 tools::Long nDiffX
= nTextWidth
- nWidth
;
580 case SvxCellHorJustify::Right
:
585 case SvxCellHorJustify::Center
:
587 nOffsetX
-= nDiffX
/ 2;
597 tools::Long nOffsetY
= 0;
598 const SvxVerJustifyItem
* pVerJustifyItem
= rDoc
.GetAttr( aCellPos
, ATTR_VER_JUSTIFY
);
599 SvxCellVerJustify eVerJust
= ( pVerJustifyItem
? pVerJustifyItem
->GetValue() : SvxCellVerJustify::Standard
);
602 case SvxCellVerJustify::Standard
:
603 case SvxCellVerJustify::Bottom
:
605 nOffsetY
= nSizeY
- nBottomM
- nTextHeight
;
608 case SvxCellVerJustify::Center
:
610 nOffsetY
= ( nSizeY
- nTopM
- nBottomM
- nTextHeight
) / 2 + nTopM
;
620 if ( mpAccessibleCell
)
622 mpAccessibleCell
->SetOffset( Point( nOffsetX
, nOffsetY
) );
625 pEditEngine
->SetNotifyHdl( LINK(this, ScAccessibleCellTextData
, NotifyHdl
) );
628 return pForwarder
.get();
631 SvxViewForwarder
* ScAccessibleCellTextData::GetViewForwarder()
633 if (!mpViewForwarder
)
634 mpViewForwarder
.reset(new ScViewForwarder(mpViewShell
, meSplitPos
));
635 return mpViewForwarder
.get();
638 SvxEditViewForwarder
* ScAccessibleCellTextData::GetEditViewForwarder( bool /* bCreate */ )
640 //#102219#; there should no EditViewForwarder be, because the cell is now readonly in this interface
644 IMPL_LINK(ScAccessibleTextData
, NotifyHdl
, EENotify
&, aNotify
, void)
646 ::std::unique_ptr
< SfxHint
> aHint
= SvxEditSourceHelper::EENotification2Hint( &aNotify
);
649 GetBroadcaster().Broadcast(*aHint
);
652 ScDocShell
* ScAccessibleCellTextData::GetDocShell(ScTabViewShell
* pViewShell
)
654 ScDocShell
* pDocSh
= nullptr;
656 pDocSh
= pViewShell
->GetViewData().GetDocShell();
660 ScAccessibleEditObjectTextData::ScAccessibleEditObjectTextData(EditView
* pEditView
, OutputDevice
* pWin
, bool isClone
)
661 : mpEditView(pEditView
)
662 , mpEditEngine(pEditView
? &pEditView
->getEditEngine() : nullptr)
665 // If the object is cloned, do NOT add notify hdl.
666 mbIsCloned
= isClone
;
667 if (mpEditEngine
&& !mbIsCloned
)
668 mpEditEngine
->SetNotifyHdl( LINK(this, ScAccessibleEditObjectTextData
, NotifyHdl
) );
671 ScAccessibleEditObjectTextData::~ScAccessibleEditObjectTextData()
673 // If the object is cloned, do NOT set notify hdl.
674 if (mpEditEngine
&& !mbIsCloned
)
675 mpEditEngine
->SetNotifyHdl(Link
<EENotify
&,void>());
676 mpViewForwarder
.reset();
677 mpEditViewForwarder
.reset();
681 void ScAccessibleEditObjectTextData::Notify( SfxBroadcaster
& rBC
, const SfxHint
& rHint
)
683 if ( rHint
.GetId() == SfxHintId::Dying
)
686 mpEditView
= nullptr;
687 mpEditEngine
= nullptr;
690 mpViewForwarder
->SetInvalid();
691 if (mpEditViewForwarder
)
692 mpEditViewForwarder
->SetInvalid();
694 ScAccessibleTextData::Notify(rBC
, rHint
);
697 ScAccessibleTextData
* ScAccessibleEditObjectTextData::Clone() const
699 // Add para to indicate the object is cloned
700 return new ScAccessibleEditObjectTextData(mpEditView
, mpWindow
, true);
703 SvxTextForwarder
* ScAccessibleEditObjectTextData::GetTextForwarder()
705 if ((!mpForwarder
&& mpEditView
) || (mpEditEngine
&& !mpEditEngine
->GetNotifyHdl().IsSet()))
708 mpEditEngine
= &mpEditView
->getEditEngine();
709 // If the object is cloned, do NOT add notify hdl.
710 if (mpEditEngine
&& !mpEditEngine
->GetNotifyHdl().IsSet()&&!mbIsCloned
)
711 mpEditEngine
->SetNotifyHdl( LINK(this, ScAccessibleEditObjectTextData
, NotifyHdl
) );
713 mpForwarder
.reset(new SvxEditEngineForwarder(*mpEditEngine
));
715 return mpForwarder
.get();
718 SvxViewForwarder
* ScAccessibleEditObjectTextData::GetViewForwarder()
720 if (!mpViewForwarder
)
722 // i#49561 Get right-aligned cell content to be read by screenreader.
723 mpViewForwarder
.reset(new ScEditObjectViewForwarder( mpWindow
, mpEditView
));
725 return mpViewForwarder
.get();
728 SvxEditViewForwarder
* ScAccessibleEditObjectTextData::GetEditViewForwarder( bool bCreate
)
730 if (!mpEditViewForwarder
&& mpEditView
)
731 mpEditViewForwarder
.reset(new ScEditViewForwarder(mpEditView
, mpWindow
));
734 if (!mpEditView
&& mpEditViewForwarder
)
736 mpEditViewForwarder
.reset();
739 return mpEditViewForwarder
.get();
742 IMPL_LINK(ScAccessibleEditObjectTextData
, NotifyHdl
, EENotify
&, rNotify
, void)
744 ::std::unique_ptr
< SfxHint
> aHint
= SvxEditSourceHelper::EENotification2Hint( &rNotify
);
747 GetBroadcaster().Broadcast(*aHint
);
750 ScAccessibleEditLineTextData::ScAccessibleEditLineTextData(EditView
* pEditView
,
753 : ScAccessibleEditObjectTextData(pEditView
, pWin
)
755 , mbEditEngineCreated(false)
758 mpTxtWnd
->InsertAccessibleTextData( *this );
761 ScAccessibleEditLineTextData::~ScAccessibleEditLineTextData()
764 mpTxtWnd
->RemoveAccessibleTextData( *this );
766 if (mbEditEngineCreated
&& mpEditEngine
)
769 mpEditEngine
= nullptr; // don't access in ScAccessibleEditObjectTextData dtor!
771 else if (mpTxtWnd
&& mpTxtWnd
->HasEditView())
773 // the NotifyHdl also has to be removed from the ScTextWnd's EditEngine
774 // (it's set in ScAccessibleEditLineTextData::GetTextForwarder, and mpEditEngine
776 mpTxtWnd
->GetEditView()->getEditEngine().SetNotifyHdl(Link
<EENotify
&,void>());
780 void ScAccessibleEditLineTextData::Dispose()
783 mpTxtWnd
->RemoveAccessibleTextData( *this );
790 ScAccessibleTextData
* ScAccessibleEditLineTextData::Clone() const
792 return new ScAccessibleEditLineTextData(mpEditView
, mpWindow
, mpTxtWnd
);
795 SvxTextForwarder
* ScAccessibleEditLineTextData::GetTextForwarder()
799 if (mpTxtWnd
->HasEditView())
801 mpEditView
= mpTxtWnd
->GetEditView();
803 if (mbEditEngineCreated
&& mpEditEngine
)
805 mbEditEngineCreated
= false;
807 mpEditView
= mpTxtWnd
->GetEditView();
808 ScAccessibleEditObjectTextData::GetTextForwarder(); // fill the mpForwarder
809 mpEditEngine
= nullptr;
813 mpEditView
= nullptr;
815 if (mpEditEngine
&& !mbEditEngineCreated
)
819 rtl::Reference
<SfxItemPool
> pEnginePool
= EditEngine::CreatePool();
820 mpEditEngine
= new ScFieldEditEngine(nullptr, pEnginePool
.get(), nullptr, true);
821 mbEditEngineCreated
= true;
822 mpEditEngine
->EnableUndo( false );
823 mpEditEngine
->SetRefMapMode(MapMode(MapUnit::Map100thMM
));
824 mpForwarder
.reset(new SvxEditEngineForwarder(*mpEditEngine
));
826 mpEditEngine
->SetText(mpTxtWnd
->GetTextString());
829 Size
aSize(pTxtWnd
->GetSizePixel());
830 aSize
= pTxtWnd
->PixelToLogic(aSize
, mpEditEngine
->GetRefMapMode());
831 mpEditEngine
->SetPaperSize(aSize
);
833 OutputDevice
& rDevice
= mpTxtWnd
->GetDrawingArea()->get_ref_device();
834 Size
aSize(rDevice
.GetOutputSizePixel());
835 aSize
= rDevice
.PixelToLogic(aSize
, mpEditEngine
->GetRefMapMode());
836 mpEditEngine
->SetPaperSize(aSize
);
839 mpEditEngine
->SetNotifyHdl( LINK(this, ScAccessibleEditObjectTextData
, NotifyHdl
) );
843 return mpForwarder
.get();
846 SvxEditViewForwarder
* ScAccessibleEditLineTextData::GetEditViewForwarder( bool bCreate
)
850 if (!mpTxtWnd
->HasEditView() && bCreate
)
852 if ( !mpTxtWnd
->IsInputActive() )
854 mpTxtWnd
->StartEditEngine();
855 mpTxtWnd
->GrabFocus();
857 mpEditView
= mpTxtWnd
->GetEditView();
862 return ScAccessibleEditObjectTextData::GetEditViewForwarder(bCreate
);
865 void ScAccessibleEditLineTextData::ResetEditMode()
867 if (mbEditEngineCreated
&& mpEditEngine
)
869 else if (mpTxtWnd
&& mpTxtWnd
->HasEditView())
870 mpTxtWnd
->GetEditView()->getEditEngine().SetNotifyHdl(Link
<EENotify
&,void>());
871 mpEditEngine
= nullptr;
874 mpEditViewForwarder
.reset();
875 mpViewForwarder
.reset();
876 mbEditEngineCreated
= false;
879 void ScAccessibleEditLineTextData::TextChanged()
881 if (mbEditEngineCreated
&& mpEditEngine
)
884 mpEditEngine
->SetText(mpTxtWnd
->GetTextString());
888 void ScAccessibleEditLineTextData::StartEdit()
891 mpEditView
= nullptr;
893 // send SdrHintKind::BeginEdit
894 SdrHint
aHint(SdrHintKind::BeginEdit
);
895 GetBroadcaster().Broadcast( aHint
);
898 void ScAccessibleEditLineTextData::EndEdit()
900 // send SdrHintKind::EndEdit
901 SdrHint
aHint(SdrHintKind::EndEdit
);
902 GetBroadcaster().Broadcast( aHint
);
905 mpEditView
= nullptr;
908 // ScAccessiblePreviewCellTextData: shared data between sub objects of an accessible cell text object
910 ScAccessiblePreviewCellTextData::ScAccessiblePreviewCellTextData(ScPreviewShell
* pViewShell
,
912 : ScAccessibleCellBaseTextData(GetDocShell(pViewShell
), rP
),
913 mpViewShell(pViewShell
)
917 ScAccessiblePreviewCellTextData::~ScAccessiblePreviewCellTextData()
920 pEditEngine
->SetNotifyHdl(Link
<EENotify
&,void>());
921 mpViewForwarder
.reset();
924 void ScAccessiblePreviewCellTextData::Notify( SfxBroadcaster
& rBC
, const SfxHint
& rHint
)
926 if ( rHint
.GetId() == SfxHintId::Dying
)
928 mpViewShell
= nullptr; // invalid now
930 mpViewForwarder
->SetInvalid();
932 ScAccessibleCellBaseTextData::Notify(rBC
, rHint
);
935 ScAccessibleTextData
* ScAccessiblePreviewCellTextData::Clone() const
937 return new ScAccessiblePreviewCellTextData(mpViewShell
, aCellPos
);
940 SvxTextForwarder
* ScAccessiblePreviewCellTextData::GetTextForwarder()
942 bool bEditEngineBefore(pEditEngine
!= nullptr);
944 ScCellTextData::GetTextForwarder(); // creates Forwarder and EditEngine
946 if (!bEditEngineBefore
&& pEditEngine
)
948 Size
aSize(mpViewShell
->GetLocationData().GetCellOutputRect(aCellPos
).GetSize());
949 vcl::Window
* pWin
= mpViewShell
->GetWindow();
951 aSize
= pWin
->PixelToLogic(aSize
, pEditEngine
->GetRefMapMode());
952 pEditEngine
->SetPaperSize(aSize
);
956 pEditEngine
->SetNotifyHdl( LINK(this, ScAccessiblePreviewCellTextData
, NotifyHdl
) );
958 return pForwarder
.get();
961 SvxViewForwarder
* ScAccessiblePreviewCellTextData::GetViewForwarder()
963 if (!mpViewForwarder
)
964 mpViewForwarder
.reset(new ScPreviewCellViewForwarder(mpViewShell
));
965 return mpViewForwarder
.get();
968 ScDocShell
* ScAccessiblePreviewCellTextData::GetDocShell(ScPreviewShell
* pViewShell
)
970 ScDocShell
* pDocSh
= nullptr;
972 pDocSh
= pViewShell
->GetDocument().GetDocumentShell();
976 // ScAccessiblePreviewHeaderCellTextData: shared data between sub objects of an accessible cell text object
978 ScAccessiblePreviewHeaderCellTextData::ScAccessiblePreviewHeaderCellTextData(ScPreviewShell
* pViewShell
,
979 OUString aText
, const ScAddress
& rP
, bool bColHeader
, bool bRowHeader
)
980 : ScAccessibleCellBaseTextData(GetDocShell(pViewShell
), rP
),
981 mpViewShell(pViewShell
),
982 maText(std::move(aText
)),
983 mbColHeader(bColHeader
),
984 mbRowHeader(bRowHeader
)
988 ScAccessiblePreviewHeaderCellTextData::~ScAccessiblePreviewHeaderCellTextData()
991 pEditEngine
->SetNotifyHdl(Link
<EENotify
&,void>());
992 mpViewForwarder
.reset();
995 void ScAccessiblePreviewHeaderCellTextData::Notify( SfxBroadcaster
& rBC
, const SfxHint
& rHint
)
997 if ( rHint
.GetId() == SfxHintId::Dying
)
999 mpViewShell
= nullptr; // invalid now
1000 if (mpViewForwarder
)
1001 mpViewForwarder
->SetInvalid();
1003 ScAccessibleCellBaseTextData::Notify(rBC
, rHint
);
1006 ScAccessibleTextData
* ScAccessiblePreviewHeaderCellTextData::Clone() const
1008 return new ScAccessiblePreviewHeaderCellTextData(mpViewShell
, maText
, aCellPos
, mbColHeader
, mbRowHeader
);
1011 SvxTextForwarder
* ScAccessiblePreviewHeaderCellTextData::GetTextForwarder()
1017 ScDocument
& rDoc
= pDocShell
->GetDocument();
1018 pEditEngine
= rDoc
.CreateFieldEditEngine();
1022 rtl::Reference
<SfxItemPool
> pEnginePool
= EditEngine::CreatePool();
1023 pEditEngine
.reset( new ScFieldEditEngine(nullptr, pEnginePool
.get(), nullptr, true) );
1025 pEditEngine
->EnableUndo( false );
1027 pEditEngine
->SetRefDevice(pDocShell
->GetRefDevice());
1029 pEditEngine
->SetRefMapMode(MapMode(MapUnit::Map100thMM
));
1030 pForwarder
.reset( new SvxEditEngineForwarder(*pEditEngine
) );
1034 return pForwarder
.get();
1036 if (!maText
.isEmpty())
1041 vcl::Window
* pWindow
= mpViewShell
->GetWindow();
1043 aOutputSize
= pWindow
->GetOutputSizePixel();
1044 tools::Rectangle
aVisRect( Point(), aOutputSize
);
1045 Size
aSize(mpViewShell
->GetLocationData().GetHeaderCellOutputRect(aVisRect
, aCellPos
, mbColHeader
).GetSize());
1047 aSize
= pWindow
->PixelToLogic(aSize
, pEditEngine
->GetRefMapMode());
1048 pEditEngine
->SetPaperSize(aSize
);
1050 pEditEngine
->SetTextCurrentDefaults( maText
);
1055 pEditEngine
->SetNotifyHdl( LINK(this, ScAccessiblePreviewHeaderCellTextData
, NotifyHdl
) );
1057 return pForwarder
.get();
1060 SvxViewForwarder
* ScAccessiblePreviewHeaderCellTextData::GetViewForwarder()
1062 if (!mpViewForwarder
)
1063 mpViewForwarder
.reset(new ScPreviewHeaderCellViewForwarder(mpViewShell
));
1064 return mpViewForwarder
.get();
1067 ScDocShell
* ScAccessiblePreviewHeaderCellTextData::GetDocShell(ScPreviewShell
* pViewShell
)
1069 ScDocShell
* pDocSh
= nullptr;
1071 pDocSh
= pViewShell
->GetDocument().GetDocumentShell();
1075 ScAccessibleHeaderTextData::ScAccessibleHeaderTextData(ScPreviewShell
* pViewShell
,
1076 const EditTextObject
* pEditObj
, SvxAdjust eAdjust
)
1078 mpViewShell(pViewShell
),
1080 mpEditObj(pEditObj
),
1085 mpDocSh
= pViewShell
->GetDocument().GetDocumentShell();
1087 mpDocSh
->GetDocument().AddUnoObject(*this);
1090 ScAccessibleHeaderTextData::~ScAccessibleHeaderTextData()
1092 SolarMutexGuard aGuard
; // needed for EditEngine dtor
1095 mpDocSh
->GetDocument().RemoveUnoObject(*this);
1097 mpEditEngine
->SetNotifyHdl(Link
<EENotify
&,void>());
1098 mpEditEngine
.reset();
1099 mpForwarder
.reset();
1102 ScAccessibleTextData
* ScAccessibleHeaderTextData::Clone() const
1104 return new ScAccessibleHeaderTextData(mpViewShell
, mpEditObj
, meAdjust
);
1107 void ScAccessibleHeaderTextData::Notify( SfxBroadcaster
&, const SfxHint
& rHint
)
1109 if ( rHint
.GetId() == SfxHintId::Dying
)
1111 mpViewShell
= nullptr;// invalid now
1113 if (mxViewForwarder
)
1114 mxViewForwarder
->SetInvalid();
1118 SvxTextForwarder
* ScAccessibleHeaderTextData::GetTextForwarder()
1122 rtl::Reference
<SfxItemPool
> pEnginePool
= EditEngine::CreatePool();
1123 std::unique_ptr
<ScHeaderEditEngine
> pHdrEngine(new ScHeaderEditEngine( pEnginePool
.get() ));
1125 pHdrEngine
->EnableUndo( false );
1126 pHdrEngine
->SetRefMapMode(MapMode(MapUnit::MapTwip
));
1128 // default font must be set, independently of document
1129 // -> use global pool from module
1130 std::unique_ptr
<CellAttributeHelper
> pTmp
;
1131 const ScPatternAttr
* pCellAttributeDefault(nullptr);
1133 if (nullptr != mpDocSh
)
1135 // we can use default CellAttribute from ScDocument
1136 pCellAttributeDefault
= &mpDocSh
->GetDocument().getCellAttributeHelper().getDefaultCellAttribute();
1140 // no access to ScDocument, use temporary CellAttributeHelper.
1141 // also see ScHeaderFooterTextData::GetTextForwarder for more comments
1142 pTmp
.reset(new CellAttributeHelper(ScModule::get()->GetPool()));
1143 pCellAttributeDefault
= &pTmp
->getDefaultCellAttribute();
1146 auto pDefaults
= std::make_unique
<SfxItemSet
>(pHdrEngine
->GetEmptyItemSet());
1147 pCellAttributeDefault
->FillEditItemSet(pDefaults
.get());
1148 // FillEditItemSet adjusts font height to 1/100th mm,
1149 // but for header/footer twips is needed, as in the PatternAttr:
1150 pDefaults
->Put( pCellAttributeDefault
->GetItem(ATTR_FONT_HEIGHT
).CloneSetWhich(EE_CHAR_FONTHEIGHT
) );
1151 pDefaults
->Put( pCellAttributeDefault
->GetItem(ATTR_CJK_FONT_HEIGHT
).CloneSetWhich(EE_CHAR_FONTHEIGHT_CJK
) );
1152 pDefaults
->Put( pCellAttributeDefault
->GetItem(ATTR_CTL_FONT_HEIGHT
).CloneSetWhich(EE_CHAR_FONTHEIGHT_CTL
) );
1153 pDefaults
->Put( SvxAdjustItem( meAdjust
, EE_PARA_JUST
) );
1154 pHdrEngine
->SetDefaults(std::move(pDefaults
));
1156 ScHeaderFieldData aData
;
1158 mpViewShell
->FillFieldData(aData
);
1160 ScHeaderFooterTextObj::FillDummyFieldData( aData
);
1161 pHdrEngine
->SetData( aData
);
1163 mpEditEngine
= std::move(pHdrEngine
);
1164 mpForwarder
.reset(new SvxEditEngineForwarder(*mpEditEngine
));
1168 return mpForwarder
.get();
1172 tools::Rectangle aVisRect
;
1173 mpViewShell
->GetLocationData().GetHeaderPosition(aVisRect
);
1174 Size
aSize(aVisRect
.GetSize());
1175 vcl::Window
* pWin
= mpViewShell
->GetWindow();
1177 aSize
= pWin
->PixelToLogic(aSize
, mpEditEngine
->GetRefMapMode());
1178 mpEditEngine
->SetPaperSize(aSize
);
1181 mpEditEngine
->SetTextCurrentDefaults(*mpEditObj
);
1184 return mpForwarder
.get();
1187 SvxViewForwarder
* ScAccessibleHeaderTextData::GetViewForwarder()
1189 if (!mxViewForwarder
)
1190 mxViewForwarder
= std::make_unique
<ScPreviewHeaderFooterViewForwarder
>(mpViewShell
);
1191 return mxViewForwarder
.get();
1194 ScAccessibleNoteTextData::ScAccessibleNoteTextData(ScPreviewShell
* pViewShell
,
1195 OUString sText
, const ScAddress
& aCellPos
, bool bMarkNote
)
1197 mpViewShell(pViewShell
),
1199 msText(std::move(sText
)),
1200 maCellPos(aCellPos
),
1201 mbMarkNote(bMarkNote
),
1205 mpDocSh
= pViewShell
->GetDocument().GetDocumentShell();
1207 mpDocSh
->GetDocument().AddUnoObject(*this);
1210 ScAccessibleNoteTextData::~ScAccessibleNoteTextData()
1212 SolarMutexGuard aGuard
; // needed for EditEngine dtor
1215 mpDocSh
->GetDocument().RemoveUnoObject(*this);
1217 mpEditEngine
->SetNotifyHdl(Link
<EENotify
&,void>());
1218 mpEditEngine
.reset();
1219 mpForwarder
.reset();
1222 ScAccessibleTextData
* ScAccessibleNoteTextData::Clone() const
1224 return new ScAccessibleNoteTextData(mpViewShell
, msText
, maCellPos
, mbMarkNote
);
1227 void ScAccessibleNoteTextData::Notify( SfxBroadcaster
&, const SfxHint
& rHint
)
1229 if ( rHint
.GetId() == SfxHintId::Dying
)
1231 mpViewShell
= nullptr;// invalid now
1233 if (mxViewForwarder
)
1234 mxViewForwarder
->SetInvalid();
1238 SvxTextForwarder
* ScAccessibleNoteTextData::GetTextForwarder()
1244 ScDocument
& rDoc
= mpDocSh
->GetDocument();
1245 mpEditEngine
= rDoc
.CreateFieldEditEngine();
1249 rtl::Reference
<SfxItemPool
> pEnginePool
= EditEngine::CreatePool();
1250 mpEditEngine
.reset( new ScFieldEditEngine(nullptr, pEnginePool
.get(), nullptr, true) );
1252 mpEditEngine
->EnableUndo( false );
1254 mpEditEngine
->SetRefDevice(mpDocSh
->GetRefDevice());
1256 mpEditEngine
->SetRefMapMode(MapMode(MapUnit::Map100thMM
));
1257 mpForwarder
.reset( new SvxEditEngineForwarder(*mpEditEngine
) );
1261 return mpForwarder
.get();
1263 if (!msText
.isEmpty())
1269 vcl::Window
* pWindow
= mpViewShell
->GetWindow();
1271 aOutputSize
= pWindow
->GetOutputSizePixel();
1272 tools::Rectangle
aVisRect( Point(), aOutputSize
);
1273 Size
aSize(mpViewShell
->GetLocationData().GetNoteInRangeOutputRect(aVisRect
, mbMarkNote
, maCellPos
).GetSize());
1275 aSize
= pWindow
->PixelToLogic(aSize
, mpEditEngine
->GetRefMapMode());
1276 mpEditEngine
->SetPaperSize(aSize
);
1278 mpEditEngine
->SetTextCurrentDefaults( msText
);
1283 mpEditEngine
->SetNotifyHdl( LINK(this, ScAccessibleNoteTextData
, NotifyHdl
) );
1285 return mpForwarder
.get();
1288 SvxViewForwarder
* ScAccessibleNoteTextData::GetViewForwarder()
1290 if (!mxViewForwarder
)
1291 mxViewForwarder
= std::make_unique
<ScPreviewNoteViewForwarder
>(mpViewShell
);
1292 return mxViewForwarder
.get();
1295 // CSV import =================================================================
1297 class ScCsvViewForwarder
: public SvxViewForwarder
1299 VclPtr
<OutputDevice
> mpWindow
;
1302 explicit ScCsvViewForwarder( OutputDevice
* pWindow
);
1304 virtual bool IsValid() const override
;
1305 virtual Point
LogicToPixel( const Point
& rPoint
, const MapMode
& rMapMode
) const override
;
1306 virtual Point
PixelToLogic( const Point
& rPoint
, const MapMode
& rMapMode
) const override
;
1311 ScCsvViewForwarder::ScCsvViewForwarder( OutputDevice
* pWindow
) :
1316 bool ScCsvViewForwarder::IsValid() const
1318 return mpWindow
!= nullptr;
1321 Point
ScCsvViewForwarder::LogicToPixel( const Point
& rPoint
, const MapMode
& rMapMode
) const
1323 if( !mpWindow
) return Point();
1324 return mpWindow
->LogicToPixel( rPoint
, rMapMode
);
1327 Point
ScCsvViewForwarder::PixelToLogic( const Point
& rPoint
, const MapMode
& rMapMode
) const
1329 if( !mpWindow
) return Point();
1330 return mpWindow
->PixelToLogic( rPoint
, rMapMode
);
1333 void ScCsvViewForwarder::SetInvalid()
1338 ScAccessibleCsvTextData::ScAccessibleCsvTextData(
1339 OutputDevice
* pWindow
, EditEngine
* pEditEngine
,
1340 OUString aCellText
, const Size
& rCellSize
) :
1341 mpWindow( pWindow
),
1342 mpEditEngine( pEditEngine
),
1343 maCellText(std::move( aCellText
)),
1344 maCellSize( rCellSize
)
1348 ScAccessibleCsvTextData::~ScAccessibleCsvTextData()
1352 void ScAccessibleCsvTextData::Notify( SfxBroadcaster
& rBC
, const SfxHint
& rHint
)
1354 if ( rHint
.GetId() == SfxHintId::Dying
)
1357 mpEditEngine
= nullptr;
1358 if (mpViewForwarder
)
1359 mpViewForwarder
->SetInvalid();
1361 ScAccessibleTextData::Notify( rBC
, rHint
);
1364 ScAccessibleTextData
* ScAccessibleCsvTextData::Clone() const
1366 return new ScAccessibleCsvTextData( mpWindow
, mpEditEngine
, maCellText
, maCellSize
);
1369 SvxTextForwarder
* ScAccessibleCsvTextData::GetTextForwarder()
1373 mpEditEngine
->SetPaperSize( maCellSize
);
1374 mpEditEngine
->SetText( maCellText
);
1375 if( !mpTextForwarder
)
1376 mpTextForwarder
.reset( new SvxEditEngineForwarder( *mpEditEngine
) );
1379 mpTextForwarder
.reset();
1380 return mpTextForwarder
.get();
1383 SvxViewForwarder
* ScAccessibleCsvTextData::GetViewForwarder()
1385 if( !mpViewForwarder
)
1386 mpViewForwarder
.reset( new ScCsvViewForwarder( mpWindow
) );
1387 return mpViewForwarder
.get();
1390 SvxEditViewForwarder
* ScAccessibleCsvTextData::GetEditViewForwarder( bool /* bCreate */ )
1395 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */