summaryrefslogtreecommitdiffstats
path: root/svx/source/dialog/pagectrl.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'svx/source/dialog/pagectrl.cxx')
-rw-r--r--svx/source/dialog/pagectrl.cxx397
1 files changed, 397 insertions, 0 deletions
diff --git a/svx/source/dialog/pagectrl.cxx b/svx/source/dialog/pagectrl.cxx
new file mode 100644
index 0000000000..fe44562ff2
--- /dev/null
+++ b/svx/source/dialog/pagectrl.cxx
@@ -0,0 +1,397 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <memory>
+#include <editeng/frmdir.hxx>
+#include <vcl/canvastools.hxx>
+#include <vcl/outdev.hxx>
+#include <vcl/settings.hxx>
+#include <tools/fract.hxx>
+#include <svx/pageitem.hxx>
+#include <svx/pagectrl.hxx>
+#include <algorithm>
+#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <drawinglayer/geometry/viewinformation2d.hxx>
+#include <drawinglayer/processor2d/baseprocessor2d.hxx>
+#include <drawinglayer/primitive2d/PolygonHairlinePrimitive2D.hxx>
+#include <drawinglayer/processor2d/processor2dtools.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+
+#define CELL_WIDTH 1600L
+#define CELL_HEIGHT 800L
+
+SvxPageWindow::SvxPageWindow() :
+ nTop(0),
+ nBottom(0),
+ nLeft(0),
+ nRight(0),
+ bResetBackground(false),
+ bFrameDirection(false),
+ nFrameDirection(SvxFrameDirection::Horizontal_LR_TB),
+ nHdLeft(0),
+ nHdRight(0),
+ nHdDist(0),
+ nHdHeight(0),
+ nFtLeft(0),
+ nFtRight(0),
+ nFtDist(0),
+ nFtHeight(0),
+ bFooter(false),
+ bHeader(false),
+ bTable(false),
+ bHorz(false),
+ bVert(false),
+ eUsage(SvxPageUsage::All)
+{
+}
+
+SvxPageWindow::~SvxPageWindow()
+{
+}
+
+void SvxPageWindow::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&)
+{
+ rRenderContext.Push(vcl::PushFlags::MAPMODE);
+ rRenderContext.SetMapMode(MapMode(MapUnit::MapTwip));
+
+ Fraction aXScale(aWinSize.Width(), std::max(aSize.Width() * 2 + aSize.Width() / 8, tools::Long(1)));
+ Fraction aYScale(aWinSize.Height(), std::max(aSize.Height(), tools::Long(1)));
+ MapMode aMapMode(rRenderContext.GetMapMode());
+
+ if(aYScale < aXScale)
+ {
+ aMapMode.SetScaleX(aYScale);
+ aMapMode.SetScaleY(aYScale);
+ }
+ else
+ {
+ aMapMode.SetScaleX(aXScale);
+ aMapMode.SetScaleY(aXScale);
+ }
+ rRenderContext.SetMapMode(aMapMode);
+ Size aSz(rRenderContext.PixelToLogic(GetOutputSizePixel()));
+ tools::Long nYPos = (aSz.Height() - aSize.Height()) / 2;
+
+ if (eUsage == SvxPageUsage::All)
+ {
+ // all pages are equal -> draw one page
+ if (aSize.Width() > aSize.Height())
+ {
+ // Draw Landscape page of the same size
+ Fraction aX = aMapMode.GetScaleX();
+ Fraction aY = aMapMode.GetScaleY();
+ Fraction a2(1.5);
+ aX *= a2;
+ aY *= a2;
+ aMapMode.SetScaleX(aX);
+ aMapMode.SetScaleY(aY);
+ rRenderContext.SetMapMode(aMapMode);
+ aSz = rRenderContext.PixelToLogic(GetOutputSizePixel());
+ nYPos = (aSz.Height() - aSize.Height()) / 2;
+ tools::Long nXPos = (aSz.Width() - aSize.Width()) / 2;
+ DrawPage(rRenderContext, Point(nXPos,nYPos),true,true);
+ }
+ else
+ // Portrait
+ DrawPage(rRenderContext, Point((aSz.Width() - aSize.Width()) / 2,nYPos),true,true);
+ }
+ else
+ {
+ // Left and right page are different -> draw two pages if possible
+ DrawPage(rRenderContext, Point(0, nYPos), false,
+ eUsage == SvxPageUsage::Left || eUsage == SvxPageUsage::All || eUsage == SvxPageUsage::Mirror);
+ DrawPage(rRenderContext, Point(aSize.Width() + aSize.Width() / 8, nYPos), true,
+ eUsage == SvxPageUsage::Right || eUsage == SvxPageUsage::All || eUsage == SvxPageUsage::Mirror);
+ }
+ rRenderContext.Pop();
+}
+
+void SvxPageWindow::DrawPage(vcl::RenderContext& rRenderContext, const Point& rOrg, const bool bSecond, const bool bEnabled)
+{
+ const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
+ const Color& rFieldColor = rStyleSettings.GetFieldColor();
+ const Color& rFieldTextColor = rStyleSettings.GetFieldTextColor();
+ const Color& rDisableColor = rStyleSettings.GetDisableColor();
+ const Color& rDlgColor = rStyleSettings.GetDialogColor();
+
+ // background
+ if (!bSecond || bResetBackground)
+ {
+ rRenderContext.SetLineColor(COL_TRANSPARENT);
+ rRenderContext.SetFillColor(rDlgColor);
+ Size winSize(rRenderContext.GetOutputSize());
+ rRenderContext.DrawRect(tools::Rectangle(Point(0,0), winSize));
+
+ if (bResetBackground)
+ bResetBackground = false;
+ }
+ rRenderContext.SetLineColor(rFieldTextColor);
+
+ // Shadow
+ Size aTempSize = aSize;
+
+ // Page
+ if (!bEnabled)
+ {
+ rRenderContext.SetFillColor(rDisableColor);
+ rRenderContext.DrawRect(tools::Rectangle(rOrg, aTempSize));
+ return;
+ }
+ rRenderContext.SetFillColor(rFieldColor);
+ rRenderContext.DrawRect(tools::Rectangle(rOrg, aTempSize));
+
+ tools::Long nL = nLeft;
+ tools::Long nR = nRight;
+
+ if (eUsage == SvxPageUsage::Mirror && !bSecond)
+ {
+ // turn for mirrored
+ nL = nRight;
+ nR = nLeft;
+ }
+
+ tools::Rectangle aRect;
+
+ aRect.SetLeft( rOrg.X() + nL );
+ aRect.SetRight( rOrg.X() + aTempSize.Width() - nR );
+ aRect.SetTop( rOrg.Y() + nTop );
+ aRect.SetBottom( rOrg.Y() + aTempSize.Height() - nBottom );
+
+ tools::Rectangle aHdRect(aRect);
+ tools::Rectangle aFtRect(aRect);
+
+ if (bHeader || bFooter)
+ {
+ // Header and/or footer used
+ const Color aLineColor(rRenderContext.GetLineColor());
+
+ // draw PageFill first and on the whole page, no outline
+ rRenderContext.SetLineColor();
+ drawFillAttributes(rRenderContext, maPageFillAttributes, aRect, aRect);
+ rRenderContext.SetLineColor(aLineColor);
+
+ if (bHeader)
+ {
+ // show headers if possible
+ aHdRect.AdjustLeft(nHdLeft );
+ aHdRect.AdjustRight( -nHdRight );
+ aHdRect.SetBottom( aRect.Top() + nHdHeight );
+ aRect.AdjustTop(nHdHeight + nHdDist );
+
+ // draw header over PageFill, plus outline
+ drawFillAttributes(rRenderContext, maHeaderFillAttributes, aHdRect, aHdRect);
+ }
+
+ if (bFooter)
+ {
+ // show footer if possible
+ aFtRect.AdjustLeft(nFtLeft );
+ aFtRect.AdjustRight( -nFtRight );
+ aFtRect.SetTop( aRect.Bottom() - nFtHeight );
+ aRect.AdjustBottom( -(nFtHeight + nFtDist) );
+
+ // draw footer over PageFill, plus outline
+ drawFillAttributes(rRenderContext, maFooterFillAttributes, aFtRect, aFtRect);
+ }
+
+ // draw page's reduced outline, only outline
+ drawFillAttributes(rRenderContext, drawinglayer::attribute::SdrAllFillAttributesHelperPtr(), aRect, aRect);
+ }
+ else
+ {
+ // draw PageFill and outline
+ drawFillAttributes(rRenderContext, maPageFillAttributes, aRect, aRect);
+ }
+
+ if (bFrameDirection && !bTable)
+ {
+ Point aPos;
+ vcl::Font aFont(rRenderContext.GetFont());
+ const Size aSaveSize = aFont.GetFontSize();
+ Size aDrawSize(0,aRect.GetHeight() / 6);
+ aFont.SetFontSize(aDrawSize);
+ rRenderContext.SetFont(aFont);
+ OUString sText("ABC");
+ Point aMove(1, rRenderContext.GetTextHeight());
+ sal_Unicode cArrow = 0x2193;
+ tools::Long nAWidth = rRenderContext.GetTextWidth(sText.copy(0,1));
+ switch (nFrameDirection)
+ {
+ case SvxFrameDirection::Horizontal_LR_TB:
+ aPos = aRect.TopLeft();
+ aPos.AdjustX(rRenderContext.PixelToLogic(Point(1,1)).X() );
+ aMove.setY( 0 );
+ cArrow = 0x2192;
+ break;
+ case SvxFrameDirection::Horizontal_RL_TB:
+ aPos = aRect.TopRight();
+ aPos.AdjustX( -nAWidth );
+ aMove.setY( 0 );
+ aMove.setX( aMove.X() * -1 );
+ cArrow = 0x2190;
+ break;
+ case SvxFrameDirection::Vertical_LR_TB:
+ aPos = aRect.TopLeft();
+ aPos.AdjustX(rRenderContext.PixelToLogic(Point(1,1)).X() );
+ aMove.setX( 0 );
+ break;
+ case SvxFrameDirection::Vertical_RL_TB:
+ aPos = aRect.TopRight();
+ aPos.AdjustX( -nAWidth );
+ aMove.setX( 0 );
+ break;
+ default: break;
+ }
+ sText += OUStringChar(cArrow);
+ for (sal_Int32 i = 0; i < sText.getLength(); i++)
+ {
+ OUString sDraw(sText.copy(i,1));
+ tools::Long nHDiff = 0;
+ tools::Long nCharWidth = rRenderContext.GetTextWidth(sDraw);
+ bool bHorizontal = 0 == aMove.Y();
+ if (!bHorizontal)
+ {
+ nHDiff = (nAWidth - nCharWidth) / 2;
+ aPos.AdjustX(nHDiff );
+ }
+ rRenderContext.DrawText(aPos,sDraw);
+ if (bHorizontal)
+ {
+ aPos.AdjustX(aMove.X() < 0 ? -nCharWidth : nCharWidth );
+ }
+ else
+ {
+ aPos.AdjustX( -nHDiff );
+ aPos.AdjustY(aMove.Y() );
+ }
+ }
+ aFont.SetFontSize(aSaveSize);
+ rRenderContext.SetFont(aFont);
+
+ }
+ if (!bTable)
+ return;
+
+ // Paint Table, if necessary center it
+ rRenderContext.SetLineColor(COL_LIGHTGRAY);
+
+ tools::Long nW = aRect.GetWidth();
+ tools::Long nH = aRect.GetHeight();
+ tools::Long const nTW = CELL_WIDTH * 3;
+ tools::Long const nTH = CELL_HEIGHT * 3;
+ tools::Long _nLeft = bHorz ? aRect.Left() + ((nW - nTW) / 2) : aRect.Left();
+ tools::Long _nTop = bVert ? aRect.Top() + ((nH - nTH) / 2) : aRect.Top();
+ tools::Rectangle aCellRect(Point(_nLeft, _nTop),Size(CELL_WIDTH, CELL_HEIGHT));
+
+ for (sal_uInt16 i = 0; i < 3; ++i)
+ {
+ aCellRect.SetLeft( _nLeft );
+ aCellRect.SetRight( _nLeft + CELL_WIDTH );
+ if(i > 0)
+ aCellRect.Move(0,CELL_HEIGHT);
+
+ for (sal_uInt16 j = 0; j < 3; ++j)
+ {
+ if (j > 0)
+ aCellRect.Move(CELL_WIDTH,0);
+ rRenderContext.DrawRect(aCellRect);
+ }
+ }
+}
+
+void SvxPageWindow::drawFillAttributes(vcl::RenderContext& rRenderContext,
+ const drawinglayer::attribute::SdrAllFillAttributesHelperPtr& rFillAttributes,
+ const tools::Rectangle& rPaintRange,
+ const tools::Rectangle& rDefineRange)
+{
+ const basegfx::B2DRange aPaintRange = vcl::unotools::b2DRectangleFromRectangle(rPaintRange);
+
+ if(aPaintRange.isEmpty() ||
+ basegfx::fTools::equalZero(aPaintRange.getWidth()) ||
+ basegfx::fTools::equalZero(aPaintRange.getHeight()))
+ return;
+
+ const basegfx::B2DRange aDefineRange = vcl::unotools::b2DRectangleFromRectangle(rDefineRange);
+
+ // prepare primitive sequence
+ drawinglayer::primitive2d::Primitive2DContainer aSequence;
+
+ // create fill geometry if there is something to fill
+ if (rFillAttributes && rFillAttributes->isUsed())
+ {
+ aSequence = rFillAttributes->getPrimitive2DSequence(aPaintRange, aDefineRange);
+ }
+
+ // create line geometry if a LineColor is set at the target device
+ if (rRenderContext.IsLineColor())
+ {
+ const drawinglayer::primitive2d::Primitive2DReference xOutline(
+ new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(
+ basegfx::utils::createPolygonFromRect(aPaintRange), rRenderContext.GetLineColor().getBColor()));
+
+ aSequence.push_back(xOutline);
+ }
+
+ // draw that if we have something to draw
+ if (aSequence.empty())
+ return;
+
+ drawinglayer::geometry::ViewInformation2D aViewInformation2D;
+ aViewInformation2D.setViewTransformation(rRenderContext.GetViewTransformation());
+ aViewInformation2D.setViewport(aPaintRange);
+
+ std::unique_ptr<drawinglayer::processor2d::BaseProcessor2D> pProcessor(
+ drawinglayer::processor2d::createProcessor2DFromOutputDevice(rRenderContext, aViewInformation2D));
+ pProcessor->process(aSequence);
+}
+
+void SvxPageWindow::EnableFrameDirection(bool bEnable)
+{
+ bFrameDirection = bEnable;
+}
+
+void SvxPageWindow::SetFrameDirection(SvxFrameDirection nDirection)
+{
+ nFrameDirection = nDirection;
+}
+
+void SvxPageWindow::ResetBackground()
+{
+ bResetBackground = true;
+}
+
+void SvxPageWindow::SetDrawingArea(weld::DrawingArea* pDrawingArea)
+{
+ CustomWidgetController::SetDrawingArea(pDrawingArea);
+
+ OutputDevice& rRefDevice = pDrawingArea->get_ref_device();
+ // Count in Twips by default
+ rRefDevice.Push(vcl::PushFlags::MAPMODE);
+ rRefDevice.SetMapMode(MapMode(MapUnit::MapTwip));
+ aWinSize = rRefDevice.LogicToPixel(Size(75, 46), MapMode(MapUnit::MapAppFont));
+ pDrawingArea->set_size_request(aWinSize.Width(), aWinSize.Height());
+
+ aWinSize.AdjustHeight( -4 );
+ aWinSize.AdjustWidth( -4 );
+
+ aWinSize = rRefDevice.PixelToLogic(aWinSize);
+ rRefDevice.Pop();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */