lok - add support for in place chart editing

This commit add a minimal support for editing chart embedded in a
spreadsheet or a text document or a presentation.
Graphic objects can be moved and resized, text objects can be edited.

Change-Id: I8e637dabf328a94bd6bb0e309a245302cff421d8
Reviewed-on: https://gerrit.libreoffice.org/39342
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Marco Cecchetti <mrcekets@gmail.com>
This commit is contained in:
Marco Cecchetti
2017-08-03 10:58:59 +02:00
committed by Marco Cecchetti
parent 166f13ef65
commit eba883c8a2
24 changed files with 977 additions and 29 deletions
@@ -488,6 +488,8 @@ private:
void executeDispatch_ToggleGridHorizontal();
void executeDispatch_ToggleGridVertical();
void executeDispatch_LOKSetTextSelection(int nType, int nX, int nY);
void sendPopupRequest(OUString const & rCID, tools::Rectangle aRectangle);
void impl_ShapeControllerDispatch( const css::util::URL& rURL,
@@ -58,6 +58,7 @@ public:
virtual void Invalidate( InvalidateFlags nFlags = InvalidateFlags::NONE ) override;
virtual void Invalidate( const tools::Rectangle& rRect, InvalidateFlags nFlags = InvalidateFlags::NONE ) override;
virtual void Invalidate( const vcl::Region& rRegion, InvalidateFlags nFlags = InvalidateFlags::NONE ) override;
virtual void LogicInvalidate( const tools::Rectangle* pRectangle ) override;
virtual css::uno::Reference< css::accessibility::XAccessible > CreateAccessible() override;
@@ -65,9 +66,17 @@ public:
ChartController* GetController();
virtual bool IsChart() const override { return true; }
vcl::Window* GetParentEditWin();
private:
// returns the chart bounding box in twips
tools::Rectangle GetBoundingBox();
private:
ChartController* m_pWindowController;
bool m_bInPaint;
VclPtr<vcl::Window> m_pViewShellWindow;
VclPtr<vcl::Window> m_pOpenGLWindow;
void adjustHighContrastMode();
@@ -1091,7 +1091,20 @@ void SAL_CALL ChartController::dispatch(
{
OUString aCommand = rURL.Path;
if(aCommand == "Paste")
if(aCommand == "LOKSetTextSelection")
{
if (rArgs.getLength() == 3)
{
sal_Int32 nType = -1;
rArgs[0].Value >>= nType;
sal_Int32 nX = 0;
rArgs[1].Value >>= nX;
sal_Int32 nY = 0;
rArgs[2].Value >>= nY;
executeDispatch_LOKSetTextSelection(nType, nX, nY);
}
}
else if(aCommand == "Paste")
this->executeDispatch_Paste();
else if(aCommand == "Copy" )
this->executeDispatch_Copy();
@@ -52,6 +52,8 @@
#include <com/sun/star/drawing/TextHorizontalAdjust.hpp>
#include <com/sun/star/chart/ErrorBarStyle.hpp>
#include <editeng/editview.hxx>
#include <editeng/outliner.hxx>
#include <svx/ActionDescriptionProvider.hxx>
#include <svtools/transfer.hxx>
#include <sot/storage.hxx>
@@ -70,6 +72,8 @@
#include <svx/unoapi.hxx>
#include <svx/unopage.hxx>
#include <LibreOfficeKit/LibreOfficeKitEnums.h>
#include <memory>
using namespace ::com::sun::star;
@@ -923,6 +927,37 @@ void ChartController::executeDispatch_ToggleGridVertical()
}
}
void ChartController::executeDispatch_LOKSetTextSelection(int nType, int nX, int nY)
{
if (m_pDrawViewWrapper)
{
if (m_pDrawViewWrapper->IsTextEdit())
{
OutlinerView* pOutlinerView = m_pDrawViewWrapper->GetTextEditOutlinerView();
if (pOutlinerView)
{
EditView& rEditView = pOutlinerView->GetEditView();
Point aPoint(convertTwipToMm100(nX), convertTwipToMm100(nY));
switch (nType)
{
case LOK_SETTEXTSELECTION_START:
rEditView.SetCursorLogicPosition(aPoint, /*bPoint=*/false, /*bClearMark=*/false);
break;
case LOK_SETTEXTSELECTION_END:
rEditView.SetCursorLogicPosition(aPoint, /*bPoint=*/true, /*bClearMark=*/false);
break;
case LOK_SETTEXTSELECTION_RESET:
rEditView.SetCursorLogicPosition(aPoint, /*bPoint=*/true, /*bClearMark=*/true);
break;
default:
assert(false);
break;
}
}
}
}
}
void ChartController::impl_ShapeControllerDispatch( const util::URL& rURL, const Sequence< beans::PropertyValue >& rArgs )
{
Reference< frame::XDispatch > xDispatch( m_aDispatchContainer.getShapeController() );
@@ -888,7 +888,10 @@ void ChartController::execute_MouseButtonUp( const MouseEvent& rMEvt )
else
m_aSelection.resetPossibleSelectionAfterSingleClickWasEnsured();
}
else if( isDoubleClick(rMEvt) && !bMouseUpWithoutMouseDown /*#i106966#*/ )
// In tiled rendering drag mode could be not yet over on the call
// that should handle the double-click, so better to perform this check
// always.
if( isDoubleClick(rMEvt) && !bMouseUpWithoutMouseDown /*#i106966#*/ )
{
Point aMousePixel = rMEvt.GetPosPixel();
execute_DoubleClick( &aMousePixel );
@@ -28,6 +28,13 @@
#include <config_features.h>
#include <com/sun/star/chart2/X3DChartWindowProvider.hpp>
#include <sfx2/ipclient.hxx>
#include <sfx2/viewsh.hxx>
#include <sfx2/lokhelper.hxx>
#include <comphelper/lok.hxx>
#define TWIPS_PER_PIXEL 15
using namespace ::com::sun::star;
namespace
@@ -50,6 +57,7 @@ ChartWindow::ChartWindow( ChartController* pController, vcl::Window* pParent, Wi
: Window(pParent, nStyle)
, m_pWindowController( pController )
, m_bInPaint(false)
, m_pViewShellWindow( nullptr )
#if HAVE_FEATURE_OPENGL
, m_pOpenGLWindow(VclPtr<OpenGLWindow>::Create(this, false))
#else
@@ -94,6 +102,7 @@ void ChartWindow::dispose()
xUpdatable->update();
}
m_pOpenGLWindow.disposeAndClear();
m_pViewShellWindow.clear();
vcl::Window::dispose();
}
@@ -108,6 +117,10 @@ void ChartWindow::PrePaint(vcl::RenderContext& )
void ChartWindow::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect)
{
if (comphelper::LibreOfficeKit::isActive()
&& rRenderContext.GetOutDevType() != OutDevType::OUTDEV_VIRDEV)
return;
m_bInPaint = true;
if (m_pOpenGLWindow && m_pOpenGLWindow->IsVisible())
{
@@ -301,6 +314,56 @@ void ChartWindow::Invalidate( const vcl::Region& rRegion, InvalidateFlags nFlags
}
}
void ChartWindow::LogicInvalidate(const tools::Rectangle* pRectangle)
{
OString sRectangle;
if (!pRectangle)
{
// we have to invalidate the whole chart area not the whole document
sRectangle = GetBoundingBox().toString();
}
else
{
tools::Rectangle aRectangle(*pRectangle);
// When dragging shapes the map mode is disabled.
if (IsMapModeEnabled())
{
if (GetMapMode().GetMapUnit() == MapUnit::Map100thMM)
aRectangle = OutputDevice::LogicToLogic(aRectangle, MapUnit::Map100thMM, MapUnit::MapTwip);
}
else
{
aRectangle = PixelToLogic(aRectangle, MapMode(MapUnit::MapTwip));
}
vcl::Window* pEditWin = GetParentEditWin();
if (pEditWin)
{
MapMode aCWMapMode = GetMapMode();
double fXScale = aCWMapMode.GetScaleX();
double fYScale = aCWMapMode.GetScaleY();
if (!IsMapModeEnabled())
{
aRectangle.Left() /= fXScale;
aRectangle.Right() /= fXScale;
aRectangle.Top() /= fYScale;
aRectangle.Bottom() /= fYScale;
}
Point aOffset = this->GetOffsetPixelFrom(*pEditWin);
aOffset.X() *= (TWIPS_PER_PIXEL / fXScale);
aOffset.Y() *= (TWIPS_PER_PIXEL / fYScale);
aRectangle = tools::Rectangle(aRectangle.TopLeft() + aOffset, aRectangle.GetSize());
}
sRectangle = aRectangle.toString();
}
SfxViewShell* pCurrentShell = SfxViewShell::Current();
SfxLokHelper::notifyInvalidation(pCurrentShell, sRectangle);
}
FactoryFunction ChartWindow::GetUITestFactory() const
{
return ChartWindowUIObject::create;
@@ -311,6 +374,53 @@ ChartController* ChartWindow::GetController()
return m_pWindowController;
}
vcl::Window* ChartWindow::GetParentEditWin()
{
if (m_pViewShellWindow)
return m_pViewShellWindow.get();
// So, you are thinking, why do not invoke pCurrentShell->GetWindow() ?
// Because in Impress the parent edit win is not view shell window.
SfxViewShell* pCurrentShell = SfxViewShell::Current();
if( pCurrentShell )
{
SfxInPlaceClient* pIPClient = pCurrentShell->GetIPClient();
if (pIPClient)
{
vcl::Window* pRootWin = pIPClient->GetEditWin();
if(pRootWin && pRootWin->IsAncestorOf(*this))
{
m_pViewShellWindow = pRootWin;
return m_pViewShellWindow.get();
}
}
}
return nullptr;
}
tools::Rectangle ChartWindow::GetBoundingBox()
{
tools::Rectangle aBBox;
vcl::Window* pRootWin = GetParentEditWin();
if (pRootWin)
{
// In all cases, the following code fragment
// returns the chart bounding box in twips.
MapMode aCWMapMode = GetMapMode();
double fXScale = aCWMapMode.GetScaleX();
double fYScale = aCWMapMode.GetScaleY();
Point aOffset = GetOffsetPixelFrom(*pRootWin);
aOffset.X() *= (TWIPS_PER_PIXEL / fXScale);
aOffset.Y() *= (TWIPS_PER_PIXEL / fYScale);
Size aSize = GetSizePixel();
aSize.Width() *= (TWIPS_PER_PIXEL / fXScale);
aSize.Height() *= (TWIPS_PER_PIXEL / fYScale);
aBBox = tools::Rectangle(aOffset, aSize);
}
return aBBox;
}
} //namespace chart
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
+24 -2
View File
@@ -376,6 +376,17 @@ void ImpEditView::DrawSelection( EditSelection aTmpSel, vcl::Region* pRegion, Ou
{
std::vector<tools::Rectangle> aRectangles;
pRegion->GetRegionRectangles(aRectangles);
if (pOutWin->IsChart())
{
const vcl::Window* pViewShellWindow = mpViewShell->GetEditWindowForActiveOLEObj();
if (pViewShellWindow && pViewShellWindow->IsAncestorOf(*pOutWin))
{
Point aOffsetPx = pOutWin->GetOffsetPixelFrom(*pViewShellWindow);
Point aLogicOffset = pOutWin->PixelToLogic(aOffsetPx);
for (tools::Rectangle& rRect : aRectangles)
rRect.Move(aLogicOffset.getX(), aLogicOffset.getY());
}
}
if (!aRectangles.empty())
{
@@ -1017,8 +1028,19 @@ void ImpEditView::ShowCursor( bool bGotoCursor, bool bForceVisCursor )
if (comphelper::LibreOfficeKit::isActive() && mpViewShell)
{
const Point& rPos = GetCursor()->GetPos();
tools::Rectangle aRect(rPos.getX(), rPos.getY(), rPos.getX() + GetCursor()->GetWidth(), rPos.getY() + GetCursor()->GetHeight());
Point aPos = GetCursor()->GetPos();
if (pOutWin->IsChart())
{
const vcl::Window* pViewShellWindow = mpViewShell->GetEditWindowForActiveOLEObj();
if (pViewShellWindow && pViewShellWindow->IsAncestorOf(*pOutWin))
{
Point aOffsetPx = pOutWin->GetOffsetPixelFrom(*pViewShellWindow);
Point aLogicOffset = pOutWin->PixelToLogic(aOffsetPx);
aPos.Move(aLogicOffset.getX(), aLogicOffset.getY());
}
}
tools::Rectangle aRect(aPos.getX(), aPos.getY(), aPos.getX() + GetCursor()->GetWidth(), aPos.getY() + GetCursor()->GetHeight());
// LOK output is always in twips, convert from mm100 if necessary.
if (pOutWin->GetMapMode().GetMapUnit() == MapUnit::Map100thMM)
+1
View File
@@ -384,6 +384,7 @@ public:
virtual void NotifyOtherViews(int nType, const OString& rKey, const OString& rPayload) = 0;
/// Wrapper around SfxLokHelper::notifyOtherView().
virtual void NotifyOtherView(OutlinerViewShell* pOtherShell, int nType, const OString& rKey, const OString& rPayload) = 0;
virtual vcl::Window* GetEditWindowForActiveOLEObj() const = 0;
protected:
~OutlinerViewShell() throw () {}
+60
View File
@@ -0,0 +1,60 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#ifndef INCLUDED_SFX2_LOKCHARTHELPER_HXX
#define INCLUDED_SFX2_LOKCHARTHELPER_HXX
#include <sfx2/dllapi.h>
#include <tools/gen.hxx>
#include <vcl/window.hxx>
#include <com/sun/star/frame/XController.hpp>
#include <com/sun/star/frame/XDispatch.hpp>
class SfxViewShell;
class VirtualDevice;
class SFX2_DLLPUBLIC LokChartHelper
{
private:
SfxViewShell* mpViewShell;
css::uno::Reference<css::frame::XController> mxController;
css::uno::Reference<css::frame::XDispatch> mxDispatcher;
VclPtr<vcl::Window> mpWindow;
public:
LokChartHelper(SfxViewShell* pViewShell)
: mpViewShell(pViewShell)
, mpWindow(nullptr)
{}
css::uno::Reference<css::frame::XController>& GetXController();
css::uno::Reference<css::frame::XDispatch>& GetXDispatcher();
vcl::Window* GetWindow();
tools::Rectangle GetChartBoundingBox();
void Invalidate();
bool Hit(const Point& aPos);
static bool HitAny(const Point& aPos);
void PaintTile(VirtualDevice& rRenderContext, const tools::Rectangle& rTileRect);
static void PaintAllChartsOnTile(VirtualDevice& rDevice,
int nOutputWidth, int nOutputHeight,
int nTilePosX, int nTilePosY,
long nTileWidth, long nTileHeight);
bool postMouseEvent(int nType, int nX, int nY,
int nCount, int nButtons, int nModifier,
double fScaleX = 1.0, double fScaleY = 1.0);
bool setTextSelection(int nType, int nX, int nY);
bool setGraphicSelection(int nType, int nX, int nY,
double fScaleX = 1.0, double fScaleY = 1.0);
};
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
+3
View File
@@ -336,6 +336,9 @@ public:
virtual void NotifyCursor(SfxViewShell* /*pViewShell*/) const;
/// Where a new view can perform some update/initialization soon after the callback has been registered.
virtual void afterCallbackRegistered();
/// See OutlinerViewShell::GetEditWindowForActiveOLEObj().
virtual vcl::Window* GetEditWindowForActiveOLEObj() const override;
};
+4
View File
@@ -931,6 +931,7 @@ public:
vcl::Window* GetParent() const;
// return the dialog we are contained in or NULL if un-contained
Dialog* GetParentDialog() const;
bool IsAncestorOf( const vcl::Window& rWindow ) const;
void Show( bool bVisible = true, ShowFlags nFlags = ShowFlags::NONE );
void Hide() { Show( false ); }
@@ -1030,6 +1031,7 @@ public:
virtual void SetOutputSizePixel( const Size& rNewSize );
bool IsDefaultPos() const;
bool IsDefaultSize() const;
Point GetOffsetPixelFrom(const vcl::Window& rWindow) const;
// those conversion routines might deliver different results during UI mirroring
Point OutputToScreenPixel( const Point& rPos ) const;
@@ -1540,6 +1542,8 @@ public:
virtual Selection GetSurroundingTextSelection() const;
virtual FactoryFunction GetUITestFactory() const;
virtual bool IsChart() const { return false; }
};
}
+48 -7
View File
@@ -48,6 +48,7 @@
#include <unotools/charclass.hxx>
#include <tools/multisel.hxx>
#include <toolkit/awt/vclxdevice.hxx>
#include <toolkit/helper/vclunohelper.hxx>
#include <unotools/saveopt.hxx>
#include <float.h>
@@ -75,6 +76,7 @@
#include <opencl/platforminfo.hxx>
#endif
#include <sfx2/lokhelper.hxx>
#include <sfx2/lokcharthelper.hxx>
#include "cellsuno.hxx"
#include <columnspanset.hxx>
@@ -503,6 +505,9 @@ void ScModelObj::paintTile( VirtualDevice& rDevice,
pGridWindow->PaintTile( rDevice, nOutputWidth, nOutputHeight,
nTilePosX, nTilePosY, nTileWidth, nTileHeight );
LokChartHelper::PaintAllChartsOnTile(rDevice, nOutputWidth, nOutputHeight,
nTilePosX, nTilePosY, nTileWidth, nTileHeight);
}
void ScModelObj::setPart( int nPart )
@@ -570,20 +575,28 @@ void ScModelObj::postKeyEvent(int nType, int nCharCode, int nKeyCode)
// There seems to be no clear way of getting the grid window for this
// particular document, hence we need to hope we get the right window.
ScViewData* pViewData = ScDocShell::GetViewData();
ScGridWindow* pGridWindow = pViewData->GetActiveWin();
vcl::Window* pWindow = pViewData->GetActiveWin();
if (!pGridWindow)
if (!pWindow)
return;
KeyEvent aEvent(nCharCode, nKeyCode, 0);
ScTabViewShell * pTabViewShell = pViewData->GetViewShell();
LokChartHelper aChartHelper(pTabViewShell);
vcl::Window* pChartWindow = aChartHelper.GetWindow();
if (pChartWindow)
{
pWindow = pChartWindow;
}
switch (nType)
{
case LOK_KEYEVENT_KEYINPUT:
pGridWindow->KeyInput(aEvent);
pWindow->KeyInput(aEvent);
break;
case LOK_KEYEVENT_KEYUP:
pGridWindow->KeyUp(aEvent);
pWindow->KeyUp(aEvent);
break;
default:
assert(false);
@@ -607,6 +620,23 @@ void ScModelObj::postMouseEvent(int nType, int nX, int nY, int nCount, int nButt
pViewData->SetZoom(Fraction(mnTilePixelWidth * TWIPS_PER_PIXEL, mnTileTwipWidth),
Fraction(mnTilePixelHeight * TWIPS_PER_PIXEL, mnTileTwipHeight), true);
// check if user hit a chart which is being edited by him
ScTabViewShell * pTabViewShell = pViewData->GetViewShell();
LokChartHelper aChartHelper(pTabViewShell);
if (aChartHelper.postMouseEvent(nType, nX, nY,
nCount, nButtons, nModifier,
pViewData->GetPPTX(), pViewData->GetPPTY()))
return;
// check if the user hit a chart which is being edited by someone else
// and, if so, skip current mouse event
if (nType != LOK_MOUSEEVENT_MOUSEMOVE)
{
if (LokChartHelper::HitAny(Point(nX, nY)))
return;
}
// Calc operates in pixels...
Point aPos(nX * pViewData->GetPPTX(), nY * pViewData->GetPPTY());
MouseEvent aEvent(aPos, nCount,
@@ -645,9 +675,13 @@ void ScModelObj::postMouseEvent(int nType, int nX, int nY, int nCount, int nButt
void ScModelObj::setTextSelection(int nType, int nX, int nY)
{
SolarMutexGuard aGuard;
ScViewData* pViewData = ScDocShell::GetViewData();
ScTabViewShell* pViewShell = pViewData->GetViewShell();
LokChartHelper aChartHelper(pViewShell);
if (aChartHelper.setTextSelection(nType, nX, nY))
return;
ScInputHandler* pInputHandler = SC_MOD()->GetInputHdl(pViewShell);
ScDrawView* pDrawView = pViewData->GetScDrawView();
@@ -822,9 +856,16 @@ void ScModelObj::setGraphicSelection(int nType, int nX, int nY)
// update the aLogicMode in ScViewData to something predictable
pViewData->SetZoom(Fraction(mnTilePixelWidth * TWIPS_PER_PIXEL, mnTileTwipWidth),
Fraction(mnTilePixelHeight * TWIPS_PER_PIXEL, mnTileTwipHeight), true);
double fPPTX = pViewData->GetPPTX();
double fPPTY = pViewData->GetPPTY();
int nPixelX = nX * pViewData->GetPPTX();
int nPixelY = nY * pViewData->GetPPTY();
ScTabViewShell* pViewShell = pViewData->GetViewShell();
LokChartHelper aChartHelper(pViewShell);
if (aChartHelper.setGraphicSelection(nType, nX, nY, fPPTX, fPPTY))
return;
int nPixelX = nX * fPPTX;
int nPixelY = nY * fPPTY;
switch (nType)
{
+51 -9
View File
@@ -119,6 +119,10 @@
#include <drawinglayer/primitive2d/structuretagprimitive2d.hxx>
#include <sfx2/lokcharthelper.hxx>
#define TWIPS_PER_PIXEL 15
using namespace ::cppu;
using namespace ::com::sun::star;
using namespace ::sd;
@@ -2250,15 +2254,15 @@ void SdXImpressDocument::paintTile( VirtualDevice& rDevice,
// 100th mm rather than TWIP. It makes most sense just to
// convert here and in getDocumentSize, and leave the tiled
// rendering API working in TWIPs.
nTileWidth = convertTwipToMm100( nTileWidth );
nTileHeight = convertTwipToMm100( nTileHeight );
nTilePosX = convertTwipToMm100( nTilePosX );
nTilePosY = convertTwipToMm100( nTilePosY );
long nTileWidthHMM = convertTwipToMm100( nTileWidth );
long nTileHeightHMM = convertTwipToMm100( nTileHeight );
int nTilePosXHMM = convertTwipToMm100( nTilePosX );
int nTilePosYHMM = convertTwipToMm100( nTilePosY );
MapMode aMapMode = rDevice.GetMapMode();
aMapMode.SetMapUnit( MapUnit::Map100thMM );
aMapMode.SetOrigin( Point( -nTilePosX,
-nTilePosY) );
aMapMode.SetOrigin( Point( -nTilePosXHMM,
-nTilePosYHMM) );
aMapMode.SetScaleX( scaleX );
aMapMode.SetScaleY( scaleY );
@@ -2266,11 +2270,14 @@ void SdXImpressDocument::paintTile( VirtualDevice& rDevice,
rDevice.SetOutputSizePixel( Size(nOutputWidth, nOutputHeight) );
Point aPoint(nTilePosX, nTilePosY);
Size aSize(nTileWidth, nTileHeight);
Point aPoint(nTilePosXHMM, nTilePosYHMM);
Size aSize(nTileWidthHMM, nTileHeightHMM);
::tools::Rectangle aRect(aPoint, aSize);
pViewSh->GetView()->CompleteRedraw(&rDevice, vcl::Region(aRect));
LokChartHelper::PaintAllChartsOnTile(rDevice, nOutputWidth, nOutputHeight,
nTilePosX, nTilePosY, nTileWidth, nTileHeight);
}
void SdXImpressDocument::setPart( int nPart )
@@ -2449,10 +2456,17 @@ void SdXImpressDocument::postKeyEvent(int nType, int nCharCode, int nKeyCode)
if (!pViewShell)
return;
sd::Window* pWindow = pViewShell->GetActiveWindow();
vcl::Window* pWindow = pViewShell->GetActiveWindow();
if (!pWindow)
return;
LokChartHelper aChartHelper(pViewShell->GetViewShell());
vcl::Window* pChartWindow = aChartHelper.GetWindow();
if (pChartWindow)
{
pWindow = pChartWindow;
}
KeyEvent aEvent(nCharCode, nKeyCode, 0);
switch (nType)
@@ -2476,6 +2490,24 @@ void SdXImpressDocument::postMouseEvent(int nType, int nX, int nY, int nCount, i
DrawViewShell* pViewShell = GetViewShell();
if (!pViewShell)
return;
double fScale = 1.0/TWIPS_PER_PIXEL;
// check if user hit a chart which is being edited by him
LokChartHelper aChartHelper(pViewShell->GetViewShell());
if (aChartHelper.postMouseEvent(nType, nX, nY,
nCount, nButtons, nModifier,
fScale, fScale))
return;
// check if the user hit a chart which is being edited by someone else
// and, if so, skip current mouse event
if (nType != LOK_MOUSEEVENT_MOUSEMOVE)
{
if (LokChartHelper::HitAny(Point(nX, nY)))
return;
}
Window* pWindow = pViewShell->GetActiveWindow();
Point aPos(Point(convertTwipToMm100(nX), convertTwipToMm100(nY)));
@@ -2513,6 +2545,10 @@ void SdXImpressDocument::setTextSelection(int nType, int nX, int nY)
if (!pViewShell)
return;
LokChartHelper aChartHelper(pViewShell->GetViewShell());
if (aChartHelper.setTextSelection(nType, nX, nY))
return;
Point aPoint(convertTwipToMm100(nX), convertTwipToMm100(nY));
switch (nType)
{
@@ -2550,6 +2586,12 @@ void SdXImpressDocument::setGraphicSelection(int nType, int nX, int nY)
if (!pViewShell)
return;
double fScale = 1.0/TWIPS_PER_PIXEL;
LokChartHelper aChartHelper(pViewShell->GetViewShell());
if (aChartHelper.setGraphicSelection(nType, nX, nY, fScale, fScale))
return;
Point aPoint(convertTwipToMm100(nX), convertTwipToMm100(nY));
switch (nType)
{
+1
View File
@@ -300,6 +300,7 @@ $(eval $(call gb_Library_add_exception_objects,sfx,\
sfx2/source/view/frame2 \
sfx2/source/view/frmload \
sfx2/source/view/ipclient \
sfx2/source/view/lokcharthelper \
sfx2/source/view/lokhelper \
sfx2/source/view/printer \
sfx2/source/view/sfxbasecontroller \
+52 -4
View File
@@ -64,6 +64,8 @@
#include <svtools/soerr.hxx>
#include <comphelper/processfactory.hxx>
#include <sfx2/lokhelper.hxx>
#define SFX_CLIENTACTIVATE_TIMEOUT 100
using namespace com::sun::star;
@@ -394,7 +396,27 @@ awt::Rectangle SAL_CALL SfxInPlaceClient_Impl::getPlacement()
aRealObjArea.SetSize( Size( Fraction( aRealObjArea.GetWidth() ) * m_aScaleWidth,
Fraction( aRealObjArea.GetHeight() ) * m_aScaleHeight ) );
aRealObjArea = m_pClient->GetEditWin()->LogicToPixel( aRealObjArea );
// In Writer and Impress the map mode is disabled. So when a chart is
// activated (for in place editing) we get the chart win size in 100th mm
// and any method that should return pixels returns 100th mm and the chart
// window map mode has a ~26.485 scale factor.
// All that does not fit with current implementation for handling chart
// editing in LOK.
if (comphelper::LibreOfficeKit::isActive())
{
vcl::Window* pEditWin = m_pClient->GetEditWin();
bool bMapModeEnabled = pEditWin->IsMapModeEnabled();
if (!bMapModeEnabled)
pEditWin->EnableMapMode();
aRealObjArea = m_pClient->GetEditWin()->LogicToPixel( aRealObjArea );
if (!bMapModeEnabled && pEditWin->IsMapModeEnabled())
pEditWin->EnableMapMode(false);
}
else
{
aRealObjArea = m_pClient->GetEditWin()->LogicToPixel( aRealObjArea );
}
return AWTRectangle( aRealObjArea );
}
@@ -409,7 +431,22 @@ awt::Rectangle SAL_CALL SfxInPlaceClient_Impl::getClipRectangle()
aRealObjArea.SetSize( Size( Fraction( aRealObjArea.GetWidth() ) * m_aScaleWidth,
Fraction( aRealObjArea.GetHeight() ) * m_aScaleHeight ) );
aRealObjArea = m_pClient->GetEditWin()->LogicToPixel( aRealObjArea );
// See comment for SfxInPlaceClient_Impl::getPlacement.
if (comphelper::LibreOfficeKit::isActive())
{
vcl::Window* pEditWin = m_pClient->GetEditWin();
bool bMapModeEnabled = pEditWin->IsMapModeEnabled();
if (!bMapModeEnabled)
pEditWin->EnableMapMode();
aRealObjArea = m_pClient->GetEditWin()->LogicToPixel( aRealObjArea );
if (!bMapModeEnabled && pEditWin->IsMapModeEnabled())
pEditWin->EnableMapMode(false);
}
else
{
aRealObjArea = m_pClient->GetEditWin()->LogicToPixel( aRealObjArea );
}
return AWTRectangle( aRealObjArea );
}
@@ -878,7 +915,13 @@ ErrCode SfxInPlaceClient::DoVerb( long nVerb )
if ( !nError )
{
// See comment for SfxInPlaceClient_Impl::getPlacement.
vcl::Window* pEditWin = GetEditWin();
bool bMapModeEnabled = pEditWin->IsMapModeEnabled();
if (comphelper::LibreOfficeKit::isActive() && !bMapModeEnabled)
{
pEditWin->EnableMapMode();
}
m_pViewSh->GetViewFrame()->GetFrame().LockResize_Impl(true);
try
{
@@ -929,8 +972,13 @@ ErrCode SfxInPlaceClient::DoVerb( long nVerb )
" exception caught: " << e.Message);
nError = ERRCODE_SO_GENERALERROR;
//TODO/LATER: better error handling
}
}
if (comphelper::LibreOfficeKit::isActive() && !bMapModeEnabled
&& pEditWin->IsMapModeEnabled())
{
pEditWin->EnableMapMode(false);
}
SfxViewFrame* pFrame = m_pViewSh->GetViewFrame();
pFrame->GetFrame().LockResize_Impl(false);
pFrame->GetFrame().Resize();
+373
View File
@@ -0,0 +1,373 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include <sfx2/lokcharthelper.hxx>
#include <LibreOfficeKit/LibreOfficeKitEnums.h>
#include <sfx2/ipclient.hxx>
#include <sfx2/lokhelper.hxx>
#include <toolkit/helper/vclunohelper.hxx>
#include <tools/fract.hxx>
#include <tools/mapunit.hxx>
#include <vcl/virdev.hxx>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/embed/XEmbeddedObject.hpp>
#include <com/sun/star/frame/XModel.hpp>
#include <com/sun/star/chart2/XChartDocument.hpp>
#define TWIPS_PER_PIXEL 15
using namespace com::sun::star;
namespace {
inline Point lcl_TwipsToHMM( const Point& rPoint )
{
return Point(convertTwipToMm100(rPoint.getX()), convertTwipToMm100(rPoint.getY()));
}
inline Size lcl_TwipsToHMM( const Size& rSize )
{
return Size(convertTwipToMm100(rSize.getWidth()), convertTwipToMm100(rSize.getHeight()));
}
} // end anonymous ns
css::uno::Reference<css::frame::XController>& LokChartHelper::GetXController()
{
if(!mxController.is() )
{
if (mpViewShell)
{
SfxInPlaceClient* pIPClient = mpViewShell->GetIPClient();
if (pIPClient)
{
css::uno::Reference< ::css::embed::XEmbeddedObject > xEmbObj = pIPClient->GetObject();
if( xEmbObj.is() )
{
::css::uno::Reference< ::css::chart2::XChartDocument > xChart( xEmbObj->getComponent(), uno::UNO_QUERY );
if( xChart.is() )
{
::css::uno::Reference< ::css::frame::XController > xChartController = xChart->getCurrentController();
if( xChartController.is() )
{
mxController = xChartController;
}
}
}
}
}
}
return mxController;
}
css::uno::Reference<css::frame::XDispatch>& LokChartHelper::GetXDispatcher()
{
if( !mxDispatcher.is() )
{
::css::uno::Reference< ::css::frame::XController >& xChartController = GetXController();
if( xChartController.is() )
{
::css::uno::Reference< ::css::frame::XDispatch > xDispatcher( xChartController, uno::UNO_QUERY );
if( xDispatcher.is() )
{
mxDispatcher = xDispatcher;
}
}
}
return mxDispatcher;
}
vcl::Window* LokChartHelper::GetWindow()
{
if (!mpWindow)
{
::css::uno::Reference< ::css::frame::XController >& xChartController = GetXController();
if( xChartController.is() )
{
::css::uno::Reference< ::css::frame::XFrame > xFrame = xChartController->getFrame();
if (xFrame.is())
{
::css::uno::Reference< ::css::awt::XWindow > xDockerWin = xFrame->getContainerWindow();
vcl::Window* pParent = VCLUnoHelper::GetWindow( xDockerWin ).get();
if (pParent)
{
sal_uInt16 nTotChildren = pParent->GetChildCount();
while (nTotChildren--)
{
vcl::Window* pChildWin = pParent->GetChild(nTotChildren);
if (pChildWin && pChildWin->IsChart())
{
mpWindow = pChildWin;
break;
}
}
}
}
}
}
return mpWindow.get();
}
tools::Rectangle LokChartHelper::GetChartBoundingBox()
{
tools::Rectangle aBBox;
if (mpViewShell)
{
SfxInPlaceClient* pIPClient = mpViewShell->GetIPClient();
if (pIPClient)
{
vcl::Window* pRootWin = pIPClient->GetEditWin();
if (pRootWin)
{
vcl::Window* pWindow = GetWindow();
if (pWindow)
{
// In all cases, the following code fragment
// returns the chart bounding box in twips.
MapMode aCWMapMode = pWindow->GetMapMode();
double fXScale = aCWMapMode.GetScaleX();
double fYScale = aCWMapMode.GetScaleY();
Point aOffset = pWindow->GetOffsetPixelFrom(*pRootWin);
aOffset.X() *= (TWIPS_PER_PIXEL / fXScale);
aOffset.Y() *= (TWIPS_PER_PIXEL / fYScale);
Size aSize = pWindow->GetSizePixel();
aSize.Width() *= (TWIPS_PER_PIXEL / fXScale);
aSize.Height() *= (TWIPS_PER_PIXEL / fYScale);
aBBox = tools::Rectangle(aOffset, aSize);
}
}
}
}
return aBBox;
}
void LokChartHelper::Invalidate()
{
mpWindow = nullptr;
mxDispatcher.clear();
mxController.clear();
}
bool LokChartHelper::Hit(const Point& aPos)
{
if (mpViewShell)
{
vcl::Window* pChartWindow = GetWindow();
if (pChartWindow)
{
tools::Rectangle rChartBBox = GetChartBoundingBox();
return rChartBBox.IsInside(aPos);
}
}
return false;
}
bool LokChartHelper::HitAny(const Point& aPos)
{
SfxViewShell* pViewShell = SfxViewShell::GetFirst();
while (pViewShell)
{
LokChartHelper aChartHelper(pViewShell);
if (aChartHelper.Hit(aPos))
return true;
pViewShell = SfxViewShell::GetNext(*pViewShell);
}
return false;
}
void LokChartHelper::PaintTile(VirtualDevice& rRenderContext, const tools::Rectangle& rTileRect)
{
if (mpViewShell)
{
vcl::Window* pChartWindow = GetWindow();
if (pChartWindow)
{
tools::Rectangle aChartRect = GetChartBoundingBox();
tools::Rectangle aTestRect = rTileRect;
aTestRect.Intersection( aChartRect );
if (!aTestRect.IsEmpty())
{
Point aOffset( aChartRect.Left() - rTileRect.Left(), aChartRect.Top() - rTileRect.Top() );
Point aOffsetFromTile = lcl_TwipsToHMM(aOffset);
Size aSize = lcl_TwipsToHMM(aChartRect.GetSize());
tools::Rectangle aRectangle(Point(0,0), aSize);
bool bEnableMapMode = !pChartWindow->IsMapModeEnabled();
pChartWindow->EnableMapMode();
bool bRenderContextEnableMapMode = !rRenderContext.IsMapModeEnabled();
rRenderContext.EnableMapMode();
rRenderContext.Push(PushFlags::MAPMODE);
MapMode aCWMapMode = pChartWindow->GetMapMode();
aCWMapMode.SetScaleX(rRenderContext.GetMapMode().GetScaleX());
aCWMapMode.SetScaleY(rRenderContext.GetMapMode().GetScaleY());
aCWMapMode.SetOrigin(aOffsetFromTile);
rRenderContext.SetMapMode(aCWMapMode);
pChartWindow->Paint(rRenderContext, aRectangle);
rRenderContext.Pop();
if (bRenderContextEnableMapMode)
rRenderContext.EnableMapMode(false);
if (bEnableMapMode)
pChartWindow->EnableMapMode(false);
}
}
}
}
void LokChartHelper::PaintAllChartsOnTile(VirtualDevice& rDevice,
int nOutputWidth, int nOutputHeight,
int nTilePosX, int nTilePosY,
long nTileWidth, long nTileHeight)
{
// Resizes the virtual device so to contain the entries context
rDevice.SetOutputSizePixel(Size(nOutputWidth, nOutputHeight));
rDevice.Push(PushFlags::MAPMODE);
MapMode aMapMode(rDevice.GetMapMode());
// Scaling. Must convert from pixels to twips. We know
// that VirtualDevices use a DPI of 96.
Fraction scaleX = Fraction(nOutputWidth, 96) * Fraction(1440L) / Fraction(nTileWidth);
Fraction scaleY = Fraction(nOutputHeight, 96) * Fraction(1440L) / Fraction(nTileHeight);
aMapMode.SetScaleX(scaleX);
aMapMode.SetScaleY(scaleY);
rDevice.SetMapMode(aMapMode);
tools::Rectangle aTileRect(Point(nTilePosX, nTilePosY), Size(nTileWidth, nTileHeight));
SfxViewShell* pViewShell = SfxViewShell::GetFirst();
while (pViewShell)
{
LokChartHelper aChartHelper(pViewShell);
aChartHelper.PaintTile(rDevice, aTileRect);
pViewShell = SfxViewShell::GetNext(*pViewShell);
}
rDevice.Pop();
}
bool LokChartHelper::postMouseEvent(int nType, int nX, int nY,
int nCount, int nButtons, int nModifier,
double fScaleX, double fScaleY)
{
Point aMousePos(nX, nY);
vcl::Window* pChartWindow = GetWindow();
if (pChartWindow)
{
tools::Rectangle rChartBBox = GetChartBoundingBox();
if (rChartBBox.IsInside(aMousePos))
{
int nChartWinX = nX - rChartBBox.Left();
int nChartWinY = nY - rChartBBox.Top();
// chart window expects pixels, but the conversion factor
// can depend on the client zoom
Point aPos(nChartWinX * fScaleX, nChartWinY * fScaleY);
MouseEvent aEvent(aPos, nCount,
MouseEventModifiers::SIMPLECLICK, nButtons, nModifier);
switch (nType)
{
case LOK_MOUSEEVENT_MOUSEBUTTONDOWN:
pChartWindow->MouseButtonDown(aEvent);
break;
case LOK_MOUSEEVENT_MOUSEBUTTONUP:
pChartWindow->MouseButtonUp(aEvent);
if (pChartWindow->IsTracking())
pChartWindow->EndTracking(TrackingEventFlags::DontCallHdl);
break;
case LOK_MOUSEEVENT_MOUSEMOVE:
pChartWindow->MouseMove(aEvent);
break;
default:
assert(false);
break;
}
return true;
}
}
return false;
}
bool LokChartHelper::setTextSelection(int nType, int nX, int nY)
{
tools::Rectangle rChartBBox = GetChartBoundingBox();
if (rChartBBox.IsInside(Point(nX, nY)))
{
css::uno::Reference<css::frame::XDispatch> xDispatcher = GetXDispatcher();
if (xDispatcher.is())
{
int nChartWinX = nX - rChartBBox.Left();
int nChartWinY = nY - rChartBBox.Top();
// no scale here the chart controller expects twips
// that are converted to hmm
util::URL aURL;
aURL.Path = "LOKSetTextSelection";
uno::Sequence< beans::PropertyValue > aArgs(3);
aArgs[0].Value <<= static_cast<sal_Int32>(nType);
aArgs[1].Value <<= static_cast<sal_Int32>(nChartWinX);
aArgs[2].Value <<= static_cast<sal_Int32>(nChartWinY);
xDispatcher->dispatch(aURL, aArgs);
}
return true;
}
return false;
}
bool LokChartHelper::setGraphicSelection(int nType, int nX, int nY,
double fScaleX, double fScaleY)
{
tools::Rectangle rChartBBox = GetChartBoundingBox();
if (rChartBBox.IsInside(Point(nX, nY)))
{
int nChartWinX = nX - rChartBBox.Left();
int nChartWinY = nY - rChartBBox.Top();
vcl::Window* pChartWindow = GetWindow();
Point aPos(nChartWinX * fScaleX, nChartWinY * fScaleY);
switch (nType)
{
case LOK_SETGRAPHICSELECTION_START:
{
MouseEvent aClickEvent(aPos, 1, MouseEventModifiers::SIMPLECLICK, MOUSE_LEFT);
pChartWindow->MouseButtonDown(aClickEvent);
MouseEvent aMoveEvent(aPos, 0, MouseEventModifiers::SIMPLEMOVE, MOUSE_LEFT);
pChartWindow->MouseMove(aMoveEvent);
}
break;
case LOK_SETGRAPHICSELECTION_END:
{
MouseEvent aMoveEvent(aPos, 0, MouseEventModifiers::SIMPLEMOVE, MOUSE_LEFT);
pChartWindow->MouseMove(aMoveEvent);
MouseEvent aClickEvent(aPos, 1, MouseEventModifiers::SIMPLECLICK, MOUSE_LEFT);
pChartWindow->MouseButtonUp(aClickEvent);
}
break;
default:
assert(false);
break;
}
return true;
}
return false;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
+14 -1
View File
@@ -832,9 +832,11 @@ SfxInPlaceClient* SfxViewShell::GetUIActiveClient() const
if ( !pClients )
return nullptr;
bool bIsTiledRendering = comphelper::LibreOfficeKit::isActive();
for (SfxInPlaceClient* pIPClient : *pClients)
{
if ( pIPClient->IsObjectUIActive() )
if ( pIPClient->IsObjectUIActive() || ( bIsTiledRendering && pIPClient->IsObjectInPlaceActive() ) )
return pIPClient;
}
@@ -1464,6 +1466,17 @@ void SfxViewShell::afterCallbackRegistered()
{
}
vcl::Window* SfxViewShell::GetEditWindowForActiveOLEObj() const
{
vcl::Window* pEditWin = nullptr;
SfxInPlaceClient* pIPClient = GetIPClient();
if (pIPClient)
{
pEditWin = pIPClient->GetEditWin();
}
return pEditWin;
}
void SfxViewShell::NotifyCursor(SfxViewShell* /*pViewShell*/) const
{
}
+36 -1
View File
@@ -207,6 +207,22 @@ void SdrMarkView::ModelHasChanged()
sSelection = "EMPTY";
else
{
sal_uInt32 nTotalPaintWindows = this->PaintWindowCount();
if (nTotalPaintWindows == 1)
{
const vcl::Window* pWin = dynamic_cast<const vcl::Window*>(this->GetFirstOutputDevice());
if (pWin && pWin->IsChart())
{
const vcl::Window* pViewShellWindow = GetSfxViewShell()->GetEditWindowForActiveOLEObj();
if (pViewShellWindow && pViewShellWindow->IsAncestorOf(*pWin))
{
Point aOffsetPx = pWin->GetOffsetPixelFrom(*pViewShellWindow);
Point aLogicOffset = pWin->PixelToLogic(aOffsetPx);
aSelection.Move(aLogicOffset.getX(), aLogicOffset.getY());
}
}
}
// In case the map mode is in 100th MM, then need to convert the coordinates over to twips for LOK.
if (mpMarkedPV)
{
@@ -732,10 +748,29 @@ void SdrMarkView::SetMarkHandles(SfxViewShell* pOtherShell)
}
tools::Rectangle aRect(GetMarkedObjRect());
tools::Rectangle aSelection(aRect);
if (bTiledRendering && !aRect.IsEmpty())
{
sal_uInt32 nTotalPaintWindows = this->PaintWindowCount();
if (nTotalPaintWindows == 1)
{
const vcl::Window* pWin = dynamic_cast<const vcl::Window*>(this->GetFirstOutputDevice());
if (pWin && pWin->IsChart())
{
const vcl::Window* pViewShellWindow = GetSfxViewShell()->GetEditWindowForActiveOLEObj();
if (pViewShellWindow && pViewShellWindow->IsAncestorOf(*pWin))
{
Point aOffsetPx = pWin->GetOffsetPixelFrom(*pViewShellWindow);
Point aLogicOffset = pWin->PixelToLogic(aOffsetPx);
aSelection.Move(aLogicOffset.getX(), aLogicOffset.getY());
}
}
}
}
if (bTiledRendering)
{
tools::Rectangle aSelection(aRect);
OString sSelection;
if (aSelection.IsEmpty())
sSelection = "EMPTY";
+9
View File
@@ -59,6 +59,8 @@
#include <comphelper/lok.hxx>
#include <svx/svdviter.hxx>
#include <sfx2/lokhelper.hxx>
using namespace ::com::sun::star;
// interface to SdrPaintWindow
@@ -1115,6 +1117,13 @@ void SdrPaintView::ShowItemBrowser(bool bShow)
void SdrPaintView::MakeVisible(const tools::Rectangle& rRect, vcl::Window& rWin)
{
// TODO: handle when the text cursor goes out of the chart area
// However this hack avoids that the cursor gets misplaced wrt the text.
if (comphelper::LibreOfficeKit::isActive() && rWin.IsChart())
{
return;
}
MapMode aMap(rWin.GetMapMode());
Size aActualSize(rWin.GetOutputSize());
+2
View File
@@ -415,6 +415,8 @@ public:
virtual bool isMimeTypeSupported() override;
/// @see vcl::ITiledRenderable::setClientVisibleArea().
virtual void setClientVisibleArea(const tools::Rectangle& rRectangle) override;
/// @see vcl::ITiledRenderable::setClientZoom.
virtual void setClientZoom(int nTilePixelWidth_, int nTilePixelHeight_, int nTileTwipWidth_, int nTileTwipHeight_) override;
/// @see vcl::ITiledRenderable::getPointer().
virtual Pointer getPointer() override;
/// @see vcl::ITiledRenderable::getTrackedChanges().
+29
View File
@@ -25,6 +25,7 @@
#include <svx/srchdlg.hxx>
#include <svx/svdobj.hxx>
#include <sfx2/viewsh.hxx>
#include <sfx2/ipclient.hxx>
#include <drawdoc.hxx>
#include <swwait.hxx>
#include <swmodule.hxx>
@@ -1885,10 +1886,12 @@ void SwViewShell::PaintTile(VirtualDevice &rDevice, int contextWidth, int contex
rDevice.SetMapMode(aMapMode);
// Update scaling of SwEditWin and its sub-widgets, needed for comments.
sal_uInt16 nOldZoomValue = 0;
if (GetWin() && GetWin()->GetMapMode().GetScaleX() != scaleX)
{
double fScale = scaleX;
SwViewOption aOption(*GetViewOptions());
nOldZoomValue = aOption.GetZoom();
aOption.SetZoom(fScale * 100);
ApplyViewOptions(aOption);
// Make sure the map mode (disabled in SwXTextDocument::initializeForTiledRendering()) is still disabled.
@@ -1918,6 +1921,32 @@ void SwViewShell::PaintTile(VirtualDevice &rDevice, int contextWidth, int contex
pPostItMgr->PaintTile(rDevice);
// SwViewShell's output device tear down
// A view shell can get a PaintTile call for a tile at a zoom level
// different from the one, the related client really is.
// In such a case it is better to reset the current scale value to
// the original one, since such a value should be in synchronous with
// the zoom level in the client (see setClientZoom).
// At present the zoom value returned by GetViewOptions()->GetZoom() is
// used in SwXTextDocument methods (postMouseEvent and setGraphicSelection)
// for passing the correct mouse position to an edited chart (if any).
if (nOldZoomValue !=0)
{
SwViewOption aOption(*GetViewOptions());
aOption.SetZoom(nOldZoomValue);
ApplyViewOptions(aOption);
// Changing the zoom value doesn't always trigger the updating of
// the client ole object area, so we call it directly.
SfxInPlaceClient* pIPClient = GetSfxViewShell()->GetIPClient();
if (pIPClient)
{
pIPClient->VisAreaChanged();
}
// Make sure the map mode (disabled in SwXTextDocument::initializeForTiledRendering()) is still disabled.
GetWin()->EnableMapMode(false);
}
mpOut = pSaveOut;
comphelper::LibreOfficeKit::setTiledPainting(false);
}
+86 -3
View File
@@ -37,6 +37,8 @@
#include <toolkit/helper/vclunohelper.hxx>
#include <toolkit/awt/vclxdevice.hxx>
#include <LibreOfficeKit/LibreOfficeKitEnums.h>
#include <sfx2/lokcharthelper.hxx>
#include <sfx2/ipclient.hxx>
#include <editeng/svxacorr.hxx>
#include <editeng/acorrcfg.hxx>
#include <cmdid.h>
@@ -166,6 +168,8 @@
#include <comphelper/servicehelper.hxx>
#include <memory>
#define TWIPS_PER_PIXEL 15
using namespace ::com::sun::star;
using namespace ::com::sun::star::text;
using namespace ::com::sun::star::i18n;
@@ -3078,6 +3082,9 @@ void SwXTextDocument::paintTile( VirtualDevice &rDevice,
SwViewShell* pViewShell = pDocShell->GetWrtShell();
pViewShell->PaintTile(rDevice, nOutputWidth, nOutputHeight,
nTilePosX, nTilePosY, nTileWidth, nTileHeight);
LokChartHelper::PaintAllChartsOnTile(rDevice, nOutputWidth, nOutputHeight,
nTilePosX, nTilePosY, nTileWidth, nTileHeight);
}
Size SwXTextDocument::getDocumentSize()
@@ -3158,6 +3165,34 @@ void SwXTextDocument::setClientVisibleArea(const tools::Rectangle& rRectangle)
pView->ForcePageUpDownOffset(2 * rRectangle.GetHeight() / 3);
}
void SwXTextDocument::setClientZoom(int nTilePixelWidth_, int /*nTilePixelHeight_*/,
int nTileTwipWidth_, int /*nTileTwipHeight_*/)
{
// Here we set the zoom value as it has been set by the user in the client.
// This value is used in postMouseEvent and setGraphicSelection methods
// for in place chart editing. We assume that x and y scale is rougly
// the same.
// Indeed we could set mnTilePixelWidth, mnTilePixelHeight, mnTileTwipWidth,
// mnTileTwipHeight data members of this class but they are not very useful
// since we need to be able to retrieve the zoom value for each view shell.
SfxInPlaceClient* pIPClient = pDocShell->GetView()->GetIPClient();
if (pIPClient)
{
SwViewShell* pWrtViewShell = pDocShell->GetWrtShell();
double fScale = nTilePixelWidth_ * TWIPS_PER_PIXEL / (nTileTwipWidth_ * 1.0);
SwViewOption aOption(*(pWrtViewShell->GetViewOptions()));
if (aOption.GetZoom() != fScale * 100)
{
aOption.SetZoom(fScale * 100);
pWrtViewShell->ApplyViewOptions(aOption);
// Changing the zoom value doesn't always trigger the updating of
// the client ole object area, so we call it directly.
pIPClient->VisAreaChanged();
}
}
}
Pointer SwXTextDocument::getPointer()
{
SolarMutexGuard aGuard;
@@ -3322,6 +3357,11 @@ void SwXTextDocument::initializeForTiledRendering(const css::uno::Sequence<css::
}
}
// Set the initial zoom value to 1; usually it is set in setClientZoom and
// SwViewShell::PaintTile; zoom value is used for chart in place
// editing, see postMouseEvent and setGraphicSelection methods.
aViewOption.SetZoom(1 * 100);
aViewOption.SetPostIts(comphelper::LibreOfficeKit::isTiledAnnotations());
pViewShell->ApplyViewOptions(aViewOption);
@@ -3354,16 +3394,25 @@ void SwXTextDocument::postKeyEvent(int nType, int nCharCode, int nKeyCode)
{
SolarMutexGuard aGuard;
SwEditWin& rEditWin = pDocShell->GetView()->GetEditWin();
vcl::Window* pWindow = &(pDocShell->GetView()->GetEditWin());
SfxViewShell* pViewShell = pDocShell->GetView();
LokChartHelper aChartHelper(pViewShell);
vcl::Window* pChartWindow = aChartHelper.GetWindow();
if (pChartWindow)
{
pWindow = pChartWindow;
}
KeyEvent aEvent(nCharCode, nKeyCode, 0);
switch (nType)
{
case LOK_KEYEVENT_KEYINPUT:
rEditWin.KeyInput(aEvent);
pWindow->KeyInput(aEvent);
break;
case LOK_KEYEVENT_KEYUP:
rEditWin.KeyUp(aEvent);
pWindow->KeyUp(aEvent);
break;
default:
assert(false);
@@ -3375,6 +3424,26 @@ void SwXTextDocument::postMouseEvent(int nType, int nX, int nY, int nCount, int
{
SolarMutexGuard aGuard;
SwViewShell* pWrtViewShell = pDocShell->GetWrtShell();
SwViewOption aOption(*(pWrtViewShell->GetViewOptions()));
double fScale = aOption.GetZoom() / (TWIPS_PER_PIXEL * 100.0);
// check if user hit a chart which is being edited by him
SfxViewShell* pViewShell = pDocShell->GetView();
LokChartHelper aChartHelper(pViewShell);
if (aChartHelper.postMouseEvent(nType, nX, nY,
nCount, nButtons, nModifier,
fScale, fScale))
return;
// check if the user hit a chart which is being edited by someone else
// and, if so, skip current mouse event
if (nType != LOK_MOUSEEVENT_MOUSEMOVE)
{
if (LokChartHelper::HitAny(Point(nX, nY)))
return;
}
SwEditWin& rEditWin = pDocShell->GetView()->GetEditWin();
Point aPos(nX , nY);
MouseEvent aEvent(aPos, nCount, MouseEventModifiers::SIMPLECLICK, nButtons, nModifier);
@@ -3406,6 +3475,11 @@ void SwXTextDocument::setTextSelection(int nType, int nX, int nY)
{
SolarMutexGuard aGuard;
SfxViewShell* pViewShell = pDocShell->GetView();
LokChartHelper aChartHelper(pViewShell);
if (aChartHelper.setTextSelection(nType, nX, nY))
return;
SwEditWin& rEditWin = pDocShell->GetView()->GetEditWin();
switch (nType)
{
@@ -3504,6 +3578,15 @@ void SwXTextDocument::setGraphicSelection(int nType, int nX, int nY)
{
SolarMutexGuard aGuard;
SwViewShell* pWrtViewShell = pDocShell->GetWrtShell();
SwViewOption aOption(*(pWrtViewShell->GetViewOptions()));
double fScale = aOption.GetZoom() / (TWIPS_PER_PIXEL * 100.0);
SfxViewShell* pViewShell = pDocShell->GetView();
LokChartHelper aChartHelper(pViewShell);
if (aChartHelper.setGraphicSelection(nType, nX, nY, fScale, fScale))
return;
SwEditWin& rEditWin = pDocShell->GetView()->GetEditWin();
switch (nType)
{
+5
View File
@@ -1005,6 +1005,11 @@ void Window::SetParent( vcl::Window* pNewParent )
Show( true, ShowFlags::NoFocusChange | ShowFlags::NoActivate );
}
bool Window::IsAncestorOf( const vcl::Window& rWindow ) const
{
return ImplIsRealParentPath(&rWindow);
}
sal_uInt16 Window::GetChildCount() const
{
if (!mpWindowImpl)
+5
View File
@@ -1207,6 +1207,11 @@ bool Window::IsDefaultSize() const
return mpWindowImpl->mbDefSize;
}
Point Window::GetOffsetPixelFrom(const vcl::Window& rWindow) const
{
return Point(GetOutOffXPixel() - rWindow.GetOutOffXPixel(), GetOutOffYPixel() - rWindow.GetOutOffYPixel());
}
void Window::EnablePaint( bool bEnable )
{
mpWindowImpl->mbPaintDisabled = !bEnable;