diff options
Diffstat (limited to 'binfilter/bf_sc/source/core/tool/sc_detfunc.cxx')
-rw-r--r-- | binfilter/bf_sc/source/core/tool/sc_detfunc.cxx | 1695 |
1 files changed, 1695 insertions, 0 deletions
diff --git a/binfilter/bf_sc/source/core/tool/sc_detfunc.cxx b/binfilter/bf_sc/source/core/tool/sc_detfunc.cxx new file mode 100644 index 000000000000..1e677adcda46 --- /dev/null +++ b/binfilter/bf_sc/source/core/tool/sc_detfunc.cxx @@ -0,0 +1,1695 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifdef _MSC_VER +#pragma hdrstop +#endif + +// INCLUDE --------------------------------------------------------------- + +#include "scitems.hxx" +#include <bf_svtools/colorcfg.hxx> +#include <bf_svx/outlobj.hxx> + +#include <bf_svx/xdef.hxx> + +#include <bf_svx/svditer.hxx> +#include <bf_svx/svdocapt.hxx> +#include <bf_svx/svdocirc.hxx> +#include <bf_svx/svdopath.hxx> +#include <bf_svx/svdpage.hxx> +#include <bf_svx/svdundo.hxx> +#include <bf_svx/xflclit.hxx> +#include <bf_svx/xlnclit.hxx> +#include <bf_svx/xlnedcit.hxx> +#include <bf_svx/xlnedit.hxx> +#include <bf_svx/xlnedwit.hxx> +#include <bf_svx/xlnstcit.hxx> +#include <bf_svx/xlnstit.hxx> +#include <bf_svx/xlnstwit.hxx> +#include <bf_svx/xlnwtit.hxx> + +#include "detfunc.hxx" +#include "document.hxx" +#include "dociter.hxx" +#include "drwlayer.hxx" +#include "userdat.hxx" +#include "validat.hxx" +#include "cell.hxx" +#include "docpool.hxx" +#include "patattr.hxx" +#include "scmod.hxx" +namespace binfilter { + +//------------------------------------------------------------------------ + +// #99319# line ends are now created with an empty name. +// The checkForUniqueItem method then finds a unique name for the item's value. +#define SC_LINEEND_NAME EMPTY_STRING + +//------------------------------------------------------------------------ + +enum DetInsertResult { // Return-Werte beim Einfuegen in einen Level + DET_INS_CONTINUE, + DET_INS_INSERTED, + DET_INS_EMPTY, + DET_INS_CIRCULAR }; + +// maximale Textlaenge (Zeichen), die noch in "kleines" Objekt passt +#define SC_NOTE_SMALLTEXT 100 + +//------------------------------------------------------------------------ + +//-/class ScPublicAttrObj : public SdrAttrObj +//-/{ +//-/private: +//-/ ScPublicAttrObj() {} // wird nicht angelegt +//-/public: +//-/ const XLineAttrSetItem* GetLineAttr() { return pLineAttr; } +//-/}; + +//------------------------------------------------------------------------ + +/*N*/ class ScDetectiveData +/*N*/ { +/*N*/ private: +/*N*/ SfxItemSet aBoxSet; +/*N*/ SfxItemSet aArrowSet; +/*N*/ SfxItemSet aToTabSet; +/*N*/ SfxItemSet aFromTabSet; +/*N*/ SfxItemSet aCircleSet; //! einzeln ? +/*N*/ USHORT nMaxLevel; +/*N*/ +/*N*/ public: +/*N*/ ScDetectiveData( SdrModel* pModel ); +/*N*/ +/*N*/ SfxItemSet& GetBoxSet() { return aBoxSet; } +/*N*/ SfxItemSet& GetArrowSet() { return aArrowSet; } +/*N*/ SfxItemSet& GetToTabSet() { return aToTabSet; } +/*N*/ SfxItemSet& GetFromTabSet() { return aFromTabSet; } +/*N*/ SfxItemSet& GetCircleSet() { return aCircleSet; } +/*N*/ +/*N*/ void SetMaxLevel( USHORT nVal ) { nMaxLevel = nVal; } +/*N*/ USHORT GetMaxLevel() const { return nMaxLevel; } +/*N*/ }; + +/*N*/ class ScCommentData +/*N*/ { +/*N*/ private: +/*N*/ SfxItemSet aCaptionSet; +/*N*/ +/*N*/ public: +/*N*/ ScCommentData( ScDocument* pDoc, SdrModel* pModel ); +/*N*/ +/*N*/ SfxItemSet& GetCaptionSet() { return aCaptionSet; } +/*N*/ }; + +//------------------------------------------------------------------------ + +/*N*/ ColorData ScDetectiveFunc::nArrowColor = 0; +/*N*/ ColorData ScDetectiveFunc::nErrorColor = 0; +/*N*/ ColorData ScDetectiveFunc::nCommentColor = 0; +/*N*/ BOOL ScDetectiveFunc::bColorsInitialized = FALSE; + +//------------------------------------------------------------------------ + +/*N*/ BOOL lcl_HasThickLine( SdrObject& rObj ) // detective.sdc +/*N*/ { +/*N*/ // thin lines get width 0 -> everything greater 0 is a thick line +/*N*/ +/*N*/ return ( ((const XLineWidthItem&)rObj.GetItem(XATTR_LINEWIDTH)).GetValue() > 0 ); +/*N*/ } + +//------------------------------------------------------------------------ + +/*N*/ ScDetectiveData::ScDetectiveData( SdrModel* pModel ) : +/*N*/ aBoxSet( pModel->GetItemPool(), SDRATTR_START, SDRATTR_END ), +/*N*/ aArrowSet( pModel->GetItemPool(), SDRATTR_START, SDRATTR_END ), +/*N*/ aToTabSet( pModel->GetItemPool(), SDRATTR_START, SDRATTR_END ), +/*N*/ aFromTabSet( pModel->GetItemPool(), SDRATTR_START, SDRATTR_END ), +/*N*/ aCircleSet( pModel->GetItemPool(), SDRATTR_START, SDRATTR_END ) +/*N*/ { +/*N*/ nMaxLevel = 0; +/*N*/ +/*N*/ aBoxSet.Put( XLineColorItem( EMPTY_STRING, Color( ScDetectiveFunc::GetArrowColor() ) ) ); +/*N*/ aBoxSet.Put( XFillStyleItem( XFILL_NONE ) ); +/*N*/ +/*N*/ // #66479# Standard-Linienenden (wie aus XLineEndList::Create) selber zusammenbasteln, +/*N*/ // um von den konfigurierten Linienenden unabhaengig zu sein +/*N*/ +/*N*/ XPolygon aTriangle(4); +/*N*/ aTriangle[0].X()=10; aTriangle[0].Y()= 0; +/*N*/ aTriangle[1].X()= 0; aTriangle[1].Y()=30; +/*N*/ aTriangle[2].X()=20; aTriangle[2].Y()=30; +/*N*/ aTriangle[3].X()=10; aTriangle[3].Y()= 0; // #99319# line end polygon must be closed +/*N*/ +/*N*/ XPolygon aSquare(5); +/*N*/ aSquare[0].X()= 0; aSquare[0].Y()= 0; +/*N*/ aSquare[1].X()=10; aSquare[1].Y()= 0; +/*N*/ aSquare[2].X()=10; aSquare[2].Y()=10; +/*N*/ aSquare[3].X()= 0; aSquare[3].Y()=10; +/*N*/ aSquare[4].X()= 0; aSquare[4].Y()= 0; // #99319# line end polygon must be closed +/*N*/ +/*N*/ XPolygon aCircle(Point(0,0),100,100); +/*N*/ +/*N*/ String aName = SC_LINEEND_NAME; +/*N*/ +/*N*/ aArrowSet.Put( XLineStartItem( aName, aCircle ) ); +/*N*/ aArrowSet.Put( XLineStartWidthItem( 200 ) ); +/*N*/ aArrowSet.Put( XLineStartCenterItem( TRUE ) ); +/*N*/ aArrowSet.Put( XLineEndItem( aName, aTriangle ) ); +/*N*/ aArrowSet.Put( XLineEndWidthItem( 200 ) ); +/*N*/ aArrowSet.Put( XLineEndCenterItem( FALSE ) ); +/*N*/ +/*N*/ aToTabSet.Put( XLineStartItem( aName, aCircle ) ); +/*N*/ aToTabSet.Put( XLineStartWidthItem( 200 ) ); +/*N*/ aToTabSet.Put( XLineStartCenterItem( TRUE ) ); +/*N*/ aToTabSet.Put( XLineEndItem( aName, aSquare ) ); +/*N*/ aToTabSet.Put( XLineEndWidthItem( 300 ) ); +/*N*/ aToTabSet.Put( XLineEndCenterItem( FALSE ) ); +/*N*/ +/*N*/ aFromTabSet.Put( XLineStartItem( aName, aSquare ) ); +/*N*/ aFromTabSet.Put( XLineStartWidthItem( 300 ) ); +/*N*/ aFromTabSet.Put( XLineStartCenterItem( TRUE ) ); +/*N*/ aFromTabSet.Put( XLineEndItem( aName, aTriangle ) ); +/*N*/ aFromTabSet.Put( XLineEndWidthItem( 200 ) ); +/*N*/ aFromTabSet.Put( XLineEndCenterItem( FALSE ) ); +/*N*/ +/*N*/ aCircleSet.Put( XLineColorItem( String(), Color( ScDetectiveFunc::GetErrorColor() ) ) ); +/*N*/ aCircleSet.Put( XFillStyleItem( XFILL_NONE ) ); +/*N*/ USHORT nWidth = 55; // 54 = 1 Pixel +/*N*/ aCircleSet.Put( XLineWidthItem( nWidth ) ); +/*N*/ } + +/*N*/ ScCommentData::ScCommentData( ScDocument* pDoc, SdrModel* pModel ) : +/*N*/ aCaptionSet( pModel->GetItemPool(), SDRATTR_START, SDRATTR_END, +/*N*/ EE_CHAR_START, EE_CHAR_END, 0 ) +/*N*/ { +/*N*/ XPolygon aTriangle(4); +/*N*/ aTriangle[0].X()=10; aTriangle[0].Y()= 0; +/*N*/ aTriangle[1].X()= 0; aTriangle[1].Y()=30; +/*N*/ aTriangle[2].X()=20; aTriangle[2].Y()=30; +/*N*/ aTriangle[3].X()=10; aTriangle[3].Y()= 0; // #99319# line end polygon must be closed +/*N*/ +/*N*/ String aName = SC_LINEEND_NAME; +/*N*/ +/*N*/ aCaptionSet.Put( XLineStartItem( aName, aTriangle ) ); +/*N*/ aCaptionSet.Put( XLineStartWidthItem( 200 ) ); +/*N*/ aCaptionSet.Put( XLineStartCenterItem( FALSE ) ); +/*N*/ aCaptionSet.Put( XFillStyleItem( XFILL_SOLID ) ); +/*N*/ Color aYellow( ScDetectiveFunc::GetCommentColor() ); +/*N*/ aCaptionSet.Put( XFillColorItem( String(), aYellow ) ); +/*N*/ +/*N*/ // shadow +/*N*/ // SdrShadowItem has FALSE, instead the shadow is set for the rectangle +/*N*/ // only with SetSpecialTextBoxShadow when the object is created +/*N*/ // (item must be set to adjust objects from older files) +/*N*/ aCaptionSet.Put( SdrShadowItem( FALSE ) ); +/*N*/ aCaptionSet.Put( SdrShadowXDistItem( 100 ) ); +/*N*/ aCaptionSet.Put( SdrShadowYDistItem( 100 ) ); +/*N*/ +/*N*/ // text attributes +/*N*/ aCaptionSet.Put( SdrTextLeftDistItem( 100 ) ); +/*N*/ aCaptionSet.Put( SdrTextRightDistItem( 100 ) ); +/*N*/ aCaptionSet.Put( SdrTextUpperDistItem( 100 ) ); +/*N*/ aCaptionSet.Put( SdrTextLowerDistItem( 100 ) ); +/*N*/ +/*N*/ // #78943# do use the default cell style, so the user has a chance to +/*N*/ // modify the font for the annotations +/*N*/ ((const ScPatternAttr&)pDoc->GetPool()->GetDefaultItem(ATTR_PATTERN)). +/*N*/ FillEditItemSet( &aCaptionSet ); +/*N*/ } + +//------------------------------------------------------------------------ + +/*N*/ inline BOOL Intersect( USHORT nStartCol1, USHORT nStartRow1, USHORT nEndCol1, USHORT nEndRow1, +/*N*/ USHORT nStartCol2, USHORT nStartRow2, USHORT nEndCol2, USHORT nEndRow2 ) +/*N*/ { +/*N*/ return nEndCol1 >= nStartCol2 && nEndCol2 >= nStartCol1 && +/*N*/ nEndRow1 >= nStartRow2 && nEndRow2 >= nStartRow1; +/*N*/ } + +/*N*/ BOOL ScDetectiveFunc::HasError( const ScTripel& rStart, const ScTripel& rEnd, ScTripel& rErrPos ) +/*N*/ { +/*N*/ rErrPos = rStart; +/*N*/ USHORT nError = 0; +/*N*/ +/*N*/ ScCellIterator aCellIter( pDoc, rStart.GetCol(), rStart.GetRow(), rStart.GetTab(), +/*N*/ rEnd.GetCol(), rEnd.GetRow(), rEnd.GetTab() ); +/*N*/ ScBaseCell* pCell = aCellIter.GetFirst(); +/*N*/ while (pCell) +/*N*/ { +/*N*/ if (pCell->GetCellType() == CELLTYPE_FORMULA) +/*N*/ { +/*N*/ nError = ((ScFormulaCell*)pCell)->GetErrCode(); +/*N*/ if (nError) +/*N*/ rErrPos.Put( aCellIter.GetCol(), aCellIter.GetRow(), aCellIter.GetTab() ); +/*N*/ } +/*N*/ pCell = aCellIter.GetNext(); +/*N*/ } +/*N*/ +/*N*/ return (nError != 0); +/*N*/ } + +/*N*/ Point ScDetectiveFunc::GetDrawPos( USHORT nCol, USHORT nRow, BOOL bArrow ) +/*N*/ { +/*N*/ // MAXCOL/ROW+1 ist erlaubt fuer Ende von Rahmen +/*N*/ if (nCol > MAXCOL+1) +/*N*/ { +/*N*/ DBG_ERROR("falsche Col in ScDetectiveFunc::GetDrawPos"); +/*N*/ nCol = MAXCOL+1; +/*N*/ } +/*N*/ if (nRow > MAXROW+1) +/*N*/ { +/*N*/ DBG_ERROR("falsche Row in ScDetectiveFunc::GetDrawPos"); +/*N*/ nRow = MAXROW+1; +/*N*/ } +/*N*/ +/*N*/ Point aPos; +/*N*/ USHORT i; +/*N*/ USHORT nLocalTab = nTab; // nicht ueber this +/*N*/ +/*N*/ for (i=0; i<nCol; i++) +/*N*/ aPos.X() += pDoc->GetColWidth( i,nLocalTab ); +/*N*/ for (i=0; i<nRow; i++) +/*N*/ aPos.Y() += pDoc->FastGetRowHeight( i,nLocalTab ); +/*N*/ +/*N*/ if (bArrow) +/*N*/ { +/*N*/ if (nCol<=MAXCOL) +/*N*/ aPos.X() += pDoc->GetColWidth( nCol, nLocalTab ) / 4; +/*N*/ if (nCol<=MAXROW) +/*N*/ aPos.Y() += pDoc->GetRowHeight( nRow, nLocalTab ) / 2; +/*N*/ } +/*N*/ +/*N*/ aPos.X() = (long) ( aPos.X() * HMM_PER_TWIPS ); +/*N*/ aPos.Y() = (long) ( aPos.Y() * HMM_PER_TWIPS ); +/*N*/ +/*N*/ return aPos; +/*N*/ } + +/*N*/ BOOL lcl_IsOtherTab( const XPolygon& rPolygon ) +/*N*/ { +/*N*/ // test if rPolygon is the line end for "other table" (rectangle) +/*N*/ +/*N*/ USHORT nCount = rPolygon.GetPointCount(); +/*N*/ if ( nCount == 4 ) +/*N*/ { +/*N*/ // 4 points -> it is a rectangle (not closed) only if the first and last point are different +/*N*/ +/*N*/ return rPolygon[0] != rPolygon[3]; +/*N*/ } +/*N*/ else if ( nCount == 5 ) +/*N*/ { +/*N*/ // 5 points -> it is a rectangle (closed) only if the first and last point are equal +/*N*/ +/*N*/ return rPolygon[0] == rPolygon[4]; +/*N*/ } +/*N*/ return FALSE; +/*N*/ } + +/*N*/ BOOL ScDetectiveFunc::HasArrow( USHORT nStartCol, USHORT nStartRow, USHORT nStartTab, +/*N*/ USHORT nEndCol, USHORT nEndRow, USHORT nEndTab ) +/*N*/ { +/*N*/ BOOL bStartAlien = ( nStartTab != nTab ); +/*N*/ BOOL bEndAlien = ( nEndTab != nTab ); +/*N*/ +/*N*/ if (bStartAlien && bEndAlien) +/*N*/ { +/*N*/ DBG_ERROR("bStartAlien && bEndAlien"); +/*N*/ return TRUE; +/*N*/ } +/*N*/ +/*N*/ Rectangle aStartRect; +/*N*/ Rectangle aEndRect; +/*N*/ if (!bStartAlien) +/*N*/ { +/*N*/ Point aStartPos = GetDrawPos( nStartCol, nStartRow, FALSE ); +/*N*/ Size aStartSize = Size( +/*N*/ (long) ( pDoc->GetColWidth( nStartCol, nTab) * HMM_PER_TWIPS ), +/*N*/ (long) ( pDoc->GetRowHeight( nStartRow, nTab) * HMM_PER_TWIPS ) ); +/*N*/ aStartRect = Rectangle( aStartPos, aStartSize ); +/*N*/ } +/*N*/ if (!bEndAlien) +/*N*/ { +/*N*/ Point aEndPos = GetDrawPos( nEndCol, nEndRow, FALSE ); +/*N*/ Size aEndSize = Size( +/*N*/ (long) ( pDoc->GetColWidth( nEndCol, nTab) * HMM_PER_TWIPS ), +/*N*/ (long) ( pDoc->GetRowHeight( nEndRow, nTab) * HMM_PER_TWIPS ) ); +/*N*/ aEndRect = Rectangle( aEndPos, aEndSize ); +/*N*/ } +/*N*/ +/*N*/ ScDrawLayer* pModel = pDoc->GetDrawLayer(); +/*N*/ SdrPage* pPage = pModel->GetPage(nTab); +/*N*/ DBG_ASSERT(pPage,"Page ?"); +/*N*/ +/*N*/ BOOL bFound = FALSE; +/*N*/ SdrObjListIter aIter( *pPage, IM_FLAT ); +/*N*/ SdrObject* pObject = aIter.Next(); +/*N*/ while (pObject && !bFound) +/*N*/ { +/*N*/ if ( pObject->GetLayer()==SC_LAYER_INTERN && +/*N*/ pObject->IsPolyObj() && pObject->GetPointCount()==2 ) +/*N*/ { +/*N*/ BOOL bObjStartAlien = +/*N*/ lcl_IsOtherTab( ((const XLineStartItem&)pObject->GetItem(XATTR_LINESTART)).GetValue() ); +/*N*/ BOOL bObjEndAlien = +/*N*/ lcl_IsOtherTab( ((const XLineEndItem&)pObject->GetItem(XATTR_LINEEND)).GetValue() ); +/*N*/ +/*N*/ //-/ BOOL bObjStartAlien = FALSE; +/*N*/ //-/ BOOL bObjEndAlien = FALSE; +/*N*/ //-/ const XLineAttrSetItem* pLineAttrs = +/*N*/ //-/ ((ScPublicAttrObj*)(SdrAttrObj*)pObject)->GetLineAttr(); +/*N*/ //-/ if (pLineAttrs) +/*N*/ //-/ { +/*N*/ //-/ const SfxItemSet& rSet = pLineAttrs->GetItemSet(); +/*N*/ //-/ bObjStartAlien = (((const XLineStartItem&)rSet.Get(XATTR_LINESTART)). +/*N*/ //-/ GetValue().GetPointCount() == 4 ); +/*N*/ //-/ bObjEndAlien = (((const XLineEndItem&)rSet.Get(XATTR_LINEEND)). +/*N*/ //-/ GetValue().GetPointCount() == 4 ); +/*N*/ //-/ } +/*N*/ +/*N*/ BOOL bStartHit = bStartAlien ? bObjStartAlien : +/*N*/ ( !bObjStartAlien && aStartRect.IsInside(pObject->GetPoint(0)) ); +/*N*/ BOOL bEndHit = bEndAlien ? bObjEndAlien : +/*N*/ ( !bObjEndAlien && aEndRect.IsInside(pObject->GetPoint(1)) ); +/*N*/ +/*N*/ if ( bStartHit && bEndHit ) +/*N*/ bFound = TRUE; +/*N*/ } +/*N*/ pObject = aIter.Next(); +/*N*/ } +/*N*/ +/*N*/ return bFound; +/*N*/ } + + +//------------------------------------------------------------------------ + +// InsertXXX: called from DrawEntry/DrawAlienEntry and InsertObject + +/*N*/ BOOL ScDetectiveFunc::InsertArrow( USHORT nCol, USHORT nRow, +/*N*/ USHORT nRefStartCol, USHORT nRefStartRow, +/*N*/ USHORT nRefEndCol, USHORT nRefEndRow, +/*N*/ BOOL bFromOtherTab, BOOL bRed, +/*N*/ ScDetectiveData& rData ) +/*N*/ { +/*N*/ ScDrawLayer* pModel = pDoc->GetDrawLayer(); +/*N*/ SdrPage* pPage = pModel->GetPage(nTab); +/*N*/ +/*N*/ BOOL bArea = ( nRefStartCol != nRefEndCol || nRefStartRow != nRefEndRow ); +/*N*/ if (bArea && !bFromOtherTab) +/*N*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 +/*N*/ } +/*N*/ +/*N*/ Point aStartPos = GetDrawPos( nRefStartCol, nRefStartRow, TRUE ); +/*N*/ Point aEndPos = GetDrawPos( nCol, nRow, TRUE ); +/*N*/ +/*N*/ if (bFromOtherTab) +/*N*/ { +/*N*/ aStartPos = Point( aEndPos.X() - 1000, aEndPos.Y() - 1000 ); +/*N*/ if (aStartPos.X() < 0) +/*N*/ aStartPos.X() += 2000; +/*N*/ if (aStartPos.Y() < 0) +/*N*/ aStartPos.Y() += 2000; +/*N*/ } +/*N*/ +/*N*/ SfxItemSet& rAttrSet = bFromOtherTab ? rData.GetFromTabSet() : rData.GetArrowSet(); +/*N*/ +/*N*/ if (bArea && !bFromOtherTab) +/*N*/ rAttrSet.Put( XLineWidthItem( 50 ) ); // Bereich +/*N*/ else +/*N*/ rAttrSet.Put( XLineWidthItem( 0 ) ); // einzelne Referenz +/*N*/ +/*N*/ ColorData nColorData = ( bRed ? GetErrorColor() : GetArrowColor() ); +/*N*/ rAttrSet.Put( XLineColorItem( String(), Color( nColorData ) ) ); +/*N*/ Point aPointArr[2] = {aStartPos, aEndPos}; +/*N*/ SdrPathObj* pArrow = new SdrPathObj(OBJ_LINE, +/*N*/ XPolyPolygon(XPolygon(Polygon(2, aPointArr)))); +/*N*/ +/*N*/ pArrow->NbcSetLogicRect(Rectangle(aStartPos,aEndPos)); //! noetig ??? +/*N*/ +/*N*/ //-/ pArrow->SetAttributes( rAttrSet, FALSE ); +/*N*/ pArrow->SetItemSetAndBroadcast(rAttrSet); +/*N*/ +/*N*/ ScDrawLayer::SetAnchor( pArrow, SCA_CELL ); +/*N*/ pArrow->SetLayer( SC_LAYER_INTERN ); +/*N*/ pPage->InsertObject( pArrow ); +/*N*/ pModel->AddCalcUndo( new SdrUndoInsertObj( *pArrow ) ); +/*N*/ +/*N*/ ScDrawObjData* pData = ScDrawLayer::GetObjData( pArrow, TRUE ); +/*N*/ if (bFromOtherTab) +/*N*/ pData->bValidStart = FALSE; +/*N*/ else +/*N*/ { +/*N*/ pData->aStt.nCol = nRefStartCol; +/*N*/ pData->aStt.nRow = nRefStartRow; +/*N*/ pData->aStt.nTab = nTab; +/*N*/ pData->bValidStart = TRUE; +/*N*/ } +/*N*/ +/*N*/ pData->aEnd.nCol = nCol; +/*N*/ pData->aEnd.nRow = nRow; +/*N*/ pData->aEnd.nTab = nTab; +/*N*/ pData->bValidEnd = TRUE; +/*N*/ +/*N*/ return TRUE; +/*N*/ } + +/*N*/ BOOL ScDetectiveFunc::InsertToOtherTab( USHORT nStartCol, USHORT nStartRow, +/*N*/ USHORT nEndCol, USHORT nEndRow, BOOL bRed, +/*N*/ ScDetectiveData& rData ) +/*N*/ { +/*N*/ ScDrawLayer* pModel = pDoc->GetDrawLayer(); +/*N*/ SdrPage* pPage = pModel->GetPage(nTab); +/*N*/ +/*N*/ BOOL bArea = ( nStartCol != nEndCol || nStartRow != nEndRow ); +/*N*/ if (bArea) +/*N*/ { +/*N*/ Point aStartCorner = GetDrawPos( nStartCol, nStartRow, FALSE ); +/*N*/ Point aEndCorner = GetDrawPos( nEndCol+1, nEndRow+1, FALSE ); +/*N*/ +/*N*/ SdrRectObj* pBox = new SdrRectObj(Rectangle(aStartCorner,aEndCorner)); +/*N*/ +/*N*/ //-/ pBox->SetAttributes( rData.GetBoxSet(), FALSE ); +/*N*/ pBox->SetItemSetAndBroadcast(rData.GetBoxSet()); +/*N*/ +/*N*/ ScDrawLayer::SetAnchor( pBox, SCA_CELL ); +/*N*/ pBox->SetLayer( SC_LAYER_INTERN ); +/*N*/ pPage->InsertObject( pBox ); +/*N*/ pModel->AddCalcUndo( new SdrUndoInsertObj( *pBox ) ); +/*N*/ +/*N*/ ScDrawObjData* pData = ScDrawLayer::GetObjData( pBox, TRUE ); +/*N*/ pData->aStt.nCol = nStartCol; +/*N*/ pData->aStt.nRow = nStartRow; +/*N*/ pData->aStt.nTab = nTab; +/*N*/ pData->aEnd.nCol = nEndCol; +/*N*/ pData->aEnd.nRow = nEndRow; +/*N*/ pData->aEnd.nTab = nTab; +/*N*/ pData->bValidStart = TRUE; +/*N*/ pData->bValidEnd = TRUE; +/*N*/ } +/*N*/ +/*N*/ Point aStartPos = GetDrawPos( nStartCol, nStartRow, TRUE ); +/*N*/ Point aEndPos = Point( aStartPos.X() + 1000, aStartPos.Y() - 1000 ); +/*N*/ if (aEndPos.Y() < 0) +/*N*/ aEndPos.Y() += 2000; +/*N*/ +/*N*/ SfxItemSet& rAttrSet = rData.GetToTabSet(); +/*N*/ if (bArea) +/*N*/ rAttrSet.Put( XLineWidthItem( 50 ) ); // Bereich +/*N*/ else +/*N*/ rAttrSet.Put( XLineWidthItem( 0 ) ); // einzelne Referenz +/*N*/ +/*N*/ ColorData nColorData = ( bRed ? GetErrorColor() : GetArrowColor() ); +/*N*/ rAttrSet.Put( XLineColorItem( String(), Color( nColorData ) ) ); +/*N*/ Point aPointArr[2] = {aStartPos, aEndPos}; +/*N*/ SdrPathObj* pArrow = new SdrPathObj(OBJ_LINE, +/*N*/ XPolyPolygon(XPolygon(Polygon(2, aPointArr)))); +/*N*/ +/*N*/ pArrow->NbcSetLogicRect(Rectangle(aStartPos,aEndPos)); //! noetig ??? +/*N*/ +/*N*/ //-/ pArrow->SetAttributes( rAttrSet, FALSE ); +/*N*/ pArrow->SetItemSetAndBroadcast(rAttrSet); +/*N*/ +/*N*/ ScDrawLayer::SetAnchor( pArrow, SCA_CELL ); +/*N*/ pArrow->SetLayer( SC_LAYER_INTERN ); +/*N*/ pPage->InsertObject( pArrow ); +/*N*/ pModel->AddCalcUndo( new SdrUndoInsertObj( *pArrow ) ); +/*N*/ +/*N*/ ScDrawObjData* pData = ScDrawLayer::GetObjData( pArrow, TRUE ); +/*N*/ pData->aStt.nCol = nStartCol; +/*N*/ pData->aStt.nRow = nStartRow; +/*N*/ pData->aStt.nTab = nTab; +/*N*/ pData->bValidStart = TRUE; +/*N*/ pData->bValidEnd = FALSE; +/*N*/ +/*N*/ return TRUE; +/*N*/ } + +//------------------------------------------------------------------------ + +// DrawEntry: Formel auf dieser Tabelle, +// Referenz auf dieser oder anderer +// DrawAlienEntry: Formel auf anderer Tabelle, +// Referenz auf dieser + +// return FALSE: da war schon ein Pfeil + +/*N*/ BOOL ScDetectiveFunc::DrawEntry( USHORT nCol, USHORT nRow, +/*N*/ const ScTripel& rRefStart, const ScTripel& rRefEnd, +/*N*/ ScDetectiveData& rData ) +/*N*/ { +/*N*/ if ( HasArrow( rRefStart.GetCol(), rRefStart.GetRow(), rRefStart.GetTab(), +/*N*/ nCol, nRow, nTab ) ) +/*N*/ return FALSE; +/*N*/ +/*N*/ ScTripel aErrorPos; +/*N*/ BOOL bError = HasError( rRefStart, rRefEnd, aErrorPos ); +/*N*/ BOOL bAlien = ( rRefEnd.GetTab() < nTab || rRefStart.GetTab() > nTab ); +/*N*/ +/*N*/ return InsertArrow( nCol, nRow, +/*N*/ rRefStart.GetCol(), rRefStart.GetRow(), +/*N*/ rRefEnd.GetCol(), rRefEnd.GetRow(), +/*N*/ bAlien, bError, rData ); +/*N*/ } + +/*N*/ BOOL ScDetectiveFunc::DrawAlienEntry( const ScTripel& rRefStart, const ScTripel& rRefEnd, +/*N*/ ScDetectiveData& rData ) +/*N*/ { +/*N*/ if ( HasArrow( rRefStart.GetCol(), rRefStart.GetRow(), rRefStart.GetTab(), +/*N*/ 0, 0, nTab+1 ) ) +/*N*/ return FALSE; +/*N*/ +/*N*/ ScTripel aErrorPos; +/*N*/ BOOL bError = HasError( rRefStart, rRefEnd, aErrorPos ); +/*N*/ +/*N*/ return InsertToOtherTab( rRefStart.GetCol(), rRefStart.GetRow(), +/*N*/ rRefEnd.GetCol(), rRefEnd.GetRow(), +/*N*/ bError, rData ); +/*N*/ } + +/*N*/ void ScDetectiveFunc::DrawCircle( USHORT nCol, USHORT nRow, ScDetectiveData& rData ) +/*N*/ { +/*N*/ ScDrawLayer* pModel = pDoc->GetDrawLayer(); +/*N*/ SdrPage* pPage = pModel->GetPage(nTab); +/*N*/ +/*N*/ Point aStartPos = GetDrawPos( nCol, nRow, FALSE ); +/*N*/ Size aSize( (long) ( pDoc->GetColWidth(nCol, nTab) * HMM_PER_TWIPS ), +/*N*/ (long) ( pDoc->GetRowHeight(nRow, nTab) * HMM_PER_TWIPS ) ); +/*N*/ Rectangle aRect( aStartPos, aSize ); +/*N*/ aRect.Left() -= 250; +/*N*/ aRect.Right() += 250; +/*N*/ aRect.Top() -= 70; +/*N*/ aRect.Bottom() += 70; +/*N*/ +/*N*/ SdrCircObj* pCircle = new SdrCircObj( OBJ_CIRC, aRect ); +/*N*/ SfxItemSet& rAttrSet = rData.GetCircleSet(); +/*N*/ +/*N*/ //-/ pCircle->SetAttributes( rAttrSet, FALSE ); +/*N*/ pCircle->SetItemSetAndBroadcast(rAttrSet); +/*N*/ +/*N*/ ScDrawLayer::SetAnchor( pCircle, SCA_CELL ); +/*N*/ pCircle->SetLayer( SC_LAYER_INTERN ); +/*N*/ pPage->InsertObject( pCircle ); +/*N*/ pModel->AddCalcUndo( new SdrUndoInsertObj( *pCircle ) ); +/*N*/ +/*N*/ ScDrawObjData* pData = ScDrawLayer::GetObjData( pCircle, TRUE ); +/*N*/ pData->aStt.nCol = nCol; +/*N*/ pData->aStt.nRow = nRow; +/*N*/ pData->aStt.nTab = nTab; +/*N*/ pData->bValidStart = TRUE; +/*N*/ pData->bValidEnd = FALSE; +/*N*/ } + + +/*N*/ void ScDetectiveFunc::DeleteArrowsAt( USHORT nCol, USHORT nRow, BOOL bDestPnt ) +/*N*/ { +/*N*/ Point aPos = GetDrawPos( nCol, nRow, FALSE ); +/*N*/ Size aSize = Size( (long) ( pDoc->GetColWidth( nCol, nTab) * HMM_PER_TWIPS ), +/*N*/ (long) ( pDoc->GetRowHeight( nRow, nTab) * HMM_PER_TWIPS ) ); +/*N*/ Rectangle aRect( aPos, aSize ); +/*N*/ +/*N*/ ScDrawLayer* pModel = pDoc->GetDrawLayer(); +/*N*/ SdrPage* pPage = pModel->GetPage(nTab); +/*N*/ DBG_ASSERT(pPage,"Page ?"); +/*N*/ +/*N*/ pPage->RecalcObjOrdNums(); +/*N*/ +/*N*/ long nDelCount = 0; +/*N*/ ULONG nObjCount = pPage->GetObjCount(); +/*N*/ if (nObjCount) +/*N*/ { +/*N*/ SdrObject** ppObj = new SdrObject*[nObjCount]; +/*N*/ +/*N*/ SdrObjListIter aIter( *pPage, IM_FLAT ); +/*N*/ SdrObject* pObject = aIter.Next(); +/*N*/ while (pObject) +/*N*/ { +/*N*/ if ( pObject->GetLayer()==SC_LAYER_INTERN && +/*N*/ pObject->IsPolyObj() && pObject->GetPointCount()==2 ) +/*N*/ { +/*N*/ if (aRect.IsInside(pObject->GetPoint(bDestPnt))) // Start/Zielpunkt +/*N*/ ppObj[nDelCount++] = pObject; +/*N*/ } +/*N*/ +/*N*/ pObject = aIter.Next(); +/*N*/ } +/*N*/ +/*N*/ long i; +/*N*/ for (i=1; i<=nDelCount; i++) +/*N*/ pModel->AddCalcUndo( new SdrUndoRemoveObj( *ppObj[nDelCount-i] ) ); +/*N*/ +/*N*/ for (i=1; i<=nDelCount; i++) +/*N*/ pPage->RemoveObject( ppObj[nDelCount-i]->GetOrdNum() ); +/*N*/ +/*N*/ delete[] ppObj; +/*N*/ } +/*N*/ } + + // Box um Referenz loeschen + +#define SC_DET_TOLERANCE 50 + +/*N*/ inline BOOL RectIsPoints( const Rectangle& rRect, const Point& rStart, const Point& rEnd ) +/*N*/ { +/*N*/ return rRect.Left() >= rStart.X() - SC_DET_TOLERANCE +/*N*/ && rRect.Left() <= rStart.X() + SC_DET_TOLERANCE +/*N*/ && rRect.Right() >= rEnd.X() - SC_DET_TOLERANCE +/*N*/ && rRect.Right() <= rEnd.X() + SC_DET_TOLERANCE +/*N*/ && rRect.Top() >= rStart.Y() - SC_DET_TOLERANCE +/*N*/ && rRect.Top() <= rStart.Y() + SC_DET_TOLERANCE +/*N*/ && rRect.Bottom() >= rEnd.Y() - SC_DET_TOLERANCE +/*N*/ && rRect.Bottom() <= rEnd.Y() + SC_DET_TOLERANCE; +/*N*/ } + +#undef SC_DET_TOLERANCE + +/*N*/ void ScDetectiveFunc::DeleteBox( USHORT nCol1, USHORT nRow1, USHORT nCol2, USHORT nRow2 ) +/*N*/ { +/* String aStr; + aStr += nCol1; + aStr += '/'; + aStr += nRow1; + aStr += '/'; + aStr += nCol2; + aStr += '/'; + aStr += nRow2; + InfoBox(0,aStr).Execute(); +*/ +/*N*/ +/*N*/ Point aStartCorner = GetDrawPos( nCol1, nRow1, FALSE ); +/*N*/ Point aEndCorner = GetDrawPos( nCol2+1, nRow2+1, FALSE ); +/*N*/ Rectangle aObjRect; +/*N*/ +/*N*/ ScDrawLayer* pModel = pDoc->GetDrawLayer(); +/*N*/ SdrPage* pPage = pModel->GetPage(nTab); +/*N*/ DBG_ASSERT(pPage,"Page ?"); +/*N*/ +/*N*/ pPage->RecalcObjOrdNums(); +/*N*/ +/*N*/ long nDelCount = 0; +/*N*/ ULONG nObjCount = pPage->GetObjCount(); +/*N*/ if (nObjCount) +/*N*/ { +/*N*/ SdrObject** ppObj = new SdrObject*[nObjCount]; +/*N*/ +/*N*/ SdrObjListIter aIter( *pPage, IM_FLAT ); +/*N*/ SdrObject* pObject = aIter.Next(); +/*N*/ while (pObject) +/*N*/ { +/*N*/ if ( pObject->GetLayer() == SC_LAYER_INTERN && +/*N*/ pObject->Type() == TYPE(SdrRectObj) ) +/*N*/ { +/*N*/ aObjRect = ((SdrRectObj*)pObject)->GetLogicRect(); +/*N*/ if ( RectIsPoints( aObjRect, aStartCorner, aEndCorner ) ) +/*N*/ ppObj[nDelCount++] = pObject; +/*N*/ } +/*N*/ +/*N*/ pObject = aIter.Next(); +/*N*/ } +/*N*/ +/*N*/ long i; +/*N*/ for (i=1; i<=nDelCount; i++) +/*N*/ pModel->AddCalcUndo( new SdrUndoRemoveObj( *ppObj[nDelCount-i] ) ); +/*N*/ +/*N*/ for (i=1; i<=nDelCount; i++) +/*N*/ pPage->RemoveObject( ppObj[nDelCount-i]->GetOrdNum() ); +/*N*/ +/*N*/ delete[] ppObj; +/*N*/ } +/*N*/ } + +//------------------------------------------------------------------------ + +/*N*/ USHORT ScDetectiveFunc::InsertPredLevelArea( const ScTripel& rRefStart, const ScTripel& rRefEnd, +/*N*/ ScDetectiveData& rData, USHORT nLevel ) +/*N*/ { +/*N*/ USHORT nResult = DET_INS_EMPTY; +/*N*/ +/*N*/ ScCellIterator aCellIter( pDoc, rRefStart.GetCol(), rRefStart.GetRow(), rRefStart.GetTab(), +/*N*/ rRefEnd.GetCol(), rRefEnd.GetRow(), rRefEnd.GetTab() ); +/*N*/ ScBaseCell* pCell = aCellIter.GetFirst(); +/*N*/ while (pCell) +/*N*/ { +/*N*/ if (pCell->GetCellType() == CELLTYPE_FORMULA) +/*N*/ switch( InsertPredLevel( aCellIter.GetCol(), aCellIter.GetRow(), rData, nLevel ) ) +/*N*/ { +/*N*/ case DET_INS_INSERTED: +/*N*/ nResult = DET_INS_INSERTED; +/*N*/ break; +/*N*/ case DET_INS_CONTINUE: +/*N*/ if (nResult != DET_INS_INSERTED) +/*N*/ nResult = DET_INS_CONTINUE; +/*N*/ break; +/*N*/ case DET_INS_CIRCULAR: +/*N*/ if (nResult == DET_INS_EMPTY) +/*N*/ nResult = DET_INS_CIRCULAR; +/*N*/ break; +/*N*/ } +/*N*/ +/*N*/ pCell = aCellIter.GetNext(); +/*N*/ } +/*N*/ +/*N*/ return nResult; +/*N*/ } + +/*N*/ USHORT ScDetectiveFunc::InsertPredLevel( USHORT nCol, USHORT nRow, ScDetectiveData& rData, +/*N*/ USHORT nLevel ) +/*N*/ { +/*N*/ ScBaseCell* pCell; +/*N*/ pDoc->GetCell( nCol, nRow, nTab, pCell ); +/*N*/ if (!pCell) +/*N*/ return DET_INS_EMPTY; +/*N*/ if (pCell->GetCellType() != CELLTYPE_FORMULA) +/*N*/ return DET_INS_EMPTY; +/*N*/ +/*N*/ ScFormulaCell* pFCell = (ScFormulaCell*)pCell; +/*N*/ if (pFCell->IsRunning()) +/*N*/ return DET_INS_CIRCULAR; +/*N*/ +/*N*/ if (pFCell->GetDirty()) +/*N*/ pFCell->Interpret(); // nach SetRunning geht's nicht mehr! +/*N*/ pFCell->SetRunning(TRUE); +/*N*/ +/*N*/ USHORT nResult = DET_INS_EMPTY; +/*N*/ +/*N*/ ScDetectiveRefIter aIter( (ScFormulaCell*) pCell ); +/*N*/ ScTripel aRefStart; +/*N*/ ScTripel aRefEnd; +/*N*/ while ( aIter.GetNextRef( aRefStart, aRefEnd ) ) +/*N*/ { +/*N*/ if (DrawEntry( nCol, nRow, aRefStart, aRefEnd, rData )) +/*N*/ { +/*N*/ nResult = DET_INS_INSERTED; // neuer Pfeil eingetragen +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ // weiterverfolgen +/*N*/ +/*N*/ if ( nLevel < rData.GetMaxLevel() ) +/*N*/ { +/*N*/ USHORT nSubResult; +/*N*/ BOOL bArea = (aRefStart != aRefEnd); +/*N*/ if (bArea) +/*N*/ nSubResult = InsertPredLevelArea( aRefStart, aRefEnd, rData, nLevel+1 ); +/*N*/ else +/*N*/ nSubResult = InsertPredLevel( aRefStart.GetCol(), aRefStart.GetRow(), +/*N*/ rData, nLevel+1 ); +/*N*/ +/*N*/ switch (nSubResult) +/*N*/ { +/*N*/ case DET_INS_INSERTED: +/*N*/ nResult = DET_INS_INSERTED; +/*N*/ break; +/*N*/ case DET_INS_CONTINUE: +/*N*/ if (nResult != DET_INS_INSERTED) +/*N*/ nResult = DET_INS_CONTINUE; +/*N*/ break; +/*N*/ case DET_INS_CIRCULAR: +/*N*/ if (nResult == DET_INS_EMPTY) +/*N*/ nResult = DET_INS_CIRCULAR; +/*N*/ break; +/*N*/ // DET_INS_EMPTY: unveraendert lassen +/*N*/ } +/*N*/ } +/*N*/ else // nMaxLevel erreicht +/*N*/ if (nResult != DET_INS_INSERTED) +/*N*/ nResult = DET_INS_CONTINUE; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ pFCell->SetRunning(FALSE); +/*N*/ +/*N*/ return nResult; +/*N*/ } + +/*N*/ USHORT ScDetectiveFunc::FindPredLevelArea( const ScTripel& rRefStart, const ScTripel& rRefEnd, +/*N*/ USHORT nLevel, USHORT nDeleteLevel ) +/*N*/ { +/*N*/ USHORT nResult = nLevel; +/*N*/ +/*N*/ ScCellIterator aCellIter( pDoc, rRefStart.GetCol(), rRefStart.GetRow(), rRefStart.GetTab(), +/*N*/ rRefEnd.GetCol(), rRefEnd.GetRow(), rRefEnd.GetTab() ); +/*N*/ ScBaseCell* pCell = aCellIter.GetFirst(); +/*N*/ while (pCell) +/*N*/ { +/*N*/ if (pCell->GetCellType() == CELLTYPE_FORMULA) +/*N*/ { +/*N*/ USHORT nTemp = FindPredLevel( aCellIter.GetCol(), aCellIter.GetRow(), nLevel, nDeleteLevel ); +/*N*/ if (nTemp > nResult) +/*N*/ nResult = nTemp; +/*N*/ } +/*N*/ pCell = aCellIter.GetNext(); +/*N*/ } +/*N*/ +/*N*/ return nResult; +/*N*/ } + + // nDeleteLevel != 0 -> loeschen + +/*N*/ USHORT ScDetectiveFunc::FindPredLevel( USHORT nCol, USHORT nRow, USHORT nLevel, USHORT nDeleteLevel ) +/*N*/ { +/*N*/ DBG_ASSERT( nLevel<1000, "Level" ); +/*N*/ +/*N*/ ScBaseCell* pCell; +/*N*/ pDoc->GetCell( nCol, nRow, nTab, pCell ); +/*N*/ if (!pCell) +/*N*/ return nLevel; +/*N*/ if (pCell->GetCellType() != CELLTYPE_FORMULA) +/*N*/ return nLevel; +/*N*/ +/*N*/ ScFormulaCell* pFCell = (ScFormulaCell*)pCell; +/*N*/ if (pFCell->IsRunning()) +/*N*/ return nLevel; +/*N*/ +/*N*/ if (pFCell->GetDirty()) +/*N*/ pFCell->Interpret(); // nach SetRunning geht's nicht mehr! +/*N*/ pFCell->SetRunning(TRUE); +/*N*/ +/*N*/ USHORT nResult = nLevel; +/*N*/ BOOL bDelete = ( nDeleteLevel && nLevel == nDeleteLevel-1 ); +/*N*/ +/*N*/ if ( bDelete ) +/*N*/ { +/*N*/ DeleteArrowsAt( nCol, nRow, TRUE ); // Pfeile, die hierher zeigen +/*N*/ } +/*N*/ +/*N*/ ScDetectiveRefIter aIter( (ScFormulaCell*) pCell ); +/*N*/ ScTripel aRefStart; +/*N*/ ScTripel aRefEnd; +/*N*/ while ( aIter.GetNextRef( aRefStart, aRefEnd ) ) +/*N*/ { +/*N*/ BOOL bArea = ( aRefStart != aRefEnd ); +/*N*/ +/*N*/ if ( bDelete ) // Rahmen loeschen ? +/*N*/ { +/*N*/ if (bArea) +/*N*/ { +/*N*/ DeleteBox( aRefStart.GetCol(), aRefStart.GetRow(), aRefEnd.GetCol(), aRefEnd.GetRow() ); +/*N*/ } +/*N*/ } +/*N*/ else // weitersuchen +/*N*/ { +/*N*/ if ( HasArrow( aRefStart.GetCol(),aRefStart.GetRow(),aRefStart.GetTab(), +/*N*/ nCol,nRow,nTab ) ) +/*N*/ { +/*N*/ USHORT nTemp; +/*N*/ if (bArea) +/*N*/ nTemp = FindPredLevelArea( aRefStart, aRefEnd, nLevel+1, nDeleteLevel ); +/*N*/ else +/*N*/ nTemp = FindPredLevel( aRefStart.GetCol(),aRefStart.GetRow(), +/*N*/ nLevel+1, nDeleteLevel ); +/*N*/ if (nTemp > nResult) +/*N*/ nResult = nTemp; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ pFCell->SetRunning(FALSE); +/*N*/ +/*N*/ return nResult; +/*N*/ } + +//------------------------------------------------------------------------ + +/*N*/ USHORT ScDetectiveFunc::InsertErrorLevel( USHORT nCol, USHORT nRow, ScDetectiveData& rData, +/*N*/ USHORT nLevel ) +/*N*/ { +/*N*/ ScBaseCell* pCell; +/*N*/ pDoc->GetCell( nCol, nRow, nTab, pCell ); +/*N*/ if (!pCell) +/*N*/ return DET_INS_EMPTY; +/*N*/ if (pCell->GetCellType() != CELLTYPE_FORMULA) +/*N*/ return DET_INS_EMPTY; +/*N*/ +/*N*/ ScFormulaCell* pFCell = (ScFormulaCell*)pCell; +/*N*/ if (pFCell->IsRunning()) +/*N*/ return DET_INS_CIRCULAR; +/*N*/ +/*N*/ if (pFCell->GetDirty()) +/*N*/ pFCell->Interpret(); // nach SetRunning geht's nicht mehr! +/*N*/ pFCell->SetRunning(TRUE); +/*N*/ +/*N*/ USHORT nResult = DET_INS_EMPTY; +/*N*/ +/*N*/ ScDetectiveRefIter aIter( (ScFormulaCell*) pCell ); +/*N*/ ScTripel aRefStart; +/*N*/ ScTripel aRefEnd; +/*N*/ ScTripel aErrorPos; +/*N*/ BOOL bHasError = FALSE; +/*N*/ while ( aIter.GetNextRef( aRefStart, aRefEnd ) ) +/*N*/ { +/*N*/ if (HasError( aRefStart, aRefEnd, aErrorPos )) +/*N*/ { +/*N*/ bHasError = TRUE; +/*N*/ if (DrawEntry( nCol, nRow, aErrorPos, aErrorPos, rData )) +/*N*/ nResult = DET_INS_INSERTED; +/*N*/ +/*N*/ // und weiterverfolgen +/*N*/ +/*N*/ if ( nLevel < rData.GetMaxLevel() ) // praktisch immer +/*N*/ { +/*N*/ if (InsertErrorLevel( aErrorPos.GetCol(), aErrorPos.GetRow(), +/*N*/ rData, nLevel+1 ) == DET_INS_INSERTED) +/*N*/ nResult = DET_INS_INSERTED; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ pFCell->SetRunning(FALSE); +/*N*/ +/*N*/ // Blaetter ? +/*N*/ if (!bHasError) +/*N*/ if (InsertPredLevel( nCol, nRow, rData, rData.GetMaxLevel() ) == DET_INS_INSERTED) +/*N*/ nResult = DET_INS_INSERTED; +/*N*/ +/*N*/ return nResult; +/*N*/ } + +//------------------------------------------------------------------------ + +/*N*/ USHORT ScDetectiveFunc::InsertSuccLevel( USHORT nCol1, USHORT nRow1, USHORT nCol2, USHORT nRow2, +/*N*/ ScDetectiveData& rData, USHORT nLevel ) +/*N*/ { +/*N*/ // ueber ganzes Dokument +/*N*/ +/*N*/ USHORT nResult = DET_INS_EMPTY; +/*N*/ // ScCellIterator aCellIter( pDoc, 0,0, nTab, MAXCOL,MAXROW, nTab ); +/*N*/ ScCellIterator aCellIter( pDoc, 0,0,0, MAXCOL,MAXROW,MAXTAB ); // alle Tabellen +/*N*/ ScBaseCell* pCell = aCellIter.GetFirst(); +/*N*/ while (pCell) +/*N*/ { +/*N*/ if (pCell->GetCellType() == CELLTYPE_FORMULA) +/*N*/ { +/*N*/ ScFormulaCell* pFCell = (ScFormulaCell*)pCell; +/*N*/ BOOL bRunning = pFCell->IsRunning(); +/*N*/ +/*N*/ if (pFCell->GetDirty()) +/*N*/ pFCell->Interpret(); // nach SetRunning geht's nicht mehr! +/*N*/ pFCell->SetRunning(TRUE); +/*N*/ +/*N*/ ScDetectiveRefIter aIter( (ScFormulaCell*) pCell ); +/*N*/ ScTripel aRefStart; +/*N*/ ScTripel aRefEnd; +/*N*/ while ( aIter.GetNextRef( aRefStart, aRefEnd ) ) +/*N*/ { +/*N*/ if (aRefStart.GetTab() <= nTab && aRefEnd.GetTab() >= nTab) +/*N*/ { +/*N*/ if (Intersect( nCol1,nRow1,nCol2,nRow2, +/*N*/ aRefStart.GetCol(),aRefStart.GetRow(), +/*N*/ aRefEnd.GetCol(),aRefEnd.GetRow() )) +/*N*/ { +/*N*/ BOOL bAlien = ( aCellIter.GetTab() != nTab ); +/*N*/ BOOL bDrawRet; +/*N*/ if (bAlien) +/*N*/ bDrawRet = DrawAlienEntry( aRefStart, aRefEnd, rData ); +/*N*/ else +/*N*/ bDrawRet = DrawEntry( aCellIter.GetCol(), aCellIter.GetRow(), +/*N*/ aRefStart, aRefEnd, rData ); +/*N*/ if (bDrawRet) +/*N*/ { +/*N*/ nResult = DET_INS_INSERTED; // neuer Pfeil eingetragen +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if (bRunning) +/*N*/ { +/*N*/ if (nResult == DET_INS_EMPTY) +/*N*/ nResult = DET_INS_CIRCULAR; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ // weiterverfolgen +/*N*/ +/*N*/ if ( nLevel < rData.GetMaxLevel() ) +/*N*/ { +/*N*/ USHORT nSubResult = InsertSuccLevel( +/*N*/ aCellIter.GetCol(), aCellIter.GetRow(), +/*N*/ aCellIter.GetCol(), aCellIter.GetRow(), +/*N*/ rData, nLevel+1 ); +/*N*/ switch (nSubResult) +/*N*/ { +/*N*/ case DET_INS_INSERTED: +/*N*/ nResult = DET_INS_INSERTED; +/*N*/ break; +/*N*/ case DET_INS_CONTINUE: +/*N*/ if (nResult != DET_INS_INSERTED) +/*N*/ nResult = DET_INS_CONTINUE; +/*N*/ break; +/*N*/ case DET_INS_CIRCULAR: +/*N*/ if (nResult == DET_INS_EMPTY) +/*N*/ nResult = DET_INS_CIRCULAR; +/*N*/ break; +/*N*/ // DET_INS_EMPTY: unveraendert lassen +/*N*/ } +/*N*/ } +/*N*/ else // nMaxLevel erreicht +/*N*/ if (nResult != DET_INS_INSERTED) +/*N*/ nResult = DET_INS_CONTINUE; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ pFCell->SetRunning(bRunning); +/*N*/ } +/*N*/ pCell = aCellIter.GetNext(); +/*N*/ } +/*N*/ +/*N*/ return nResult; +/*N*/ } + +/*N*/ USHORT ScDetectiveFunc::FindSuccLevel( USHORT nCol1, USHORT nRow1, USHORT nCol2, USHORT nRow2, +/*N*/ USHORT nLevel, USHORT nDeleteLevel ) +/*N*/ { +/*N*/ DBG_ASSERT( nLevel<1000, "Level" ); +/*N*/ +/*N*/ USHORT nResult = nLevel; +/*N*/ BOOL bDelete = ( nDeleteLevel && nLevel == nDeleteLevel-1 ); +/*N*/ +/*N*/ ScCellIterator aCellIter( pDoc, 0,0, nTab, MAXCOL,MAXROW, nTab ); +/*N*/ ScBaseCell* pCell = aCellIter.GetFirst(); +/*N*/ while (pCell) +/*N*/ { +/*N*/ if (pCell->GetCellType() == CELLTYPE_FORMULA) +/*N*/ { +/*N*/ ScFormulaCell* pFCell = (ScFormulaCell*)pCell; +/*N*/ BOOL bRunning = pFCell->IsRunning(); +/*N*/ +/*N*/ if (pFCell->GetDirty()) +/*N*/ pFCell->Interpret(); // nach SetRunning geht's nicht mehr! +/*N*/ pFCell->SetRunning(TRUE); +/*N*/ +/*N*/ ScDetectiveRefIter aIter( (ScFormulaCell*) pCell ); +/*N*/ ScTripel aRefStart; +/*N*/ ScTripel aRefEnd; +/*N*/ while ( aIter.GetNextRef( aRefStart, aRefEnd ) ) +/*N*/ { +/*N*/ if (aRefStart.GetTab() <= nTab && aRefEnd.GetTab() >= nTab) +/*N*/ { +/*N*/ if (Intersect( nCol1,nRow1,nCol2,nRow2, +/*N*/ aRefStart.GetCol(),aRefStart.GetRow(), +/*N*/ aRefEnd.GetCol(),aRefEnd.GetRow() )) +/*N*/ { +/*N*/ if ( bDelete ) // Pfeile, die hier anfangen +/*N*/ { +/*N*/ if (aRefStart != aRefEnd) +/*N*/ { +/*N*/ DeleteBox( aRefStart.GetCol(), aRefStart.GetRow(), +/*N*/ aRefEnd.GetCol(), aRefEnd.GetRow() ); +/*N*/ } +/*N*/ DeleteArrowsAt( aRefStart.GetCol(), aRefStart.GetRow(), FALSE ); +/*N*/ } +/*N*/ else if ( !bRunning && +/*N*/ HasArrow( aRefStart.GetCol(),aRefStart.GetRow(),aRefStart.GetTab(), +/*N*/ aCellIter.GetCol(),aCellIter.GetRow(),aCellIter.GetTab() ) ) +/*N*/ { +/*N*/ USHORT nTemp = FindSuccLevel( aCellIter.GetCol(), aCellIter.GetRow(), +/*N*/ aCellIter.GetCol(), aCellIter.GetRow(), +/*N*/ nLevel+1, nDeleteLevel ); +/*N*/ if (nTemp > nResult) +/*N*/ nResult = nTemp; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ pFCell->SetRunning(bRunning); +/*N*/ } +/*N*/ pCell = aCellIter.GetNext(); +/*N*/ } +/*N*/ +/*N*/ return nResult; +/*N*/ } + + +// +// -------------------------------------------------------------------------------- +// + +/*N*/ BOOL ScDetectiveFunc::ShowPred( USHORT nCol, USHORT nRow ) +/*N*/ { +/*N*/ ScDrawLayer* pModel = pDoc->GetDrawLayer(); +/*N*/ if (!pModel) +/*N*/ return FALSE; +/*N*/ +/*N*/ SdrPage* pPage = pModel->GetPage(nTab); +/*N*/ DBG_ASSERT(pPage,"Page ?"); +/*N*/ +/*N*/ ScDetectiveData aData( pModel ); +/*N*/ +/*N*/ USHORT nMaxLevel = 0; +/*N*/ USHORT nResult = DET_INS_CONTINUE; +/*N*/ while (nResult == DET_INS_CONTINUE && nMaxLevel < 1000) +/*N*/ { +/*N*/ aData.SetMaxLevel( nMaxLevel ); +/*N*/ nResult = InsertPredLevel( nCol, nRow, aData, 0 ); +/*N*/ ++nMaxLevel; +/*N*/ } +/*N*/ +/*N*/ return ( nResult == DET_INS_INSERTED ); +/*N*/ } + +/*N*/ BOOL ScDetectiveFunc::ShowSucc( USHORT nCol, USHORT nRow ) +/*N*/ { +/*N*/ ScDrawLayer* pModel = pDoc->GetDrawLayer(); +/*N*/ if (!pModel) +/*N*/ return FALSE; +/*N*/ +/*N*/ SdrPage* pPage = pModel->GetPage(nTab); +/*N*/ DBG_ASSERT(pPage,"Page ?"); +/*N*/ +/*N*/ ScDetectiveData aData( pModel ); +/*N*/ +/*N*/ USHORT nMaxLevel = 0; +/*N*/ USHORT nResult = DET_INS_CONTINUE; +/*N*/ while (nResult == DET_INS_CONTINUE && nMaxLevel < 1000) +/*N*/ { +/*N*/ aData.SetMaxLevel( nMaxLevel ); +/*N*/ nResult = InsertSuccLevel( nCol, nRow, nCol, nRow, aData, 0 ); +/*N*/ ++nMaxLevel; +/*N*/ } +/*N*/ +/*N*/ return ( nResult == DET_INS_INSERTED ); +/*N*/ } + +/*N*/ BOOL ScDetectiveFunc::ShowError( USHORT nCol, USHORT nRow ) +/*N*/ { +/*N*/ ScDrawLayer* pModel = pDoc->GetDrawLayer(); +/*N*/ if (!pModel) +/*N*/ return FALSE; +/*N*/ +/*N*/ SdrPage* pPage = pModel->GetPage(nTab); +/*N*/ DBG_ASSERT(pPage,"Page ?"); +/*N*/ +/*N*/ ScTripel aPos( nCol, nRow, nTab ); +/*N*/ ScTripel aErrPos; +/*N*/ if ( !HasError( aPos,aPos,aErrPos ) ) +/*N*/ return FALSE; +/*N*/ +/*N*/ ScDetectiveData aData( pModel ); +/*N*/ +/*N*/ aData.SetMaxLevel( 1000 ); +/*N*/ USHORT nResult = InsertErrorLevel( nCol, nRow, aData, 0 ); +/*N*/ +/*N*/ return ( nResult == DET_INS_INSERTED ); +/*N*/ } + +/*N*/ BOOL ScDetectiveFunc::DeleteSucc( USHORT nCol, USHORT nRow ) +/*N*/ { +/*N*/ ScDrawLayer* pModel = pDoc->GetDrawLayer(); +/*N*/ if (!pModel) +/*N*/ return FALSE; +/*N*/ +/*N*/ SdrPage* pPage = pModel->GetPage(nTab); +/*N*/ DBG_ASSERT(pPage,"Page ?"); +/*N*/ +/*N*/ USHORT nLevelCount = FindSuccLevel( nCol, nRow, nCol, nRow, 0, 0 ); +/*N*/ if ( nLevelCount ) +/*N*/ FindSuccLevel( nCol, nRow, nCol, nRow, 0, nLevelCount ); // loeschen +/*N*/ +/*N*/ return ( nLevelCount != 0 ); +/*N*/ } + +/*N*/ BOOL ScDetectiveFunc::DeletePred( USHORT nCol, USHORT nRow ) +/*N*/ { +/*N*/ ScDrawLayer* pModel = pDoc->GetDrawLayer(); +/*N*/ if (!pModel) +/*N*/ return FALSE; +/*N*/ +/*N*/ SdrPage* pPage = pModel->GetPage(nTab); +/*N*/ DBG_ASSERT(pPage,"Page ?"); +/*N*/ +/*N*/ USHORT nLevelCount = FindPredLevel( nCol, nRow, 0, 0 ); +/*N*/ if ( nLevelCount ) +/*N*/ FindPredLevel( nCol, nRow, 0, nLevelCount ); // loeschen +/*N*/ +/*N*/ return ( nLevelCount != 0 ); +/*N*/ } + +/*N*/ BOOL ScDetectiveFunc::DeleteAll( ScDetectiveDelete eWhat ) +/*N*/ { +/*N*/ ScDrawLayer* pModel = pDoc->GetDrawLayer(); +/*N*/ if (!pModel) +/*N*/ return FALSE; +/*N*/ +/*N*/ SdrPage* pPage = pModel->GetPage(nTab); +/*N*/ DBG_ASSERT(pPage,"Page ?"); +/*N*/ +/*N*/ pPage->RecalcObjOrdNums(); +/*N*/ +/*N*/ long nDelCount = 0; +/*N*/ ULONG nObjCount = pPage->GetObjCount(); +/*N*/ if (nObjCount) +/*N*/ { +/*N*/ SdrObject** ppObj = new SdrObject*[nObjCount]; +/*N*/ +/*N*/ SdrObjListIter aIter( *pPage, IM_FLAT ); +/*N*/ SdrObject* pObject = aIter.Next(); +/*N*/ while (pObject) +/*N*/ { +/*N*/ if ( pObject->GetLayer() == SC_LAYER_INTERN ) +/*N*/ { +/*N*/ BOOL bDoThis = TRUE; +/*N*/ if ( eWhat != SC_DET_ALL ) +/*N*/ { +/*N*/ BOOL bCircle = ( pObject->ISA(SdrCircObj) ); +/*N*/ BOOL bCaption = ( pObject->ISA(SdrCaptionObj) ); +/*N*/ if ( eWhat == SC_DET_DETECTIVE ) // Detektiv, aus Menue +/*N*/ bDoThis = !bCaption; // auch Kreise +/*N*/ else if ( eWhat == SC_DET_CIRCLES ) // Kreise, wenn neue erzeugt werden +/*N*/ bDoThis = bCircle; +/*N*/ else if ( eWhat == SC_DET_COMMENTS ) +/*N*/ bDoThis = bCaption; +/*N*/ else if ( eWhat == SC_DET_ARROWS ) // DetectiveRefresh +/*N*/ bDoThis = !bCaption && !bCircle; // don't include circles +/*N*/ else +/*N*/ DBG_ERROR("wat?"); +/*N*/ } +/*N*/ if ( bDoThis ) +/*N*/ ppObj[nDelCount++] = pObject; +/*N*/ } +/*N*/ +/*N*/ pObject = aIter.Next(); +/*N*/ } +/*N*/ +/*N*/ long i; +/*N*/ for (i=1; i<=nDelCount; i++) +/*N*/ pModel->AddCalcUndo( new SdrUndoRemoveObj( *ppObj[nDelCount-i] ) ); +/*N*/ +/*N*/ for (i=1; i<=nDelCount; i++) +/*N*/ pPage->RemoveObject( ppObj[nDelCount-i]->GetOrdNum() ); +/*N*/ +/*N*/ delete[] ppObj; +/*N*/ } +/*N*/ +/*N*/ return ( nDelCount != 0 ); +/*N*/ } + +/*N*/ BOOL ScDetectiveFunc::MarkInvalid(BOOL& rOverflow) +/*N*/ { +/*N*/ rOverflow = FALSE; +/*N*/ ScDrawLayer* pModel = pDoc->GetDrawLayer(); +/*N*/ if (!pModel) +/*N*/ return FALSE; +/*N*/ +/*N*/ BOOL bDeleted = DeleteAll( SC_DET_CIRCLES ); // nur die Kreise +/*N*/ +/*N*/ ScDetectiveData aData( pModel ); +/*N*/ long nInsCount = 0; +/*N*/ +/*N*/ // Stellen suchen, wo Gueltigkeit definiert ist +/*N*/ +/*N*/ ScDocAttrIterator aAttrIter( pDoc, nTab, 0,0,MAXCOL,MAXROW ); +/*N*/ USHORT nCol, nRow1, nRow2; +/*N*/ const ScPatternAttr* pPattern = aAttrIter.GetNext( nCol, nRow1, nRow2 ); +/*N*/ while ( pPattern && nInsCount < SC_DET_MAXCIRCLE ) +/*N*/ { +/*N*/ ULONG nIndex = ((const SfxUInt32Item&)pPattern->GetItem(ATTR_VALIDDATA)).GetValue(); +/*N*/ if (nIndex) +/*N*/ { +/*N*/ const ScValidationData* pData = pDoc->GetValidationEntry( nIndex ); +/*N*/ if ( pData ) +/*N*/ { +/*N*/ // Zellen in dem Bereich durchgehen +/*N*/ +/*N*/ BOOL bMarkEmpty = !pData->IsIgnoreBlank(); +/*N*/ USHORT nNextRow = nRow1; +/*N*/ USHORT nRow; +/*N*/ ScCellIterator aCellIter( pDoc, nCol,nRow1,nTab, nCol,nRow2,nTab ); +/*N*/ ScBaseCell* pCell = aCellIter.GetFirst(); +/*N*/ while ( pCell && nInsCount < SC_DET_MAXCIRCLE ) +/*N*/ { +/*N*/ USHORT nCellRow = aCellIter.GetRow(); +/*N*/ if ( bMarkEmpty ) +/*N*/ for ( nRow = nNextRow; nRow < nCellRow && nInsCount < SC_DET_MAXCIRCLE; nRow++ ) +/*N*/ { +/*N*/ DrawCircle( nCol, nRow, aData ); +/*N*/ ++nInsCount; +/*N*/ } +/*N*/ if ( !pData->IsDataValid( pCell, ScAddress( nCol, nCellRow, nTab ) ) ) +/*N*/ { +/*N*/ DrawCircle( nCol, nCellRow, aData ); +/*N*/ ++nInsCount; +/*N*/ } +/*N*/ nNextRow = nCellRow + 1; +/*N*/ pCell = aCellIter.GetNext(); +/*N*/ } +/*N*/ if ( bMarkEmpty ) +/*N*/ for ( nRow = nNextRow; nRow <= nRow2 && nInsCount < SC_DET_MAXCIRCLE; nRow++ ) +/*N*/ { +/*N*/ DrawCircle( nCol, nRow, aData ); +/*N*/ ++nInsCount; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ pPattern = aAttrIter.GetNext( nCol, nRow1, nRow2 ); +/*N*/ } +/*N*/ +/*N*/ if ( nInsCount >= SC_DET_MAXCIRCLE ) +/*N*/ rOverflow = TRUE; +/*N*/ +/*N*/ return ( bDeleted || nInsCount != 0 ); +/*N*/ } + +/*N*/ SdrObject* ScDetectiveFunc::ShowCommentUser( USHORT nCol, USHORT nRow, const String& rUserText, +/*N*/ const Rectangle& rVisible, BOOL bLeft, BOOL bForce, +/*N*/ SdrPage* pDestPage ) +/*N*/ { +/*N*/ ScDrawLayer* pModel = pDoc->GetDrawLayer(); +/*N*/ if (!pModel && !pDestPage) +/*N*/ return NULL; +/*N*/ +/*N*/ SdrObject* pObject = NULL; +/*N*/ ScPostIt aNote; +/*N*/ BOOL bFound = pDoc->GetNote( nCol, nRow, nTab, aNote ); +/*N*/ if ( bFound || bForce || rUserText.Len() ) +/*N*/ { + DBG_BF_ASSERT(0, "STRIP"); //STRIP001 SdrModel* pDestModel = pModel; +/*N*/ } +/*N*/ +/*N*/ return pObject; +/*N*/ } + +/*N*/ SdrObject* ScDetectiveFunc::ShowComment( USHORT nCol, USHORT nRow, BOOL bForce, SdrPage* pDestPage ) +/*N*/ { +/*N*/ return ShowCommentUser( nCol, nRow, String(), Rectangle(0,0,0,0), FALSE, bForce, pDestPage ); +/*N*/ } + +/*N*/ BOOL ScDetectiveFunc::HideComment( USHORT nCol, USHORT nRow ) +/*N*/ { +/*N*/ ScDrawLayer* pModel = pDoc->GetDrawLayer(); +/*N*/ if (!pModel) +/*N*/ return FALSE; +/*N*/ SdrPage* pPage = pModel->GetPage(nTab); +/*N*/ DBG_ASSERT(pPage,"Page ?"); +/*N*/ +/*N*/ pPage->RecalcObjOrdNums(); +/*N*/ BOOL bDone = FALSE; +/*N*/ +/*N*/ SdrObjListIter aIter( *pPage, IM_FLAT ); +/*N*/ SdrObject* pObject = aIter.Next(); +/*N*/ while (pObject && !bDone) +/*N*/ { +/*N*/ if ( pObject->GetLayer() == SC_LAYER_INTERN && pObject->ISA( SdrCaptionObj ) ) +/*N*/ { +/*N*/ ScDrawObjData* pData = ScDrawLayer::GetObjData( pObject ); +/*N*/ if ( pData && nCol == pData->aStt.nCol && nRow == pData->aStt.nRow ) +/*N*/ { +/*N*/ pModel->AddCalcUndo( new SdrUndoRemoveObj( *pObject ) ); +/*N*/ pPage->RemoveObject( pObject->GetOrdNum() ); +/*N*/ bDone = TRUE; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ pObject = aIter.Next(); +/*N*/ } +/*N*/ +/*N*/ return bDone; +/*N*/ } + +/*N*/ void ScDetectiveFunc::UpdateAllComments() +/*N*/ { +/*N*/ // for all caption objects, update attributes and SpecialTextBoxShadow flag +/*N*/ // (on all tables - nTab is ignored!) +/*N*/ +/*N*/ // no undo actions, this is refreshed after undo +/*N*/ +/*N*/ ScDrawLayer* pModel = pDoc->GetDrawLayer(); +/*N*/ if (!pModel) +/*N*/ return; +/*N*/ +/*N*/ ScCommentData aData( pDoc, pModel ); +/*N*/ +/*N*/ USHORT nTabCount = pDoc->GetTableCount(); +/*N*/ for (USHORT nObjTab=0; nObjTab<nTabCount; nObjTab++) +/*N*/ { +/*N*/ SdrPage* pPage = pModel->GetPage(nObjTab); +/*N*/ DBG_ASSERT(pPage,"Page ?"); +/*N*/ if (pPage) +/*N*/ { +/*N*/ SdrObjListIter aIter( *pPage, IM_FLAT ); +/*N*/ SdrObject* pObject = aIter.Next(); +/*N*/ while (pObject) +/*N*/ { +/*?*/ if ( pObject->GetLayer() == SC_LAYER_INTERN && pObject->ISA( SdrCaptionObj ) ) +/*?*/ { +/*?*/ SdrCaptionObj* pCaption = (SdrCaptionObj*)pObject; +/*?*/ +/*?*/ SfxItemSet& rAttrSet = aData.GetCaptionSet(); +/*?*/ +/*?*/ //-/ pCaption->SetAttributes( rAttrSet, FALSE ); +/*?*/ pCaption->SetItemSetAndBroadcast(rAttrSet); +/*?*/ +/*?*/ pCaption->SetSpecialTextBoxShadow(); +/*?*/ } +/*?*/ +/*?*/ pObject = aIter.Next(); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } + +/*N*/ void ScDetectiveFunc::UpdateAllArrowColors() // detective.sdc +/*N*/ { +/*N*/ // no undo actions necessary +/*N*/ +/*N*/ ScDrawLayer* pModel = pDoc->GetDrawLayer(); +/*N*/ if (!pModel) +/*N*/ return; +/*N*/ +/*N*/ USHORT nTabCount = pDoc->GetTableCount(); +/*N*/ for (USHORT nObjTab=0; nObjTab<nTabCount; nObjTab++) +/*N*/ { +/*N*/ SdrPage* pPage = pModel->GetPage(nObjTab); +/*N*/ DBG_ASSERT(pPage,"Page ?"); +/*N*/ if (pPage) +/*N*/ { +/*N*/ SdrObjListIter aIter( *pPage, IM_FLAT ); +/*N*/ SdrObject* pObject = aIter.Next(); +/*N*/ while (pObject) +/*N*/ { +/*N*/ if ( pObject->GetLayer() == SC_LAYER_INTERN ) +/*N*/ { +/*N*/ BOOL bArrow = FALSE; +/*N*/ BOOL bError = FALSE; +/*N*/ +/*N*/ ScAddress aPos; +/*N*/ ScRange aSource; +/*N*/ BOOL bDummy; +/*N*/ ScDetectiveObjType eType = GetDetectiveObjectType( pObject, aPos, aSource, bDummy ); +/*N*/ if ( eType == SC_DETOBJ_ARROW || eType == SC_DETOBJ_TOOTHERTAB ) +/*N*/ { +/*N*/ // source is valid, determine error flag from source range +/*N*/ +/*N*/ ScTripel aStart( aSource.aStart.Col(), aSource.aStart.Row(), aSource.aStart.Tab() ); +/*N*/ ScTripel aEnd( aSource.aEnd.Col(), aSource.aEnd.Row(), aSource.aEnd.Tab() ); +/*N*/ ScTripel aErrPos; +/*N*/ if ( HasError( aStart, aEnd, aErrPos ) ) +/*N*/ bError = TRUE; +/*N*/ else +/*N*/ bArrow = TRUE; +/*N*/ } +/*N*/ else if ( eType == SC_DETOBJ_FROMOTHERTAB ) +/*N*/ { +/*N*/ // source range is no longer known, take error flag from formula itself +/*N*/ // (this means, if the formula has an error, all references to other tables +/*N*/ // are marked red) +/*N*/ +/*N*/ ScTripel aFormulaPos( aPos.Col(), aPos.Row(), aPos.Tab() ); +/*N*/ ScTripel aErrPos; +/*N*/ if ( HasError( aFormulaPos, aFormulaPos, aErrPos ) ) +/*N*/ bError = TRUE; +/*N*/ else +/*N*/ bArrow = TRUE; +/*N*/ } +/*N*/ else if ( eType == SC_DETOBJ_CIRCLE ) +/*N*/ { +/*N*/ // circles (error marks) are always red +/*N*/ +/*N*/ bError = TRUE; +/*N*/ } +/*N*/ else if ( eType == SC_DETOBJ_NONE ) +/*N*/ { +/*N*/ // frame for area reference has no ObjType, always gets arrow color +/*N*/ +/*N*/ if ( pObject->ISA( SdrRectObj ) && !pObject->ISA( SdrCaptionObj ) ) +/*N*/ { +/*N*/ bArrow = TRUE; +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ if ( bArrow || bError ) +/*N*/ { +/*N*/ ColorData nColorData = ( bError ? GetErrorColor() : GetArrowColor() ); +/*N*/ pObject->SetItem( XLineColorItem( String(), Color( nColorData ) ) ); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ pObject = aIter.Next(); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } + +/*N*/ BOOL ScDetectiveFunc::FindFrameForObject( SdrObject* pObject, ScRange& rRange ) // detective.sdc +/*N*/ { +/*N*/ // find the rectangle for an arrow (always the object directly before the arrow) +/*N*/ // rRange must be initialized to the source cell of the arrow (start of area) +/*N*/ +/*N*/ ScDrawLayer* pModel = pDoc->GetDrawLayer(); +/*N*/ if (!pModel) return FALSE; +/*N*/ +/*N*/ SdrPage* pPage = pModel->GetPage(nTab); +/*N*/ DBG_ASSERT(pPage,"Page ?"); +/*N*/ if (!pPage) return FALSE; +/*N*/ +/*N*/ ULONG nPos = pPage->GetContainer().GetPos( pObject ); +/*N*/ if ( nPos != CONTAINER_ENTRY_NOTFOUND && nPos > 0 ) +/*N*/ { +/*N*/ SdrObject* pPrevObj = pPage->GetObj( nPos - 1 ); +/*N*/ if ( pPrevObj && pPrevObj->GetLayer() == SC_LAYER_INTERN && pPrevObj->ISA(SdrRectObj) ) +/*N*/ { +/*N*/ ScDrawObjData* pPrevData = ScDrawLayer::GetObjData( pPrevObj ); +/*N*/ if ( pPrevData && pPrevData->bValidStart && pPrevData->bValidEnd ) +/*N*/ { +/*N*/ if ( pPrevData->aStt.nCol == rRange.aStart.Col() && +/*N*/ pPrevData->aStt.nRow == rRange.aStart.Row() && +/*N*/ pPrevData->aStt.nTab == rRange.aStart.Tab() ) +/*N*/ { +/*N*/ rRange.aEnd.Set( pPrevData->aEnd.nCol, +/*N*/ pPrevData->aEnd.nRow, +/*N*/ pPrevData->aEnd.nTab ); +/*N*/ return TRUE; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ return FALSE; +/*N*/ } + +/*N*/ ScDetectiveObjType ScDetectiveFunc::GetDetectiveObjectType( SdrObject* pObject, +/*N*/ ScAddress& rPosition, ScRange& rSource, BOOL& rRedLine ) +/*N*/ { +/*N*/ rRedLine = FALSE; // detective.sdc +/*N*/ ScDetectiveObjType eType = SC_DETOBJ_NONE; +/*N*/ +/*N*/ if ( pObject && pObject->GetLayer() == SC_LAYER_INTERN ) +/*N*/ { +/*N*/ ScDrawObjData* pData = ScDrawLayer::GetObjData( pObject ); +/*N*/ if ( pObject->IsPolyObj() && pObject->GetPointCount() == 2 ) +/*N*/ { +/*N*/ // line object -> arrow +/*N*/ +/*N*/ if ( pData->bValidStart ) +/*N*/ eType = ( pData->bValidEnd ) ? SC_DETOBJ_ARROW : SC_DETOBJ_TOOTHERTAB; +/*N*/ else if ( pData->bValidEnd ) +/*N*/ eType = SC_DETOBJ_FROMOTHERTAB; +/*N*/ +/*N*/ if ( pData->bValidStart ) +/*N*/ rSource = ScRange( pData->aStt.nCol, pData->aStt.nRow, pData->aStt.nTab ); +/*N*/ if ( pData->bValidEnd ) +/*N*/ rPosition = ScAddress( pData->aEnd.nCol, pData->aEnd.nRow, pData->aEnd.nTab ); +/*N*/ +/*N*/ if ( pData->bValidStart && lcl_HasThickLine( *pObject ) ) +/*N*/ { +/*N*/ // thick line -> look for frame before this object +/*N*/ +/*N*/ FindFrameForObject( pObject, rSource ); // modifies rSource +/*N*/ } +/*N*/ +/*N*/ ColorData nObjColor = ((const XLineColorItem&)pObject->GetItem(XATTR_LINECOLOR)).GetValue().GetColor(); +/*N*/ if ( nObjColor == GetErrorColor() && nObjColor != GetArrowColor() ) +/*N*/ rRedLine = TRUE; +/*N*/ } +/*N*/ else if ( pObject->ISA(SdrCircObj) ) +/*N*/ { +/*N*/ if ( pData->bValidStart ) +/*N*/ { +/*N*/ // cell position is returned in rPosition +/*N*/ +/*N*/ rPosition = ScAddress( pData->aStt.nCol, pData->aStt.nRow, pData->aStt.nTab ); +/*N*/ eType = SC_DETOBJ_CIRCLE; +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ return eType; +/*N*/ } + +/*N*/ void ScDetectiveFunc::InsertObject( ScDetectiveObjType eType, +/*N*/ const ScAddress& rPosition, const ScRange& rSource, +/*N*/ BOOL bRedLine ) +/*N*/ { +DBG_BF_ASSERT(0, "STRIP"); //STRIP001 ScDrawLayer* pModel = pDoc->GetDrawLayer(); +/*N*/ } + +// static +/*N*/ ColorData ScDetectiveFunc::GetArrowColor() +/*N*/ { +/*N*/ if (!bColorsInitialized) +/*N*/ InitializeColors(); +/*N*/ return nArrowColor; +/*N*/ } + +// static +/*N*/ ColorData ScDetectiveFunc::GetErrorColor() +/*N*/ { +/*N*/ if (!bColorsInitialized) +/*N*/ InitializeColors(); +/*N*/ return nErrorColor; +/*N*/ } + +// static +/*N*/ ColorData ScDetectiveFunc::GetCommentColor() +/*N*/ { +/*N*/ if (!bColorsInitialized) +/*N*/ InitializeColors(); +/*N*/ return nCommentColor; +/*N*/ } + +// static +/*N*/ void ScDetectiveFunc::InitializeColors() +/*N*/ { +/*N*/ // may be called several times to update colors from configuration +/*N*/ +/*N*/ const ColorConfig& rColorCfg = SC_MOD()->GetColorConfig(); +/*N*/ nArrowColor = rColorCfg.GetColorValue(CALCDETECTIVE).nColor; +/*N*/ nErrorColor = rColorCfg.GetColorValue(CALCDETECTIVEERROR).nColor; +/*N*/ nCommentColor = rColorCfg.GetColorValue(CALCNOTESBACKGROUND).nColor; +/*N*/ +/*N*/ bColorsInitialized = TRUE; +/*N*/ } + +// static + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |