1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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>
43 #include "zforauto.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"
52 #include "tabvwsh.hxx"
54 #define FRAME_OFFSET 4
58 ScAutoFmtPreview::ScAutoFmtPreview(vcl::Window
* pParent
)
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
))
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()
93 void ScAutoFmtPreview::dispose()
96 vcl::Window::dispose();
99 static void lcl_SetFontProperties(
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
)
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 )
161 sal_uInt16
ScAutoFmtPreview::GetFormatIndex( size_t nCol
, size_t nRow
) const
163 static const sal_uInt16 pnFmtMap
[] =
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
)
193 // Emit the cell text
196 bool bNumFormat
= pCurData
->GetIncludeValueFormat();
199 Color
* pDummy
= nullptr;
200 sal_uInt16 nIndex
= static_cast<sal_uInt16
>(maArray
.GetCellIndex(nCol
, nRow
, mbRTL
));
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;
211 case 20: cellString
= aStrSum
; break;
216 case 18: nVal
= nIndex
;
220 case 7: nVal
= nIndex
;
225 case 13: nVal
= nIndex
;
226 nNum
= 12 == nIndex
? 10 : 9;
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;
239 ScNumFormatAbbrev
& rNumFormat
= (ScNumFormatAbbrev
&) pCurData
->GetNumFormat(sal_uInt16(nNum
));
240 nNum
= rNumFormat
.GetFormatIndex(*pNumFmt
);
244 pNumFmt
->GetOutputString(nVal
, nNum
, cellString
, &pDummy
);
248 if (!cellString
.isEmpty())
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
);
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
;
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);
295 cellString
= cellString
.copy(0, cellString
.getLength() - 1 );
297 aScriptedText
.SetText( cellString
, xBreakIter
);
298 aStrSize
= aScriptedText
.GetTextSize();
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;
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
;
325 case SVX_HOR_JUSTIFY_RIGHT
:
328 case SVX_HOR_JUSTIFY_BLOCK
:
329 case SVX_HOR_JUSTIFY_REPEAT
:
330 case SVX_HOR_JUSTIFY_CENTER
:
333 // coverity[dead_error_line] - following conditions exist to avoid compiler warning
334 case SVX_HOR_JUSTIFY_STANDARD
:
336 // Standard is not handled here
343 // Standard justification
345 if (nCol
== 0 || nRow
== 0)
347 // Text label to the left or sum left adjusted
348 aPos
.X() += FRAME_OFFSET
;
352 // Numbers/Dates right adjusted
356 aScriptedText
.DrawText(aPos
);
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
)
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
)
395 if (pCurData
->GetIncludeBackground())
396 DrawBackground(rRenderContext
);
399 DrawStrings(rRenderContext
);
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 );
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()
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
)
477 bFitWidth
= pNewData
->GetIncludeWidthHeight();
480 CalcCellArray( bFitWidth
);
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());
494 Rectangle
aRect(aTmpPoint
, aWndSize
);
496 aFont
.SetTransparent( true );
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: */