LibreOffice Module sc (master) 1
detfunc.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 <scitems.hxx>
21#include <svtools/colorcfg.hxx>
22#include <editeng/eeitem.hxx>
25#include <svx/sdshitm.hxx>
26#include <svx/sdsxyitm.hxx>
27#include <svx/sdtditm.hxx>
28#include <svx/svditer.hxx>
29#include <svx/svdocapt.hxx>
30#include <svx/svdocirc.hxx>
31#include <svx/svdopath.hxx>
32#include <svx/svdorect.hxx>
33#include <svx/svdpage.hxx>
34#include <svx/svdundo.hxx>
35#include <svx/xfillit0.hxx>
36#include <svx/xflclit.hxx>
37#include <svx/xlnclit.hxx>
38#include <svx/xlnedcit.hxx>
39#include <svx/xlnedit.hxx>
40#include <svx/xlnedwit.hxx>
41#include <svx/xlnstcit.hxx>
42#include <svx/xlnstit.hxx>
43#include <svx/xlnstwit.hxx>
44#include <svx/xlnwtit.hxx>
45#include <svx/sdtagitm.hxx>
46#include <svx/sxcecitm.hxx>
47#include <svl/whiter.hxx>
48#include <osl/diagnose.h>
49
53
54#include <attrib.hxx>
55#include <detfunc.hxx>
56#include <document.hxx>
57#include <dociter.hxx>
58#include <drwlayer.hxx>
59#include <userdat.hxx>
60#include <validat.hxx>
61#include <formulacell.hxx>
62#include <docpool.hxx>
63#include <patattr.hxx>
64#include <scmod.hxx>
65#include <postit.hxx>
66#include <reftokenhelper.hxx>
67#include <formulaiter.hxx>
68#include <cellvalue.hxx>
69
70#include <vector>
71#include <memory>
72
73using ::std::vector;
74using namespace com::sun::star;
75
76namespace {
77
78enum DetInsertResult { // return-values for inserting in one level
79 DET_INS_CONTINUE,
80 DET_INS_INSERTED,
81 DET_INS_EMPTY,
82 DET_INS_CIRCULAR };
83
84}
85
87{
88private:
93 SfxItemSet aCircleSet; //TODO: individually ?
94 sal_uInt16 nMaxLevel;
95
96public:
97 explicit ScDetectiveData( SdrModel* pModel );
98
104
105 void SetMaxLevel( sal_uInt16 nVal ) { nMaxLevel = nVal; }
106 sal_uInt16 GetMaxLevel() const { return nMaxLevel; }
107};
108
109namespace {
110
111class ScCommentData
112{
113public:
114 ScCommentData( ScDocument& rDoc, SdrModel* pModel );
115
116 SfxItemSet& GetCaptionSet() { return aCaptionSet; }
117 void UpdateCaptionSet( const SfxItemSet& rItemSet );
118
119private:
120 SfxItemSet aCaptionSet;
121};
122
123}
124
129
130static bool lcl_HasThickLine( const SdrObject& rObj )
131{
132 // thin lines get width 0 -> everything greater 0 is a thick line
133
134 return rObj.GetMergedItem(XATTR_LINEWIDTH).GetValue() > 0;
135}
136
138 aBoxSet( pModel->GetItemPool(), svl::Items<SDRATTR_START, SDRATTR_END> ),
139 aArrowSet( pModel->GetItemPool(), svl::Items<SDRATTR_START, SDRATTR_END> ),
140 aToTabSet( pModel->GetItemPool(), svl::Items<SDRATTR_START, SDRATTR_END> ),
141 aFromTabSet( pModel->GetItemPool(), svl::Items<SDRATTR_START, SDRATTR_END> ),
142 aCircleSet( pModel->GetItemPool(), svl::Items<SDRATTR_START, SDRATTR_END> ),
143 nMaxLevel(0)
144{
145
147 aBoxSet.Put( XFillStyleItem( drawing::FillStyle_NONE ) );
148
149 // create default line endings (like XLineEndList::Create)
150 // to be independent from the configured line endings
151
152 basegfx::B2DPolygon aTriangle;
153 aTriangle.append(basegfx::B2DPoint(10.0, 0.0));
154 aTriangle.append(basegfx::B2DPoint(0.0, 30.0));
155 aTriangle.append(basegfx::B2DPoint(20.0, 30.0));
156 aTriangle.setClosed(true);
157
158 basegfx::B2DPolygon aSquare;
159 aSquare.append(basegfx::B2DPoint(0.0, 0.0));
160 aSquare.append(basegfx::B2DPoint(10.0, 0.0));
161 aSquare.append(basegfx::B2DPoint(10.0, 10.0));
162 aSquare.append(basegfx::B2DPoint(0.0, 10.0));
163 aSquare.setClosed(true);
164
166 aCircle.setClosed(true);
167
168 const OUString aName;
169
175 aArrowSet.Put( XLineEndCenterItem( false ) );
176
182 aToTabSet.Put( XLineEndCenterItem( false ) );
183
190
192 aCircleSet.Put( XFillStyleItem( drawing::FillStyle_NONE ) );
193 aCircleSet.Put( XLineWidthItem( 55 ) ); // 54 = 1 Pixel
194}
195
196ScCommentData::ScCommentData( ScDocument& rDoc, SdrModel* pModel ) :
197 aCaptionSet( pModel->GetItemPool(), svl::Items<SDRATTR_START, SDRATTR_END, EE_ITEMS_START, EE_ITEMS_END> )
198{
199 basegfx::B2DPolygon aTriangle;
200 aTriangle.append(basegfx::B2DPoint(10.0, 0.0));
201 aTriangle.append(basegfx::B2DPoint(0.0, 30.0));
202 aTriangle.append(basegfx::B2DPoint(20.0, 30.0));
203 aTriangle.setClosed(true);
204
205 aCaptionSet.Put( XLineStartItem( OUString(), basegfx::B2DPolyPolygon(aTriangle)));
206 aCaptionSet.Put( XLineStartWidthItem( 200 ) );
207 aCaptionSet.Put( XLineStartCenterItem( false ) );
208 aCaptionSet.Put( XFillStyleItem( drawing::FillStyle_SOLID ) );
210 aCaptionSet.Put( XFillColorItem( OUString(), aYellow ) );
211
212 // shadow
213 // SdrShadowItem has sal_False, instead the shadow is set for the rectangle
214 // only with SetSpecialTextBoxShadow when the object is created
215 // (item must be set to adjust objects from older files)
216 aCaptionSet.Put( makeSdrShadowItem( false ) );
217 aCaptionSet.Put( makeSdrShadowXDistItem( 100 ) );
218 aCaptionSet.Put( makeSdrShadowYDistItem( 100 ) );
219
220 // text attributes
221 aCaptionSet.Put( makeSdrTextLeftDistItem( 100 ) );
222 aCaptionSet.Put( makeSdrTextRightDistItem( 100 ) );
223 aCaptionSet.Put( makeSdrTextUpperDistItem( 100 ) );
224 aCaptionSet.Put( makeSdrTextLowerDistItem( 100 ) );
225
226 aCaptionSet.Put( makeSdrTextAutoGrowWidthItem( false ) );
227 aCaptionSet.Put( makeSdrTextAutoGrowHeightItem( true ) );
228
229 // do use the default cell style, so the user has a chance to
230 // modify the font for the annotations
231 rDoc.GetPool()->GetDefaultItem(ATTR_PATTERN).FillEditItemSet( &aCaptionSet );
232
233 // support the best position for the tail connector now that
234 // that notes can be resized and repositioned.
235 aCaptionSet.Put( SdrCaptionEscDirItem( SdrCaptionEscDir::BestFit) );
236}
237
238void ScCommentData::UpdateCaptionSet( const SfxItemSet& rItemSet )
239{
240 SfxWhichIter aWhichIter( rItemSet );
241 const SfxPoolItem* pPoolItem = nullptr;
242
243 for( sal_uInt16 nWhich = aWhichIter.FirstWhich(); nWhich > 0; nWhich = aWhichIter.NextWhich() )
244 {
245 if(aWhichIter.GetItemState(false, &pPoolItem) == SfxItemState::SET)
246 {
247 switch(nWhich)
248 {
249 case SDRATTR_SHADOW:
250 // use existing Caption default - appears that setting this
251 // to true screws up the tail appearance. See also comment
252 // for default setting above.
253 break;
255 // use existing Caption default - svx sets a value of 35
256 // but default 100 gives a better appearance.
257 break;
259 // use existing Caption default - svx sets a value of 35
260 // but default 100 gives a better appearance.
261 break;
262
263 default:
264 aCaptionSet.Put(*pPoolItem);
265 }
266 }
267 }
268}
269
271{
272 rDoc.SetStreamValid(nTab, false);
273}
274
275static bool Intersect( SCCOL nStartCol1, SCROW nStartRow1, SCCOL nEndCol1, SCROW nEndRow1,
276 SCCOL nStartCol2, SCROW nStartRow2, SCCOL nEndCol2, SCROW nEndRow2 )
277{
278 return nEndCol1 >= nStartCol2 && nEndCol2 >= nStartCol1 &&
279 nEndRow1 >= nStartRow2 && nEndRow2 >= nStartRow1;
280}
281
282bool ScDetectiveFunc::HasError( const ScRange& rRange, ScAddress& rErrPos )
283{
284 rErrPos = rRange.aStart;
285 FormulaError nError = FormulaError::NONE;
286
287 ScCellIterator aIter( rDoc, rRange);
288 for (bool bHasCell = aIter.first(); bHasCell; bHasCell = aIter.next())
289 {
290 if (aIter.getType() != CELLTYPE_FORMULA)
291 continue;
292
293 nError = aIter.getFormulaCell()->GetErrCode();
294 if (nError != FormulaError::NONE)
295 rErrPos = aIter.GetPos();
296 }
297
298 return (nError != FormulaError::NONE);
299}
300
302{
303 OSL_ENSURE( rDoc.ValidColRow( nCol, nRow ), "ScDetectiveFunc::GetDrawPos - invalid cell address" );
304 nCol = rDoc.SanitizeCol( nCol );
305 nRow = rDoc.SanitizeRow( nRow );
306
307 Point aPos;
308
309 switch( eMode )
310 {
312 break;
314 ++nCol;
315 ++nRow;
316 break;
318 aPos.AdjustX(rDoc.GetColWidth( nCol, nTab ) / 4 );
319 aPos.AdjustY(rDoc.GetRowHeight( nRow, nTab ) / 2 );
320 break;
321 }
322
323 for ( SCCOL i = 0; i < nCol; ++i )
324 aPos.AdjustX(rDoc.GetColWidth( i, nTab ) );
325 aPos.AdjustY(rDoc.GetRowHeight( 0, nRow - 1, nTab ) );
326
329
330 if ( rDoc.IsNegativePage( nTab ) )
331 aPos.setX( aPos.X() * -1 );
332
333 return aPos;
334}
335
337{
338 tools::Rectangle aRect(
339 GetDrawPos( ::std::min( nCol1, nCol2 ), ::std::min( nRow1, nRow2 ), DrawPosMode::TopLeft ),
340 GetDrawPos( ::std::max( nCol1, nCol2 ), ::std::max( nRow1, nRow2 ), DrawPosMode::BottomRight ) );
341 aRect.Normalize(); // reorder left/right in RTL sheets
342 return aRect;
343}
344
346{
347 return GetDrawRect( nCol, nRow, nCol, nRow );
348}
349
350static bool lcl_IsOtherTab( const basegfx::B2DPolyPolygon& rPolyPolygon )
351{
352 // test if rPolygon is the line end for "other table" (rectangle)
353 if(1 == rPolyPolygon.count())
354 {
355 const basegfx::B2DPolygon& aSubPoly(rPolyPolygon.getB2DPolygon(0));
356
357 // #i73305# circle consists of 4 segments, too, distinguishable from square by
358 // the use of control points
359 if(4 == aSubPoly.count() && aSubPoly.isClosed() && !aSubPoly.areControlPointsUsed())
360 {
361 return true;
362 }
363 }
364
365 return false;
366}
367
369 SCCOL nEndCol, SCROW nEndRow, SCTAB nEndTab )
370{
371 bool bStartAlien = ( rStart.Tab() != nTab );
372 bool bEndAlien = ( nEndTab != nTab );
373
374 if (bStartAlien && bEndAlien)
375 {
376 OSL_FAIL("bStartAlien && bEndAlien");
377 return true;
378 }
379
380 tools::Rectangle aStartRect;
381 tools::Rectangle aEndRect;
382 if (!bStartAlien)
383 aStartRect = GetDrawRect( rStart.Col(), rStart.Row() );
384 if (!bEndAlien)
385 aEndRect = GetDrawRect( nEndCol, nEndRow );
386
387 ScDrawLayer* pModel = rDoc.GetDrawLayer();
388 SdrPage* pPage = pModel->GetPage(static_cast<sal_uInt16>(nTab));
389 OSL_ENSURE(pPage,"Page ?");
390
391 bool bFound = false;
392 SdrObjListIter aIter( pPage, SdrIterMode::Flat );
393 SdrObject* pObject = aIter.Next();
394 while (pObject && !bFound)
395 {
396 if ( pObject->GetLayer()==SC_LAYER_INTERN &&
397 pObject->IsPolyObj() && pObject->GetPointCount()==2 )
398 {
399 const SfxItemSet& rSet = pObject->GetMergedItemSet();
400
401 bool bObjStartAlien =
402 lcl_IsOtherTab( rSet.Get(XATTR_LINESTART).GetLineStartValue() );
403 bool bObjEndAlien =
404 lcl_IsOtherTab( rSet.Get(XATTR_LINEEND).GetLineEndValue() );
405
406 bool bStartHit = bStartAlien ? bObjStartAlien :
407 ( !bObjStartAlien && aStartRect.Contains(pObject->GetPoint(0)) );
408 bool bEndHit = bEndAlien ? bObjEndAlien :
409 ( !bObjEndAlien && aEndRect.Contains(pObject->GetPoint(1)) );
410
411 if ( bStartHit && bEndHit )
412 bFound = true;
413 }
414 pObject = aIter.Next();
415 }
416
417 return bFound;
418}
419
421{
422 if ( pObject->GetLayer()==SC_LAYER_INTERN &&
423 pObject->IsPolyObj() && pObject->GetPointCount()==2 )
424 {
425 const SfxItemSet& rSet = pObject->GetMergedItemSet();
426
427 bool bObjStartAlien =
428 lcl_IsOtherTab( rSet.Get(XATTR_LINESTART).GetLineStartValue() );
429 bool bObjEndAlien =
430 lcl_IsOtherTab( rSet.Get(XATTR_LINEEND).GetLineEndValue() );
431
432 return !bObjStartAlien && !bObjEndAlien;
433 }
434
435 return false;
436}
437
438// InsertXXX: called from DrawEntry/DrawAlienEntry and InsertObject
439
441 SCCOL nRefStartCol, SCROW nRefStartRow,
442 SCCOL nRefEndCol, SCROW nRefEndRow,
443 bool bFromOtherTab, bool bRed,
444 ScDetectiveData& rData )
445{
446 ScDrawLayer* pModel = rDoc.GetDrawLayer();
447 SdrPage* pPage = pModel->GetPage(static_cast<sal_uInt16>(nTab));
448
449 bool bArea = ( nRefStartCol != nRefEndCol || nRefStartRow != nRefEndRow );
450 if (bArea && !bFromOtherTab)
451 {
452 // insert the rectangle before the arrow - this is relied on in FindFrameForObject
453
454 tools::Rectangle aRect = GetDrawRect( nRefStartCol, nRefStartRow, nRefEndCol, nRefEndRow );
456 *pModel,
457 aRect);
458
459 pBox->SetMergedItemSetAndBroadcast(rData.GetBoxSet());
460
461 pBox->SetLayer( SC_LAYER_INTERN );
462 pPage->InsertObject( pBox.get() );
463 pModel->AddCalcUndo( std::make_unique<SdrUndoInsertObj>( *pBox ) );
464
465 ScDrawObjData* pData = ScDrawLayer::GetObjData( pBox.get(), true );
466 pData->maStart.Set( nRefStartCol, nRefStartRow, nTab);
467 pData->maEnd.Set( nRefEndCol, nRefEndRow, nTab);
468 }
469
470 Point aStartPos = GetDrawPos( nRefStartCol, nRefStartRow, DrawPosMode::DetectiveArrow );
471 Point aEndPos = GetDrawPos( nCol, nRow, DrawPosMode::DetectiveArrow );
472
473 if (bFromOtherTab)
474 {
475 bool bNegativePage = rDoc.IsNegativePage( nTab );
476 tools::Long nPageSign = bNegativePage ? -1 : 1;
477
478 aStartPos = Point( aEndPos.X() - 1000 * nPageSign, aEndPos.Y() - 1000 );
479 if (aStartPos.X() * nPageSign < 0)
480 aStartPos.AdjustX(2000 * nPageSign );
481 if (aStartPos.Y() < 0)
482 aStartPos.AdjustY(2000 );
483 }
484
485 SfxItemSet& rAttrSet = bFromOtherTab ? rData.GetFromTabSet() : rData.GetArrowSet();
486
487 if (bArea && !bFromOtherTab)
488 rAttrSet.Put( XLineWidthItem( 50 ) ); // range
489 else
490 rAttrSet.Put( XLineWidthItem( 0 ) ); // single reference
491
492 Color nColor = ( bRed ? GetErrorColor() : GetArrowColor() );
493 rAttrSet.Put( XLineColorItem( OUString(), nColor ) );
494
495 basegfx::B2DPolygon aTempPoly;
496 aTempPoly.append(basegfx::B2DPoint(aStartPos.X(), aStartPos.Y()));
497 aTempPoly.append(basegfx::B2DPoint(aEndPos.X(), aEndPos.Y()));
499 *pModel,
500 SdrObjKind::Line,
501 basegfx::B2DPolyPolygon(aTempPoly));
502 pArrow->NbcSetLogicRect(tools::Rectangle::Normalize(aStartPos,aEndPos)); //TODO: needed ???
503 pArrow->SetMergedItemSetAndBroadcast(rAttrSet);
504
505 pArrow->SetLayer( SC_LAYER_INTERN );
506 pPage->InsertObject( pArrow.get() );
507 pModel->AddCalcUndo( std::make_unique<SdrUndoInsertObj>( *pArrow ) );
508
509 ScDrawObjData* pData = ScDrawLayer::GetObjData(pArrow.get(), true);
510 if (bFromOtherTab)
511 pData->maStart.SetInvalid();
512 else
513 pData->maStart.Set( nRefStartCol, nRefStartRow, nTab);
514
515 pData->maEnd.Set( nCol, nRow, nTab);
517
518 Modified();
519}
520
522 SCCOL nEndCol, SCROW nEndRow, bool bRed,
523 ScDetectiveData& rData )
524{
525 ScDrawLayer* pModel = rDoc.GetDrawLayer();
526 SdrPage* pPage = pModel->GetPage(static_cast<sal_uInt16>(nTab));
527
528 bool bArea = ( nStartCol != nEndCol || nStartRow != nEndRow );
529 if (bArea)
530 {
531 tools::Rectangle aRect = GetDrawRect( nStartCol, nStartRow, nEndCol, nEndRow );
533 *pModel,
534 aRect);
535
536 pBox->SetMergedItemSetAndBroadcast(rData.GetBoxSet());
537
538 pBox->SetLayer( SC_LAYER_INTERN );
539 pPage->InsertObject( pBox.get() );
540 pModel->AddCalcUndo( std::make_unique<SdrUndoInsertObj>( *pBox ) );
541
542 ScDrawObjData* pData = ScDrawLayer::GetObjData( pBox.get(), true );
543 pData->maStart.Set( nStartCol, nStartRow, nTab);
544 pData->maEnd.Set( nEndCol, nEndRow, nTab);
545 }
546
547 bool bNegativePage = rDoc.IsNegativePage( nTab );
548 tools::Long nPageSign = bNegativePage ? -1 : 1;
549
550 Point aStartPos = GetDrawPos( nStartCol, nStartRow, DrawPosMode::DetectiveArrow );
551 Point aEndPos( aStartPos.X() + 1000 * nPageSign, aStartPos.Y() - 1000 );
552 if (aEndPos.Y() < 0)
553 aEndPos.AdjustY(2000 );
554
555 SfxItemSet& rAttrSet = rData.GetToTabSet();
556 if (bArea)
557 rAttrSet.Put( XLineWidthItem( 50 ) ); // range
558 else
559 rAttrSet.Put( XLineWidthItem( 0 ) ); // single reference
560
561 Color nColor = ( bRed ? GetErrorColor() : GetArrowColor() );
562 rAttrSet.Put( XLineColorItem( OUString(), nColor ) );
563
564 basegfx::B2DPolygon aTempPoly;
565 aTempPoly.append(basegfx::B2DPoint(aStartPos.X(), aStartPos.Y()));
566 aTempPoly.append(basegfx::B2DPoint(aEndPos.X(), aEndPos.Y()));
568 *pModel,
569 SdrObjKind::Line,
570 basegfx::B2DPolyPolygon(aTempPoly));
571 pArrow->NbcSetLogicRect(tools::Rectangle::Normalize(aStartPos,aEndPos)); //TODO: needed ???
572
573 pArrow->SetMergedItemSetAndBroadcast(rAttrSet);
574
575 pArrow->SetLayer( SC_LAYER_INTERN );
576 pPage->InsertObject( pArrow.get() );
577 pModel->AddCalcUndo( std::make_unique<SdrUndoInsertObj>( *pArrow ) );
578
579 ScDrawObjData* pData = ScDrawLayer::GetObjData( pArrow.get(), true );
580 pData->maStart.Set( nStartCol, nStartRow, nTab);
581 pData->maEnd.SetInvalid();
582
583 Modified();
584}
585
586// DrawEntry: formula from this spreadsheet,
587// reference on this or other
588// DrawAlienEntry: formula from other spreadsheet,
589// reference on this
590
591// return FALSE: there was already an arrow
592
594 const ScRange& rRef,
595 ScDetectiveData& rData )
596{
597 if ( HasArrow( rRef.aStart, nCol, nRow, nTab ) )
598 return false;
599
600 ScAddress aErrorPos;
601 bool bError = HasError( rRef, aErrorPos );
602 bool bAlien = ( rRef.aEnd.Tab() < nTab || rRef.aStart.Tab() > nTab );
603
604 InsertArrow( nCol, nRow,
605 rRef.aStart.Col(), rRef.aStart.Row(),
606 rRef.aEnd.Col(), rRef.aEnd.Row(),
607 bAlien, bError, rData );
608 return true;
609}
610
612 ScDetectiveData& rData )
613{
614 if ( HasArrow( rRef.aStart, 0, 0, nTab+1 ) )
615 return false;
616
617 ScAddress aErrorPos;
618 bool bError = HasError( rRef, aErrorPos );
619
620 InsertToOtherTab( rRef.aStart.Col(), rRef.aStart.Row(),
621 rRef.aEnd.Col(), rRef.aEnd.Row(),
622 bError, rData );
623 return true;
624}
625
627{
628 ScDrawLayer* pModel = rDoc.GetDrawLayer();
629 SdrPage* pPage = pModel->GetPage(static_cast<sal_uInt16>(nTab));
630
631 tools::Rectangle aRect = ScDrawLayer::GetCellRect(rDoc, ScAddress(nCol, nRow, nTab), true);
632 aRect.AdjustLeft( -250 );
633 aRect.AdjustRight(250 );
634 aRect.AdjustTop( -70 );
635 aRect.AdjustBottom(70 );
636
638 *pModel,
639 SdrCircKind::Full,
640 aRect);
641 SfxItemSet& rAttrSet = rData.GetCircleSet();
642
643 pCircle->SetMergedItemSetAndBroadcast(rAttrSet);
644
645 pCircle->SetLayer( SC_LAYER_INTERN );
646 pPage->InsertObject( pCircle.get() );
647 pModel->AddCalcUndo( std::make_unique<SdrUndoInsertObj>( *pCircle ) );
648
649 ScDrawObjData* pData = ScDrawLayer::GetObjData( pCircle.get(), true );
650 pData->maStart.Set( nCol, nRow, nTab);
651 pData->maEnd.SetInvalid();
653
654 Modified();
655}
656
657void ScDetectiveFunc::DeleteArrowsAt( SCCOL nCol, SCROW nRow, bool bDestPnt )
658{
659 tools::Rectangle aRect = GetDrawRect( nCol, nRow );
660
661 ScDrawLayer* pModel = rDoc.GetDrawLayer();
662 SdrPage* pPage = pModel->GetPage(static_cast<sal_uInt16>(nTab));
663 OSL_ENSURE(pPage,"Page ?");
664
665 pPage->RecalcObjOrdNums();
666
667 const size_t nObjCount = pPage->GetObjCount();
668 if (!nObjCount)
669 return;
670
671 size_t nDelCount = 0;
672 std::unique_ptr<SdrObject*[]> ppObj(new SdrObject*[nObjCount]);
673
674 SdrObjListIter aIter( pPage, SdrIterMode::Flat );
675 SdrObject* pObject = aIter.Next();
676 while (pObject)
677 {
678 if ( pObject->GetLayer()==SC_LAYER_INTERN &&
679 pObject->IsPolyObj() && pObject->GetPointCount()==2 )
680 {
681 if (aRect.Contains(pObject->GetPoint(bDestPnt ? 1 : 0))) // start/destinationpoint
682 ppObj[nDelCount++] = pObject;
683 }
684
685 pObject = aIter.Next();
686 }
687
688 const bool bRecording = pModel->IsRecording();
689
690 if (bRecording)
691 {
692 for (size_t i=1; i<=nDelCount; ++i)
693 pModel->AddCalcUndo(std::make_unique<SdrUndoDelObj>(*ppObj[nDelCount-i]));
694 }
695
696 for (size_t i=1; i<=nDelCount; ++i)
697 {
698 // remove the object from the drawing page, delete if undo is disabled
699 pPage->RemoveObject(ppObj[nDelCount-i]->GetOrdNum());
700 }
701
702 ppObj.reset();
703
704 Modified();
705}
706
707 // delete box around reference
708
709#define SC_DET_TOLERANCE 50
710
711static bool RectIsPoints( const tools::Rectangle& rRect, const Point& rStart, const Point& rEnd )
712{
713 return rRect.Left() >= rStart.X() - SC_DET_TOLERANCE
714 && rRect.Left() <= rStart.X() + SC_DET_TOLERANCE
715 && rRect.Right() >= rEnd.X() - SC_DET_TOLERANCE
716 && rRect.Right() <= rEnd.X() + SC_DET_TOLERANCE
717 && rRect.Top() >= rStart.Y() - SC_DET_TOLERANCE
718 && rRect.Top() <= rStart.Y() + SC_DET_TOLERANCE
719 && rRect.Bottom() >= rEnd.Y() - SC_DET_TOLERANCE
720 && rRect.Bottom() <= rEnd.Y() + SC_DET_TOLERANCE;
721}
722
723#undef SC_DET_TOLERANCE
724
725void ScDetectiveFunc::DeleteBox( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
726{
727 tools::Rectangle aCornerRect = GetDrawRect( nCol1, nRow1, nCol2, nRow2 );
728 Point aStartCorner = aCornerRect.TopLeft();
729 Point aEndCorner = aCornerRect.BottomRight();
730 tools::Rectangle aObjRect;
731
732 ScDrawLayer* pModel = rDoc.GetDrawLayer();
733 SdrPage* pPage = pModel->GetPage(static_cast<sal_uInt16>(nTab));
734 OSL_ENSURE(pPage,"Page ?");
735
736 pPage->RecalcObjOrdNums();
737
738 const size_t nObjCount = pPage->GetObjCount();
739 if (!nObjCount)
740 return;
741
742 size_t nDelCount = 0;
743 std::unique_ptr<SdrObject*[]> ppObj(new SdrObject*[nObjCount]);
744
745 SdrObjListIter aIter( pPage, SdrIterMode::Flat );
746 SdrObject* pObject = aIter.Next();
747 while (pObject)
748 {
749 if ( pObject->GetLayer() == SC_LAYER_INTERN )
750 if ( auto pSdrRectObj = dynamic_cast< const SdrRectObj* >(pObject) )
751 {
752 aObjRect = pSdrRectObj->GetLogicRect();
753 aObjRect.Normalize();
754 if ( RectIsPoints( aObjRect, aStartCorner, aEndCorner ) )
755 ppObj[nDelCount++] = pObject;
756 }
757
758 pObject = aIter.Next();
759 }
760
761 for (size_t i=1; i<=nDelCount; ++i)
762 pModel->AddCalcUndo( std::make_unique<SdrUndoRemoveObj>( *ppObj[nDelCount-i] ) );
763
764 for (size_t i=1; i<=nDelCount; ++i)
765 pPage->RemoveObject( ppObj[nDelCount-i]->GetOrdNum() );
766
767 ppObj.reset();
768
769 Modified();
770}
771
773 ScDetectiveData& rData, sal_uInt16 nLevel )
774{
775 sal_uInt16 nResult = DET_INS_EMPTY;
776
777 ScCellIterator aIter( rDoc, rRef);
778 for (bool bHasCell = aIter.first(); bHasCell; bHasCell = aIter.next())
779 {
780 if (aIter.getType() != CELLTYPE_FORMULA)
781 continue;
782
783 const ScAddress& rPos = aIter.GetPos();
784 switch (InsertPredLevel(rPos.Col(), rPos.Row(), rData, nLevel))
785 {
786 case DET_INS_INSERTED:
787 nResult = DET_INS_INSERTED;
788 break;
789 case DET_INS_CONTINUE:
790 if (nResult != DET_INS_INSERTED)
791 nResult = DET_INS_CONTINUE;
792 break;
793 case DET_INS_CIRCULAR:
794 if (nResult == DET_INS_EMPTY)
795 nResult = DET_INS_CIRCULAR;
796 break;
797 default:
798 ;
799 }
800 }
801
802 return nResult;
803}
804
806 sal_uInt16 nLevel )
807{
808 ScRefCellValue aCell(rDoc, ScAddress(nCol, nRow, nTab));
809 if (aCell.getType() != CELLTYPE_FORMULA)
810 return DET_INS_EMPTY;
811
812 ScFormulaCell* pFCell = aCell.getFormula();
813 if (pFCell->IsRunning())
814 return DET_INS_CIRCULAR;
815
816 if (pFCell->GetDirty())
817 pFCell->Interpret(); // can't be called after SetRunning
818 pFCell->SetRunning(true);
819
820 sal_uInt16 nResult = DET_INS_EMPTY;
821
822 ScDetectiveRefIter aIter(rDoc, pFCell);
823 ScRange aRef;
824 while ( aIter.GetNextRef( aRef ) )
825 {
826 if (DrawEntry( nCol, nRow, aRef, rData ))
827 {
828 nResult = DET_INS_INSERTED; // insert new arrow
829 }
830 else
831 {
832 // continue
833
834 if ( nLevel < rData.GetMaxLevel() )
835 {
836 sal_uInt16 nSubResult;
837 bool bArea = (aRef.aStart != aRef.aEnd);
838 if (bArea)
839 nSubResult = InsertPredLevelArea( aRef, rData, nLevel+1 );
840 else
841 nSubResult = InsertPredLevel( aRef.aStart.Col(), aRef.aStart.Row(),
842 rData, nLevel+1 );
843
844 switch (nSubResult)
845 {
846 case DET_INS_INSERTED:
847 nResult = DET_INS_INSERTED;
848 break;
849 case DET_INS_CONTINUE:
850 if (nResult != DET_INS_INSERTED)
851 nResult = DET_INS_CONTINUE;
852 break;
853 case DET_INS_CIRCULAR:
854 if (nResult == DET_INS_EMPTY)
855 nResult = DET_INS_CIRCULAR;
856 break;
857 // DET_INS_EMPTY: no change
858 }
859 }
860 else // nMaxLevel reached
861 if (nResult != DET_INS_INSERTED)
862 nResult = DET_INS_CONTINUE;
863 }
864 }
865
866 pFCell->SetRunning(false);
867
868 return nResult;
869}
870
872 sal_uInt16 nLevel, sal_uInt16 nDeleteLevel )
873{
874 sal_uInt16 nResult = nLevel;
875
876 ScCellIterator aCellIter( rDoc, rRef);
877 for (bool bHasCell = aCellIter.first(); bHasCell; bHasCell = aCellIter.next())
878 {
879 if (aCellIter.getType() != CELLTYPE_FORMULA)
880 continue;
881
882 sal_uInt16 nTemp = FindPredLevel(aCellIter.GetPos().Col(), aCellIter.GetPos().Row(), nLevel, nDeleteLevel);
883 if (nTemp > nResult)
884 nResult = nTemp;
885 }
886
887 return nResult;
888}
889
890 // nDeleteLevel != 0 -> delete
891
892sal_uInt16 ScDetectiveFunc::FindPredLevel( SCCOL nCol, SCROW nRow, sal_uInt16 nLevel, sal_uInt16 nDeleteLevel )
893{
894 OSL_ENSURE( nLevel<1000, "Level" );
895
896 ScRefCellValue aCell(rDoc, ScAddress(nCol, nRow, nTab));
897 if (aCell.getType() != CELLTYPE_FORMULA)
898 return nLevel;
899
900 ScFormulaCell* pFCell = aCell.getFormula();
901 if (pFCell->IsRunning())
902 return nLevel;
903
904 if (pFCell->GetDirty())
905 pFCell->Interpret(); // can't be called after SetRunning
906 pFCell->SetRunning(true);
907
908 sal_uInt16 nResult = nLevel;
909 bool bDelete = ( nDeleteLevel && nLevel == nDeleteLevel-1 );
910
911 if ( bDelete )
912 {
913 DeleteArrowsAt( nCol, nRow, true ); // arrows, that are pointing here
914 }
915
916 ScDetectiveRefIter aIter(rDoc, pFCell);
917 ScRange aRef;
918 while ( aIter.GetNextRef( aRef) )
919 {
920 bool bArea = ( aRef.aStart != aRef.aEnd );
921
922 if ( bDelete ) // delete frame ?
923 {
924 if (bArea)
925 {
926 DeleteBox( aRef.aStart.Col(), aRef.aStart.Row(), aRef.aEnd.Col(), aRef.aEnd.Row() );
927 }
928 }
929 else // continue searching
930 {
931 if ( HasArrow( aRef.aStart, nCol,nRow,nTab ) )
932 {
933 sal_uInt16 nTemp;
934 if (bArea)
935 nTemp = FindPredLevelArea( aRef, nLevel+1, nDeleteLevel );
936 else
937 nTemp = FindPredLevel( aRef.aStart.Col(),aRef.aStart.Row(),
938 nLevel+1, nDeleteLevel );
939 if (nTemp > nResult)
940 nResult = nTemp;
941 }
942 }
943 }
944
945 pFCell->SetRunning(false);
946
947 return nResult;
948}
949
951 sal_uInt16 nLevel )
952{
953 ScRefCellValue aCell(rDoc, ScAddress(nCol, nRow, nTab));
954 if (aCell.getType() != CELLTYPE_FORMULA)
955 return DET_INS_EMPTY;
956
957 ScFormulaCell* pFCell = aCell.getFormula();
958 if (pFCell->IsRunning())
959 return DET_INS_CIRCULAR;
960
961 if (pFCell->GetDirty())
962 pFCell->Interpret(); // can't be called after SetRunning
963 pFCell->SetRunning(true);
964
965 sal_uInt16 nResult = DET_INS_EMPTY;
966
967 ScDetectiveRefIter aIter(rDoc, pFCell);
968 ScRange aRef;
969 ScAddress aErrorPos;
970 bool bHasError = false;
971 while ( aIter.GetNextRef( aRef ) )
972 {
973 if (HasError( aRef, aErrorPos ))
974 {
975 bHasError = true;
976 if (DrawEntry( nCol, nRow, ScRange( aErrorPos), rData ))
977 nResult = DET_INS_INSERTED;
978
979 if ( nLevel < rData.GetMaxLevel() ) // hits most of the time
980 {
981 if (InsertErrorLevel( aErrorPos.Col(), aErrorPos.Row(),
982 rData, nLevel+1 ) == DET_INS_INSERTED)
983 nResult = DET_INS_INSERTED;
984 }
985 }
986 }
987
988 pFCell->SetRunning(false);
989
990 // leaves ?
991 if (!bHasError)
992 if (InsertPredLevel( nCol, nRow, rData, rData.GetMaxLevel() ) == DET_INS_INSERTED)
993 nResult = DET_INS_INSERTED;
994
995 return nResult;
996}
997
998sal_uInt16 ScDetectiveFunc::InsertSuccLevel( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
999 ScDetectiveData& rData, sal_uInt16 nLevel )
1000{
1001 // over the entire document.
1002
1003 sal_uInt16 nResult = DET_INS_EMPTY;
1004 ScCellIterator aCellIter(rDoc, ScRange(0,0,0,rDoc.MaxCol(),rDoc.MaxRow(),MAXTAB)); // all sheets
1005 for (bool bHas = aCellIter.first(); bHas; bHas = aCellIter.next())
1006 {
1007 if (aCellIter.getType() != CELLTYPE_FORMULA)
1008 continue;
1009
1010 ScFormulaCell* pFCell = aCellIter.getFormulaCell();
1011 bool bRunning = pFCell->IsRunning();
1012
1013 if (pFCell->GetDirty())
1014 pFCell->Interpret(); // can't be called after SetRunning
1015 pFCell->SetRunning(true);
1016
1017 ScDetectiveRefIter aIter(rDoc, pFCell);
1018 ScRange aRef;
1019 while ( aIter.GetNextRef( aRef) )
1020 {
1021 if (aRef.aStart.Tab() <= nTab && aRef.aEnd.Tab() >= nTab)
1022 {
1023 if (Intersect( nCol1,nRow1,nCol2,nRow2,
1024 aRef.aStart.Col(),aRef.aStart.Row(),
1025 aRef.aEnd.Col(),aRef.aEnd.Row() ))
1026 {
1027 bool bAlien = ( aCellIter.GetPos().Tab() != nTab );
1028 bool bDrawRet;
1029 if (bAlien)
1030 bDrawRet = DrawAlienEntry( aRef, rData );
1031 else
1032 bDrawRet = DrawEntry( aCellIter.GetPos().Col(), aCellIter.GetPos().Row(),
1033 aRef, rData );
1034 if (bDrawRet)
1035 {
1036 nResult = DET_INS_INSERTED; // insert new arrow
1037 }
1038 else
1039 {
1040 if (bRunning)
1041 {
1042 if (nResult == DET_INS_EMPTY)
1043 nResult = DET_INS_CIRCULAR;
1044 }
1045 else
1046 {
1047
1048 if ( nLevel < rData.GetMaxLevel() )
1049 {
1050 sal_uInt16 nSubResult = InsertSuccLevel(
1051 aCellIter.GetPos().Col(), aCellIter.GetPos().Row(),
1052 aCellIter.GetPos().Col(), aCellIter.GetPos().Row(),
1053 rData, nLevel+1 );
1054 switch (nSubResult)
1055 {
1056 case DET_INS_INSERTED:
1057 nResult = DET_INS_INSERTED;
1058 break;
1059 case DET_INS_CONTINUE:
1060 if (nResult != DET_INS_INSERTED)
1061 nResult = DET_INS_CONTINUE;
1062 break;
1063 case DET_INS_CIRCULAR:
1064 if (nResult == DET_INS_EMPTY)
1065 nResult = DET_INS_CIRCULAR;
1066 break;
1067 // DET_INS_EMPTY: leave unchanged
1068 }
1069 }
1070 else // nMaxLevel reached
1071 if (nResult != DET_INS_INSERTED)
1072 nResult = DET_INS_CONTINUE;
1073 }
1074 }
1075 }
1076 }
1077 }
1078 pFCell->SetRunning(bRunning);
1079 }
1080
1081 return nResult;
1082}
1083
1084sal_uInt16 ScDetectiveFunc::FindSuccLevel( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
1085 sal_uInt16 nLevel, sal_uInt16 nDeleteLevel )
1086{
1087 OSL_ENSURE( nLevel<1000, "Level" );
1088
1089 sal_uInt16 nResult = nLevel;
1090 bool bDelete = ( nDeleteLevel && nLevel == nDeleteLevel-1 );
1091
1092 ScCellIterator aCellIter( rDoc, ScRange(0, 0, nTab, rDoc.MaxCol(), rDoc.MaxRow(), nTab) );
1093 for (bool bHas = aCellIter.first(); bHas; bHas = aCellIter.next())
1094 {
1095 if (aCellIter.getType() != CELLTYPE_FORMULA)
1096 continue;
1097
1098 ScFormulaCell* pFCell = aCellIter.getFormulaCell();
1099 bool bRunning = pFCell->IsRunning();
1100
1101 if (pFCell->GetDirty())
1102 pFCell->Interpret(); // can't be called after SetRunning
1103 pFCell->SetRunning(true);
1104
1105 ScDetectiveRefIter aIter(rDoc, pFCell);
1106 ScRange aRef;
1107 while ( aIter.GetNextRef( aRef) )
1108 {
1109 if (aRef.aStart.Tab() <= nTab && aRef.aEnd.Tab() >= nTab)
1110 {
1111 if (Intersect( nCol1,nRow1,nCol2,nRow2,
1112 aRef.aStart.Col(),aRef.aStart.Row(),
1113 aRef.aEnd.Col(),aRef.aEnd.Row() ))
1114 {
1115 if ( bDelete ) // arrows, that are starting here
1116 {
1117 if (aRef.aStart != aRef.aEnd)
1118 {
1119 DeleteBox( aRef.aStart.Col(), aRef.aStart.Row(),
1120 aRef.aEnd.Col(), aRef.aEnd.Row() );
1121 }
1122 DeleteArrowsAt( aRef.aStart.Col(), aRef.aStart.Row(), false );
1123 }
1124 else if ( !bRunning &&
1125 HasArrow( aRef.aStart,
1126 aCellIter.GetPos().Col(),aCellIter.GetPos().Row(),aCellIter.GetPos().Tab() ) )
1127 {
1128 sal_uInt16 nTemp = FindSuccLevel( aCellIter.GetPos().Col(), aCellIter.GetPos().Row(),
1129 aCellIter.GetPos().Col(), aCellIter.GetPos().Row(),
1130 nLevel+1, nDeleteLevel );
1131 if (nTemp > nResult)
1132 nResult = nTemp;
1133 }
1134 }
1135 }
1136 }
1137
1138 pFCell->SetRunning(bRunning);
1139 }
1140
1141 return nResult;
1142}
1143
1145{
1146 ScDrawLayer* pModel = rDoc.GetDrawLayer();
1147 if (!pModel)
1148 return false;
1149
1150 ScDetectiveData aData( pModel );
1151
1152 sal_uInt16 nMaxLevel = 0;
1153 sal_uInt16 nResult = DET_INS_CONTINUE;
1154 while (nResult == DET_INS_CONTINUE && nMaxLevel < 1000)
1155 {
1156 aData.SetMaxLevel( nMaxLevel );
1157 nResult = InsertPredLevel( nCol, nRow, aData, 0 );
1158 ++nMaxLevel;
1159 }
1160
1161 return ( nResult == DET_INS_INSERTED );
1162}
1163
1165{
1166 ScDrawLayer* pModel = rDoc.GetDrawLayer();
1167 if (!pModel)
1168 return false;
1169
1170 ScDetectiveData aData( pModel );
1171
1172 sal_uInt16 nMaxLevel = 0;
1173 sal_uInt16 nResult = DET_INS_CONTINUE;
1174 while (nResult == DET_INS_CONTINUE && nMaxLevel < 1000)
1175 {
1176 aData.SetMaxLevel( nMaxLevel );
1177 nResult = InsertSuccLevel( nCol, nRow, nCol, nRow, aData, 0 );
1178 ++nMaxLevel;
1179 }
1180
1181 return ( nResult == DET_INS_INSERTED );
1182}
1183
1185{
1186 ScDrawLayer* pModel = rDoc.GetDrawLayer();
1187 if (!pModel)
1188 return false;
1189
1190 ScRange aRange( nCol, nRow, nTab );
1191 ScAddress aErrPos;
1192 if ( !HasError( aRange,aErrPos ) )
1193 return false;
1194
1195 ScDetectiveData aData( pModel );
1196
1197 aData.SetMaxLevel( 1000 );
1198 sal_uInt16 nResult = InsertErrorLevel( nCol, nRow, aData, 0 );
1199
1200 return ( nResult == DET_INS_INSERTED );
1201}
1202
1204{
1205 ScDrawLayer* pModel = rDoc.GetDrawLayer();
1206 if (!pModel)
1207 return false;
1208
1209 sal_uInt16 nLevelCount = FindSuccLevel( nCol, nRow, nCol, nRow, 0, 0 );
1210 if ( nLevelCount )
1211 FindSuccLevel( nCol, nRow, nCol, nRow, 0, nLevelCount ); // delete
1212
1213 return ( nLevelCount != 0 );
1214}
1215
1217{
1218 ScDrawLayer* pModel = rDoc.GetDrawLayer();
1219 if (!pModel)
1220 return false;
1221
1222 sal_uInt16 nLevelCount = FindPredLevel( nCol, nRow, 0, 0 );
1223 if ( nLevelCount )
1224 FindPredLevel( nCol, nRow, 0, nLevelCount ); // delete
1225
1226 return ( nLevelCount != 0 );
1227}
1228
1230{
1231 tools::Rectangle aRect = ScDrawLayer::GetCellRect(rDoc, ScAddress(nCol, nRow, nTab), true);
1232 aRect.AdjustLeft(-250);
1233 aRect.AdjustRight(250);
1234 aRect.AdjustTop(-70);
1235 aRect.AdjustBottom(70);
1236
1237 Point aStartCorner = aRect.TopLeft();
1238 Point aEndCorner = aRect.BottomRight();
1239
1240 ScDrawLayer* pModel = rDoc.GetDrawLayer();
1241 if (!pModel)
1242 return false;
1243
1244 SdrPage* pPage = pModel->GetPage(static_cast<sal_uInt16>(nTab));
1245 OSL_ENSURE(pPage, "Page ?");
1246
1247 pPage->RecalcObjOrdNums();
1248
1249 const size_t nObjCount = pPage->GetObjCount();
1250 size_t nDelCount = 0;
1251 if (nObjCount)
1252 {
1253 std::unique_ptr<SdrObject*[]> ppObj(new SdrObject*[nObjCount]);
1254
1255 SdrObjListIter aIter(pPage, SdrIterMode::Flat);
1256 SdrObject* pObject = aIter.Next();
1257 while (pObject)
1258 {
1259 if (pObject->GetLayer() == SC_LAYER_INTERN)
1260 if (auto pSdrCircObj = dynamic_cast<const SdrCircObj*>(pObject) )
1261 {
1262 tools::Rectangle aObjRect = pSdrCircObj->GetLogicRect();
1263 if (RectIsPoints(aObjRect, aStartCorner, aEndCorner))
1264 ppObj[nDelCount++] = pObject;
1265 }
1266
1267 pObject = aIter.Next();
1268 }
1269
1270 for (size_t i = 1; i <= nDelCount; ++i)
1271 pModel->AddCalcUndo(std::make_unique<SdrUndoRemoveObj>(*ppObj[nDelCount - i]));
1272
1273 for (size_t i = 1; i <= nDelCount; ++i)
1274 pPage->RemoveObject(ppObj[nDelCount - i]->GetOrdNum());
1275
1276 ppObj.reset();
1277
1278 Modified();
1279 }
1280
1281 return (nDelCount != 0);
1282}
1283
1285{
1286 ScDrawLayer* pModel = rDoc.GetDrawLayer();
1287 if (!pModel)
1288 return false;
1289
1290 SdrPage* pPage = pModel->GetPage(static_cast<sal_uInt16>(nTab));
1291 OSL_ENSURE(pPage,"Page ?");
1292
1293 pPage->RecalcObjOrdNums();
1294
1295 size_t nDelCount = 0;
1296 const size_t nObjCount = pPage->GetObjCount();
1297 if (nObjCount)
1298 {
1299 std::unique_ptr<SdrObject*[]> ppObj(new SdrObject*[nObjCount]);
1300
1301 SdrObjListIter aIter( pPage, SdrIterMode::Flat );
1302 SdrObject* pObject = aIter.Next();
1303 while (pObject)
1304 {
1305 if ( pObject->GetLayer() == SC_LAYER_INTERN )
1306 {
1307 bool bDoThis = true;
1308 bool bCircle = ( dynamic_cast<const SdrCircObj*>( pObject) != nullptr );
1309 bool bCaption = ScDrawLayer::IsNoteCaption( pObject );
1310 if ( eWhat == ScDetectiveDelete::Detective ) // detective, from menu
1311 bDoThis = !bCaption; // also circles
1312 else if ( eWhat == ScDetectiveDelete::Circles ) // circles, if new created
1313 bDoThis = bCircle;
1314 else if ( eWhat == ScDetectiveDelete::Arrows ) // DetectiveRefresh
1315 bDoThis = !bCaption && !bCircle; // don't include circles
1316 else
1317 {
1318 OSL_FAIL("what?");
1319 }
1320 if ( bDoThis )
1321 ppObj[nDelCount++] = pObject;
1322 }
1323
1324 pObject = aIter.Next();
1325 }
1326
1327 for (size_t i=1; i<=nDelCount; ++i)
1328 pModel->AddCalcUndo( std::make_unique<SdrUndoRemoveObj>( *ppObj[nDelCount-i] ) );
1329
1330 for (size_t i=1; i<=nDelCount; ++i)
1331 pPage->RemoveObject( ppObj[nDelCount-i]->GetOrdNum() );
1332
1333 ppObj.reset();
1334
1335 Modified();
1336 }
1337
1338 return ( nDelCount != 0 );
1339}
1340
1341bool ScDetectiveFunc::MarkInvalid(bool& rOverflow)
1342{
1343 rOverflow = false;
1344 ScDrawLayer* pModel = rDoc.GetDrawLayer();
1345 if (!pModel)
1346 return false;
1347
1348 bool bDeleted = DeleteAll( ScDetectiveDelete::Circles ); // just circles
1349
1350 ScDetectiveData aData( pModel );
1351 tools::Long nInsCount = 0;
1352
1353 // search for valid places
1354 ScDocAttrIterator aAttrIter( rDoc, nTab, 0,0,rDoc.MaxCol(),rDoc.MaxRow() );
1355 SCCOL nCol;
1356 SCROW nRow1;
1357 SCROW nRow2;
1358 const ScPatternAttr* pPattern = aAttrIter.GetNext( nCol, nRow1, nRow2 );
1359 while ( pPattern && nInsCount < SC_DET_MAXCIRCLE )
1360 {
1361 sal_uInt32 nIndex = pPattern->GetItem(ATTR_VALIDDATA).GetValue();
1362 if (nIndex)
1363 {
1365 if ( pData )
1366 {
1367 // pass cells in this area
1368
1369 bool bMarkEmpty = !pData->IsIgnoreBlank();
1370 SCROW nNextRow = nRow1;
1371 SCROW nRow;
1372 ScCellIterator aCellIter( rDoc, ScRange(nCol, nRow1, nTab, nCol, nRow2, nTab) );
1373 for (bool bHas = aCellIter.first(); bHas && nInsCount < SC_DET_MAXCIRCLE; bHas = aCellIter.next())
1374 {
1375 SCROW nCellRow = aCellIter.GetPos().Row();
1376 if ( bMarkEmpty )
1377 for ( nRow = nNextRow; nRow < nCellRow && nInsCount < SC_DET_MAXCIRCLE; nRow++ )
1378 {
1379 if(!pPattern->GetItem(ATTR_MERGE_FLAG).IsOverlapped())
1380 DrawCircle( nCol, nRow, aData );
1381 ++nInsCount;
1382 }
1383 ScRefCellValue aCell = aCellIter.getRefCellValue();
1384 if (!pData->IsDataValid(aCell, aCellIter.GetPos()))
1385 {
1386 if(!pPattern->GetItem(ATTR_MERGE_FLAG).IsOverlapped())
1387 DrawCircle( nCol, nCellRow, aData );
1388 ++nInsCount;
1389 }
1390 nNextRow = nCellRow + 1;
1391 }
1392 if ( bMarkEmpty )
1393 for ( nRow = nNextRow; nRow <= nRow2 && nInsCount < SC_DET_MAXCIRCLE; nRow++ )
1394 {
1395 if(!pPattern->GetItem(ATTR_MERGE_FLAG).IsOverlapped())
1396 DrawCircle(nCol, nRow, aData);
1397 ++nInsCount;
1398 }
1399 }
1400 }
1401
1402 pPattern = aAttrIter.GetNext( nCol, nRow1, nRow2 );
1403 }
1404
1405 if ( nInsCount >= SC_DET_MAXCIRCLE )
1406 rOverflow = true;
1407
1408 return ( bDeleted || nInsCount != 0 );
1409}
1410
1411void ScDetectiveFunc::GetAllPreds(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
1412 vector<ScTokenRef>& rRefTokens)
1413{
1414 ScCellIterator aIter(rDoc, ScRange(nCol1, nRow1, nTab, nCol2, nRow2, nTab));
1415 for (bool bHas = aIter.first(); bHas; bHas = aIter.next())
1416 {
1417 if (aIter.getType() != CELLTYPE_FORMULA)
1418 continue;
1419
1420 ScFormulaCell* pFCell = aIter.getFormulaCell();
1421 ScDetectiveRefIter aRefIter(rDoc, pFCell);
1422 for (formula::FormulaToken* p = aRefIter.GetNextRefToken(); p; p = aRefIter.GetNextRefToken())
1423 {
1424 ScTokenRef pRef(p->Clone());
1425 ScRefTokenHelper::join(&rDoc, rRefTokens, pRef, aIter.GetPos());
1426 }
1427 }
1428}
1429
1430void ScDetectiveFunc::GetAllSuccs(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
1431 vector<ScTokenRef>& rRefTokens)
1432{
1433 vector<ScTokenRef> aSrcRange;
1434 aSrcRange.push_back(
1435 ScRefTokenHelper::createRefToken(rDoc, ScRange(nCol1, nRow1, nTab, nCol2, nRow2, nTab)));
1436
1437 ScCellIterator aIter(rDoc, ScRange(0, 0, nTab, rDoc.MaxCol(), rDoc.MaxRow(), nTab));
1438 for (bool bHas = aIter.first(); bHas; bHas = aIter.next())
1439 {
1440 if (aIter.getType() != CELLTYPE_FORMULA)
1441 continue;
1442
1443 ScFormulaCell* pFCell = aIter.getFormulaCell();
1444 ScDetectiveRefIter aRefIter(rDoc, pFCell);
1445 for (formula::FormulaToken* p = aRefIter.GetNextRefToken(); p; p = aRefIter.GetNextRefToken())
1446 {
1447 const ScAddress& aPos = aIter.GetPos();
1448 ScTokenRef pRef(p->Clone());
1449 if (ScRefTokenHelper::intersects(&rDoc, aSrcRange, pRef, aPos))
1450 {
1451 // This address is absolute.
1453 ScRefTokenHelper::join(&rDoc, rRefTokens, pRef, ScAddress());
1454 }
1455 }
1456 }
1457}
1458
1460{
1461 // for all caption objects, update attributes and SpecialTextBoxShadow flag
1462 // (on all tables - nTab is ignored!)
1463
1464 // no undo actions, this is refreshed after undo
1465
1466 ScDrawLayer* pModel = rDoc.GetDrawLayer();
1467 if (!pModel)
1468 return;
1469
1470 for( SCTAB nObjTab = 0, nTabCount = rDoc.GetTableCount(); nObjTab < nTabCount; ++nObjTab )
1471 {
1472 SdrPage* pPage = pModel->GetPage( static_cast< sal_uInt16 >( nObjTab ) );
1473 OSL_ENSURE( pPage, "Page ?" );
1474 if( pPage )
1475 {
1476 SdrObjListIter aIter( pPage, SdrIterMode::Flat );
1477 for( SdrObject* pObject = aIter.Next(); pObject; pObject = aIter.Next() )
1478 {
1480 {
1481 ScPostIt* pNote = rDoc.GetNote( pData->maStart );
1482 // caption should exist, we iterate over drawing objects...
1483 OSL_ENSURE( pNote && (pNote->GetCaption() == pObject), "ScDetectiveFunc::UpdateAllComments - invalid cell note" );
1484 if( pNote )
1485 {
1486 ScCommentData aData( rDoc, pModel );
1487 SfxItemSet aAttrColorSet = pObject->GetMergedItemSet();
1488 aAttrColorSet.Put( XFillColorItem( OUString(), GetCommentColor() ) );
1489 aData.UpdateCaptionSet( aAttrColorSet );
1490 pObject->SetMergedItemSetAndBroadcast( aData.GetCaptionSet() );
1491 if( SdrCaptionObj* pCaption = dynamic_cast< SdrCaptionObj* >( pObject ) )
1492 {
1493 pCaption->SetSpecialTextBoxShadow();
1494 pCaption->SetFixedTail();
1495 }
1496 }
1497 }
1498 }
1499 }
1500 }
1501}
1502
1504{
1505 // no undo actions necessary
1506
1507 ScDrawLayer* pModel = rDoc.GetDrawLayer();
1508 if (!pModel)
1509 return;
1510
1511 for( SCTAB nObjTab = 0, nTabCount = rDoc.GetTableCount(); nObjTab < nTabCount; ++nObjTab )
1512 {
1513 SdrPage* pPage = pModel->GetPage( static_cast< sal_uInt16 >( nObjTab ) );
1514 OSL_ENSURE( pPage, "Page ?" );
1515 if( pPage )
1516 {
1517 SdrObjListIter aIter( pPage, SdrIterMode::Flat );
1518 for( SdrObject* pObject = aIter.Next(); pObject; pObject = aIter.Next() )
1519 {
1520 if ( pObject->GetLayer() == SC_LAYER_INTERN )
1521 {
1522 bool bArrow = false;
1523 bool bError = false;
1524
1525 ScAddress aPos;
1526 ScRange aSource;
1527 bool bDummy;
1528 ScDetectiveObjType eType = GetDetectiveObjectType( pObject, nObjTab, aPos, aSource, bDummy );
1530 {
1531 // source is valid, determine error flag from source range
1532
1533 ScAddress aErrPos;
1534 if ( HasError( aSource, aErrPos ) )
1535 bError = true;
1536 else
1537 bArrow = true;
1538 }
1539 else if ( eType == SC_DETOBJ_FROMOTHERTAB )
1540 {
1541 // source range is no longer known, take error flag from formula itself
1542 // (this means, if the formula has an error, all references to other tables
1543 // are marked red)
1544
1545 ScAddress aErrPos;
1546 if ( HasError( ScRange( aPos), aErrPos ) )
1547 bError = true;
1548 else
1549 bArrow = true;
1550 }
1551 else if ( eType == SC_DETOBJ_CIRCLE )
1552 {
1553 // circles (error marks) are always red
1554
1555 bError = true;
1556 }
1557 else if ( eType == SC_DETOBJ_NONE )
1558 {
1559 // frame for area reference has no ObjType, always gets arrow color
1560
1561 if ( dynamic_cast<const SdrRectObj*>( pObject) != nullptr && dynamic_cast<const SdrCaptionObj*>( pObject) == nullptr )
1562 {
1563 bArrow = true;
1564 }
1565 }
1566
1567 if ( bArrow || bError )
1568 {
1569 Color nColor = ( bError ? GetErrorColor() : GetArrowColor() );
1570 pObject->SetMergedItem( XLineColorItem( OUString(), nColor ) );
1571
1572 // repaint only
1573 pObject->ActionChanged();
1574 }
1575 }
1576 }
1577 }
1578 }
1579}
1580
1582{
1583 // find the rectangle for an arrow (always the object directly before the arrow)
1584 // rRange must be initialized to the source cell of the arrow (start of area)
1585
1586 ScDrawLayer* pModel = rDoc.GetDrawLayer();
1587 if (!pModel) return;
1588
1589 SdrPage* pPage = pModel->GetPage(static_cast<sal_uInt16>(nTab));
1590 OSL_ENSURE(pPage,"Page ?");
1591 if (!pPage) return;
1592
1593 // test if the object is a direct page member
1594 if( !(pObject && pObject->getSdrPageFromSdrObject() && (pObject->getSdrPageFromSdrObject() == pObject->getParentSdrObjListFromSdrObject()->getSdrPageFromSdrObjList())) )
1595 return;
1596
1597 // Is there a previous object?
1598 const size_t nOrdNum = pObject->GetOrdNum();
1599
1600 if(nOrdNum <= 0)
1601 return;
1602
1603 SdrObject* pPrevObj = pPage->GetObj(nOrdNum - 1);
1604
1605 if ( pPrevObj && pPrevObj->GetLayer() == SC_LAYER_INTERN && dynamic_cast<const SdrRectObj*>( pPrevObj) != nullptr )
1606 {
1607 ScDrawObjData* pPrevData = ScDrawLayer::GetObjDataTab( pPrevObj, rRange.aStart.Tab() );
1608 if ( pPrevData && pPrevData->maStart.IsValid() && pPrevData->maEnd.IsValid() && (pPrevData->maStart == rRange.aStart) )
1609 {
1610 rRange.aEnd = pPrevData->maEnd;
1611 return;
1612 }
1613 }
1614}
1615
1617 ScAddress& rPosition, ScRange& rSource, bool& rRedLine )
1618{
1619 rRedLine = false;
1621
1622 if ( pObject && pObject->GetLayer() == SC_LAYER_INTERN )
1623 {
1625 {
1626 bool bValidStart = pData->maStart.IsValid();
1627 bool bValidEnd = pData->maEnd.IsValid();
1628
1629 if ( pObject->IsPolyObj() && pObject->GetPointCount() == 2 )
1630 {
1631 // line object -> arrow
1632
1633 if ( bValidStart )
1635 else if ( bValidEnd )
1637
1638 if ( bValidStart )
1639 rSource = pData->maStart;
1640 if ( bValidEnd )
1641 rPosition = pData->maEnd;
1642
1643 if ( bValidStart && lcl_HasThickLine( *pObject ) )
1644 {
1645 // thick line -> look for frame before this object
1646
1647 FindFrameForObject( pObject, rSource ); // modifies rSource
1648 }
1649
1650 Color nObjColor = pObject->GetMergedItem(XATTR_LINECOLOR).GetColorValue();
1651 if ( nObjColor == GetErrorColor() && nObjColor != GetArrowColor() )
1652 rRedLine = true;
1653 }
1654 else if (dynamic_cast<const SdrCircObj*>(pObject) != nullptr)
1655 {
1656 if (bValidStart)
1657 {
1658 // cell position is returned in rPosition
1659 rPosition = pData->maStart;
1661 }
1662 }
1663 else if (dynamic_cast<const SdrRectObj*>(pObject) != nullptr)
1664 {
1665 if (bValidStart)
1666 {
1667 // cell position is returned in rPosition
1668 rPosition = pData->maStart;
1670 }
1671 }
1672 }
1673 }
1674
1675 return eType;
1676}
1677
1679 const ScAddress& rPosition, const ScRange& rSource,
1680 bool bRedLine )
1681{
1682 ScDrawLayer* pModel = rDoc.GetDrawLayer();
1683 if (!pModel) return;
1684 ScDetectiveData aData( pModel );
1685
1686 switch (eType)
1687 {
1688 case SC_DETOBJ_ARROW:
1690 InsertArrow( rPosition.Col(), rPosition.Row(),
1691 rSource.aStart.Col(), rSource.aStart.Row(),
1692 rSource.aEnd.Col(), rSource.aEnd.Row(),
1693 (eType == SC_DETOBJ_FROMOTHERTAB), bRedLine, aData );
1694 break;
1696 InsertToOtherTab( rSource.aStart.Col(), rSource.aStart.Row(),
1697 rSource.aEnd.Col(), rSource.aEnd.Row(),
1698 bRedLine, aData );
1699 break;
1700 case SC_DETOBJ_CIRCLE:
1701 DrawCircle( rPosition.Col(), rPosition.Row(), aData );
1702 break;
1703 default:
1704 {
1705 // added to avoid warnings
1706 }
1707 }
1708}
1709
1711{
1712 if (!bColorsInitialized)
1714 return nArrowColor;
1715}
1716
1718{
1719 if (!bColorsInitialized)
1721 return nErrorColor;
1722}
1723
1725{
1726 if (!bColorsInitialized)
1728 return nCommentColor;
1729}
1730
1732{
1733 // may be called several times to update colors from configuration
1734
1735 const svtools::ColorConfig& rColorCfg = SC_MOD()->GetColorConfig();
1739
1740 bColorsInitialized = true;
1741}
1742
1744{
1745 return bColorsInitialized;
1746}
1747
1749{
1750 rDisplay += "\n--------\n";
1751}
1752
1753/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const SCTAB MAXTAB
Definition: address.hxx:70
SCTAB Tab() const
Definition: address.hxx:283
bool IsValid() const
Definition: address.hxx:305
SCROW Row() const
Definition: address.hxx:274
SCCOL Col() const
Definition: address.hxx:279
Walk through all cells in an area.
Definition: dociter.hxx:206
CellType getType() const
Definition: dociter.hxx:233
ScFormulaCell * getFormulaCell()
Definition: dociter.hxx:236
const ScAddress & GetPos() const
Definition: dociter.hxx:231
const ScRefCellValue & getRefCellValue() const
Definition: dociter.hxx:239
SfxItemSet aToTabSet
Definition: detfunc.cxx:91
ScDetectiveData(SdrModel *pModel)
Definition: detfunc.cxx:137
SfxItemSet aFromTabSet
Definition: detfunc.cxx:92
SfxItemSet aArrowSet
Definition: detfunc.cxx:90
sal_uInt16 GetMaxLevel() const
Definition: detfunc.cxx:106
SfxItemSet & GetBoxSet()
Definition: detfunc.cxx:99
SfxItemSet & GetToTabSet()
Definition: detfunc.cxx:101
SfxItemSet & GetCircleSet()
Definition: detfunc.cxx:103
sal_uInt16 nMaxLevel
Definition: detfunc.cxx:94
SfxItemSet aCircleSet
Definition: detfunc.cxx:93
SfxItemSet & GetFromTabSet()
Definition: detfunc.cxx:102
SfxItemSet aBoxSet
Definition: detfunc.cxx:89
void SetMaxLevel(sal_uInt16 nVal)
Definition: detfunc.cxx:105
SfxItemSet & GetArrowSet()
Definition: detfunc.cxx:100
bool DrawAlienEntry(const ScRange &rRef, ScDetectiveData &rData)
Definition: detfunc.cxx:611
static void InitializeColors()
Definition: detfunc.cxx:1731
sal_uInt16 FindPredLevelArea(const ScRange &rRef, sal_uInt16 nLevel, sal_uInt16 nDeleteLevel)
Definition: detfunc.cxx:871
bool DeleteSucc(SCCOL nCol, SCROW nRow)
Definition: detfunc.cxx:1203
bool ShowError(SCCOL nCol, SCROW nRow)
Definition: detfunc.cxx:1184
bool ShowPred(SCCOL nCol, SCROW nRow)
Definition: detfunc.cxx:1144
static Color nArrowColor
Definition: detfunc.hxx:50
void DrawCircle(SCCOL nCol, SCROW nRow, ScDetectiveData &rData)
Definition: detfunc.cxx:626
bool HasError(const ScRange &rRange, ScAddress &rErrPos)
Definition: detfunc.cxx:282
static void UpdateAllComments(ScDocument &rDoc)
on all tables
Definition: detfunc.cxx:1459
void DeleteArrowsAt(SCCOL nCol, SCROW nRow, bool bDestPnt)
Definition: detfunc.cxx:657
static Color GetArrowColor()
Definition: detfunc.cxx:1710
static bool IsColorsInitialized()
Definition: detfunc.cxx:1743
void UpdateAllArrowColors()
on all tables
Definition: detfunc.cxx:1503
sal_uInt16 FindSuccLevel(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, sal_uInt16 nLevel, sal_uInt16 nDeleteLevel)
Definition: detfunc.cxx:1084
tools::Rectangle GetDrawRect(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2) const
Definition: detfunc.cxx:336
sal_uInt16 InsertErrorLevel(SCCOL nCol, SCROW nRow, ScDetectiveData &rData, sal_uInt16 nLevel)
Definition: detfunc.cxx:950
bool DeletePred(SCCOL nCol, SCROW nRow)
Definition: detfunc.cxx:1216
bool DeleteAll(ScDetectiveDelete eWhat)
Definition: detfunc.cxx:1284
bool HasArrow(const ScAddress &rStart, SCCOL nEndCol, SCROW nEndRow, SCTAB nEndTab)
Definition: detfunc.cxx:368
void FindFrameForObject(const SdrObject *pObject, ScRange &rRange)
Definition: detfunc.cxx:1581
static bool IsNonAlienArrow(const SdrObject *pObject)
Definition: detfunc.cxx:420
static void AppendChangTrackNoteSeparator(OUString &str)
Definition: detfunc.cxx:1748
sal_uInt16 FindPredLevel(SCCOL nCol, SCROW nRow, sal_uInt16 nLevel, sal_uInt16 nDeleteLevel)
Definition: detfunc.cxx:892
bool DrawEntry(SCCOL nCol, SCROW nRow, const ScRange &rRef, ScDetectiveData &rData)
DrawEntry / DrawAlienEntry check for existing arrows and errors.
Definition: detfunc.cxx:593
void InsertArrow(SCCOL nCol, SCROW nRow, SCCOL nRefStartCol, SCROW nRefStartRow, SCCOL nRefEndCol, SCROW nRefEndRow, bool bFromOtherTab, bool bRed, ScDetectiveData &rData)
called from DrawEntry/DrawAlienEntry and InsertObject
Definition: detfunc.cxx:440
void InsertObject(ScDetectiveObjType eType, const ScAddress &rPosition, const ScRange &rSource, bool bRedLine)
Definition: detfunc.cxx:1678
void GetAllSuccs(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, ::std::vector< ScTokenRef > &rRefTokens)
Definition: detfunc.cxx:1430
bool MarkInvalid(bool &rOverflow)
Definition: detfunc.cxx:1341
bool ShowSucc(SCCOL nCol, SCROW nRow)
Definition: detfunc.cxx:1164
static Color nErrorColor
Definition: detfunc.hxx:51
sal_uInt16 InsertPredLevel(SCCOL nCol, SCROW nRow, ScDetectiveData &rData, sal_uInt16 nLevel)
Definition: detfunc.cxx:805
void GetAllPreds(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, ::std::vector< ScTokenRef > &rRefTokens)
Definition: detfunc.cxx:1411
void DeleteBox(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2)
Definition: detfunc.cxx:725
void Modified()
Definition: detfunc.cxx:270
void InsertToOtherTab(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, bool bRed, ScDetectiveData &rData)
Definition: detfunc.cxx:521
@ BottomRight
Bottom-right edge of the cell.
@ TopLeft
Top-left edge of the cell.
@ DetectiveArrow
Position inside cell for detective arrows.
ScDetectiveObjType GetDetectiveObjectType(SdrObject *pObject, SCTAB nObjTab, ScAddress &rPosition, ScRange &rSource, bool &rRedLine)
Definition: detfunc.cxx:1616
static Color GetErrorColor()
Definition: detfunc.cxx:1717
static Color nCommentColor
Definition: detfunc.hxx:52
Point GetDrawPos(SCCOL nCol, SCROW nRow, DrawPosMode eMode) const
Definition: detfunc.cxx:301
static bool bColorsInitialized
Definition: detfunc.hxx:53
ScDocument & rDoc
Definition: detfunc.hxx:55
sal_uInt16 InsertSuccLevel(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, ScDetectiveData &rData, sal_uInt16 nLevel)
Definition: detfunc.cxx:998
sal_uInt16 InsertPredLevelArea(const ScRange &rRef, ScDetectiveData &rData, sal_uInt16 nLevel)
Definition: detfunc.cxx:772
bool DeleteCirclesAt(SCCOL nCol, SCROW nRow)
Definition: detfunc.cxx:1229
static Color GetCommentColor()
Definition: detfunc.cxx:1724
Iterator for references in a formula cell.
Definition: formulaiter.hxx:32
bool GetNextRef(ScRange &rRange)
Definition: formulaiter.cxx:52
formula::FormulaToken * GetNextRefToken()
Definition: formulaiter.cxx:67
const ScPatternAttr * GetNext(SCCOL &rCol, SCROW &rRow1, SCROW &rRow2)
Definition: dociter.cxx:1584
SCROW SanitizeRow(SCROW nRow) const
Definition: document.hxx:905
SC_DLLPUBLIC sal_uInt16 GetRowHeight(SCROW nRow, SCTAB nTab, bool bHiddenAsZero=true) const
Definition: document.cxx:4224
SC_DLLPUBLIC sal_uInt16 GetColWidth(SCCOL nCol, SCTAB nTab, bool bHiddenAsZero=true) const
Definition: document.cxx:4183
SC_DLLPUBLIC SCCOL MaxCol() const
Definition: document.hxx:891
SC_DLLPUBLIC const ScValidationData * GetValidationEntry(sal_uInt32 nIndex) const
Definition: documen4.cxx:881
SC_DLLPUBLIC ScDocumentPool * GetPool()
Definition: document.cxx:6169
SC_DLLPUBLIC SCROW MaxRow() const
Definition: document.hxx:892
SC_DLLPUBLIC ScPostIt * GetNote(const ScAddress &rPos)
Definition: document.cxx:6729
SC_DLLPUBLIC bool IsNegativePage(SCTAB nTab) const
Definition: document.cxx:1005
void SetStreamValid(SCTAB nTab, bool bSet, bool bIgnoreLock=false)
Definition: document.cxx:936
SC_DLLPUBLIC ScDrawLayer * GetDrawLayer()
Definition: document.hxx:1082
SCCOL SanitizeCol(SCCOL nCol) const
Definition: document.hxx:904
SC_DLLPUBLIC SCTAB GetTableCount() const
Definition: document.cxx:316
bool ValidColRow(SCCOL nCol, SCROW nRow) const
Definition: document.hxx:900
static ScDrawObjData * GetObjDataTab(SdrObject *pObj, SCTAB nTab)
Definition: drwlayer.cxx:2618
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:2109
static ScDrawObjData * GetObjData(SdrObject *pObj, bool bCreate=false)
Definition: drwlayer.cxx:2604
static bool IsNoteCaption(SdrObject *pObj)
Returns true, if the passed object is the caption of a cell note.
Definition: drwlayer.cxx:2631
bool IsRecording() const
Definition: drwlayer.hxx:142
static ScDrawObjData * GetNoteCaptionData(SdrObject *pObj, SCTAB nTab)
Returns the object data, if the passed object is a cell note caption.
Definition: drwlayer.cxx:2637
void AddCalcUndo(std::unique_ptr< SdrUndoAction > pUndo)
Definition: drwlayer.cxx:1416
ScAddress maStart
Definition: userdat.hxx:36
@ ValidationCircle
Definition: userdat.hxx:34
ScAddress maEnd
Definition: userdat.hxx:37
bool IsRunning() const
void SetRunning(bool bVal)
bool GetDirty() const
FormulaError GetErrCode()
bool Interpret(SCROW nStartOffset=-1, SCROW nEndOffset=-1)
const SfxPoolItem & GetItem(sal_uInt16 nWhichP) const
Definition: patattr.hxx:72
Additional class containing cell annotation data.
Definition: postit.hxx:58
SdrCaptionObj * GetCaption() const
Returns an existing note caption object.
Definition: postit.hxx:134
ScAddress aEnd
Definition: address.hxx:498
ScAddress aStart
Definition: address.hxx:497
const SdrPage * GetPage(sal_uInt16 nPgNum) const
SdrObject * Next()
virtual void InsertObject(SdrObject *pObj, size_t nPos=SAL_MAX_SIZE)
SdrObject * GetObj(size_t nNum) const
size_t GetObjCount() const
void RecalcObjOrdNums()
virtual rtl::Reference< SdrObject > RemoveObject(size_t nObjNum)
const SfxPoolItem & GetMergedItem(const sal_uInt16 nWhich) const
virtual SdrLayerID GetLayer() const
const SfxPoolItem & GetDefaultItem(sal_uInt16 nWhich) const
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
const SfxPoolItem & Get(sal_uInt16 nWhich, bool bSrchInParent=true) const
B2DPolygon const & getB2DPolygon(sal_uInt32 nIndex) const
sal_uInt32 count() const
bool isClosed() const
bool areControlPointsUsed() const
void append(const basegfx::B2DPoint &rPoint, sal_uInt32 nCount)
sal_uInt32 count() const
void setClosed(bool bNew)
ColorConfigValue GetColorValue(ColorConfigEntry eEntry, bool bSmart=true) const
bool Contains(const Point &rPOINT) const
constexpr tools::Long Top() const
constexpr Point TopLeft() const
constexpr tools::Long Right() const
tools::Long AdjustTop(tools::Long nVertMoveDelta)
tools::Long AdjustRight(tools::Long nHorzMoveDelta)
constexpr Point BottomRight() const
tools::Long AdjustBottom(tools::Long nVertMoveDelta)
tools::Long AdjustLeft(tools::Long nHorzMoveDelta)
constexpr tools::Long Left() const
constexpr tools::Long Bottom() const
static bool lcl_HasThickLine(const SdrObject &rObj)
Definition: detfunc.cxx:130
static bool lcl_IsOtherTab(const basegfx::B2DPolyPolygon &rPolyPolygon)
Definition: detfunc.cxx:350
static bool Intersect(SCCOL nStartCol1, SCROW nStartRow1, SCCOL nEndCol1, SCROW nEndRow1, SCCOL nStartCol2, SCROW nStartRow2, SCCOL nEndCol2, SCROW nEndRow2)
Definition: detfunc.cxx:275
static bool RectIsPoints(const tools::Rectangle &rRect, const Point &rStart, const Point &rEnd)
Definition: detfunc.cxx:711
#define SC_DET_TOLERANCE
Definition: detfunc.cxx:709
#define SC_DET_MAXCIRCLE
Definition: detfunc.hxx:34
ScDetectiveObjType
Definition: detfunc.hxx:39
@ SC_DETOBJ_NONE
Definition: detfunc.hxx:40
@ SC_DETOBJ_TOOTHERTAB
Definition: detfunc.hxx:43
@ SC_DETOBJ_CIRCLE
Definition: detfunc.hxx:44
@ SC_DETOBJ_ARROW
Definition: detfunc.hxx:41
@ SC_DETOBJ_FROMOTHERTAB
Definition: detfunc.hxx:42
@ SC_DETOBJ_RECTANGLE
Definition: detfunc.hxx:45
ScDetectiveDelete
Definition: detfunc.hxx:36
constexpr sal_uInt16 EE_ITEMS_END(EE_FEATURE_END)
constexpr sal_uInt16 EE_ITEMS_START(OWN_ATTR_VALUE_END+1)
EmbeddedObjectRef * pObject
FormulaError
DocumentType eType
@ CELLTYPE_FORMULA
Definition: global.hxx:275
constexpr SdrLayerID SC_LAYER_INTERN(2)
sal_Int32 nIndex
OUString aName
Mode eMode
void * p
std::unique_ptr< sal_Int32[]> pData
constexpr OUStringLiteral aData
ScTokenRef createRefToken(const ScDocument &rDoc, const ScAddress &rAddr)
bool SC_DLLPUBLIC intersects(const ScDocument *pDoc, const ::std::vector< ScTokenRef > &rTokens, const ScTokenRef &pToken, const ScAddress &rPos)
void SC_DLLPUBLIC join(const ScDocument *pDoc, ::std::vector< ScTokenRef > &rTokens, const ScTokenRef &pToken, const ScAddress &rPos)
B2DPolygon createPolygonFromEllipse(const B2DPoint &rCenter, double fRadiusX, double fRadiusY, sal_uInt32 nStartQuadrant=0)
int i
constexpr Point convert(const Point &rPoint, o3tl::Length eFrom, o3tl::Length eTo)
These need to be in global namespace just like their respective types are.
CALCDETECTIVEERROR
CALCNOTESBACKGROUND
long Long
constexpr TypedWhichId< ScMergeFlagAttr > ATTR_MERGE_FLAG(145)
constexpr TypedWhichId< ScPatternAttr > ATTR_PATTERN(156)
constexpr TypedWhichId< SfxUInt32Item > ATTR_VALIDDATA(153)
#define SC_MOD()
Definition: scmod.hxx:249
SdrOnOffItem makeSdrShadowItem(bool bShadow)
SdrMetricItem makeSdrShadowXDistItem(tools::Long nDist)
SdrMetricItem makeSdrShadowYDistItem(tools::Long nDist)
SdrOnOffItem makeSdrTextAutoGrowHeightItem(bool bAuto)
SdrOnOffItem makeSdrTextAutoGrowWidthItem(bool bAuto)
SdrMetricItem makeSdrTextUpperDistItem(tools::Long mnHeight)
SdrMetricItem makeSdrTextRightDistItem(tools::Long mnHeight)
SdrMetricItem makeSdrTextLowerDistItem(tools::Long mnHeight)
SdrMetricItem makeSdrTextLeftDistItem(tools::Long mnHeight)
static SfxItemSet & rSet
This is very similar to ScCellValue, except that it references the original value instead of copying ...
Definition: cellvalue.hxx:108
ScFormulaCell * getFormula() const
Definition: cellvalue.hxx:137
CellType getType() const
Definition: cellvalue.hxx:133
constexpr TypedWhichId< SdrOnOffItem > SDRATTR_SHADOW(SDRATTR_SHADOW_FIRST+0)
constexpr sal_uInt16 SDRATTR_START(XATTR_START)
constexpr TypedWhichId< SdrMetricItem > SDRATTR_SHADOWYDIST(SDRATTR_SHADOW_FIRST+3)
constexpr sal_uInt16 SDRATTR_END(SDRATTR_WRITINGMODE2_LAST)
constexpr TypedWhichId< SdrMetricItem > SDRATTR_SHADOWXDIST(SDRATTR_SHADOW_FIRST+2)
sal_Int16 SCTAB
Definition: types.hxx:22
sal_Int16 SCCOL
Definition: types.hxx:21
::boost::intrusive_ptr< formula::FormulaToken > ScTokenRef
Definition: types.hxx:29
sal_Int32 SCROW
Definition: types.hxx:17
constexpr TypedWhichId< XLineColorItem > XATTR_LINECOLOR(XATTR_LINE_FIRST+3)
constexpr TypedWhichId< XLineWidthItem > XATTR_LINEWIDTH(XATTR_LINE_FIRST+2)
constexpr TypedWhichId< XLineEndItem > XATTR_LINEEND(XATTR_LINE_FIRST+5)
constexpr TypedWhichId< XLineStartItem > XATTR_LINESTART(XATTR_LINE_FIRST+4)