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 const uno::Reference
<uno::XComponentContext
>& xContext
59 = comphelper::getProcessComponentContext();
60 m_xBreak
= i18n::BreakIterator::create(xContext
);
61 mxNumFormat
.reset(new SvNumberFormatter(xContext
, LANGUAGE_SYSTEM
));
66 void AutoFormatPreview::Resize()
68 Size aSize
= GetOutputSizePixel();
69 maPreviousSize
= Size(aSize
.Width() - 6, aSize
.Height() - 30);
70 mnLabelColumnWidth
= (maPreviousSize
.Width() - 4) / 4 - 12;
71 mnDataColumnWidth1
= (maPreviousSize
.Width() - 4 - 2 * mnLabelColumnWidth
) / 3;
72 mnDataColumnWidth2
= (maPreviousSize
.Width() - 4 - 2 * mnLabelColumnWidth
) / 4;
73 mnRowHeight
= (maPreviousSize
.Height() - 4) / 5;
74 NotifyChange(maCurrentData
);
77 void AutoFormatPreview::DetectRTL(SwWrtShell
const* pWrtShell
)
79 if (!pWrtShell
->IsCursorInTable()) // We haven't created the table yet
80 mbRTL
= AllSettings::GetLayoutRTL();
82 mbRTL
= pWrtShell
->IsTableRightToLeft();
85 static void lcl_SetFontProperties(vcl::Font
& rFont
, const SvxFontItem
& rFontItem
,
86 const SvxWeightItem
& rWeightItem
,
87 const SvxPostureItem
& rPostureItem
)
89 rFont
.SetFamily(rFontItem
.GetFamily());
90 rFont
.SetFamilyName(rFontItem
.GetFamilyName());
91 rFont
.SetStyleName(rFontItem
.GetStyleName());
92 rFont
.SetCharSet(rFontItem
.GetCharSet());
93 rFont
.SetPitch(rFontItem
.GetPitch());
94 rFont
.SetWeight(rWeightItem
.GetValue());
95 rFont
.SetItalic(rPostureItem
.GetValue());
98 #define SETONALLFONTS(MethodName, Value) \
99 rFont.MethodName(Value); \
100 rCJKFont.MethodName(Value); \
101 rCTLFont.MethodName(Value);
103 void AutoFormatPreview::MakeFonts(vcl::RenderContext
const& rRenderContext
, sal_uInt8 nIndex
,
104 vcl::Font
& rFont
, vcl::Font
& rCJKFont
, vcl::Font
& rCTLFont
)
106 const SwBoxAutoFormat
& rBoxFormat
= maCurrentData
.GetBoxFormat(nIndex
);
108 rFont
= rCJKFont
= rCTLFont
= rRenderContext
.GetFont();
109 Size
aFontSize(rFont
.GetFontSize().Width(), 10 * rRenderContext
.GetDPIScaleFactor());
111 lcl_SetFontProperties(rFont
, rBoxFormat
.GetFont(), rBoxFormat
.GetWeight(),
112 rBoxFormat
.GetPosture());
113 lcl_SetFontProperties(rCJKFont
, rBoxFormat
.GetCJKFont(), rBoxFormat
.GetCJKWeight(),
114 rBoxFormat
.GetCJKPosture());
115 lcl_SetFontProperties(rCTLFont
, rBoxFormat
.GetCTLFont(), rBoxFormat
.GetCTLWeight(),
116 rBoxFormat
.GetCTLPosture());
118 SETONALLFONTS(SetUnderline
, rBoxFormat
.GetUnderline().GetValue());
119 SETONALLFONTS(SetOverline
, rBoxFormat
.GetOverline().GetValue());
120 SETONALLFONTS(SetStrikeout
, rBoxFormat
.GetCrossedOut().GetValue());
121 SETONALLFONTS(SetOutline
, rBoxFormat
.GetContour().GetValue());
122 SETONALLFONTS(SetShadow
, rBoxFormat
.GetShadowed().GetValue());
123 SETONALLFONTS(SetColor
, rBoxFormat
.GetColor().GetValue());
124 SETONALLFONTS(SetFontSize
, aFontSize
);
125 SETONALLFONTS(SetTransparent
, true);
128 sal_uInt8
AutoFormatPreview::GetFormatIndex(size_t nCol
, size_t nRow
) const
130 static const sal_uInt8 pnFormatMap
[]
131 = { 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 };
132 return pnFormatMap
[maArray
.GetCellIndex(nCol
, nRow
, mbRTL
)];
135 void AutoFormatPreview::DrawString(vcl::RenderContext
& rRenderContext
, size_t nCol
, size_t nRow
)
137 // Output of the cell text:
141 sal_uInt8 nIndex
= static_cast<sal_uInt8
>(maArray
.GetCellIndex(nCol
, nRow
, mbRTL
));
146 cellString
= maStringJan
;
149 cellString
= maStringFeb
;
152 cellString
= maStringMar
;
155 cellString
= maStringNorth
;
158 cellString
= maStringMid
;
161 cellString
= maStringSouth
;
165 cellString
= maStringSum
;
183 nNum
= 12 == nIndex
? 10 : 9;
215 if (maCurrentData
.IsValueFormat())
218 LanguageType eLng
, eSys
;
219 maCurrentData
.GetBoxFormat(sal_uInt8(nNum
)).GetValueFormat(sFormat
, eLng
, eSys
);
221 SvNumFormatType nType
;
224 sal_uInt32 nKey
= mxNumFormat
->GetIndexPuttingAndConverting(sFormat
, eLng
, eSys
,
225 nType
, bNew
, nCheckPos
);
227 mxNumFormat
->GetOutputString(nVal
, nKey
, cellString
, &pDummy
);
230 cellString
= OUString::number(sal_Int32(nVal
));
234 if (cellString
.isEmpty())
237 SvtScriptedTextHelper
aScriptedText(rRenderContext
);
239 sal_uInt8 nFormatIndex
= GetFormatIndex(nCol
, nRow
);
240 const basegfx::B2DRange
aCellRange(maArray
.GetCellRange(nCol
, nRow
));
241 const tools::Rectangle
cellRect(basegfx::fround
<tools::Long
>(aCellRange
.getMinX()),
242 basegfx::fround
<tools::Long
>(aCellRange
.getMinY()),
243 basegfx::fround
<tools::Long
>(aCellRange
.getMaxX()),
244 basegfx::fround
<tools::Long
>(aCellRange
.getMaxY()));
245 Point aPos
= cellRect
.TopLeft();
246 tools::Long nRightX
= 0;
248 Size
theMaxStrSize(cellRect
.GetWidth() - FRAME_OFFSET
, cellRect
.GetHeight() - FRAME_OFFSET
);
249 if (maCurrentData
.IsFont())
251 vcl::Font aFont
, aCJKFont
, aCTLFont
;
252 MakeFonts(rRenderContext
, nFormatIndex
, aFont
, aCJKFont
, aCTLFont
);
253 aScriptedText
.SetFonts(&aFont
, &aCJKFont
, &aCTLFont
);
256 aScriptedText
.SetDefaultFont();
258 aScriptedText
.SetText(cellString
, m_xBreak
);
259 aStrSize
= aScriptedText
.GetTextSize();
261 if (maCurrentData
.IsFont() && theMaxStrSize
.Height() < aStrSize
.Height())
263 // If the string in this font does not
264 // fit into the cell, the standard font
266 aScriptedText
.SetDefaultFont();
267 aStrSize
= aScriptedText
.GetTextSize();
270 while (theMaxStrSize
.Width() <= aStrSize
.Width() && cellString
.getLength() > 1)
272 cellString
= cellString
.copy(0, cellString
.getLength() - 1);
273 aScriptedText
.SetText(cellString
, m_xBreak
);
274 aStrSize
= aScriptedText
.GetTextSize();
277 nRightX
= cellRect
.GetWidth() - aStrSize
.Width() - FRAME_OFFSET
;
279 // vertical (always centering):
280 aPos
.AdjustY((mnRowHeight
- aStrSize
.Height()) / 2);
284 aPos
.AdjustX(nRightX
);
285 else if (maCurrentData
.IsJustify())
287 const SvxAdjustItem
& rAdj
= maCurrentData
.GetBoxFormat(nFormatIndex
).GetAdjust();
288 switch (rAdj
.GetAdjust())
290 case SvxAdjust::Left
:
291 aPos
.AdjustX(FRAME_OFFSET
);
293 case SvxAdjust::Right
:
294 aPos
.AdjustX(nRightX
);
297 aPos
.AdjustX((cellRect
.GetWidth() - aStrSize
.Width()) / 2);
304 if (nCol
== 0 || nIndex
== 4)
306 // Text-Label left or sum left aligned
307 aPos
.AdjustX(FRAME_OFFSET
);
311 // numbers/dates right aligned
312 aPos
.AdjustX(nRightX
);
316 aScriptedText
.DrawText(aPos
);
319 void AutoFormatPreview::DrawBackground(vcl::RenderContext
& rRenderContext
)
321 for (size_t nRow
= 0; nRow
< 5; ++nRow
)
323 for (size_t nCol
= 0; nCol
< 5; ++nCol
)
325 SvxBrushItem
aBrushItem(
326 maCurrentData
.GetBoxFormat(GetFormatIndex(nCol
, nRow
)).GetBackground());
328 rRenderContext
.Push(vcl::PushFlags::LINECOLOR
| vcl::PushFlags::FILLCOLOR
);
329 rRenderContext
.SetLineColor();
330 rRenderContext
.SetFillColor(aBrushItem
.GetColor());
331 const basegfx::B2DRange
aCellRange(maArray
.GetCellRange(nCol
, nRow
));
332 rRenderContext
.DrawRect(
333 tools::Rectangle(basegfx::fround
<tools::Long
>(aCellRange
.getMinX()),
334 basegfx::fround
<tools::Long
>(aCellRange
.getMinY()),
335 basegfx::fround
<tools::Long
>(aCellRange
.getMaxX()),
336 basegfx::fround
<tools::Long
>(aCellRange
.getMaxY())));
337 rRenderContext
.Pop();
342 void AutoFormatPreview::PaintCells(vcl::RenderContext
& rRenderContext
)
345 if (maCurrentData
.IsBackground())
346 DrawBackground(rRenderContext
);
349 for (size_t nRow
= 0; nRow
< 5; ++nRow
)
350 for (size_t nCol
= 0; nCol
< 5; ++nCol
)
351 DrawString(rRenderContext
, nCol
, nRow
);
354 if (!maCurrentData
.IsFrame())
357 const drawinglayer::geometry::ViewInformation2D aNewViewInformation2D
;
358 std::unique_ptr
<drawinglayer::processor2d::BaseProcessor2D
> pProcessor2D(
359 drawinglayer::processor2d::createPixelProcessor2DFromOutputDevice(rRenderContext
,
360 aNewViewInformation2D
));
364 pProcessor2D
->process(maArray
.CreateB2DPrimitiveArray());
365 pProcessor2D
.reset();
369 void AutoFormatPreview::Init()
371 maArray
.Initialize(5, 5);
372 mnLabelColumnWidth
= 0;
373 mnDataColumnWidth1
= 0;
374 mnDataColumnWidth2
= 0;
376 CalcCellArray(false);
380 void AutoFormatPreview::CalcCellArray(bool _bFitWidth
)
382 maArray
.SetAllColWidths(_bFitWidth
? mnDataColumnWidth2
: mnDataColumnWidth1
);
383 maArray
.SetColWidth(0, mnLabelColumnWidth
);
384 maArray
.SetColWidth(4, mnLabelColumnWidth
);
386 maArray
.SetAllRowHeights(mnRowHeight
);
388 maPreviousSize
.setWidth(maArray
.GetWidth() + 4);
389 maPreviousSize
.setHeight(maArray
.GetHeight() + 4);
392 static void lclSetStyleFromBorder(svx::frame::Style
& rStyle
,
393 const ::editeng::SvxBorderLine
* pBorder
)
395 rStyle
.Set(pBorder
, 0.05, 5);
398 void AutoFormatPreview::CalcLineMap()
400 for (size_t nRow
= 0; nRow
< 5; ++nRow
)
402 for (size_t nCol
= 0; nCol
< 5; ++nCol
)
404 svx::frame::Style aStyle
;
406 const SvxBoxItem
& rItem
407 = maCurrentData
.GetBoxFormat(GetFormatIndex(nCol
, nRow
)).GetBox();
408 lclSetStyleFromBorder(aStyle
, rItem
.GetLeft());
409 maArray
.SetCellStyleLeft(nCol
, nRow
, aStyle
);
410 lclSetStyleFromBorder(aStyle
, rItem
.GetRight());
411 maArray
.SetCellStyleRight(nCol
, nRow
, aStyle
);
412 lclSetStyleFromBorder(aStyle
, rItem
.GetTop());
413 maArray
.SetCellStyleTop(nCol
, nRow
, aStyle
);
414 lclSetStyleFromBorder(aStyle
, rItem
.GetBottom());
415 maArray
.SetCellStyleBottom(nCol
, nRow
, aStyle
);
417 // FIXME - uncomment to draw diagonal borders
418 // lclSetStyleFromBorder( aStyle, GetDiagItem( nCol, nRow, true ).GetLine() );
419 // maArray.SetCellStyleTLBR( nCol, nRow, aStyle );
420 // lclSetStyleFromBorder( aStyle, GetDiagItem( nCol, nRow, false ).GetLine() );
421 // maArray.SetCellStyleBLTR( nCol, nRow, aStyle );
426 void AutoFormatPreview::NotifyChange(const SwTableAutoFormat
& rNewData
)
428 maCurrentData
= rNewData
;
429 mbFitWidth
= maCurrentData
.IsJustify(); // true; //???
430 CalcCellArray(mbFitWidth
);
435 void AutoFormatPreview::Paint(vcl::RenderContext
& rRenderContext
, const tools::Rectangle
&)
437 rRenderContext
.Push(vcl::PushFlags::ALL
);
439 const Color
& rWinColor
440 = SwModule::get()->GetColorConfig().GetColorValue(::svtools::DOCCOLOR
).nColor
;
441 rRenderContext
.SetBackground(Wallpaper(rWinColor
));
442 rRenderContext
.Erase();
444 DrawModeFlags nOldDrawMode
= rRenderContext
.GetDrawMode();
445 if (rRenderContext
.GetSettings().GetStyleSettings().GetHighContrastMode())
446 rRenderContext
.SetDrawMode(DrawModeFlags::SettingsLine
| DrawModeFlags::SettingsFill
447 | DrawModeFlags::SettingsText
| DrawModeFlags::SettingsGradient
);
449 Size theWndSize
= rRenderContext
.GetOutputSizePixel();
451 vcl::Font
aFont(rRenderContext
.GetFont());
452 aFont
.SetTransparent(true);
453 rRenderContext
.SetFont(aFont
);
456 Color oldColor
= rRenderContext
.GetLineColor();
457 rRenderContext
.SetLineColor();
458 rRenderContext
.DrawRect(tools::Rectangle(Point(0, 0), theWndSize
));
459 rRenderContext
.SetLineColor(oldColor
);
461 // Center the preview
462 maArray
.SetXOffset(2 + (theWndSize
.Width() - maPreviousSize
.Width()) / 2);
463 maArray
.SetYOffset(2 + (theWndSize
.Height() - maPreviousSize
.Height()) / 2);
464 // Draw cells on virtual device
465 PaintCells(rRenderContext
);
467 rRenderContext
.SetDrawMode(nOldDrawMode
);
468 rRenderContext
.Pop();
471 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */