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