1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <editeng/adjustitem.hxx>
21 #include <editeng/boxitem.hxx>
22 #include <editeng/brushitem.hxx>
23 #include <editeng/crossedoutitem.hxx>
24 #include <editeng/colritem.hxx>
25 #include <editeng/contouritem.hxx>
26 #include <editeng/fontitem.hxx>
27 #include <editeng/postitem.hxx>
28 #include <editeng/shdditem.hxx>
29 #include <editeng/udlnitem.hxx>
30 #include <editeng/wghtitem.hxx>
31 #include <vcl/settings.hxx>
32 #include <com/sun/star/i18n/BreakIterator.hpp>
33 #include <comphelper/processfactory.hxx>
34 #include <svtools/scriptedtext.hxx>
35 #include <svx/framelink.hxx>
36 #include <drawinglayer/processor2d/baseprocessor2d.hxx>
37 #include <drawinglayer/processor2d/processor2dtools.hxx>
38 #include <strings.hrc>
39 #include <svtools/colorcfg.hxx>
40 #include <swmodule.hxx>
42 #include <autoformatpreview.hxx>
44 #define FRAME_OFFSET 4
46 AutoFormatPreview::AutoFormatPreview()
47 : maCurrentData(OUString())
50 , maStringJan(SwResId(STR_JAN
))
51 , maStringFeb(SwResId(STR_FEB
))
52 , maStringMar(SwResId(STR_MAR
))
53 , maStringNorth(SwResId(STR_NORTH
))
54 , maStringMid(SwResId(STR_MID
))
55 , maStringSouth(SwResId(STR_SOUTH
))
56 , maStringSum(SwResId(STR_SUM
))
58 uno::Reference
<uno::XComponentContext
> xContext
= comphelper::getProcessComponentContext();
59 m_xBreak
= i18n::BreakIterator::create(xContext
);
60 mxNumFormat
.reset(new SvNumberFormatter(xContext
, LANGUAGE_SYSTEM
));
65 void AutoFormatPreview::Resize()
67 Size aSize
= GetOutputSizePixel();
68 maPreviousSize
= Size(aSize
.Width() - 6, aSize
.Height() - 30);
69 mnLabelColumnWidth
= (maPreviousSize
.Width() - 4) / 4 - 12;
70 mnDataColumnWidth1
= (maPreviousSize
.Width() - 4 - 2 * mnLabelColumnWidth
) / 3;
71 mnDataColumnWidth2
= (maPreviousSize
.Width() - 4 - 2 * mnLabelColumnWidth
) / 4;
72 mnRowHeight
= (maPreviousSize
.Height() - 4) / 5;
73 NotifyChange(maCurrentData
);
76 void AutoFormatPreview::DetectRTL(SwWrtShell
const* pWrtShell
)
78 if (!pWrtShell
->IsCursorInTable()) // We haven't created the table yet
79 mbRTL
= AllSettings::GetLayoutRTL();
81 mbRTL
= pWrtShell
->IsTableRightToLeft();
84 static void lcl_SetFontProperties(vcl::Font
& rFont
, const SvxFontItem
& rFontItem
,
85 const SvxWeightItem
& rWeightItem
,
86 const SvxPostureItem
& rPostureItem
)
88 rFont
.SetFamily(rFontItem
.GetFamily());
89 rFont
.SetFamilyName(rFontItem
.GetFamilyName());
90 rFont
.SetStyleName(rFontItem
.GetStyleName());
91 rFont
.SetCharSet(rFontItem
.GetCharSet());
92 rFont
.SetPitch(rFontItem
.GetPitch());
93 rFont
.SetWeight(rWeightItem
.GetValue());
94 rFont
.SetItalic(rPostureItem
.GetValue());
97 #define SETONALLFONTS(MethodName, Value) \
98 rFont.MethodName(Value); \
99 rCJKFont.MethodName(Value); \
100 rCTLFont.MethodName(Value);
102 void AutoFormatPreview::MakeFonts(vcl::RenderContext
const& rRenderContext
, sal_uInt8 nIndex
,
103 vcl::Font
& rFont
, vcl::Font
& rCJKFont
, vcl::Font
& rCTLFont
)
105 const SwBoxAutoFormat
& rBoxFormat
= maCurrentData
.GetBoxFormat(nIndex
);
107 rFont
= rCJKFont
= rCTLFont
= rRenderContext
.GetFont();
108 Size
aFontSize(rFont
.GetFontSize().Width(), 10 * rRenderContext
.GetDPIScaleFactor());
110 lcl_SetFontProperties(rFont
, rBoxFormat
.GetFont(), rBoxFormat
.GetWeight(),
111 rBoxFormat
.GetPosture());
112 lcl_SetFontProperties(rCJKFont
, rBoxFormat
.GetCJKFont(), rBoxFormat
.GetCJKWeight(),
113 rBoxFormat
.GetCJKPosture());
114 lcl_SetFontProperties(rCTLFont
, rBoxFormat
.GetCTLFont(), rBoxFormat
.GetCTLWeight(),
115 rBoxFormat
.GetCTLPosture());
117 SETONALLFONTS(SetUnderline
, rBoxFormat
.GetUnderline().GetValue());
118 SETONALLFONTS(SetOverline
, rBoxFormat
.GetOverline().GetValue());
119 SETONALLFONTS(SetStrikeout
, rBoxFormat
.GetCrossedOut().GetValue());
120 SETONALLFONTS(SetOutline
, rBoxFormat
.GetContour().GetValue());
121 SETONALLFONTS(SetShadow
, rBoxFormat
.GetShadowed().GetValue());
122 SETONALLFONTS(SetColor
, rBoxFormat
.GetColor().GetValue());
123 SETONALLFONTS(SetFontSize
, aFontSize
);
124 SETONALLFONTS(SetTransparent
, true);
127 sal_uInt8
AutoFormatPreview::GetFormatIndex(size_t nCol
, size_t nRow
) const
129 static const sal_uInt8 pnFormatMap
[]
130 = { 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 };
131 return pnFormatMap
[maArray
.GetCellIndex(nCol
, nRow
, mbRTL
)];
134 void AutoFormatPreview::DrawString(vcl::RenderContext
& rRenderContext
, size_t nCol
, size_t nRow
)
136 // Output of the cell text:
140 sal_uInt8 nIndex
= static_cast<sal_uInt8
>(maArray
.GetCellIndex(nCol
, nRow
, mbRTL
));
145 cellString
= maStringJan
;
148 cellString
= maStringFeb
;
151 cellString
= maStringMar
;
154 cellString
= maStringNorth
;
157 cellString
= maStringMid
;
160 cellString
= maStringSouth
;
164 cellString
= maStringSum
;
182 nNum
= 12 == nIndex
? 10 : 9;
214 if (maCurrentData
.IsValueFormat())
217 LanguageType eLng
, eSys
;
218 maCurrentData
.GetBoxFormat(sal_uInt8(nNum
)).GetValueFormat(sFormat
, eLng
, eSys
);
220 SvNumFormatType nType
;
223 sal_uInt32 nKey
= mxNumFormat
->GetIndexPuttingAndConverting(sFormat
, eLng
, eSys
,
224 nType
, bNew
, nCheckPos
);
226 mxNumFormat
->GetOutputString(nVal
, nKey
, cellString
, &pDummy
);
229 cellString
= OUString::number(sal_Int32(nVal
));
233 if (cellString
.isEmpty())
236 SvtScriptedTextHelper
aScriptedText(rRenderContext
);
238 sal_uInt8 nFormatIndex
= GetFormatIndex(nCol
, nRow
);
239 const basegfx::B2DRange
aCellRange(maArray
.GetCellRange(nCol
, nRow
));
240 const tools::Rectangle
cellRect(
241 basegfx::fround(aCellRange
.getMinX()), basegfx::fround(aCellRange
.getMinY()),
242 basegfx::fround(aCellRange
.getMaxX()), basegfx::fround(aCellRange
.getMaxY()));
243 Point aPos
= cellRect
.TopLeft();
244 tools::Long nRightX
= 0;
246 Size
theMaxStrSize(cellRect
.GetWidth() - FRAME_OFFSET
, cellRect
.GetHeight() - FRAME_OFFSET
);
247 if (maCurrentData
.IsFont())
249 vcl::Font aFont
, aCJKFont
, aCTLFont
;
250 MakeFonts(rRenderContext
, nFormatIndex
, aFont
, aCJKFont
, aCTLFont
);
251 aScriptedText
.SetFonts(&aFont
, &aCJKFont
, &aCTLFont
);
254 aScriptedText
.SetDefaultFont();
256 aScriptedText
.SetText(cellString
, m_xBreak
);
257 aStrSize
= aScriptedText
.GetTextSize();
259 if (maCurrentData
.IsFont() && theMaxStrSize
.Height() < aStrSize
.Height())
261 // If the string in this font does not
262 // fit into the cell, the standard font
264 aScriptedText
.SetDefaultFont();
265 aStrSize
= aScriptedText
.GetTextSize();
268 while (theMaxStrSize
.Width() <= aStrSize
.Width() && cellString
.getLength() > 1)
270 cellString
= cellString
.copy(0, cellString
.getLength() - 1);
271 aScriptedText
.SetText(cellString
, m_xBreak
);
272 aStrSize
= aScriptedText
.GetTextSize();
275 nRightX
= cellRect
.GetWidth() - aStrSize
.Width() - FRAME_OFFSET
;
277 // vertical (always centering):
278 aPos
.AdjustY((mnRowHeight
- aStrSize
.Height()) / 2);
282 aPos
.AdjustX(nRightX
);
283 else if (maCurrentData
.IsJustify())
285 const SvxAdjustItem
& rAdj
= maCurrentData
.GetBoxFormat(nFormatIndex
).GetAdjust();
286 switch (rAdj
.GetAdjust())
288 case SvxAdjust::Left
:
289 aPos
.AdjustX(FRAME_OFFSET
);
291 case SvxAdjust::Right
:
292 aPos
.AdjustX(nRightX
);
295 aPos
.AdjustX((cellRect
.GetWidth() - aStrSize
.Width()) / 2);
302 if (nCol
== 0 || nIndex
== 4)
304 // Text-Label left or sum left aligned
305 aPos
.AdjustX(FRAME_OFFSET
);
309 // numbers/dates right aligned
310 aPos
.AdjustX(nRightX
);
314 aScriptedText
.DrawText(aPos
);
317 void AutoFormatPreview::DrawBackground(vcl::RenderContext
& rRenderContext
)
319 for (size_t nRow
= 0; nRow
< 5; ++nRow
)
321 for (size_t nCol
= 0; nCol
< 5; ++nCol
)
323 SvxBrushItem
aBrushItem(
324 maCurrentData
.GetBoxFormat(GetFormatIndex(nCol
, nRow
)).GetBackground());
326 rRenderContext
.Push(vcl::PushFlags::LINECOLOR
| vcl::PushFlags::FILLCOLOR
);
327 rRenderContext
.SetLineColor();
328 rRenderContext
.SetFillColor(aBrushItem
.GetColor());
329 const basegfx::B2DRange
aCellRange(maArray
.GetCellRange(nCol
, nRow
));
330 rRenderContext
.DrawRect(tools::Rectangle(
331 basegfx::fround(aCellRange
.getMinX()), basegfx::fround(aCellRange
.getMinY()),
332 basegfx::fround(aCellRange
.getMaxX()), basegfx::fround(aCellRange
.getMaxY())));
333 rRenderContext
.Pop();
338 void AutoFormatPreview::PaintCells(vcl::RenderContext
& rRenderContext
)
341 if (maCurrentData
.IsBackground())
342 DrawBackground(rRenderContext
);
345 for (size_t nRow
= 0; nRow
< 5; ++nRow
)
346 for (size_t nCol
= 0; nCol
< 5; ++nCol
)
347 DrawString(rRenderContext
, nCol
, nRow
);
350 if (!maCurrentData
.IsFrame())
353 const drawinglayer::geometry::ViewInformation2D aNewViewInformation2D
;
354 std::unique_ptr
<drawinglayer::processor2d::BaseProcessor2D
> pProcessor2D(
355 drawinglayer::processor2d::createPixelProcessor2DFromOutputDevice(rRenderContext
,
356 aNewViewInformation2D
));
360 pProcessor2D
->process(maArray
.CreateB2DPrimitiveArray());
361 pProcessor2D
.reset();
365 void AutoFormatPreview::Init()
367 maArray
.Initialize(5, 5);
368 mnLabelColumnWidth
= 0;
369 mnDataColumnWidth1
= 0;
370 mnDataColumnWidth2
= 0;
372 CalcCellArray(false);
376 void AutoFormatPreview::CalcCellArray(bool _bFitWidth
)
378 maArray
.SetAllColWidths(_bFitWidth
? mnDataColumnWidth2
: mnDataColumnWidth1
);
379 maArray
.SetColWidth(0, mnLabelColumnWidth
);
380 maArray
.SetColWidth(4, mnLabelColumnWidth
);
382 maArray
.SetAllRowHeights(mnRowHeight
);
384 maPreviousSize
.setWidth(maArray
.GetWidth() + 4);
385 maPreviousSize
.setHeight(maArray
.GetHeight() + 4);
388 static void lclSetStyleFromBorder(svx::frame::Style
& rStyle
,
389 const ::editeng::SvxBorderLine
* pBorder
)
391 rStyle
.Set(pBorder
, 0.05, 5);
394 void AutoFormatPreview::CalcLineMap()
396 for (size_t nRow
= 0; nRow
< 5; ++nRow
)
398 for (size_t nCol
= 0; nCol
< 5; ++nCol
)
400 svx::frame::Style aStyle
;
402 const SvxBoxItem
& rItem
403 = maCurrentData
.GetBoxFormat(GetFormatIndex(nCol
, nRow
)).GetBox();
404 lclSetStyleFromBorder(aStyle
, rItem
.GetLeft());
405 maArray
.SetCellStyleLeft(nCol
, nRow
, aStyle
);
406 lclSetStyleFromBorder(aStyle
, rItem
.GetRight());
407 maArray
.SetCellStyleRight(nCol
, nRow
, aStyle
);
408 lclSetStyleFromBorder(aStyle
, rItem
.GetTop());
409 maArray
.SetCellStyleTop(nCol
, nRow
, aStyle
);
410 lclSetStyleFromBorder(aStyle
, rItem
.GetBottom());
411 maArray
.SetCellStyleBottom(nCol
, nRow
, aStyle
);
413 // FIXME - uncomment to draw diagonal borders
414 // lclSetStyleFromBorder( aStyle, GetDiagItem( nCol, nRow, true ).GetLine() );
415 // maArray.SetCellStyleTLBR( nCol, nRow, aStyle );
416 // lclSetStyleFromBorder( aStyle, GetDiagItem( nCol, nRow, false ).GetLine() );
417 // maArray.SetCellStyleBLTR( nCol, nRow, aStyle );
422 void AutoFormatPreview::NotifyChange(const SwTableAutoFormat
& rNewData
)
424 maCurrentData
= rNewData
;
425 mbFitWidth
= maCurrentData
.IsJustify(); // true; //???
426 CalcCellArray(mbFitWidth
);
431 void AutoFormatPreview::Paint(vcl::RenderContext
& rRenderContext
, const tools::Rectangle
&)
433 rRenderContext
.Push(vcl::PushFlags::ALL
);
435 const Color
& rWinColor
= SW_MOD()->GetColorConfig().GetColorValue(::svtools::DOCCOLOR
).nColor
;
436 rRenderContext
.SetBackground(Wallpaper(rWinColor
));
437 rRenderContext
.Erase();
439 DrawModeFlags nOldDrawMode
= rRenderContext
.GetDrawMode();
440 if (rRenderContext
.GetSettings().GetStyleSettings().GetHighContrastMode())
441 rRenderContext
.SetDrawMode(DrawModeFlags::SettingsLine
| DrawModeFlags::SettingsFill
442 | DrawModeFlags::SettingsText
| DrawModeFlags::SettingsGradient
);
444 Size theWndSize
= rRenderContext
.GetOutputSizePixel();
446 vcl::Font
aFont(rRenderContext
.GetFont());
447 aFont
.SetTransparent(true);
448 rRenderContext
.SetFont(aFont
);
451 Color oldColor
= rRenderContext
.GetLineColor();
452 rRenderContext
.SetLineColor();
453 rRenderContext
.DrawRect(tools::Rectangle(Point(0, 0), theWndSize
));
454 rRenderContext
.SetLineColor(oldColor
);
456 // Center the preview
457 maArray
.SetXOffset(2 + (theWndSize
.Width() - maPreviousSize
.Width()) / 2);
458 maArray
.SetYOffset(2 + (theWndSize
.Height() - maPreviousSize
.Height()) / 2);
459 // Draw cells on virtual device
460 PaintCells(rRenderContext
);
462 rRenderContext
.SetDrawMode(nOldDrawMode
);
463 rRenderContext
.Pop();
466 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */