diff options
Diffstat (limited to 'sc/source/ui/Accessibility/AccessibleText.cxx')
-rw-r--r-- | sc/source/ui/Accessibility/AccessibleText.cxx | 1781 |
1 files changed, 1781 insertions, 0 deletions
diff --git a/sc/source/ui/Accessibility/AccessibleText.cxx b/sc/source/ui/Accessibility/AccessibleText.cxx new file mode 100644 index 000000000000..2dbbd15c2f12 --- /dev/null +++ b/sc/source/ui/Accessibility/AccessibleText.cxx @@ -0,0 +1,1781 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + +#include "scitems.hxx" +#include <editeng/eeitem.hxx> + +#include <memory> +#include "AccessibleText.hxx" +#include "AccessibleCell.hxx" +#include "tabvwsh.hxx" +#include "editutil.hxx" +#include "document.hxx" +#include "scmod.hxx" +#include "prevwsh.hxx" +#include "docsh.hxx" +#include "prevloc.hxx" +#include "patattr.hxx" +#include "inputwin.hxx" +#include <editeng/unofored.hxx> +#include <editeng/editview.hxx> +#include <editeng/unoedhlp.hxx> +#include <vcl/virdev.hxx> +#include <editeng/editobj.hxx> +#include <editeng/adjitem.hxx> +#include <editeng/justifyitem.hxx> +#include <svx/svdmodel.hxx> +#include <svx/algitem.hxx> +#include <vcl/svapp.hxx> + + +// ============================================================================ + +class ScViewForwarder : public SvxViewForwarder +{ + ScTabViewShell* mpViewShell; + ScAddress maCellPos; + ScSplitPos meSplitPos; +public: + ScViewForwarder(ScTabViewShell* pViewShell, ScSplitPos eSplitPos, const ScAddress& rCell); + virtual ~ScViewForwarder(); + + virtual sal_Bool IsValid() const; + virtual Rectangle GetVisArea() const; + virtual Point LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const; + virtual Point PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const; + + void SetInvalid(); +}; + +ScViewForwarder::ScViewForwarder(ScTabViewShell* pViewShell, ScSplitPos eSplitPos, const ScAddress& rCell) + : + mpViewShell(pViewShell), + maCellPos(rCell), + meSplitPos(eSplitPos) +{ +} + +ScViewForwarder::~ScViewForwarder() +{ +} + +sal_Bool ScViewForwarder::IsValid() const +{ + return mpViewShell != NULL; +} + +Rectangle ScViewForwarder::GetVisArea() const +{ + Rectangle aVisArea; + if (mpViewShell) + { + Window* pWindow = mpViewShell->GetWindowByPos(meSplitPos); + if (pWindow) + { + aVisArea.SetSize(pWindow->GetSizePixel()); + + ScHSplitPos eWhichH = ((meSplitPos == SC_SPLIT_TOPLEFT) || (meSplitPos == SC_SPLIT_BOTTOMLEFT)) ? + SC_SPLIT_LEFT : SC_SPLIT_RIGHT; + ScVSplitPos eWhichV = ((meSplitPos == SC_SPLIT_TOPLEFT) || (meSplitPos == SC_SPLIT_TOPRIGHT)) ? + SC_SPLIT_TOP : SC_SPLIT_BOTTOM; + + Point aBaseCellPos(mpViewShell->GetViewData()->GetScrPos(mpViewShell->GetViewData()->GetPosX(eWhichH), + mpViewShell->GetViewData()->GetPosY(eWhichV), meSplitPos, sal_True)); + Point aCellPos(mpViewShell->GetViewData()->GetScrPos(maCellPos.Col(), maCellPos.Row(), meSplitPos, sal_True)); + aVisArea.SetPos(aCellPos - aBaseCellPos); + } + } + else + { + OSL_FAIL("this ViewForwarder is not valid"); + } + return aVisArea; +} + +Point ScViewForwarder::LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const +{ + if (mpViewShell) + { + Window* pWindow = mpViewShell->GetWindowByPos(meSplitPos); + if (pWindow) + return pWindow->LogicToPixel( rPoint, rMapMode ); + } + else + { + OSL_FAIL("this ViewForwarder is not valid"); + } + return Point(); +} + +Point ScViewForwarder::PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const +{ + if (mpViewShell) + { + Window* pWindow = mpViewShell->GetWindowByPos(meSplitPos); + if (pWindow) + return pWindow->PixelToLogic( rPoint, rMapMode ); + } + else + { + OSL_FAIL("this ViewForwarder is not valid"); + } + return Point(); +} + +void ScViewForwarder::SetInvalid() +{ + mpViewShell = NULL; +} + +// ============================================================================ + +class ScEditObjectViewForwarder : public SvxViewForwarder +{ + Window* mpWindow; + // #i49561# EditView needed for access to its visible area. + const EditView* mpEditView; +public: + ScEditObjectViewForwarder( Window* pWindow, + const EditView* _pEditView); + virtual ~ScEditObjectViewForwarder(); + + virtual sal_Bool IsValid() const; + virtual Rectangle GetVisArea() const; + virtual Point LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const; + virtual Point PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const; + + void SetInvalid(); +}; + +ScEditObjectViewForwarder::ScEditObjectViewForwarder( Window* pWindow, + const EditView* _pEditView ) + : + mpWindow(pWindow), + mpEditView( _pEditView ) +{ +} + +ScEditObjectViewForwarder::~ScEditObjectViewForwarder() +{ +} + +sal_Bool ScEditObjectViewForwarder::IsValid() const +{ + return (mpWindow != NULL); +} + +Rectangle ScEditObjectViewForwarder::GetVisArea() const +{ + Rectangle aVisArea; + if (mpWindow) + { + Rectangle aVisRect(mpWindow->GetWindowExtentsRelative(mpWindow->GetAccessibleParentWindow())); + + aVisRect.SetPos(Point(0, 0)); + + aVisArea = aVisRect; + } + else + { + OSL_FAIL("this ViewForwarder is not valid"); + } + return aVisArea; +} + +Point ScEditObjectViewForwarder::LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const +{ + if (mpWindow) + { + // #i49561# - consider offset of the visible area + // of the EditView before converting point to pixel. + Point aPoint( rPoint ); + if ( mpEditView ) + { + Rectangle aEditViewVisArea( mpEditView->GetVisArea() ); + aPoint += aEditViewVisArea.TopLeft(); + } + return mpWindow->LogicToPixel( aPoint, rMapMode ); + } + else + { + OSL_FAIL("this ViewForwarder is not valid"); + } + return Point(); +} + +Point ScEditObjectViewForwarder::PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const +{ + if (mpWindow) + { + // #i49561# - consider offset of the visible area + // of the EditView after converting point to logic. + Point aPoint( mpWindow->PixelToLogic( rPoint, rMapMode ) ); + if ( mpEditView ) + { + Rectangle aEditViewVisArea( mpEditView->GetVisArea() ); + aPoint -= aEditViewVisArea.TopLeft(); + } + return aPoint; + } + else + { + OSL_FAIL("this ViewForwarder is not valid"); + } + return Point(); +} + +void ScEditObjectViewForwarder::SetInvalid() +{ + mpWindow = NULL; +} + +class ScPreviewViewForwarder : public SvxViewForwarder +{ +protected: + ScPreviewShell* mpViewShell; + mutable ScPreviewTableInfo* mpTableInfo; +public: + ScPreviewViewForwarder(ScPreviewShell* pViewShell); + virtual ~ScPreviewViewForwarder(); + + virtual sal_Bool IsValid() const; + virtual Rectangle GetVisArea() const; + virtual Point LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const; + virtual Point PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const; + + void SetInvalid(); + + Rectangle GetVisRect() const; + + // clips the VisArea and calculates with the negativ coordinates + Rectangle CorrectVisArea(const Rectangle& rVisArea) const; +}; + +ScPreviewViewForwarder::ScPreviewViewForwarder(ScPreviewShell* pViewShell) + : + mpViewShell(pViewShell), + mpTableInfo(NULL) +{ +} + +ScPreviewViewForwarder::~ScPreviewViewForwarder() +{ + delete mpTableInfo; +} + +sal_Bool ScPreviewViewForwarder::IsValid() const +{ + return mpViewShell != NULL; +} + +Rectangle ScPreviewViewForwarder::GetVisArea() const +{ + Rectangle aVisArea; + OSL_FAIL("should be implemented in an abrevated class"); + return aVisArea; +} + +Point ScPreviewViewForwarder::LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const +{ + if (mpViewShell) + { + Window* pWindow = mpViewShell->GetWindow(); + if (pWindow) + { + MapMode aMapMode(pWindow->GetMapMode().GetMapUnit()); + Point aPoint2( OutputDevice::LogicToLogic( rPoint, rMapMode, aMapMode) ); + return pWindow->LogicToPixel(aPoint2); + } + } + else + { + OSL_FAIL("this ViewForwarder is not valid"); + } + return Point(); +} + +Point ScPreviewViewForwarder::PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const +{ + if (mpViewShell) + { + Window* pWindow = mpViewShell->GetWindow(); + if (pWindow) + { + MapMode aMapMode(pWindow->GetMapMode()); + aMapMode.SetOrigin(Point()); + Point aPoint1( pWindow->PixelToLogic( rPoint ) ); + Point aPoint2( OutputDevice::LogicToLogic( aPoint1, + aMapMode.GetMapUnit(), + rMapMode ) ); + return aPoint2; + } + } + else + { + OSL_FAIL("this ViewForwarder is not valid"); + } + return Point(); +} + +void ScPreviewViewForwarder::SetInvalid() +{ + mpViewShell = NULL; +} + +Rectangle ScPreviewViewForwarder::GetVisRect() const +{ + if ( mpViewShell ) + { + Size aOutputSize; + Window* pWindow = mpViewShell->GetWindow(); + if ( pWindow ) + aOutputSize = pWindow->GetOutputSizePixel(); + Point aPoint; + Rectangle aVisRect( aPoint, aOutputSize ); + return aVisRect; + } + return Rectangle(); +} + +Rectangle ScPreviewViewForwarder::CorrectVisArea(const Rectangle& rVisArea) const +{ + Rectangle aVisArea(rVisArea); + Point aPos = aVisArea.TopLeft(); // get first the position to remember negative positions after clipping + + Window* pWin = mpViewShell->GetWindow(); + if (pWin) + aVisArea = pWin->GetWindowExtentsRelative(pWin).GetIntersection(aVisArea); + + sal_Int32 nX(aPos.getX()); + sal_Int32 nY(aPos.getY()); + + if (nX > 0) + nX = 0; + else if (nX < 0) + nX = -nX; + if (nY > 0) + nY = 0; + else if (nY < 0) + nY = -nY; + aVisArea.SetPos(Point(nX, nY)); + + return aVisArea; +} + +class ScPreviewHeaderFooterViewForwarder : public ScPreviewViewForwarder +{ + sal_Bool mbHeader; +public: + ScPreviewHeaderFooterViewForwarder(ScPreviewShell* pViewShell, sal_Bool bHeader); + virtual ~ScPreviewHeaderFooterViewForwarder(); + + virtual Rectangle GetVisArea() const; +}; + +ScPreviewHeaderFooterViewForwarder::ScPreviewHeaderFooterViewForwarder(ScPreviewShell* pViewShell, sal_Bool bHeader) + : + ScPreviewViewForwarder(pViewShell), + mbHeader(bHeader) +{ +} + +ScPreviewHeaderFooterViewForwarder::~ScPreviewHeaderFooterViewForwarder() +{ +} + +Rectangle ScPreviewHeaderFooterViewForwarder::GetVisArea() const +{ + Rectangle aVisArea; + if (mpViewShell) + { + const ScPreviewLocationData& rData = mpViewShell->GetLocationData(); + if ( mbHeader ) + rData.GetHeaderPosition( aVisArea ); + else + rData.GetFooterPosition( aVisArea ); + + aVisArea = CorrectVisArea(aVisArea); + } + else + { + OSL_FAIL("this ViewForwarder is not valid"); + } + return aVisArea; +} + +class ScPreviewCellViewForwarder : public ScPreviewViewForwarder +{ + ScAddress maCellPos; +public: + ScPreviewCellViewForwarder(ScPreviewShell* pViewShell, + ScAddress aCellPos); + virtual ~ScPreviewCellViewForwarder(); + + virtual Rectangle GetVisArea() const; +}; + +ScPreviewCellViewForwarder::ScPreviewCellViewForwarder(ScPreviewShell* pViewShell, + ScAddress aCellPos) + : + ScPreviewViewForwarder(pViewShell), + maCellPos(aCellPos) +{ +} + +ScPreviewCellViewForwarder::~ScPreviewCellViewForwarder() +{ +} + +Rectangle ScPreviewCellViewForwarder::GetVisArea() const +{ + Rectangle aVisArea; + if (mpViewShell) + { + const ScPreviewLocationData& rData = mpViewShell->GetLocationData(); + aVisArea = rData.GetCellOutputRect(maCellPos); + + aVisArea = CorrectVisArea(aVisArea); + } + else + { + OSL_FAIL("this ViewForwarder is not valid"); + } + return aVisArea; +} + +class ScPreviewHeaderCellViewForwarder : public ScPreviewViewForwarder +{ + ScAddress maCellPos; + sal_Bool mbColHeader; + sal_Bool mbRowHeader; +public: + ScPreviewHeaderCellViewForwarder(ScPreviewShell* pViewShell, + ScAddress aCellPos, + sal_Bool bColHeader, sal_Bool bRowHeader); + virtual ~ScPreviewHeaderCellViewForwarder(); + + virtual Rectangle GetVisArea() const; +}; + +ScPreviewHeaderCellViewForwarder::ScPreviewHeaderCellViewForwarder(ScPreviewShell* pViewShell, + ScAddress aCellPos, + sal_Bool bColHeader, sal_Bool bRowHeader) + : + ScPreviewViewForwarder(pViewShell), + maCellPos(aCellPos), + mbColHeader(bColHeader), + mbRowHeader(bRowHeader) +{ +} + +ScPreviewHeaderCellViewForwarder::~ScPreviewHeaderCellViewForwarder() +{ +} + +Rectangle ScPreviewHeaderCellViewForwarder::GetVisArea() const +{ + Rectangle aVisArea; + if (mpViewShell) + { + const ScPreviewLocationData& rData = mpViewShell->GetLocationData(); + aVisArea = rData.GetHeaderCellOutputRect(GetVisRect(), maCellPos, mbColHeader); + + aVisArea = CorrectVisArea(aVisArea); + } + else + { + OSL_FAIL("this ViewForwarder is not valid"); + } + return aVisArea; +} + +class ScPreviewNoteViewForwarder : public ScPreviewViewForwarder +{ + ScAddress maCellPos; + sal_Bool mbNoteMark; +public: + ScPreviewNoteViewForwarder(ScPreviewShell* pViewShell, + ScAddress aCellPos, + sal_Bool bNoteMark); + virtual ~ScPreviewNoteViewForwarder(); + + virtual Rectangle GetVisArea() const; +}; + +ScPreviewNoteViewForwarder::ScPreviewNoteViewForwarder(ScPreviewShell* pViewShell, + ScAddress aCellPos, + sal_Bool bNoteMark) + : + ScPreviewViewForwarder(pViewShell), + maCellPos(aCellPos), + mbNoteMark(bNoteMark) +{ +} + +ScPreviewNoteViewForwarder::~ScPreviewNoteViewForwarder() +{ +} + +Rectangle ScPreviewNoteViewForwarder::GetVisArea() const +{ + Rectangle aVisArea; + if (mpViewShell) + { + const ScPreviewLocationData& rData = mpViewShell->GetLocationData(); + aVisArea = rData.GetNoteInRangeOutputRect(GetVisRect(), mbNoteMark, maCellPos); + + aVisArea = CorrectVisArea(aVisArea); + } + else + { + OSL_FAIL("this ViewForwarder is not valid"); + } + return aVisArea; +} + +class ScEditViewForwarder : public SvxEditViewForwarder +{ + EditView* mpEditView; + Window* mpWindow; +public: + ScEditViewForwarder(EditView* pEditView, Window* pWin); + virtual ~ScEditViewForwarder(); + + virtual sal_Bool IsValid() const; + virtual Rectangle GetVisArea() const; + virtual Point LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const; + virtual Point PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const; + virtual sal_Bool GetSelection( ESelection& rSelection ) const; + virtual sal_Bool SetSelection( const ESelection& rSelection ); + virtual sal_Bool Copy(); + virtual sal_Bool Cut(); + virtual sal_Bool Paste(); + + void GrabFocus(); + + void SetInvalid(); +}; + +ScEditViewForwarder::ScEditViewForwarder(EditView* pEditView, Window* pWin) + : mpEditView(pEditView), + mpWindow(pWin) +{ + GrabFocus(); +} + +ScEditViewForwarder::~ScEditViewForwarder() +{ +} + +sal_Bool ScEditViewForwarder::IsValid() const +{ + sal_Bool bResult(false); + if (mpWindow && mpEditView) + { + bResult = sal_True; + } + return bResult; +} + +Rectangle ScEditViewForwarder::GetVisArea() const +{ + Rectangle aVisArea; + if (IsValid() && mpEditView->GetEditEngine()) + { + MapMode aMapMode(mpEditView->GetEditEngine()->GetRefMapMode()); + + aVisArea = mpWindow->LogicToPixel( mpEditView->GetVisArea(), aMapMode ); + } + else + { + OSL_FAIL("this EditViewForwarder is no longer valid"); + } + return aVisArea; +} + +Point ScEditViewForwarder::LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const +{ + if (mpWindow) + return mpWindow->LogicToPixel( rPoint, rMapMode ); + else + { + OSL_FAIL("this ViewForwarder is not valid"); + } + return Point(); +} + +Point ScEditViewForwarder::PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const +{ + if (mpWindow) + return mpWindow->PixelToLogic( rPoint, rMapMode ); + else + { + OSL_FAIL("this ViewForwarder is not valid"); + } + return Point(); +} + +sal_Bool ScEditViewForwarder::GetSelection( ESelection& rSelection ) const +{ + sal_Bool bResult(false); + if (IsValid()) + { + rSelection = mpEditView->GetSelection(); + bResult = sal_True; + } + else + { + OSL_FAIL("this ViewForwarder is not valid"); + } + return bResult; +} + +sal_Bool ScEditViewForwarder::SetSelection( const ESelection& rSelection ) +{ + sal_Bool bResult(false); + if (IsValid()) + { + mpEditView->SetSelection(rSelection); + bResult = sal_True; + } + else + { + OSL_FAIL("this ViewForwarder is not valid"); + } + return bResult; +} + +sal_Bool ScEditViewForwarder::Copy() +{ + sal_Bool bResult(false); + if (IsValid()) + { + mpEditView->Copy(); + bResult = sal_True; + } + else + { + OSL_FAIL("this ViewForwarder is not valid"); + } + return bResult; +} + +sal_Bool ScEditViewForwarder::Cut() +{ + sal_Bool bResult(false); + if (IsValid()) + { + mpEditView->Cut(); + bResult = sal_True; + } + else + { + OSL_FAIL("this ViewForwarder is not valid"); + } + return bResult; +} + +sal_Bool ScEditViewForwarder::Paste() +{ + sal_Bool bResult(false); + if (IsValid()) + { + mpEditView->Paste(); + bResult = sal_True; + } + else + { + OSL_FAIL("this ViewForwarder is not valid"); + } + return bResult; +} + +void ScEditViewForwarder::GrabFocus() +{ +} + +void ScEditViewForwarder::SetInvalid() +{ + mpWindow = NULL; + mpEditView = NULL; +} + +// ScAccessibleCellTextData: shared data between sub objects of a accessible cell text object + +ScAccessibleCellTextData::ScAccessibleCellTextData(ScTabViewShell* pViewShell, + const ScAddress& rP, ScSplitPos eSplitPos, ScAccessibleCell* pAccCell) + : ScAccessibleCellBaseTextData(GetDocShell(pViewShell), rP), + mpViewForwarder(NULL), + mpEditViewForwarder(NULL), + mpViewShell(pViewShell), + meSplitPos(eSplitPos), + mbViewEditEngine(false), + mpAccessibleCell( pAccCell ) +{ +} + +ScAccessibleCellTextData::~ScAccessibleCellTextData() +{ + if (pEditEngine) + pEditEngine->SetNotifyHdl(Link()); + if (mpViewForwarder) + delete mpViewForwarder; + if (mpEditViewForwarder) + delete mpEditViewForwarder; +} + +void ScAccessibleCellTextData::Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) +{ + if ( rHint.ISA( SfxSimpleHint ) ) + { + sal_uLong nId = ((const SfxSimpleHint&)rHint).GetId(); + if ( nId == SFX_HINT_DYING ) + { + mpViewShell = NULL; // invalid now + if (mpViewForwarder) + mpViewForwarder->SetInvalid(); + if (mpEditViewForwarder) + mpEditViewForwarder->SetInvalid(); + } + } + ScAccessibleCellBaseTextData::Notify(rBC, rHint); +} + +ScAccessibleTextData* ScAccessibleCellTextData::Clone() const +{ + return new ScAccessibleCellTextData( mpViewShell, aCellPos, meSplitPos, mpAccessibleCell ); +} + +void ScAccessibleCellTextData::GetCellText(const ScAddress& rCellPos, String& rText) +{ +// #104893#; don't use the input string +// ScCellTextData::GetCellText(rCellPos, rText); + ScDocument* pDoc = pDocShell->GetDocument(); + if (pDoc) + { + // #104893#; use the displayed string + pDoc->GetString(rCellPos.Col(), rCellPos.Row(), rCellPos.Tab(), rText); + if (mpViewShell) + { + const ScViewOptions& aOptions = mpViewShell->GetViewData()->GetOptions(); + CellType aCellType; + pDoc->GetCellType(rCellPos.Col(), rCellPos.Row(), rCellPos.Tab(), aCellType); + if (aCellType == CELLTYPE_FORMULA && aOptions.GetOption( VOPT_FORMULAS )) + { + pDoc->GetFormula( rCellPos.Col(), rCellPos.Row(), rCellPos.Tab(), rText); + } + else if (!aOptions.GetOption( VOPT_NULLVALS )) + { + if ((aCellType == CELLTYPE_VALUE || aCellType == CELLTYPE_FORMULA) && pDoc->GetValue(rCellPos) == 0.0) + rText.Erase(); + } + } + } +} + +SvxTextForwarder* ScAccessibleCellTextData::GetTextForwarder() +{ + ScCellTextData::GetTextForwarder(); // creates Forwarder and EditEngine + + ScDocument* pDoc = ( pDocShell ? pDocShell->GetDocument() : NULL ); + if ( pDoc && pEditEngine && mpViewShell ) + { + long nSizeX, nSizeY; + mpViewShell->GetViewData()->GetMergeSizePixel( + aCellPos.Col(), aCellPos.Row(), nSizeX, nSizeY); + + Size aSize(nSizeX, nSizeY); + + // #i92143# text getRangeExtents reports incorrect 'x' values for spreadsheet cells + long nIndent = 0; + const SvxHorJustifyItem* pHorJustifyItem = static_cast< const SvxHorJustifyItem* >( + pDoc->GetAttr( aCellPos.Col(), aCellPos.Row(), aCellPos.Tab(), ATTR_HOR_JUSTIFY ) ); + SvxCellHorJustify eHorJust = ( pHorJustifyItem ? static_cast< SvxCellHorJustify >( pHorJustifyItem->GetValue() ) : SVX_HOR_JUSTIFY_STANDARD ); + if ( eHorJust == SVX_HOR_JUSTIFY_LEFT ) + { + const SfxUInt16Item* pIndentItem = static_cast< const SfxUInt16Item* >( + pDoc->GetAttr( aCellPos.Col(), aCellPos.Row(), aCellPos.Tab(), ATTR_INDENT ) ); + if ( pIndentItem ) + { + nIndent = static_cast< long >( pIndentItem->GetValue() ); + } + } + + const SvxMarginItem* pMarginItem = static_cast< const SvxMarginItem* >( + pDoc->GetAttr( aCellPos.Col(), aCellPos.Row(), aCellPos.Tab(), ATTR_MARGIN ) ); + ScViewData* pViewData = mpViewShell->GetViewData(); + double nPPTX = ( pViewData ? pViewData->GetPPTX() : 0 ); + double nPPTY = ( pViewData ? pViewData->GetPPTY() : 0 ); + long nLeftM = ( pMarginItem ? static_cast< long >( ( pMarginItem->GetLeftMargin() + nIndent ) * nPPTX ) : 0 ); + long nTopM = ( pMarginItem ? static_cast< long >( pMarginItem->GetTopMargin() * nPPTY ) : 0 ); + long nRightM = ( pMarginItem ? static_cast< long >( pMarginItem->GetRightMargin() * nPPTX ) : 0 ); + long nBottomM = ( pMarginItem ? static_cast< long >( pMarginItem->GetBottomMargin() * nPPTY ) : 0 ); + long nWidth = aSize.getWidth() - nLeftM - nRightM; + aSize.setWidth( nWidth ); + aSize.setHeight( aSize.getHeight() - nTopM - nBottomM ); + + Window* pWin = mpViewShell->GetWindowByPos( meSplitPos ); + if ( pWin ) + { + aSize = pWin->PixelToLogic( aSize, pEditEngine->GetRefMapMode() ); + } + + /* #i19430# Gnopernicus reads text partly if it sticks out of the cell + boundaries. This leads to wrong results in cases where the cell text + is rotated, because rotation is not taken into account when calcu- + lating the visible part of the text. In these cases we will expand + the cell size passed as paper size to the edit engine. The function + accessibility::AccessibleStaticTextBase::GetParagraphBoundingBox() + (see svx/source/accessibility/AccessibleStaticTextBase.cxx) will + return the size of the complete text then, which is used to expand + the cell bounding box in ScAccessibleCell::GetBoundingBox() + (see sc/source/ui/Accessibility/AccessibleCell.cxx). */ + const SfxInt32Item* pItem = static_cast< const SfxInt32Item* >( + pDoc->GetAttr( aCellPos.Col(), aCellPos.Row(), aCellPos.Tab(), ATTR_ROTATE_VALUE ) ); + if( pItem && (pItem->GetValue() != 0) ) + { + pEditEngine->SetPaperSize( Size( LONG_MAX, aSize.getHeight() ) ); + long nTxtWidth = static_cast< long >( pEditEngine->CalcTextWidth() ); + aSize.setWidth( std::max( aSize.getWidth(), nTxtWidth + 2 ) ); + } + else + { + // #i92143# text getRangeExtents reports incorrect 'x' values for spreadsheet cells + const SfxBoolItem* pLineBreakItem = static_cast< const SfxBoolItem* >( + pDoc->GetAttr( aCellPos.Col(), aCellPos.Row(), aCellPos.Tab(), ATTR_LINEBREAK ) ); + bool bLineBreak = ( pLineBreakItem && pLineBreakItem->GetValue() ); + if ( !bLineBreak ) + { + long nTxtWidth = static_cast< long >( pEditEngine->CalcTextWidth() ); + aSize.setWidth( ::std::max( aSize.getWidth(), nTxtWidth ) ); + } + } + + pEditEngine->SetPaperSize( aSize ); + + // #i92143# text getRangeExtents reports incorrect 'x' values for spreadsheet cells + if ( eHorJust == SVX_HOR_JUSTIFY_STANDARD && pDoc->HasValueData( aCellPos.Col(), aCellPos.Row(), aCellPos.Tab() ) ) + { + pEditEngine->SetDefaultItem( SvxAdjustItem( SVX_ADJUST_RIGHT, EE_PARA_JUST ) ); + } + + Size aTextSize; + if ( pWin ) + { + aTextSize = pWin->LogicToPixel( Size( pEditEngine->CalcTextWidth(), pEditEngine->GetTextHeight() ), pEditEngine->GetRefMapMode() ); + } + long nTextWidth = aTextSize.Width(); + long nTextHeight = aTextSize.Height(); + + long nOffsetX = nLeftM; + long nDiffX = nTextWidth - nWidth; + if ( nDiffX > 0 ) + { + switch ( eHorJust ) + { + case SVX_HOR_JUSTIFY_RIGHT: + { + nOffsetX -= nDiffX; + } + break; + case SVX_HOR_JUSTIFY_CENTER: + { + nOffsetX -= nDiffX / 2; + } + break; + default: + { + } + break; + } + } + + long nOffsetY = 0; + const SvxVerJustifyItem* pVerJustifyItem = static_cast< const SvxVerJustifyItem* >( + pDoc->GetAttr( aCellPos.Col(), aCellPos.Row(), aCellPos.Tab(), ATTR_VER_JUSTIFY ) ); + SvxCellVerJustify eVerJust = ( pVerJustifyItem ? static_cast< SvxCellVerJustify >( pVerJustifyItem->GetValue() ) : SVX_VER_JUSTIFY_STANDARD ); + switch ( eVerJust ) + { + case SVX_VER_JUSTIFY_STANDARD: + case SVX_VER_JUSTIFY_BOTTOM: + { + nOffsetY = nSizeY - nBottomM - nTextHeight; + } + break; + case SVX_VER_JUSTIFY_CENTER: + { + nOffsetY = ( nSizeY - nTopM - nBottomM - nTextHeight ) / 2 + nTopM; + } + break; + default: + { + nOffsetY = nTopM; + } + break; + } + + if ( mpAccessibleCell ) + { + mpAccessibleCell->SetOffset( Point( nOffsetX, nOffsetY ) ); + } + + pEditEngine->SetNotifyHdl( LINK(this, ScAccessibleCellTextData, NotifyHdl) ); + } + + return pForwarder; +} + +SvxViewForwarder* ScAccessibleCellTextData::GetViewForwarder() +{ + if (!mpViewForwarder) + mpViewForwarder = new ScViewForwarder(mpViewShell, meSplitPos, aCellPos); + return mpViewForwarder; +} + +SvxEditViewForwarder* ScAccessibleCellTextData::GetEditViewForwarder( sal_Bool /* bCreate */ ) +{ + //#102219#; there should no EditViewForwarder be, because the cell is now readonly in this interface + return NULL; +} + +IMPL_LINK(ScAccessibleCellTextData, NotifyHdl, EENotify*, aNotify) +{ + if( aNotify ) + { + ::std::auto_ptr< SfxHint > aHint = SvxEditSourceHelper::EENotification2Hint( aNotify ); + + if( aHint.get() ) + GetBroadcaster().Broadcast( *aHint.get() ); + } + + return 0; +} + +ScDocShell* ScAccessibleCellTextData::GetDocShell(ScTabViewShell* pViewShell) +{ + ScDocShell* pDocSh = NULL; + if (pViewShell) + pDocSh = pViewShell->GetViewData()->GetDocShell(); + return pDocSh; +} + + +ScAccessibleEditObjectTextData::ScAccessibleEditObjectTextData(EditView* pEditView, Window* pWin) + : + mpViewForwarder(NULL), + mpEditViewForwarder(NULL), + mpEditView(pEditView), + mpEditEngine(pEditView ? pEditView->GetEditEngine() : 0), + mpForwarder(NULL), + mpWindow(pWin) +{ + if (mpEditEngine) + mpEditEngine->SetNotifyHdl( LINK(this, ScAccessibleEditObjectTextData, NotifyHdl) ); +} + +ScAccessibleEditObjectTextData::~ScAccessibleEditObjectTextData() +{ + if (mpEditEngine) + mpEditEngine->SetNotifyHdl(Link()); + if (mpViewForwarder) + delete mpViewForwarder; + if (mpEditViewForwarder) + delete mpEditViewForwarder; + if (mpForwarder) + delete mpForwarder; +} + +void ScAccessibleEditObjectTextData::Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) +{ + if ( rHint.ISA( SfxSimpleHint ) ) + { + sal_uLong nId = ((const SfxSimpleHint&)rHint).GetId(); + if ( nId == SFX_HINT_DYING ) + { + mpWindow = NULL; + mpEditView = NULL; + mpEditEngine = NULL; + DELETEZ(mpForwarder); + if (mpViewForwarder) + mpViewForwarder->SetInvalid(); + if (mpEditViewForwarder) + mpEditViewForwarder->SetInvalid(); + } + } + ScAccessibleTextData::Notify(rBC, rHint); +} + +ScAccessibleTextData* ScAccessibleEditObjectTextData::Clone() const +{ + return new ScAccessibleEditObjectTextData(mpEditView, mpWindow); +} + +SvxTextForwarder* ScAccessibleEditObjectTextData::GetTextForwarder() +{ + if ((!mpForwarder && mpEditView) || (mpEditEngine && !mpEditEngine->GetNotifyHdl().IsSet())) + { + if (!mpEditEngine) + mpEditEngine = mpEditView->GetEditEngine(); + if (mpEditEngine && !mpEditEngine->GetNotifyHdl().IsSet()) + mpEditEngine->SetNotifyHdl( LINK(this, ScAccessibleEditObjectTextData, NotifyHdl) ); + if(!mpForwarder) + mpForwarder = new SvxEditEngineForwarder(*mpEditEngine); + } + return mpForwarder; +} + +SvxViewForwarder* ScAccessibleEditObjectTextData::GetViewForwarder() +{ + if (!mpViewForwarder) + { + // i#49561 Get right-aligned cell content to be read by screenreader. + mpViewForwarder = new ScEditObjectViewForwarder( mpWindow, mpEditView ); + } + return mpViewForwarder; +} + +SvxEditViewForwarder* ScAccessibleEditObjectTextData::GetEditViewForwarder( sal_Bool bCreate ) +{ + if (!mpEditViewForwarder && mpEditView) + mpEditViewForwarder = new ScEditViewForwarder(mpEditView, mpWindow); + if (bCreate) + { + if (!mpEditView && mpEditViewForwarder) + { + DELETEZ(mpEditViewForwarder); + } + else if (mpEditViewForwarder) + mpEditViewForwarder->GrabFocus(); + } + return mpEditViewForwarder; +} + +IMPL_LINK(ScAccessibleEditObjectTextData, NotifyHdl, EENotify*, aNotify) +{ + if( aNotify ) + { + ::std::auto_ptr< SfxHint > aHint = SvxEditSourceHelper::EENotification2Hint( aNotify ); + + if( aHint.get() ) + GetBroadcaster().Broadcast( *aHint.get() ); + } + + return 0; +} + +ScAccessibleEditLineTextData::ScAccessibleEditLineTextData(EditView* pEditView, Window* pWin) + : + ScAccessibleEditObjectTextData(pEditView, pWin), + mbEditEngineCreated(false) +{ + ScTextWnd* pTxtWnd = (ScTextWnd*)pWin; + + if (pTxtWnd) + pTxtWnd->InsertAccessibleTextData( *this ); +} + +ScAccessibleEditLineTextData::~ScAccessibleEditLineTextData() +{ + ScTextWnd* pTxtWnd = (ScTextWnd*)mpWindow; + + if (pTxtWnd) + pTxtWnd->RemoveAccessibleTextData( *this ); + + if (mbEditEngineCreated && mpEditEngine) + { + delete mpEditEngine; + mpEditEngine = NULL; // don't access in ScAccessibleEditObjectTextData dtor! + } + else if (pTxtWnd && pTxtWnd->GetEditView() && pTxtWnd->GetEditView()->GetEditEngine()) + { + // the NotifyHdl also has to be removed from the ScTextWnd's EditEngine + // (it's set in ScAccessibleEditLineTextData::GetTextForwarder, and mpEditEngine + // is reset there) + pTxtWnd->GetEditView()->GetEditEngine()->SetNotifyHdl(Link()); + } +} + +void ScAccessibleEditLineTextData::Dispose() +{ + ScTextWnd* pTxtWnd = (ScTextWnd*)mpWindow; + + if (pTxtWnd) + pTxtWnd->RemoveAccessibleTextData( *this ); + + ResetEditMode(); + mpWindow = NULL; +} + +ScAccessibleTextData* ScAccessibleEditLineTextData::Clone() const +{ + return new ScAccessibleEditLineTextData(mpEditView, mpWindow); +} + +SvxTextForwarder* ScAccessibleEditLineTextData::GetTextForwarder() +{ + ScTextWnd* pTxtWnd = (ScTextWnd*)mpWindow; + + if (pTxtWnd) + { + mpEditView = pTxtWnd->GetEditView(); + if (mpEditView) + { + if (mbEditEngineCreated && mpEditEngine) + ResetEditMode(); + mbEditEngineCreated = false; + + mpEditView = pTxtWnd->GetEditView(); + ScAccessibleEditObjectTextData::GetTextForwarder(); // fill the mpForwarder + mpEditEngine = NULL; + } + else + { + if (mpEditEngine && !mbEditEngineCreated) + ResetEditMode(); + if (!mpEditEngine) + { + SfxItemPool* pEnginePool = EditEngine::CreatePool(); + pEnginePool->FreezeIdRanges(); + mpEditEngine = new ScFieldEditEngine( pEnginePool, NULL, sal_True ); + mbEditEngineCreated = sal_True; + mpEditEngine->EnableUndo( false ); + mpEditEngine->SetRefMapMode( MAP_100TH_MM ); + mpForwarder = new SvxEditEngineForwarder(*mpEditEngine); + + mpEditEngine->SetText(pTxtWnd->GetTextString()); + + Size aSize(pTxtWnd->GetSizePixel()); + + aSize = pTxtWnd->PixelToLogic(aSize, mpEditEngine->GetRefMapMode()); + + mpEditEngine->SetPaperSize(aSize); + + mpEditEngine->SetNotifyHdl( LINK(this, ScAccessibleEditObjectTextData, NotifyHdl) ); + } + } + } + return mpForwarder; +} + +SvxEditViewForwarder* ScAccessibleEditLineTextData::GetEditViewForwarder( sal_Bool bCreate ) +{ + ScTextWnd* pTxtWnd = (ScTextWnd*)mpWindow; + + if (pTxtWnd) + { + mpEditView = pTxtWnd->GetEditView(); + if (!mpEditView && bCreate) + { + if ( !pTxtWnd->IsInputActive() ) + { + pTxtWnd->StartEditEngine(); + pTxtWnd->GrabFocus(); + + mpEditView = pTxtWnd->GetEditView(); + } + } + } + + return ScAccessibleEditObjectTextData::GetEditViewForwarder(bCreate); +} + +void ScAccessibleEditLineTextData::ResetEditMode() +{ + ScTextWnd* pTxtWnd = (ScTextWnd*)mpWindow; + + if (mbEditEngineCreated && mpEditEngine) + delete mpEditEngine; + else if (pTxtWnd && pTxtWnd->GetEditView() && pTxtWnd->GetEditView()->GetEditEngine()) + pTxtWnd->GetEditView()->GetEditEngine()->SetNotifyHdl(Link()); + mpEditEngine = NULL; + + DELETEZ(mpForwarder); + DELETEZ(mpEditViewForwarder); + DELETEZ(mpViewForwarder); + mbEditEngineCreated = false; +} + +void ScAccessibleEditLineTextData::TextChanged() +{ + if (mbEditEngineCreated && mpEditEngine) + { + ScTextWnd* pTxtWnd = (ScTextWnd*)mpWindow; + + if (pTxtWnd) + mpEditEngine->SetText(pTxtWnd->GetTextString()); + } +} + +void ScAccessibleEditLineTextData::StartEdit() +{ + ResetEditMode(); + mpEditView = NULL; + + // send HINT_BEGEDIT + SdrHint aHint(HINT_BEGEDIT); + GetBroadcaster().Broadcast( aHint ); +} + +void ScAccessibleEditLineTextData::EndEdit() +{ + // send HINT_ENDEDIT + SdrHint aHint(HINT_ENDEDIT); + GetBroadcaster().Broadcast( aHint ); + + ResetEditMode(); + mpEditView = NULL; +} + + +// ScAccessiblePreviewCellTextData: shared data between sub objects of a accessible cell text object + +ScAccessiblePreviewCellTextData::ScAccessiblePreviewCellTextData(ScPreviewShell* pViewShell, + const ScAddress& rP) + : ScAccessibleCellBaseTextData(GetDocShell(pViewShell), rP), + mpViewForwarder(NULL), + mpViewShell(pViewShell) +{ +} + +ScAccessiblePreviewCellTextData::~ScAccessiblePreviewCellTextData() +{ + if (pEditEngine) + pEditEngine->SetNotifyHdl(Link()); + if (mpViewForwarder) + delete mpViewForwarder; +} + +void ScAccessiblePreviewCellTextData::Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) +{ + if ( rHint.ISA( SfxSimpleHint ) ) + { + sal_uLong nId = ((const SfxSimpleHint&)rHint).GetId(); + if ( nId == SFX_HINT_DYING ) + { + mpViewShell = NULL; // invalid now + if (mpViewForwarder) + mpViewForwarder->SetInvalid(); + } + } + ScAccessibleCellBaseTextData::Notify(rBC, rHint); +} + +ScAccessibleTextData* ScAccessiblePreviewCellTextData::Clone() const +{ + return new ScAccessiblePreviewCellTextData(mpViewShell, aCellPos); +} + +SvxTextForwarder* ScAccessiblePreviewCellTextData::GetTextForwarder() +{ + sal_Bool bEditEngineBefore(pEditEngine != NULL); + + ScCellTextData::GetTextForwarder(); // creates Forwarder and EditEngine + + if (!bEditEngineBefore && pEditEngine) + { + Size aSize(mpViewShell->GetLocationData().GetCellOutputRect(aCellPos).GetSize()); + Window* pWin = mpViewShell->GetWindow(); + if (pWin) + aSize = pWin->PixelToLogic(aSize, pEditEngine->GetRefMapMode()); + pEditEngine->SetPaperSize(aSize); + } + + if (pEditEngine) + pEditEngine->SetNotifyHdl( LINK(this, ScAccessibleCellTextData, NotifyHdl) ); + + return pForwarder; +} + +SvxViewForwarder* ScAccessiblePreviewCellTextData::GetViewForwarder() +{ + if (!mpViewForwarder) + mpViewForwarder = new ScPreviewCellViewForwarder(mpViewShell, aCellPos); + return mpViewForwarder; +} + +ScDocShell* ScAccessiblePreviewCellTextData::GetDocShell(ScPreviewShell* pViewShell) +{ + ScDocShell* pDocSh = NULL; + if (pViewShell && pViewShell->GetDocument()) + pDocSh = (ScDocShell*) pViewShell->GetDocument()->GetDocumentShell(); + return pDocSh; +} + + +// ScAccessiblePreviewHeaderCellTextData: shared data between sub objects of a accessible cell text object + +ScAccessiblePreviewHeaderCellTextData::ScAccessiblePreviewHeaderCellTextData(ScPreviewShell* pViewShell, + const String& rText, const ScAddress& rP, sal_Bool bColHeader, sal_Bool bRowHeader) + : ScAccessibleCellBaseTextData(GetDocShell(pViewShell), rP), + mpViewForwarder(NULL), + mpViewShell(pViewShell), + maText(rText), + mbColHeader(bColHeader), + mbRowHeader(bRowHeader) +{ +} + +ScAccessiblePreviewHeaderCellTextData::~ScAccessiblePreviewHeaderCellTextData() +{ + if (pEditEngine) + pEditEngine->SetNotifyHdl(Link()); + if (mpViewForwarder) + delete mpViewForwarder; +} + +void ScAccessiblePreviewHeaderCellTextData::Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) +{ + if ( rHint.ISA( SfxSimpleHint ) ) + { + sal_uLong nId = ((const SfxSimpleHint&)rHint).GetId(); + if ( nId == SFX_HINT_DYING ) + { + mpViewShell = NULL; // invalid now + if (mpViewForwarder) + mpViewForwarder->SetInvalid(); + } + } + ScAccessibleCellBaseTextData::Notify(rBC, rHint); +} + +ScAccessibleTextData* ScAccessiblePreviewHeaderCellTextData::Clone() const +{ + return new ScAccessiblePreviewHeaderCellTextData(mpViewShell, maText, aCellPos, mbColHeader, mbRowHeader); +} + +SvxTextForwarder* ScAccessiblePreviewHeaderCellTextData::GetTextForwarder() +{ + if (!pEditEngine) + { + if ( pDocShell ) + { + ScDocument* pDoc = pDocShell->GetDocument(); + pEditEngine = pDoc->CreateFieldEditEngine(); + } + else + { + SfxItemPool* pEnginePool = EditEngine::CreatePool(); + pEnginePool->FreezeIdRanges(); + pEditEngine = new ScFieldEditEngine( pEnginePool, NULL, sal_True ); + } + pEditEngine->EnableUndo( false ); + if (pDocShell) + pEditEngine->SetRefDevice(pDocShell->GetRefDevice()); + else + pEditEngine->SetRefMapMode( MAP_100TH_MM ); + pForwarder = new SvxEditEngineForwarder(*pEditEngine); + } + + if (bDataValid) + return pForwarder; + + if (maText.Len() && pEditEngine) + { + + if ( mpViewShell ) + { + Size aOutputSize; + Window* pWindow = mpViewShell->GetWindow(); + if ( pWindow ) + aOutputSize = pWindow->GetOutputSizePixel(); + Point aPoint; + Rectangle aVisRect( aPoint, aOutputSize ); + Size aSize(mpViewShell->GetLocationData().GetHeaderCellOutputRect(aVisRect, aCellPos, mbColHeader).GetSize()); + if (pWindow) + aSize = pWindow->PixelToLogic(aSize, pEditEngine->GetRefMapMode()); + pEditEngine->SetPaperSize(aSize); + } + pEditEngine->SetText( maText ); + } + + bDataValid = sal_True; + + if (pEditEngine) + pEditEngine->SetNotifyHdl( LINK(this, ScAccessibleCellTextData, NotifyHdl) ); + + return pForwarder; +} + +SvxViewForwarder* ScAccessiblePreviewHeaderCellTextData::GetViewForwarder() +{ + if (!mpViewForwarder) + mpViewForwarder = new ScPreviewHeaderCellViewForwarder(mpViewShell, aCellPos, mbColHeader, mbRowHeader); + return mpViewForwarder; +} + +ScDocShell* ScAccessiblePreviewHeaderCellTextData::GetDocShell(ScPreviewShell* pViewShell) +{ + ScDocShell* pDocSh = NULL; + if (pViewShell && pViewShell->GetDocument()) + pDocSh = (ScDocShell*) pViewShell->GetDocument()->GetDocumentShell(); + return pDocSh; +} + +ScAccessibleHeaderTextData::ScAccessibleHeaderTextData(ScPreviewShell* pViewShell, + const EditTextObject* pEditObj, sal_Bool bHeader, SvxAdjust eAdjust) + : + mpViewForwarder(NULL), + mpViewShell(pViewShell), + mpEditEngine(NULL), + mpForwarder(NULL), + mpDocSh(NULL), + mpEditObj(pEditObj), + mbHeader(bHeader), + mbDataValid(false), + meAdjust(eAdjust) +{ + if (pViewShell && pViewShell->GetDocument()) + mpDocSh = (ScDocShell*) pViewShell->GetDocument()->GetDocumentShell(); + if (mpDocSh) + mpDocSh->GetDocument()->AddUnoObject(*this); +} + +ScAccessibleHeaderTextData::~ScAccessibleHeaderTextData() +{ + SolarMutexGuard aGuard; // needed for EditEngine dtor + + if (mpDocSh) + mpDocSh->GetDocument()->RemoveUnoObject(*this); + if (mpEditEngine) + mpEditEngine->SetNotifyHdl(Link()); + delete mpEditEngine; + delete mpForwarder; +} + +ScAccessibleTextData* ScAccessibleHeaderTextData::Clone() const +{ + return new ScAccessibleHeaderTextData(mpViewShell, mpEditObj, mbHeader, meAdjust); +} + +void ScAccessibleHeaderTextData::Notify( SfxBroadcaster&, const SfxHint& rHint ) +{ + if ( rHint.ISA( SfxSimpleHint ) ) + { + sal_uLong nId = ((const SfxSimpleHint&)rHint).GetId(); + if ( nId == SFX_HINT_DYING ) + { + mpViewShell = NULL;// invalid now + mpDocSh = NULL; + if (mpViewForwarder) + mpViewForwarder->SetInvalid(); + } + } +} + +SvxTextForwarder* ScAccessibleHeaderTextData::GetTextForwarder() +{ + if (!mpEditEngine) + { + SfxItemPool* pEnginePool = EditEngine::CreatePool(); + pEnginePool->FreezeIdRanges(); + ScHeaderEditEngine* pHdrEngine = new ScHeaderEditEngine( pEnginePool, sal_True ); + + pHdrEngine->EnableUndo( false ); + pHdrEngine->SetRefMapMode( MAP_TWIP ); + + // default font must be set, independently of document + // -> use global pool from module + + SfxItemSet aDefaults( pHdrEngine->GetEmptyItemSet() ); + const ScPatternAttr& rPattern = (const ScPatternAttr&)SC_MOD()->GetPool().GetDefaultItem(ATTR_PATTERN); + rPattern.FillEditItemSet( &aDefaults ); + // FillEditItemSet adjusts font height to 1/100th mm, + // but for header/footer twips is needed, as in the PatternAttr: + aDefaults.Put( rPattern.GetItem(ATTR_FONT_HEIGHT), EE_CHAR_FONTHEIGHT ); + aDefaults.Put( rPattern.GetItem(ATTR_CJK_FONT_HEIGHT), EE_CHAR_FONTHEIGHT_CJK ); + aDefaults.Put( rPattern.GetItem(ATTR_CTL_FONT_HEIGHT), EE_CHAR_FONTHEIGHT_CTL ); + aDefaults.Put( SvxAdjustItem( meAdjust, EE_PARA_JUST ) ); + pHdrEngine->SetDefaults( aDefaults ); + + ScHeaderFieldData aData; + if (mpViewShell) + mpViewShell->FillFieldData(aData); + else + ScHeaderFooterTextObj::FillDummyFieldData( aData ); + pHdrEngine->SetData( aData ); + + mpEditEngine = pHdrEngine; + mpForwarder = new SvxEditEngineForwarder(*mpEditEngine); + } + + if (mbDataValid) + return mpForwarder; + + if ( mpViewShell ) + { + Rectangle aVisRect; + mpViewShell->GetLocationData().GetHeaderPosition(aVisRect); + Size aSize(aVisRect.GetSize()); + Window* pWin = mpViewShell->GetWindow(); + if (pWin) + aSize = pWin->PixelToLogic(aSize, mpEditEngine->GetRefMapMode()); + mpEditEngine->SetPaperSize(aSize); + } + if (mpEditObj) + mpEditEngine->SetText(*mpEditObj); + + mbDataValid = sal_True; + return mpForwarder; +} + +SvxViewForwarder* ScAccessibleHeaderTextData::GetViewForwarder() +{ + if (!mpViewForwarder) + mpViewForwarder = new ScPreviewHeaderFooterViewForwarder(mpViewShell, mbHeader); + return mpViewForwarder; +} + +ScAccessibleNoteTextData::ScAccessibleNoteTextData(ScPreviewShell* pViewShell, + const String& sText, const ScAddress& aCellPos, sal_Bool bMarkNote) + : + mpViewForwarder(NULL), + mpViewShell(pViewShell), + mpEditEngine(NULL), + mpForwarder(NULL), + mpDocSh(NULL), + msText(sText), + maCellPos(aCellPos), + mbMarkNote(bMarkNote), + mbDataValid(false) +{ + if (pViewShell && pViewShell->GetDocument()) + mpDocSh = (ScDocShell*) pViewShell->GetDocument()->GetDocumentShell(); + if (mpDocSh) + mpDocSh->GetDocument()->AddUnoObject(*this); +} + +ScAccessibleNoteTextData::~ScAccessibleNoteTextData() +{ + SolarMutexGuard aGuard; // needed for EditEngine dtor + + if (mpDocSh) + mpDocSh->GetDocument()->RemoveUnoObject(*this); + if (mpEditEngine) + mpEditEngine->SetNotifyHdl(Link()); + delete mpEditEngine; + delete mpForwarder; +} + +ScAccessibleTextData* ScAccessibleNoteTextData::Clone() const +{ + return new ScAccessibleNoteTextData(mpViewShell, msText, maCellPos, mbMarkNote); +} + +void ScAccessibleNoteTextData::Notify( SfxBroadcaster&, const SfxHint& rHint ) +{ + if ( rHint.ISA( SfxSimpleHint ) ) + { + sal_uLong nId = ((const SfxSimpleHint&)rHint).GetId(); + if ( nId == SFX_HINT_DYING ) + { + mpViewShell = NULL;// invalid now + mpDocSh = NULL; + if (mpViewForwarder) + mpViewForwarder->SetInvalid(); + } + } +} + +SvxTextForwarder* ScAccessibleNoteTextData::GetTextForwarder() +{ + if (!mpEditEngine) + { + if ( mpDocSh ) + { + ScDocument* pDoc = mpDocSh->GetDocument(); + mpEditEngine = pDoc->CreateFieldEditEngine(); + } + else + { + SfxItemPool* pEnginePool = EditEngine::CreatePool(); + pEnginePool->FreezeIdRanges(); + mpEditEngine = new ScFieldEditEngine( pEnginePool, NULL, sal_True ); + } + mpEditEngine->EnableUndo( false ); + if (mpDocSh) + mpEditEngine->SetRefDevice(mpDocSh->GetRefDevice()); + else + mpEditEngine->SetRefMapMode( MAP_100TH_MM ); + mpForwarder = new SvxEditEngineForwarder(*mpEditEngine); + } + + if (mbDataValid) + return mpForwarder; + + if (msText.Len() && mpEditEngine) + { + + if ( mpViewShell ) + { + Size aOutputSize; + Window* pWindow = mpViewShell->GetWindow(); + if ( pWindow ) + aOutputSize = pWindow->GetOutputSizePixel(); + Point aPoint; + Rectangle aVisRect( aPoint, aOutputSize ); + Size aSize(mpViewShell->GetLocationData().GetNoteInRangeOutputRect(aVisRect, mbMarkNote, maCellPos).GetSize()); + if (pWindow) + aSize = pWindow->PixelToLogic(aSize, mpEditEngine->GetRefMapMode()); + mpEditEngine->SetPaperSize(aSize); + } + mpEditEngine->SetText( msText ); + } + + mbDataValid = sal_True; + + if (mpEditEngine) + mpEditEngine->SetNotifyHdl( LINK(this, ScAccessibleCellTextData, NotifyHdl) ); + + return mpForwarder; +} + +SvxViewForwarder* ScAccessibleNoteTextData::GetViewForwarder() +{ + if (!mpViewForwarder) + mpViewForwarder = new ScPreviewNoteViewForwarder(mpViewShell, maCellPos, mbMarkNote); + return mpViewForwarder; +} + + +// CSV import ================================================================= + +class ScCsvViewForwarder : public SvxViewForwarder +{ + Rectangle maBoundBox; + Window* mpWindow; + +public: + explicit ScCsvViewForwarder( Window* pWindow, const Rectangle& rBoundBox ); + + virtual sal_Bool IsValid() const; + virtual Rectangle GetVisArea() const; + virtual Point LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const; + virtual Point PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const; + + void SetInvalid(); +}; + +ScCsvViewForwarder::ScCsvViewForwarder( Window* pWindow, const Rectangle& rBoundBox ) : + maBoundBox( rBoundBox ), + mpWindow( pWindow ) +{ +} + +sal_Bool ScCsvViewForwarder::IsValid() const +{ + return mpWindow != NULL; +} + +Rectangle ScCsvViewForwarder::GetVisArea() const +{ + return maBoundBox; +} + +Point ScCsvViewForwarder::LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const +{ + if( !mpWindow ) return Point(); + return mpWindow->LogicToPixel( rPoint, rMapMode ); +} + +Point ScCsvViewForwarder::PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const +{ + if( !mpWindow ) return Point(); + return mpWindow->PixelToLogic( rPoint, rMapMode ); +} + +void ScCsvViewForwarder::SetInvalid() +{ + mpWindow = NULL; +} + +ScAccessibleCsvTextData::ScAccessibleCsvTextData( + Window* pWindow, EditEngine* pEditEngine, + const String& rCellText, const Rectangle& rBoundBox, const Size& rCellSize ) : + mpWindow( pWindow ), + mpEditEngine( pEditEngine ), + maCellText( rCellText ), + maBoundBox( rBoundBox ), + maCellSize( rCellSize ) +{ +} + +ScAccessibleCsvTextData::~ScAccessibleCsvTextData() +{ +} + +void ScAccessibleCsvTextData::Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) +{ + if ( rHint.ISA( SfxSimpleHint ) ) + { + sal_uLong nId = ((const SfxSimpleHint&)rHint).GetId(); + if( nId == SFX_HINT_DYING ) + { + mpWindow = NULL; + mpEditEngine = NULL; + if (mpViewForwarder.get()) + mpViewForwarder->SetInvalid(); + } + } + ScAccessibleTextData::Notify( rBC, rHint ); +} + +ScAccessibleTextData* ScAccessibleCsvTextData::Clone() const +{ + return new ScAccessibleCsvTextData( mpWindow, mpEditEngine, maCellText, maBoundBox, maCellSize ); +} + +SvxTextForwarder* ScAccessibleCsvTextData::GetTextForwarder() +{ + if( mpEditEngine ) + { + mpEditEngine->SetPaperSize( maCellSize ); + mpEditEngine->SetText( maCellText ); + if( !mpTextForwarder.get() ) + mpTextForwarder.reset( new SvxEditEngineForwarder( *mpEditEngine ) ); + } + else + mpTextForwarder.reset( NULL ); + return mpTextForwarder.get(); +} + +SvxViewForwarder* ScAccessibleCsvTextData::GetViewForwarder() +{ + if( !mpViewForwarder.get() ) + mpViewForwarder.reset( new ScCsvViewForwarder( mpWindow, maBoundBox ) ); + return mpViewForwarder.get(); +} + +SvxEditViewForwarder* ScAccessibleCsvTextData::GetEditViewForwarder( sal_Bool /* bCreate */ ) +{ + return NULL; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |