LibreOffice Module sw (master) 1
autoformatpreview.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
21#include <editeng/boxitem.hxx>
22#include <editeng/brushitem.hxx>
24#include <editeng/colritem.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>
35#include <svx/framelink.hxx>
38#include <strings.hrc>
39#include <svtools/colorcfg.hxx>
40#include <swmodule.hxx>
41
42#include <autoformatpreview.hxx>
43
44#define FRAME_OFFSET 4
45
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))
57{
58 uno::Reference<uno::XComponentContext> xContext = comphelper::getProcessComponentContext();
59 m_xBreak = i18n::BreakIterator::create(xContext);
60 mxNumFormat.reset(new SvNumberFormatter(xContext, LANGUAGE_SYSTEM));
61
62 Init();
63}
64
66{
67 Size aSize = GetOutputSizePixel();
68 maPreviousSize = Size(aSize.Width() - 6, aSize.Height() - 30);
69 mnLabelColumnWidth = (maPreviousSize.Width() - 4) / 4 - 12;
72 mnRowHeight = (maPreviousSize.Height() - 4) / 5;
74}
75
77{
78 if (!pWrtShell->IsCursorInTable()) // We haven't created the table yet
80 else
81 mbRTL = pWrtShell->IsTableRightToLeft();
82}
83
84static void lcl_SetFontProperties(vcl::Font& rFont, const SvxFontItem& rFontItem,
85 const SvxWeightItem& rWeightItem,
86 const SvxPostureItem& rPostureItem)
87{
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());
95}
96
97#define SETONALLFONTS(MethodName, Value) \
98 rFont.MethodName(Value); \
99 rCJKFont.MethodName(Value); \
100 rCTLFont.MethodName(Value);
101
103 vcl::Font& rFont, vcl::Font& rCJKFont, vcl::Font& rCTLFont)
104{
106
107 rFont = rCJKFont = rCTLFont = rRenderContext.GetFont();
108 Size aFontSize(rFont.GetFontSize().Width(), 10 * rRenderContext.GetDPIScaleFactor());
109
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());
116
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);
125}
126
127sal_uInt8 AutoFormatPreview::GetFormatIndex(size_t nCol, size_t nRow) const
128{
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)];
132}
133
134void AutoFormatPreview::DrawString(vcl::RenderContext& rRenderContext, size_t nCol, size_t nRow)
135{
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));
141
142 switch (nIndex)
143 {
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;
212
213 MAKENUMSTR:
215 {
216 OUString sFormat;
217 LanguageType eLng, eSys;
218 maCurrentData.GetBoxFormat(sal_uInt8(nNum)).GetValueFormat(sFormat, eLng, eSys);
219
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);
227 }
228 else
229 cellString = OUString::number(sal_Int32(nVal));
230 break;
231 }
232
233 if (cellString.isEmpty())
234 return;
235
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;
245
246 Size theMaxStrSize(cellRect.GetWidth() - FRAME_OFFSET, cellRect.GetHeight() - FRAME_OFFSET);
247 if (maCurrentData.IsFont())
248 {
249 vcl::Font aFont, aCJKFont, aCTLFont;
250 MakeFonts(rRenderContext, nFormatIndex, aFont, aCJKFont, aCTLFont);
251 aScriptedText.SetFonts(&aFont, &aCJKFont, &aCTLFont);
252 }
253 else
254 aScriptedText.SetDefaultFont();
255
256 aScriptedText.SetText(cellString, m_xBreak);
257 aStrSize = aScriptedText.GetTextSize();
258
259 if (maCurrentData.IsFont() && theMaxStrSize.Height() < aStrSize.Height())
260 {
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();
266 }
267
268 while (theMaxStrSize.Width() <= aStrSize.Width() && cellString.getLength() > 1)
269 {
270 cellString = cellString.copy(0, cellString.getLength() - 1);
271 aScriptedText.SetText(cellString, m_xBreak);
272 aStrSize = aScriptedText.GetTextSize();
273 }
274
275 nRightX = cellRect.GetWidth() - aStrSize.Width() - FRAME_OFFSET;
276
277 // vertical (always centering):
278 aPos.AdjustY((mnRowHeight - aStrSize.Height()) / 2);
279
280 // horizontal
281 if (mbRTL)
282 aPos.AdjustX(nRightX);
283 else if (maCurrentData.IsJustify())
284 {
285 const SvxAdjustItem& rAdj = maCurrentData.GetBoxFormat(nFormatIndex).GetAdjust();
286 switch (rAdj.GetAdjust())
287 {
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;
297 }
298 }
299 else
300 {
301 // Standard align:
302 if (nCol == 0 || nIndex == 4)
303 {
304 // Text-Label left or sum left aligned
305 aPos.AdjustX(FRAME_OFFSET);
306 }
307 else
308 {
309 // numbers/dates right aligned
310 aPos.AdjustX(nRightX);
311 }
312 }
313
314 aScriptedText.DrawText(aPos);
315}
316
318{
319 for (size_t nRow = 0; nRow < 5; ++nRow)
320 {
321 for (size_t nCol = 0; nCol < 5; ++nCol)
322 {
323 SvxBrushItem aBrushItem(
324 maCurrentData.GetBoxFormat(GetFormatIndex(nCol, nRow)).GetBackground());
325
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();
334 }
335 }
336}
337
339{
340 // 1) background
342 DrawBackground(rRenderContext);
343
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);
348
349 // 3) border
350 if (!maCurrentData.IsFrame())
351 return;
352
353 const drawinglayer::geometry::ViewInformation2D aNewViewInformation2D;
354 std::unique_ptr<drawinglayer::processor2d::BaseProcessor2D> pProcessor2D(
356 aNewViewInformation2D));
357
358 if (pProcessor2D)
359 {
360 pProcessor2D->process(maArray.CreateB2DPrimitiveArray());
361 pProcessor2D.reset();
362 }
363}
364
366{
367 maArray.Initialize(5, 5);
371 mnRowHeight = 0;
372 CalcCellArray(false);
373 CalcLineMap();
374}
375
377{
381
383
386}
387
389 const ::editeng::SvxBorderLine* pBorder)
390{
391 rStyle.Set(pBorder, 0.05, 5);
392}
393
395{
396 for (size_t nRow = 0; nRow < 5; ++nRow)
397 {
398 for (size_t nCol = 0; nCol < 5; ++nCol)
399 {
400 svx::frame::Style aStyle;
401
402 const SvxBoxItem& rItem
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);
412
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 );
418 }
419 }
420}
421
423{
424 maCurrentData = rNewData;
425 mbFitWidth = maCurrentData.IsJustify(); // true; //???
427 CalcLineMap();
428 Invalidate();
429}
430
432{
433 rRenderContext.Push(vcl::PushFlags::ALL);
434
435 const Color& rWinColor = SW_MOD()->GetColorConfig().GetColorValue(::svtools::DOCCOLOR).nColor;
436 rRenderContext.SetBackground(Wallpaper(rWinColor));
437 rRenderContext.Erase();
438
439 DrawModeFlags nOldDrawMode = rRenderContext.GetDrawMode();
440 if (rRenderContext.GetSettings().GetStyleSettings().GetHighContrastMode())
441 rRenderContext.SetDrawMode(DrawModeFlags::SettingsLine | DrawModeFlags::SettingsFill
442 | DrawModeFlags::SettingsText | DrawModeFlags::SettingsGradient);
443
444 Size theWndSize = rRenderContext.GetOutputSizePixel();
445
446 vcl::Font aFont(rRenderContext.GetFont());
447 aFont.SetTransparent(true);
448 rRenderContext.SetFont(aFont);
449
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);
455
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);
461
462 rRenderContext.SetDrawMode(nOldDrawMode);
463 rRenderContext.Pop();
464}
465
466/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
DrawModeFlags
#define SETONALLFONTS(MethodName, Value)
#define FRAME_OFFSET
static void lcl_SetFontProperties(vcl::Font &rFont, const SvxFontItem &rFontItem, const SvxWeightItem &rWeightItem, const SvxPostureItem &rPostureItem)
static void lclSetStyleFromBorder(svx::frame::Style &rStyle, const ::editeng::SvxBorderLine *pBorder)
const StyleSettings & GetStyleSettings() const
static bool GetLayoutRTL()
const SvxContourItem & GetContour() const
const SvxColorItem & GetColor() const
const SvxWeightItem & GetWeight() const
const SvxBoxItem & GetBox() const
const SvxWeightItem & GetCTLWeight() const
const SvxFontItem & GetCTLFont() const
const SvxPostureItem & GetPosture() const
const SvxFontItem & GetFont() const
const SvxWeightItem & GetCJKWeight() const
const SvxPostureItem & GetCJKPosture() const
const SvxOverlineItem & GetOverline() const
const SvxFontItem & GetCJKFont() const
const SvxAdjustItem & GetAdjust() const
const SvxShadowedItem & GetShadowed() const
const SvxPostureItem & GetCTLPosture() const
const SvxCrossedOutItem & GetCrossedOut() const
const SvxUnderlineItem & GetUnderline() const
void DetectRTL(SwWrtShell const *pWrtShell)
void DrawString(vcl::RenderContext &rRenderContext, size_t nCol, size_t nRow)
sal_uInt8 GetFormatIndex(size_t nCol, size_t nRow) const
const OUString maStringMar
const OUString maStringSum
svx::frame::Array maArray
void DrawBackground(vcl::RenderContext &rRenderContext)
void PaintCells(vcl::RenderContext &rRenderContext)
tools::Long mnLabelColumnWidth
const OUString maStringSouth
bool mbFitWidth
Implementation to draw the frame borders.
const OUString maStringMid
void NotifyChange(const SwTableAutoFormat &rNewData)
const OUString maStringFeb
uno::Reference< i18n::XBreakIterator > m_xBreak
virtual void Resize() override
std::unique_ptr< SvNumberFormatter > mxNumFormat
const OUString maStringNorth
SwTableAutoFormat maCurrentData
tools::Long mnDataColumnWidth1
tools::Long mnDataColumnWidth2
const OUString maStringJan
virtual void Paint(vcl::RenderContext &rRenderContext, const tools::Rectangle &rRect) override
void MakeFonts(vcl::RenderContext const &rRenderContext, sal_uInt8 nIndex, vcl::Font &rFont, vcl::Font &rCJKFont, vcl::Font &rCTLFont)
void CalcCellArray(bool bFitWidth)
const vcl::Font & GetFont() const
float GetDPIScaleFactor() const
void SetFont(const vcl::Font &rNewFont)
Size GetOutputSizePixel() const
void DrawRect(const tools::Rectangle &rRect)
void SetLineColor()
void SetFillColor()
const Color & GetLineColor() const
void Push(vcl::PushFlags nFlags=vcl::PushFlags::ALL)
void SetBackground()
void SetDrawMode(DrawModeFlags nDrawMode)
DrawModeFlags GetDrawMode() const
const AllSettings & GetSettings() const
tools::Long AdjustY(tools::Long nVertMove)
tools::Long AdjustX(tools::Long nHorzMove)
constexpr tools::Long Height() const
void setWidth(tools::Long nWidth)
void setHeight(tools::Long nHeight)
constexpr tools::Long Width() const
bool GetHighContrastMode() const
const Size & GetTextSize() const
void SetText(const OUString &_rText, const css::uno::Reference< css::i18n::XBreakIterator > &_xBreakIter)
void DrawText(const Point &_rPos)
void SetFonts(vcl::Font const *_pLatinFont, vcl::Font const *_pAsianFont, vcl::Font const *_pCmplxFont)
SvxAdjust GetAdjust() const
const editeng::SvxBorderLine * GetTop() const
const editeng::SvxBorderLine * GetRight() const
const editeng::SvxBorderLine * GetLeft() const
const editeng::SvxBorderLine * GetBottom() const
const Color & GetColor() const
const Color & GetValue() const
FontFamily GetFamily() const
FontPitch GetPitch() const
const OUString & GetStyleName() const
rtl_TextEncoding GetCharSet() const
const OUString & GetFamilyName() const
const SwTableNode * IsCursorInTable() const
Check if Point of current cursor is placed within a table.
Definition: crsrsh.cxx:600
bool IsTableRightToLeft() const
Definition: fetab.cxx:2480
bool IsJustify() const
Definition: tblafmt.hxx:218
const SwBoxAutoFormat & GetBoxFormat(sal_uInt8 nPos) const
Definition: tblafmt.cxx:455
bool IsValueFormat() const
Definition: tblafmt.hxx:221
bool IsBackground() const
Definition: tblafmt.hxx:220
bool IsFont() const
Definition: tblafmt.hxx:217
bool IsFrame() const
Definition: tblafmt.hxx:219
Used by the UI to modify the document model.
Definition: wrtsh.hxx:97
TYPE getMaxX() const
TYPE getMinX() const
TYPE getMinY() const
TYPE getMaxY() const
void SetCellStyleBottom(sal_Int32 nCol, sal_Int32 nRow, const Style &rStyle)
void SetCellStyleLeft(sal_Int32 nCol, sal_Int32 nRow, const Style &rStyle)
void SetCellStyleRight(sal_Int32 nCol, sal_Int32 nRow, const Style &rStyle)
void SetColWidth(sal_Int32 nCol, sal_Int32 nWidth)
void SetXOffset(sal_Int32 nXOffset)
sal_Int32 GetWidth() const
basegfx::B2DRange GetCellRange(sal_Int32 nCol, sal_Int32 nRow) const
void Initialize(sal_Int32 nWidth, sal_Int32 nHeight)
void SetYOffset(sal_Int32 nYOffset)
drawinglayer::primitive2d::Primitive2DContainer CreateB2DPrimitiveArray() const
sal_Int32 GetHeight() const
void SetAllColWidths(sal_Int32 nWidth)
void SetAllRowHeights(sal_Int32 nHeight)
sal_Int32 GetCellIndex(sal_Int32 nCol, sal_Int32 nRow, bool bRTL) const
void SetCellStyleTop(sal_Int32 nCol, sal_Int32 nRow, const Style &rStyle)
void Set(double nP, double nD, double nS)
constexpr tools::Long GetWidth() const
constexpr Point TopLeft() const
constexpr tools::Long GetHeight() const
void SetStyleName(const OUString &rStyleName)
void SetPitch(FontPitch ePitch)
void SetTransparent(bool bTransparent)
void SetItalic(FontItalic)
void SetWeight(FontWeight)
void SetFamily(FontFamily)
void SetCharSet(rtl_TextEncoding)
const Size & GetFontSize() const
void SetFamilyName(const OUString &rFamilyName)
Size const & GetOutputSizePixel() const
sal_Int32 nIndex
#define LANGUAGE_SYSTEM
B2IRange fround(const B2DRange &rRange)
Reference< XComponentContext > getProcessComponentContext()
std::unique_ptr< BaseProcessor2D > createPixelProcessor2DFromOutputDevice(OutputDevice &rTargetOutDev, const drawinglayer::geometry::ViewInformation2D &rViewInformation2D)
long Long
QPRO_FUNC_TYPE nType
sal_uIntPtr sal_uLong
OUString SwResId(TranslateId aId)
Definition: swmodule.cxx:168
#define SW_MOD()
Definition: swmodule.hxx:254
unsigned char sal_uInt8
SvNumFormatType