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 
20 #include <editeng/adjustitem.hxx>
21 #include <editeng/boxitem.hxx>
22 #include <editeng/brushitem.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>
34 #include <svtools/scriptedtext.hxx>
35 #include <svx/framelink.hxx>
38 #include <strings.hrc>
39 
40 #include <autoformatpreview.hxx>
41 
42 #define FRAME_OFFSET 4
43 
45  : maCurrentData(OUString())
46  , mbFitWidth(false)
47  , mbRTL(false)
48  , maStringJan(SwResId(STR_JAN))
49  , maStringFeb(SwResId(STR_FEB))
50  , maStringMar(SwResId(STR_MAR))
51  , maStringNorth(SwResId(STR_NORTH))
52  , maStringMid(SwResId(STR_MID))
53  , maStringSouth(SwResId(STR_SOUTH))
54  , maStringSum(SwResId(STR_SUM))
55 {
56  uno::Reference<uno::XComponentContext> xContext = comphelper::getProcessComponentContext();
57  m_xBreak = i18n::BreakIterator::create(xContext);
58  mxNumFormat.reset(new SvNumberFormatter(xContext, LANGUAGE_SYSTEM));
59 
60  Init();
61 }
62 
64 {
65  Size aSize = GetOutputSizePixel();
66  maPreviousSize = Size(aSize.Width() - 6, aSize.Height() - 30);
67  mnLabelColumnWidth = (maPreviousSize.Width() - 4) / 4 - 12;
70  mnRowHeight = (maPreviousSize.Height() - 4) / 5;
72 }
73 
75 {
76  if (!pWrtShell->IsCursorInTable()) // We haven't created the table yet
78  else
79  mbRTL = pWrtShell->IsTableRightToLeft();
80 }
81 
82 static void lcl_SetFontProperties(vcl::Font& rFont, const SvxFontItem& rFontItem,
83  const SvxWeightItem& rWeightItem,
84  const SvxPostureItem& rPostureItem)
85 {
86  rFont.SetFamily(rFontItem.GetFamily());
87  rFont.SetFamilyName(rFontItem.GetFamilyName());
88  rFont.SetStyleName(rFontItem.GetStyleName());
89  rFont.SetCharSet(rFontItem.GetCharSet());
90  rFont.SetPitch(rFontItem.GetPitch());
91  rFont.SetWeight(rWeightItem.GetValue());
92  rFont.SetItalic(rPostureItem.GetValue());
93 }
94 
95 #define SETONALLFONTS(MethodName, Value) \
96  rFont.MethodName(Value); \
97  rCJKFont.MethodName(Value); \
98  rCTLFont.MethodName(Value);
99 
100 void AutoFormatPreview::MakeFonts(vcl::RenderContext const& rRenderContext, sal_uInt8 nIndex,
101  vcl::Font& rFont, vcl::Font& rCJKFont, vcl::Font& rCTLFont)
102 {
103  const SwBoxAutoFormat& rBoxFormat = maCurrentData.GetBoxFormat(nIndex);
104 
105  rFont = rCJKFont = rCTLFont = rRenderContext.GetFont();
106  Size aFontSize(rFont.GetFontSize().Width(), 10 * rRenderContext.GetDPIScaleFactor());
107 
108  lcl_SetFontProperties(rFont, rBoxFormat.GetFont(), rBoxFormat.GetWeight(),
109  rBoxFormat.GetPosture());
110  lcl_SetFontProperties(rCJKFont, rBoxFormat.GetCJKFont(), rBoxFormat.GetCJKWeight(),
111  rBoxFormat.GetCJKPosture());
112  lcl_SetFontProperties(rCTLFont, rBoxFormat.GetCTLFont(), rBoxFormat.GetCTLWeight(),
113  rBoxFormat.GetCTLPosture());
114 
115  SETONALLFONTS(SetUnderline, rBoxFormat.GetUnderline().GetValue());
116  SETONALLFONTS(SetOverline, rBoxFormat.GetOverline().GetValue());
117  SETONALLFONTS(SetStrikeout, rBoxFormat.GetCrossedOut().GetValue());
118  SETONALLFONTS(SetOutline, rBoxFormat.GetContour().GetValue());
119  SETONALLFONTS(SetShadow, rBoxFormat.GetShadowed().GetValue());
120  SETONALLFONTS(SetColor, rBoxFormat.GetColor().GetValue());
121  SETONALLFONTS(SetFontSize, aFontSize);
122  SETONALLFONTS(SetTransparent, true);
123 }
124 
125 sal_uInt8 AutoFormatPreview::GetFormatIndex(size_t nCol, size_t nRow) const
126 {
127  static const sal_uInt8 pnFormatMap[]
128  = { 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 };
129  return pnFormatMap[maArray.GetCellIndex(nCol, nRow, mbRTL)];
130 }
131 
132 void AutoFormatPreview::DrawString(vcl::RenderContext& rRenderContext, size_t nCol, size_t nRow)
133 {
134  // Output of the cell text:
135  sal_uLong nNum;
136  double nVal;
137  OUString cellString;
138  sal_uInt8 nIndex = static_cast<sal_uInt8>(maArray.GetCellIndex(nCol, nRow, mbRTL));
139 
140  switch (nIndex)
141  {
142  case 1:
143  cellString = maStringJan;
144  break;
145  case 2:
146  cellString = maStringFeb;
147  break;
148  case 3:
149  cellString = maStringMar;
150  break;
151  case 5:
152  cellString = maStringNorth;
153  break;
154  case 10:
155  cellString = maStringMid;
156  break;
157  case 15:
158  cellString = maStringSouth;
159  break;
160  case 4:
161  case 20:
162  cellString = maStringSum;
163  break;
164  case 6:
165  case 8:
166  case 16:
167  case 18:
168  nVal = nIndex;
169  nNum = 5;
170  goto MAKENUMSTR;
171  case 17:
172  case 7:
173  nVal = nIndex;
174  nNum = 6;
175  goto MAKENUMSTR;
176  case 11:
177  case 12:
178  case 13:
179  nVal = nIndex;
180  nNum = 12 == nIndex ? 10 : 9;
181  goto MAKENUMSTR;
182  case 9:
183  nVal = 21;
184  nNum = 7;
185  goto MAKENUMSTR;
186  case 14:
187  nVal = 36;
188  nNum = 11;
189  goto MAKENUMSTR;
190  case 19:
191  nVal = 51;
192  nNum = 7;
193  goto MAKENUMSTR;
194  case 21:
195  nVal = 33;
196  nNum = 13;
197  goto MAKENUMSTR;
198  case 22:
199  nVal = 36;
200  nNum = 14;
201  goto MAKENUMSTR;
202  case 23:
203  nVal = 39;
204  nNum = 13;
205  goto MAKENUMSTR;
206  case 24:
207  nVal = 108;
208  nNum = 15;
209  goto MAKENUMSTR;
210 
211  MAKENUMSTR:
213  {
214  OUString sFormat;
215  LanguageType eLng, eSys;
216  maCurrentData.GetBoxFormat(sal_uInt8(nNum)).GetValueFormat(sFormat, eLng, eSys);
217 
219  bool bNew;
220  sal_Int32 nCheckPos;
221  sal_uInt32 nKey = mxNumFormat->GetIndexPuttingAndConverting(sFormat, eLng, eSys,
222  nType, bNew, nCheckPos);
223  Color* pDummy;
224  mxNumFormat->GetOutputString(nVal, nKey, cellString, &pDummy);
225  }
226  else
227  cellString = OUString::number(sal_Int32(nVal));
228  break;
229  }
230 
231  if (cellString.isEmpty())
232  return;
233 
234  SvtScriptedTextHelper aScriptedText(rRenderContext);
235  Size aStrSize;
236  sal_uInt8 nFormatIndex = GetFormatIndex(nCol, nRow);
237  const basegfx::B2DRange aCellRange(maArray.GetCellRange(nCol, nRow, true));
238  const tools::Rectangle cellRect(
239  basegfx::fround(aCellRange.getMinX()), basegfx::fround(aCellRange.getMinY()),
240  basegfx::fround(aCellRange.getMaxX()), basegfx::fround(aCellRange.getMaxY()));
241  Point aPos = cellRect.TopLeft();
242  long nRightX = 0;
243 
244  Size theMaxStrSize(cellRect.GetWidth() - FRAME_OFFSET, cellRect.GetHeight() - FRAME_OFFSET);
245  if (maCurrentData.IsFont())
246  {
247  vcl::Font aFont, aCJKFont, aCTLFont;
248  MakeFonts(rRenderContext, nFormatIndex, aFont, aCJKFont, aCTLFont);
249  aScriptedText.SetFonts(&aFont, &aCJKFont, &aCTLFont);
250  }
251  else
252  aScriptedText.SetDefaultFont();
253 
254  aScriptedText.SetText(cellString, m_xBreak);
255  aStrSize = aScriptedText.GetTextSize();
256 
257  if (maCurrentData.IsFont() && theMaxStrSize.Height() < aStrSize.Height())
258  {
259  // If the string in this font does not
260  // fit into the cell, the standard font
261  // is taken again:
262  aScriptedText.SetDefaultFont();
263  aStrSize = aScriptedText.GetTextSize();
264  }
265 
266  while (theMaxStrSize.Width() <= aStrSize.Width() && cellString.getLength() > 1)
267  {
268  cellString = cellString.copy(0, cellString.getLength() - 1);
269  aScriptedText.SetText(cellString, m_xBreak);
270  aStrSize = aScriptedText.GetTextSize();
271  }
272 
273  nRightX = cellRect.GetWidth() - aStrSize.Width() - FRAME_OFFSET;
274 
275  // vertical (always centering):
276  aPos.AdjustY((mnRowHeight - aStrSize.Height()) / 2);
277 
278  // horizontal
279  if (mbRTL)
280  aPos.AdjustX(nRightX);
281  else if (maCurrentData.IsJustify())
282  {
283  const SvxAdjustItem& rAdj = maCurrentData.GetBoxFormat(nFormatIndex).GetAdjust();
284  switch (rAdj.GetAdjust())
285  {
286  case SvxAdjust::Left:
287  aPos.AdjustX(FRAME_OFFSET);
288  break;
289  case SvxAdjust::Right:
290  aPos.AdjustX(nRightX);
291  break;
292  default:
293  aPos.AdjustX((cellRect.GetWidth() - aStrSize.Width()) / 2);
294  break;
295  }
296  }
297  else
298  {
299  // Standard align:
300  if (nCol == 0 || nIndex == 4)
301  {
302  // Text-Label left or sum left aligned
303  aPos.AdjustX(FRAME_OFFSET);
304  }
305  else
306  {
307  // numbers/dates right aligned
308  aPos.AdjustX(nRightX);
309  }
310  }
311 
312  aScriptedText.DrawText(aPos);
313 }
314 
316 {
317  for (size_t nRow = 0; nRow < 5; ++nRow)
318  {
319  for (size_t nCol = 0; nCol < 5; ++nCol)
320  {
321  SvxBrushItem aBrushItem(
323 
324  rRenderContext.Push(PushFlags::LINECOLOR | PushFlags::FILLCOLOR);
325  rRenderContext.SetLineColor();
326  rRenderContext.SetFillColor(aBrushItem.GetColor());
327  const basegfx::B2DRange aCellRange(maArray.GetCellRange(nCol, nRow, true));
328  rRenderContext.DrawRect(tools::Rectangle(
329  basegfx::fround(aCellRange.getMinX()), basegfx::fround(aCellRange.getMinY()),
330  basegfx::fround(aCellRange.getMaxX()), basegfx::fround(aCellRange.getMaxY())));
331  rRenderContext.Pop();
332  }
333  }
334 }
335 
337 {
338  // 1) background
340  DrawBackground(rRenderContext);
341 
342  // 2) values
343  for (size_t nRow = 0; nRow < 5; ++nRow)
344  for (size_t nCol = 0; nCol < 5; ++nCol)
345  DrawString(rRenderContext, nCol, nRow);
346 
347  // 3) border
348  if (maCurrentData.IsFrame())
349  {
350  const drawinglayer::geometry::ViewInformation2D aNewViewInformation2D;
351  std::unique_ptr<drawinglayer::processor2d::BaseProcessor2D> pProcessor2D(
353  rRenderContext, aNewViewInformation2D));
354 
355  if (pProcessor2D)
356  {
357  pProcessor2D->process(maArray.CreateB2DPrimitiveArray());
358  pProcessor2D.reset();
359  }
360  }
361 }
362 
364 {
365  maArray.Initialize(5, 5);
366  mnLabelColumnWidth = 0;
367  mnDataColumnWidth1 = 0;
368  mnDataColumnWidth2 = 0;
369  mnRowHeight = 0;
370  CalcCellArray(false);
371  CalcLineMap();
372 }
373 
374 void AutoFormatPreview::CalcCellArray(bool _bFitWidth)
375 {
379 
381 
384 }
385 
387  const ::editeng::SvxBorderLine* pBorder)
388 {
389  rStyle.Set(pBorder, 0.05, 5);
390 }
391 
393 {
394  for (size_t nRow = 0; nRow < 5; ++nRow)
395  {
396  for (size_t nCol = 0; nCol < 5; ++nCol)
397  {
398  svx::frame::Style aStyle;
399 
400  const SvxBoxItem& rItem
402  lclSetStyleFromBorder(aStyle, rItem.GetLeft());
403  maArray.SetCellStyleLeft(nCol, nRow, aStyle);
404  lclSetStyleFromBorder(aStyle, rItem.GetRight());
405  maArray.SetCellStyleRight(nCol, nRow, aStyle);
406  lclSetStyleFromBorder(aStyle, rItem.GetTop());
407  maArray.SetCellStyleTop(nCol, nRow, aStyle);
408  lclSetStyleFromBorder(aStyle, rItem.GetBottom());
409  maArray.SetCellStyleBottom(nCol, nRow, aStyle);
410 
411  // FIXME - uncomment to draw diagonal borders
412  // lclSetStyleFromBorder( aStyle, GetDiagItem( nCol, nRow, true ).GetLine() );
413  // maArray.SetCellStyleTLBR( nCol, nRow, aStyle );
414  // lclSetStyleFromBorder( aStyle, GetDiagItem( nCol, nRow, false ).GetLine() );
415  // maArray.SetCellStyleBLTR( nCol, nRow, aStyle );
416  }
417  }
418 }
419 
421 {
422  maCurrentData = rNewData;
423  mbFitWidth = maCurrentData.IsJustify(); // true; //???
425  CalcLineMap();
426  Invalidate();
427 }
428 
430 {
431  rRenderContext.Push(PushFlags::ALL);
432 
433  DrawModeFlags nOldDrawMode = rRenderContext.GetDrawMode();
434  if (rRenderContext.GetSettings().GetStyleSettings().GetHighContrastMode())
435  rRenderContext.SetDrawMode(DrawModeFlags::SettingsLine | DrawModeFlags::SettingsFill
436  | DrawModeFlags::SettingsText | DrawModeFlags::SettingsGradient);
437 
438  Size theWndSize = rRenderContext.GetOutputSizePixel();
439 
440  vcl::Font aFont(rRenderContext.GetFont());
441  aFont.SetTransparent(true);
442 
443  rRenderContext.SetFont(aFont);
444  rRenderContext.SetLineColor();
445  const Color& rWinColor = rRenderContext.GetSettings().GetStyleSettings().GetWindowColor();
446  rRenderContext.SetBackground(Wallpaper(rWinColor));
447  rRenderContext.SetFillColor(rWinColor);
448 
449  // Draw the Frame
450  Color oldColor = rRenderContext.GetLineColor();
451  rRenderContext.SetLineColor();
452  rRenderContext.DrawRect(tools::Rectangle(Point(0, 0), theWndSize));
453  rRenderContext.SetLineColor(oldColor);
454 
455  // Center the preview
456  maArray.SetXOffset(2 + (theWndSize.Width() - maPreviousSize.Width()) / 2);
457  maArray.SetYOffset(2 + (theWndSize.Height() - maPreviousSize.Height()) / 2);
458  // Draw cells on virtual device
459  PaintCells(rRenderContext);
460 
461  rRenderContext.SetDrawMode(nOldDrawMode);
462  rRenderContext.Pop();
463 }
464 
465 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void SetFamily(FontFamily)
long Width() const
void SetAllColWidths(long nWidth)
bool IsValueFormat() const
Definition: tblafmt.hxx:222
void SetXOffset(long nXOffset)
SvxAdjust GetAdjust() const
DrawModeFlags
long AdjustX(long nHorzMove)
long Height() const
const SvxShadowedItem & GetShadowed() const
sal_uIntPtr sal_uLong
const StyleSettings & GetStyleSettings() const
const SvxAdjustItem & GetAdjust() const
basegfx::B2DRange GetCellRange(size_t nCol, size_t nRow, bool bExpandMerged) const
const OUString maStringJan
const SvxWeightItem & GetCTLWeight() const
void SetWeight(FontWeight)
const SvxFontItem & GetCTLFont() const
void SetCharSet(rtl_TextEncoding)
void SetColWidth(size_t nCol, long nWidth)
const SvxBrushItem & GetBackground() const
const editeng::SvxBorderLine * GetRight() const
size_t GetCellIndex(size_t nCol, size_t nRow, bool bRTL) const
void DrawString(vcl::RenderContext &rRenderContext, size_t nCol, size_t nRow)
void SetCellStyleTop(size_t nCol, size_t nRow, const Style &rStyle)
const SvxPostureItem & GetCTLPosture() const
FontPitch GetPitch() const
void SetCellStyleBottom(size_t nCol, size_t nRow, const Style &rStyle)
#define FRAME_OFFSET
void NotifyChange(const SwTableAutoFormat &rNewData)
const SvxWeightItem & GetCJKWeight() const
FontFamily GetFamily() const
long GetWidth() const
SwTableAutoFormat maCurrentData
Size const & GetOutputSizePixel() const
void SetDrawMode(DrawModeFlags nDrawMode)
const OUString maStringMar
Used by the UI to modify the document model.
Definition: wrtsh.hxx:88
bool IsFont() const
Definition: tblafmt.hxx:218
const Size & GetTextSize() const
const SvxFontItem & GetFont() const
void SetYOffset(long nYOffset)
void SetBackground()
void DetectRTL(SwWrtShell const *pWrtShell)
FUNC_TYPE const nType
bool IsJustify() const
Definition: tblafmt.hxx:219
bool IsTableRightToLeft() const
Definition: fetab.cxx:2308
const vcl::Font & GetFont() const
rtl_TextEncoding GetCharSet() const
const SvxUnderlineItem & GetUnderline() const
bool GetHighContrastMode() const
const SvxWeightItem & GetWeight() const
bool IsBackground() const
Definition: tblafmt.hxx:221
const OUString maStringFeb
const OUString maStringMid
long GetHeight() const
B2IRange fround(const B2DRange &rRange)
void DrawRect(const tools::Rectangle &rRect)
void SetPitch(FontPitch ePitch)
const OUString & GetStyleName() const
const OUString maStringNorth
sal_uInt8 GetFormatIndex(size_t nCol, size_t nRow) const
void SetCellStyleLeft(size_t nCol, size_t nRow, const Style &rStyle)
const SvxContourItem & GetContour() const
std::unique_ptr< BaseProcessor2D > createPixelProcessor2DFromOutputDevice(OutputDevice &rTargetOutDev, const drawinglayer::geometry::ViewInformation2D &rViewInformation2D)
const editeng::SvxBorderLine * GetTop() const
void SetLineColor()
const SwTableNode * IsCursorInTable() const
Definition: crsrsh.hxx:888
void PaintCells(vcl::RenderContext &rRenderContext)
drawinglayer::primitive2d::Primitive2DContainer CreateB2DPrimitiveArray() const
void SetFamilyName(const OUString &rFamilyName)
static void lclSetStyleFromBorder(svx::frame::Style &rStyle, const ::editeng::SvxBorderLine *pBorder)
const editeng::SvxBorderLine * GetLeft() const
long AdjustY(long nVertMove)
const SwBoxAutoFormat & GetBoxFormat(sal_uInt8 nPos) const
Definition: tblafmt.cxx:464
void SetFonts(vcl::Font const *_pLatinFont, vcl::Font const *_pAsianFont, vcl::Font const *_pCmplxFont)
#define LANGUAGE_SYSTEM
void SetFillColor()
const Color & GetLineColor() const
static bool GetLayoutRTL()
#define SETONALLFONTS(MethodName, Value)
const Size & GetFontSize() const
void DrawBackground(vcl::RenderContext &rRenderContext)
SvNumFormatType
void Initialize(size_t nWidth, size_t nHeight)
void CalcCellArray(bool bFitWidth)
const AllSettings & GetSettings() const
Size GetOutputSizePixel() const
OUString SwResId(const char *pId)
Definition: swmodule.cxx:191
void SetText(const OUString &_rText, const css::uno::Reference< css::i18n::XBreakIterator > &_xBreakIter)
DrawModeFlags GetDrawMode() const
const SvxPostureItem & GetCJKPosture() const
void GetValueFormat(OUString &rFormat, LanguageType &rLng, LanguageType &rSys) const
Definition: tblafmt.hxx:76
float GetDPIScaleFactor() const
void SetAllRowHeights(long nHeight)
std::unique_ptr< SvNumberFormatter > mxNumFormat
const OUString & GetFamilyName() const
bool mbFitWidth
Implementation to draw the frame borders.
const SvxCrossedOutItem & GetCrossedOut() const
void SetStyleName(const OUString &rStyleName)
virtual void Paint(vcl::RenderContext &rRenderContext, const tools::Rectangle &rRect) override
const SvxOverlineItem & GetOverline() const
unsigned char sal_uInt8
void SetFont(const vcl::Font &rNewFont)
const OUString maStringSum
void SetTransparent(bool bTransparent)
const OUString maStringSouth
void DrawText(const Point &_rPos)
const SvxFontItem & GetCJKFont() const
Reference< XComponentContext > getProcessComponentContext()
void MakeFonts(vcl::RenderContext const &rRenderContext, sal_uInt8 nIndex, vcl::Font &rFont, vcl::Font &rCJKFont, vcl::Font &rCTLFont)
const Color & GetWindowColor() const
void SetCellStyleRight(size_t nCol, size_t nRow, const Style &rStyle)
void SetItalic(FontItalic)
void Set(double nP, double nD, double nS)
uno::Reference< i18n::XBreakIterator > m_xBreak
const SvxPostureItem & GetPosture() const
const SvxColorItem & GetColor() const
void Push(PushFlags nFlags=PushFlags::ALL)
void setWidth(long nWidth)
const editeng::SvxBorderLine * GetBottom() const
svx::frame::Array maArray
bool IsFrame() const
Definition: tblafmt.hxx:220
const SvxBoxItem & GetBox() const
const Color & GetValue() const
static void lcl_SetFontProperties(vcl::Font &rFont, const SvxFontItem &rFontItem, const SvxWeightItem &rWeightItem, const SvxPostureItem &rPostureItem)
virtual void Resize() override
void setHeight(long nHeight)