tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / sc / source / ui / view / drawvie3.cxx
blobf5fba7aa55876e863f65184fe669794e0856e3f2
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 <cstdlib>
24 #include <svx/svdograf.hxx>
25 #include <svx/svdoole2.hxx>
26 #include <svx/ImageMapInfo.hxx>
27 #include <sfx2/viewfrm.hxx>
28 #include <comphelper/lok.hxx>
29 #include <officecfg/Office/Common.hxx>
31 #include <strings.hrc>
32 #include <scresid.hxx>
33 #include <drawview.hxx>
34 #include <drwlayer.hxx>
35 #include "imapwrap.hxx"
36 #include <viewdata.hxx>
37 #include <document.hxx>
38 #include <userdat.hxx>
39 #include <tabvwsh.hxx>
40 #include <docsh.hxx>
42 ScDrawView::ScDrawView(
43 OutputDevice* pOut,
44 ScViewData* pData )
45 : FmFormView(*pData->GetDocument().GetDrawLayer(), pOut),
46 pViewData( pData ),
47 pDev( pOut ),
48 rDoc( pData->GetDocument() ),
49 nTab( pData->GetTabNo() ),
50 pDropMarkObj( nullptr ),
51 bInConstruct( true )
53 SetNegativeX(comphelper::LibreOfficeKit::isActive() && rDoc.IsLayoutRTL(nTab));
54 // #i73602# Use default from the configuration
55 SetBufferedOverlayAllowed(!comphelper::IsFuzzing() && officecfg::Office::Common::Drawinglayer::OverlayBuffer_Calc::get());
57 // #i74769#, #i75172# Use default from the configuration
58 SetBufferedOutputAllowed(!comphelper::IsFuzzing() && officecfg::Office::Common::Drawinglayer::PaintBuffer_Calc::get());
60 Construct();
63 // set anchor
65 void ScDrawView::SetPageAnchored()
67 const SdrMarkList& rMarkList = GetMarkedObjectList();
68 if( rMarkList.GetMarkCount() == 0 )
69 return;
71 const size_t nCount = rMarkList.GetMarkCount();
73 BegUndo(ScResId(SCSTR_UNDO_PAGE_ANCHOR));
74 for( size_t i=0; i<nCount; ++i )
76 SdrObject* pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
77 AddUndo (std::make_unique<ScUndoAnchorData>( pObj, &rDoc, nTab ));
78 ScDrawLayer::SetPageAnchored( *pObj );
80 EndUndo();
82 if ( pViewData )
83 pViewData->GetDocShell()->SetDrawModified();
85 // Remove the anchor object.
86 maHdlList.RemoveAllByKind(SdrHdlKind::Anchor);
87 maHdlList.RemoveAllByKind(SdrHdlKind::Anchor_TR);
90 void ScDrawView::SetCellAnchored(bool bResizeWithCell)
92 const SdrMarkList& rMarkList = GetMarkedObjectList();
93 if( rMarkList.GetMarkCount() == 0 )
94 return;
96 const size_t nCount = rMarkList.GetMarkCount();
98 BegUndo(ScResId(SCSTR_UNDO_CELL_ANCHOR));
99 for( size_t i=0; i<nCount; ++i )
101 SdrObject* pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
102 AddUndo (std::make_unique<ScUndoAnchorData>( pObj, &rDoc, nTab ));
103 ScDrawLayer::SetCellAnchoredFromPosition(*pObj, rDoc, nTab, bResizeWithCell);
105 EndUndo();
107 if ( pViewData )
109 pViewData->GetDocShell()->SetDrawModified();
111 // Set the anchor object.
112 AddCustomHdl();
116 ScAnchorType ScDrawView::GetAnchorType() const
118 bool bPage = false;
119 bool bCell = false;
120 bool bCellResize = false;
121 const SdrMarkList& rMarkList = GetMarkedObjectList();
122 if( rMarkList.GetMarkCount() != 0 )
124 const size_t nCount = rMarkList.GetMarkCount();
125 for( size_t i=0; i<nCount; ++i )
127 const SdrObject* pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
128 const ScAnchorType aAnchorType = ScDrawLayer::GetAnchorType( *pObj );
129 if( aAnchorType == SCA_CELL )
130 bCell =true;
131 else if (aAnchorType == SCA_CELL_RESIZE)
132 bCellResize = true;
133 else
134 bPage = true;
137 if( bPage && !bCell && !bCellResize )
138 return SCA_PAGE;
139 if( !bPage && bCell && !bCellResize )
140 return SCA_CELL;
141 if( !bPage && !bCell && bCellResize )
142 return SCA_CELL_RESIZE;
143 return SCA_DONTKNOW;
146 namespace {
148 bool lcl_AreRectanglesApproxEqual(const tools::Rectangle& rRectA, const tools::Rectangle& rRectB)
150 // Twips <-> Hmm conversions introduce +-1 differences although the rectangles should actually
151 // be equal. Therefore test with == is not appropriate in some cases.
152 if (std::abs(rRectA.Left() - rRectB.Left()) > 1)
153 return false;
154 if (std::abs(rRectA.Top() - rRectB.Top()) > 1)
155 return false;
156 if (std::abs(rRectA.Right() - rRectB.Right()) > 1)
157 return false;
158 if (std::abs(rRectA.Bottom() - rRectB.Bottom()) > 1)
159 return false;
160 return true;
164 * Updated the anchors of any non-note object that is cell anchored which
165 * has been moved since the last anchors for its position was calculated.
167 void adjustAnchoredPosition(const SdrHint& rHint, const ScDocument& rDoc, SCTAB nTab)
169 if (rHint.GetKind() != SdrHintKind::ObjectChange && rHint.GetKind() != SdrHintKind::ObjectInserted)
170 return;
172 SdrObject* pObj = const_cast<SdrObject*>(rHint.GetObject());
173 if (!pObj)
174 return;
176 ScDrawObjData *pAnchor = ScDrawLayer::GetObjData(pObj);
177 if (!pAnchor)
178 return;
180 if (pAnchor->meType == ScDrawObjData::CellNote)
181 return;
183 // SetCellAnchoredFromPosition has to be called only if shape geometry has been changed, and not
184 // if only shape visibility has been changed. It is not enough to test shape rect, because e.g. a
185 // 180deg rotation changes only the logic rect (tdf#139583).
186 ScDrawObjData& rNoRotatedAnchor = *ScDrawLayer::GetNonRotatedObjData(pObj, true /*bCreate*/);
187 if (lcl_AreRectanglesApproxEqual(pAnchor->getShapeRect(), pObj->GetSnapRect())
188 && lcl_AreRectanglesApproxEqual(rNoRotatedAnchor.getShapeRect(), pObj->GetLogicRect()))
189 return;
191 if (pAnchor->maStart.Tab() != nTab)
192 // The object is not anchored on the current sheet. Skip it.
193 // TODO: In the future, we may want to adjust objects that are
194 // anchored on all selected sheets.
195 return;
197 ScDrawLayer::SetCellAnchoredFromPosition(*pObj, rDoc, pAnchor->maStart.Tab(), pAnchor->mbResizeWithCell);
202 void ScDrawView::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
204 if (rHint.GetId() == SfxHintId::ThisIsAnSdrHint)
206 const SdrHint* pSdrHint = static_cast<const SdrHint*>( &rHint );
207 adjustAnchoredPosition(*pSdrHint, rDoc, nTab);
208 FmFormView::Notify( rBC,rHint );
210 else if (rHint.GetId() == SfxHintId::ScTabDeleted) // Sheet has been deleted
212 auto pDeletedHint = static_cast<const ScTabDeletedHint*>(&rHint);
213 SCTAB nDelTab = pDeletedHint->GetTab();
214 if (ValidTab(nDelTab))
216 // used to be: HidePagePgNum(nDelTab) - hide only if the deleted sheet is shown here
217 if ( nDelTab == nTab )
218 HideSdrPage();
221 else if (rHint.GetId() == SfxHintId::ScTabSizeChanged) // Size has been changed
223 auto pChangedHint = static_cast<const ScTabSizeChangedHint*>(&rHint);
224 if ( nTab == pChangedHint->GetTab() )
225 UpdateWorkArea();
227 else
228 FmFormView::Notify( rBC,rHint );
231 void ScDrawView::UpdateIMap( SdrObject* pObj )
233 if ( !(pViewData &&
234 pViewData->GetViewShell()->GetViewFrame().HasChildWindow( ScIMapChildWindowId() ) &&
235 pObj && ( dynamic_cast<const SdrGrafObj*>( pObj) != nullptr || dynamic_cast<const SdrOle2Obj*>( pObj) != nullptr )) )
236 return;
238 Graphic aGraphic;
239 TargetList aTargetList;
240 SvxIMapInfo* pIMapInfo = SvxIMapInfo::GetIMapInfo( pObj );
241 const ImageMap* pImageMap = nullptr;
242 if ( pIMapInfo )
243 pImageMap = &pIMapInfo->GetImageMap();
245 // handle target list
246 SfxViewFrame::GetTargetList( aTargetList );
248 // handle graphics from object
249 if ( auto pGrafObj = dynamic_cast<SdrGrafObj*>( pObj) )
250 aGraphic = pGrafObj->GetGraphic();
251 else
253 const Graphic* pGraphic = static_cast<const SdrOle2Obj*>(pObj)->GetGraphic();
254 if ( pGraphic )
255 aGraphic = *pGraphic;
258 ScIMapDlgSet( aGraphic, pImageMap, &aTargetList, pObj ); // from imapwrap
261 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */