nss: upgrade to release 3.73
[LibreOffice.git] / sc / source / ui / Accessibility / AccessibleText.cxx
blob3166fbd513a4448dfe358d4cc606118a57fce7e6
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <scitems.hxx>
21 #include <editeng/eeitem.hxx>
23 #include <memory>
24 #include <AccessibleText.hxx>
25 #include <AccessibleCell.hxx>
26 #include <attrib.hxx>
27 #include <tabvwsh.hxx>
28 #include <editutil.hxx>
29 #include <document.hxx>
30 #include <scmod.hxx>
31 #include <prevwsh.hxx>
32 #include <docsh.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>
44 #include <vcl/svapp.hxx>
46 class ScViewForwarder : public SvxViewForwarder
48 ScTabViewShell* mpViewShell;
49 ScSplitPos meSplitPos;
50 public:
51 ScViewForwarder(ScTabViewShell* pViewShell, ScSplitPos eSplitPos);
53 virtual bool IsValid() const override;
54 virtual Point LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const override;
55 virtual Point PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const override;
57 void SetInvalid();
60 ScViewForwarder::ScViewForwarder(ScTabViewShell* pViewShell, ScSplitPos eSplitPos)
62 mpViewShell(pViewShell),
63 meSplitPos(eSplitPos)
67 bool ScViewForwarder::IsValid() const
69 return mpViewShell != nullptr;
72 Point ScViewForwarder::LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const
74 if (mpViewShell)
76 vcl::Window* pWindow = mpViewShell->GetWindowByPos(meSplitPos);
77 if (pWindow)
78 return pWindow->LogicToPixel( rPoint, rMapMode );
80 else
82 OSL_FAIL("this ViewForwarder is not valid");
84 return Point();
87 Point ScViewForwarder::PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const
89 if (mpViewShell)
91 vcl::Window* pWindow = mpViewShell->GetWindowByPos(meSplitPos);
92 if (pWindow)
93 return pWindow->PixelToLogic( rPoint, rMapMode );
95 else
97 OSL_FAIL("this ViewForwarder is not valid");
99 return Point();
102 void ScViewForwarder::SetInvalid()
104 mpViewShell = nullptr;
107 class ScEditObjectViewForwarder : public SvxViewForwarder
109 VclPtr<OutputDevice> mpWindow;
110 // #i49561# EditView needed for access to its visible area.
111 const EditView* mpEditView;
112 public:
113 ScEditObjectViewForwarder( OutputDevice* pWindow,
114 const EditView* _pEditView);
116 virtual bool IsValid() const override;
117 virtual Point LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const override;
118 virtual Point PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const override;
120 void SetInvalid();
123 ScEditObjectViewForwarder::ScEditObjectViewForwarder( OutputDevice* pWindow,
124 const EditView* _pEditView )
125 : mpWindow(pWindow)
126 , mpEditView( _pEditView )
130 bool ScEditObjectViewForwarder::IsValid() const
132 return (mpWindow != nullptr);
135 Point ScEditObjectViewForwarder::LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const
137 if (mpWindow)
139 // #i49561# - consider offset of the visible area
140 // of the EditView before converting point to pixel.
141 Point aPoint( rPoint );
142 if ( mpEditView )
144 tools::Rectangle aEditViewVisArea( mpEditView->GetVisArea() );
145 aPoint += aEditViewVisArea.TopLeft();
147 return mpWindow->LogicToPixel( aPoint, rMapMode );
149 else
151 OSL_FAIL("this ViewForwarder is not valid");
153 return Point();
156 Point ScEditObjectViewForwarder::PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const
158 if (mpWindow)
160 // #i49561# - consider offset of the visible area
161 // of the EditView after converting point to logic.
162 Point aPoint( mpWindow->PixelToLogic( rPoint, rMapMode ) );
163 if ( mpEditView )
165 tools::Rectangle aEditViewVisArea( mpEditView->GetVisArea() );
166 aPoint -= aEditViewVisArea.TopLeft();
168 return aPoint;
170 else
172 OSL_FAIL("this ViewForwarder is not valid");
174 return Point();
177 void ScEditObjectViewForwarder::SetInvalid()
179 mpWindow = nullptr;
182 class ScPreviewViewForwarder : public SvxViewForwarder
184 protected:
185 ScPreviewShell* mpViewShell;
186 public:
187 explicit ScPreviewViewForwarder(ScPreviewShell* pViewShell);
189 virtual bool IsValid() const override;
190 virtual Point LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const override;
191 virtual Point PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const override;
193 void SetInvalid();
196 ScPreviewViewForwarder::ScPreviewViewForwarder(ScPreviewShell* pViewShell)
197 : mpViewShell(pViewShell)
201 bool ScPreviewViewForwarder::IsValid() const
203 return mpViewShell != nullptr;
206 Point ScPreviewViewForwarder::LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const
208 if (mpViewShell)
210 vcl::Window* pWindow = mpViewShell->GetWindow();
211 if (pWindow)
213 MapMode aMapMode(pWindow->GetMapMode().GetMapUnit());
214 Point aPoint2( OutputDevice::LogicToLogic( rPoint, rMapMode, aMapMode) );
215 return pWindow->LogicToPixel(aPoint2);
218 else
220 OSL_FAIL("this ViewForwarder is not valid");
222 return Point();
225 Point ScPreviewViewForwarder::PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const
227 if (mpViewShell)
229 vcl::Window* pWindow = mpViewShell->GetWindow();
230 if (pWindow)
232 MapMode aMapMode(pWindow->GetMapMode());
233 aMapMode.SetOrigin(Point());
234 Point aPoint1( pWindow->PixelToLogic( rPoint ) );
235 Point aPoint2( OutputDevice::LogicToLogic( aPoint1,
236 MapMode(aMapMode.GetMapUnit()),
237 rMapMode ) );
238 return aPoint2;
241 else
243 OSL_FAIL("this ViewForwarder is not valid");
245 return Point();
248 void ScPreviewViewForwarder::SetInvalid()
250 mpViewShell = nullptr;
253 namespace {
255 class ScPreviewHeaderFooterViewForwarder : public ScPreviewViewForwarder
257 public:
258 ScPreviewHeaderFooterViewForwarder(ScPreviewShell* pViewShell);
263 ScPreviewHeaderFooterViewForwarder::ScPreviewHeaderFooterViewForwarder(ScPreviewShell* pViewShell)
265 ScPreviewViewForwarder(pViewShell)
269 namespace {
271 class ScPreviewCellViewForwarder : public ScPreviewViewForwarder
273 public:
274 ScPreviewCellViewForwarder(ScPreviewShell* pViewShell);
279 ScPreviewCellViewForwarder::ScPreviewCellViewForwarder(ScPreviewShell* pViewShell)
281 ScPreviewViewForwarder(pViewShell)
285 namespace {
287 class ScPreviewHeaderCellViewForwarder : public ScPreviewViewForwarder
289 public:
290 ScPreviewHeaderCellViewForwarder(ScPreviewShell* pViewShell);
295 ScPreviewHeaderCellViewForwarder::ScPreviewHeaderCellViewForwarder(ScPreviewShell* pViewShell)
297 ScPreviewViewForwarder(pViewShell)
301 namespace {
303 class ScPreviewNoteViewForwarder : public ScPreviewViewForwarder
305 public:
306 ScPreviewNoteViewForwarder(ScPreviewShell* pViewShell);
311 ScPreviewNoteViewForwarder::ScPreviewNoteViewForwarder(ScPreviewShell* pViewShell)
313 ScPreviewViewForwarder(pViewShell)
317 class ScEditViewForwarder : public SvxEditViewForwarder
319 EditView* mpEditView;
320 VclPtr<OutputDevice> mpWindow;
321 public:
322 ScEditViewForwarder(EditView* pEditView, OutputDevice* pWin);
324 virtual bool IsValid() const override;
325 virtual Point LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const override;
326 virtual Point PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const override;
327 virtual bool GetSelection( ESelection& rSelection ) const override;
328 virtual bool SetSelection( const ESelection& rSelection ) override;
329 virtual bool Copy() override;
330 virtual bool Cut() override;
331 virtual bool Paste() override;
333 void SetInvalid();
336 ScEditViewForwarder::ScEditViewForwarder(EditView* pEditView, OutputDevice* pWin)
337 : mpEditView(pEditView)
338 , mpWindow(pWin)
342 bool ScEditViewForwarder::IsValid() const
344 return mpWindow && mpEditView;
347 Point ScEditViewForwarder::LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const
349 if (mpWindow)
350 return mpWindow->LogicToPixel( rPoint, rMapMode );
351 else
353 OSL_FAIL("this ViewForwarder is not valid");
355 return Point();
358 Point ScEditViewForwarder::PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const
360 if (mpWindow)
361 return mpWindow->PixelToLogic( rPoint, rMapMode );
362 else
364 OSL_FAIL("this ViewForwarder is not valid");
366 return Point();
369 bool ScEditViewForwarder::GetSelection( ESelection& rSelection ) const
371 bool bResult(false);
372 if (IsValid())
374 rSelection = mpEditView->GetSelection();
375 bResult = true;
377 else
379 OSL_FAIL("this ViewForwarder is not valid");
381 return bResult;
384 bool ScEditViewForwarder::SetSelection( const ESelection& rSelection )
386 bool bResult(false);
387 if (IsValid())
389 mpEditView->SetSelection(rSelection);
390 bResult = true;
392 else
394 OSL_FAIL("this ViewForwarder is not valid");
396 return bResult;
399 bool ScEditViewForwarder::Copy()
401 bool bResult(false);
402 if (IsValid())
404 mpEditView->Copy();
405 bResult = true;
407 else
409 OSL_FAIL("this ViewForwarder is not valid");
411 return bResult;
414 bool ScEditViewForwarder::Cut()
416 bool bResult(false);
417 if (IsValid())
419 mpEditView->Cut();
420 bResult = true;
422 else
424 OSL_FAIL("this ViewForwarder is not valid");
426 return bResult;
429 bool ScEditViewForwarder::Paste()
431 bool bResult(false);
432 if (IsValid())
434 mpEditView->Paste();
435 bResult = true;
437 else
439 OSL_FAIL("this ViewForwarder is not valid");
441 return bResult;
444 void ScEditViewForwarder::SetInvalid()
446 mpWindow = nullptr;
447 mpEditView = nullptr;
450 // ScAccessibleCellTextData: shared data between sub objects of an accessible cell text object
452 ScAccessibleCellTextData::ScAccessibleCellTextData(ScTabViewShell* pViewShell,
453 const ScAddress& rP, ScSplitPos eSplitPos, ScAccessibleCell* pAccCell)
454 : ScAccessibleCellBaseTextData(GetDocShell(pViewShell), rP),
455 mpViewShell(pViewShell),
456 meSplitPos(eSplitPos),
457 mpAccessibleCell( pAccCell )
461 ScAccessibleCellTextData::~ScAccessibleCellTextData()
463 if (pEditEngine)
464 pEditEngine->SetNotifyHdl(Link<EENotify&,void>());
465 mpViewForwarder.reset();
468 void ScAccessibleCellTextData::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
470 if ( rHint.GetId() == SfxHintId::Dying )
472 mpViewShell = nullptr; // invalid now
473 if (mpViewForwarder)
474 mpViewForwarder->SetInvalid();
476 ScAccessibleCellBaseTextData::Notify(rBC, rHint);
479 ScAccessibleTextData* ScAccessibleCellTextData::Clone() const
481 return new ScAccessibleCellTextData( mpViewShell, aCellPos, meSplitPos, mpAccessibleCell );
484 SvxTextForwarder* ScAccessibleCellTextData::GetTextForwarder()
486 ScCellTextData::GetTextForwarder(); // creates Forwarder and EditEngine
488 if ( pDocShell && pEditEngine && mpViewShell )
490 ScDocument& rDoc = pDocShell->GetDocument();
491 tools::Long nSizeX, nSizeY;
492 mpViewShell->GetViewData().GetMergeSizePixel(
493 aCellPos.Col(), aCellPos.Row(), nSizeX, nSizeY);
495 Size aSize(nSizeX, nSizeY);
497 // #i92143# text getRangeExtents reports incorrect 'x' values for spreadsheet cells
498 tools::Long nIndent = 0;
499 const SvxHorJustifyItem* pHorJustifyItem = rDoc.GetAttr( aCellPos, ATTR_HOR_JUSTIFY );
500 SvxCellHorJustify eHorJust = pHorJustifyItem ? pHorJustifyItem->GetValue() : SvxCellHorJustify::Standard;
501 if ( eHorJust == SvxCellHorJustify::Left )
503 const ScIndentItem* pIndentItem = rDoc.GetAttr( aCellPos, ATTR_INDENT );
504 if ( pIndentItem )
506 nIndent = static_cast< tools::Long >( pIndentItem->GetValue() );
510 const SvxMarginItem* pMarginItem = rDoc.GetAttr( aCellPos, ATTR_MARGIN );
511 ScViewData& rViewData = mpViewShell->GetViewData();
512 double nPPTX = rViewData.GetPPTX();
513 double nPPTY = rViewData.GetPPTY();
514 tools::Long nLeftM = ( pMarginItem ? static_cast< tools::Long >( ( pMarginItem->GetLeftMargin() + nIndent ) * nPPTX ) : 0 );
515 tools::Long nTopM = ( pMarginItem ? static_cast< tools::Long >( pMarginItem->GetTopMargin() * nPPTY ) : 0 );
516 tools::Long nRightM = ( pMarginItem ? static_cast< tools::Long >( pMarginItem->GetRightMargin() * nPPTX ) : 0 );
517 tools::Long nBottomM = ( pMarginItem ? static_cast< tools::Long >( pMarginItem->GetBottomMargin() * nPPTY ) : 0 );
518 tools::Long nWidth = aSize.getWidth() - nLeftM - nRightM;
519 aSize.setWidth( nWidth );
520 aSize.setHeight( aSize.getHeight() - nTopM - nBottomM );
522 vcl::Window* pWin = mpViewShell->GetWindowByPos( meSplitPos );
523 if ( pWin )
525 aSize = pWin->PixelToLogic( aSize, pEditEngine->GetRefMapMode() );
528 /* #i19430# Gnopernicus reads text partly if it sticks out of the cell
529 boundaries. This leads to wrong results in cases where the cell text
530 is rotated, because rotation is not taken into account when calcu-
531 lating the visible part of the text. In these cases we will expand
532 the cell size passed as paper size to the edit engine. The function
533 accessibility::AccessibleStaticTextBase::GetParagraphBoundingBox()
534 (see svx/source/accessibility/AccessibleStaticTextBase.cxx) will
535 return the size of the complete text then, which is used to expand
536 the cell bounding box in ScAccessibleCell::GetBoundingBox()
537 (see sc/source/ui/Accessibility/AccessibleCell.cxx). */
538 const ScRotateValueItem* pItem = rDoc.GetAttr( aCellPos, ATTR_ROTATE_VALUE );
539 if( pItem && (pItem->GetValue() != 0) )
541 pEditEngine->SetPaperSize( Size( LONG_MAX, aSize.getHeight() ) );
542 tools::Long nTxtWidth = static_cast< tools::Long >( pEditEngine->CalcTextWidth() );
543 aSize.setWidth( std::max( aSize.getWidth(), nTxtWidth + 2 ) );
545 else
547 // #i92143# text getRangeExtents reports incorrect 'x' values for spreadsheet cells
548 const ScLineBreakCell* pLineBreakItem = rDoc.GetAttr( aCellPos, ATTR_LINEBREAK );
549 bool bLineBreak = ( pLineBreakItem && pLineBreakItem->GetValue() );
550 if ( !bLineBreak )
552 tools::Long nTxtWidth = static_cast< tools::Long >( pEditEngine->CalcTextWidth() );
553 aSize.setWidth( ::std::max( aSize.getWidth(), nTxtWidth ) );
557 pEditEngine->SetPaperSize( aSize );
559 // #i92143# text getRangeExtents reports incorrect 'x' values for spreadsheet cells
560 if ( eHorJust == SvxCellHorJustify::Standard && rDoc.HasValueData( aCellPos.Col(), aCellPos.Row(), aCellPos.Tab() ) )
562 pEditEngine->SetDefaultItem( SvxAdjustItem( SvxAdjust::Right, EE_PARA_JUST ) );
565 Size aTextSize;
566 if ( pWin )
568 aTextSize = pWin->LogicToPixel( Size( pEditEngine->CalcTextWidth(), pEditEngine->GetTextHeight() ), pEditEngine->GetRefMapMode() );
570 tools::Long nTextWidth = aTextSize.Width();
571 tools::Long nTextHeight = aTextSize.Height();
573 tools::Long nOffsetX = nLeftM;
574 tools::Long nDiffX = nTextWidth - nWidth;
575 if ( nDiffX > 0 )
577 switch ( eHorJust )
579 case SvxCellHorJustify::Right:
581 nOffsetX -= nDiffX;
583 break;
584 case SvxCellHorJustify::Center:
586 nOffsetX -= nDiffX / 2;
588 break;
589 default:
592 break;
596 tools::Long nOffsetY = 0;
597 const SvxVerJustifyItem* pVerJustifyItem = rDoc.GetAttr( aCellPos, ATTR_VER_JUSTIFY );
598 SvxCellVerJustify eVerJust = ( pVerJustifyItem ? pVerJustifyItem->GetValue() : SvxCellVerJustify::Standard );
599 switch ( eVerJust )
601 case SvxCellVerJustify::Standard:
602 case SvxCellVerJustify::Bottom:
604 nOffsetY = nSizeY - nBottomM - nTextHeight;
606 break;
607 case SvxCellVerJustify::Center:
609 nOffsetY = ( nSizeY - nTopM - nBottomM - nTextHeight ) / 2 + nTopM;
611 break;
612 default:
614 nOffsetY = nTopM;
616 break;
619 if ( mpAccessibleCell )
621 mpAccessibleCell->SetOffset( Point( nOffsetX, nOffsetY ) );
624 pEditEngine->SetNotifyHdl( LINK(this, ScAccessibleCellTextData, NotifyHdl) );
627 return pForwarder.get();
630 SvxViewForwarder* ScAccessibleCellTextData::GetViewForwarder()
632 if (!mpViewForwarder)
633 mpViewForwarder.reset(new ScViewForwarder(mpViewShell, meSplitPos));
634 return mpViewForwarder.get();
637 SvxEditViewForwarder* ScAccessibleCellTextData::GetEditViewForwarder( bool /* bCreate */ )
639 //#102219#; there should no EditViewForwarder be, because the cell is now readonly in this interface
640 return nullptr;
643 IMPL_LINK(ScAccessibleTextData, NotifyHdl, EENotify&, aNotify, void)
645 ::std::unique_ptr< SfxHint > aHint = SvxEditSourceHelper::EENotification2Hint( &aNotify );
647 if (aHint)
648 GetBroadcaster().Broadcast(*aHint);
651 ScDocShell* ScAccessibleCellTextData::GetDocShell(ScTabViewShell* pViewShell)
653 ScDocShell* pDocSh = nullptr;
654 if (pViewShell)
655 pDocSh = pViewShell->GetViewData().GetDocShell();
656 return pDocSh;
659 ScAccessibleEditObjectTextData::ScAccessibleEditObjectTextData(EditView* pEditView, OutputDevice* pWin, bool isClone)
661 mpEditView(pEditView),
662 mpEditEngine(pEditView ? pEditView->GetEditEngine() : nullptr),
663 mpWindow(pWin)
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();
678 mpForwarder.reset();
681 void ScAccessibleEditObjectTextData::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
683 if ( rHint.GetId() == SfxHintId::Dying )
685 mpWindow = nullptr;
686 mpEditView = nullptr;
687 mpEditEngine = nullptr;
688 mpForwarder.reset();
689 if (mpViewForwarder)
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()))
707 if (!mpEditEngine)
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) );
712 if(!mpForwarder)
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));
732 if (bCreate)
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 );
746 if (aHint)
747 GetBroadcaster().Broadcast(*aHint);
750 ScAccessibleEditLineTextData::ScAccessibleEditLineTextData(EditView* pEditView,
751 OutputDevice* pWin,
752 ScTextWnd* pTxtWnd)
753 : ScAccessibleEditObjectTextData(pEditView, pWin)
754 , mpTxtWnd(pTxtWnd)
755 , mbEditEngineCreated(false)
757 if (mpTxtWnd)
758 mpTxtWnd->InsertAccessibleTextData( *this );
761 ScAccessibleEditLineTextData::~ScAccessibleEditLineTextData()
763 if (mpTxtWnd)
764 mpTxtWnd->RemoveAccessibleTextData( *this );
766 if (mbEditEngineCreated && mpEditEngine)
768 delete mpEditEngine;
769 mpEditEngine = nullptr; // don't access in ScAccessibleEditObjectTextData dtor!
771 else if (mpTxtWnd && mpTxtWnd->HasEditView() && mpTxtWnd->GetEditView()->GetEditEngine())
773 // the NotifyHdl also has to be removed from the ScTextWnd's EditEngine
774 // (it's set in ScAccessibleEditLineTextData::GetTextForwarder, and mpEditEngine
775 // is reset there)
776 mpTxtWnd->GetEditView()->GetEditEngine()->SetNotifyHdl(Link<EENotify&,void>());
780 void ScAccessibleEditLineTextData::Dispose()
782 if (mpTxtWnd)
783 mpTxtWnd->RemoveAccessibleTextData( *this );
785 ResetEditMode();
786 mpWindow = nullptr;
787 mpTxtWnd = nullptr;
790 ScAccessibleTextData* ScAccessibleEditLineTextData::Clone() const
792 return new ScAccessibleEditLineTextData(mpEditView, mpWindow, mpTxtWnd);
795 SvxTextForwarder* ScAccessibleEditLineTextData::GetTextForwarder()
797 if (mpTxtWnd)
799 if (mpTxtWnd->HasEditView())
801 mpEditView = mpTxtWnd->GetEditView();
803 if (mbEditEngineCreated && mpEditEngine)
804 ResetEditMode();
805 mbEditEngineCreated = false;
807 mpEditView = mpTxtWnd->GetEditView();
808 ScAccessibleEditObjectTextData::GetTextForwarder(); // fill the mpForwarder
809 mpEditEngine = nullptr;
811 else
813 mpEditView = nullptr;
815 if (mpEditEngine && !mbEditEngineCreated)
816 ResetEditMode();
817 if (!mpEditEngine)
819 SfxItemPool* pEnginePool = EditEngine::CreatePool();
820 pEnginePool->FreezeIdRanges();
821 mpEditEngine = new ScFieldEditEngine(nullptr, pEnginePool, nullptr, true);
822 mbEditEngineCreated = true;
823 mpEditEngine->EnableUndo( false );
824 mpEditEngine->SetRefMapMode(MapMode(MapUnit::Map100thMM));
825 mpForwarder.reset(new SvxEditEngineForwarder(*mpEditEngine));
827 mpEditEngine->SetText(mpTxtWnd->GetTextString());
829 #if 0
830 Size aSize(pTxtWnd->GetSizePixel());
831 aSize = pTxtWnd->PixelToLogic(aSize, mpEditEngine->GetRefMapMode());
832 mpEditEngine->SetPaperSize(aSize);
833 #else
834 OutputDevice& rDevice = mpTxtWnd->GetDrawingArea()->get_ref_device();
835 Size aSize(rDevice.GetOutputSizePixel());
836 aSize = rDevice.PixelToLogic(aSize, mpEditEngine->GetRefMapMode());
837 mpEditEngine->SetPaperSize(aSize);
838 #endif
840 mpEditEngine->SetNotifyHdl( LINK(this, ScAccessibleEditObjectTextData, NotifyHdl) );
844 return mpForwarder.get();
847 SvxEditViewForwarder* ScAccessibleEditLineTextData::GetEditViewForwarder( bool bCreate )
849 if (mpTxtWnd)
851 if (!mpTxtWnd->HasEditView() && bCreate)
853 if ( !mpTxtWnd->IsInputActive() )
855 mpTxtWnd->StartEditEngine();
856 mpTxtWnd->GrabFocus();
858 mpEditView = mpTxtWnd->GetEditView();
863 return ScAccessibleEditObjectTextData::GetEditViewForwarder(bCreate);
866 void ScAccessibleEditLineTextData::ResetEditMode()
868 if (mbEditEngineCreated && mpEditEngine)
869 delete mpEditEngine;
870 else if (mpTxtWnd && mpTxtWnd->HasEditView() && mpTxtWnd->GetEditView()->GetEditEngine())
871 mpTxtWnd->GetEditView()->GetEditEngine()->SetNotifyHdl(Link<EENotify&,void>());
872 mpEditEngine = nullptr;
874 mpForwarder.reset();
875 mpEditViewForwarder.reset();
876 mpViewForwarder.reset();
877 mbEditEngineCreated = false;
880 void ScAccessibleEditLineTextData::TextChanged()
882 if (mbEditEngineCreated && mpEditEngine)
884 if (mpTxtWnd)
885 mpEditEngine->SetText(mpTxtWnd->GetTextString());
889 void ScAccessibleEditLineTextData::StartEdit()
891 ResetEditMode();
892 mpEditView = nullptr;
894 // send SdrHintKind::BeginEdit
895 SdrHint aHint(SdrHintKind::BeginEdit);
896 GetBroadcaster().Broadcast( aHint );
899 void ScAccessibleEditLineTextData::EndEdit()
901 // send SdrHintKind::EndEdit
902 SdrHint aHint(SdrHintKind::EndEdit);
903 GetBroadcaster().Broadcast( aHint );
905 ResetEditMode();
906 mpEditView = nullptr;
909 // ScAccessiblePreviewCellTextData: shared data between sub objects of an accessible cell text object
911 ScAccessiblePreviewCellTextData::ScAccessiblePreviewCellTextData(ScPreviewShell* pViewShell,
912 const ScAddress& rP)
913 : ScAccessibleCellBaseTextData(GetDocShell(pViewShell), rP),
914 mpViewShell(pViewShell)
918 ScAccessiblePreviewCellTextData::~ScAccessiblePreviewCellTextData()
920 if (pEditEngine)
921 pEditEngine->SetNotifyHdl(Link<EENotify&,void>());
922 mpViewForwarder.reset();
925 void ScAccessiblePreviewCellTextData::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
927 if ( rHint.GetId() == SfxHintId::Dying )
929 mpViewShell = nullptr; // invalid now
930 if (mpViewForwarder)
931 mpViewForwarder->SetInvalid();
933 ScAccessibleCellBaseTextData::Notify(rBC, rHint);
936 ScAccessibleTextData* ScAccessiblePreviewCellTextData::Clone() const
938 return new ScAccessiblePreviewCellTextData(mpViewShell, aCellPos);
941 SvxTextForwarder* ScAccessiblePreviewCellTextData::GetTextForwarder()
943 bool bEditEngineBefore(pEditEngine != nullptr);
945 ScCellTextData::GetTextForwarder(); // creates Forwarder and EditEngine
947 if (!bEditEngineBefore && pEditEngine)
949 Size aSize(mpViewShell->GetLocationData().GetCellOutputRect(aCellPos).GetSize());
950 vcl::Window* pWin = mpViewShell->GetWindow();
951 if (pWin)
952 aSize = pWin->PixelToLogic(aSize, pEditEngine->GetRefMapMode());
953 pEditEngine->SetPaperSize(aSize);
956 if (pEditEngine)
957 pEditEngine->SetNotifyHdl( LINK(this, ScAccessiblePreviewCellTextData, NotifyHdl) );
959 return pForwarder.get();
962 SvxViewForwarder* ScAccessiblePreviewCellTextData::GetViewForwarder()
964 if (!mpViewForwarder)
965 mpViewForwarder.reset(new ScPreviewCellViewForwarder(mpViewShell));
966 return mpViewForwarder.get();
969 ScDocShell* ScAccessiblePreviewCellTextData::GetDocShell(ScPreviewShell* pViewShell)
971 ScDocShell* pDocSh = nullptr;
972 if (pViewShell)
973 pDocSh = static_cast<ScDocShell*>( pViewShell->GetDocument().GetDocumentShell());
974 return pDocSh;
977 // ScAccessiblePreviewHeaderCellTextData: shared data between sub objects of an accessible cell text object
979 ScAccessiblePreviewHeaderCellTextData::ScAccessiblePreviewHeaderCellTextData(ScPreviewShell* pViewShell,
980 const OUString& rText, const ScAddress& rP, bool bColHeader, bool bRowHeader)
981 : ScAccessibleCellBaseTextData(GetDocShell(pViewShell), rP),
982 mpViewShell(pViewShell),
983 maText(rText),
984 mbColHeader(bColHeader),
985 mbRowHeader(bRowHeader)
989 ScAccessiblePreviewHeaderCellTextData::~ScAccessiblePreviewHeaderCellTextData()
991 if (pEditEngine)
992 pEditEngine->SetNotifyHdl(Link<EENotify&,void>());
993 mpViewForwarder.reset();
996 void ScAccessiblePreviewHeaderCellTextData::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
998 if ( rHint.GetId() == SfxHintId::Dying )
1000 mpViewShell = nullptr; // invalid now
1001 if (mpViewForwarder)
1002 mpViewForwarder->SetInvalid();
1004 ScAccessibleCellBaseTextData::Notify(rBC, rHint);
1007 ScAccessibleTextData* ScAccessiblePreviewHeaderCellTextData::Clone() const
1009 return new ScAccessiblePreviewHeaderCellTextData(mpViewShell, maText, aCellPos, mbColHeader, mbRowHeader);
1012 SvxTextForwarder* ScAccessiblePreviewHeaderCellTextData::GetTextForwarder()
1014 if (!pEditEngine)
1016 if ( pDocShell )
1018 ScDocument& rDoc = pDocShell->GetDocument();
1019 pEditEngine = rDoc.CreateFieldEditEngine();
1021 else
1023 SfxItemPool* pEnginePool = EditEngine::CreatePool();
1024 pEnginePool->FreezeIdRanges();
1025 pEditEngine.reset( new ScFieldEditEngine(nullptr, pEnginePool, nullptr, true) );
1027 pEditEngine->EnableUndo( false );
1028 if (pDocShell)
1029 pEditEngine->SetRefDevice(pDocShell->GetRefDevice());
1030 else
1031 pEditEngine->SetRefMapMode(MapMode(MapUnit::Map100thMM));
1032 pForwarder.reset( new SvxEditEngineForwarder(*pEditEngine) );
1035 if (bDataValid)
1036 return pForwarder.get();
1038 if (!maText.isEmpty())
1040 if ( mpViewShell )
1042 Size aOutputSize;
1043 vcl::Window* pWindow = mpViewShell->GetWindow();
1044 if ( pWindow )
1045 aOutputSize = pWindow->GetOutputSizePixel();
1046 tools::Rectangle aVisRect( Point(), aOutputSize );
1047 Size aSize(mpViewShell->GetLocationData().GetHeaderCellOutputRect(aVisRect, aCellPos, mbColHeader).GetSize());
1048 if (pWindow)
1049 aSize = pWindow->PixelToLogic(aSize, pEditEngine->GetRefMapMode());
1050 pEditEngine->SetPaperSize(aSize);
1052 pEditEngine->SetTextCurrentDefaults( maText );
1055 bDataValid = true;
1057 pEditEngine->SetNotifyHdl( LINK(this, ScAccessiblePreviewHeaderCellTextData, NotifyHdl) );
1059 return pForwarder.get();
1062 SvxViewForwarder* ScAccessiblePreviewHeaderCellTextData::GetViewForwarder()
1064 if (!mpViewForwarder)
1065 mpViewForwarder.reset(new ScPreviewHeaderCellViewForwarder(mpViewShell));
1066 return mpViewForwarder.get();
1069 ScDocShell* ScAccessiblePreviewHeaderCellTextData::GetDocShell(ScPreviewShell* pViewShell)
1071 ScDocShell* pDocSh = nullptr;
1072 if (pViewShell)
1073 pDocSh = static_cast<ScDocShell*>(pViewShell->GetDocument().GetDocumentShell());
1074 return pDocSh;
1077 ScAccessibleHeaderTextData::ScAccessibleHeaderTextData(ScPreviewShell* pViewShell,
1078 const EditTextObject* pEditObj, SvxAdjust eAdjust)
1080 mpViewForwarder(nullptr),
1081 mpViewShell(pViewShell),
1082 mpDocSh(nullptr),
1083 mpEditObj(pEditObj),
1084 mbDataValid(false),
1085 meAdjust(eAdjust)
1087 if (pViewShell)
1088 mpDocSh = static_cast<ScDocShell*>(pViewShell->GetDocument().GetDocumentShell());
1089 if (mpDocSh)
1090 mpDocSh->GetDocument().AddUnoObject(*this);
1093 ScAccessibleHeaderTextData::~ScAccessibleHeaderTextData()
1095 SolarMutexGuard aGuard; // needed for EditEngine dtor
1097 if (mpDocSh)
1098 mpDocSh->GetDocument().RemoveUnoObject(*this);
1099 if (mpEditEngine)
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
1115 mpDocSh = nullptr;
1116 if (mpViewForwarder)
1117 mpViewForwarder->SetInvalid();
1121 SvxTextForwarder* ScAccessibleHeaderTextData::GetTextForwarder()
1123 if (!mpEditEngine)
1125 SfxItemPool* pEnginePool = EditEngine::CreatePool();
1126 pEnginePool->FreezeIdRanges();
1127 std::unique_ptr<ScHeaderEditEngine> pHdrEngine(new ScHeaderEditEngine( pEnginePool ));
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;
1147 if (mpViewShell)
1148 mpViewShell->FillFieldData(aData);
1149 else
1150 ScHeaderFooterTextObj::FillDummyFieldData( aData );
1151 pHdrEngine->SetData( aData );
1153 mpEditEngine = std::move(pHdrEngine);
1154 mpForwarder.reset(new SvxEditEngineForwarder(*mpEditEngine));
1157 if (mbDataValid)
1158 return mpForwarder.get();
1160 if ( mpViewShell )
1162 tools::Rectangle aVisRect;
1163 mpViewShell->GetLocationData().GetHeaderPosition(aVisRect);
1164 Size aSize(aVisRect.GetSize());
1165 vcl::Window* pWin = mpViewShell->GetWindow();
1166 if (pWin)
1167 aSize = pWin->PixelToLogic(aSize, mpEditEngine->GetRefMapMode());
1168 mpEditEngine->SetPaperSize(aSize);
1170 if (mpEditObj)
1171 mpEditEngine->SetTextCurrentDefaults(*mpEditObj);
1173 mbDataValid = true;
1174 return mpForwarder.get();
1177 SvxViewForwarder* ScAccessibleHeaderTextData::GetViewForwarder()
1179 if (!mpViewForwarder)
1180 mpViewForwarder = new ScPreviewHeaderFooterViewForwarder(mpViewShell);
1181 return mpViewForwarder;
1184 ScAccessibleNoteTextData::ScAccessibleNoteTextData(ScPreviewShell* pViewShell,
1185 const OUString& sText, const ScAddress& aCellPos, bool bMarkNote)
1187 mpViewForwarder(nullptr),
1188 mpViewShell(pViewShell),
1189 mpDocSh(nullptr),
1190 msText(sText),
1191 maCellPos(aCellPos),
1192 mbMarkNote(bMarkNote),
1193 mbDataValid(false)
1195 if (pViewShell)
1196 mpDocSh = static_cast<ScDocShell*>(pViewShell->GetDocument().GetDocumentShell());
1197 if (mpDocSh)
1198 mpDocSh->GetDocument().AddUnoObject(*this);
1201 ScAccessibleNoteTextData::~ScAccessibleNoteTextData()
1203 SolarMutexGuard aGuard; // needed for EditEngine dtor
1205 if (mpDocSh)
1206 mpDocSh->GetDocument().RemoveUnoObject(*this);
1207 if (mpEditEngine)
1208 mpEditEngine->SetNotifyHdl(Link<EENotify&,void>());
1209 mpEditEngine.reset();
1210 mpForwarder.reset();
1213 ScAccessibleTextData* ScAccessibleNoteTextData::Clone() const
1215 return new ScAccessibleNoteTextData(mpViewShell, msText, maCellPos, mbMarkNote);
1218 void ScAccessibleNoteTextData::Notify( SfxBroadcaster&, const SfxHint& rHint )
1220 if ( rHint.GetId() == SfxHintId::Dying )
1222 mpViewShell = nullptr;// invalid now
1223 mpDocSh = nullptr;
1224 if (mpViewForwarder)
1225 mpViewForwarder->SetInvalid();
1229 SvxTextForwarder* ScAccessibleNoteTextData::GetTextForwarder()
1231 if (!mpEditEngine)
1233 if ( mpDocSh )
1235 ScDocument& rDoc = mpDocSh->GetDocument();
1236 mpEditEngine = rDoc.CreateFieldEditEngine();
1238 else
1240 SfxItemPool* pEnginePool = EditEngine::CreatePool();
1241 pEnginePool->FreezeIdRanges();
1242 mpEditEngine.reset( new ScFieldEditEngine(nullptr, pEnginePool, nullptr, true) );
1244 mpEditEngine->EnableUndo( false );
1245 if (mpDocSh)
1246 mpEditEngine->SetRefDevice(mpDocSh->GetRefDevice());
1247 else
1248 mpEditEngine->SetRefMapMode(MapMode(MapUnit::Map100thMM));
1249 mpForwarder.reset( new SvxEditEngineForwarder(*mpEditEngine) );
1252 if (mbDataValid)
1253 return mpForwarder.get();
1255 if (!msText.isEmpty())
1258 if ( mpViewShell )
1260 Size aOutputSize;
1261 vcl::Window* pWindow = mpViewShell->GetWindow();
1262 if ( pWindow )
1263 aOutputSize = pWindow->GetOutputSizePixel();
1264 tools::Rectangle aVisRect( Point(), aOutputSize );
1265 Size aSize(mpViewShell->GetLocationData().GetNoteInRangeOutputRect(aVisRect, mbMarkNote, maCellPos).GetSize());
1266 if (pWindow)
1267 aSize = pWindow->PixelToLogic(aSize, mpEditEngine->GetRefMapMode());
1268 mpEditEngine->SetPaperSize(aSize);
1270 mpEditEngine->SetTextCurrentDefaults( msText );
1273 mbDataValid = true;
1275 mpEditEngine->SetNotifyHdl( LINK(this, ScAccessibleNoteTextData, NotifyHdl) );
1277 return mpForwarder.get();
1280 SvxViewForwarder* ScAccessibleNoteTextData::GetViewForwarder()
1282 if (!mpViewForwarder)
1283 mpViewForwarder = new ScPreviewNoteViewForwarder(mpViewShell);
1284 return mpViewForwarder;
1287 // CSV import =================================================================
1289 class ScCsvViewForwarder : public SvxViewForwarder
1291 VclPtr<OutputDevice> mpWindow;
1293 public:
1294 explicit ScCsvViewForwarder( OutputDevice* pWindow );
1296 virtual bool IsValid() const override;
1297 virtual Point LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const override;
1298 virtual Point PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const override;
1300 void SetInvalid();
1303 ScCsvViewForwarder::ScCsvViewForwarder( OutputDevice* pWindow ) :
1304 mpWindow( pWindow )
1308 bool ScCsvViewForwarder::IsValid() const
1310 return mpWindow != nullptr;
1313 Point ScCsvViewForwarder::LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const
1315 if( !mpWindow ) return Point();
1316 return mpWindow->LogicToPixel( rPoint, rMapMode );
1319 Point ScCsvViewForwarder::PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const
1321 if( !mpWindow ) return Point();
1322 return mpWindow->PixelToLogic( rPoint, rMapMode );
1325 void ScCsvViewForwarder::SetInvalid()
1327 mpWindow = nullptr;
1330 ScAccessibleCsvTextData::ScAccessibleCsvTextData(
1331 OutputDevice* pWindow, EditEngine* pEditEngine,
1332 const OUString& rCellText, const Size& rCellSize ) :
1333 mpWindow( pWindow ),
1334 mpEditEngine( pEditEngine ),
1335 maCellText( rCellText ),
1336 maCellSize( rCellSize )
1340 ScAccessibleCsvTextData::~ScAccessibleCsvTextData()
1344 void ScAccessibleCsvTextData::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
1346 if ( rHint.GetId() == SfxHintId::Dying )
1348 mpWindow = nullptr;
1349 mpEditEngine = nullptr;
1350 if (mpViewForwarder)
1351 mpViewForwarder->SetInvalid();
1353 ScAccessibleTextData::Notify( rBC, rHint );
1356 ScAccessibleTextData* ScAccessibleCsvTextData::Clone() const
1358 return new ScAccessibleCsvTextData( mpWindow, mpEditEngine, maCellText, maCellSize );
1361 SvxTextForwarder* ScAccessibleCsvTextData::GetTextForwarder()
1363 if( mpEditEngine )
1365 mpEditEngine->SetPaperSize( maCellSize );
1366 mpEditEngine->SetText( maCellText );
1367 if( !mpTextForwarder )
1368 mpTextForwarder.reset( new SvxEditEngineForwarder( *mpEditEngine ) );
1370 else
1371 mpTextForwarder.reset();
1372 return mpTextForwarder.get();
1375 SvxViewForwarder* ScAccessibleCsvTextData::GetViewForwarder()
1377 if( !mpViewForwarder )
1378 mpViewForwarder.reset( new ScCsvViewForwarder( mpWindow ) );
1379 return mpViewForwarder.get();
1382 SvxEditViewForwarder* ScAccessibleCsvTextData::GetEditViewForwarder( bool /* bCreate */ )
1384 return nullptr;
1387 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */