tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / sc / source / ui / miscdlgs / autofmt.cxx
bloba8dbe981d3868bf46c0f0ace93d3c344c65acc4d
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 <editeng/boxitem.hxx>
22 #include <editeng/brushitem.hxx>
23 #include <editeng/contouritem.hxx>
24 #include <editeng/colritem.hxx>
25 #include <editeng/crossedoutitem.hxx>
26 #include <editeng/fontitem.hxx>
27 #include <editeng/justifyitem.hxx>
28 #include <editeng/lineitem.hxx>
29 #include <editeng/postitem.hxx>
30 #include <editeng/shdditem.hxx>
31 #include <editeng/udlnitem.hxx>
32 #include <editeng/wghtitem.hxx>
33 #include <o3tl/unit_conversion.hxx>
34 #include <osl/diagnose.h>
35 #include <svl/numformat.hxx>
36 #include <svtools/scriptedtext.hxx>
37 #include <svx/framelink.hxx>
38 #include <vcl/settings.hxx>
39 #include <vcl/svapp.hxx>
40 #include <vcl/virdev.hxx>
41 #include <comphelper/processfactory.hxx>
42 #include <drawinglayer/processor2d/processor2dtools.hxx>
43 #include <drawinglayer/processor2d/baseprocessor2d.hxx>
45 #include <strings.hrc>
46 #include <zforauto.hxx>
47 #include <global.hxx>
48 #include <autoform.hxx>
49 #include <autofmt.hxx>
50 #include <scresid.hxx>
51 #include <document.hxx>
52 #include <viewdata.hxx>
53 #include <svtools/colorcfg.hxx>
54 #include <scmod.hxx>
56 #define FRAME_OFFSET 4
58 // ScAutoFmtPreview
60 ScAutoFmtPreview::ScAutoFmtPreview()
61 : pCurData(nullptr)
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 void ScAutoFmtPreview::SetDrawingArea(weld::DrawingArea* pDrawingArea)
78 aVD.disposeAndReset(VclPtr<VirtualDevice>::Create(pDrawingArea->get_ref_device()));
79 CustomWidgetController::SetDrawingArea(pDrawingArea);
82 void ScAutoFmtPreview::Resize()
84 Size aSize(GetOutputSizePixel());
85 aPrvSize = Size(aSize.Width() - 6, aSize.Height() - 30);
86 mnLabelColWidth = (aPrvSize.Width() - 4) / 4 - 12;
87 mnDataColWidth1 = (aPrvSize.Width() - 4 - 2 * mnLabelColWidth) / 3;
88 mnDataColWidth2 = (aPrvSize.Width() - 4 - 2 * mnLabelColWidth) / 4;
89 mnRowHeight = (aPrvSize.Height() - 4) / 5;
90 NotifyChange(pCurData);
93 ScAutoFmtPreview::~ScAutoFmtPreview()
97 static void lcl_SetFontProperties(
98 vcl::Font& rFont,
99 const SvxFontItem& rFontItem,
100 const SvxWeightItem& rWeightItem,
101 const SvxPostureItem& rPostureItem )
103 rFont.SetFamily ( rFontItem.GetFamily() );
104 rFont.SetFamilyName ( rFontItem.GetFamilyName() );
105 rFont.SetStyleName ( rFontItem.GetStyleName() );
106 rFont.SetCharSet ( rFontItem.GetCharSet() );
107 rFont.SetPitch ( rFontItem.GetPitch() );
108 rFont.SetWeight ( rWeightItem.GetValue() );
109 rFont.SetItalic ( rPostureItem.GetValue() );
112 void ScAutoFmtPreview::MakeFonts(vcl::RenderContext const& rRenderContext, sal_uInt16 nIndex, vcl::Font& rFont, vcl::Font& rCJKFont, vcl::Font& rCTLFont)
114 if ( !pCurData )
115 return;
117 rFont = rCJKFont = rCTLFont = rRenderContext.GetFont();
118 Size aFontSize(rFont.GetFontSize().Width(), 10 * rRenderContext.GetDPIScaleFactor());
120 const SvxFontItem* pFontItem = pCurData->GetItem( nIndex, ATTR_FONT );
121 const SvxWeightItem* pWeightItem = pCurData->GetItem( nIndex, ATTR_FONT_WEIGHT );
122 const SvxPostureItem* pPostureItem = pCurData->GetItem( nIndex, ATTR_FONT_POSTURE );
123 const SvxFontItem* pCJKFontItem = pCurData->GetItem( nIndex, ATTR_CJK_FONT );
124 const SvxWeightItem* pCJKWeightItem = pCurData->GetItem( nIndex, ATTR_CJK_FONT_WEIGHT );
125 const SvxPostureItem* pCJKPostureItem = pCurData->GetItem( nIndex, ATTR_CJK_FONT_POSTURE );
126 const SvxFontItem* pCTLFontItem = pCurData->GetItem( nIndex, ATTR_CTL_FONT );
127 const SvxWeightItem* pCTLWeightItem = pCurData->GetItem( nIndex, ATTR_CTL_FONT_WEIGHT );
128 const SvxPostureItem* pCTLPostureItem = pCurData->GetItem( nIndex, ATTR_CTL_FONT_POSTURE );
129 const SvxUnderlineItem* pUnderlineItem = pCurData->GetItem( nIndex, ATTR_FONT_UNDERLINE );
130 const SvxOverlineItem* pOverlineItem = pCurData->GetItem( nIndex, ATTR_FONT_OVERLINE );
131 const SvxCrossedOutItem* pCrossedOutItem = pCurData->GetItem( nIndex, ATTR_FONT_CROSSEDOUT );
132 const SvxContourItem* pContourItem = pCurData->GetItem( nIndex, ATTR_FONT_CONTOUR );
133 const SvxShadowedItem* pShadowedItem = pCurData->GetItem( nIndex, ATTR_FONT_SHADOWED );
134 const SvxColorItem* pColorItem = pCurData->GetItem( nIndex, ATTR_FONT_COLOR );
136 lcl_SetFontProperties( rFont, *pFontItem, *pWeightItem, *pPostureItem );
137 lcl_SetFontProperties( rCJKFont, *pCJKFontItem, *pCJKWeightItem, *pCJKPostureItem );
138 lcl_SetFontProperties( rCTLFont, *pCTLFontItem, *pCTLWeightItem, *pCTLPostureItem );
140 Color aColor( pColorItem->GetValue() );
141 if( aColor == COL_TRANSPARENT )
142 aColor = Application::GetSettings().GetStyleSettings().GetWindowTextColor();
144 #define SETONALLFONTS( MethodName, Value ) \
145 rFont.MethodName( Value ); rCJKFont.MethodName( Value ); rCTLFont.MethodName( Value );
147 SETONALLFONTS( SetUnderline, pUnderlineItem->GetValue() )
148 SETONALLFONTS( SetOverline, pOverlineItem->GetValue() )
149 SETONALLFONTS( SetStrikeout, pCrossedOutItem->GetValue() )
150 SETONALLFONTS( SetOutline, pContourItem->GetValue() )
151 SETONALLFONTS( SetShadow, pShadowedItem->GetValue() )
152 SETONALLFONTS( SetColor, aColor )
153 SETONALLFONTS( SetFontSize, aFontSize )
154 SETONALLFONTS( SetTransparent, true )
156 #undef SETONALLFONTS
159 sal_uInt16 ScAutoFmtPreview::GetFormatIndex( size_t nCol, size_t nRow ) const
161 static const sal_uInt16 pnFmtMap[] =
163 0, 1, 2, 1, 3,
164 4, 5, 6, 5, 7,
165 8, 9, 10, 9, 11,
166 4, 5, 6, 5, 7,
167 12, 13, 14, 13, 15
169 return pnFmtMap[ maArray.GetCellIndex( nCol, nRow, mbRTL ) ];
172 const SvxBoxItem& ScAutoFmtPreview::GetBoxItem( size_t nCol, size_t nRow ) const
174 assert(pCurData && "ScAutoFmtPreview::GetBoxItem - no format data found");
175 return * pCurData->GetItem( GetFormatIndex( nCol, nRow ), ATTR_BORDER );
178 const SvxLineItem& ScAutoFmtPreview::GetDiagItem( size_t nCol, size_t nRow, bool bTLBR ) const
180 assert(pCurData && "ScAutoFmtPreview::GetDiagItem - no format data found");
181 return * pCurData->GetItem( GetFormatIndex( nCol, nRow ), bTLBR ? ATTR_BORDER_TLBR : ATTR_BORDER_BLTR );
184 void ScAutoFmtPreview::DrawString(vcl::RenderContext& rRenderContext, size_t nCol, size_t nRow)
186 if (!pCurData)
188 return;
191 // Emit the cell text
193 OUString cellString;
194 bool bNumFormat = pCurData->GetIncludeValueFormat();
195 sal_uInt32 nNum;
196 double nVal;
197 const Color* pDummy = nullptr;
198 sal_uInt16 nIndex = static_cast<sal_uInt16>(maArray.GetCellIndex(nCol, nRow, mbRTL));
200 switch (nIndex)
202 case 1: cellString = aStrJan; break;
203 case 2: cellString = aStrFeb; break;
204 case 3: cellString = aStrMar; break;
205 case 5: cellString = aStrNorth; break;
206 case 10: cellString = aStrMid; break;
207 case 15: cellString = aStrSouth; break;
208 case 4:
209 case 20: cellString = aStrSum; break;
211 case 6:
212 case 8:
213 case 16:
214 case 18: nVal = nIndex;
215 nNum = 5;
216 goto mknum;
217 case 17:
218 case 7: nVal = nIndex;
219 nNum = 6;
220 goto mknum;
221 case 11:
222 case 12:
223 case 13: nVal = nIndex;
224 nNum = 12 == nIndex ? 10 : 9;
225 goto mknum;
227 case 9: nVal = 21; nNum = 7; goto mknum;
228 case 14: nVal = 36; nNum = 11; goto mknum;
229 case 19: nVal = 51; nNum = 7; goto mknum;
230 case 21: nVal = 33; nNum = 13; goto mknum;
231 case 22: nVal = 36; nNum = 14; goto mknum;
232 case 23: nVal = 39; nNum = 13; goto mknum;
233 case 24: nVal = 108; nNum = 15;
234 mknum:
235 if (bNumFormat)
237 ScNumFormatAbbrev& rNumFormat = const_cast<ScNumFormatAbbrev&>(pCurData->GetNumFormat(sal_uInt16(nNum)));
238 nNum = rNumFormat.GetFormatIndex(*pNumFmt);
240 else
241 nNum = 0;
242 pNumFmt->GetOutputString(nVal, nNum, cellString, &pDummy);
243 break;
246 if (cellString.isEmpty())
247 return;
249 Size aStrSize;
250 sal_uInt16 nFmtIndex = GetFormatIndex( nCol, nRow );
251 const basegfx::B2DRange cellRange(maArray.GetCellRange( nCol, nRow ));
252 Point aPos(basegfx::fround<tools::Long>(cellRange.getMinX()), basegfx::fround<tools::Long>(cellRange.getMinY()));
253 sal_uInt16 nRightX = 0;
254 bool bJustify = pCurData->GetIncludeJustify();
255 SvxCellHorJustify eJustification;
257 SvtScriptedTextHelper aScriptedText(rRenderContext);
259 // Justification:
261 eJustification = mbRTL ? SvxCellHorJustify::Right : bJustify ?
262 pCurData->GetItem(nFmtIndex, ATTR_HOR_JUSTIFY)->GetValue() :
263 SvxCellHorJustify::Standard;
265 if (pCurData->GetIncludeFont())
267 vcl::Font aFont, aCJKFont, aCTLFont;
268 Size theMaxStrSize;
270 MakeFonts(rRenderContext, nFmtIndex, aFont, aCJKFont, aCTLFont);
272 theMaxStrSize = Size(basegfx::fround<tools::Long>(cellRange.getWidth()), basegfx::fround<tools::Long>(cellRange.getHeight()));
273 theMaxStrSize.AdjustWidth( -(FRAME_OFFSET) );
274 theMaxStrSize.AdjustHeight( -(FRAME_OFFSET) );
276 aScriptedText.SetFonts( &aFont, &aCJKFont, &aCTLFont );
277 aScriptedText.SetText(cellString, xBreakIter);
278 aStrSize = aScriptedText.GetTextSize();
280 if (theMaxStrSize.Height() < aStrSize.Height())
282 // if the string does not fit in the row using this font,
283 // the default font is used
284 aScriptedText.SetDefaultFont();
285 aStrSize = aScriptedText.GetTextSize();
287 while((theMaxStrSize.Width() <= aStrSize.Width()) && (cellString.getLength() > 1))
289 if( eJustification == SvxCellHorJustify::Right )
290 cellString = cellString.copy(1);
291 else
292 cellString = cellString.copy(0, cellString.getLength() - 1 );
294 aScriptedText.SetText( cellString, xBreakIter );
295 aStrSize = aScriptedText.GetTextSize();
298 else
300 aScriptedText.SetDefaultFont();
301 aScriptedText.SetText( cellString, xBreakIter );
302 aStrSize = aScriptedText.GetTextSize();
305 nRightX = sal_uInt16(basegfx::fround(cellRange.getWidth()) - aStrSize.Width() - FRAME_OFFSET);
307 // vertical (always center):
309 aPos.AdjustY((mnRowHeight - static_cast<sal_uInt16>(aStrSize.Height())) / 2 );
311 // horizontal
313 if (eJustification != SvxCellHorJustify::Standard)
315 sal_uInt16 nHorPos = sal_uInt16((basegfx::fround(cellRange.getWidth())-aStrSize.Width()) / 2);
316 //sal_uInt16 nHorPos = sal_uInt16((basegfx::fround(cellRange.getWidth())-aStrSize.Width()) / 2);
318 switch (eJustification)
320 case SvxCellHorJustify::Left:
321 aPos.AdjustX(FRAME_OFFSET );
322 break;
323 case SvxCellHorJustify::Right:
324 aPos.AdjustX(nRightX );
325 break;
326 case SvxCellHorJustify::Block:
327 case SvxCellHorJustify::Repeat:
328 case SvxCellHorJustify::Center:
329 aPos.AdjustX(nHorPos );
330 break;
331 // coverity[dead_error_line] - following conditions exist to avoid compiler warning
332 case SvxCellHorJustify::Standard:
333 default:
334 // Standard is not handled here
335 break;
338 else
341 // Standard justification
343 if (nCol == 0 || nRow == 0)
345 // Text label to the left or sum left adjusted
346 aPos.AdjustX(FRAME_OFFSET );
348 else
350 // Numbers/Dates right adjusted
351 aPos.AdjustX(nRightX );
354 aScriptedText.DrawText(aPos);
357 #undef FRAME_OFFSET
359 void ScAutoFmtPreview::DrawBackground(vcl::RenderContext& rRenderContext)
361 if (!pCurData)
362 return;
364 for(size_t nRow = 0; nRow < 5; ++nRow)
366 for(size_t nCol = 0; nCol < 5; ++nCol)
368 const SvxBrushItem* pItem =
369 pCurData->GetItem( GetFormatIndex( nCol, nRow ), ATTR_BACKGROUND );
371 rRenderContext.Push( vcl::PushFlags::LINECOLOR | vcl::PushFlags::FILLCOLOR );
372 rRenderContext.SetLineColor();
373 rRenderContext.SetFillColor( pItem->GetColor() );
375 const basegfx::B2DRange aCellRange(maArray.GetCellRange( nCol, nRow ));
376 rRenderContext.DrawRect(
377 tools::Rectangle(
378 basegfx::fround<tools::Long>(aCellRange.getMinX()), basegfx::fround<tools::Long>(aCellRange.getMinY()),
379 basegfx::fround<tools::Long>(aCellRange.getMaxX()), basegfx::fround<tools::Long>(aCellRange.getMaxY())));
381 rRenderContext.Pop();
386 void ScAutoFmtPreview::PaintCells(vcl::RenderContext& rRenderContext)
388 if (!pCurData)
389 return;
391 // 1) background
392 if (pCurData->GetIncludeBackground())
393 DrawBackground(rRenderContext);
395 // 2) values
396 for(size_t nRow = 0; nRow < 5; ++nRow)
397 for(size_t nCol = 0; nCol < 5; ++nCol)
398 DrawString(rRenderContext, nCol, nRow);
400 // 3) border
401 if (!pCurData->GetIncludeFrame())
402 return;
404 const drawinglayer::geometry::ViewInformation2D aNewViewInformation2D;
405 std::unique_ptr<drawinglayer::processor2d::BaseProcessor2D> pProcessor2D(
406 drawinglayer::processor2d::createPixelProcessor2DFromOutputDevice(
407 rRenderContext,
408 aNewViewInformation2D));
410 pProcessor2D->process(maArray.CreateB2DPrimitiveArray());
411 pProcessor2D.reset();
414 void ScAutoFmtPreview::Init()
416 maArray.Initialize( 5, 5 );
417 mnLabelColWidth = 0;
418 mnDataColWidth1 = 0;
419 mnDataColWidth2 = 0;
420 mnRowHeight = 0;
421 CalcCellArray( false );
422 CalcLineMap();
425 void ScAutoFmtPreview::DetectRTL(const ScViewData& rViewData)
427 SCTAB nCurrentTab = rViewData.GetTabNo();
428 ScDocument& rDoc = rViewData.GetDocument();
429 mbRTL = rDoc.IsLayoutRTL(nCurrentTab);
430 xBreakIter = rDoc.GetBreakIterator();
433 void ScAutoFmtPreview::CalcCellArray( bool bFitWidthP )
435 maArray.SetXOffset( 2 );
436 maArray.SetAllColWidths( bFitWidthP ? mnDataColWidth2 : mnDataColWidth1 );
437 maArray.SetColWidth( 0, mnLabelColWidth );
438 maArray.SetColWidth( 4, mnLabelColWidth );
440 maArray.SetYOffset( 2 );
441 maArray.SetAllRowHeights( mnRowHeight );
443 aPrvSize.setWidth( maArray.GetWidth() + 4 );
444 aPrvSize.setHeight( maArray.GetHeight() + 4 );
447 static void lclSetStyleFromBorder( svx::frame::Style& rStyle, const ::editeng::SvxBorderLine* pBorder )
449 rStyle.Set(pBorder, o3tl::convert(1.0, o3tl::Length::twip, o3tl::Length::pt), 5);
452 void ScAutoFmtPreview::CalcLineMap()
454 if ( !pCurData )
455 return;
457 for( size_t nRow = 0; nRow < 5; ++nRow )
459 for( size_t nCol = 0; nCol < 5; ++nCol )
461 svx::frame::Style aStyle;
463 const SvxBoxItem& rItem = GetBoxItem( nCol, nRow );
464 lclSetStyleFromBorder( aStyle, rItem.GetLeft() );
465 maArray.SetCellStyleLeft( nCol, nRow, aStyle );
466 lclSetStyleFromBorder( aStyle, rItem.GetRight() );
467 maArray.SetCellStyleRight( nCol, nRow, aStyle );
468 lclSetStyleFromBorder( aStyle, rItem.GetTop() );
469 maArray.SetCellStyleTop( nCol, nRow, aStyle );
470 lclSetStyleFromBorder( aStyle, rItem.GetBottom() );
471 maArray.SetCellStyleBottom( nCol, nRow, aStyle );
473 lclSetStyleFromBorder( aStyle, GetDiagItem( nCol, nRow, true ).GetLine() );
474 maArray.SetCellStyleTLBR( nCol, nRow, aStyle );
475 lclSetStyleFromBorder( aStyle, GetDiagItem( nCol, nRow, false ).GetLine() );
476 maArray.SetCellStyleBLTR( nCol, nRow, aStyle );
481 void ScAutoFmtPreview::NotifyChange( ScAutoFormatData* pNewData )
483 if (pNewData)
485 pCurData = pNewData;
486 bFitWidth = pNewData->GetIncludeWidthHeight();
489 CalcCellArray( bFitWidth );
490 CalcLineMap();
492 Invalidate();
495 void ScAutoFmtPreview::DoPaint(vcl::RenderContext& rRenderContext)
497 rRenderContext.Push(vcl::PushFlags::ALL);
498 DrawModeFlags nOldDrawMode = aVD->GetDrawMode();
500 Size aWndSize(GetOutputSizePixel());
501 vcl::Font aFont(aVD->GetFont());
502 const Color& aBackCol = ScModule::get()->GetColorConfig().GetColorValue( ::svtools::DOCCOLOR ).nColor;
503 tools::Rectangle aRect(Point(), aWndSize);
505 aFont.SetTransparent( true );
506 aVD->SetFont(aFont);
507 aVD->SetLineColor();
508 aVD->SetFillColor(aBackCol);
509 aVD->SetOutputSize(aWndSize);
510 aVD->DrawRect(aRect);
512 PaintCells(*aVD);
514 rRenderContext.SetLineColor();
515 rRenderContext.SetFillColor(aBackCol);
516 rRenderContext.DrawRect(aRect);
518 Point aPos((aWndSize.Width() - aPrvSize.Width()) / 2, (aWndSize.Height() - aPrvSize.Height()) / 2);
519 if (AllSettings::GetLayoutRTL())
520 aPos.setX( -aPos.X() );
521 rRenderContext.DrawOutDev(aPos, aWndSize, Point(), aWndSize, *aVD);
522 aVD->SetDrawMode(nOldDrawMode);
523 rRenderContext.Pop();
526 void ScAutoFmtPreview::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& /*rRect*/)
528 DoPaint(rRenderContext);
531 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */