LibreOffice Module sc (master)  1
drawvie3.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 #include <sal/config.h>
21 
22 #include <cstdlib>
23 
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>
30 
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>
41 
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 )
52 {
54  // #i73602# Use default from the configuration
56 
57  // #i74769#, #i75172# Use default from the configuration
59 
60  Construct();
61 }
62 
63 // set anchor
64 
66 {
67  if( !AreObjectsMarked() )
68  return;
69 
70  const SdrMarkList* pMark = &GetMarkedObjectList();
71  const size_t nCount = pMark->GetMarkCount();
72 
73  BegUndo(ScResId(SCSTR_UNDO_PAGE_ANCHOR));
74  for( size_t i=0; i<nCount; ++i )
75  {
76  SdrObject* pObj = pMark->GetMark(i)->GetMarkedSdrObj();
77  AddUndo (std::make_unique<ScUndoAnchorData>( pObj, &rDoc, nTab ));
79  }
80  EndUndo();
81 
82  if ( pViewData )
84 
85  // Remove the anchor object.
86  maHdlList.RemoveAllByKind(SdrHdlKind::Anchor);
87  maHdlList.RemoveAllByKind(SdrHdlKind::Anchor_TR);
88 }
89 
90 void ScDrawView::SetCellAnchored(bool bResizeWithCell)
91 {
92  if( !AreObjectsMarked() )
93  return;
94 
95  const SdrMarkList* pMark = &GetMarkedObjectList();
96  const size_t nCount = pMark->GetMarkCount();
97 
98  BegUndo(ScResId(SCSTR_UNDO_CELL_ANCHOR));
99  for( size_t i=0; i<nCount; ++i )
100  {
101  SdrObject* pObj = pMark->GetMark(i)->GetMarkedSdrObj();
102  AddUndo (std::make_unique<ScUndoAnchorData>( pObj, &rDoc, nTab ));
103  ScDrawLayer::SetCellAnchoredFromPosition(*pObj, rDoc, nTab, bResizeWithCell);
104  }
105  EndUndo();
106 
107  if ( pViewData )
108  {
110 
111  // Set the anchor object.
112  AddCustomHdl();
113  }
114 }
115 
117 {
118  bool bPage = false;
119  bool bCell = false;
120  bool bCellResize = false;
121  if( AreObjectsMarked() )
122  {
123  const SdrMarkList* pMark = &GetMarkedObjectList();
124  const size_t nCount = pMark->GetMarkCount();
125  for( size_t i=0; i<nCount; ++i )
126  {
127  const SdrObject* pObj = pMark->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;
135  }
136  }
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;
144 }
145 
146 namespace {
147 
148 bool lcl_AreRectanglesApproxEqual(const tools::Rectangle& rRectA, const tools::Rectangle& rRectB)
149 {
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;
161 }
162 
167 void adjustAnchoredPosition(const SdrHint& rHint, const ScDocument& rDoc, SCTAB nTab)
168 {
169  if (rHint.GetKind() != SdrHintKind::ObjectChange && rHint.GetKind() != SdrHintKind::ObjectInserted)
170  return;
171 
172  SdrObject* pObj = const_cast<SdrObject*>(rHint.GetObject());
173  if (!pObj)
174  return;
175 
176  ScDrawObjData *pAnchor = ScDrawLayer::GetObjData(pObj);
177  if (!pAnchor)
178  return;
179 
180  if (pAnchor->meType == ScDrawObjData::CellNote)
181  return;
182 
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;
190 
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;
196 
197  ScDrawLayer::SetCellAnchoredFromPosition(*pObj, rDoc, pAnchor->maStart.Tab(), pAnchor->mbResizeWithCell);
198 }
199 
200 }
201 
202 void ScDrawView::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
203 {
204  if (rHint.GetId() == SfxHintId::ThisIsAnSdrHint)
205  {
206  const SdrHint* pSdrHint = static_cast<const SdrHint*>( &rHint );
207  adjustAnchoredPosition(*pSdrHint, rDoc, nTab);
208  FmFormView::Notify( rBC,rHint );
209  }
210  else if (auto pDeletedHint = dynamic_cast<const ScTabDeletedHint*>(&rHint)) // Sheet has been deleted
211  {
212  SCTAB nDelTab = pDeletedHint->GetTab();
213  if (ValidTab(nDelTab))
214  {
215  // used to be: HidePagePgNum(nDelTab) - hide only if the deleted sheet is shown here
216  if ( nDelTab == nTab )
217  HideSdrPage();
218  }
219  }
220  else if (auto pChangedHint = dynamic_cast<const ScTabSizeChangedHint*>(&rHint)) // Size has been changed
221  {
222  if ( nTab == pChangedHint->GetTab() )
223  UpdateWorkArea();
224  }
225  else
226  FmFormView::Notify( rBC,rHint );
227 }
228 
230 {
231  if ( !(pViewData &&
233  pObj && ( dynamic_cast<const SdrGrafObj*>( pObj) != nullptr || dynamic_cast<const SdrOle2Obj*>( pObj) != nullptr )) )
234  return;
235 
236  Graphic aGraphic;
237  TargetList aTargetList;
238  SvxIMapInfo* pIMapInfo = SvxIMapInfo::GetIMapInfo( pObj );
239  const ImageMap* pImageMap = nullptr;
240  if ( pIMapInfo )
241  pImageMap = &pIMapInfo->GetImageMap();
242 
243  // handle target list
244  SfxViewFrame::GetTargetList( aTargetList );
245 
246  // handle graphics from object
247  if ( auto pGrafObj = dynamic_cast<SdrGrafObj*>( pObj) )
248  aGraphic = pGrafObj->GetGraphic();
249  else
250  {
251  const Graphic* pGraphic = static_cast<const SdrOle2Obj*>(pObj)->GetGraphic();
252  if ( pGraphic )
253  aGraphic = *pGraphic;
254  }
255 
256  ScIMapDlgSet( aGraphic, pImageMap, &aTargetList, pObj ); // from imapwrap
257 }
258 
259 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SfxViewFrame * GetViewFrame() const
ScDocShell * GetDocShell() const
Definition: viewdata.hxx:354
SdrHintKind GetKind() const
size_t GetMarkCount() const
OUString ScResId(TranslateId aId)
Definition: scdll.cxx:90
void UpdateIMap(SdrObject *pObj)
Definition: drawvie3.cxx:229
static void SetPageAnchored(SdrObject &)
Definition: drwlayer.cxx:2440
constexpr tools::Long Left() const
bool AreObjectsMarked() const
static void GetTargetList(TargetList &rList)
static ScDrawObjData * GetObjData(SdrObject *pObj, bool bCreate=false)
Definition: drwlayer.cxx:2602
void BegUndo()
SdrMark * GetMark(size_t nNum) const
virtual void AddCustomHdl() override
Definition: drawview.cxx:138
ScViewData * pViewData
Definition: drawview.hxx:35
ScAddress maStart
Definition: userdat.hxx:36
SfxHintId GetId() const
virtual const tools::Rectangle & GetSnapRect() const
virtual void Notify(SfxBroadcaster &rBC, const SfxHint &rHint) override
Definition: drawvie3.cxx:202
void SetBufferedOutputAllowed(bool bNew)
virtual void Notify(SfxBroadcaster &rBC, const SfxHint &rHint) override
int nCount
SCTAB Tab() const
Definition: address.hxx:283
void EndUndo()
void UpdateWorkArea()
Definition: drawview.cxx:263
ScTabViewShell * GetViewShell() const
Definition: viewdata.hxx:357
SdrObject * GetMarkedSdrObj() const
bool mbResizeWithCell
Definition: userdat.hxx:41
const tools::Rectangle & getShapeRect() const
Definition: userdat.hxx:46
ScAnchorType
Definition: global.hxx:371
void AddUndo(std::unique_ptr< SdrUndoAction > pUndo)
void Construct()
Definition: drawview.cxx:71
void SetBufferedOverlayAllowed(bool bNew)
int i
void SetCellAnchored(bool bResizeWithCell)
Definition: drawvie3.cxx:90
static ScAnchorType GetAnchorType(const SdrObject &)
Definition: drwlayer.cxx:2446
static void SetCellAnchoredFromPosition(SdrObject &rObj, const ScDocument &rDoc, SCTAB nTab, bool bResizeWithCell)
Definition: drwlayer.cxx:2297
const SdrMarkList & GetMarkedObjectList() const
void RemoveAllByKind(SdrHdlKind eKind)
void ScIMapDlgSet(const Graphic &rGraphic, const ImageMap *pImageMap, const TargetList *pTargetList, void *pEditingObj)
Definition: imapwrap.cxx:29
constexpr tools::Long Right() const
ScDrawView(OutputDevice *pOut, ScViewData *pData)
Definition: drawvie3.cxx:42
constexpr tools::Long Top() const
void SetPageAnchored()
Definition: drawvie3.cxx:65
constexpr tools::Long Bottom() const
bool HasChildWindow(sal_uInt16)
ScAnchorType GetAnchorType() const
Definition: drawvie3.cxx:116
static ScDrawObjData * GetNonRotatedObjData(SdrObject *pObj, bool bCreate=false)
Definition: drwlayer.cxx:2583
void SetNegativeX(bool bOn)
ScDocument & rDoc
needed ?
Definition: drawview.hxx:37
SC_DLLPUBLIC bool IsLayoutRTL(SCTAB nTab) const
Definition: document.cxx:990
const ImageMap & GetImageMap() const
virtual void HideSdrPage() override
SdrHdlList maHdlList
void SetDrawModified()
SetDrawModified - without Formula update.
Definition: docsh.cxx:3010
virtual const tools::Rectangle & GetLogicRect() const
::std::vector< OUString > TargetList
bool ValidTab(SCTAB nTab)
Definition: address.hxx:111
sal_Int16 SCTAB
Definition: types.hxx:22
SCTAB nTab
Definition: drawview.hxx:38
static SvxIMapInfo * GetIMapInfo(const SdrObject *pObject)
const SdrObject * GetObject() const
sal_uInt16 ScIMapChildWindowId()
Definition: imapwrap.cxx:24