471 lines
16 KiB
C++
471 lines
16 KiB
C++
/* -*- 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 <editeng/adjustitem.hxx>
|
|
#include <editeng/boxitem.hxx>
|
|
#include <editeng/brushitem.hxx>
|
|
#include <editeng/crossedoutitem.hxx>
|
|
#include <editeng/colritem.hxx>
|
|
#include <editeng/contouritem.hxx>
|
|
#include <editeng/fontitem.hxx>
|
|
#include <editeng/postitem.hxx>
|
|
#include <editeng/shdditem.hxx>
|
|
#include <editeng/udlnitem.hxx>
|
|
#include <editeng/wghtitem.hxx>
|
|
#include <vcl/settings.hxx>
|
|
#include <com/sun/star/i18n/BreakIterator.hpp>
|
|
#include <comphelper/processfactory.hxx>
|
|
#include <svtools/scriptedtext.hxx>
|
|
#include <svx/framelink.hxx>
|
|
#include <drawinglayer/processor2d/baseprocessor2d.hxx>
|
|
#include <drawinglayer/processor2d/processor2dtools.hxx>
|
|
#include <strings.hrc>
|
|
#include <svtools/colorcfg.hxx>
|
|
#include <swmodule.hxx>
|
|
|
|
#include <autoformatpreview.hxx>
|
|
|
|
#define FRAME_OFFSET 4
|
|
|
|
AutoFormatPreview::AutoFormatPreview()
|
|
: maCurrentData(OUString())
|
|
, mbFitWidth(false)
|
|
, mbRTL(false)
|
|
, maStringJan(SwResId(STR_JAN))
|
|
, maStringFeb(SwResId(STR_FEB))
|
|
, maStringMar(SwResId(STR_MAR))
|
|
, maStringNorth(SwResId(STR_NORTH))
|
|
, maStringMid(SwResId(STR_MID))
|
|
, maStringSouth(SwResId(STR_SOUTH))
|
|
, maStringSum(SwResId(STR_SUM))
|
|
{
|
|
const uno::Reference<uno::XComponentContext>& xContext
|
|
= comphelper::getProcessComponentContext();
|
|
m_xBreak = i18n::BreakIterator::create(xContext);
|
|
mxNumFormat.reset(new SvNumberFormatter(xContext, LANGUAGE_SYSTEM));
|
|
|
|
Init();
|
|
}
|
|
|
|
void AutoFormatPreview::Resize()
|
|
{
|
|
Size aSize = GetOutputSizePixel();
|
|
maPreviousSize = Size(aSize.Width() - 6, aSize.Height() - 30);
|
|
mnLabelColumnWidth = (maPreviousSize.Width() - 4) / 4 - 12;
|
|
mnDataColumnWidth1 = (maPreviousSize.Width() - 4 - 2 * mnLabelColumnWidth) / 3;
|
|
mnDataColumnWidth2 = (maPreviousSize.Width() - 4 - 2 * mnLabelColumnWidth) / 4;
|
|
mnRowHeight = (maPreviousSize.Height() - 4) / 5;
|
|
NotifyChange(maCurrentData);
|
|
}
|
|
|
|
void AutoFormatPreview::DetectRTL(SwWrtShell const* pWrtShell)
|
|
{
|
|
if (!pWrtShell->IsCursorInTable()) // We haven't created the table yet
|
|
mbRTL = AllSettings::GetLayoutRTL();
|
|
else
|
|
mbRTL = pWrtShell->IsTableRightToLeft();
|
|
}
|
|
|
|
static void lcl_SetFontProperties(vcl::Font& rFont, const SvxFontItem& rFontItem,
|
|
const SvxWeightItem& rWeightItem,
|
|
const SvxPostureItem& rPostureItem)
|
|
{
|
|
rFont.SetFamily(rFontItem.GetFamily());
|
|
rFont.SetFamilyName(rFontItem.GetFamilyName());
|
|
rFont.SetStyleName(rFontItem.GetStyleName());
|
|
rFont.SetCharSet(rFontItem.GetCharSet());
|
|
rFont.SetPitch(rFontItem.GetPitch());
|
|
rFont.SetWeight(rWeightItem.GetValue());
|
|
rFont.SetItalic(rPostureItem.GetValue());
|
|
}
|
|
|
|
#define SETONALLFONTS(MethodName, Value) \
|
|
rFont.MethodName(Value); \
|
|
rCJKFont.MethodName(Value); \
|
|
rCTLFont.MethodName(Value);
|
|
|
|
void AutoFormatPreview::MakeFonts(vcl::RenderContext const& rRenderContext, sal_uInt8 nIndex,
|
|
vcl::Font& rFont, vcl::Font& rCJKFont, vcl::Font& rCTLFont)
|
|
{
|
|
const SwBoxAutoFormat& rBoxFormat = maCurrentData.GetBoxFormat(nIndex);
|
|
|
|
rFont = rCJKFont = rCTLFont = rRenderContext.GetFont();
|
|
Size aFontSize(rFont.GetFontSize().Width(), 10 * rRenderContext.GetDPIScaleFactor());
|
|
|
|
lcl_SetFontProperties(rFont, rBoxFormat.GetFont(), rBoxFormat.GetWeight(),
|
|
rBoxFormat.GetPosture());
|
|
lcl_SetFontProperties(rCJKFont, rBoxFormat.GetCJKFont(), rBoxFormat.GetCJKWeight(),
|
|
rBoxFormat.GetCJKPosture());
|
|
lcl_SetFontProperties(rCTLFont, rBoxFormat.GetCTLFont(), rBoxFormat.GetCTLWeight(),
|
|
rBoxFormat.GetCTLPosture());
|
|
|
|
SETONALLFONTS(SetUnderline, rBoxFormat.GetUnderline().GetValue());
|
|
SETONALLFONTS(SetOverline, rBoxFormat.GetOverline().GetValue());
|
|
SETONALLFONTS(SetStrikeout, rBoxFormat.GetCrossedOut().GetValue());
|
|
SETONALLFONTS(SetOutline, rBoxFormat.GetContour().GetValue());
|
|
SETONALLFONTS(SetShadow, rBoxFormat.GetShadowed().GetValue());
|
|
SETONALLFONTS(SetColor, rBoxFormat.GetColor().GetValue());
|
|
SETONALLFONTS(SetFontSize, aFontSize);
|
|
SETONALLFONTS(SetTransparent, true);
|
|
}
|
|
|
|
sal_uInt8 AutoFormatPreview::GetFormatIndex(size_t nCol, size_t nRow) const
|
|
{
|
|
static const sal_uInt8 pnFormatMap[]
|
|
= { 0, 1, 2, 1, 3, 4, 5, 6, 5, 7, 8, 9, 10, 9, 11, 4, 5, 6, 5, 7, 12, 13, 14, 13, 15 };
|
|
return pnFormatMap[maArray.GetCellIndex(nCol, nRow, mbRTL)];
|
|
}
|
|
|
|
void AutoFormatPreview::DrawString(vcl::RenderContext& rRenderContext, size_t nCol, size_t nRow)
|
|
{
|
|
// Output of the cell text:
|
|
sal_uLong nNum;
|
|
double nVal;
|
|
OUString cellString;
|
|
sal_uInt8 nIndex = static_cast<sal_uInt8>(maArray.GetCellIndex(nCol, nRow, mbRTL));
|
|
|
|
switch (nIndex)
|
|
{
|
|
case 1:
|
|
cellString = maStringJan;
|
|
break;
|
|
case 2:
|
|
cellString = maStringFeb;
|
|
break;
|
|
case 3:
|
|
cellString = maStringMar;
|
|
break;
|
|
case 5:
|
|
cellString = maStringNorth;
|
|
break;
|
|
case 10:
|
|
cellString = maStringMid;
|
|
break;
|
|
case 15:
|
|
cellString = maStringSouth;
|
|
break;
|
|
case 4:
|
|
case 20:
|
|
cellString = maStringSum;
|
|
break;
|
|
case 6:
|
|
case 8:
|
|
case 16:
|
|
case 18:
|
|
nVal = nIndex;
|
|
nNum = 5;
|
|
goto MAKENUMSTR;
|
|
case 17:
|
|
case 7:
|
|
nVal = nIndex;
|
|
nNum = 6;
|
|
goto MAKENUMSTR;
|
|
case 11:
|
|
case 12:
|
|
case 13:
|
|
nVal = nIndex;
|
|
nNum = 12 == nIndex ? 10 : 9;
|
|
goto MAKENUMSTR;
|
|
case 9:
|
|
nVal = 21;
|
|
nNum = 7;
|
|
goto MAKENUMSTR;
|
|
case 14:
|
|
nVal = 36;
|
|
nNum = 11;
|
|
goto MAKENUMSTR;
|
|
case 19:
|
|
nVal = 51;
|
|
nNum = 7;
|
|
goto MAKENUMSTR;
|
|
case 21:
|
|
nVal = 33;
|
|
nNum = 13;
|
|
goto MAKENUMSTR;
|
|
case 22:
|
|
nVal = 36;
|
|
nNum = 14;
|
|
goto MAKENUMSTR;
|
|
case 23:
|
|
nVal = 39;
|
|
nNum = 13;
|
|
goto MAKENUMSTR;
|
|
case 24:
|
|
nVal = 108;
|
|
nNum = 15;
|
|
goto MAKENUMSTR;
|
|
|
|
MAKENUMSTR:
|
|
if (maCurrentData.IsValueFormat())
|
|
{
|
|
OUString sFormat;
|
|
LanguageType eLng, eSys;
|
|
maCurrentData.GetBoxFormat(sal_uInt8(nNum)).GetValueFormat(sFormat, eLng, eSys);
|
|
|
|
SvNumFormatType nType;
|
|
bool bNew;
|
|
sal_Int32 nCheckPos;
|
|
sal_uInt32 nKey = mxNumFormat->GetIndexPuttingAndConverting(sFormat, eLng, eSys,
|
|
nType, bNew, nCheckPos);
|
|
const Color* pDummy;
|
|
mxNumFormat->GetOutputString(nVal, nKey, cellString, &pDummy);
|
|
}
|
|
else
|
|
cellString = OUString::number(sal_Int32(nVal));
|
|
break;
|
|
}
|
|
|
|
if (cellString.isEmpty())
|
|
return;
|
|
|
|
SvtScriptedTextHelper aScriptedText(rRenderContext);
|
|
Size aStrSize;
|
|
sal_uInt8 nFormatIndex = GetFormatIndex(nCol, nRow);
|
|
const basegfx::B2DRange aCellRange(maArray.GetCellRange(nCol, nRow));
|
|
const tools::Rectangle cellRect(basegfx::fround<tools::Long>(aCellRange.getMinX()),
|
|
basegfx::fround<tools::Long>(aCellRange.getMinY()),
|
|
basegfx::fround<tools::Long>(aCellRange.getMaxX()),
|
|
basegfx::fround<tools::Long>(aCellRange.getMaxY()));
|
|
Point aPos = cellRect.TopLeft();
|
|
tools::Long nRightX = 0;
|
|
|
|
Size theMaxStrSize(cellRect.GetWidth() - FRAME_OFFSET, cellRect.GetHeight() - FRAME_OFFSET);
|
|
if (maCurrentData.IsFont())
|
|
{
|
|
vcl::Font aFont, aCJKFont, aCTLFont;
|
|
MakeFonts(rRenderContext, nFormatIndex, aFont, aCJKFont, aCTLFont);
|
|
aScriptedText.SetFonts(&aFont, &aCJKFont, &aCTLFont);
|
|
}
|
|
else
|
|
aScriptedText.SetDefaultFont();
|
|
|
|
aScriptedText.SetText(cellString, m_xBreak);
|
|
aStrSize = aScriptedText.GetTextSize();
|
|
|
|
if (maCurrentData.IsFont() && theMaxStrSize.Height() < aStrSize.Height())
|
|
{
|
|
// If the string in this font does not
|
|
// fit into the cell, the standard font
|
|
// is taken again:
|
|
aScriptedText.SetDefaultFont();
|
|
aStrSize = aScriptedText.GetTextSize();
|
|
}
|
|
|
|
while (theMaxStrSize.Width() <= aStrSize.Width() && cellString.getLength() > 1)
|
|
{
|
|
cellString = cellString.copy(0, cellString.getLength() - 1);
|
|
aScriptedText.SetText(cellString, m_xBreak);
|
|
aStrSize = aScriptedText.GetTextSize();
|
|
}
|
|
|
|
nRightX = cellRect.GetWidth() - aStrSize.Width() - FRAME_OFFSET;
|
|
|
|
// vertical (always centering):
|
|
aPos.AdjustY((mnRowHeight - aStrSize.Height()) / 2);
|
|
|
|
// horizontal
|
|
if (mbRTL)
|
|
aPos.AdjustX(nRightX);
|
|
else if (maCurrentData.IsJustify())
|
|
{
|
|
const SvxAdjustItem& rAdj = maCurrentData.GetBoxFormat(nFormatIndex).GetAdjust();
|
|
switch (rAdj.GetAdjust())
|
|
{
|
|
case SvxAdjust::Left:
|
|
aPos.AdjustX(FRAME_OFFSET);
|
|
break;
|
|
case SvxAdjust::Right:
|
|
aPos.AdjustX(nRightX);
|
|
break;
|
|
default:
|
|
aPos.AdjustX((cellRect.GetWidth() - aStrSize.Width()) / 2);
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Standard align:
|
|
if (nCol == 0 || nIndex == 4)
|
|
{
|
|
// Text-Label left or sum left aligned
|
|
aPos.AdjustX(FRAME_OFFSET);
|
|
}
|
|
else
|
|
{
|
|
// numbers/dates right aligned
|
|
aPos.AdjustX(nRightX);
|
|
}
|
|
}
|
|
|
|
aScriptedText.DrawText(aPos);
|
|
}
|
|
|
|
void AutoFormatPreview::DrawBackground(vcl::RenderContext& rRenderContext)
|
|
{
|
|
for (size_t nRow = 0; nRow < 5; ++nRow)
|
|
{
|
|
for (size_t nCol = 0; nCol < 5; ++nCol)
|
|
{
|
|
SvxBrushItem aBrushItem(
|
|
maCurrentData.GetBoxFormat(GetFormatIndex(nCol, nRow)).GetBackground());
|
|
|
|
rRenderContext.Push(vcl::PushFlags::LINECOLOR | vcl::PushFlags::FILLCOLOR);
|
|
rRenderContext.SetLineColor();
|
|
rRenderContext.SetFillColor(aBrushItem.GetColor());
|
|
const basegfx::B2DRange aCellRange(maArray.GetCellRange(nCol, nRow));
|
|
rRenderContext.DrawRect(
|
|
tools::Rectangle(basegfx::fround<tools::Long>(aCellRange.getMinX()),
|
|
basegfx::fround<tools::Long>(aCellRange.getMinY()),
|
|
basegfx::fround<tools::Long>(aCellRange.getMaxX()),
|
|
basegfx::fround<tools::Long>(aCellRange.getMaxY())));
|
|
rRenderContext.Pop();
|
|
}
|
|
}
|
|
}
|
|
|
|
void AutoFormatPreview::PaintCells(vcl::RenderContext& rRenderContext)
|
|
{
|
|
// 1) background
|
|
if (maCurrentData.IsBackground())
|
|
DrawBackground(rRenderContext);
|
|
|
|
// 2) values
|
|
for (size_t nRow = 0; nRow < 5; ++nRow)
|
|
for (size_t nCol = 0; nCol < 5; ++nCol)
|
|
DrawString(rRenderContext, nCol, nRow);
|
|
|
|
// 3) border
|
|
if (!maCurrentData.IsFrame())
|
|
return;
|
|
|
|
const drawinglayer::geometry::ViewInformation2D aNewViewInformation2D;
|
|
std::unique_ptr<drawinglayer::processor2d::BaseProcessor2D> pProcessor2D(
|
|
drawinglayer::processor2d::createPixelProcessor2DFromOutputDevice(rRenderContext,
|
|
aNewViewInformation2D));
|
|
|
|
if (pProcessor2D)
|
|
{
|
|
pProcessor2D->process(maArray.CreateB2DPrimitiveArray());
|
|
pProcessor2D.reset();
|
|
}
|
|
}
|
|
|
|
void AutoFormatPreview::Init()
|
|
{
|
|
maArray.Initialize(5, 5);
|
|
mnLabelColumnWidth = 0;
|
|
mnDataColumnWidth1 = 0;
|
|
mnDataColumnWidth2 = 0;
|
|
mnRowHeight = 0;
|
|
CalcCellArray(false);
|
|
CalcLineMap();
|
|
}
|
|
|
|
void AutoFormatPreview::CalcCellArray(bool _bFitWidth)
|
|
{
|
|
maArray.SetAllColWidths(_bFitWidth ? mnDataColumnWidth2 : mnDataColumnWidth1);
|
|
maArray.SetColWidth(0, mnLabelColumnWidth);
|
|
maArray.SetColWidth(4, mnLabelColumnWidth);
|
|
|
|
maArray.SetAllRowHeights(mnRowHeight);
|
|
|
|
maPreviousSize.setWidth(maArray.GetWidth() + 4);
|
|
maPreviousSize.setHeight(maArray.GetHeight() + 4);
|
|
}
|
|
|
|
static void lclSetStyleFromBorder(svx::frame::Style& rStyle,
|
|
const ::editeng::SvxBorderLine* pBorder)
|
|
{
|
|
rStyle.Set(pBorder, 0.05, 5);
|
|
}
|
|
|
|
void AutoFormatPreview::CalcLineMap()
|
|
{
|
|
for (size_t nRow = 0; nRow < 5; ++nRow)
|
|
{
|
|
for (size_t nCol = 0; nCol < 5; ++nCol)
|
|
{
|
|
svx::frame::Style aStyle;
|
|
|
|
const SvxBoxItem& rItem
|
|
= maCurrentData.GetBoxFormat(GetFormatIndex(nCol, nRow)).GetBox();
|
|
lclSetStyleFromBorder(aStyle, rItem.GetLeft());
|
|
maArray.SetCellStyleLeft(nCol, nRow, aStyle);
|
|
lclSetStyleFromBorder(aStyle, rItem.GetRight());
|
|
maArray.SetCellStyleRight(nCol, nRow, aStyle);
|
|
lclSetStyleFromBorder(aStyle, rItem.GetTop());
|
|
maArray.SetCellStyleTop(nCol, nRow, aStyle);
|
|
lclSetStyleFromBorder(aStyle, rItem.GetBottom());
|
|
maArray.SetCellStyleBottom(nCol, nRow, aStyle);
|
|
|
|
// FIXME - uncomment to draw diagonal borders
|
|
// lclSetStyleFromBorder( aStyle, GetDiagItem( nCol, nRow, true ).GetLine() );
|
|
// maArray.SetCellStyleTLBR( nCol, nRow, aStyle );
|
|
// lclSetStyleFromBorder( aStyle, GetDiagItem( nCol, nRow, false ).GetLine() );
|
|
// maArray.SetCellStyleBLTR( nCol, nRow, aStyle );
|
|
}
|
|
}
|
|
}
|
|
|
|
void AutoFormatPreview::NotifyChange(const SwTableAutoFormat& rNewData)
|
|
{
|
|
maCurrentData = rNewData;
|
|
mbFitWidth = maCurrentData.IsJustify(); // true; //???
|
|
CalcCellArray(mbFitWidth);
|
|
CalcLineMap();
|
|
Invalidate();
|
|
}
|
|
|
|
void AutoFormatPreview::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&)
|
|
{
|
|
rRenderContext.Push(vcl::PushFlags::ALL);
|
|
|
|
const Color& rWinColor
|
|
= SwModule::get()->GetColorConfig().GetColorValue(::svtools::DOCCOLOR).nColor;
|
|
rRenderContext.SetBackground(Wallpaper(rWinColor));
|
|
rRenderContext.Erase();
|
|
|
|
DrawModeFlags nOldDrawMode = rRenderContext.GetDrawMode();
|
|
if (rRenderContext.GetSettings().GetStyleSettings().GetHighContrastMode())
|
|
rRenderContext.SetDrawMode(DrawModeFlags::SettingsLine | DrawModeFlags::SettingsFill
|
|
| DrawModeFlags::SettingsText | DrawModeFlags::SettingsGradient);
|
|
|
|
Size theWndSize = rRenderContext.GetOutputSizePixel();
|
|
|
|
vcl::Font aFont(rRenderContext.GetFont());
|
|
aFont.SetTransparent(true);
|
|
rRenderContext.SetFont(aFont);
|
|
|
|
// Draw the Frame
|
|
Color oldColor = rRenderContext.GetLineColor();
|
|
rRenderContext.SetLineColor();
|
|
rRenderContext.DrawRect(tools::Rectangle(Point(0, 0), theWndSize));
|
|
rRenderContext.SetLineColor(oldColor);
|
|
|
|
// Center the preview
|
|
maArray.SetXOffset(2 + (theWndSize.Width() - maPreviousSize.Width()) / 2);
|
|
maArray.SetYOffset(2 + (theWndSize.Height() - maPreviousSize.Height()) / 2);
|
|
// Draw cells on virtual device
|
|
PaintCells(rRenderContext);
|
|
|
|
rRenderContext.SetDrawMode(nOldDrawMode);
|
|
rRenderContext.Pop();
|
|
}
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|