tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / sc / source / ui / view / output3.cxx
blob1f5311c720dea702de84975912b41f12b65e700d
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 <sal/config.h>
22 #include <o3tl/unit_conversion.hxx>
23 #include <svx/svdoutl.hxx>
24 #include <svx/svdpagv.hxx>
25 #include <svx/svdview.hxx>
26 #include <vcl/svapp.hxx>
27 #include <vcl/settings.hxx>
28 #include <osl/diagnose.h>
30 #include <output.hxx>
31 #include <drwlayer.hxx>
32 #include <document.hxx>
33 #include <tabvwsh.hxx>
35 #include <svx/fmview.hxx>
36 #include <svx/sdrpaintwindow.hxx>
37 #include <svx/sdrpagewindow.hxx>
39 // #i72502#
40 Point ScOutputData::PrePrintDrawingLayer(tools::Long nLogStX, tools::Long nLogStY )
42 tools::Rectangle aRect;
43 SCCOL nCol;
44 Point aOffset;
45 tools::Long nLayoutSign(bLayoutRTL ? -1 : 1);
47 for (nCol=0; nCol<nX1; nCol++)
48 aOffset.AdjustX( -(mpDoc->GetColWidth( nCol, nTab ) * nLayoutSign) );
49 aOffset.AdjustY( -sal_Int32(mpDoc->GetRowHeight( 0, nY1-1, nTab )) );
51 tools::Long nDataWidth = 0;
52 for (nCol=nX1; nCol<=nX2; nCol++)
53 nDataWidth += mpDoc->GetColWidth( nCol, nTab );
55 if ( bLayoutRTL )
56 aOffset.AdjustX(nDataWidth );
58 aRect.SetLeft( -aOffset.X() );
59 aRect.SetRight( -aOffset.X() );
60 aRect.SetTop( -aOffset.Y() );
61 aRect.SetBottom( -aOffset.Y() );
63 Point aMMOffset( aOffset );
64 aMMOffset.setX(o3tl::convert(aMMOffset.X(), o3tl::Length::twip, o3tl::Length::mm100));
65 aMMOffset.setY(o3tl::convert(aMMOffset.Y(), o3tl::Length::twip, o3tl::Length::mm100));
67 if (!bMetaFile)
68 aMMOffset += Point( nLogStX, nLogStY );
70 for (nCol=nX1; nCol<=nX2; nCol++)
71 aRect.AdjustRight(mpDoc->GetColWidth( nCol, nTab ) );
72 aRect.AdjustBottom(mpDoc->GetRowHeight( nY1, nY2, nTab ) );
74 aRect.SetLeft(o3tl::convert(aRect.Left(), o3tl::Length::twip, o3tl::Length::mm100));
75 aRect.SetTop(o3tl::convert(aRect.Top(), o3tl::Length::twip, o3tl::Length::mm100));
76 aRect.SetRight(o3tl::convert(aRect.Right(), o3tl::Length::twip, o3tl::Length::mm100));
77 aRect.SetBottom(o3tl::convert(aRect.Bottom(), o3tl::Length::twip, o3tl::Length::mm100));
79 if(pViewShell || pDrawView)
81 SdrView* pLocalDrawView = pDrawView ? pDrawView : pViewShell->GetScDrawView();
83 if(pLocalDrawView)
85 // #i76114# MapMode has to be set because BeginDrawLayers uses GetPaintRegion
86 MapMode aOldMode = mpDev->GetMapMode();
87 if (!bMetaFile)
88 mpDev->SetMapMode( MapMode( MapUnit::Map100thMM, aMMOffset, aOldMode.GetScaleX(), aOldMode.GetScaleY() ) );
90 // #i74769# work with SdrPaintWindow directly
91 // #i76114# pass bDisableIntersect = true, because the intersection of the table area
92 // with the Window's paint region can be empty
93 vcl::Region aRectRegion(aRect);
94 mpTargetPaintWindow = pLocalDrawView->BeginDrawLayers(mpDev, aRectRegion, true);
95 OSL_ENSURE(mpTargetPaintWindow, "BeginDrawLayers: Got no SdrPaintWindow (!)");
97 if (!bMetaFile)
98 mpDev->SetMapMode( aOldMode );
102 return aMMOffset;
105 // #i72502#
106 void ScOutputData::PostPrintDrawingLayer(const Point& rMMOffset) // #i74768#
108 // #i74768# just use offset as in PrintDrawingLayer() to also get the form controls
109 // painted with offset
110 MapMode aOldMode = mpDev->GetMapMode();
112 if (!bMetaFile)
114 mpDev->SetMapMode( MapMode( MapUnit::Map100thMM, rMMOffset, aOldMode.GetScaleX(), aOldMode.GetScaleY() ) );
117 if(pViewShell || pDrawView)
119 SdrView* pLocalDrawView = pDrawView ? pDrawView : pViewShell->GetScDrawView();
121 if(pLocalDrawView)
123 // #i74769# work with SdrPaintWindow directly
124 pLocalDrawView->EndDrawLayers(*mpTargetPaintWindow, true);
125 mpTargetPaintWindow = nullptr;
129 // #i74768#
130 if (!bMetaFile)
132 mpDev->SetMapMode( aOldMode );
136 // #i72502#
137 void ScOutputData::PrintDrawingLayer(SdrLayerID nLayer, const Point& rMMOffset)
139 bool bHideAllDrawingLayer(false);
141 if(pViewShell || pDrawView)
143 SdrView* pLocalDrawView = pDrawView ? pDrawView : pViewShell->GetScDrawView();
145 if(pLocalDrawView)
147 bHideAllDrawingLayer = pLocalDrawView->getHideOle() && pLocalDrawView->getHideChart()
148 && pLocalDrawView->getHideDraw() && pLocalDrawView->getHideFormControl();
152 if(bHideAllDrawingLayer || (!mpDoc->GetDrawLayer()))
154 return;
157 MapMode aOldMode = mpDev->GetMapMode();
159 if (!bMetaFile)
161 mpDev->SetMapMode( MapMode( MapUnit::Map100thMM, rMMOffset, aOldMode.GetScaleX(), aOldMode.GetScaleY() ) );
164 DrawSelectiveObjects( nLayer );
166 if (!bMetaFile)
168 mpDev->SetMapMode( aOldMode );
172 void ScOutputData::DrawSelectiveObjects(SdrLayerID nLayer)
174 ScDrawLayer* pModel = mpDoc->GetDrawLayer();
175 if (!pModel)
176 return;
178 // #i46362# high contrast mode (and default text direction) must be handled
179 // by the application, so it's still needed when using DrawLayer().
181 SdrOutliner& rOutl = pModel->GetDrawOutliner();
182 rOutl.EnableAutoColor( mbUseStyleColor );
183 rOutl.SetDefaultHorizontalTextDirection(
184 mpDoc->GetEditTextDirection( nTab ) );
185 Color aOldOutlinerBackgroundColor = rOutl.GetBackgroundColor();
186 const ScTabViewShell* pTabViewShellBg = mbUseStyleColor ? ScTabViewShell::GetActiveViewShell() : nullptr;
187 if (pTabViewShellBg)
189 // Similar to writer's SwViewShellImp::PaintLayer set the default
190 // background of the Outliner for the AutoColor cases where there is no
191 // explicit background known. But like elsewhere in calc, take
192 // mbUseStyleColor of false as ScAutoFontColorMode::Print for print
193 // output, so don't set a default outliner background then.
194 const ScViewRenderingOptions& rViewRenderingOptions = pTabViewShellBg->GetViewRenderingData();
195 rOutl.SetBackgroundColor(rViewRenderingOptions.GetDocColor());
198 // #i69767# The hyphenator must be set (used to be before drawing a text shape with hyphenation).
199 // LinguMgr::GetHyphenator (EditEngine) uses a wrapper now that creates the real hyphenator on demand,
200 // so it's not a performance problem to call UseHyphenator even when it's not needed.
202 pModel->UseHyphenator();
204 DrawModeFlags nOldDrawMode = mpDev->GetDrawMode();
205 if ( mbUseStyleColor && Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
207 mpDev->SetDrawMode( nOldDrawMode | DrawModeFlags::SettingsLine | DrawModeFlags::SettingsFill |
208 DrawModeFlags::SettingsText | DrawModeFlags::SettingsGradient );
211 if(pViewShell || pDrawView)
213 SdrView* pLocalDrawView = pDrawView ? pDrawView : pViewShell->GetScDrawView();
215 if(pLocalDrawView)
217 SdrPageView* pPageView = pLocalDrawView->GetSdrPageView();
219 if(pPageView)
221 // tdf#160589 need to check for registered PaintWindow using the
222 // 'original' TargetDevice, mpDev might have been changed by a
223 // call to ::SetContentDevice. That again might patch in a
224 // pre-render device fetched from SdrPaintWindow::GetTargetOutputDevice
225 // and thus the test if target is a registered PageWindow would fail
226 assert(nullptr != mpOriginalTargetDevice && "mpOriginalTargetDevice *must* be set when constructing ScOutputData (!)");
227 if (nullptr != pPageView->FindPageWindow(*mpOriginalTargetDevice))
229 // Target OutputDevice is registered for this view
230 // (as it should be), we can just render
231 pPageView->DrawLayer(sal::static_int_cast<SdrLayerID>(nLayer), mpDev);
233 else if (0 != pPageView->PageWindowCount())
235 // We need to temporarily make the target OutputDevice being
236 // 'known/registered' in the paint mechanism so that
237 // SdrPageView::DrawLayer can find it.
238 // This situation can occur when someone interprets the
239 // OutputDevice parameter that gets handed over to DrawLayer
240 // (or other SdrPageView repaint methods) to be there to
241 // define a new render target.
242 // This is *not* the case: This parameter is used to
243 // *identify* an already registered target-OutputDevice.
244 // The default is even to call with a nullptr -> that triggers
245 // the repaint for *all* registered OutputDevices/Windows.
246 // Since this is a common and known misinterpretation it
247 // is good to offer workarounds in the code - there are some
248 // already.
249 // For now - use an already existing 'patch mechanism' and
250 // 'smuggle' the unknown/temporary OutputDevice as a
251 // temporary SdrPaintWindow to the SdrPageWindow, that is
252 // not very expensive.
253 // NOTE: Just using the 1st SdrPageWindow here will be OK
254 // in most cases, the splitting of a view is only used
255 // in calc nowadays and should have identical zoom.
256 // Still, trigger a warning...
257 OSL_ENSURE(1 == pPageView->PageWindowCount(),
258 "ScOutputData::DrawSelectiveObjects: More than one SdrPageView, still using 1st one (!)");
259 SdrPageWindow* patchedPageWindow(pPageView->GetPageWindow(0));
260 assert(nullptr != patchedPageWindow && "SdrPageWindow *must* exist when 0 != PageWindowCount()");
261 SdrPaintWindow temporaryPaintWindow(*pLocalDrawView, *mpDev);
262 SdrPaintWindow* previousPaintWindow(patchedPageWindow->patchPaintWindow(temporaryPaintWindow));
263 pPageView->DrawLayer(sal::static_int_cast<SdrLayerID>(nLayer), mpDev);
264 patchedPageWindow->unpatchPaintWindow(previousPaintWindow);
266 else
268 // There does not even exist a SdrPageWindow. Still call the
269 // paint to get the paint done, but be aware that this will create
270 // temporary SdrPaintWindow and SdrPageWindow and - due to the
271 // former - will not be able to use the decomposition buffering
272 // in the VC/VOC/OC mechanism. For that reason this might be
273 // somewhat 'expensive'.
274 // You will also get a warning about it (see OSL_FAIL in
275 // SdrPageView::DrawLayer)
276 pPageView->DrawLayer(sal::static_int_cast<SdrLayerID>(nLayer), mpDev);
282 if (pTabViewShellBg)
283 rOutl.SetBackgroundColor(aOldOutlinerBackgroundColor);
285 mpDev->SetDrawMode(nOldDrawMode);
288 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */