Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / sw / source / ui / table / autoformatpreview.cxx
blobe04fffefcae48f52b6ca911334eebe0d5eb133cc
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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())
48 , mbFitWidth(false)
49 , mbRTL(false)
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));
62 Init();
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();
80 else
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:
137 sal_uLong nNum;
138 double nVal;
139 OUString cellString;
140 sal_uInt8 nIndex = static_cast<sal_uInt8>(maArray.GetCellIndex(nCol, nRow, mbRTL));
142 switch (nIndex)
144 case 1:
145 cellString = maStringJan;
146 break;
147 case 2:
148 cellString = maStringFeb;
149 break;
150 case 3:
151 cellString = maStringMar;
152 break;
153 case 5:
154 cellString = maStringNorth;
155 break;
156 case 10:
157 cellString = maStringMid;
158 break;
159 case 15:
160 cellString = maStringSouth;
161 break;
162 case 4:
163 case 20:
164 cellString = maStringSum;
165 break;
166 case 6:
167 case 8:
168 case 16:
169 case 18:
170 nVal = nIndex;
171 nNum = 5;
172 goto MAKENUMSTR;
173 case 17:
174 case 7:
175 nVal = nIndex;
176 nNum = 6;
177 goto MAKENUMSTR;
178 case 11:
179 case 12:
180 case 13:
181 nVal = nIndex;
182 nNum = 12 == nIndex ? 10 : 9;
183 goto MAKENUMSTR;
184 case 9:
185 nVal = 21;
186 nNum = 7;
187 goto MAKENUMSTR;
188 case 14:
189 nVal = 36;
190 nNum = 11;
191 goto MAKENUMSTR;
192 case 19:
193 nVal = 51;
194 nNum = 7;
195 goto MAKENUMSTR;
196 case 21:
197 nVal = 33;
198 nNum = 13;
199 goto MAKENUMSTR;
200 case 22:
201 nVal = 36;
202 nNum = 14;
203 goto MAKENUMSTR;
204 case 23:
205 nVal = 39;
206 nNum = 13;
207 goto MAKENUMSTR;
208 case 24:
209 nVal = 108;
210 nNum = 15;
211 goto MAKENUMSTR;
213 MAKENUMSTR:
214 if (maCurrentData.IsValueFormat())
216 OUString sFormat;
217 LanguageType eLng, eSys;
218 maCurrentData.GetBoxFormat(sal_uInt8(nNum)).GetValueFormat(sFormat, eLng, eSys);
220 SvNumFormatType nType;
221 bool bNew;
222 sal_Int32 nCheckPos;
223 sal_uInt32 nKey = mxNumFormat->GetIndexPuttingAndConverting(sFormat, eLng, eSys,
224 nType, bNew, nCheckPos);
225 const Color* pDummy;
226 mxNumFormat->GetOutputString(nVal, nKey, cellString, &pDummy);
228 else
229 cellString = OUString::number(sal_Int32(nVal));
230 break;
233 if (cellString.isEmpty())
234 return;
236 SvtScriptedTextHelper aScriptedText(rRenderContext);
237 Size aStrSize;
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);
253 else
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
263 // is taken again:
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);
280 // horizontal
281 if (mbRTL)
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);
290 break;
291 case SvxAdjust::Right:
292 aPos.AdjustX(nRightX);
293 break;
294 default:
295 aPos.AdjustX((cellRect.GetWidth() - aStrSize.Width()) / 2);
296 break;
299 else
301 // Standard align:
302 if (nCol == 0 || nIndex == 4)
304 // Text-Label left or sum left aligned
305 aPos.AdjustX(FRAME_OFFSET);
307 else
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)
340 // 1) background
341 if (maCurrentData.IsBackground())
342 DrawBackground(rRenderContext);
344 // 2) values
345 for (size_t nRow = 0; nRow < 5; ++nRow)
346 for (size_t nCol = 0; nCol < 5; ++nCol)
347 DrawString(rRenderContext, nCol, nRow);
349 // 3) border
350 if (!maCurrentData.IsFrame())
351 return;
353 const drawinglayer::geometry::ViewInformation2D aNewViewInformation2D;
354 std::unique_ptr<drawinglayer::processor2d::BaseProcessor2D> pProcessor2D(
355 drawinglayer::processor2d::createPixelProcessor2DFromOutputDevice(rRenderContext,
356 aNewViewInformation2D));
358 if (pProcessor2D)
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;
371 mnRowHeight = 0;
372 CalcCellArray(false);
373 CalcLineMap();
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);
427 CalcLineMap();
428 Invalidate();
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);
450 // Draw the Frame
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: */