LibreOffice Module sc (master)  1
drwlayer.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 <com/sun/star/uno/Reference.hxx>
21 #include <com/sun/star/chart/XChartDocument.hpp>
22 #include <com/sun/star/chart2/XChartDocument.hpp>
23 #include <com/sun/star/embed/XClassifiedObject.hpp>
24 #include <com/sun/star/embed/XEmbeddedObject.hpp>
25 
26 #include <scitems.hxx>
27 #include <editeng/eeitem.hxx>
28 #include <editeng/frmdiritem.hxx>
29 #include <sot/exchange.hxx>
30 #include <svx/objfac3d.hxx>
31 #include <svx/xtable.hxx>
32 #include <svx/svdoutl.hxx>
33 #include <svx/svditer.hxx>
34 #include <svx/svdlayer.hxx>
35 #include <svx/svdocapt.hxx>
36 #include <svx/svdograf.hxx>
37 #include <svx/svdoole2.hxx>
38 #include <svx/svdundo.hxx>
39 #include <svx/sdsxyitm.hxx>
40 #include <svx/svxids.hrc>
41 #include <i18nlangtag/mslangid.hxx>
42 #include <editeng/unolingu.hxx>
43 #include <svx/drawitem.hxx>
44 #include <editeng/fhgtitem.hxx>
46 #include <sfx2/objsh.hxx>
47 #include <svl/itempool.hxx>
48 #include <vcl/canvastools.hxx>
49 #include <vcl/svapp.hxx>
50 #include <vcl/settings.hxx>
51 #include <tools/globname.hxx>
52 
55 
56 #include <drwlayer.hxx>
57 #include <drawpage.hxx>
58 #include <global.hxx>
59 #include <document.hxx>
60 #include <userdat.hxx>
61 #include <markdata.hxx>
62 #include <globstr.hrc>
63 #include <scresid.hxx>
64 #include <scmod.hxx>
65 #include <postit.hxx>
66 #include <attrib.hxx>
67 #include <charthelper.hxx>
68 #include <table.hxx>
70 
71 #include <vcl/fieldvalues.hxx>
72 #include <memory>
73 
74 namespace com::sun::star::embed { class XEmbeddedObject; }
75 
76 #define DET_ARROW_OFFSET 1000
77 
78 using namespace ::com::sun::star;
79 
80 static E3dObjFactory* pF3d = nullptr;
81 static sal_uInt16 nInst = 0;
82 
84 
85 bool bDrawIsInUndo = false; //TODO: Member
86 
88  const ScAddress& rNS, const ScAddress& rNE ) :
89  SdrUndoObj( *pObjP ),
90  aOldStt( rOS ),
91  aOldEnd( rOE ),
92  aNewStt( rNS ),
93  aNewEnd( rNE )
94 {
95 }
96 
98 {
99 }
100 
102 {
104  OSL_ENSURE(pData,"ScUndoObjData: Data missing");
105  if (pData)
106  {
107  pData->maStart = aOldStt;
108  pData->maEnd = aOldEnd;
109  }
110 
111  // Undo also an untransformed anchor
113  if (pData)
114  {
115  pData->maStart = aOldStt;
116  pData->maEnd = aOldEnd;
117  }
118 }
119 
121 {
123  OSL_ENSURE(pData,"ScUndoObjData: Data missing");
124  if (pData)
125  {
126  pData->maStart = aNewStt;
127  pData->maEnd = aNewEnd;
128  }
129 
130  // Redo also an untransformed anchor
132  if (pData)
133  {
134  pData->maStart = aNewStt;
135  pData->maEnd = aNewEnd;
136  }
137 }
138 
140  SdrUndoObj( *pObjP ),
141  mpDoc( pDoc ),
142  mnTab( nTab )
143 {
146 }
147 
149 {
150 }
151 
153 {
154  // Trigger Object Change
156  {
157  SdrHint aHint(SdrHintKind::ObjectChange, *pObj);
158  pObj->getSdrModelFromSdrObject().Broadcast(aHint);
159  }
160 
161  if (mbWasCellAnchored)
163  else
165 }
166 
168 {
169  if (mbWasCellAnchored)
171  else
173 
174  // Trigger Object Change
176  {
177  SdrHint aHint(SdrHintKind::ObjectChange, *pObj);
178  pObj->getSdrModelFromSdrObject().Broadcast(aHint);
179  }
180 }
181 
183  nTab( nTabNo )
184 {
185 }
186 
188 {
189 }
190 
192  nTab( nTabNo )
193 {
194 }
195 
197 {
198 }
199 
200 #define MAXMM 10000000
201 
203 {
204  return static_cast< tools::Long >( vcl::ConvertDoubleValue (static_cast<sal_Int64>(nVal), 0, 0,
205  FieldUnit::TWIP, FieldUnit::MM_100TH) );
206 }
207 
209 {
210  return static_cast< tools::Long > ( vcl::ConvertDoubleValue (static_cast<sal_Int64>(nVal), 0, 0,
211  FieldUnit::MM_100TH, FieldUnit::TWIP) );
212 }
213 
215 {
216  rRect.SetLeft( HmmToTwips( rRect.Left() ) );
217  rRect.SetRight( HmmToTwips( rRect.Right() ) );
218  rRect.SetTop( HmmToTwips( rRect.Top()) );
219  rRect.SetBottom( HmmToTwips(rRect.Bottom()) );
220 }
221 
223 {
224  if (!pClipDoc)
225  return ScRange();
226 
227  SCCOL nClipStartX;
228  SCROW nClipStartY;
229  SCCOL nClipEndX;
230  SCROW nClipEndY;
231  pClipDoc->GetClipStart(nClipStartX, nClipStartY);
232  pClipDoc->GetClipArea(nClipEndX, nClipEndY, true);
233  nClipEndX = nClipEndX + nClipStartX;
234  nClipEndY += nClipStartY; // GetClipArea returns the difference
235 
236  return ScRange(nClipStartX, nClipStartY, nClipTab, nClipEndX, nClipEndY, nClipTab);
237 }
238 
239 ScDrawLayer::ScDrawLayer( ScDocument* pDocument, const OUString& rName ) :
240  FmFormModel(
241  nullptr,
242  pGlobalDrawPersist ? pGlobalDrawPersist : (pDocument ? pDocument->GetDocumentShell() : nullptr)),
243  aName( rName ),
244  pDoc( pDocument ),
245  bRecording( false ),
246  bAdjustEnabled( true ),
247  bHyphenatorSet( false )
248 {
249  pGlobalDrawPersist = nullptr; // Only use once
250 
251  SfxObjectShell* pObjSh = pDocument ? pDocument->GetDocumentShell() : nullptr;
253  if ( pObjSh )
254  {
255  SetObjectShell( pObjSh );
256 
257  // set color table
258  const SvxColorListItem* pColItem = pObjSh->GetItem( SID_COLOR_TABLE );
259  if ( pColItem )
260  pXCol = pColItem->GetColorList();
261  }
262  SetPropertyList( static_cast<XPropertyList *> (pXCol.get()) );
263 
264  SetSwapGraphics();
265 
266  SetScaleUnit(MapUnit::Map100thMM);
267  SfxItemPool& rPool = GetItemPool();
268  rPool.SetDefaultMetric(MapUnit::Map100thMM);
269  SvxFrameDirectionItem aModeItem( SvxFrameDirection::Environment, EE_PARA_WRITINGDIR );
270  rPool.SetPoolDefaultItem( aModeItem );
271 
272  // #i33700#
273  // Set shadow distance defaults as PoolDefaultItems. Details see bug.
276 
277  // default for script spacing depends on locale, see SdDrawDocument ctor in sd
279  if (MsLangId::isKorean(eOfficeLanguage) || eOfficeLanguage == LANGUAGE_JAPANESE)
280  {
281  // secondary is edit engine pool
283  }
284 
285  rPool.FreezeIdRanges(); // the pool is also used directly
286 
287  SdrLayerAdmin& rAdmin = GetLayerAdmin();
288  rAdmin.NewLayer("vorne", sal_uInt8(SC_LAYER_FRONT));
289  rAdmin.NewLayer("hinten", sal_uInt8(SC_LAYER_BACK));
290  rAdmin.NewLayer("intern", sal_uInt8(SC_LAYER_INTERN));
291  rAdmin.NewLayer("Controls", sal_uInt8(SC_LAYER_CONTROLS));
292  rAdmin.SetControlLayerName("Controls");
293  rAdmin.NewLayer("hidden", sal_uInt8(SC_LAYER_HIDDEN));
294  // "Controls" is new - must also be created when loading
295 
296  // Set link for URL-Fields
297  ScModule* pScMod = SC_MOD();
298  Outliner& rOutliner = GetDrawOutliner();
299  rOutliner.SetCalcFieldValueHdl( LINK( pScMod, ScModule, CalcFieldValueHdl ) );
300 
301  Outliner& rHitOutliner = GetHitTestOutliner();
302  rHitOutliner.SetCalcFieldValueHdl( LINK( pScMod, ScModule, CalcFieldValueHdl ) );
303 
304  // set FontHeight pool defaults without changing static SdrEngineDefaults
305  SfxItemPool* pOutlinerPool = rOutliner.GetEditTextObjectPool();
306  if ( pOutlinerPool )
307  {
311  }
312  SfxItemPool* pHitOutlinerPool = rHitOutliner.GetEditTextObjectPool();
313  if ( pHitOutlinerPool )
314  {
315  pHitOutlinerPool->SetPoolDefaultItem(SvxFontHeightItem( 423, 100, EE_CHAR_FONTHEIGHT )); // 12Pt
316  pHitOutlinerPool->SetPoolDefaultItem(SvxFontHeightItem( 423, 100, EE_CHAR_FONTHEIGHT_CJK )); // 12Pt
317  pHitOutlinerPool->SetPoolDefaultItem(SvxFontHeightItem( 423, 100, EE_CHAR_FONTHEIGHT_CTL )); // 12Pt
318  }
319 
320  // initial undo mode as in Calc document
321  if( pDoc )
323 
324  // URL-Buttons have no handler anymore, all is done by themselves
325 
326  if( !nInst++ )
327  {
328  pF3d = new E3dObjFactory;
329  }
330 }
331 
333 {
334  Broadcast(SdrHint(SdrHintKind::ModelCleared));
335 
336  ClearModel(true);
337 
338  pUndoGroup.reset();
339  if( !--nInst )
340  {
341  delete pF3d;
342  pF3d = nullptr;
343  }
344 }
345 
347 {
348  if (!bHyphenatorSet)
349  {
350  css::uno::Reference< css::linguistic2::XHyphenator >
351  xHyphenator = LinguMgr::GetHyphenator();
352 
353  GetDrawOutliner().SetHyphenator( xHyphenator );
354  GetHitTestOutliner().SetHyphenator( xHyphenator );
355 
356  bHyphenatorSet = true;
357  }
358 }
359 
360 SdrPage* ScDrawLayer::AllocPage(bool bMasterPage)
361 {
362  return new ScDrawPage(*this, bMasterPage);
363 }
364 
366 {
367  bool bFound = false;
368 
369  sal_uInt16 nCount = GetPageCount();
370  for (sal_uInt16 i=0; i<nCount && !bFound; i++)
371  if (GetPage(i)->GetObjCount())
372  bFound = true;
373 
374  return bFound;
375 }
376 
378 {
379  // Allocated model (for clipboard etc) must not have a pointer
380  // to the original model's document, pass NULL as document:
381 
382  return new ScDrawLayer( nullptr, aName );
383 }
384 
386 {
387  if (bDrawIsInUndo)
388  return false; // not inserted
389 
390  ScDrawPage* pPage = static_cast<ScDrawPage*>(AllocPage( false ));
391  InsertPage(pPage, static_cast<sal_uInt16>(nTab));
392  if (bRecording)
393  AddCalcUndo(std::make_unique<SdrUndoNewPage>(*pPage));
394 
395  ResetTab(nTab, pDoc->GetTableCount()-1);
396  return true; // inserted
397 }
398 
400 {
401  if (bDrawIsInUndo)
402  return;
403 
404  Broadcast( ScTabDeletedHint( nTab ) );
405  if (bRecording)
406  {
407  SdrPage* pPage = GetPage(static_cast<sal_uInt16>(nTab));
408  AddCalcUndo(std::make_unique<SdrUndoDelPage>(*pPage)); // Undo-Action becomes the page owner
409  RemovePage( static_cast<sal_uInt16>(nTab) ); // just deliver, not deleting
410  }
411  else
412  DeletePage( static_cast<sal_uInt16>(nTab) ); // just get rid of it
413 
414  ResetTab(nTab, pDoc->GetTableCount()-1);
415 }
416 
417 void ScDrawLayer::ScRenamePage( SCTAB nTab, const OUString& rNewName )
418 {
419  ScDrawPage* pPage = static_cast<ScDrawPage*>( GetPage(static_cast<sal_uInt16>(nTab)) );
420  if (pPage)
421  pPage->SetName(rNewName);
422 }
423 
424 void ScDrawLayer::ScMovePage( sal_uInt16 nOldPos, sal_uInt16 nNewPos )
425 {
426  MovePage( nOldPos, nNewPos );
427  sal_uInt16 nMinPos = std::min(nOldPos, nNewPos);
428  ResetTab(nMinPos, pDoc->GetTableCount()-1);
429 }
430 
431 void ScDrawLayer::ScCopyPage( sal_uInt16 nOldPos, sal_uInt16 nNewPos )
432 {
433  if (bDrawIsInUndo)
434  return;
435 
436  SdrPage* pOldPage = GetPage(nOldPos);
437  SdrPage* pNewPage = GetPage(nNewPos);
438 
439  // Copying
440 
441  if (pOldPage && pNewPage)
442  {
443  SCTAB nOldTab = static_cast<SCTAB>(nOldPos);
444  SCTAB nNewTab = static_cast<SCTAB>(nNewPos);
445 
446  SdrObjListIter aIter( pOldPage, SdrIterMode::Flat );
447  SdrObject* pOldObject = aIter.Next();
448  while (pOldObject)
449  {
450  ScDrawObjData* pOldData = GetObjData(pOldObject);
451  if (pOldData)
452  {
453  pOldData->maStart.SetTab(nOldTab);
454  pOldData->maEnd.SetTab(nOldTab);
455  }
456 
457  // Clone to target SdrModel
458  SdrObject* pNewObject(pOldObject->CloneSdrObject(*this));
459  pNewObject->NbcMove(Size(0,0));
460  pNewPage->InsertObject( pNewObject );
461  ScDrawObjData* pNewData = GetObjData(pNewObject);
462  if (pNewData)
463  {
464  pNewData->maStart.SetTab(nNewTab);
465  pNewData->maEnd.SetTab(nNewTab);
466  }
467 
468  if (bRecording)
469  AddCalcUndo( std::make_unique<SdrUndoInsertObj>( *pNewObject ) );
470 
471  pOldObject = aIter.Next();
472  }
473  }
474 
475  ResetTab(static_cast<SCTAB>(nNewPos), pDoc->GetTableCount()-1);
476 }
477 
478 void ScDrawLayer::ResetTab( SCTAB nStart, SCTAB nEnd )
479 {
480  SCTAB nPageSize = static_cast<SCTAB>(GetPageCount());
481  if (nPageSize < 0)
482  // No drawing pages exist.
483  return;
484 
485  if (nEnd >= nPageSize)
486  // Avoid iterating beyond the last existing page.
487  nEnd = nPageSize - 1;
488 
489  for (SCTAB i = nStart; i <= nEnd; ++i)
490  {
491  SdrPage* pPage = GetPage(static_cast<sal_uInt16>(i));
492  if (!pPage)
493  continue;
494 
495  SdrObjListIter aIter(pPage, SdrIterMode::Flat);
496  for (SdrObject* pObj = aIter.Next(); pObj; pObj = aIter.Next())
497  {
498  ScDrawObjData* pData = GetObjData(pObj);
499  if (!pData)
500  continue;
501 
502  pData->maStart.SetTab(i);
503  pData->maEnd.SetTab(i);
504  }
505  }
506 }
507 
508 static bool IsInBlock( const ScAddress& rPos, SCCOL nCol1,SCROW nRow1, SCCOL nCol2,SCROW nRow2 )
509 {
510  return rPos.Col() >= nCol1 && rPos.Col() <= nCol2 &&
511  rPos.Row() >= nRow1 && rPos.Row() <= nRow2;
512 }
513 
514 void ScDrawLayer::MoveCells( SCTAB nTab, SCCOL nCol1,SCROW nRow1, SCCOL nCol2,SCROW nRow2,
515  SCCOL nDx,SCROW nDy, bool bUpdateNoteCaptionPos )
516 {
517  SdrPage* pPage = GetPage(static_cast<sal_uInt16>(nTab));
518  OSL_ENSURE(pPage,"Page not found");
519  if (!pPage)
520  return;
521 
522  bool bNegativePage = pDoc && pDoc->IsNegativePage( nTab );
523 
524  const size_t nCount = pPage->GetObjCount();
525  for ( size_t i = 0; i < nCount; ++i )
526  {
527  SdrObject* pObj = pPage->GetObj( i );
528  ScDrawObjData* pData = GetObjDataTab( pObj, nTab );
529  if( pData )
530  {
531  const ScAddress aOldStt = pData->maStart;
532  const ScAddress aOldEnd = pData->maEnd;
533  bool bChange = false;
534  if ( aOldStt.IsValid() && IsInBlock( aOldStt, nCol1,nRow1, nCol2,nRow2 ) )
535  {
536  pData->maStart.IncCol( nDx );
537  pData->maStart.IncRow( nDy );
538  bChange = true;
539  }
540  if ( aOldEnd.IsValid() && IsInBlock( aOldEnd, nCol1,nRow1, nCol2,nRow2 ) )
541  {
542  pData->maEnd.IncCol( nDx );
543  pData->maEnd.IncRow( nDy );
544  bChange = true;
545  }
546  if (bChange)
547  {
548  if ( dynamic_cast<const SdrRectObj*>( pObj) != nullptr && pData->maStart.IsValid() && pData->maEnd.IsValid() )
549  pData->maStart.PutInOrder( pData->maEnd );
550 
551  // Update also an untransformed anchor that's what we stored ( and still do ) to xml
552  ScDrawObjData* pNoRotatedAnchor = GetNonRotatedObjData( pObj );
553  if ( pNoRotatedAnchor )
554  {
555  pNoRotatedAnchor->maStart = pData->maStart;
556  pNoRotatedAnchor->maEnd = pData->maEnd;
557  }
558 
559  AddCalcUndo( std::make_unique<ScUndoObjData>( pObj, aOldStt, aOldEnd, pData->maStart, pData->maEnd ) );
560  RecalcPos( pObj, *pData, bNegativePage, bUpdateNoteCaptionPos );
561  }
562  }
563  }
564 }
565 
566 void ScDrawLayer::SetPageSize( sal_uInt16 nPageNo, const Size& rSize, bool bUpdateNoteCaptionPos )
567 {
568  SdrPage* pPage = GetPage(nPageNo);
569  if (!pPage)
570  return;
571 
572  if ( rSize != pPage->GetSize() )
573  {
574  pPage->SetSize( rSize );
575  Broadcast( ScTabSizeChangedHint( static_cast<SCTAB>(nPageNo) ) ); // SetWorkArea() on the views
576  }
577 
578  // Implement Detective lines (adjust to new heights / widths)
579  // even if size is still the same
580  // (individual rows/columns can have been changed))
581 
582  bool bNegativePage = pDoc && pDoc->IsNegativePage( static_cast<SCTAB>(nPageNo) );
583 
584  // Disable mass broadcasts from drawing objects' position changes.
585  bool bWasLocked = isLocked();
586  setLock(true);
587  const size_t nCount = pPage->GetObjCount();
588  for ( size_t i = 0; i < nCount; ++i )
589  {
590  SdrObject* pObj = pPage->GetObj( i );
591  ScDrawObjData* pData = GetObjDataTab( pObj, static_cast<SCTAB>(nPageNo) );
592  if( pData )
593  RecalcPos( pObj, *pData, bNegativePage, bUpdateNoteCaptionPos );
594  }
595  setLock(bWasLocked);
596 }
597 
598 namespace
599 {
600  //Can't have a zero width dimension
601  tools::Rectangle lcl_makeSafeRectangle(const tools::Rectangle &rNew)
602  {
603  tools::Rectangle aRect = rNew;
604  if (aRect.Bottom() == aRect.Top())
605  aRect.SetBottom( aRect.Top()+1 );
606  if (aRect.Right() == aRect.Left())
607  aRect.SetRight( aRect.Left()+1 );
608  return aRect;
609  }
610 
611  Point lcl_calcAvailableDiff(const ScDocument &rDoc, SCCOL nCol, SCROW nRow, SCTAB nTab, const Point &aWantedDiff)
612  {
613  Point aAvailableDiff(aWantedDiff);
614  tools::Long nHeight = static_cast<tools::Long>(rDoc.GetRowHeight( nRow, nTab ) * HMM_PER_TWIPS);
615  tools::Long nWidth = static_cast<tools::Long>(rDoc.GetColWidth( nCol, nTab ) * HMM_PER_TWIPS);
616  if (aAvailableDiff.Y() > nHeight)
617  aAvailableDiff.setY( nHeight );
618  if (aAvailableDiff.X() > nWidth)
619  aAvailableDiff.setX( nWidth );
620  return aAvailableDiff;
621  }
622 
623  tools::Rectangle lcl_UpdateCalcPoly(basegfx::B2DPolygon &rCalcPoly, int nWhichPoint, const Point &rPos)
624  {
625  rCalcPoly.setB2DPoint(nWhichPoint, basegfx::B2DPoint(rPos.X(), rPos.Y()));
626  basegfx::B2DRange aRange(basegfx::utils::getRange(rCalcPoly));
627  return tools::Rectangle(static_cast<tools::Long>(aRange.getMinX()), static_cast<tools::Long>(aRange.getMinY()),
628  static_cast<tools::Long>(aRange.getMaxX()), static_cast<tools::Long>(aRange.getMaxY()));
629  }
630 }
631 
633  bool bUseLogicRect, bool bNegativePage, bool bCanResize,
634  bool bHiddenAsZero)
635 {
636  tools::Rectangle aRect = bUseLogicRect ? pObj->GetLogicRect() : pObj->GetSnapRect();
637  SCCOL nCol1 = rData.maStart.Col();
638  SCROW nRow1 = rData.maStart.Row();
639  SCTAB nTab1 = rData.maStart.Tab();
640  SCCOL nCol2 = rData.maEnd.Col();
641  SCROW nRow2 = rData.maEnd.Row();
642  SCTAB nTab2 = rData.maEnd.Tab();
643  Point aPos(pDoc->GetColOffset(nCol1, nTab1, bHiddenAsZero),
644  pDoc->GetRowOffset(nRow1, nTab1, bHiddenAsZero));
645  aPos.setX(TwipsToHmm(aPos.X()));
646  aPos.setY(TwipsToHmm(aPos.Y()));
647  aPos += lcl_calcAvailableDiff(*pDoc, nCol1, nRow1, nTab1, rData.maStartOffset);
648 
649  // this sets the needed changed position (translation)
650  aRect.SetPos(aPos);
651 
652  if (bCanResize)
653  {
654  // all this stuff is additional stuff to evtl. not only translate the
655  // range (Rectangle), but also check for and evtl. do corrections for it's size
656  const tools::Rectangle aLastCellRect(rData.getLastCellRect());
657 
658  // If the row was hidden before, or we don't have a valid cell rect, calculate the
659  // new rect based on the end point.
660  // Also when the end point is set, we need to consider it.
661  if (rData.mbWasInHiddenRow || aLastCellRect.IsEmpty() || nRow1 != nRow2 || nCol1 != nCol2)
662  {
663  Point aEnd(pDoc->GetColOffset(nCol2, nTab2, bHiddenAsZero),
664  pDoc->GetRowOffset(nRow2, nTab2, bHiddenAsZero));
665  aEnd.setX(TwipsToHmm(aEnd.X()));
666  aEnd.setY(TwipsToHmm(aEnd.Y()));
667  aEnd += lcl_calcAvailableDiff(*pDoc, nCol2, nRow2, nTab2, rData.maEndOffset);
668 
669  aRect = tools::Rectangle(aPos, aEnd);
670  }
671  else if (!aLastCellRect.IsEmpty())
672  {
673  // We calculate based on the last cell rect to be able to scale the image
674  // as much as the cell was scaled.
675  // Still, we keep the image in its current cell (to keep start anchor == end anchor)
676  const tools::Rectangle aCurrentCellRect(GetCellRect(*GetDocument(), rData.maStart, true));
677  tools::Long nCurrentWidth(aCurrentCellRect.GetWidth());
678  tools::Long nCurrentHeight(aCurrentCellRect.GetHeight());
679  const tools::Long nLastWidth(aLastCellRect.GetWidth());
680  const tools::Long nLastHeight(aLastCellRect.GetHeight());
681 
682  // tdf#116931 Avoid and correct nifty numerical problems with the integer
683  // based and converted values (GetCellRect uses multiplies with HMM_PER_TWIPS)
684  if(nCurrentWidth + 1 == nLastWidth || nCurrentWidth == nLastWidth + 1)
685  {
686  nCurrentWidth = nLastWidth;
687  }
688 
689  if(nCurrentHeight + 1 == nLastHeight || nCurrentHeight == nLastHeight + 1)
690  {
691  nCurrentHeight = nLastHeight;
692  }
693 
694  // get initial ScalingFactors
695  double fWidthFactor(nCurrentWidth == nLastWidth || 0 == nLastWidth
696  ? 1.0
697  : static_cast<double>(nCurrentWidth) / static_cast<double>(nLastWidth));
698  double fHeightFactor(nCurrentHeight == nLastHeight || 0 == nLastHeight
699  ? 1.0
700  : static_cast<double>(nCurrentHeight) / static_cast<double>(nLastHeight));
701 
702  // check if we grow or shrink - and at all
703  const bool bIsGrowing(nCurrentWidth > nLastWidth || nCurrentHeight > nLastHeight);
704  const bool bIsShrinking(nCurrentWidth < nLastWidth || nCurrentHeight < nLastHeight);
705  const bool bIsSizeChanged(bIsGrowing || bIsShrinking);
706 
707  // handle AspectRatio, only needed if size does change
708  if(bIsSizeChanged && pObj->shouldKeepAspectRatio())
709  {
710  tools::Rectangle aRectIncludingOffset = aRect;
711  aRectIncludingOffset.setWidth(aRect.GetWidth() + rData.maStartOffset.X());
712  aRectIncludingOffset.setHeight(aRect.GetHeight() + rData.maStartOffset.Y());
713  tools::Long nWidth = aRectIncludingOffset.GetWidth();
714  assert(nWidth && "div-by-zero");
715  double fMaxWidthFactor = static_cast<double>(nCurrentWidth)
716  / static_cast<double>(nWidth);
717  tools::Long nHeight = aRectIncludingOffset.GetHeight();
718  assert(nHeight && "div-by-zero");
719  double fMaxHeightFactor = static_cast<double>(nCurrentHeight)
720  / static_cast<double>(nHeight);
721  double fMaxFactor = std::min(fMaxHeightFactor, fMaxWidthFactor);
722 
723  if(bIsGrowing) // cell is growing larger
724  {
725  // To actually grow the image, we need to take the max
726  fWidthFactor = std::max(fWidthFactor, fHeightFactor);
727  }
728  else if(bIsShrinking) // cell is growing smaller, take the min
729  {
730  fWidthFactor = std::min(fWidthFactor, fHeightFactor);
731  }
732 
733  // We don't want the image to become larger than the current cell
734  fWidthFactor = fHeightFactor = std::min(fWidthFactor, fMaxFactor);
735  }
736 
737  if(bIsSizeChanged)
738  {
739  // tdf#116931 re-organized scaling (if needed)
740  // Check if we need to scale at all. Always scale on growing.
741  bool bNeedToScale(bIsGrowing);
742 
743  if(!bNeedToScale && bIsShrinking)
744  {
745  // Check if original still fits into space. Do *not* forget to
746  // compare with evtl. numerically corrected aCurrentCellRect
747  const bool bFitsInX(aRect.Right() <= aCurrentCellRect.Left() + nCurrentWidth);
748  const bool bFitsInY(aRect.Bottom() <= aCurrentCellRect.Top() + nCurrentHeight);
749 
750  // If the image still fits in the smaller cell, don't resize it at all
751  bNeedToScale = (!bFitsInX || !bFitsInY);
752  }
753 
754  if(bNeedToScale)
755  {
756  // tdf#116931 use transformations now. Translation is already applied
757  // (see aRect.SetPos above), so only scale needs to be applied - relative
758  // to *new* CellRect (which is aCurrentCellRect).
759  // Prepare scale relative to top-left of aCurrentCellRect
760  basegfx::B2DHomMatrix aChange;
761 
762  aChange.translate(-aCurrentCellRect.getX(), -aCurrentCellRect.getY());
763  aChange.scale(fWidthFactor, fHeightFactor);
764  aChange.translate(aCurrentCellRect.getX(), aCurrentCellRect.getY());
765 
766  // create B2DRange and transform by prepared scale
768 
769  aNewRange.transform(aChange);
770 
771  // apply to aRect
772  aRect = tools::Rectangle(
773  basegfx::fround(aNewRange.getMinX()), basegfx::fround(aNewRange.getMinY()),
774  basegfx::fround(aNewRange.getMaxX()), basegfx::fround(aNewRange.getMaxY()));
775  }
776  }
777  }
778  }
779 
780  if (bNegativePage)
781  MirrorRectRTL(aRect);
782 
783  rData.setShapeRect(GetDocument(), lcl_makeSafeRectangle(aRect), pObj->IsVisible());
784 }
785 
786 void ScDrawLayer::RecalcPos( SdrObject* pObj, ScDrawObjData& rData, bool bNegativePage, bool bUpdateNoteCaptionPos )
787 {
788  OSL_ENSURE( pDoc, "ScDrawLayer::RecalcPos - missing document" );
789  if( !pDoc )
790  return;
791 
792  if (rData.meType == ScDrawObjData::CellNote)
793  {
794  OSL_ENSURE( rData.maStart.IsValid(), "ScDrawLayer::RecalcPos - invalid position for cell note" );
795  /* #i109372# On insert/remove rows/columns/cells: Updating the caption
796  position must not be done, if the cell containing the note has not
797  been moved yet in the document. The calling code now passes an
798  additional boolean stating if the cells are already moved. */
799  if( bUpdateNoteCaptionPos )
800  /* When inside an undo action, there may be pending note captions
801  where cell note is already deleted (thus document cannot find
802  the note object anymore). The caption will be deleted later
803  with drawing undo. */
804  if( ScPostIt* pNote = pDoc->GetNote( rData.maStart ) )
805  pNote->UpdateCaptionPos( rData.maStart );
806  return;
807  }
808 
809  bool bValid1 = rData.maStart.IsValid();
810  SCCOL nCol1 = rData.maStart.Col();
811  SCROW nRow1 = rData.maStart.Row();
812  SCTAB nTab1 = rData.maStart.Tab();
813  bool bValid2 = rData.maEnd.IsValid();
814  SCCOL nCol2 = rData.maEnd.Col();
815  SCROW nRow2 = rData.maEnd.Row();
816  SCTAB nTab2 = rData.maEnd.Tab();
817 
819  {
820  // Validation circle for detective.
821  rData.setShapeRect(GetDocument(), pObj->GetLogicRect());
822 
823  Point aPos( pDoc->GetColOffset( nCol1, nTab1 ), pDoc->GetRowOffset( nRow1, nTab1 ) );
824  aPos.setX(TwipsToHmm( aPos.X() ));
825  aPos.setY(TwipsToHmm( aPos.Y() ));
826 
827  // Calculations and values as in detfunc.cxx
828 
829  Size aSize( TwipsToHmm( pDoc->GetColWidth( nCol1, nTab1) ),
830  TwipsToHmm( pDoc->GetRowHeight( nRow1, nTab1) ) );
831  tools::Rectangle aRect( aPos, aSize );
832  aRect.AdjustLeft( -250 );
833  aRect.AdjustRight(250 );
834  aRect.AdjustTop( -70 );
835  aRect.AdjustBottom(70 );
836  if ( bNegativePage )
837  MirrorRectRTL( aRect );
838 
839  if ( pObj->GetLogicRect() != aRect )
840  {
841  if (bRecording)
842  AddCalcUndo( std::make_unique<SdrUndoGeoObj>( *pObj ) );
843  rData.setShapeRect(GetDocument(), lcl_makeSafeRectangle(aRect));
844  pObj->SetLogicRect(rData.getShapeRect());
845  }
846  }
847  else if (rData.meType == ScDrawObjData::DetectiveArrow)
848  {
849  rData.setShapeRect(GetDocument(), pObj->GetLogicRect());
850  basegfx::B2DPolygon aCalcPoly;
851  Point aOrigStartPos(pObj->GetPoint(0));
852  Point aOrigEndPos(pObj->GetPoint(1));
853  aCalcPoly.append(basegfx::B2DPoint(aOrigStartPos.X(), aOrigStartPos.Y()));
854  aCalcPoly.append(basegfx::B2DPoint(aOrigEndPos.X(), aOrigEndPos.Y()));
855  //TODO: do not create multiple Undos for one object (last one can be omitted then)
856 
857  SCCOL nLastCol;
858  SCROW nLastRow;
859  if( bValid1 )
860  {
861  Point aPos( pDoc->GetColOffset( nCol1, nTab1 ), pDoc->GetRowOffset( nRow1, nTab1 ) );
862  if (!pDoc->ColHidden(nCol1, nTab1, nullptr, &nLastCol))
863  aPos.AdjustX(pDoc->GetColWidth( nCol1, nTab1 ) / 4 );
864  if (!pDoc->RowHidden(nRow1, nTab1, nullptr, &nLastRow))
865  aPos.AdjustY(pDoc->GetRowHeight( nRow1, nTab1 ) / 2 );
866  aPos.setX(TwipsToHmm( aPos.X() ));
867  aPos.setY(TwipsToHmm( aPos.Y() ));
868  Point aStartPos = aPos;
869  if ( bNegativePage )
870  aStartPos.setX( -aStartPos.X() ); // don't modify aPos - used below
871  if ( pObj->GetPoint( 0 ) != aStartPos )
872  {
873  if (bRecording)
874  AddCalcUndo( std::make_unique<SdrUndoGeoObj>( *pObj ) );
875 
876  rData.setShapeRect(GetDocument(), lcl_UpdateCalcPoly(aCalcPoly, 0, aStartPos));
877  pObj->SetPoint( aStartPos, 0 );
878  }
879 
880  if( !bValid2 )
881  {
882  Point aEndPos( aPos.X() + DET_ARROW_OFFSET, aPos.Y() - DET_ARROW_OFFSET );
883  if (aEndPos.Y() < 0)
884  aEndPos.AdjustY(2 * DET_ARROW_OFFSET);
885  if ( bNegativePage )
886  aEndPos.setX( -aEndPos.X() );
887  if ( pObj->GetPoint( 1 ) != aEndPos )
888  {
889  if (bRecording)
890  AddCalcUndo( std::make_unique<SdrUndoGeoObj>( *pObj ) );
891 
892  rData.setShapeRect(GetDocument(), lcl_UpdateCalcPoly(aCalcPoly, 1, aEndPos));
893  pObj->SetPoint( aEndPos, 1 );
894  }
895  }
896  }
897  if( bValid2 )
898  {
899  Point aPos( pDoc->GetColOffset( nCol2, nTab2 ), pDoc->GetRowOffset( nRow2, nTab2 ) );
900  if (!pDoc->ColHidden(nCol2, nTab2, nullptr, &nLastCol))
901  aPos.AdjustX(pDoc->GetColWidth( nCol2, nTab2 ) / 4 );
902  if (!pDoc->RowHidden(nRow2, nTab2, nullptr, &nLastRow))
903  aPos.AdjustY(pDoc->GetRowHeight( nRow2, nTab2 ) / 2 );
904  aPos.setX(TwipsToHmm( aPos.X() ));
905  aPos.setY(TwipsToHmm( aPos.Y() ));
906  Point aEndPos = aPos;
907  if ( bNegativePage )
908  aEndPos.setX( -aEndPos.X() ); // don't modify aPos - used below
909  if ( pObj->GetPoint( 1 ) != aEndPos )
910  {
911  if (bRecording)
912  AddCalcUndo( std::make_unique<SdrUndoGeoObj>( *pObj ) );
913 
914  rData.setShapeRect(GetDocument(), lcl_UpdateCalcPoly(aCalcPoly, 1, aEndPos));
915  pObj->SetPoint( aEndPos, 1 );
916  }
917 
918  if( !bValid1 )
919  {
920  Point aStartPos( aPos.X() - DET_ARROW_OFFSET, aPos.Y() - DET_ARROW_OFFSET );
921  if (aStartPos.X() < 0)
922  aStartPos.AdjustX(2 * DET_ARROW_OFFSET);
923  if (aStartPos.Y() < 0)
924  aStartPos.AdjustY(2 * DET_ARROW_OFFSET);
925  if ( bNegativePage )
926  aStartPos.setX( -aStartPos.X() );
927  if ( pObj->GetPoint( 0 ) != aStartPos )
928  {
929  if (bRecording)
930  AddCalcUndo( std::make_unique<SdrUndoGeoObj>( *pObj ) );
931 
932  rData.setShapeRect(GetDocument(), lcl_UpdateCalcPoly(aCalcPoly, 0, aStartPos));
933  pObj->SetPoint( aStartPos, 0 );
934  }
935  }
936  }
937  }
938  else
939  {
940  // Prevent multiple broadcasts during the series of changes.
941  bool bWasLocked = pObj->getSdrModelFromSdrObject().isLocked();
942  pObj->getSdrModelFromSdrObject().setLock(true);
943  bool bCanResize = bValid2 && !pObj->IsResizeProtect() && rData.mbResizeWithCell;
944 
945  //First time positioning, must be able to at least move it
946  ScDrawObjData& rNoRotatedAnchor = *GetNonRotatedObjData( pObj, true );
947  if (rData.getShapeRect().IsEmpty())
948  {
949  // Every shape it is saved with a negative offset relative to cell
950  ScAnchorType aAnchorType = ScDrawLayer::GetAnchorType(*pObj);
951  if (aAnchorType == SCA_CELL || aAnchorType == SCA_CELL_RESIZE)
952  {
953  // tdf#117145 All that TR*etBaseGeometry does here is to translate
954  // the existing transformation. This can simply be applied to the existing
955  // matrix, no need to decompose as done before. Also doing this from
956  // Calc did not change metrics in any way.
957  const tools::Rectangle aRect(pDoc->GetMMRect(nCol1, nRow1, nCol1 , nRow1, nTab1));
958  const Point aPoint(bNegativePage ? aRect.Right() : aRect.Left(), aRect.Top());
959  basegfx::B2DPolyPolygon aPolyPolygon;
960  basegfx::B2DHomMatrix aOriginalMatrix;
961 
962  pObj->TRGetBaseGeometry(aOriginalMatrix, aPolyPolygon);
963  aOriginalMatrix.translate(aPoint.X(), aPoint.Y());
964  pObj->TRSetBaseGeometry(aOriginalMatrix, aPolyPolygon);
965  }
966 
967  // It's confusing ( but blame that we persist the anchor in terms of unrotated shape )
968  // that the initial anchor we get here is in terms of an unrotated shape ( if the shape is rotated )
969  // we need to save the old anchor ( for persisting ) and also track any resize or repositions that happen.
970 
971  // This is an evil hack, having an anchor that is one minute in terms of untransformed object and then later
972  // in terms of the transformed object is not ideal, similarly having 2 anchors per object is wasteful, can't
973  // see another way out of this at the moment though.
974  rNoRotatedAnchor.maStart = rData.maStart;
975  rNoRotatedAnchor.maEnd = rData.maEnd;
976  rNoRotatedAnchor.maStartOffset = rData.maStartOffset;
977  rNoRotatedAnchor.maEndOffset = rData.maEndOffset;
978 
979  // get bounding rectangle of shape ( include any hidden row/columns ), <sigh> we need to do this
980  // because if the shape is rotated the anchor from xml is in terms of the unrotated shape, if
981  // the shape is hidden ( by the rows that contain the shape being hidden ) then our hack of
982  // trying to infer the 'real' e.g. rotated anchor from the SnapRect will fail (because the LogicRect will
983  // not have the correct position or size). The only way we can possible do this is to first get the
984  // 'unrotated' shape dimensions from the persisted Anchor (from xml) and then 'create' an Anchor from the
985  // associated rotated shape (note: we do this by actually setting the LogicRect for the shape temporarily to the
986  // *full* size then grabbing the SnapRect (which gives the transformed rotated dimensions), it would be
987  // wonderful if we could do this mathematically without having to temporarily tweak the object... otoh this way
988  // is guaranteed to get consistent results)
989  ResizeLastRectFromAnchor( pObj, rData, true, bNegativePage, bCanResize, false );
990  // aFullRect contains the unrotated size and position of the shape (regardless of any hidden row/columns)
991  tools::Rectangle aFullRect = rData.getShapeRect();
992 
993  // get current size and position from the anchor for use later
994  ResizeLastRectFromAnchor( pObj, rNoRotatedAnchor, true, bNegativePage, bCanResize );
995 
996  // resize/position the shape to *full* size e.g. how it would be ( if no hidden rows/cols affected things )
997  pObj->SetLogicRect(aFullRect);
998 
999  // Ok, here is more nastiness, from xml the Anchor is in terms of the LogicRect which is the
1000  // untransformed unrotated shape, here we swap out that initial anchor and from now on use
1001  // an Anchor based on the SnapRect ( which is what you see on the screen )
1002  const tools::Rectangle aObjRect(pObj->GetSnapRect());
1004  aObjRect,
1005  rData,
1006  *pDoc,
1007  nTab1,
1008  false);
1009 
1010  // reset shape to true 'maybe affected by hidden rows/cols' size calculated previously
1011  pObj->SetLogicRect(rNoRotatedAnchor.getShapeRect());
1012  }
1013 
1014  // update anchor with snap rect
1015  ResizeLastRectFromAnchor( pObj, rData, false, bNegativePage, bCanResize );
1016 
1017  if( bCanResize )
1018  {
1019  tools::Rectangle aNew = rData.getShapeRect();
1020 
1021  if ( pObj->GetSnapRect() != aNew )
1022  {
1023  tools::Rectangle aOld(pObj->GetSnapRect());
1024 
1025  if (bRecording)
1026  AddCalcUndo( std::make_unique<SdrUndoGeoObj>( *pObj ) );
1027  tools::Long nOldWidth = aOld.GetWidth();
1028  tools::Long nOldHeight = aOld.GetHeight();
1029  if (pObj->IsPolyObj() && nOldWidth && nOldHeight)
1030  {
1031  // Polyline objects need special treatment.
1032  Size aSizeMove(aNew.Left()-aOld.Left(), aNew.Top()-aOld.Top());
1033  pObj->NbcMove(aSizeMove);
1034 
1035  double fXFrac = static_cast<double>(aNew.GetWidth()) / static_cast<double>(nOldWidth);
1036  double fYFrac = static_cast<double>(aNew.GetHeight()) / static_cast<double>(nOldHeight);
1037  pObj->NbcResize(aNew.TopLeft(), Fraction(fXFrac), Fraction(fYFrac));
1038  }
1039  // order of these lines is important, modify rData.maLastRect carefully it is used as both
1040  // a value and a flag for initialisation
1041  rData.setShapeRect(GetDocument(), lcl_makeSafeRectangle(rData.getShapeRect()), pObj->IsVisible());
1042  if (pObj->GetObjIdentifier() == OBJ_CUSTOMSHAPE)
1043  pObj->AdjustToMaxRect(rData.getShapeRect());
1044  else
1045  pObj->SetSnapRect(rData.getShapeRect());
1046  // update 'unrotated anchor' it's the anchor we persist, it must be kept in sync
1047  // with the normal Anchor
1048  ResizeLastRectFromAnchor( pObj, rNoRotatedAnchor, true, bNegativePage, bCanResize );
1049  }
1050  }
1051  else
1052  {
1053  Point aPos( rData.getShapeRect().getX(), rData.getShapeRect().getY() );
1054  if ( pObj->GetRelativePos() != aPos )
1055  {
1056  if (bRecording)
1057  AddCalcUndo( std::make_unique<SdrUndoGeoObj>( *pObj ) );
1058  pObj->SetRelativePos( aPos );
1059  }
1060  }
1061  /*
1062  * If we were not allowed resize the object, then the end cell anchor
1063  * is possibly incorrect now, and if the object has no end-cell (e.g.
1064  * missing in original .xml) we are also forced to generate one
1065  */
1066  bool bEndAnchorIsBad = !bValid2 || pObj->IsResizeProtect();
1067  if (bEndAnchorIsBad)
1068  {
1069  // update 'rotated' anchor
1070  ScDrawLayer::UpdateCellAnchorFromPositionEnd(*pObj, rData, *pDoc, nTab1, false);
1071  // update 'unrotated' anchor
1072  ScDrawLayer::UpdateCellAnchorFromPositionEnd(*pObj, rNoRotatedAnchor, *pDoc, nTab1 );
1073  }
1074 
1075  // End prevent multiple broadcasts during the series of changes.
1076  pObj->getSdrModelFromSdrObject().setLock(bWasLocked);
1077  if (!bWasLocked)
1078  pObj->BroadcastObjectChange();
1079  }
1080 }
1081 
1082 bool ScDrawLayer::GetPrintArea( ScRange& rRange, bool bSetHor, bool bSetVer ) const
1083 {
1084  OSL_ENSURE( pDoc, "ScDrawLayer::GetPrintArea without document" );
1085  if ( !pDoc )
1086  return false;
1087 
1088  SCTAB nTab = rRange.aStart.Tab();
1089  OSL_ENSURE( rRange.aEnd.Tab() == nTab, "GetPrintArea: Tab differ" );
1090 
1091  bool bNegativePage = pDoc->IsNegativePage( nTab );
1092 
1093  bool bAny = false;
1094  tools::Long nEndX = 0;
1095  tools::Long nEndY = 0;
1096  tools::Long nStartX = LONG_MAX;
1097  tools::Long nStartY = LONG_MAX;
1098 
1099  // Calculate borders
1100 
1101  if (!bSetHor)
1102  {
1103  nStartX = 0;
1104  SCCOL nStartCol = rRange.aStart.Col();
1105  SCCOL i;
1106  for (i=0; i<nStartCol; i++)
1107  nStartX +=pDoc->GetColWidth(i,nTab);
1108  nEndX = nStartX;
1109  SCCOL nEndCol = rRange.aEnd.Col();
1110  for (i=nStartCol; i<=nEndCol; i++)
1111  nEndX += pDoc->GetColWidth(i,nTab);
1112  nStartX = TwipsToHmm( nStartX );
1113  nEndX = TwipsToHmm( nEndX );
1114  }
1115  if (!bSetVer)
1116  {
1117  nStartY = pDoc->GetRowHeight( 0, rRange.aStart.Row()-1, nTab);
1118  nEndY = nStartY + pDoc->GetRowHeight( rRange.aStart.Row(),
1119  rRange.aEnd.Row(), nTab);
1120  nStartY = TwipsToHmm( nStartY );
1121  nEndY = TwipsToHmm( nEndY );
1122  }
1123 
1124  if ( bNegativePage )
1125  {
1126  nStartX = -nStartX; // positions are negative, swap start/end so the same comparisons work
1127  nEndX = -nEndX;
1128  ::std::swap( nStartX, nEndX );
1129  }
1130 
1131  const SdrPage* pPage = GetPage(static_cast<sal_uInt16>(nTab));
1132  OSL_ENSURE(pPage,"Page not found");
1133  if (pPage)
1134  {
1135  SdrObjListIter aIter( pPage, SdrIterMode::Flat );
1136  SdrObject* pObject = aIter.Next();
1137  while (pObject)
1138  {
1139  //TODO: test Flags (hidden?)
1140 
1141  tools::Rectangle aObjRect = pObject->GetCurrentBoundRect();
1142  bool bFit = true;
1143  if ( !bSetHor && ( aObjRect.Right() < nStartX || aObjRect.Left() > nEndX ) )
1144  bFit = false;
1145  if ( !bSetVer && ( aObjRect.Bottom() < nStartY || aObjRect.Top() > nEndY ) )
1146  bFit = false;
1147  // #i104716# don't include hidden note objects
1148  if ( bFit && pObject->GetLayer() != SC_LAYER_HIDDEN )
1149  {
1150  if (bSetHor)
1151  {
1152  if (aObjRect.Left() < nStartX) nStartX = aObjRect.Left();
1153  if (aObjRect.Right() > nEndX) nEndX = aObjRect.Right();
1154  }
1155  if (bSetVer)
1156  {
1157  if (aObjRect.Top() < nStartY) nStartY = aObjRect.Top();
1158  if (aObjRect.Bottom() > nEndY) nEndY = aObjRect.Bottom();
1159  }
1160  bAny = true;
1161  }
1162 
1163  pObject = aIter.Next();
1164  }
1165  }
1166 
1167  if ( bNegativePage )
1168  {
1169  nStartX = -nStartX; // reverse transformation, so the same cell address calculation works
1170  nEndX = -nEndX;
1171  ::std::swap( nStartX, nEndX );
1172  }
1173 
1174  if (bAny)
1175  {
1176  OSL_ENSURE( nStartX<=nEndX && nStartY<=nEndY, "Start/End wrong in ScDrawLayer::GetPrintArea" );
1177 
1178  if (bSetHor)
1179  {
1180  nStartX = HmmToTwips( nStartX );
1181  nEndX = HmmToTwips( nEndX );
1182  tools::Long nWidth;
1183 
1184  nWidth = 0;
1185  rRange.aStart.SetCol( 0 );
1186  if (nWidth <= nStartX)
1187  {
1188  for (SCCOL nCol : pDoc->GetColumnsRange(nTab, 0, MAXCOL))
1189  {
1190  nWidth += pDoc->GetColWidth(nCol,nTab);
1191  if (nWidth > nStartX)
1192  {
1193  rRange.aStart.SetCol( nCol );
1194  break;
1195  }
1196  }
1197  }
1198 
1199  nWidth = 0;
1200  rRange.aEnd.SetCol( 0 );
1201  if (nWidth <= nEndX)
1202  {
1203  for (SCCOL nCol : pDoc->GetColumnsRange(nTab, 0, MAXCOL)) //TODO: start at Start
1204  {
1205  nWidth += pDoc->GetColWidth(nCol,nTab);
1206  if (nWidth > nEndX)
1207  {
1208  rRange.aEnd.SetCol( nCol );
1209  break;
1210  }
1211  }
1212  }
1213  }
1214 
1215  if (bSetVer)
1216  {
1217  nStartY = HmmToTwips( nStartY );
1218  nEndY = HmmToTwips( nEndY );
1219  SCROW nRow = pDoc->GetRowForHeight( nTab, nStartY);
1220  rRange.aStart.SetRow( nRow>0 ? (nRow-1) : 0);
1221  nRow = pDoc->GetRowForHeight( nTab, nEndY);
1222  rRange.aEnd.SetRow( nRow == MAXROW ? MAXROW :
1223  (nRow>0 ? (nRow-1) : 0));
1224  }
1225  }
1226  else
1227  {
1228  if (bSetHor)
1229  {
1230  rRange.aStart.SetCol(0);
1231  rRange.aEnd.SetCol(0);
1232  }
1233  if (bSetVer)
1234  {
1235  rRange.aStart.SetRow(0);
1236  rRange.aEnd.SetRow(0);
1237  }
1238  }
1239  return bAny;
1240 }
1241 
1242 void ScDrawLayer::AddCalcUndo( std::unique_ptr<SdrUndoAction> pUndo )
1243 {
1244  if (bRecording)
1245  {
1246  if (!pUndoGroup)
1247  pUndoGroup.reset(new SdrUndoGroup(*this));
1248 
1249  pUndoGroup->AddAction( std::move(pUndo) );
1250  }
1251 }
1252 
1253 void ScDrawLayer::BeginCalcUndo(bool bDisableTextEditUsesCommonUndoManager)
1254 {
1255  SetDisableTextEditUsesCommonUndoManager(bDisableTextEditUsesCommonUndoManager);
1256  pUndoGroup.reset();
1257  bRecording = true;
1258 }
1259 
1260 std::unique_ptr<SdrUndoGroup> ScDrawLayer::GetCalcUndo()
1261 {
1262  std::unique_ptr<SdrUndoGroup> pRet = std::move(pUndoGroup);
1263  bRecording = false;
1265  return pRet;
1266 }
1267 
1268 void ScDrawLayer::MoveArea( SCTAB nTab, SCCOL nCol1,SCROW nRow1, SCCOL nCol2,SCROW nRow2,
1269  SCCOL nDx,SCROW nDy, bool bInsDel, bool bUpdateNoteCaptionPos )
1270 {
1271  OSL_ENSURE( pDoc, "ScDrawLayer::MoveArea without document" );
1272  if ( !pDoc )
1273  return;
1274 
1275  if (!bAdjustEnabled)
1276  return;
1277 
1278  bool bNegativePage = pDoc->IsNegativePage( nTab );
1279 
1280  tools::Rectangle aRect = pDoc->GetMMRect( nCol1, nRow1, nCol2, nRow2, nTab );
1281  lcl_ReverseTwipsToMM( aRect );
1282  //TODO: use twips directly?
1283 
1284  Point aMove;
1285 
1286  if (nDx > 0)
1287  for (SCCOL s=0; s<nDx; s++)
1288  aMove.AdjustX(pDoc->GetColWidth(s+nCol1,nTab) );
1289  else
1290  for (SCCOL s=-1; s>=nDx; s--)
1291  aMove.AdjustX( -(pDoc->GetColWidth(s+nCol1,nTab)) );
1292  if (nDy > 0)
1293  aMove.AdjustY(pDoc->GetRowHeight( nRow1, nRow1+nDy-1, nTab) );
1294  else
1295  aMove.AdjustY( -sal_Int16(pDoc->GetRowHeight( nRow1+nDy, nRow1-1, nTab)) );
1296 
1297  if ( bNegativePage )
1298  aMove.setX( -aMove.X() );
1299 
1300  Point aTopLeft = aRect.TopLeft(); // Beginning when zoomed out
1301  if (bInsDel)
1302  {
1303  if ( aMove.X() != 0 && nDx < 0 ) // nDx counts cells, sign is independent of RTL
1304  aTopLeft.AdjustX(aMove.X() );
1305  if ( aMove.Y() < 0 )
1306  aTopLeft.AdjustY(aMove.Y() );
1307  }
1308 
1309  // Detectiv arrows: Adjust cell position
1310 
1311  MoveCells( nTab, nCol1,nRow1, nCol2,nRow2, nDx,nDy, bUpdateNoteCaptionPos );
1312 }
1313 
1314 bool ScDrawLayer::HasObjectsInRows( SCTAB nTab, SCROW nStartRow, SCROW nEndRow )
1315 {
1316  OSL_ENSURE( pDoc, "ScDrawLayer::HasObjectsInRows without document" );
1317  if ( !pDoc )
1318  return false;
1319 
1320  SdrPage* pPage = GetPage(static_cast<sal_uInt16>(nTab));
1321  OSL_ENSURE(pPage,"Page not found");
1322  if (!pPage)
1323  return false;
1324 
1325  // for an empty page, there's no need to calculate the row heights
1326  if (!pPage->GetObjCount())
1327  return false;
1328 
1329  tools::Rectangle aTestRect;
1330 
1331  aTestRect.AdjustTop(pDoc->GetRowHeight( 0, nStartRow-1, nTab) );
1332 
1333  if (nEndRow==MAXROW)
1334  aTestRect.SetBottom( MAXMM );
1335  else
1336  {
1337  aTestRect.SetBottom( aTestRect.Top() );
1338  aTestRect.AdjustBottom(pDoc->GetRowHeight( nStartRow, nEndRow, nTab) );
1339  aTestRect.SetBottom(TwipsToHmm( aTestRect.Bottom() ));
1340  }
1341 
1342  aTestRect.SetTop(TwipsToHmm( aTestRect.Top() ));
1343 
1344  aTestRect.SetLeft( 0 );
1345  aTestRect.SetRight( MAXMM );
1346 
1347  bool bNegativePage = pDoc->IsNegativePage( nTab );
1348  if ( bNegativePage )
1349  MirrorRectRTL( aTestRect );
1350 
1351  bool bFound = false;
1352 
1353  tools::Rectangle aObjRect;
1354  SdrObjListIter aIter( pPage );
1355  SdrObject* pObject = aIter.Next();
1356  while ( pObject && !bFound )
1357  {
1358  aObjRect = pObject->GetSnapRect(); //TODO: GetLogicRect ?
1359  if (aTestRect.IsInside(aObjRect.TopLeft()) || aTestRect.IsInside(aObjRect.BottomLeft()))
1360  bFound = true;
1361 
1362  pObject = aIter.Next();
1363  }
1364 
1365  return bFound;
1366 }
1367 
1369  SCCOL nCol2,SCROW nRow2, bool bAnchored )
1370 {
1371  OSL_ENSURE( pDoc, "ScDrawLayer::DeleteObjectsInArea without document" );
1372  if ( !pDoc )
1373  return;
1374 
1375  SdrPage* pPage = GetPage(static_cast<sal_uInt16>(nTab));
1376  OSL_ENSURE(pPage,"Page ?");
1377  if (!pPage)
1378  return;
1379 
1380  pPage->RecalcObjOrdNums();
1381 
1382  const size_t nObjCount = pPage->GetObjCount();
1383  if (!nObjCount)
1384  return;
1385 
1386  size_t nDelCount = 0;
1387  tools::Rectangle aDelRect = pDoc->GetMMRect( nCol1, nRow1, nCol2, nRow2, nTab );
1388 
1389  std::unique_ptr<SdrObject*[]> ppObj(new SdrObject*[nObjCount]);
1390 
1391  SdrObjListIter aIter( pPage, SdrIterMode::Flat );
1392  SdrObject* pObject = aIter.Next();
1393  while (pObject)
1394  {
1395  // do not delete note caption, they are always handled by the cell note
1396  // TODO: detective objects are still deleted, is this desired?
1397  if (!IsNoteCaption( pObject ))
1398  {
1399  tools::Rectangle aObjRect = pObject->GetCurrentBoundRect();
1400  if (aDelRect.IsInside(aObjRect))
1401  {
1402  if (bAnchored)
1403  {
1404  ScAnchorType aAnchorType = ScDrawLayer::GetAnchorType(*pObject);
1405  if(aAnchorType == SCA_CELL || aAnchorType == SCA_CELL_RESIZE)
1406  ppObj[nDelCount++] = pObject;
1407  }
1408  else
1409  ppObj[nDelCount++] = pObject;
1410  }
1411  }
1412 
1413  pObject = aIter.Next();
1414  }
1415 
1416  if (bRecording)
1417  for (size_t i=1; i<=nDelCount; ++i)
1418  AddCalcUndo( std::make_unique<SdrUndoRemoveObj>( *ppObj[nDelCount-i] ) );
1419 
1420  for (size_t i=1; i<=nDelCount; ++i)
1421  pPage->RemoveObject( ppObj[nDelCount-i]->GetOrdNum() );
1422 }
1423 
1425 {
1426  OSL_ENSURE( pDoc, "ScDrawLayer::DeleteObjectsInSelection without document" );
1427  if ( !pDoc )
1428  return;
1429 
1430  if ( !rMark.IsMultiMarked() )
1431  return;
1432 
1433  ScRange aMarkRange;
1434  rMark.GetMultiMarkArea( aMarkRange );
1435 
1436  SCTAB nTabCount = pDoc->GetTableCount();
1437  for (const SCTAB nTab : rMark)
1438  {
1439  if (nTab >= nTabCount)
1440  break;
1441 
1442  SdrPage* pPage = GetPage(static_cast<sal_uInt16>(nTab));
1443  if (pPage)
1444  {
1445  pPage->RecalcObjOrdNums();
1446  const size_t nObjCount = pPage->GetObjCount();
1447  if (nObjCount)
1448  {
1449  size_t nDelCount = 0;
1450  // Rectangle around the whole selection
1451  tools::Rectangle aMarkBound = pDoc->GetMMRect(
1452  aMarkRange.aStart.Col(), aMarkRange.aStart.Row(),
1453  aMarkRange.aEnd.Col(), aMarkRange.aEnd.Row(), nTab );
1454 
1455  std::unique_ptr<SdrObject*[]> ppObj(new SdrObject*[nObjCount]);
1456 
1457  SdrObjListIter aIter( pPage, SdrIterMode::Flat );
1458  SdrObject* pObject = aIter.Next();
1459  while (pObject)
1460  {
1461  // do not delete note caption, they are always handled by the cell note
1462  // TODO: detective objects are still deleted, is this desired?
1463  if (!IsNoteCaption( pObject ))
1464  {
1465  tools::Rectangle aObjRect = pObject->GetCurrentBoundRect();
1466  ScRange aRange = pDoc->GetRange(nTab, aObjRect);
1467  bool bObjectInMarkArea =
1468  aMarkBound.IsInside(aObjRect) && rMark.IsAllMarked(aRange);
1469  const ScDrawObjData* pObjData = ScDrawLayer::GetObjData(pObject);
1470  ScAnchorType aAnchorType = ScDrawLayer::GetAnchorType(*pObject);
1471  bool bObjectAnchoredToMarkedCell
1472  = ((aAnchorType == SCA_CELL || aAnchorType == SCA_CELL_RESIZE)
1473  && pObjData && rMark.IsCellMarked(pObjData->maStart.Col(),
1474  pObjData->maStart.Row()));
1475  if (bObjectInMarkArea || bObjectAnchoredToMarkedCell)
1476  {
1477  ppObj[nDelCount++] = pObject;
1478  }
1479  }
1480 
1481  pObject = aIter.Next();
1482  }
1483 
1484  // Delete objects (backwards)
1485 
1486  if (bRecording)
1487  for (size_t i=1; i<=nDelCount; ++i)
1488  AddCalcUndo( std::make_unique<SdrUndoRemoveObj>( *ppObj[nDelCount-i] ) );
1489 
1490  for (size_t i=1; i<=nDelCount; ++i)
1491  pPage->RemoveObject( ppObj[nDelCount-i]->GetOrdNum() );
1492  }
1493  }
1494  else
1495  {
1496  OSL_FAIL("pPage?");
1497  }
1498  }
1499 }
1500 
1501 void ScDrawLayer::CopyToClip( ScDocument* pClipDoc, SCTAB nTab, const tools::Rectangle& rRange )
1502 {
1503  // copy everything in the specified range into the same page (sheet) in the clipboard doc
1504 
1505  SdrPage* pSrcPage = GetPage(static_cast<sal_uInt16>(nTab));
1506  if (!pSrcPage)
1507  return;
1508 
1509  ScDrawLayer* pDestModel = nullptr;
1510  SdrPage* pDestPage = nullptr;
1511 
1512  SdrObjListIter aIter( pSrcPage, SdrIterMode::Flat );
1513  SdrObject* pOldObject = aIter.Next();
1514  while (pOldObject)
1515  {
1516  tools::Rectangle aObjRect = pOldObject->GetCurrentBoundRect();
1517 
1518  bool bObjectInArea = rRange.IsInside(aObjRect);
1519  const ScDrawObjData* pObjData = ScDrawLayer::GetObjData(pOldObject);
1520  if (pObjData)
1521  {
1522  ScRange aClipRange = lcl_getClipRangeFromClipDoc(pClipDoc, nTab);
1523  bObjectInArea = bObjectInArea || aClipRange.In(pObjData->maStart);
1524  }
1525 
1526  // do not copy internal objects (detective) and note captions
1527  if (bObjectInArea && pOldObject->GetLayer() != SC_LAYER_INTERN
1528  && !IsNoteCaption(pOldObject))
1529  {
1530  if ( !pDestModel )
1531  {
1532  pDestModel = pClipDoc->GetDrawLayer(); // does the document already have a drawing layer?
1533  if ( !pDestModel )
1534  {
1535  // allocate drawing layer in clipboard document only if there are objects to copy
1536 
1537  pClipDoc->InitDrawLayer(); //TODO: create contiguous pages
1538  pDestModel = pClipDoc->GetDrawLayer();
1539  }
1540  if (pDestModel)
1541  pDestPage = pDestModel->GetPage( static_cast<sal_uInt16>(nTab) );
1542  }
1543 
1544  OSL_ENSURE( pDestPage, "no page" );
1545  if (pDestPage)
1546  {
1547  // Clone to target SdrModel
1548  SdrObject* pNewObject(pOldObject->CloneSdrObject(*pDestModel));
1549 
1550  uno::Reference< chart2::XChartDocument > xOldChart( ScChartHelper::GetChartFromSdrObject( pOldObject ) );
1551  if(!xOldChart.is())//#i110034# do not move charts as they lose all their data references otherwise
1552  pNewObject->NbcMove(Size(0,0));
1553  pDestPage->InsertObject( pNewObject );
1554 
1555  // no undo needed in clipboard document
1556  // charts are not updated
1557  }
1558  }
1559 
1560  pOldObject = aIter.Next();
1561  }
1562 }
1563 
1564 static bool lcl_IsAllInRange( const ::std::vector< ScRangeList >& rRangesVector, const ScRange& rClipRange )
1565 {
1566  // check if every range of rRangesVector is completely in rClipRange
1567 
1568  for( const ScRangeList& rRanges : rRangesVector )
1569  {
1570  for ( size_t i = 0, nCount = rRanges.size(); i < nCount; i++ )
1571  {
1572  const ScRange & rRange = rRanges[ i ];
1573  if ( !rClipRange.In( rRange ) )
1574  {
1575  return false; // at least one range is not valid
1576  }
1577  }
1578  }
1579 
1580  return true; // everything is fine
1581 }
1582 
1583 static bool lcl_MoveRanges( ::std::vector< ScRangeList >& rRangesVector, const ScRange& rSourceRange, const ScAddress& rDestPos )
1584 {
1585  bool bChanged = false;
1586 
1587  ScRange aErrorRange( ScAddress::UNINITIALIZED );
1588  for( ScRangeList& rRanges : rRangesVector )
1589  {
1590  for ( size_t i = 0, nCount = rRanges.size(); i < nCount; i++ )
1591  {
1592  ScRange & rRange = rRanges[ i ];
1593  if ( rSourceRange.In( rRange ) )
1594  {
1595  SCCOL nDiffX = rDestPos.Col() - rSourceRange.aStart.Col();
1596  SCROW nDiffY = rDestPos.Row() - rSourceRange.aStart.Row();
1597  SCTAB nDiffZ = rDestPos.Tab() - rSourceRange.aStart.Tab();
1598  if (!rRange.Move( nDiffX, nDiffY, nDiffZ, aErrorRange))
1599  {
1600  assert(!"can't move range");
1601  }
1602  bChanged = true;
1603  }
1604  }
1605  }
1606 
1607  return bChanged;
1608 }
1609 
1610 void ScDrawLayer::CopyFromClip( ScDrawLayer* pClipModel, SCTAB nSourceTab, const tools::Rectangle& rSourceRange,
1611  const ScAddress& rDestPos, const tools::Rectangle& rDestRange )
1612 {
1613  OSL_ENSURE( pDoc, "ScDrawLayer::CopyFromClip without document" );
1614  if ( !pDoc )
1615  return;
1616 
1617  if (!pClipModel)
1618  return;
1619 
1620  if (bDrawIsInUndo) //TODO: can this happen?
1621  {
1622  OSL_FAIL("CopyFromClip, bDrawIsInUndo");
1623  return;
1624  }
1625 
1626  bool bMirrorObj = ( rSourceRange.Left() < 0 && rSourceRange.Right() < 0 &&
1627  rDestRange.Left() > 0 && rDestRange.Right() > 0 ) ||
1628  ( rSourceRange.Left() > 0 && rSourceRange.Right() > 0 &&
1629  rDestRange.Left() < 0 && rDestRange.Right() < 0 );
1630  tools::Rectangle aMirroredSource = rSourceRange;
1631  if ( bMirrorObj )
1632  MirrorRectRTL( aMirroredSource );
1633 
1634  SCTAB nDestTab = rDestPos.Tab();
1635 
1636  SdrPage* pSrcPage = pClipModel->GetPage(static_cast<sal_uInt16>(nSourceTab));
1637  SdrPage* pDestPage = GetPage(static_cast<sal_uInt16>(nDestTab));
1638  OSL_ENSURE( pSrcPage && pDestPage, "draw page missing" );
1639  if ( !pSrcPage || !pDestPage )
1640  return;
1641 
1642  SdrObjListIter aIter( pSrcPage, SdrIterMode::Flat );
1643  SdrObject* pOldObject = aIter.Next();
1644 
1645  ScDocument* pClipDoc = pClipModel->GetDocument();
1646  // a clipboard document and its source share the same document item pool,
1647  // so the pointers can be compared to see if this is copy&paste within
1648  // the same document
1649  bool bSameDoc = pDoc && pClipDoc && pDoc->GetPool() == pClipDoc->GetPool();
1650  bool bDestClip = pDoc && pDoc->IsClipboard();
1651 
1652  //#i110034# charts need correct sheet names for xml range conversion during load
1653  //so the target sheet name is temporarily renamed (if we have any SdrObjects)
1654  OUString aDestTabName;
1655  bool bRestoreDestTabName = false;
1656  if( pOldObject && !bSameDoc && !bDestClip )
1657  {
1658  if( pDoc && pClipDoc )
1659  {
1660  OUString aSourceTabName;
1661  if( pClipDoc->GetName( nSourceTab, aSourceTabName )
1662  && pDoc->GetName( nDestTab, aDestTabName ) )
1663  {
1664  if( aSourceTabName != aDestTabName &&
1665  pDoc->ValidNewTabName(aSourceTabName) )
1666  {
1667  bRestoreDestTabName = pDoc->RenameTab( nDestTab, aSourceTabName );
1668  }
1669  }
1670  }
1671  }
1672 
1673  // first mirror, then move
1674  Size aMove( rDestRange.Left() - aMirroredSource.Left(), rDestRange.Top() - aMirroredSource.Top() );
1675 
1676  tools::Long nDestWidth = rDestRange.GetWidth();
1677  tools::Long nDestHeight = rDestRange.GetHeight();
1678  tools::Long nSourceWidth = rSourceRange.GetWidth();
1679  tools::Long nSourceHeight = rSourceRange.GetHeight();
1680 
1681  tools::Long nWidthDiff = nDestWidth - nSourceWidth;
1682  tools::Long nHeightDiff = nDestHeight - nSourceHeight;
1683 
1684  Fraction aHorFract(1,1);
1685  Fraction aVerFract(1,1);
1686  bool bResize = false;
1687  // sizes can differ by 1 from twips->1/100mm conversion for equal cell sizes,
1688  // don't resize to empty size when pasting into hidden columns or rows
1689  if ( std::abs(nWidthDiff) > 1 && nDestWidth > 1 && nSourceWidth > 1 )
1690  {
1691  aHorFract = Fraction( nDestWidth, nSourceWidth );
1692  bResize = true;
1693  }
1694  if ( std::abs(nHeightDiff) > 1 && nDestHeight > 1 && nSourceHeight > 1 )
1695  {
1696  aVerFract = Fraction( nDestHeight, nSourceHeight );
1697  bResize = true;
1698  }
1699  Point aRefPos = rDestRange.TopLeft(); // for resizing (after moving)
1700 
1701  while (pOldObject)
1702  {
1703  tools::Rectangle aObjRect = pOldObject->GetCurrentBoundRect();
1704  // do not copy internal objects (detective) and note captions
1705 
1706  SCTAB nClipTab = bRestoreDestTabName ? nDestTab : nSourceTab;
1707  ScRange aClipRange = lcl_getClipRangeFromClipDoc(pClipDoc, nClipTab);
1708 
1709  bool bObjectInArea = rSourceRange.IsInside(aObjRect);
1710  const ScDrawObjData* pObjData = ScDrawLayer::GetObjData(pOldObject);
1711  if (pObjData) // Consider images anchored to the copied cell
1712  bObjectInArea = bObjectInArea || aClipRange.In(pObjData->maStart);
1713  if (bObjectInArea && (pOldObject->GetLayer() != SC_LAYER_INTERN)
1714  && !IsNoteCaption(pOldObject))
1715  {
1716  // Clone to target SdrModel
1717  SdrObject* pNewObject(pOldObject->CloneSdrObject(*this));
1718 
1719  if ( bMirrorObj )
1720  MirrorRTL( pNewObject ); // first mirror, then move
1721 
1722  pNewObject->NbcMove( aMove );
1723  if ( bResize )
1724  pNewObject->NbcResize( aRefPos, aHorFract, aVerFract );
1725 
1726  pDestPage->InsertObject( pNewObject );
1727  if (bRecording)
1728  AddCalcUndo( std::make_unique<SdrUndoInsertObj>( *pNewObject ) );
1729 
1730  //#i110034# handle chart data references (after InsertObject)
1731 
1732  if ( pNewObject->GetObjIdentifier() == OBJ_OLE2 )
1733  {
1734  uno::Reference< embed::XEmbeddedObject > xIPObj = static_cast<SdrOle2Obj*>(pNewObject)->GetObjRef();
1735  uno::Reference< embed::XClassifiedObject > xClassified = xIPObj;
1736  SvGlobalName aObjectClassName;
1737  if ( xClassified.is() )
1738  {
1739  try {
1740  aObjectClassName = SvGlobalName( xClassified->getClassID() );
1741  } catch( uno::Exception& )
1742  {
1743  // TODO: handle error?
1744  }
1745  }
1746 
1747  if ( xIPObj.is() && SotExchange::IsChart( aObjectClassName ) )
1748  {
1749  uno::Reference< chart2::XChartDocument > xNewChart( ScChartHelper::GetChartFromSdrObject( pNewObject ) );
1750  if( xNewChart.is() && !xNewChart->hasInternalDataProvider() )
1751  {
1752  OUString aChartName = static_cast<SdrOle2Obj*>(pNewObject)->GetPersistName();
1753  ::std::vector< ScRangeList > aRangesVector;
1754  pDoc->GetChartRanges( aChartName, aRangesVector, *pDoc );
1755  if( !aRangesVector.empty() )
1756  {
1757  bool bInSourceRange = false;
1758  if ( pClipDoc )
1759  {
1760  bInSourceRange = lcl_IsAllInRange( aRangesVector, aClipRange );
1761  }
1762 
1763  // always lose references when pasting into a clipboard document (transpose)
1764  if ( ( bInSourceRange || bSameDoc ) && !bDestClip )
1765  {
1766  if ( bInSourceRange )
1767  {
1768  if ( rDestPos != aClipRange.aStart )
1769  {
1770  // update the data ranges to the new (copied) position
1771  if ( lcl_MoveRanges( aRangesVector, aClipRange, rDestPos ) )
1772  pDoc->SetChartRanges( aChartName, aRangesVector );
1773  }
1774  }
1775  else
1776  {
1777  // leave the ranges unchanged
1778  }
1779  }
1780  else
1781  {
1782  // pasting into a new document without the complete source data
1783  // -> break connection to source data and switch to own data
1784 
1785  uno::Reference< chart::XChartDocument > xOldChartDoc( ScChartHelper::GetChartFromSdrObject( pOldObject ), uno::UNO_QUERY );
1786  uno::Reference< chart::XChartDocument > xNewChartDoc( xNewChart, uno::UNO_QUERY );
1787  if( xOldChartDoc.is() && xNewChartDoc.is() )
1788  xNewChartDoc->attachData( xOldChartDoc->getData() );
1789 
1790  // (see ScDocument::UpdateChartListenerCollection, PastingDrawFromOtherDoc)
1791  }
1792  }
1793  }
1794  }
1795  }
1796  }
1797 
1798  pOldObject = aIter.Next();
1799  }
1800 
1801  if( bRestoreDestTabName )
1802  pDoc->RenameTab( nDestTab, aDestTabName );
1803 }
1804 
1806 {
1807  sal_uInt16 nIdent = pObj->GetObjIdentifier();
1808 
1809  // don't mirror OLE or graphics, otherwise ask the object
1810  // if it can be mirrored
1811  bool bCanMirror = ( nIdent != OBJ_GRAF && nIdent != OBJ_OLE2 );
1812  if (bCanMirror)
1813  {
1814  SdrObjTransformInfoRec aInfo;
1815  pObj->TakeObjInfo( aInfo );
1816  bCanMirror = aInfo.bMirror90Allowed;
1817  }
1818 
1819  if (bCanMirror)
1820  {
1821  Point aRef1( 0, 0 );
1822  Point aRef2( 0, 1 );
1823  if (bRecording)
1824  AddCalcUndo( std::make_unique<SdrUndoGeoObj>( *pObj ) );
1825  pObj->Mirror( aRef1, aRef2 );
1826  }
1827  else
1828  {
1829  // Move instead of mirroring:
1830  // New start position is negative of old end position
1831  // -> move by sum of start and end position
1832  tools::Rectangle aObjRect = pObj->GetLogicRect();
1833  Size aMoveSize( -(aObjRect.Left() + aObjRect.Right()), 0 );
1834  if (bRecording)
1835  AddCalcUndo( std::make_unique<SdrUndoMoveObj>( *pObj, aMoveSize ) );
1836  pObj->Move( aMoveSize );
1837  }
1838 }
1839 
1841 {
1842  // mirror and swap left/right
1843  tools::Long nTemp = rRect.Left();
1844  rRect.SetLeft( -rRect.Right() );
1845  rRect.SetRight( -nTemp );
1846 }
1847 
1848 tools::Rectangle ScDrawLayer::GetCellRect( const ScDocument& rDoc, const ScAddress& rPos, bool bMergedCell )
1849 {
1850  tools::Rectangle aCellRect;
1851  OSL_ENSURE( rDoc.ValidColRowTab( rPos.Col(), rPos.Row(), rPos.Tab() ), "ScDrawLayer::GetCellRect - invalid cell address" );
1852  if( rDoc.ValidColRowTab( rPos.Col(), rPos.Row(), rPos.Tab() ) )
1853  {
1854  // find top left position of passed cell address
1855  Point aTopLeft;
1856  for( SCCOL nCol = 0; nCol < rPos.Col(); ++nCol )
1857  aTopLeft.AdjustX(rDoc.GetColWidth( nCol, rPos.Tab() ) );
1858  if( rPos.Row() > 0 )
1859  aTopLeft.AdjustY(rDoc.GetRowHeight( 0, rPos.Row() - 1, rPos.Tab() ) );
1860 
1861  // find bottom-right position of passed cell address
1862  ScAddress aEndPos = rPos;
1863  if( bMergedCell )
1864  {
1865  const ScMergeAttr* pMerge = rDoc.GetAttr( rPos, ATTR_MERGE );
1866  if( pMerge->GetColMerge() > 1 )
1867  aEndPos.IncCol( pMerge->GetColMerge() - 1 );
1868  if( pMerge->GetRowMerge() > 1 )
1869  aEndPos.IncRow( pMerge->GetRowMerge() - 1 );
1870  }
1871  Point aBotRight = aTopLeft;
1872  for( SCCOL nCol = rPos.Col(); nCol <= aEndPos.Col(); ++nCol )
1873  aBotRight.AdjustX(rDoc.GetColWidth( nCol, rPos.Tab() ) );
1874  aBotRight.AdjustY(rDoc.GetRowHeight( rPos.Row(), aEndPos.Row(), rPos.Tab() ) );
1875 
1876  // twips -> 1/100 mm
1877  aTopLeft.setX( static_cast< tools::Long >( aTopLeft.X() * HMM_PER_TWIPS ) );
1878  aTopLeft.setY( static_cast< tools::Long >( aTopLeft.Y() * HMM_PER_TWIPS ) );
1879  aBotRight.setX( static_cast< tools::Long >( aBotRight.X() * HMM_PER_TWIPS ) );
1880  aBotRight.setY( static_cast< tools::Long >( aBotRight.Y() * HMM_PER_TWIPS ) );
1881 
1882  aCellRect = tools::Rectangle( aTopLeft, aBotRight );
1883  if( rDoc.IsNegativePage( rPos.Tab() ) )
1884  MirrorRectRTL( aCellRect );
1885  }
1886  return aCellRect;
1887 }
1888 
1890 {
1891  OUString aName = pObj->GetName();
1892  if ( pObj->GetObjIdentifier() == OBJ_OLE2 )
1893  {
1894  // For OLE, the user defined name (GetName) is used
1895  // if it's not empty (accepting possibly duplicate names),
1896  // otherwise the persist name is used so every object appears
1897  // in the Navigator at all.
1898 
1899  if ( aName.isEmpty() )
1900  aName = static_cast<const SdrOle2Obj*>(pObj)->GetPersistName();
1901  }
1902  return aName;
1903 }
1904 
1905 static bool IsNamedObject( const SdrObject* pObj, const OUString& rName )
1906 {
1907  // sal_True if rName is the object's Name or PersistName
1908  // (used to find a named object)
1909 
1910  return ( pObj->GetName() == rName ||
1911  ( pObj->GetObjIdentifier() == OBJ_OLE2 &&
1912  static_cast<const SdrOle2Obj*>(pObj)->GetPersistName() == rName ) );
1913 }
1914 
1915 SdrObject* ScDrawLayer::GetNamedObject( const OUString& rName, sal_uInt16 nId, SCTAB& rFoundTab ) const
1916 {
1917  sal_uInt16 nTabCount = GetPageCount();
1918  for (sal_uInt16 nTab=0; nTab<nTabCount; nTab++)
1919  {
1920  const SdrPage* pPage = GetPage(nTab);
1921  OSL_ENSURE(pPage,"Page ?");
1922  if (pPage)
1923  {
1924  SdrObjListIter aIter( pPage, SdrIterMode::DeepWithGroups );
1925  SdrObject* pObject = aIter.Next();
1926  while (pObject)
1927  {
1928  if ( nId == 0 || pObject->GetObjIdentifier() == nId )
1929  if ( IsNamedObject( pObject, rName ) )
1930  {
1931  rFoundTab = static_cast<SCTAB>(nTab);
1932  return pObject;
1933  }
1934 
1935  pObject = aIter.Next();
1936  }
1937  }
1938  }
1939 
1940  return nullptr;
1941 }
1942 
1943 OUString ScDrawLayer::GetNewGraphicName( tools::Long* pnCounter ) const
1944 {
1945  OUString aBase = ScResId(STR_GRAPHICNAME) + " ";
1946 
1947  bool bThere = true;
1948  OUString aGraphicName;
1949  SCTAB nDummy;
1950  tools::Long nId = pnCounter ? *pnCounter : 0;
1951  while (bThere)
1952  {
1953  ++nId;
1954  aGraphicName = aBase + OUString::number( nId );
1955  bThere = ( GetNamedObject( aGraphicName, 0, nDummy ) != nullptr );
1956  }
1957 
1958  if ( pnCounter )
1959  *pnCounter = nId;
1960 
1961  return aGraphicName;
1962 }
1963 
1965 {
1966  // make sure all graphic objects have names (after Excel import etc.)
1967 
1968  sal_uInt16 nTabCount = GetPageCount();
1969  for (sal_uInt16 nTab=0; nTab<nTabCount; nTab++)
1970  {
1971  SdrPage* pPage = GetPage(nTab);
1972  OSL_ENSURE(pPage,"Page ?");
1973  if (pPage)
1974  {
1975  SdrObjListIter aIter( pPage, SdrIterMode::DeepWithGroups );
1976  SdrObject* pObject = aIter.Next();
1977 
1978  /* The index passed to GetNewGraphicName() will be set to
1979  the used index in each call. This prevents the repeated search
1980  for all names from 1 to current index. */
1981  tools::Long nCounter = 0;
1982 
1983  while (pObject)
1984  {
1985  if ( pObject->GetObjIdentifier() == OBJ_GRAF && pObject->GetName().isEmpty())
1986  pObject->SetName( GetNewGraphicName( &nCounter ) );
1987 
1988  pObject = aIter.Next();
1989  }
1990  }
1991  }
1992 }
1993 
1994 namespace
1995 {
1996  SdrObjUserData* GetFirstUserDataOfType(const SdrObject *pObj, sal_uInt16 nId)
1997  {
1998  sal_uInt16 nCount = pObj ? pObj->GetUserDataCount() : 0;
1999  for( sal_uInt16 i = 0; i < nCount; i++ )
2000  {
2001  SdrObjUserData* pData = pObj->GetUserData( i );
2002  if( pData && pData->GetInventor() == SdrInventor::ScOrSwDraw && pData->GetId() == nId )
2003  return pData;
2004  }
2005  return nullptr;
2006  }
2007 
2008  void DeleteFirstUserDataOfType(SdrObject *pObj, sal_uInt16 nId)
2009  {
2010  sal_uInt16 nCount = pObj ? pObj->GetUserDataCount() : 0;
2011  for( sal_uInt16 i = nCount; i > 0; i-- )
2012  {
2013  SdrObjUserData* pData = pObj->GetUserData( i-1 );
2014  if( pData && pData->GetInventor() == SdrInventor::ScOrSwDraw && pData->GetId() == nId )
2015  pObj->DeleteUserData(i-1);
2016  }
2017  }
2018 }
2019 
2021 {
2022  ScDrawObjData* pAnchor = GetNonRotatedObjData( &rObj, true );
2023  pAnchor->maStart = rAnchor.maStart;
2024  pAnchor->maEnd = rAnchor.maEnd;
2025  pAnchor->maStartOffset = rAnchor.maStartOffset;
2026  pAnchor->maEndOffset = rAnchor.maEndOffset;
2027  pAnchor->mbResizeWithCell = rAnchor.mbResizeWithCell;
2028 }
2029 
2031 {
2032  ScDrawObjData* pAnchor = GetObjData( &rObj, true );
2033  pAnchor->maStart = rAnchor.maStart;
2034  pAnchor->maEnd = rAnchor.maEnd;
2035  pAnchor->maStartOffset = rAnchor.maStartOffset;
2036  pAnchor->maEndOffset = rAnchor.maEndOffset;
2037  pAnchor->mbResizeWithCell = rAnchor.mbResizeWithCell;
2038 }
2039 
2041  bool bResizeWithCell )
2042 {
2043  ScDrawObjData aAnchor;
2044  // set anchor in terms of the visual ( SnapRect )
2045  // object ( e.g. for when object is rotated )
2046  const tools::Rectangle aObjRect(rObj.GetSnapRect());
2048  aObjRect,
2049  aAnchor,
2050  rDoc,
2051  nTab);
2052 
2053  aAnchor.mbResizeWithCell = bResizeWithCell;
2054  SetCellAnchored( rObj, aAnchor );
2055  // - keep also an anchor in terms of the Logic ( untransformed ) object
2056  // because that's what we stored ( and still do ) to xml
2057  ScDrawObjData aVisAnchor;
2058  const tools::Rectangle aObjRect2(rObj.GetLogicRect());
2060  aObjRect2,
2061  aVisAnchor,
2062  rDoc,
2063  nTab);
2064 
2065  aVisAnchor.mbResizeWithCell = bResizeWithCell;
2066  SetVisualCellAnchored( rObj, aVisAnchor );
2067  // absolutely necessary to set flag that in order to prevent ScDrawLayer::RecalcPos
2068  // doing an initialisation hack
2069  if ( ScDrawObjData* pAnchor = GetObjData( &rObj ) )
2070  {
2071  pAnchor->setShapeRect(&rDoc, rObj.GetSnapRect());
2072  }
2073 }
2074 
2076  const tools::Rectangle &rObjRect,
2077  ScDrawObjData &rAnchor,
2078  const ScDocument &rDoc,
2079  SCTAB nTab,
2080  bool bHiddenAsZero)
2081 {
2082  ScRange aRange = rDoc.GetRange( nTab, rObjRect, bHiddenAsZero );
2083 
2084  tools::Rectangle aCellRect;
2085 
2086  rAnchor.maStart = aRange.aStart;
2087  aCellRect = rDoc.GetMMRect( aRange.aStart.Col(), aRange.aStart.Row(),
2088  aRange.aStart.Col(), aRange.aStart.Row(), aRange.aStart.Tab(), bHiddenAsZero );
2089  rAnchor.maStartOffset.setY( rObjRect.Top()-aCellRect.Top() );
2090  if (!rDoc.IsNegativePage(nTab))
2091  rAnchor.maStartOffset.setX( rObjRect.Left()-aCellRect.Left() );
2092  else
2093  rAnchor.maStartOffset.setX( aCellRect.Right()-rObjRect.Right() );
2094 
2095  rAnchor.maEnd = aRange.aEnd;
2096  aCellRect = rDoc.GetMMRect( aRange.aEnd.Col(), aRange.aEnd.Row(),
2097  aRange.aEnd.Col(), aRange.aEnd.Row(), aRange.aEnd.Tab(), bHiddenAsZero );
2098  if (!rObjRect.IsEmpty())
2099  rAnchor.maEndOffset.setY( rObjRect.Bottom()-aCellRect.Top() );
2100  if (!rDoc.IsNegativePage(nTab))
2101  {
2102  if (!rObjRect.IsEmpty())
2103  rAnchor.maEndOffset.setX( rObjRect.Right()-aCellRect.Left() );
2104  }
2105  else
2106  rAnchor.maEndOffset.setX( aCellRect.Right()-rObjRect.Left() );
2107 }
2108 
2109 void ScDrawLayer::UpdateCellAnchorFromPositionEnd( const SdrObject &rObj, ScDrawObjData &rAnchor, const ScDocument &rDoc, SCTAB nTab, bool bUseLogicRect )
2110 {
2111  tools::Rectangle aObjRect(bUseLogicRect ? rObj.GetLogicRect() : rObj.GetSnapRect());
2112  ScRange aRange = rDoc.GetRange( nTab, aObjRect );
2113 
2114  ScDrawObjData* pAnchor = &rAnchor;
2115  pAnchor->maEnd = aRange.aEnd;
2116 
2117  tools::Rectangle aCellRect = rDoc.GetMMRect( aRange.aEnd.Col(), aRange.aEnd.Row(),
2118  aRange.aEnd.Col(), aRange.aEnd.Row(), aRange.aEnd.Tab() );
2119  pAnchor->maEndOffset.setY( aObjRect.Bottom()-aCellRect.Top() );
2120  if (!rDoc.IsNegativePage(nTab))
2121  pAnchor->maEndOffset.setX( aObjRect.Right()-aCellRect.Left() );
2122  else
2123  pAnchor->maEndOffset.setX( aCellRect.Right()-aObjRect.Left() );
2124 }
2125 
2127 {
2128  // Cell anchored object always has a user data, to store the anchor cell
2129  // info. If it doesn't then it's page-anchored.
2130  return GetFirstUserDataOfType(&rObj, SC_UD_OBJDATA) != nullptr;
2131 }
2132 
2134 {
2135  // Cell anchored object always has a user data, to store the anchor cell
2136  // info. If it doesn't then it's page-anchored.
2137  ScDrawObjData* pDrawObjData = GetObjData(const_cast<SdrObject*>(&rObj));
2138  if (!pDrawObjData)
2139  return false;
2140 
2141  return pDrawObjData->mbResizeWithCell;
2142 }
2143 
2145 {
2146  DeleteFirstUserDataOfType(&rObj, SC_UD_OBJDATA);
2147  DeleteFirstUserDataOfType(&rObj, SC_UD_OBJDATA);
2148 }
2149 
2151 {
2152  //If this object has a cell anchor associated with it
2153  //then it's cell-anchored, otherwise it's page-anchored
2154  const ScDrawObjData* pObjData = ScDrawLayer::GetObjData(const_cast<SdrObject*>(&rObj));
2155 
2156  // When there is no cell anchor, it is page anchored.
2157  if (!pObjData)
2158  return SCA_PAGE;
2159 
2160  // It's cell-anchored, check if the object resizes with the cell
2161  if (pObjData->mbResizeWithCell)
2162  return SCA_CELL_RESIZE;
2163 
2164  return SCA_CELL;
2165 }
2166 
2167 std::vector<SdrObject*>
2169 {
2170  SdrPage* pPage = GetPage(static_cast<sal_uInt16>(nTab));
2171  if (!pPage || pPage->GetObjCount() < 1)
2172  return std::vector<SdrObject*>();
2173 
2174  std::vector<SdrObject*> aObjects;
2175  SdrObjListIter aIter( pPage, SdrIterMode::Flat );
2176  SdrObject* pObject = aIter.Next();
2177  ScRange aRange( 0, nStartRow, nTab, MAXCOL, nEndRow, nTab);
2178  while (pObject)
2179  {
2180  if (!dynamic_cast<SdrCaptionObj*>(pObject)) // Caption objects are handled differently
2181  {
2182  ScDrawObjData* pObjData = GetObjData(pObject);
2183  if (pObjData && aRange.In(pObjData->maStart))
2184  aObjects.push_back(pObject);
2185  }
2186  pObject = aIter.Next();
2187  }
2188  return aObjects;
2189 }
2190 
2191 std::map<SCROW, std::vector<SdrObject*>>
2193 {
2194  SdrPage* pPage = GetPage(static_cast<sal_uInt16>(nTab));
2195  if (!pPage || pPage->GetObjCount() < 1)
2196  return std::map<SCROW, std::vector<SdrObject*>>();
2197 
2198  std::map<SCROW, std::vector<SdrObject*>> aRowObjects;
2199  SdrObjListIter aIter( pPage, SdrIterMode::Flat );
2200  SdrObject* pObject = aIter.Next();
2201  ScRange aRange( nCol, nStartRow, nTab, nCol, nEndRow, nTab);
2202  while (pObject)
2203  {
2204  if (!dynamic_cast<SdrCaptionObj*>(pObject)) // Caption objects are handled differently
2205  {
2206  ScDrawObjData* pObjData = GetObjData(pObject);
2207  if (pObjData && aRange.In(pObjData->maStart))
2208  aRowObjects[pObjData->maStart.Row()].push_back(pObject);
2209  }
2210  pObject = aIter.Next();
2211  }
2212  return aRowObjects;
2213 }
2214 
2216 {
2217  // This only works for one table at a time
2218  assert(rRange.aStart.Tab() == rRange.aEnd.Tab());
2219 
2220  SdrPage* pPage = GetPage(static_cast<sal_uInt16>(rRange.aStart.Tab()));
2221  if (!pPage || pPage->GetObjCount() < 1)
2222  return false;
2223 
2224  SdrObjListIter aIter( pPage, SdrIterMode::Flat );
2225  SdrObject* pObject = aIter.Next();
2226  while (pObject)
2227  {
2228  if (!dynamic_cast<SdrCaptionObj*>(pObject)) // Caption objects are handled differently
2229  {
2230  ScDrawObjData* pObjData = GetObjData(pObject);
2231  if (pObjData && rRange.In(pObjData->maStart)) // Object is in given range
2232  return true;
2233  }
2234  pObject = aIter.Next();
2235  }
2236  return false;
2237 }
2238 
2239 void ScDrawLayer::MoveObject(SdrObject* pObject, const ScAddress& rNewPosition)
2240 {
2241  // Get anchor data
2242  ScDrawObjData* pObjData = GetObjData(pObject, false);
2243  if (!pObjData)
2244  return;
2245  const ScAddress aOldStart = pObjData->maStart;
2246  const ScAddress aOldEnd = pObjData->maEnd;
2247 
2248  // Set start address
2249  pObjData->maStart = rNewPosition;
2250 
2251  // Set end address
2252  const SCCOL nObjectColSpan = aOldEnd.Col() - aOldStart.Col();
2253  const SCROW nObjectRowSpan = aOldEnd.Row() - aOldStart.Row();
2254  ScAddress aNewEnd = rNewPosition;
2255  aNewEnd.IncRow(nObjectRowSpan);
2256  aNewEnd.IncCol(nObjectColSpan);
2257  pObjData->maEnd = aNewEnd;
2258 
2259  // Update draw object according to new anchor
2260  RecalcPos(pObject, *pObjData, false, false);
2261 }
2262 
2264 {
2265  sal_uInt16 nCount = pObj ? pObj->GetUserDataCount() : 0;
2266  sal_uInt16 nFound = 0;
2267  for( sal_uInt16 i = 0; i < nCount; i++ )
2268  {
2269  SdrObjUserData* pData = pObj->GetUserData( i );
2270  if( pData && pData->GetInventor() == SdrInventor::ScOrSwDraw && pData->GetId() == SC_UD_OBJDATA && ++nFound == 2 )
2271  return static_cast<ScDrawObjData*>(pData);
2272  }
2273  if( pObj && bCreate )
2274  {
2275  ScDrawObjData* pData = new ScDrawObjData;
2276  pObj->AppendUserData(std::unique_ptr<SdrObjUserData>(pData));
2277  return pData;
2278  }
2279  return nullptr;
2280 }
2281 
2283 {
2284  if (SdrObjUserData *pData = GetFirstUserDataOfType(pObj, SC_UD_OBJDATA))
2285  return static_cast<ScDrawObjData*>(pData);
2286 
2287  if( pObj && bCreate )
2288  {
2289  ScDrawObjData* pData = new ScDrawObjData;
2290  pObj->AppendUserData(std::unique_ptr<SdrObjUserData>(pData));
2291  return pData;
2292  }
2293  return nullptr;
2294 }
2295 
2297 {
2298  ScDrawObjData* pData = GetObjData( pObj );
2299  if ( pData )
2300  {
2301  if ( pData->maStart.IsValid() )
2302  pData->maStart.SetTab( nTab );
2303  if ( pData->maEnd.IsValid() )
2304  pData->maEnd.SetTab( nTab );
2305  }
2306  return pData;
2307 }
2308 
2310 {
2311  ScDrawObjData* pData = pObj ? GetObjData( pObj ) : nullptr;
2312  return pData && pData->meType == ScDrawObjData::CellNote;
2313 }
2314 
2316 {
2317  ScDrawObjData* pData = pObj ? GetObjDataTab( pObj, nTab ) : nullptr;
2318  return (pData && pData->meType == ScDrawObjData::CellNote) ? pData : nullptr;
2319 }
2320 
2322 {
2323  if (SdrObjUserData *pData = GetFirstUserDataOfType(pObj, SC_UD_MACRODATA))
2324  return static_cast<ScMacroInfo*>(pData);
2325 
2326  if ( bCreate )
2327  {
2328  ScMacroInfo* pData = new ScMacroInfo;
2329  pObj->AppendUserData(std::unique_ptr<SdrObjUserData>(pData));
2330  return pData;
2331  }
2332  return nullptr;
2333 }
2334 
2336 {
2337  OSL_ENSURE(!pGlobalDrawPersist,"Multiple SetGlobalDrawPersist");
2338  pGlobalDrawPersist = pPersist;
2339 }
2340 
2341 void ScDrawLayer::SetChanged( bool bFlg /* = true */ )
2342 {
2343  if ( bFlg && pDoc )
2345  FmFormModel::SetChanged( bFlg );
2346 }
2347 
2348 css::uno::Reference< css::uno::XInterface > ScDrawLayer::createUnoModel()
2349 {
2350  css::uno::Reference< css::uno::XInterface > xRet;
2351  if( pDoc && pDoc->GetDocumentShell() )
2352  xRet = pDoc->GetDocumentShell()->GetModel();
2353 
2354  return xRet;
2355 }
2356 
2357 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SdrOutliner & GetDrawOutliner(const SdrTextObj *pObj=nullptr) const
void BeginCalcUndo(bool bDisableTextEditUsesCommonUndoManager)
Definition: drwlayer.cxx:1253
Point TopLeft() const
std::map< SCROW, std::vector< SdrObject * > > GetObjectsAnchoredToRange(SCTAB nTab, SCCOL nCol, SCROW nStartRow, SCROW nEndRow)
Definition: drwlayer.cxx:2192
bool mbWasCellAnchored
Definition: drwlayer.hxx:77
void SetPos(const Point &rPoint)
bool bAdjustEnabled
Definition: drwlayer.hxx:96
void EnsureGraphicNames()
Definition: drwlayer.cxx:1964
OBJ_GRAF
SCCOL GetColMerge() const
Definition: attrib.hxx:69
static void GetCellAnchorFromPosition(const tools::Rectangle &rRectangle, ScDrawObjData &rAnchor, const ScDocument &rDoc, SCTAB nTab, bool bHiddenAsZero=true)
Definition: drwlayer.cxx:2075
static SfxObjectShell * pGlobalDrawPersist
Definition: drwlayer.hxx:212
virtual void TakeObjInfo(SdrObjTransformInfoRec &rInfo) const
void append(const basegfx::B2DPoint &rPoint, sal_uInt32 nCount)
constexpr TypedWhichId< SvxScriptSpaceItem > EE_PARA_ASIANCJKSPACING(EE_PARA_START+4)
static void SetVisualCellAnchored(SdrObject &, const ScDrawObjData &rAnchor)
Definition: drwlayer.cxx:2020
void GetClipStart(SCCOL &nClipX, SCROW &nClipY)
Definition: document.cxx:3170
ScAddress aStart
Definition: address.hxx:500
virtual void SetSize(const Size &aSiz)
todo: It should be possible to have MarkArrays for each table, in order to enable "search all" across...
Definition: markdata.hxx:43
virtual const tools::Rectangle & GetCurrentBoundRect() const
std::vector< SdrObject * > GetObjectsAnchoredToRows(SCTAB nTab, SCROW nStartRow, SCROW nEndRow)
Definition: drwlayer.cxx:2168
OBJ_CUSTOMSHAPE
OBJ_OLE2
SC_DLLPUBLIC bool IsNegativePage(SCTAB nTab) const
Definition: document.cxx:1002
void SetPoint(const Point &rPnt, sal_uInt32 i)
tools::Long AdjustRight(tools::Long nHorzMoveDelta)
SCROW Row() const
Definition: address.hxx:262
void MirrorRTL(SdrObject *pObj)
Definition: drwlayer.cxx:1805
std::unique_ptr< ContentProperties > pData
virtual ~ScDrawLayer() override
Definition: drwlayer.cxx:332
virtual bool IsPolyObj() const
virtual void NbcResize(const Point &rRef, const Fraction &xFact, const Fraction &yFact)
static css::uno::Reference< css::chart2::XChartDocument > GetChartFromSdrObject(const SdrObject *pObject)
static void SetPageAnchored(SdrObject &)
Definition: drwlayer.cxx:2144
LanguageType getLanguageType(bool bResolveSystem=true) const
Point BottomLeft() const
ScUndoObjData(SdrObject *pObj, const ScAddress &rOS, const ScAddress &rOE, const ScAddress &rNS, const ScAddress &rNE)
Definition: drwlayer.cxx:87
static ScMacroInfo * GetMacroInfo(SdrObject *pObj, bool bCreate=false)
Definition: drwlayer.cxx:2321
long Long
void ResetTab(SCTAB nStart, SCTAB nEnd)
Definition: drwlayer.cxx:478
static const AllSettings & GetSettings()
virtual Point GetRelativePos() const
SC_DLLPUBLIC bool ValidNewTabName(const OUString &rName) const
Definition: document.cxx:374
virtual void SetChanged(bool bFlg=true) override
Definition: drwlayer.cxx:2341
static ScDrawObjData * GetObjData(SdrObject *pObj, bool bCreate=false)
Definition: drwlayer.cxx:2282
#define DET_ARROW_OFFSET
Definition: drwlayer.cxx:76
SdrObject * GetObj(size_t nNum) const
void RecalcObjOrdNums()
bool IsInserted() const
static bool IsCellAnchored(const SdrObject &rObj)
Definition: drwlayer.cxx:2126
static bool lcl_MoveRanges(::std::vector< ScRangeList > &rRangesVector, const ScRange &rSourceRange, const ScAddress &rDestPos)
Definition: drwlayer.cxx:1583
size_t GetObjCount() const
tools::Long getY() const
void PutInOrder(ScAddress &rAddress)
Definition: address.hxx:384
void DeleteObjectsInArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, bool bAnchored=false)
Definition: drwlayer.cxx:1368
sal_Int16 nId
void SetSwapGraphics()
static void lcl_ReverseTwipsToMM(tools::Rectangle &rRect)
Definition: drwlayer.cxx:214
SC_DLLPUBLIC bool Move(SCCOL aDeltaX, SCROW aDeltaY, SCTAB aDeltaZ, ScRange &rErrorRange, const ScDocument *pDocument=nullptr)
Definition: address.cxx:2363
bool HasObjectsInRows(SCTAB nTab, SCROW nStartRow, SCROW nEndRow)
Definition: drwlayer.cxx:1314
constexpr SdrLayerID SC_LAYER_BACK(1)
tools::Long GetWidth() const
SdrObject * GetNamedObject(const OUString &rName, sal_uInt16 nId, SCTAB &rFoundTab) const
Definition: drwlayer.cxx:1915
ScAddress aEnd
Definition: address.hxx:501
void CopyFromClip(ScDrawLayer *pClipModel, SCTAB nSourceTab, const tools::Rectangle &rSourceRange, const ScAddress &rDestPos, const tools::Rectangle &rDestRange)
Definition: drwlayer.cxx:1610
ScAddress aNewStt
Definition: drwlayer.hxx:63
static tools::Rectangle GetCellRect(const ScDocument &rDoc, const ScAddress &rPos, bool bMergedCell)
Returns the rectangle for the passed cell address in 1/100 mm.
Definition: drwlayer.cxx:1848
void RecalcPos(SdrObject *pObj, ScDrawObjData &rData, bool bNegativePage, bool bUpdateNoteCaptionPos)
Definition: drwlayer.cxx:786
void UseHyphenator()
Definition: drwlayer.cxx:346
css::uno::Reference< css::frame::XModel > GetModel() const
virtual ~ScTabDeletedHint() override
Definition: drwlayer.cxx:187
SC_DLLPUBLIC ScRange GetRange(SCTAB nTab, const tools::Rectangle &rMMRect, bool bHiddenAsZero=true) const
Definition: documen3.cxx:1782
void DeleteObjectsInSelection(const ScMarkData &rMark)
Definition: drwlayer.cxx:1424
virtual void InsertObject(SdrObject *pObj, size_t nPos=SAL_MAX_SIZE)
EmbeddedObjectRef * pObject
ScAddress maStart
Definition: userdat.hxx:38
void FreezeIdRanges()
void GetClipArea(SCCOL &nClipX, SCROW &nClipY, bool bIncludeFiltered)
Definition: document.cxx:3118
bool ValidColRowTab(SCCOL nCol, SCROW nRow, SCTAB nTab) const
Definition: document.hxx:878
double getMaxX() const
constexpr TypedWhichId< SvxFontHeightItem > EE_CHAR_FONTHEIGHT(EE_CHAR_START+2)
void SetRight(tools::Long v)
static sal_uInt16 IsChart(const SvGlobalName &rName)
virtual void Redo() override
Definition: drwlayer.cxx:167
void MoveArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, SCCOL nDx, SCROW nDy, bool bInsDel, bool bUpdateNoteCaptionPos)
Definition: drwlayer.cxx:1268
constexpr TypedWhichId< SvxFrameDirectionItem > EE_PARA_WRITINGDIR(EE_PARA_START+0)
constexpr TypedWhichId< ScMergeAttr > ATTR_MERGE(144)
SC_DLLPUBLIC sal_uInt16 GetRowHeight(SCROW nRow, SCTAB nTab, bool bHiddenAsZero=true) const
Definition: document.cxx:4161
virtual const tools::Rectangle & GetSnapRect() const
virtual css::uno::Reference< css::uno::XInterface > createUnoModel() override
Definition: drwlayer.cxx:2348
bool IsVisible() const
SC_DLLPUBLIC ScDocumentPool * GetPool()
Definition: document.cxx:6061
bool IsEmpty() const
SC_DLLPUBLIC ScPostIt * GetNote(const ScAddress &rPos)
Notes.
Definition: document.cxx:6508
static void SetGlobalDrawPersist(SfxObjectShell *pPersist)
Definition: drwlayer.cxx:2335
void setShapeRect(const ScDocument *rDoc, tools::Rectangle rNewRect, bool bIsVisible=true)
Definition: userdat.hxx:50
static bool lcl_IsAllInRange(const ::std::vector< ScRangeList > &rRangesVector, const ScRange &rClipRange)
Definition: drwlayer.cxx:1564
void EnableUndo(bool bEnable)
void SetChartListenerCollectionNeedsUpdate(bool bFlg)
Definition: document.hxx:2150
virtual ~ScUndoObjData() override
Definition: drwlayer.cxx:97
SC_DLLPUBLIC bool RenameTab(SCTAB nTab, const OUString &rName, bool bExternalDocument=false)
Definition: document.cxx:853
ScUndoAnchorData(SdrObject *pObj, ScDocument *pDoc, SCTAB nTab)
Definition: drwlayer.cxx:139
tools::Long Left() const
virtual SdrPage * AllocPage(bool bMasterPage) override
Definition: drwlayer.cxx:360
SdrPage * getSdrPageFromSdrObject() const
void SetLeft(tools::Long v)
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
SC_DLLPUBLIC SCTAB GetTableCount() const
Definition: document.cxx:314
BASEGFX_DLLPUBLIC void transform(const B2DHomMatrix &rMatrix)
Additional class containing cell annotation data.
Definition: postit.hxx:160
bool IsMultiMarked() const
Definition: markdata.hxx:83
int nCount
const SCROW MAXROW
Definition: address.hxx:69
tools::Long Bottom() const
bool isLocked() const
void setB2DPoint(sal_uInt32 nIndex, const basegfx::B2DPoint &rValue)
#define HMM_PER_TWIPS
Definition: global.hxx:92
SCTAB Tab() const
Definition: address.hxx:271
void SetRow(SCROW nRowP)
Definition: address.hxx:275
Point maEndOffset
Definition: userdat.hxx:41
bool mbWasInHiddenRow
Definition: userdat.hxx:44
tools::Long getX() const
double getMaxY() const
tools::Long AdjustBottom(tools::Long nVertMoveDelta)
virtual void SetChanged(bool bFlg=true)
void SetName(const OUString &rName)
void SetCol(SCCOL nColP)
Definition: address.hxx:279
bool HasObjects() const
Definition: drwlayer.cxx:365
B2IRange fround(const B2DRange &rRange)
SC_DLLPUBLIC const SfxPoolItem * GetAttr(SCCOL nCol, SCROW nRow, SCTAB nTab, sal_uInt16 nWhich) const
Definition: document.cxx:4714
static XColorListRef GetStdColorList()
void ScMovePage(sal_uInt16 nOldPos, sal_uInt16 nNewPos)
Definition: drwlayer.cxx:424
const LanguageTag & GetLanguageTag() const
SdrOutliner & GetHitTestOutliner() const
bool IsClipboard() const
Definition: document.hxx:1530
bool IsValid() const
Definition: address.hxx:293
virtual void DeletePage(sal_uInt16 nPgNum)
virtual void Redo() override
Definition: drwlayer.cxx:120
bool mbResizeWithCell
Definition: userdat.hxx:43
ScDocument * GetDocument() const
Definition: drwlayer.hxx:122
const SfxPoolItem * GetItem(sal_uInt16 nSlotId) const
const tools::Rectangle & getShapeRect() const
Definition: userdat.hxx:48
void SetTab(SCTAB nTabP)
Definition: address.hxx:283
bool bDrawIsInUndo
Definition: drwlayer.cxx:85
ScAnchorType
Definition: global.hxx:383
SC_DLLPUBLIC ScDrawLayer * GetDrawLayer()
Definition: document.hxx:1059
void SetPageSize(sal_uInt16 nPageNo, const Size &rSize, bool bUpdateNoteCaptionPos)
Definition: drwlayer.cxx:566
virtual void InsertPage(SdrPage *pPage, sal_uInt16 nPos=0xFFFF) override
bool bRecording
Definition: drwlayer.hxx:95
SC_DLLPUBLIC bool ColHidden(SCCOL nCol, SCTAB nTab, SCCOL *pFirstCol=nullptr, SCCOL *pLastCol=nullptr) const
Definition: document.cxx:4445
bool GetPrintArea(ScRange &rRange, bool bSetHor, bool bSetVer) const
Definition: drwlayer.cxx:1082
SC_DLLPUBLIC void InitDrawLayer(SfxObjectShell *pDocShell=nullptr)
Definition: documen9.cxx:96
static void SetCellAnchored(SdrObject &, const ScDrawObjData &rAnchor)
Definition: drwlayer.cxx:2030
int i
ScAddress aOldStt
Definition: drwlayer.hxx:61
virtual sal_uInt16 GetObjIdentifier() const
void IncCol(SCCOL nDelta=1)
Definition: address.hxx:304
ScDrawLayer(ScDocument *pDocument, const OUString &rName)
Definition: drwlayer.cxx:239
static ScAnchorType GetAnchorType(const SdrObject &)
Definition: drwlayer.cxx:2150
sal_Int16 SCCOL
Definition: types.hxx:22
virtual void TRSetBaseGeometry(const basegfx::B2DHomMatrix &rMatrix, const basegfx::B2DPolyPolygon &rPolyPolygon)
static ScDrawObjData * GetNoteCaptionData(SdrObject *pObj, SCTAB nTab)
Returns the object data, if the passed object is a cell note caption.
Definition: drwlayer.cxx:2315
static void SetCellAnchoredFromPosition(SdrObject &rObj, const ScDocument &rDoc, SCTAB nTab, bool bResizeWithCell)
Definition: drwlayer.cxx:2040
#define SC_MOD()
Definition: scmod.hxx:253
virtual void AdjustToMaxRect(const tools::Rectangle &rMaxRect, bool bShrinkOnly=false)
Size GetSize() const
static ScRange lcl_getClipRangeFromClipDoc(ScDocument *pClipDoc, SCTAB nClipTab)
Definition: drwlayer.cxx:222
const SCCOL MAXCOL
Definition: address.hxx:70
static css::uno::Reference< css::linguistic2::XHyphenator > GetHyphenator()
void BroadcastObjectChange() const
virtual ~ScUndoAnchorData() override
Definition: drwlayer.cxx:148
ScDocument * pDoc
Definition: drwlayer.hxx:93
const SdrPage * GetPage(sal_uInt16 nPgNum) const
SdrLayer * NewLayer(const OUString &rName, sal_uInt16 nPos=0xFFFF)
void SetCalcFieldValueHdl(const Link< EditFieldInfo *, void > &rLink)
void IncRow(SCROW nDelta=1)
Definition: address.hxx:300
bool ScAddPage(SCTAB nTab)
Definition: drwlayer.cxx:385
static tools::Long TwipsToHmm(tools::Long nVal)
Definition: drwlayer.cxx:202
void DeleteUserData(sal_uInt16 nNum)
OUString ScResId(const char *pId)
Definition: scdll.cxx:95
void scale(double fX, double fY)
SdrModel & getSdrModelFromSdrObject() const
void MoveObject(SdrObject *pObj, const ScAddress &rNewPosition)
Definition: drwlayer.cxx:2239
void AddCalcUndo(std::unique_ptr< SdrUndoAction > pUndo)
Definition: drwlayer.cxx:1242
bool IsInside(const Point &rPOINT) const
virtual void SetLogicRect(const tools::Rectangle &rRect)
OUString GetNewGraphicName(tools::Long *pnCounter=nullptr) const
Definition: drwlayer.cxx:1943
void SetTop(tools::Long v)
Point maStartOffset
Definition: userdat.hxx:40
virtual void Move(const Size &rSiz)
void SetBottom(tools::Long v)
SdrObject * pObj
SfxItemPool * GetEditTextObjectPool() const
static bool IsInBlock(const ScAddress &rPos, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2)
Definition: drwlayer.cxx:508
bool IsResizeProtect() const
SC_DLLPUBLIC tools::Rectangle GetMMRect(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, SCTAB nTab, bool bHiddenAsZero=true) const
Definition: documen3.cxx:1972
const XColorListRef & GetColorList() const
virtual void Undo() override
Definition: drwlayer.cxx:101
virtual void SetRelativePos(const Point &rPnt)
SCROW GetRowForHeight(SCTAB nTab, sal_uLong nHeight) const
Given the height i.e.
Definition: document.cxx:4193
bool In(const ScAddress &) const
is Address& in Range?
Definition: address.hxx:733
tools::Long Top() const
SC_DLLPUBLIC void GetChartRanges(const OUString &rChartName, std::vector< ScRangeList > &rRanges, const ScDocument &rSheetNameDoc)
Definition: documen5.cxx:167
virtual SdrObject * RemoveObject(size_t nObjNum)
virtual void Mirror(const Point &rRef1, const Point &rRef2)
OUString GetName() const
const long LONG_MAX
SdrMetricItem makeSdrShadowYDistItem(long nDist)
SCCOL Col() const
Definition: address.hxx:267
B2DRange getRange(const B2DPolygon &rCandidate)
void AppendUserData(std::unique_ptr< SdrObjUserData > pData)
virtual SdrLayerID GetLayer() const
tools::Long AdjustTop(tools::Long nVertMoveDelta)
basegfx::B2DRange b2DRectangleFromRectangle(const ::tools::Rectangle &rRect)
SfxItemPool * GetSecondaryPool() const
SfxItemPool * m_pItemPool
void MoveCells(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, SCCOL nDx, SCROW nDy, bool bUpdateNoteCaptionPos)
Definition: drwlayer.cxx:514
void setLock(bool bLock)
SdrObject * Next()
bool bHyphenatorSet
Definition: drwlayer.hxx:97
void ResizeLastRectFromAnchor(const SdrObject *pObj, ScDrawObjData &rData, bool bUseLogicRect, bool bNegativePage, bool bCanResize, bool bHiddenAsZero=true)
Definition: drwlayer.cxx:632
sal_Int32 SCROW
Definition: types.hxx:18
virtual void Undo() override
Definition: drwlayer.cxx:152
double getMinY() const
void SetDefaultMetric(MapUnit eNewMetric)
constexpr SdrLayerID SC_LAYER_HIDDEN(4)
void ScRenamePage(SCTAB nTab, const OUString &rNewName)
Definition: drwlayer.cxx:417
std::unique_ptr< SdrUndoGroup > GetCalcUndo()
Definition: drwlayer.cxx:1260
constexpr TypedWhichId< SvxFontHeightItem > EE_CHAR_FONTHEIGHT_CTL(EE_CHAR_START+20)
unsigned char sal_uInt8
void setWidth(tools::Long n)
sal_uInt16 GetId() const
static ScDrawObjData * GetObjDataTab(SdrObject *pObj, SCTAB nTab)
Definition: drwlayer.cxx:2296
#define MAXMM
Definition: drwlayer.cxx:200
void SetObjectShell(SfxObjectShell *pShell)
virtual void NbcMove(const Size &rSiz)
constexpr SdrLayerID SC_LAYER_FRONT(0)
static ScDrawObjData * GetNonRotatedObjData(SdrObject *pObj, bool bCreate=false)
Definition: drwlayer.cxx:2263
OUString aName
SdrObjUserData * GetUserData(sal_uInt16 nNum) const
#define SC_UD_MACRODATA
Definition: userdat.hxx:31
constexpr SdrLayerID SC_LAYER_INTERN(2)
static void MirrorRectRTL(tools::Rectangle &rRect)
Definition: drwlayer.cxx:1840
static void UpdateCellAnchorFromPositionEnd(const SdrObject &rObj, ScDrawObjData &rAnchor, const ScDocument &rDoc, SCTAB nTab, bool bUseLogicRect=true)
Definition: drwlayer.cxx:2109
virtual SdrObject * CloneSdrObject(SdrModel &rTargetModel) const
static OUString GetVisibleName(const SdrObject *pObj)
Definition: drwlayer.cxx:1889
std::unique_ptr< SdrUndoGroup > pUndoGroup
Definition: drwlayer.hxx:94
virtual SdrPage * RemovePage(sal_uInt16 nPgNum) override
static bool isKorean(LanguageType nLang)
OUString aName
Definition: drwlayer.hxx:92
sal_uInt16 GetUserDataCount() const
void translate(double fX, double fY)
virtual ~ScTabSizeChangedHint() override
Definition: drwlayer.cxx:196
ScAddress aNewEnd
Definition: drwlayer.hxx:64
SC_DLLPUBLIC bool RowHidden(SCROW nRow, SCTAB nTab, SCROW *pFirstRow=nullptr, SCROW *pLastRow=nullptr) const
Definition: document.cxx:4429
virtual void MovePage(sal_uInt16 nPgNum, sal_uInt16 nNewPos)
void SetControlLayerName(const OUString &rNewName)
SC_DLLPUBLIC ScColumnsRange GetColumnsRange(SCTAB nTab, SCCOL nColBegin, SCCOL nColEnd) const
Definition: document.cxx:2521
#define SC_UD_OBJDATA
Definition: userdat.hxx:29
bool HasObjectsAnchoredInRange(const ScRange &rRange)
Definition: drwlayer.cxx:2215
tools::Long GetHeight() const
bool mbWasResizeWithCell
Definition: drwlayer.hxx:78
virtual void SetSnapRect(const tools::Rectangle &rRect)
virtual bool shouldKeepAspectRatio() const
static bool IsNoteCaption(SdrObject *pObj)
Returns true, if the passed object is the caption of a cell note.
Definition: drwlayer.cxx:2309
double ConvertDoubleValue(double nValue, sal_Int64 mnBaseValue, sal_uInt16 nDecDigits, FieldUnit eInUnit, FieldUnit eOutUnit)
SfxObjectShell * GetDocumentShell() const
Definition: document.hxx:1058
tools::Long AdjustLeft(tools::Long nHorzMoveDelta)
ScAddress aOldEnd
Definition: drwlayer.hxx:62
bool IsUndoEnabled() const
Definition: document.hxx:1531
constexpr TypedWhichId< SvxFontHeightItem > EE_CHAR_FONTHEIGHT_CJK(EE_CHAR_START+19)
const SfxItemPool & GetItemPool() const
double getMinX() const
SCROW GetRowMerge() const
Definition: attrib.hxx:70
void SetScaleUnit(MapUnit eMap)
void GetMultiMarkArea(ScRange &rRange) const
Definition: markdata.cxx:117
virtual const tools::Rectangle & GetLogicRect() const
void ScCopyPage(sal_uInt16 nOldPos, sal_uInt16 nNewPos)
Definition: drwlayer.cxx:431
ScTabDeletedHint(SCTAB nTabNo)
Definition: drwlayer.cxx:182
static E3dObjFactory * pF3d
Definition: drwlayer.cxx:80
void SetDisableTextEditUsesCommonUndoManager(bool bNew)
static sal_uInt16 nInst
Definition: drwlayer.cxx:81
virtual bool TRGetBaseGeometry(basegfx::B2DHomMatrix &rMatrix, basegfx::B2DPolyPolygon &rPolyPolygon) const
const SdrLayerAdmin & GetLayerAdmin() const
SC_DLLPUBLIC sal_uInt16 GetColWidth(SCCOL nCol, SCTAB nTab, bool bHiddenAsZero=true) const
Definition: document.cxx:4120
void SetChartRanges(const OUString &rChartName, const std::vector< ScRangeList > &rRanges)
Definition: documen5.cxx:184
ScAddress maEnd
Definition: userdat.hxx:39
SdrInventor GetInventor() const
void SetName(const OUString &rStr)
static tools::Long HmmToTwips(tools::Long nVal)
Definition: drwlayer.cxx:208
void SetPropertyList(XPropertyListRef const &p)
virtual Point GetPoint(sal_uInt32 i) const
#define LANGUAGE_JAPANESE
void ClearModel(bool bCalledFromDestructor)
void ScRemovePage(SCTAB nTab)
Definition: drwlayer.cxx:399
constexpr SdrLayerID SC_LAYER_CONTROLS(3)
const tools::Rectangle & getLastCellRect() const
Definition: userdat.hxx:49
SC_DLLPUBLIC bool GetName(SCTAB nTab, OUString &rName) const
Definition: document.cxx:213
ScTabSizeChangedHint(SCTAB nTabNo)
Definition: drwlayer.cxx:191
tools::Long Right() const
SC_DLLPUBLIC sal_uLong GetColOffset(SCCOL nCol, SCTAB nTab, bool bHiddenAsZero=true) const
Definition: document.cxx:4224
static bool IsResizeWithCell(const SdrObject &rObj)
Definition: drwlayer.cxx:2133
ScDocument * mpDoc
Definition: drwlayer.hxx:79
sal_uInt16 GetPageCount() const
void setHeight(tools::Long n)
sal_Int16 SCTAB
Definition: types.hxx:23
SdrMetricItem makeSdrShadowXDistItem(long nDist)
SC_DLLPUBLIC sal_uLong GetRowOffset(SCROW nRow, SCTAB nTab, bool bHiddenAsZero=true) const
Definition: document.cxx:4232
void SetPoolDefaultItem(const SfxPoolItem &)
static bool IsNamedObject(const SdrObject *pObj, const OUString &rName)
Definition: drwlayer.cxx:1905
void CopyToClip(ScDocument *pClipDoc, SCTAB nTab, const tools::Rectangle &rRange)
Definition: drwlayer.cxx:1501
virtual SdrModel * AllocModel() const override
Definition: drwlayer.cxx:377