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
)
662 mpEditView(pEditView
),
663 mpEditEngine(pEditView
? pEditView
->GetEditEngine() : nullptr),
666 // If the object is cloned, do NOT add notify hdl.
667 mbIsCloned
= isClone
;
668 if (mpEditEngine
&& !mbIsCloned
)
669 mpEditEngine
->SetNotifyHdl( LINK(this, ScAccessibleEditObjectTextData
, NotifyHdl
) );
672 ScAccessibleEditObjectTextData::~ScAccessibleEditObjectTextData()
674 // If the object is cloned, do NOT set notify hdl.
675 if (mpEditEngine
&& !mbIsCloned
)
676 mpEditEngine
->SetNotifyHdl(Link
<EENotify
&,void>());
677 mpViewForwarder
.reset();
678 mpEditViewForwarder
.reset();
682 void ScAccessibleEditObjectTextData::Notify( SfxBroadcaster
& rBC
, const SfxHint
& rHint
)
684 if ( rHint
.GetId() == SfxHintId::Dying
)
687 mpEditView
= nullptr;
688 mpEditEngine
= nullptr;
691 mpViewForwarder
->SetInvalid();
692 if (mpEditViewForwarder
)
693 mpEditViewForwarder
->SetInvalid();
695 ScAccessibleTextData::Notify(rBC
, rHint
);
698 ScAccessibleTextData
* ScAccessibleEditObjectTextData::Clone() const
700 // Add para to indicate the object is cloned
701 return new ScAccessibleEditObjectTextData(mpEditView
, mpWindow
, true);
704 SvxTextForwarder
* ScAccessibleEditObjectTextData::GetTextForwarder()
706 if ((!mpForwarder
&& mpEditView
) || (mpEditEngine
&& !mpEditEngine
->GetNotifyHdl().IsSet()))
709 mpEditEngine
= mpEditView
->GetEditEngine();
710 // If the object is cloned, do NOT add notify hdl.
711 if (mpEditEngine
&& !mpEditEngine
->GetNotifyHdl().IsSet()&&!mbIsCloned
)
712 mpEditEngine
->SetNotifyHdl( LINK(this, ScAccessibleEditObjectTextData
, NotifyHdl
) );
714 mpForwarder
.reset(new SvxEditEngineForwarder(*mpEditEngine
));
716 return mpForwarder
.get();
719 SvxViewForwarder
* ScAccessibleEditObjectTextData::GetViewForwarder()
721 if (!mpViewForwarder
)
723 // i#49561 Get right-aligned cell content to be read by screenreader.
724 mpViewForwarder
.reset(new ScEditObjectViewForwarder( mpWindow
, mpEditView
));
726 return mpViewForwarder
.get();
729 SvxEditViewForwarder
* ScAccessibleEditObjectTextData::GetEditViewForwarder( bool bCreate
)
731 if (!mpEditViewForwarder
&& mpEditView
)
732 mpEditViewForwarder
.reset(new ScEditViewForwarder(mpEditView
, mpWindow
));
735 if (!mpEditView
&& mpEditViewForwarder
)
737 mpEditViewForwarder
.reset();
740 return mpEditViewForwarder
.get();
743 IMPL_LINK(ScAccessibleEditObjectTextData
, NotifyHdl
, EENotify
&, rNotify
, void)
745 ::std::unique_ptr
< SfxHint
> aHint
= SvxEditSourceHelper::EENotification2Hint( &rNotify
);
748 GetBroadcaster().Broadcast(*aHint
);
751 ScAccessibleEditLineTextData::ScAccessibleEditLineTextData(EditView
* pEditView
,
754 : ScAccessibleEditObjectTextData(pEditView
, pWin
)
756 , mbEditEngineCreated(false)
759 mpTxtWnd
->InsertAccessibleTextData( *this );
762 ScAccessibleEditLineTextData::~ScAccessibleEditLineTextData()
765 mpTxtWnd
->RemoveAccessibleTextData( *this );
767 if (mbEditEngineCreated
&& mpEditEngine
)
770 mpEditEngine
= nullptr; // don't access in ScAccessibleEditObjectTextData dtor!
772 else if (mpTxtWnd
&& mpTxtWnd
->HasEditView() && mpTxtWnd
->GetEditView()->GetEditEngine())
774 // the NotifyHdl also has to be removed from the ScTextWnd's EditEngine
775 // (it's set in ScAccessibleEditLineTextData::GetTextForwarder, and mpEditEngine
777 mpTxtWnd
->GetEditView()->GetEditEngine()->SetNotifyHdl(Link
<EENotify
&,void>());
781 void ScAccessibleEditLineTextData::Dispose()
784 mpTxtWnd
->RemoveAccessibleTextData( *this );
791 ScAccessibleTextData
* ScAccessibleEditLineTextData::Clone() const
793 return new ScAccessibleEditLineTextData(mpEditView
, mpWindow
, mpTxtWnd
);
796 SvxTextForwarder
* ScAccessibleEditLineTextData::GetTextForwarder()
800 if (mpTxtWnd
->HasEditView())
802 mpEditView
= mpTxtWnd
->GetEditView();
804 if (mbEditEngineCreated
&& mpEditEngine
)
806 mbEditEngineCreated
= false;
808 mpEditView
= mpTxtWnd
->GetEditView();
809 ScAccessibleEditObjectTextData::GetTextForwarder(); // fill the mpForwarder
810 mpEditEngine
= nullptr;
814 mpEditView
= nullptr;
816 if (mpEditEngine
&& !mbEditEngineCreated
)
820 rtl::Reference
<SfxItemPool
> pEnginePool
= EditEngine::CreatePool();
821 pEnginePool
->FreezeIdRanges();
822 mpEditEngine
= new ScFieldEditEngine(nullptr, pEnginePool
.get(), nullptr, true);
823 mbEditEngineCreated
= true;
824 mpEditEngine
->EnableUndo( false );
825 mpEditEngine
->SetRefMapMode(MapMode(MapUnit::Map100thMM
));
826 mpForwarder
.reset(new SvxEditEngineForwarder(*mpEditEngine
));
828 mpEditEngine
->SetText(mpTxtWnd
->GetTextString());
831 Size
aSize(pTxtWnd
->GetSizePixel());
832 aSize
= pTxtWnd
->PixelToLogic(aSize
, mpEditEngine
->GetRefMapMode());
833 mpEditEngine
->SetPaperSize(aSize
);
835 OutputDevice
& rDevice
= mpTxtWnd
->GetDrawingArea()->get_ref_device();
836 Size
aSize(rDevice
.GetOutputSizePixel());
837 aSize
= rDevice
.PixelToLogic(aSize
, mpEditEngine
->GetRefMapMode());
838 mpEditEngine
->SetPaperSize(aSize
);
841 mpEditEngine
->SetNotifyHdl( LINK(this, ScAccessibleEditObjectTextData
, NotifyHdl
) );
845 return mpForwarder
.get();
848 SvxEditViewForwarder
* ScAccessibleEditLineTextData::GetEditViewForwarder( bool bCreate
)
852 if (!mpTxtWnd
->HasEditView() && bCreate
)
854 if ( !mpTxtWnd
->IsInputActive() )
856 mpTxtWnd
->StartEditEngine();
857 mpTxtWnd
->GrabFocus();
859 mpEditView
= mpTxtWnd
->GetEditView();
864 return ScAccessibleEditObjectTextData::GetEditViewForwarder(bCreate
);
867 void ScAccessibleEditLineTextData::ResetEditMode()
869 if (mbEditEngineCreated
&& mpEditEngine
)
871 else if (mpTxtWnd
&& mpTxtWnd
->HasEditView() && mpTxtWnd
->GetEditView()->GetEditEngine())
872 mpTxtWnd
->GetEditView()->GetEditEngine()->SetNotifyHdl(Link
<EENotify
&,void>());
873 mpEditEngine
= nullptr;
876 mpEditViewForwarder
.reset();
877 mpViewForwarder
.reset();
878 mbEditEngineCreated
= false;
881 void ScAccessibleEditLineTextData::TextChanged()
883 if (mbEditEngineCreated
&& mpEditEngine
)
886 mpEditEngine
->SetText(mpTxtWnd
->GetTextString());
890 void ScAccessibleEditLineTextData::StartEdit()
893 mpEditView
= nullptr;
895 // send SdrHintKind::BeginEdit
896 SdrHint
aHint(SdrHintKind::BeginEdit
);
897 GetBroadcaster().Broadcast( aHint
);
900 void ScAccessibleEditLineTextData::EndEdit()
902 // send SdrHintKind::EndEdit
903 SdrHint
aHint(SdrHintKind::EndEdit
);
904 GetBroadcaster().Broadcast( aHint
);
907 mpEditView
= nullptr;
910 // ScAccessiblePreviewCellTextData: shared data between sub objects of an accessible cell text object
912 ScAccessiblePreviewCellTextData::ScAccessiblePreviewCellTextData(ScPreviewShell
* pViewShell
,
914 : ScAccessibleCellBaseTextData(GetDocShell(pViewShell
), rP
),
915 mpViewShell(pViewShell
)
919 ScAccessiblePreviewCellTextData::~ScAccessiblePreviewCellTextData()
922 pEditEngine
->SetNotifyHdl(Link
<EENotify
&,void>());
923 mpViewForwarder
.reset();
926 void ScAccessiblePreviewCellTextData::Notify( SfxBroadcaster
& rBC
, const SfxHint
& rHint
)
928 if ( rHint
.GetId() == SfxHintId::Dying
)
930 mpViewShell
= nullptr; // invalid now
932 mpViewForwarder
->SetInvalid();
934 ScAccessibleCellBaseTextData::Notify(rBC
, rHint
);
937 ScAccessibleTextData
* ScAccessiblePreviewCellTextData::Clone() const
939 return new ScAccessiblePreviewCellTextData(mpViewShell
, aCellPos
);
942 SvxTextForwarder
* ScAccessiblePreviewCellTextData::GetTextForwarder()
944 bool bEditEngineBefore(pEditEngine
!= nullptr);
946 ScCellTextData::GetTextForwarder(); // creates Forwarder and EditEngine
948 if (!bEditEngineBefore
&& pEditEngine
)
950 Size
aSize(mpViewShell
->GetLocationData().GetCellOutputRect(aCellPos
).GetSize());
951 vcl::Window
* pWin
= mpViewShell
->GetWindow();
953 aSize
= pWin
->PixelToLogic(aSize
, pEditEngine
->GetRefMapMode());
954 pEditEngine
->SetPaperSize(aSize
);
958 pEditEngine
->SetNotifyHdl( LINK(this, ScAccessiblePreviewCellTextData
, NotifyHdl
) );
960 return pForwarder
.get();
963 SvxViewForwarder
* ScAccessiblePreviewCellTextData::GetViewForwarder()
965 if (!mpViewForwarder
)
966 mpViewForwarder
.reset(new ScPreviewCellViewForwarder(mpViewShell
));
967 return mpViewForwarder
.get();
970 ScDocShell
* ScAccessiblePreviewCellTextData::GetDocShell(ScPreviewShell
* pViewShell
)
972 ScDocShell
* pDocSh
= nullptr;
974 pDocSh
= static_cast<ScDocShell
*>( pViewShell
->GetDocument().GetDocumentShell());
978 // ScAccessiblePreviewHeaderCellTextData: shared data between sub objects of an accessible cell text object
980 ScAccessiblePreviewHeaderCellTextData::ScAccessiblePreviewHeaderCellTextData(ScPreviewShell
* pViewShell
,
981 OUString aText
, const ScAddress
& rP
, bool bColHeader
, bool bRowHeader
)
982 : ScAccessibleCellBaseTextData(GetDocShell(pViewShell
), rP
),
983 mpViewShell(pViewShell
),
984 maText(std::move(aText
)),
985 mbColHeader(bColHeader
),
986 mbRowHeader(bRowHeader
)
990 ScAccessiblePreviewHeaderCellTextData::~ScAccessiblePreviewHeaderCellTextData()
993 pEditEngine
->SetNotifyHdl(Link
<EENotify
&,void>());
994 mpViewForwarder
.reset();
997 void ScAccessiblePreviewHeaderCellTextData::Notify( SfxBroadcaster
& rBC
, const SfxHint
& rHint
)
999 if ( rHint
.GetId() == SfxHintId::Dying
)
1001 mpViewShell
= nullptr; // invalid now
1002 if (mpViewForwarder
)
1003 mpViewForwarder
->SetInvalid();
1005 ScAccessibleCellBaseTextData::Notify(rBC
, rHint
);
1008 ScAccessibleTextData
* ScAccessiblePreviewHeaderCellTextData::Clone() const
1010 return new ScAccessiblePreviewHeaderCellTextData(mpViewShell
, maText
, aCellPos
, mbColHeader
, mbRowHeader
);
1013 SvxTextForwarder
* ScAccessiblePreviewHeaderCellTextData::GetTextForwarder()
1019 ScDocument
& rDoc
= pDocShell
->GetDocument();
1020 pEditEngine
= rDoc
.CreateFieldEditEngine();
1024 rtl::Reference
<SfxItemPool
> pEnginePool
= EditEngine::CreatePool();
1025 pEnginePool
->FreezeIdRanges();
1026 pEditEngine
.reset( new ScFieldEditEngine(nullptr, pEnginePool
.get(), nullptr, true) );
1028 pEditEngine
->EnableUndo( false );
1030 pEditEngine
->SetRefDevice(pDocShell
->GetRefDevice());
1032 pEditEngine
->SetRefMapMode(MapMode(MapUnit::Map100thMM
));
1033 pForwarder
.reset( new SvxEditEngineForwarder(*pEditEngine
) );
1037 return pForwarder
.get();
1039 if (!maText
.isEmpty())
1044 vcl::Window
* pWindow
= mpViewShell
->GetWindow();
1046 aOutputSize
= pWindow
->GetOutputSizePixel();
1047 tools::Rectangle
aVisRect( Point(), aOutputSize
);
1048 Size
aSize(mpViewShell
->GetLocationData().GetHeaderCellOutputRect(aVisRect
, aCellPos
, mbColHeader
).GetSize());
1050 aSize
= pWindow
->PixelToLogic(aSize
, pEditEngine
->GetRefMapMode());
1051 pEditEngine
->SetPaperSize(aSize
);
1053 pEditEngine
->SetTextCurrentDefaults( maText
);
1058 pEditEngine
->SetNotifyHdl( LINK(this, ScAccessiblePreviewHeaderCellTextData
, NotifyHdl
) );
1060 return pForwarder
.get();
1063 SvxViewForwarder
* ScAccessiblePreviewHeaderCellTextData::GetViewForwarder()
1065 if (!mpViewForwarder
)
1066 mpViewForwarder
.reset(new ScPreviewHeaderCellViewForwarder(mpViewShell
));
1067 return mpViewForwarder
.get();
1070 ScDocShell
* ScAccessiblePreviewHeaderCellTextData::GetDocShell(ScPreviewShell
* pViewShell
)
1072 ScDocShell
* pDocSh
= nullptr;
1074 pDocSh
= static_cast<ScDocShell
*>(pViewShell
->GetDocument().GetDocumentShell());
1078 ScAccessibleHeaderTextData::ScAccessibleHeaderTextData(ScPreviewShell
* pViewShell
,
1079 const EditTextObject
* pEditObj
, SvxAdjust eAdjust
)
1081 mpViewShell(pViewShell
),
1083 mpEditObj(pEditObj
),
1088 mpDocSh
= static_cast<ScDocShell
*>(pViewShell
->GetDocument().GetDocumentShell());
1090 mpDocSh
->GetDocument().AddUnoObject(*this);
1093 ScAccessibleHeaderTextData::~ScAccessibleHeaderTextData()
1095 SolarMutexGuard aGuard
; // needed for EditEngine dtor
1098 mpDocSh
->GetDocument().RemoveUnoObject(*this);
1100 mpEditEngine
->SetNotifyHdl(Link
<EENotify
&,void>());
1101 mpEditEngine
.reset();
1102 mpForwarder
.reset();
1105 ScAccessibleTextData
* ScAccessibleHeaderTextData::Clone() const
1107 return new ScAccessibleHeaderTextData(mpViewShell
, mpEditObj
, meAdjust
);
1110 void ScAccessibleHeaderTextData::Notify( SfxBroadcaster
&, const SfxHint
& rHint
)
1112 if ( rHint
.GetId() == SfxHintId::Dying
)
1114 mpViewShell
= nullptr;// invalid now
1116 if (mxViewForwarder
)
1117 mxViewForwarder
->SetInvalid();
1121 SvxTextForwarder
* ScAccessibleHeaderTextData::GetTextForwarder()
1125 rtl::Reference
<SfxItemPool
> pEnginePool
= EditEngine::CreatePool();
1126 pEnginePool
->FreezeIdRanges();
1127 std::unique_ptr
<ScHeaderEditEngine
> pHdrEngine(new ScHeaderEditEngine( pEnginePool
.get() ));
1129 pHdrEngine
->EnableUndo( false );
1130 pHdrEngine
->SetRefMapMode(MapMode(MapUnit::MapTwip
));
1132 // default font must be set, independently of document
1133 // -> use global pool from module
1135 SfxItemSet
aDefaults( pHdrEngine
->GetEmptyItemSet() );
1136 const ScPatternAttr
& rPattern
= SC_MOD()->GetPool().GetDefaultItem(ATTR_PATTERN
);
1137 rPattern
.FillEditItemSet( &aDefaults
);
1138 // FillEditItemSet adjusts font height to 1/100th mm,
1139 // but for header/footer twips is needed, as in the PatternAttr:
1140 aDefaults
.Put( rPattern
.GetItem(ATTR_FONT_HEIGHT
).CloneSetWhich(EE_CHAR_FONTHEIGHT
) );
1141 aDefaults
.Put( rPattern
.GetItem(ATTR_CJK_FONT_HEIGHT
).CloneSetWhich(EE_CHAR_FONTHEIGHT_CJK
) );
1142 aDefaults
.Put( rPattern
.GetItem(ATTR_CTL_FONT_HEIGHT
).CloneSetWhich(EE_CHAR_FONTHEIGHT_CTL
) );
1143 aDefaults
.Put( SvxAdjustItem( meAdjust
, EE_PARA_JUST
) );
1144 pHdrEngine
->SetDefaults( aDefaults
);
1146 ScHeaderFieldData aData
;
1148 mpViewShell
->FillFieldData(aData
);
1150 ScHeaderFooterTextObj::FillDummyFieldData( aData
);
1151 pHdrEngine
->SetData( aData
);
1153 mpEditEngine
= std::move(pHdrEngine
);
1154 mpForwarder
.reset(new SvxEditEngineForwarder(*mpEditEngine
));
1158 return mpForwarder
.get();
1162 tools::Rectangle aVisRect
;
1163 mpViewShell
->GetLocationData().GetHeaderPosition(aVisRect
);
1164 Size
aSize(aVisRect
.GetSize());
1165 vcl::Window
* pWin
= mpViewShell
->GetWindow();
1167 aSize
= pWin
->PixelToLogic(aSize
, mpEditEngine
->GetRefMapMode());
1168 mpEditEngine
->SetPaperSize(aSize
);
1171 mpEditEngine
->SetTextCurrentDefaults(*mpEditObj
);
1174 return mpForwarder
.get();
1177 SvxViewForwarder
* ScAccessibleHeaderTextData::GetViewForwarder()
1179 if (!mxViewForwarder
)
1180 mxViewForwarder
= std::make_unique
<ScPreviewHeaderFooterViewForwarder
>(mpViewShell
);
1181 return mxViewForwarder
.get();
1184 ScAccessibleNoteTextData::ScAccessibleNoteTextData(ScPreviewShell
* pViewShell
,
1185 OUString sText
, const ScAddress
& aCellPos
, bool bMarkNote
)
1187 mpViewShell(pViewShell
),
1189 msText(std::move(sText
)),
1190 maCellPos(aCellPos
),
1191 mbMarkNote(bMarkNote
),
1195 mpDocSh
= static_cast<ScDocShell
*>(pViewShell
->GetDocument().GetDocumentShell());
1197 mpDocSh
->GetDocument().AddUnoObject(*this);
1200 ScAccessibleNoteTextData::~ScAccessibleNoteTextData()
1202 SolarMutexGuard aGuard
; // needed for EditEngine dtor
1205 mpDocSh
->GetDocument().RemoveUnoObject(*this);
1207 mpEditEngine
->SetNotifyHdl(Link
<EENotify
&,void>());
1208 mpEditEngine
.reset();
1209 mpForwarder
.reset();
1212 ScAccessibleTextData
* ScAccessibleNoteTextData::Clone() const
1214 return new ScAccessibleNoteTextData(mpViewShell
, msText
, maCellPos
, mbMarkNote
);
1217 void ScAccessibleNoteTextData::Notify( SfxBroadcaster
&, const SfxHint
& rHint
)
1219 if ( rHint
.GetId() == SfxHintId::Dying
)
1221 mpViewShell
= nullptr;// invalid now
1223 if (mxViewForwarder
)
1224 mxViewForwarder
->SetInvalid();
1228 SvxTextForwarder
* ScAccessibleNoteTextData::GetTextForwarder()
1234 ScDocument
& rDoc
= mpDocSh
->GetDocument();
1235 mpEditEngine
= rDoc
.CreateFieldEditEngine();
1239 rtl::Reference
<SfxItemPool
> pEnginePool
= EditEngine::CreatePool();
1240 pEnginePool
->FreezeIdRanges();
1241 mpEditEngine
.reset( new ScFieldEditEngine(nullptr, pEnginePool
.get(), nullptr, true) );
1243 mpEditEngine
->EnableUndo( false );
1245 mpEditEngine
->SetRefDevice(mpDocSh
->GetRefDevice());
1247 mpEditEngine
->SetRefMapMode(MapMode(MapUnit::Map100thMM
));
1248 mpForwarder
.reset( new SvxEditEngineForwarder(*mpEditEngine
) );
1252 return mpForwarder
.get();
1254 if (!msText
.isEmpty())
1260 vcl::Window
* pWindow
= mpViewShell
->GetWindow();
1262 aOutputSize
= pWindow
->GetOutputSizePixel();
1263 tools::Rectangle
aVisRect( Point(), aOutputSize
);
1264 Size
aSize(mpViewShell
->GetLocationData().GetNoteInRangeOutputRect(aVisRect
, mbMarkNote
, maCellPos
).GetSize());
1266 aSize
= pWindow
->PixelToLogic(aSize
, mpEditEngine
->GetRefMapMode());
1267 mpEditEngine
->SetPaperSize(aSize
);
1269 mpEditEngine
->SetTextCurrentDefaults( msText
);
1274 mpEditEngine
->SetNotifyHdl( LINK(this, ScAccessibleNoteTextData
, NotifyHdl
) );
1276 return mpForwarder
.get();
1279 SvxViewForwarder
* ScAccessibleNoteTextData::GetViewForwarder()
1281 if (!mxViewForwarder
)
1282 mxViewForwarder
= std::make_unique
<ScPreviewNoteViewForwarder
>(mpViewShell
);
1283 return mxViewForwarder
.get();
1286 // CSV import =================================================================
1288 class ScCsvViewForwarder
: public SvxViewForwarder
1290 VclPtr
<OutputDevice
> mpWindow
;
1293 explicit ScCsvViewForwarder( OutputDevice
* pWindow
);
1295 virtual bool IsValid() const override
;
1296 virtual Point
LogicToPixel( const Point
& rPoint
, const MapMode
& rMapMode
) const override
;
1297 virtual Point
PixelToLogic( const Point
& rPoint
, const MapMode
& rMapMode
) const override
;
1302 ScCsvViewForwarder::ScCsvViewForwarder( OutputDevice
* pWindow
) :
1307 bool ScCsvViewForwarder::IsValid() const
1309 return mpWindow
!= nullptr;
1312 Point
ScCsvViewForwarder::LogicToPixel( const Point
& rPoint
, const MapMode
& rMapMode
) const
1314 if( !mpWindow
) return Point();
1315 return mpWindow
->LogicToPixel( rPoint
, rMapMode
);
1318 Point
ScCsvViewForwarder::PixelToLogic( const Point
& rPoint
, const MapMode
& rMapMode
) const
1320 if( !mpWindow
) return Point();
1321 return mpWindow
->PixelToLogic( rPoint
, rMapMode
);
1324 void ScCsvViewForwarder::SetInvalid()
1329 ScAccessibleCsvTextData::ScAccessibleCsvTextData(
1330 OutputDevice
* pWindow
, EditEngine
* pEditEngine
,
1331 OUString aCellText
, const Size
& rCellSize
) :
1332 mpWindow( pWindow
),
1333 mpEditEngine( pEditEngine
),
1334 maCellText(std::move( aCellText
)),
1335 maCellSize( rCellSize
)
1339 ScAccessibleCsvTextData::~ScAccessibleCsvTextData()
1343 void ScAccessibleCsvTextData::Notify( SfxBroadcaster
& rBC
, const SfxHint
& rHint
)
1345 if ( rHint
.GetId() == SfxHintId::Dying
)
1348 mpEditEngine
= nullptr;
1349 if (mpViewForwarder
)
1350 mpViewForwarder
->SetInvalid();
1352 ScAccessibleTextData::Notify( rBC
, rHint
);
1355 ScAccessibleTextData
* ScAccessibleCsvTextData::Clone() const
1357 return new ScAccessibleCsvTextData( mpWindow
, mpEditEngine
, maCellText
, maCellSize
);
1360 SvxTextForwarder
* ScAccessibleCsvTextData::GetTextForwarder()
1364 mpEditEngine
->SetPaperSize( maCellSize
);
1365 mpEditEngine
->SetText( maCellText
);
1366 if( !mpTextForwarder
)
1367 mpTextForwarder
.reset( new SvxEditEngineForwarder( *mpEditEngine
) );
1370 mpTextForwarder
.reset();
1371 return mpTextForwarder
.get();
1374 SvxViewForwarder
* ScAccessibleCsvTextData::GetViewForwarder()
1376 if( !mpViewForwarder
)
1377 mpViewForwarder
.reset( new ScCsvViewForwarder( mpWindow
) );
1378 return mpViewForwarder
.get();
1381 SvxEditViewForwarder
* ScAccessibleCsvTextData::GetEditViewForwarder( bool /* bCreate */ )
1386 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */