Stop leaking all ScPostIt instances.
[LibreOffice.git] / sc / source / ui / miscdlgs / autofmt.cxx
blob425014f378a5a2313687946334fb2b6cd3677ab2
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 <sfx2/viewfrm.hxx>
36 #include <comphelper/processfactory.hxx>
38 #include "sc.hrc"
39 #include "scmod.hxx"
40 #include "attrib.hxx"
41 #include "zforauto.hxx"
42 #include "global.hxx"
43 #include "globstr.hrc"
44 #include "autoform.hxx"
45 #include "miscdlgs.hrc"
46 #include "autofmt.hxx"
47 #include "scresid.hxx"
48 #include "document.hxx"
49 #include "docsh.hxx"
50 #include "tabvwsh.hxx"
52 #define FRAME_OFFSET 4
55 //========================================================================
56 // ScAutoFmtPreview
58 ScAutoFmtPreview::ScAutoFmtPreview( Window* pParent, const ResId& rRes, ScDocument* pDoc ) :
59 Window ( pParent, rRes ),
60 pCurData ( NULL ),
61 aVD ( *this ),
62 aScriptedText ( aVD ),
63 xBreakIter ( pDoc->GetBreakIterator() ),
64 bFitWidth ( false ),
65 mbRTL ( false ),
66 aPrvSize ( GetSizePixel().Width() - 6, GetSizePixel().Height() - 30 ),
67 mnLabelColWidth ( (aPrvSize.Width() - 4) / 4 - 12 ),
68 mnDataColWidth1 ( (aPrvSize.Width() - 4 - 2 * mnLabelColWidth) / 3 ),
69 mnDataColWidth2 ( (aPrvSize.Width() - 4 - 2 * mnLabelColWidth) / 4 ),
70 mnRowHeight ( (aPrvSize.Height() - 4) / 5 ),
71 aStrJan ( ScResId( STR_JAN ) ),
72 aStrFeb ( ScResId( STR_FEB ) ),
73 aStrMar ( ScResId( STR_MAR ) ),
74 aStrNorth ( ScResId( STR_NORTH ) ),
75 aStrMid ( ScResId( STR_MID ) ),
76 aStrSouth ( ScResId( STR_SOUTH ) ),
77 aStrSum ( ScResId( STR_SUM ) ),
78 pNumFmt ( new SvNumberFormatter( ::comphelper::getProcessComponentContext(), ScGlobal::eLnge ) )
80 Init();
83 //------------------------------------------------------------------------
85 ScAutoFmtPreview::~ScAutoFmtPreview()
87 delete pNumFmt;
90 //------------------------------------------------------------------------
92 static void lcl_SetFontProperties(
93 Font& rFont,
94 const SvxFontItem& rFontItem,
95 const SvxWeightItem& rWeightItem,
96 const SvxPostureItem& rPostureItem )
98 rFont.SetFamily ( rFontItem.GetFamily() );
99 rFont.SetName ( rFontItem.GetFamilyName() );
100 rFont.SetStyleName ( rFontItem.GetStyleName() );
101 rFont.SetCharSet ( rFontItem.GetCharSet() );
102 rFont.SetPitch ( rFontItem.GetPitch() );
103 rFont.SetWeight ( (FontWeight)rWeightItem.GetValue() );
104 rFont.SetItalic ( (FontItalic)rPostureItem.GetValue() );
107 void ScAutoFmtPreview::MakeFonts( sal_uInt16 nIndex, Font& rFont, Font& rCJKFont, Font& rCTLFont )
109 if ( pCurData )
111 rFont = rCJKFont = rCTLFont = GetFont();
112 Size aFontSize( rFont.GetSize().Width(), 10 );
114 const SvxFontItem* pFontItem = (const SvxFontItem*) pCurData->GetItem( nIndex, ATTR_FONT );
115 const SvxWeightItem* pWeightItem = (const SvxWeightItem*) pCurData->GetItem( nIndex, ATTR_FONT_WEIGHT );
116 const SvxPostureItem* pPostureItem = (const SvxPostureItem*) pCurData->GetItem( nIndex, ATTR_FONT_POSTURE );
117 const SvxFontItem* pCJKFontItem = (const SvxFontItem*) pCurData->GetItem( nIndex, ATTR_CJK_FONT );
118 const SvxWeightItem* pCJKWeightItem = (const SvxWeightItem*) pCurData->GetItem( nIndex, ATTR_CJK_FONT_WEIGHT );
119 const SvxPostureItem* pCJKPostureItem = (const SvxPostureItem*) pCurData->GetItem( nIndex, ATTR_CJK_FONT_POSTURE );
120 const SvxFontItem* pCTLFontItem = (const SvxFontItem*) pCurData->GetItem( nIndex, ATTR_CTL_FONT );
121 const SvxWeightItem* pCTLWeightItem = (const SvxWeightItem*) pCurData->GetItem( nIndex, ATTR_CTL_FONT_WEIGHT );
122 const SvxPostureItem* pCTLPostureItem = (const SvxPostureItem*) pCurData->GetItem( nIndex, ATTR_CTL_FONT_POSTURE );
123 const SvxUnderlineItem* pUnderlineItem = (const SvxUnderlineItem*) pCurData->GetItem( nIndex, ATTR_FONT_UNDERLINE );
124 const SvxOverlineItem* pOverlineItem = (const SvxOverlineItem*) pCurData->GetItem( nIndex, ATTR_FONT_OVERLINE );
125 const SvxCrossedOutItem* pCrossedOutItem = (const SvxCrossedOutItem*)pCurData->GetItem( nIndex, ATTR_FONT_CROSSEDOUT );
126 const SvxContourItem* pContourItem = (const SvxContourItem*) pCurData->GetItem( nIndex, ATTR_FONT_CONTOUR );
127 const SvxShadowedItem* pShadowedItem = (const SvxShadowedItem*) pCurData->GetItem( nIndex, ATTR_FONT_SHADOWED );
128 const SvxColorItem* pColorItem = (const SvxColorItem*) pCurData->GetItem( nIndex, ATTR_FONT_COLOR );
130 lcl_SetFontProperties( rFont, *pFontItem, *pWeightItem, *pPostureItem );
131 lcl_SetFontProperties( rCJKFont, *pCJKFontItem, *pCJKWeightItem, *pCJKPostureItem );
132 lcl_SetFontProperties( rCTLFont, *pCTLFontItem, *pCTLWeightItem, *pCTLPostureItem );
134 Color aColor( pColorItem->GetValue() );
135 if( aColor.GetColor() == COL_TRANSPARENT )
136 aColor = GetSettings().GetStyleSettings().GetWindowTextColor();
138 #define SETONALLFONTS( MethodName, Value ) \
139 rFont.MethodName( Value ); rCJKFont.MethodName( Value ); rCTLFont.MethodName( Value );
141 SETONALLFONTS( SetUnderline, (FontUnderline)pUnderlineItem->GetValue() )
142 SETONALLFONTS( SetOverline, (FontUnderline)pOverlineItem->GetValue() )
143 SETONALLFONTS( SetStrikeout, (FontStrikeout)pCrossedOutItem->GetValue() )
144 SETONALLFONTS( SetOutline, pContourItem->GetValue() )
145 SETONALLFONTS( SetShadow, pShadowedItem->GetValue() )
146 SETONALLFONTS( SetColor, aColor )
147 SETONALLFONTS( SetSize, aFontSize )
148 SETONALLFONTS( SetTransparent, sal_True )
150 #undef SETONALLFONTS
154 //------------------------------------------------------------------------
156 sal_uInt16 ScAutoFmtPreview::GetFormatIndex( size_t nCol, size_t nRow ) const
158 static const sal_uInt16 pnFmtMap[] =
160 0, 1, 2, 1, 3,
161 4, 5, 6, 5, 7,
162 8, 9, 10, 9, 11,
163 4, 5, 6, 5, 7,
164 12, 13, 14, 13, 15
166 return pnFmtMap[ maArray.GetCellIndex( nCol, nRow, mbRTL ) ];
169 const SvxBoxItem& ScAutoFmtPreview::GetBoxItem( size_t nCol, size_t nRow ) const
171 OSL_ENSURE( pCurData, "ScAutoFmtPreview::GetBoxItem - no format data found" );
172 return *static_cast< const SvxBoxItem* >( pCurData->GetItem( GetFormatIndex( nCol, nRow ), ATTR_BORDER ) );
175 const SvxLineItem& ScAutoFmtPreview::GetDiagItem( size_t nCol, size_t nRow, bool bTLBR ) const
177 OSL_ENSURE( pCurData, "ScAutoFmtPreview::GetDiagItem - no format data found" );
178 return *static_cast< const SvxLineItem* >( pCurData->GetItem( GetFormatIndex( nCol, nRow ), bTLBR ? ATTR_BORDER_TLBR : ATTR_BORDER_BLTR ) );
181 //------------------------------------------------------------------------
183 void ScAutoFmtPreview::DrawString( size_t nCol, size_t nRow )
185 if ( pCurData )
187 //------------------------
188 // Ausgabe des Zelltextes:
189 //------------------------
191 OUString cellString;
192 sal_Bool bNumFormat = pCurData->GetIncludeValueFormat();
193 sal_uLong nNum;
194 double nVal;
195 Color* pDummy = NULL;
196 sal_uInt16 nIndex = static_cast< sal_uInt16 >( maArray.GetCellIndex( nCol, nRow, mbRTL ) );
198 switch( nIndex )
200 case 1: cellString = aStrJan; break;
201 case 2: cellString = aStrFeb; break;
202 case 3: cellString = aStrMar; break;
203 case 5: cellString = aStrNorth; break;
204 case 10: cellString = aStrMid; break;
205 case 15: cellString = aStrSouth; break;
206 case 4:
207 case 20: cellString = aStrSum; break;
209 case 6:
210 case 8:
211 case 16:
212 case 18: nVal = nIndex;
213 nNum = 5;
214 goto mknum;
215 case 17:
216 case 7: nVal = nIndex;
217 nNum = 6;
218 goto mknum;
219 case 11:
220 case 12:
221 case 13: nVal = nIndex;
222 nNum = 12 == nIndex ? 10 : 9;
223 goto mknum;
225 case 9: nVal = 21; nNum = 7; goto mknum;
226 case 14: nVal = 36; nNum = 11; goto mknum;
227 case 19: nVal = 51; nNum = 7; goto mknum;
228 case 21: nVal = 33; nNum = 13; goto mknum;
229 case 22: nVal = 36; nNum = 14; goto mknum;
230 case 23: nVal = 39; nNum = 13; goto mknum;
231 case 24: nVal = 108; nNum = 15;
232 mknum:
233 if( bNumFormat )
235 ScNumFormatAbbrev& rNumFormat = (ScNumFormatAbbrev&)pCurData->GetNumFormat( (sal_uInt16) nNum );
236 nNum = rNumFormat.GetFormatIndex( *pNumFmt );
238 else
239 nNum = 0;
240 pNumFmt->GetOutputString( nVal, nNum, cellString, &pDummy );
241 break;
244 if ( !cellString.isEmpty())
246 Size aStrSize;
247 sal_uInt16 nFmtIndex = GetFormatIndex( nCol, nRow );
248 Rectangle cellRect = maArray.GetCellRect( nCol, nRow );
249 Point aPos = cellRect.TopLeft();
250 sal_uInt16 nRightX = 0;
251 sal_Bool bJustify = pCurData->GetIncludeJustify();
252 SvxHorJustifyItem aHorJustifyItem( SVX_HOR_JUSTIFY_STANDARD, ATTR_HOR_JUSTIFY );
253 SvxCellHorJustify eJustification;
255 //-------------
256 // Ausrichtung:
257 //-------------
258 eJustification = mbRTL ? SVX_HOR_JUSTIFY_RIGHT : bJustify ?
259 (SvxCellHorJustify)(((const SvxHorJustifyItem*)pCurData->GetItem( nFmtIndex, ATTR_HOR_JUSTIFY ))->GetValue()) :
260 SVX_HOR_JUSTIFY_STANDARD;
262 if ( pCurData->GetIncludeFont() )
264 Font aFont, aCJKFont, aCTLFont;
265 Size theMaxStrSize;
267 MakeFonts( nFmtIndex, aFont, aCJKFont, aCTLFont );
269 theMaxStrSize = cellRect.GetSize();
270 theMaxStrSize.Width() -= FRAME_OFFSET;
271 theMaxStrSize.Height() -= FRAME_OFFSET;
273 aScriptedText.SetFonts( &aFont, &aCJKFont, &aCTLFont );
274 aScriptedText.SetText( cellString, xBreakIter );
275 aStrSize = aScriptedText.GetTextSize();
277 if ( theMaxStrSize.Height() < aStrSize.Height() )
279 // wenn der String in diesem Font nicht
280 // in die Zelle passt, wird wieder der
281 // Standard-Font genommen:
282 aScriptedText.SetDefaultFont();
283 aStrSize = aScriptedText.GetTextSize();
285 while ( ( theMaxStrSize.Width() <= aStrSize.Width() )
286 && ( cellString.getLength() > 1 ) )
288 if( eJustification == SVX_HOR_JUSTIFY_RIGHT )
289 cellString = cellString.copy(1);
290 else
291 cellString = cellString.copy(0, cellString.getLength() - 1 );
293 aScriptedText.SetText( cellString, xBreakIter );
294 aStrSize = aScriptedText.GetTextSize();
297 else
299 aScriptedText.SetDefaultFont();
300 aScriptedText.SetText( cellString, xBreakIter );
301 aStrSize = aScriptedText.GetTextSize();
304 nRightX = (sal_uInt16)( cellRect.GetWidth()
305 - aStrSize.Width()
306 - FRAME_OFFSET );
308 //-----------------------------
309 // vertikal (immer zentrieren):
310 //-----------------------------
311 aPos.Y() += (mnRowHeight - (sal_uInt16)aStrSize.Height()) / 2;
313 //-----------
314 // horizontal
315 //-----------
316 if ( eJustification != SVX_HOR_JUSTIFY_STANDARD )
318 sal_uInt16 nHorPos = (sal_uInt16)
319 ((cellRect.GetWidth()-aStrSize.Width())/2);
321 switch ( eJustification )
323 case SVX_HOR_JUSTIFY_LEFT:
324 aPos.X() += FRAME_OFFSET;
325 break;
326 case SVX_HOR_JUSTIFY_RIGHT:
327 aPos.X() += nRightX;
328 break;
329 case SVX_HOR_JUSTIFY_BLOCK:
330 case SVX_HOR_JUSTIFY_REPEAT:
331 case SVX_HOR_JUSTIFY_CENTER:
332 aPos.X() += nHorPos;
333 break;
334 case SVX_HOR_JUSTIFY_STANDARD:
335 default:
336 // Standard wird hier nicht behandelt
337 break;
340 else
342 //---------------------
343 // Standardausrichtung:
344 //---------------------
345 if ( (nCol == 0) || (nRow == 0) )
347 // Text-Label links oder Summe linksbuendig
348 aPos.X() += FRAME_OFFSET;
350 else
352 // Zahlen/Datum rechtsbuendig
353 aPos.X() += nRightX;
357 //-------------------------------
358 aScriptedText.DrawText( aPos );
359 //-------------------------------
364 #undef FRAME_OFFSET
366 //------------------------------------------------------------------------
368 void ScAutoFmtPreview::DrawStrings()
370 for( size_t nRow = 0; nRow < 5; ++nRow )
371 for( size_t nCol = 0; nCol < 5; ++nCol )
372 DrawString( nCol, nRow );
375 //------------------------------------------------------------------------
377 void ScAutoFmtPreview::DrawBackground()
379 if( pCurData )
381 for( size_t nRow = 0; nRow < 5; ++nRow )
383 for( size_t nCol = 0; nCol < 5; ++nCol )
385 const SvxBrushItem* pItem = static_cast< const SvxBrushItem* >(
386 pCurData->GetItem( GetFormatIndex( nCol, nRow ), ATTR_BACKGROUND ) );
388 aVD.Push( PUSH_LINECOLOR | PUSH_FILLCOLOR );
389 aVD.SetLineColor();
390 aVD.SetFillColor( pItem->GetColor() );
391 aVD.DrawRect( maArray.GetCellRect( nCol, nRow ) );
392 aVD.Pop();
398 //------------------------------------------------------------------------
400 void ScAutoFmtPreview::PaintCells()
402 if ( pCurData )
404 // 1) background
405 if ( pCurData->GetIncludeBackground() )
406 DrawBackground();
408 // 2) values
409 DrawStrings();
411 // 3) border
412 if ( pCurData->GetIncludeFrame() )
413 maArray.DrawArray( aVD );
417 //------------------------------------------------------------------------
419 void ScAutoFmtPreview::Init()
421 SetBorderStyle( WINDOW_BORDER_MONO );
422 maArray.Initialize( 5, 5 );
423 maArray.SetUseDiagDoubleClipping( false );
424 CalcCellArray( false );
425 CalcLineMap();
427 TypeId aType(TYPE(ScDocShell));
428 ScDocShell* pDocShell = (ScDocShell*)SfxObjectShell::GetFirst(&aType);
429 SfxViewFrame* pFrame = SfxViewFrame::GetFirst( pDocShell );
430 SfxViewShell* p = pFrame->GetViewShell();
431 ScTabViewShell* pViewSh = dynamic_cast< ScTabViewShell* >( p );
432 ScViewData* pViewData = pViewSh->GetViewData();
433 SCTAB nCurrentTab = pViewData->GetTabNo();
434 ScDocument* pDoc = pViewData->GetDocument();
435 mbRTL = pDoc->IsLayoutRTL( nCurrentTab );
438 //------------------------------------------------------------------------
440 void ScAutoFmtPreview::CalcCellArray( bool bFitWidthP )
442 maArray.SetXOffset( 2 );
443 maArray.SetAllColWidths( bFitWidthP ? mnDataColWidth2 : mnDataColWidth1 );
444 maArray.SetColWidth( 0, mnLabelColWidth );
445 maArray.SetColWidth( 4, mnLabelColWidth );
447 maArray.SetYOffset( 2 );
448 maArray.SetAllRowHeights( mnRowHeight );
450 aPrvSize.Width() = maArray.GetWidth() + 4;
451 aPrvSize.Height() = maArray.GetHeight() + 4;
454 //------------------------------------------------------------------------
456 inline void lclSetStyleFromBorder( svx::frame::Style& rStyle, const ::editeng::SvxBorderLine* pBorder )
458 rStyle.Set( pBorder, 1.0 / TWIPS_PER_POINT, 5 );
461 void ScAutoFmtPreview::CalcLineMap()
463 if ( pCurData )
465 for( size_t nRow = 0; nRow < 5; ++nRow )
467 for( size_t nCol = 0; nCol < 5; ++nCol )
469 svx::frame::Style aStyle;
471 const SvxBoxItem& rItem = GetBoxItem( nCol, nRow );
472 lclSetStyleFromBorder( aStyle, rItem.GetLeft() );
473 maArray.SetCellStyleLeft( nCol, nRow, aStyle );
474 lclSetStyleFromBorder( aStyle, rItem.GetRight() );
475 maArray.SetCellStyleRight( nCol, nRow, aStyle );
476 lclSetStyleFromBorder( aStyle, rItem.GetTop() );
477 maArray.SetCellStyleTop( nCol, nRow, aStyle );
478 lclSetStyleFromBorder( aStyle, rItem.GetBottom() );
479 maArray.SetCellStyleBottom( nCol, nRow, aStyle );
481 lclSetStyleFromBorder( aStyle, GetDiagItem( nCol, nRow, true ).GetLine() );
482 maArray.SetCellStyleTLBR( nCol, nRow, aStyle );
483 lclSetStyleFromBorder( aStyle, GetDiagItem( nCol, nRow, false ).GetLine() );
484 maArray.SetCellStyleBLTR( nCol, nRow, aStyle );
490 //------------------------------------------------------------------------
492 void ScAutoFmtPreview::NotifyChange( ScAutoFormatData* pNewData )
494 if ( pNewData != pCurData )
496 pCurData = pNewData;
497 bFitWidth = pNewData->GetIncludeWidthHeight();
498 CalcCellArray( bFitWidth );
499 CalcLineMap();
501 else if ( bFitWidth != pNewData->GetIncludeWidthHeight() )
503 bFitWidth = !bFitWidth;
504 CalcCellArray( bFitWidth );
507 DoPaint( Rectangle( Point(0,0), GetSizePixel() ) );
510 //------------------------------------------------------------------------
512 void ScAutoFmtPreview::DoPaint( const Rectangle& /* rRect */ )
514 sal_uInt32 nOldDrawMode = aVD.GetDrawMode();
516 Size aWndSize( GetSizePixel() );
517 Font aFont( aVD.GetFont() );
518 Color aBackCol( GetSettings().GetStyleSettings().GetWindowColor() );
519 Point aTmpPoint;
520 Rectangle aRect( aTmpPoint, aWndSize );
522 aFont.SetTransparent( sal_True );
523 aVD.SetFont( aFont );
524 aVD.SetLineColor();
525 aVD.SetFillColor( aBackCol );
526 aVD.SetOutputSize( aWndSize );
527 aVD.DrawRect( aRect );
529 PaintCells();
530 SetLineColor();
531 SetFillColor( aBackCol );
532 DrawRect( aRect );
534 Point aPos( (aWndSize.Width() - aPrvSize.Width()) / 2, (aWndSize.Height() - aPrvSize.Height()) / 2 );
535 if (Application::GetSettings().GetLayoutRTL())
536 aPos.X() = -aPos.X();
537 DrawOutDev( aPos, aWndSize, Point(), aWndSize, aVD );
539 aVD.SetDrawMode( nOldDrawMode );
542 //------------------------------------------------------------------------
544 void ScAutoFmtPreview::Paint( const Rectangle& rRect )
546 DoPaint( rRect );
549 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */