Version 5.2.6.1, tag libreoffice-5.2.6.1
[LibreOffice.git] / sc / source / ui / miscdlgs / autofmt.cxx
blobb5b49315d078690f45bfd366f9a125bce9ef36dc
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 "scitems.hxx"
21 #include <svx/algitem.hxx>
22 #include <editeng/boxitem.hxx>
23 #include <editeng/brushitem.hxx>
24 #include <editeng/contouritem.hxx>
25 #include <editeng/colritem.hxx>
26 #include <editeng/crossedoutitem.hxx>
27 #include <editeng/fontitem.hxx>
28 #include <editeng/postitem.hxx>
29 #include <editeng/shdditem.hxx>
30 #include <editeng/udlnitem.hxx>
31 #include <editeng/wghtitem.hxx>
32 #include <vcl/svapp.hxx>
33 #include <svl/zforlist.hxx>
34 #include <vcl/msgbox.hxx>
35 #include <vcl/settings.hxx>
36 #include <vcl/builderfactory.hxx>
37 #include <sfx2/viewfrm.hxx>
38 #include <comphelper/processfactory.hxx>
40 #include "sc.hrc"
41 #include "scmod.hxx"
42 #include "attrib.hxx"
43 #include "zforauto.hxx"
44 #include "global.hxx"
45 #include "globstr.hrc"
46 #include "autoform.hxx"
47 #include "miscdlgs.hrc"
48 #include "autofmt.hxx"
49 #include "scresid.hxx"
50 #include "document.hxx"
51 #include "docsh.hxx"
52 #include "tabvwsh.hxx"
54 #define FRAME_OFFSET 4
56 // ScAutoFmtPreview
58 ScAutoFmtPreview::ScAutoFmtPreview(vcl::Window* pParent)
59 : Window(pParent)
60 , pCurData(nullptr)
61 , aVD(*this)
62 , bFitWidth(false)
63 , mbRTL(false)
64 , aStrJan(ScResId(STR_JAN))
65 , aStrFeb(ScResId(STR_FEB))
66 , aStrMar(ScResId(STR_MAR))
67 , aStrNorth(ScResId(STR_NORTH))
68 , aStrMid(ScResId(STR_MID))
69 , aStrSouth(ScResId(STR_SOUTH))
70 , aStrSum(ScResId(STR_SUM))
71 , pNumFmt(new SvNumberFormatter(::comphelper::getProcessComponentContext(), ScGlobal::eLnge))
73 Init();
76 VCL_BUILDER_FACTORY(ScAutoFmtPreview)
78 void ScAutoFmtPreview::Resize()
80 aPrvSize = Size(GetSizePixel().Width() - 6, GetSizePixel().Height() - 30);
81 mnLabelColWidth = (aPrvSize.Width() - 4) / 4 - 12;
82 mnDataColWidth1 = (aPrvSize.Width() - 4 - 2 * mnLabelColWidth) / 3;
83 mnDataColWidth2 = (aPrvSize.Width() - 4 - 2 * mnLabelColWidth) / 4;
84 mnRowHeight = (aPrvSize.Height() - 4) / 5;
85 NotifyChange(pCurData);
88 ScAutoFmtPreview::~ScAutoFmtPreview()
90 disposeOnce();
93 void ScAutoFmtPreview::dispose()
95 delete pNumFmt;
96 vcl::Window::dispose();
99 static void lcl_SetFontProperties(
100 vcl::Font& rFont,
101 const SvxFontItem& rFontItem,
102 const SvxWeightItem& rWeightItem,
103 const SvxPostureItem& rPostureItem )
105 rFont.SetFamily ( rFontItem.GetFamily() );
106 rFont.SetFamilyName ( rFontItem.GetFamilyName() );
107 rFont.SetStyleName ( rFontItem.GetStyleName() );
108 rFont.SetCharSet ( rFontItem.GetCharSet() );
109 rFont.SetPitch ( rFontItem.GetPitch() );
110 rFont.SetWeight ( (FontWeight)rWeightItem.GetValue() );
111 rFont.SetItalic ( (FontItalic)rPostureItem.GetValue() );
114 void ScAutoFmtPreview::MakeFonts( sal_uInt16 nIndex, vcl::Font& rFont, vcl::Font& rCJKFont, vcl::Font& rCTLFont )
116 if ( pCurData )
118 rFont = rCJKFont = rCTLFont = GetFont();
119 Size aFontSize( rFont.GetFontSize().Width(), 10 * GetDPIScaleFactor() );
121 const SvxFontItem* pFontItem = static_cast<const SvxFontItem*> (pCurData->GetItem( nIndex, ATTR_FONT ));
122 const SvxWeightItem* pWeightItem = static_cast<const SvxWeightItem*> (pCurData->GetItem( nIndex, ATTR_FONT_WEIGHT ));
123 const SvxPostureItem* pPostureItem = static_cast<const SvxPostureItem*> (pCurData->GetItem( nIndex, ATTR_FONT_POSTURE ));
124 const SvxFontItem* pCJKFontItem = static_cast<const SvxFontItem*> (pCurData->GetItem( nIndex, ATTR_CJK_FONT ));
125 const SvxWeightItem* pCJKWeightItem = static_cast<const SvxWeightItem*> (pCurData->GetItem( nIndex, ATTR_CJK_FONT_WEIGHT ));
126 const SvxPostureItem* pCJKPostureItem = static_cast<const SvxPostureItem*> (pCurData->GetItem( nIndex, ATTR_CJK_FONT_POSTURE ));
127 const SvxFontItem* pCTLFontItem = static_cast<const SvxFontItem*> (pCurData->GetItem( nIndex, ATTR_CTL_FONT ));
128 const SvxWeightItem* pCTLWeightItem = static_cast<const SvxWeightItem*> (pCurData->GetItem( nIndex, ATTR_CTL_FONT_WEIGHT ));
129 const SvxPostureItem* pCTLPostureItem = static_cast<const SvxPostureItem*> (pCurData->GetItem( nIndex, ATTR_CTL_FONT_POSTURE ));
130 const SvxUnderlineItem* pUnderlineItem = static_cast<const SvxUnderlineItem*> (pCurData->GetItem( nIndex, ATTR_FONT_UNDERLINE ));
131 const SvxOverlineItem* pOverlineItem = static_cast<const SvxOverlineItem*> (pCurData->GetItem( nIndex, ATTR_FONT_OVERLINE ));
132 const SvxCrossedOutItem* pCrossedOutItem = static_cast<const SvxCrossedOutItem*>(pCurData->GetItem( nIndex, ATTR_FONT_CROSSEDOUT ));
133 const SvxContourItem* pContourItem = static_cast<const SvxContourItem*> (pCurData->GetItem( nIndex, ATTR_FONT_CONTOUR ));
134 const SvxShadowedItem* pShadowedItem = static_cast<const SvxShadowedItem*> (pCurData->GetItem( nIndex, ATTR_FONT_SHADOWED ));
135 const SvxColorItem* pColorItem = static_cast<const SvxColorItem*> (pCurData->GetItem( nIndex, ATTR_FONT_COLOR ));
137 lcl_SetFontProperties( rFont, *pFontItem, *pWeightItem, *pPostureItem );
138 lcl_SetFontProperties( rCJKFont, *pCJKFontItem, *pCJKWeightItem, *pCJKPostureItem );
139 lcl_SetFontProperties( rCTLFont, *pCTLFontItem, *pCTLWeightItem, *pCTLPostureItem );
141 Color aColor( pColorItem->GetValue() );
142 if( aColor.GetColor() == COL_TRANSPARENT )
143 aColor = GetSettings().GetStyleSettings().GetWindowTextColor();
145 #define SETONALLFONTS( MethodName, Value ) \
146 rFont.MethodName( Value ); rCJKFont.MethodName( Value ); rCTLFont.MethodName( Value );
148 SETONALLFONTS( SetUnderline, (FontLineStyle)pUnderlineItem->GetValue() )
149 SETONALLFONTS( SetOverline, (FontLineStyle)pOverlineItem->GetValue() )
150 SETONALLFONTS( SetStrikeout, (FontStrikeout)pCrossedOutItem->GetValue() )
151 SETONALLFONTS( SetOutline, pContourItem->GetValue() )
152 SETONALLFONTS( SetShadow, pShadowedItem->GetValue() )
153 SETONALLFONTS( SetColor, aColor )
154 SETONALLFONTS( SetFontSize, aFontSize )
155 SETONALLFONTS( SetTransparent, true )
157 #undef SETONALLFONTS
161 sal_uInt16 ScAutoFmtPreview::GetFormatIndex( size_t nCol, size_t nRow ) const
163 static const sal_uInt16 pnFmtMap[] =
165 0, 1, 2, 1, 3,
166 4, 5, 6, 5, 7,
167 8, 9, 10, 9, 11,
168 4, 5, 6, 5, 7,
169 12, 13, 14, 13, 15
171 return pnFmtMap[ maArray.GetCellIndex( nCol, nRow, mbRTL ) ];
174 const SvxBoxItem& ScAutoFmtPreview::GetBoxItem( size_t nCol, size_t nRow ) const
176 OSL_ENSURE( pCurData, "ScAutoFmtPreview::GetBoxItem - no format data found" );
177 return *static_cast< const SvxBoxItem* >( pCurData->GetItem( GetFormatIndex( nCol, nRow ), ATTR_BORDER ) );
180 const SvxLineItem& ScAutoFmtPreview::GetDiagItem( size_t nCol, size_t nRow, bool bTLBR ) const
182 OSL_ENSURE( pCurData, "ScAutoFmtPreview::GetDiagItem - no format data found" );
183 return *static_cast< const SvxLineItem* >( pCurData->GetItem( GetFormatIndex( nCol, nRow ), bTLBR ? ATTR_BORDER_TLBR : ATTR_BORDER_BLTR ) );
186 void ScAutoFmtPreview::DrawString(vcl::RenderContext& rRenderContext, size_t nCol, size_t nRow)
188 if (!pCurData)
190 return;
193 // Emit the cell text
195 OUString cellString;
196 bool bNumFormat = pCurData->GetIncludeValueFormat();
197 sal_uInt32 nNum;
198 double nVal;
199 Color* pDummy = nullptr;
200 sal_uInt16 nIndex = static_cast<sal_uInt16>(maArray.GetCellIndex(nCol, nRow, mbRTL));
202 switch (nIndex)
204 case 1: cellString = aStrJan; break;
205 case 2: cellString = aStrFeb; break;
206 case 3: cellString = aStrMar; break;
207 case 5: cellString = aStrNorth; break;
208 case 10: cellString = aStrMid; break;
209 case 15: cellString = aStrSouth; break;
210 case 4:
211 case 20: cellString = aStrSum; break;
213 case 6:
214 case 8:
215 case 16:
216 case 18: nVal = nIndex;
217 nNum = 5;
218 goto mknum;
219 case 17:
220 case 7: nVal = nIndex;
221 nNum = 6;
222 goto mknum;
223 case 11:
224 case 12:
225 case 13: nVal = nIndex;
226 nNum = 12 == nIndex ? 10 : 9;
227 goto mknum;
229 case 9: nVal = 21; nNum = 7; goto mknum;
230 case 14: nVal = 36; nNum = 11; goto mknum;
231 case 19: nVal = 51; nNum = 7; goto mknum;
232 case 21: nVal = 33; nNum = 13; goto mknum;
233 case 22: nVal = 36; nNum = 14; goto mknum;
234 case 23: nVal = 39; nNum = 13; goto mknum;
235 case 24: nVal = 108; nNum = 15;
236 mknum:
237 if (bNumFormat)
239 ScNumFormatAbbrev& rNumFormat = (ScNumFormatAbbrev&) pCurData->GetNumFormat(sal_uInt16(nNum));
240 nNum = rNumFormat.GetFormatIndex(*pNumFmt);
242 else
243 nNum = 0;
244 pNumFmt->GetOutputString(nVal, nNum, cellString, &pDummy);
245 break;
248 if (!cellString.isEmpty())
251 Size aStrSize;
252 sal_uInt16 nFmtIndex = GetFormatIndex( nCol, nRow );
253 Rectangle cellRect = maArray.GetCellRect( nCol, nRow );
254 Point aPos = cellRect.TopLeft();
255 sal_uInt16 nRightX = 0;
256 bool bJustify = pCurData->GetIncludeJustify();
257 SvxHorJustifyItem aHorJustifyItem( SVX_HOR_JUSTIFY_STANDARD, ATTR_HOR_JUSTIFY );
258 SvxCellHorJustify eJustification;
260 SvtScriptedTextHelper aScriptedText(rRenderContext);
262 // Justification:
264 eJustification = mbRTL ? SVX_HOR_JUSTIFY_RIGHT : bJustify ?
265 (SvxCellHorJustify) (static_cast<const SvxHorJustifyItem*>(pCurData->GetItem(nFmtIndex, ATTR_HOR_JUSTIFY))->GetValue()) :
266 SVX_HOR_JUSTIFY_STANDARD;
268 if (pCurData->GetIncludeFont())
270 vcl::Font aFont, aCJKFont, aCTLFont;
271 Size theMaxStrSize;
273 MakeFonts( nFmtIndex, aFont, aCJKFont, aCTLFont );
275 theMaxStrSize = cellRect.GetSize();
276 theMaxStrSize.Width() -= FRAME_OFFSET;
277 theMaxStrSize.Height() -= FRAME_OFFSET;
279 aScriptedText.SetFonts( &aFont, &aCJKFont, &aCTLFont );
280 aScriptedText.SetText(cellString, xBreakIter);
281 aStrSize = aScriptedText.GetTextSize();
283 if (theMaxStrSize.Height() < aStrSize.Height())
285 // if the string does not fit in the row using this font,
286 // the default font is used
287 aScriptedText.SetDefaultFont();
288 aStrSize = aScriptedText.GetTextSize();
290 while((theMaxStrSize.Width() <= aStrSize.Width()) && (cellString.getLength() > 1))
292 if( eJustification == SVX_HOR_JUSTIFY_RIGHT )
293 cellString = cellString.copy(1);
294 else
295 cellString = cellString.copy(0, cellString.getLength() - 1 );
297 aScriptedText.SetText( cellString, xBreakIter );
298 aStrSize = aScriptedText.GetTextSize();
301 else
303 aScriptedText.SetDefaultFont();
304 aScriptedText.SetText( cellString, xBreakIter );
305 aStrSize = aScriptedText.GetTextSize();
308 nRightX = sal_uInt16(cellRect.GetWidth() - aStrSize.Width() - FRAME_OFFSET);
310 // vertical (always center):
312 aPos.Y() += (mnRowHeight - (sal_uInt16)aStrSize.Height()) / 2;
314 // horizontal
316 if (eJustification != SVX_HOR_JUSTIFY_STANDARD)
318 sal_uInt16 nHorPos = sal_uInt16((cellRect.GetWidth()-aStrSize.Width()) / 2);
320 switch (eJustification)
322 case SVX_HOR_JUSTIFY_LEFT:
323 aPos.X() += FRAME_OFFSET;
324 break;
325 case SVX_HOR_JUSTIFY_RIGHT:
326 aPos.X() += nRightX;
327 break;
328 case SVX_HOR_JUSTIFY_BLOCK:
329 case SVX_HOR_JUSTIFY_REPEAT:
330 case SVX_HOR_JUSTIFY_CENTER:
331 aPos.X() += nHorPos;
332 break;
333 // coverity[dead_error_line] - following conditions exist to avoid compiler warning
334 case SVX_HOR_JUSTIFY_STANDARD:
335 default:
336 // Standard is not handled here
337 break;
340 else
343 // Standard justification
345 if (nCol == 0 || nRow == 0)
347 // Text label to the left or sum left adjusted
348 aPos.X() += FRAME_OFFSET;
350 else
352 // Numbers/Dates right adjusted
353 aPos.X() += nRightX;
356 aScriptedText.DrawText(aPos);
360 #undef FRAME_OFFSET
362 void ScAutoFmtPreview::DrawStrings(vcl::RenderContext& rRenderContext)
364 for(size_t nRow = 0; nRow < 5; ++nRow)
365 for(size_t nCol = 0; nCol < 5; ++nCol)
366 DrawString(rRenderContext, nCol, nRow);
369 void ScAutoFmtPreview::DrawBackground(vcl::RenderContext& rRenderContext)
371 if (pCurData)
373 for(size_t nRow = 0; nRow < 5; ++nRow)
375 for(size_t nCol = 0; nCol < 5; ++nCol)
377 const SvxBrushItem* pItem = static_cast< const SvxBrushItem* >(
378 pCurData->GetItem( GetFormatIndex( nCol, nRow ), ATTR_BACKGROUND ) );
380 rRenderContext.Push( PushFlags::LINECOLOR | PushFlags::FILLCOLOR );
381 rRenderContext.SetLineColor();
382 rRenderContext.SetFillColor( pItem->GetColor() );
383 rRenderContext.DrawRect( maArray.GetCellRect( nCol, nRow ) );
384 rRenderContext.Pop();
390 void ScAutoFmtPreview::PaintCells(vcl::RenderContext& rRenderContext)
392 if (pCurData)
394 // 1) background
395 if (pCurData->GetIncludeBackground())
396 DrawBackground(rRenderContext);
398 // 2) values
399 DrawStrings(rRenderContext);
401 // 3) border
402 if (pCurData->GetIncludeFrame())
403 maArray.DrawArray(rRenderContext);
407 void ScAutoFmtPreview::Init()
409 SetBorderStyle( WindowBorderStyle::MONO );
410 maArray.Initialize( 5, 5 );
411 maArray.SetUseDiagDoubleClipping( false );
412 CalcCellArray( false );
413 CalcLineMap();
416 void ScAutoFmtPreview::DetectRTL(ScViewData *pViewData)
418 SCTAB nCurrentTab = pViewData->GetTabNo();
419 ScDocument* pDoc = pViewData->GetDocument();
420 mbRTL = pDoc->IsLayoutRTL(nCurrentTab);
421 xBreakIter = pDoc->GetBreakIterator();
424 void ScAutoFmtPreview::CalcCellArray( bool bFitWidthP )
426 maArray.SetXOffset( 2 );
427 maArray.SetAllColWidths( bFitWidthP ? mnDataColWidth2 : mnDataColWidth1 );
428 maArray.SetColWidth( 0, mnLabelColWidth );
429 maArray.SetColWidth( 4, mnLabelColWidth );
431 maArray.SetYOffset( 2 );
432 maArray.SetAllRowHeights( mnRowHeight );
434 aPrvSize.Width() = maArray.GetWidth() + 4;
435 aPrvSize.Height() = maArray.GetHeight() + 4;
438 inline void lclSetStyleFromBorder( svx::frame::Style& rStyle, const ::editeng::SvxBorderLine* pBorder )
440 rStyle.Set( pBorder, 1.0 / TWIPS_PER_POINT, 5 );
443 void ScAutoFmtPreview::CalcLineMap()
445 if ( pCurData )
447 for( size_t nRow = 0; nRow < 5; ++nRow )
449 for( size_t nCol = 0; nCol < 5; ++nCol )
451 svx::frame::Style aStyle;
453 const SvxBoxItem& rItem = GetBoxItem( nCol, nRow );
454 lclSetStyleFromBorder( aStyle, rItem.GetLeft() );
455 maArray.SetCellStyleLeft( nCol, nRow, aStyle );
456 lclSetStyleFromBorder( aStyle, rItem.GetRight() );
457 maArray.SetCellStyleRight( nCol, nRow, aStyle );
458 lclSetStyleFromBorder( aStyle, rItem.GetTop() );
459 maArray.SetCellStyleTop( nCol, nRow, aStyle );
460 lclSetStyleFromBorder( aStyle, rItem.GetBottom() );
461 maArray.SetCellStyleBottom( nCol, nRow, aStyle );
463 lclSetStyleFromBorder( aStyle, GetDiagItem( nCol, nRow, true ).GetLine() );
464 maArray.SetCellStyleTLBR( nCol, nRow, aStyle );
465 lclSetStyleFromBorder( aStyle, GetDiagItem( nCol, nRow, false ).GetLine() );
466 maArray.SetCellStyleBLTR( nCol, nRow, aStyle );
472 void ScAutoFmtPreview::NotifyChange( ScAutoFormatData* pNewData )
474 if (pNewData)
476 pCurData = pNewData;
477 bFitWidth = pNewData->GetIncludeWidthHeight();
480 CalcCellArray( bFitWidth );
481 CalcLineMap();
483 Invalidate(Rectangle(Point(0,0), GetSizePixel()));
486 void ScAutoFmtPreview::DoPaint(vcl::RenderContext& rRenderContext, const Rectangle& /*rRect*/)
488 DrawModeFlags nOldDrawMode = aVD->GetDrawMode();
490 Size aWndSize(GetSizePixel());
491 vcl::Font aFont(aVD->GetFont());
492 Color aBackCol(rRenderContext.GetSettings().GetStyleSettings().GetWindowColor());
493 Point aTmpPoint;
494 Rectangle aRect(aTmpPoint, aWndSize);
496 aFont.SetTransparent( true );
497 aVD->SetFont(aFont);
498 aVD->SetLineColor();
499 aVD->SetFillColor(aBackCol);
500 aVD->SetOutputSize(aWndSize);
501 aVD->DrawRect(aRect);
503 PaintCells(*aVD.get());
505 rRenderContext.SetLineColor();
506 rRenderContext.SetFillColor(aBackCol);
507 rRenderContext.DrawRect(aRect);
509 Point aPos((aWndSize.Width() - aPrvSize.Width()) / 2, (aWndSize.Height() - aPrvSize.Height()) / 2);
510 if (AllSettings::GetLayoutRTL())
511 aPos.X() = -aPos.X();
512 rRenderContext.DrawOutDev(aPos, aWndSize, Point(), aWndSize, *aVD.get());
513 aVD->SetDrawMode(nOldDrawMode);
516 void ScAutoFmtPreview::Paint(vcl::RenderContext& rRenderContext, const Rectangle& rRect)
518 DoPaint(rRenderContext, rRect);
521 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */