LCOV - code coverage report
Current view: top level - sc/source/core/data - validat.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 57 395 14.4 %
Date: 2012-08-25 Functions: 15 36 41.7 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 50 839 6.0 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*************************************************************************
       3                 :            :  *
       4                 :            :  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       5                 :            :  *
       6                 :            :  * Copyright 2000, 2010 Oracle and/or its affiliates.
       7                 :            :  *
       8                 :            :  * OpenOffice.org - a multi-platform office productivity suite
       9                 :            :  *
      10                 :            :  * This file is part of OpenOffice.org.
      11                 :            :  *
      12                 :            :  * OpenOffice.org is free software: you can redistribute it and/or modify
      13                 :            :  * it under the terms of the GNU Lesser General Public License version 3
      14                 :            :  * only, as published by the Free Software Foundation.
      15                 :            :  *
      16                 :            :  * OpenOffice.org is distributed in the hope that it will be useful,
      17                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :  * GNU Lesser General Public License version 3 for more details
      20                 :            :  * (a copy is included in the LICENSE file that accompanied this code).
      21                 :            :  *
      22                 :            :  * You should have received a copy of the GNU Lesser General Public License
      23                 :            :  * version 3 along with OpenOffice.org.  If not, see
      24                 :            :  * <http://www.openoffice.org/license.html>
      25                 :            :  * for a copy of the LGPLv3 License.
      26                 :            :  *
      27                 :            :  ************************************************************************/
      28                 :            : 
      29                 :            : #include "scitems.hxx"
      30                 :            : #include <sfx2/app.hxx>
      31                 :            : #include <sfx2/docfile.hxx>
      32                 :            : #include <sfx2/objsh.hxx>
      33                 :            : #include <basic/sbmeth.hxx>
      34                 :            : #include <basic/sbmod.hxx>
      35                 :            : #include <basic/sbstar.hxx>
      36                 :            : #include <basic/basmgr.hxx>
      37                 :            : 
      38                 :            : #include <basic/sbx.hxx>
      39                 :            : #include <svl/zforlist.hxx>
      40                 :            : #include <vcl/msgbox.hxx>
      41                 :            : #include <rtl/math.hxx>
      42                 :            : 
      43                 :            : #include "validat.hxx"
      44                 :            : #include "document.hxx"
      45                 :            : #include "cell.hxx"
      46                 :            : #include "patattr.hxx"
      47                 :            : #include "rechead.hxx"
      48                 :            : #include "globstr.hrc"
      49                 :            : #include "rangenam.hxx"
      50                 :            : #include "dbdata.hxx"
      51                 :            : #include "typedstrdata.hxx"
      52                 :            : 
      53                 :            : #include <math.h>
      54                 :            : #include <memory>
      55                 :            : 
      56                 :            : using namespace formula;
      57                 :            : 
      58                 :            : //
      59                 :            : //  Eintrag fuer Gueltigkeit (es gibt nur eine Bedingung)
      60                 :            : //
      61                 :            : 
      62                 :        111 : ScValidationData::ScValidationData( ScValidationMode eMode, ScConditionMode eOper,
      63                 :            :                             const String& rExpr1, const String& rExpr2,
      64                 :            :                             ScDocument* pDocument, const ScAddress& rPos,
      65                 :            :                             const String& rExprNmsp1, const String& rExprNmsp2,
      66                 :            :                             FormulaGrammar::Grammar eGrammar1, FormulaGrammar::Grammar eGrammar2 ) :
      67                 :            :     ScConditionEntry( eOper, rExpr1, rExpr2, pDocument, rPos, rExprNmsp1, rExprNmsp2, eGrammar1, eGrammar2 ),
      68                 :            :     nKey( 0 ),
      69                 :            :     eDataMode( eMode ),
      70                 :            :     eErrorStyle( SC_VALERR_STOP ),
      71 [ +  - ][ +  - ]:        111 :     mnListType( ValidListType::UNSORTED )
         [ +  - ][ +  - ]
      72                 :            : {
      73                 :        111 :     bShowInput = bShowError = false;
      74                 :        111 : }
      75                 :            : 
      76                 :          3 : ScValidationData::ScValidationData( ScValidationMode eMode, ScConditionMode eOper,
      77                 :            :                             const ScTokenArray* pArr1, const ScTokenArray* pArr2,
      78                 :            :                             ScDocument* pDocument, const ScAddress& rPos ) :
      79                 :            :     ScConditionEntry( eOper, pArr1, pArr2, pDocument, rPos ),
      80                 :            :     nKey( 0 ),
      81                 :            :     eDataMode( eMode ),
      82                 :            :     eErrorStyle( SC_VALERR_STOP ),
      83 [ +  - ][ +  - ]:          3 :     mnListType( ValidListType::UNSORTED )
         [ +  - ][ +  - ]
      84                 :            : {
      85                 :          3 :     bShowInput = bShowError = false;
      86                 :          3 : }
      87                 :            : 
      88                 :          3 : ScValidationData::ScValidationData( const ScValidationData& r ) :
      89                 :            :     ScConditionEntry( r ),
      90                 :            :     nKey( r.nKey ),
      91                 :            :     eDataMode( r.eDataMode ),
      92                 :            :     bShowInput( r.bShowInput ),
      93                 :            :     bShowError( r.bShowError ),
      94                 :            :     eErrorStyle( r.eErrorStyle ),
      95                 :            :     mnListType( r.mnListType ),
      96                 :            :     aInputTitle( r.aInputTitle ),
      97                 :            :     aInputMessage( r.aInputMessage ),
      98                 :            :     aErrorTitle( r.aErrorTitle ),
      99 [ +  - ][ +  - ]:          3 :     aErrorMessage( r.aErrorMessage )
         [ +  - ][ +  - ]
     100                 :            : {
     101                 :            :     //  Formeln per RefCount kopiert
     102                 :          3 : }
     103                 :            : 
     104                 :         12 : ScValidationData::ScValidationData( ScDocument* pDocument, const ScValidationData& r ) :
     105                 :            :     ScConditionEntry( pDocument, r ),
     106                 :            :     nKey( r.nKey ),
     107                 :            :     eDataMode( r.eDataMode ),
     108                 :            :     bShowInput( r.bShowInput ),
     109                 :            :     bShowError( r.bShowError ),
     110                 :            :     eErrorStyle( r.eErrorStyle ),
     111                 :            :     mnListType( r.mnListType ),
     112                 :            :     aInputTitle( r.aInputTitle ),
     113                 :            :     aInputMessage( r.aInputMessage ),
     114                 :            :     aErrorTitle( r.aErrorTitle ),
     115 [ +  - ][ +  - ]:         12 :     aErrorMessage( r.aErrorMessage )
         [ +  - ][ +  - ]
     116                 :            : {
     117                 :            :     //  Formeln wirklich kopiert
     118                 :         12 : }
     119                 :            : 
     120 [ +  - ][ +  - ]:        129 : ScValidationData::~ScValidationData()
         [ +  - ][ +  - ]
     121                 :            : {
     122         [ -  + ]:        150 : }
     123                 :            : 
     124                 :         54 : sal_Bool ScValidationData::IsEmpty() const
     125                 :            : {
     126         [ +  - ]:         54 :     String aEmpty;
     127         [ +  - ]:         54 :     ScValidationData aDefault( SC_VALID_ANY, SC_COND_EQUAL, aEmpty, aEmpty, GetDocument(), ScAddress() );
     128 [ +  - ][ +  - ]:         54 :     return EqualEntries( aDefault );
                 [ +  - ]
     129                 :            : }
     130                 :            : 
     131                 :        132 : sal_Bool ScValidationData::EqualEntries( const ScValidationData& r ) const
     132                 :            : {
     133                 :            :         //  gleiche Parameter eingestellt (ohne Key)
     134                 :            : 
     135                 :        132 :     return ScConditionEntry::operator==(r) &&
     136                 :            :             eDataMode       == r.eDataMode &&
     137                 :            :             bShowInput      == r.bShowInput &&
     138                 :            :             bShowError      == r.bShowError &&
     139                 :            :             eErrorStyle     == r.eErrorStyle &&
     140                 :            :             mnListType      == r.mnListType &&
     141                 :         48 :             aInputTitle     == r.aInputTitle &&
     142                 :         48 :             aInputMessage   == r.aInputMessage &&
     143                 :         48 :             aErrorTitle     == r.aErrorTitle &&
     144 [ +  - ][ +  - ]:        276 :             aErrorMessage   == r.aErrorMessage;
         [ +  - ][ +  - ]
           [ +  -  +  -  
             +  -  +  - ]
         [ +  - ][ +  + ]
     145                 :            : }
     146                 :            : 
     147                 :         57 : void ScValidationData::ResetInput()
     148                 :            : {
     149                 :         57 :     bShowInput = false;
     150                 :         57 : }
     151                 :            : 
     152                 :          9 : void ScValidationData::ResetError()
     153                 :            : {
     154                 :          9 :     bShowError = false;
     155                 :          9 : }
     156                 :            : 
     157                 :         51 : void ScValidationData::SetInput( const String& rTitle, const String& rMsg )
     158                 :            : {
     159                 :         51 :     bShowInput = sal_True;
     160                 :         51 :     aInputTitle = rTitle;
     161                 :         51 :     aInputMessage = rMsg;
     162                 :         51 : }
     163                 :            : 
     164                 :         60 : void ScValidationData::SetError( const String& rTitle, const String& rMsg,
     165                 :            :                                     ScValidErrorStyle eStyle )
     166                 :            : {
     167                 :         60 :     bShowError = sal_True;
     168                 :         60 :     eErrorStyle = eStyle;
     169                 :         60 :     aErrorTitle = rTitle;
     170                 :         60 :     aErrorMessage = rMsg;
     171                 :         60 : }
     172                 :            : 
     173                 :         45 : sal_Bool ScValidationData::GetErrMsg( String& rTitle, String& rMsg,
     174                 :            :                                     ScValidErrorStyle& rStyle ) const
     175                 :            : {
     176                 :         45 :     rTitle = aErrorTitle;
     177                 :         45 :     rMsg   = aErrorMessage;
     178                 :         45 :     rStyle = eErrorStyle;
     179                 :         45 :     return bShowError;
     180                 :            : }
     181                 :            : 
     182                 :          0 : sal_Bool ScValidationData::DoScript( const ScAddress& rPos, const String& rInput,
     183                 :            :                                 ScFormulaCell* pCell, Window* pParent ) const
     184                 :            : {
     185                 :          0 :     ScDocument* pDocument = GetDocument();
     186                 :          0 :     SfxObjectShell* pDocSh = pDocument->GetDocumentShell();
     187 [ #  # ][ #  # ]:          0 :     if ( !pDocSh || !pDocument->CheckMacroWarn() )
         [ #  # ][ #  # ]
     188                 :          0 :         return false;
     189                 :            : 
     190                 :          0 :     sal_Bool bScriptReturnedFalse = false;  // Standard: kein Abbruch
     191                 :            : 
     192                 :            :     // Set up parameters
     193         [ #  # ]:          0 :     ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > aParams(2);
     194                 :            : 
     195                 :            :     //  1) eingegebener / berechneter Wert
     196         [ #  # ]:          0 :     String aValStr = rInput;
     197                 :            :     double nValue;
     198                 :          0 :     sal_Bool bIsValue = false;
     199         [ #  # ]:          0 :     if ( pCell )                // wenn Zelle gesetzt, aus Interpret gerufen
     200                 :            :     {
     201         [ #  # ]:          0 :         bIsValue = pCell->IsValue();
     202         [ #  # ]:          0 :         if ( bIsValue )
     203         [ #  # ]:          0 :             nValue  = pCell->GetValue();
     204                 :            :         else
     205 [ #  # ][ #  # ]:          0 :             aValStr = pCell->GetString();
     206                 :            :     }
     207         [ #  # ]:          0 :     if ( bIsValue )
     208 [ #  # ][ #  # ]:          0 :         aParams[0] = ::com::sun::star::uno::makeAny( nValue );
     209                 :            :     else
     210 [ #  # ][ #  # ]:          0 :         aParams[0] = ::com::sun::star::uno::makeAny( ::rtl::OUString( aValStr ) );
                 [ #  # ]
     211                 :            : 
     212                 :            :     //  2) Position der Zelle
     213         [ #  # ]:          0 :     String aPosStr;
     214 [ #  # ][ #  # ]:          0 :     rPos.Format( aPosStr, SCA_VALID | SCA_TAB_3D, pDocument, pDocument->GetAddressConvention() );
     215 [ #  # ][ #  # ]:          0 :     aParams[1] = ::com::sun::star::uno::makeAny( ::rtl::OUString( aPosStr ) );
                 [ #  # ]
     216                 :            : 
     217                 :            :     //  use link-update flag to prevent closing the document
     218                 :            :     //  while the macro is running
     219         [ #  # ]:          0 :     sal_Bool bWasInLinkUpdate = pDocument->IsInLinkUpdate();
     220         [ #  # ]:          0 :     if ( !bWasInLinkUpdate )
     221         [ #  # ]:          0 :         pDocument->SetInLinkUpdate( sal_True );
     222                 :            : 
     223         [ #  # ]:          0 :     if ( pCell )
     224         [ #  # ]:          0 :         pDocument->LockTable( rPos.Tab() );
     225                 :            : 
     226                 :          0 :     ::com::sun::star::uno::Any aRet;
     227         [ #  # ]:          0 :     ::com::sun::star::uno::Sequence< sal_Int16 > aOutArgsIndex;
     228         [ #  # ]:          0 :     ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > aOutArgs;
     229                 :            : 
     230                 :            :     ErrCode eRet = pDocSh->CallXScript(
     231         [ #  # ]:          0 :         aErrorTitle, aParams, aRet, aOutArgsIndex, aOutArgs );
     232                 :            : 
     233         [ #  # ]:          0 :     if ( pCell )
     234         [ #  # ]:          0 :         pDocument->UnlockTable( rPos.Tab() );
     235                 :            : 
     236         [ #  # ]:          0 :     if ( !bWasInLinkUpdate )
     237         [ #  # ]:          0 :         pDocument->SetInLinkUpdate( false );
     238                 :            : 
     239                 :            :     // Check the return value from the script
     240                 :            :     // The contents of the cell get reset if the script returns false
     241                 :          0 :     sal_Bool bTmp = false;
     242   [ #  #  #  #  :          0 :     if ( eRet == ERRCODE_NONE &&
           #  # ][ #  # ]
                 [ #  # ]
     243         [ #  # ]:          0 :              aRet.getValueType() == getCppuBooleanType() &&
     244                 :          0 :              sal_True == ( aRet >>= bTmp ) &&
     245                 :            :              bTmp == false )
     246                 :            :     {
     247                 :          0 :         bScriptReturnedFalse = sal_True;
     248                 :            :     }
     249                 :            : 
     250 [ #  # ][ #  # ]:          0 :     if ( eRet == ERRCODE_BASIC_METHOD_NOT_FOUND && !pCell )
     251                 :            :     // Makro nicht gefunden (nur bei Eingabe)
     252                 :            :     {
     253                 :            :         //! andere Fehlermeldung, wenn gefunden, aber nicht bAllowed ??
     254                 :            : 
     255                 :            :         ErrorBox aBox( pParent, WinBits(WB_OK),
     256 [ #  # ][ #  # ]:          0 :                         ScGlobal::GetRscString( STR_VALID_MACRONOTFOUND ) );
     257 [ #  # ][ #  # ]:          0 :         aBox.Execute();
     258                 :            :     }
     259                 :            : 
     260 [ #  # ][ #  # ]:          0 :     return bScriptReturnedFalse;
         [ #  # ][ #  # ]
                 [ #  # ]
     261                 :            : }
     262                 :            : 
     263                 :            :     // sal_True -> Abbruch
     264                 :            : 
     265                 :          0 : sal_Bool ScValidationData::DoMacro( const ScAddress& rPos, const String& rInput,
     266                 :            :                                 ScFormulaCell* pCell, Window* pParent ) const
     267                 :            : {
     268         [ #  # ]:          0 :     if ( SfxApplication::IsXScriptURL( aErrorTitle ) )
     269                 :            :     {
     270                 :          0 :         return DoScript( rPos, rInput, pCell, pParent );
     271                 :            :     }
     272                 :            : 
     273                 :          0 :     ScDocument* pDocument = GetDocument();
     274                 :          0 :     SfxObjectShell* pDocSh = pDocument->GetDocumentShell();
     275 [ #  # ][ #  # ]:          0 :     if ( !pDocSh || !pDocument->CheckMacroWarn() )
                 [ #  # ]
     276                 :          0 :         return false;
     277                 :            : 
     278                 :          0 :     sal_Bool bDone = false;
     279                 :          0 :     sal_Bool bRet = false;                      // Standard: kein Abbruch
     280                 :            : 
     281                 :            :     //  Wenn das Dok waehrend eines Basic-Calls geladen wurde,
     282                 :            :     //  ist das Sbx-Objekt evtl. nicht angelegt (?)
     283                 :            : //  pDocSh->GetSbxObject();
     284                 :            : 
     285                 :            : #ifndef DISABLE_SCRIPTING
     286                 :            :     //  keine Sicherheitsabfrage mehr vorneweg (nur CheckMacroWarn), das passiert im CallBasic
     287                 :            : 
     288                 :            :     //  Funktion ueber den einfachen Namen suchen,
     289                 :            :     //  dann aBasicStr, aMacroStr fuer SfxObjectShell::CallBasic zusammenbauen
     290                 :            : 
     291                 :          0 :     StarBASIC* pRoot = pDocSh->GetBasic();
     292         [ #  # ]:          0 :     SbxVariable* pVar = pRoot->Find( aErrorTitle, SbxCLASS_METHOD );
     293 [ #  # ][ #  # ]:          0 :     if ( pVar && pVar->ISA(SbMethod) )
                 [ #  # ]
     294                 :            :     {
     295                 :          0 :         SbMethod* pMethod = (SbMethod*)pVar;
     296                 :          0 :         SbModule* pModule = pMethod->GetModule();
     297         [ #  # ]:          0 :         SbxObject* pObject = pModule->GetParent();
     298 [ #  # ][ #  # ]:          0 :         String aMacroStr = pObject->GetName();
     299         [ #  # ]:          0 :         aMacroStr += '.';
     300 [ #  # ][ #  # ]:          0 :         aMacroStr += pModule->GetName();
     301         [ #  # ]:          0 :         aMacroStr += '.';
     302 [ #  # ][ #  # ]:          0 :         aMacroStr += pMethod->GetName();
     303         [ #  # ]:          0 :         String aBasicStr;
     304                 :            : 
     305                 :            :         //  the distinction between document- and app-basic has to be done
     306                 :            :         //  by checking the parent (as in ScInterpreter::ScMacro), not by looping
     307                 :            :         //  over all open documents, because this may be called from within loading,
     308                 :            :         //  when SfxObjectShell::GetFirst/GetNext won't find the document.
     309                 :            : 
     310 [ #  # ][ #  # ]:          0 :         if ( pObject->GetParent() )
     311 [ #  # ][ #  # ]:          0 :             aBasicStr = pObject->GetParent()->GetName();    // Dokumentenbasic
                 [ #  # ]
     312                 :            :         else
     313 [ #  # ][ #  # ]:          0 :             aBasicStr = SFX_APP()->GetName();               // Applikationsbasic
                 [ #  # ]
     314                 :            : 
     315                 :            :         //  Parameter fuer Makro
     316 [ #  # ][ #  # ]:          0 :         SbxArrayRef refPar = new SbxArray;
     317                 :            : 
     318                 :            :         //  1) eingegebener / berechneter Wert
     319         [ #  # ]:          0 :         String aValStr = rInput;
     320                 :          0 :         double nValue = 0.0;
     321                 :          0 :         sal_Bool bIsValue = false;
     322         [ #  # ]:          0 :         if ( pCell )                // wenn Zelle gesetzt, aus Interpret gerufen
     323                 :            :         {
     324         [ #  # ]:          0 :             bIsValue = pCell->IsValue();
     325         [ #  # ]:          0 :             if ( bIsValue )
     326         [ #  # ]:          0 :                 nValue  = pCell->GetValue();
     327                 :            :             else
     328 [ #  # ][ #  # ]:          0 :                 aValStr = pCell->GetString();
     329                 :            :         }
     330         [ #  # ]:          0 :         if ( bIsValue )
     331 [ #  # ][ #  # ]:          0 :             refPar->Get(1)->PutDouble( nValue );
     332                 :            :         else
     333 [ #  # ][ #  # ]:          0 :             refPar->Get(1)->PutString( aValStr );
                 [ #  # ]
     334                 :            : 
     335                 :            :         //  2) Position der Zelle
     336         [ #  # ]:          0 :         String aPosStr;
     337 [ #  # ][ #  # ]:          0 :         rPos.Format( aPosStr, SCA_VALID | SCA_TAB_3D, pDocument, pDocument->GetAddressConvention() );
     338 [ #  # ][ #  # ]:          0 :         refPar->Get(2)->PutString( aPosStr );
                 [ #  # ]
     339                 :            : 
     340                 :            :         //  use link-update flag to prevent closing the document
     341                 :            :         //  while the macro is running
     342         [ #  # ]:          0 :         sal_Bool bWasInLinkUpdate = pDocument->IsInLinkUpdate();
     343         [ #  # ]:          0 :         if ( !bWasInLinkUpdate )
     344         [ #  # ]:          0 :             pDocument->SetInLinkUpdate( sal_True );
     345                 :            : 
     346         [ #  # ]:          0 :         if ( pCell )
     347         [ #  # ]:          0 :             pDocument->LockTable( rPos.Tab() );
     348 [ #  # ][ #  # ]:          0 :         SbxVariableRef refRes = new SbxVariable;
     349         [ #  # ]:          0 :         ErrCode eRet = pDocSh->CallBasic( aMacroStr, aBasicStr, refPar, refRes );
     350         [ #  # ]:          0 :         if ( pCell )
     351         [ #  # ]:          0 :             pDocument->UnlockTable( rPos.Tab() );
     352                 :            : 
     353         [ #  # ]:          0 :         if ( !bWasInLinkUpdate )
     354         [ #  # ]:          0 :             pDocument->SetInLinkUpdate( false );
     355                 :            : 
     356                 :            :         //  Eingabe abbrechen, wenn Basic-Makro sal_False zurueckgibt
     357 [ #  # ][ #  # ]:          0 :         if ( eRet == ERRCODE_NONE && refRes->GetType() == SbxBOOL && refRes->GetBool() == false )
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     358                 :          0 :             bRet = sal_True;
     359 [ #  # ][ #  # ]:          0 :         bDone = sal_True;
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     360                 :            :     }
     361                 :            : #endif
     362 [ #  # ][ #  # ]:          0 :     if ( !bDone && !pCell )         // Makro nicht gefunden (nur bei Eingabe)
     363                 :            :     {
     364                 :            :         //! andere Fehlermeldung, wenn gefunden, aber nicht bAllowed ??
     365                 :            : 
     366                 :            :         ErrorBox aBox( pParent, WinBits(WB_OK),
     367 [ #  # ][ #  # ]:          0 :                         ScGlobal::GetRscString( STR_VALID_MACRONOTFOUND ) );
     368 [ #  # ][ #  # ]:          0 :         aBox.Execute();
     369                 :            :     }
     370                 :            : 
     371                 :          0 :     return bRet;
     372                 :            : }
     373                 :            : 
     374                 :          0 : void ScValidationData::DoCalcError( ScFormulaCell* pCell ) const
     375                 :            : {
     376         [ #  # ]:          0 :     if ( eErrorStyle == SC_VALERR_MACRO )
     377                 :          0 :         DoMacro( pCell->aPos, EMPTY_STRING, pCell, NULL );
     378                 :          0 : }
     379                 :            : 
     380                 :            :     // sal_True -> Abbruch
     381                 :            : 
     382                 :          0 : sal_Bool ScValidationData::DoError( Window* pParent, const String& rInput,
     383                 :            :                                 const ScAddress& rPos ) const
     384                 :            : {
     385         [ #  # ]:          0 :     if ( eErrorStyle == SC_VALERR_MACRO )
     386         [ #  # ]:          0 :         return DoMacro( rPos, rInput, NULL, pParent );
     387                 :            : 
     388                 :            :     //  Fehlermeldung ausgeben
     389                 :            : 
     390         [ #  # ]:          0 :     String aTitle = aErrorTitle;
     391         [ #  # ]:          0 :     if (!aTitle.Len())
     392 [ #  # ][ #  # ]:          0 :         aTitle = ScGlobal::GetRscString( STR_MSSG_DOSUBTOTALS_0 );  // application title
     393         [ #  # ]:          0 :     String aMessage = aErrorMessage;
     394         [ #  # ]:          0 :     if (!aMessage.Len())
     395 [ #  # ][ #  # ]:          0 :         aMessage = ScGlobal::GetRscString( STR_VALID_DEFERROR );
     396                 :            : 
     397                 :            :     //! ErrorBox / WarningBox / InfoBox ?
     398                 :            :     //! (bei InfoBox immer nur OK-Button)
     399                 :            : 
     400                 :          0 :     WinBits nStyle = 0;
     401   [ #  #  #  # ]:          0 :     switch (eErrorStyle)
     402                 :            :     {
     403                 :            :         case SC_VALERR_STOP:
     404                 :          0 :             nStyle = WB_OK | WB_DEF_OK;
     405                 :          0 :             break;
     406                 :            :         case SC_VALERR_WARNING:
     407                 :          0 :             nStyle = WB_OK_CANCEL | WB_DEF_CANCEL;
     408                 :          0 :             break;
     409                 :            :         case SC_VALERR_INFO:
     410                 :          0 :             nStyle = WB_OK_CANCEL | WB_DEF_OK;
     411                 :          0 :             break;
     412                 :            :         default:
     413                 :            :         {
     414                 :            :             // added to avoid warnings
     415                 :            :         }
     416                 :            :     }
     417                 :            : 
     418         [ #  # ]:          0 :     MessBox aBox( pParent, WinBits(nStyle), aTitle, aMessage );
     419         [ #  # ]:          0 :     sal_uInt16 nRet = aBox.Execute();
     420                 :            : 
     421 [ #  # ][ #  # ]:          0 :     return ( eErrorStyle == SC_VALERR_STOP || nRet == RET_CANCEL );
         [ #  # ][ #  # ]
                 [ #  # ]
     422                 :            : }
     423                 :            : 
     424                 :            : 
     425                 :          0 : sal_Bool ScValidationData::IsDataValid( const String& rTest, const ScPatternAttr& rPattern,
     426                 :            :                                     const ScAddress& rPos ) const
     427                 :            : {
     428         [ #  # ]:          0 :     if ( eDataMode == SC_VALID_ANY )
     429                 :          0 :         return sal_True;                        // alles erlaubt
     430                 :            : 
     431         [ #  # ]:          0 :     if ( rTest.GetChar(0) == '=' )
     432                 :          0 :         return false;                       // Formeln sind sonst immer ungueltig
     433                 :            : 
     434         [ #  # ]:          0 :     if ( !rTest.Len() )
     435                 :          0 :         return IsIgnoreBlank();             // leer: wie eingestellt
     436                 :            : 
     437         [ #  # ]:          0 :     SvNumberFormatter* pFormatter = GetDocument()->GetFormatTable();
     438                 :            : 
     439                 :            :     //  Test, was es denn ist - wie in ScColumn::SetString
     440                 :            : 
     441         [ #  # ]:          0 :     sal_uInt32 nFormat = rPattern.GetNumberFormat( pFormatter );
     442                 :            : 
     443                 :            :     double nVal;
     444         [ #  # ]:          0 :     sal_Bool bIsVal = pFormatter->IsNumberFormat( rTest, nFormat, nVal );
     445                 :            :     ScBaseCell* pCell;
     446         [ #  # ]:          0 :     if (bIsVal)
     447 [ #  # ][ #  # ]:          0 :         pCell = new ScValueCell( nVal );
     448                 :            :     else
     449 [ #  # ][ #  # ]:          0 :         pCell = new ScStringCell( rTest );
                 [ #  # ]
     450                 :            : 
     451         [ #  # ]:          0 :     sal_Bool bRet = IsDataValid( pCell, rPos );
     452                 :            : 
     453         [ #  # ]:          0 :     pCell->Delete();
     454                 :          0 :     return bRet;
     455                 :            : }
     456                 :            : 
     457                 :          0 : sal_Bool ScValidationData::IsDataValid( ScBaseCell* pCell, const ScAddress& rPos ) const
     458                 :            : {
     459         [ #  # ]:          0 :     if( eDataMode == SC_VALID_LIST )
     460         [ #  # ]:          0 :         return IsListValid( pCell, rPos );
     461                 :            : 
     462                 :          0 :     double nVal = 0.0;
     463         [ #  # ]:          0 :     String aString;
     464                 :          0 :     sal_Bool bIsVal = sal_True;
     465                 :            : 
     466   [ #  #  #  #  :          0 :     switch (pCell->GetCellType())
                      # ]
     467                 :            :     {
     468                 :            :         case CELLTYPE_VALUE:
     469                 :          0 :             nVal = ((ScValueCell*)pCell)->GetValue();
     470                 :          0 :             break;
     471                 :            :         case CELLTYPE_STRING:
     472         [ #  # ]:          0 :             aString = ((ScStringCell*)pCell)->GetString();
     473                 :          0 :             bIsVal = false;
     474                 :          0 :             break;
     475                 :            :         case CELLTYPE_EDIT:
     476 [ #  # ][ #  # ]:          0 :             aString = ((ScEditCell*)pCell)->GetString();
     477                 :          0 :             bIsVal = false;
     478                 :          0 :             break;
     479                 :            :         case CELLTYPE_FORMULA:
     480                 :            :             {
     481         [ #  # ]:          0 :                 ScFormulaCell* pFCell = (ScFormulaCell*)pCell;
     482         [ #  # ]:          0 :                 bIsVal = pFCell->IsValue();
     483         [ #  # ]:          0 :                 if ( bIsVal )
     484         [ #  # ]:          0 :                     nVal  = pFCell->GetValue();
     485                 :            :                 else
     486 [ #  # ][ #  # ]:          0 :                     aString = pFCell->GetString();
     487                 :            :             }
     488                 :          0 :             break;
     489                 :            :         default:                        // Notizen, Broadcaster
     490                 :          0 :             return IsIgnoreBlank();     // wie eingestellt
     491                 :            :     }
     492                 :            : 
     493                 :          0 :     sal_Bool bOk = sal_True;
     494   [ #  #  #  # ]:          0 :     switch (eDataMode)
     495                 :            :     {
     496                 :            :         // SC_VALID_ANY schon oben
     497                 :            : 
     498                 :            :         case SC_VALID_WHOLE:
     499                 :            :         case SC_VALID_DECIMAL:
     500                 :            :         case SC_VALID_DATE:         // Date/Time ist nur Formatierung
     501                 :            :         case SC_VALID_TIME:
     502                 :          0 :             bOk = bIsVal;
     503 [ #  # ][ #  # ]:          0 :             if ( bOk && eDataMode == SC_VALID_WHOLE )
     504                 :          0 :                 bOk = ::rtl::math::approxEqual( nVal, floor(nVal+0.5) );        // ganze Zahlen
     505         [ #  # ]:          0 :             if ( bOk )
     506         [ #  # ]:          0 :                 bOk = IsCellValid( pCell, rPos );
     507                 :          0 :             break;
     508                 :            : 
     509                 :            :         case SC_VALID_CUSTOM:
     510                 :            :             //  fuer Custom muss eOp == SC_COND_DIRECT sein
     511                 :            :             //! der Wert muss im Dokument stehen !!!!!!!!!!!!!!!!!!!!
     512         [ #  # ]:          0 :             bOk = IsCellValid( pCell, rPos );
     513                 :          0 :             break;
     514                 :            : 
     515                 :            :         case SC_VALID_TEXTLEN:
     516                 :          0 :             bOk = !bIsVal;          // nur Text
     517         [ #  # ]:          0 :             if ( bOk )
     518                 :            :             {
     519                 :          0 :                 double nLenVal = (double) aString.Len();
     520 [ #  # ][ #  # ]:          0 :                 ScValueCell* pTmpCell = new ScValueCell( nLenVal );
     521         [ #  # ]:          0 :                 bOk = IsCellValid( pTmpCell, rPos );
     522         [ #  # ]:          0 :                 pTmpCell->Delete();
     523                 :            :             }
     524                 :          0 :             break;
     525                 :            : 
     526                 :            :         default:
     527                 :            :             OSL_FAIL("hammanochnich");
     528                 :          0 :             break;
     529                 :            :     }
     530                 :            : 
     531         [ #  # ]:          0 :     return bOk;
     532                 :            : }
     533                 :            : 
     534                 :            : // ----------------------------------------------------------------------------
     535                 :            : 
     536                 :            : namespace {
     537                 :            : 
     538                 :            : /** Token array helper. Iterates over all string tokens.
     539                 :            :     @descr  The token array must contain separated string tokens only.
     540                 :            :     @param bSkipEmpty  true = Ignores string tokens with empty strings. */
     541                 :            : class ScStringTokenIterator
     542                 :            : {
     543                 :            : public:
     544                 :          0 :     inline explicit             ScStringTokenIterator( ScTokenArray& rTokArr, bool bSkipEmpty = true ) :
     545                 :          0 :                                     mrTokArr( rTokArr ), mbSkipEmpty( bSkipEmpty ), mbOk( true ) {}
     546                 :            : 
     547                 :            :     /** Returns the string of the first string token or NULL on error or empty token array. */
     548                 :            :     const String*               First();
     549                 :            :     /** Returns the string of the next string token or NULL on error or end of token array. */
     550                 :            :     const String*               Next();
     551                 :            : 
     552                 :            :     /** Returns false, if a wrong token has been found. Does NOT return false on end of token array. */
     553                 :          0 :     inline bool                 Ok() const { return mbOk; }
     554                 :            : 
     555                 :            : private:
     556                 :            :     ScTokenArray&               mrTokArr;       /// The token array for iteration.
     557                 :            :     bool                        mbSkipEmpty;    /// Ignore empty strings.
     558                 :            :     bool                        mbOk;           /// true = correct token or end of token array.
     559                 :            : };
     560                 :            : 
     561                 :          0 : const String* ScStringTokenIterator::First()
     562                 :            : {
     563                 :          0 :     mrTokArr.Reset();
     564                 :          0 :     mbOk = true;
     565                 :          0 :     return Next();
     566                 :            : }
     567                 :            : 
     568                 :          0 : const String* ScStringTokenIterator::Next()
     569                 :            : {
     570         [ #  # ]:          0 :     if( !mbOk )
     571                 :          0 :         return NULL;
     572                 :            : 
     573                 :            :     // seek to next non-separator token
     574                 :          0 :     const FormulaToken* pToken = mrTokArr.NextNoSpaces();
     575 [ #  # ][ #  # ]:          0 :     while( pToken && (pToken->GetOpCode() == ocSep) )
                 [ #  # ]
     576                 :          0 :         pToken = mrTokArr.NextNoSpaces();
     577                 :            : 
     578 [ #  # ][ #  # ]:          0 :     mbOk = !pToken || (pToken->GetType() == formula::svString);
     579 [ #  # ][ #  # ]:          0 :     const String* pString = (mbOk && pToken) ? &pToken->GetString() : NULL;
     580                 :            :     // string found but empty -> get next token; otherwise return it
     581 [ #  # ][ #  # ]:          0 :     return (mbSkipEmpty && pString && !pString->Len()) ? Next() : pString;
                 [ #  # ]
     582                 :            : }
     583                 :            : 
     584                 :            : // ----------------------------------------------------------------------------
     585                 :            : 
     586                 :            : /** Returns the number format of the passed cell, or the standard format. */
     587                 :          0 : sal_uLong lclGetCellFormat( ScDocument& rDoc, const ScAddress& rPos )
     588                 :            : {
     589                 :          0 :     const ScPatternAttr* pPattern = rDoc.GetPattern( rPos.Col(), rPos.Row(), rPos.Tab() );
     590         [ #  # ]:          0 :     if( !pPattern )
     591                 :          0 :         pPattern = rDoc.GetDefPattern();
     592                 :          0 :     return pPattern->GetNumberFormat( rDoc.GetFormatTable() );
     593                 :            : }
     594                 :            : 
     595                 :            : } // namespace
     596                 :            : 
     597                 :            : // ----------------------------------------------------------------------------
     598                 :            : 
     599                 :          0 : bool ScValidationData::HasSelectionList() const
     600                 :            : {
     601 [ #  # ][ #  # ]:          0 :     return (eDataMode == SC_VALID_LIST) && (mnListType != ValidListType::INVISIBLE);
     602                 :            : }
     603                 :            : 
     604                 :          0 : bool ScValidationData::GetSelectionFromFormula(
     605                 :            :     std::vector<ScTypedStrData>* pStrings, ScBaseCell* pCell, const ScAddress& rPos,
     606                 :            :     const ScTokenArray& rTokArr, int& rMatch) const
     607                 :            : {
     608                 :          0 :     bool bOk = true;
     609                 :            : 
     610                 :            :     // pDoc is private in condition, use an accessor and a long winded name.
     611                 :          0 :     ScDocument* pDocument = GetDocument();
     612         [ #  # ]:          0 :     if( NULL == pDocument )
     613                 :          0 :         return false;
     614                 :            : 
     615                 :            :     ScFormulaCell aValidationSrc( pDocument, rPos, &rTokArr,
     616         [ #  # ]:          0 :            formula::FormulaGrammar::GRAM_DEFAULT, MM_FORMULA);
     617                 :            : 
     618                 :            :     // Make sure the formula gets interpreted and a result is delivered,
     619                 :            :     // regardless of the AutoCalc setting.
     620         [ #  # ]:          0 :     aValidationSrc.Interpret();
     621                 :            : 
     622                 :          0 :     ScMatrixRef xMatRef;
     623         [ #  # ]:          0 :     const ScMatrix *pValues = aValidationSrc.GetMatrix();
     624         [ #  # ]:          0 :     if (!pValues)
     625                 :            :     {
     626                 :            :         // The somewhat nasty case of either an error occurred, or the
     627                 :            :         // dereferenced value of a single cell reference or an immediate result
     628                 :            :         // is stored as a single value.
     629                 :            : 
     630                 :            :         // Use an interim matrix to create the TypedStrData below.
     631 [ #  # ][ #  # ]:          0 :         xMatRef = new ScMatrix(1, 1, 0.0);
                 [ #  # ]
     632                 :            : 
     633         [ #  # ]:          0 :         sal_uInt16 nErrCode = aValidationSrc.GetErrCode();
     634         [ #  # ]:          0 :         if (nErrCode)
     635                 :            :         {
     636                 :            :             /* TODO : to use later in an alert box?
     637                 :            :              * String rStrResult = "...";
     638                 :            :              * rStrResult += ScGlobal::GetLongErrorString(nErrCode);
     639                 :            :              */
     640                 :            : 
     641         [ #  # ]:          0 :             xMatRef->PutError( nErrCode, 0, 0);
     642                 :          0 :             bOk = false;
     643                 :            :         }
     644 [ #  # ][ #  # ]:          0 :         else if (aValidationSrc.HasValueData())
     645 [ #  # ][ #  # ]:          0 :             xMatRef->PutDouble( aValidationSrc.GetValue(), 0);
     646                 :            :         else
     647                 :            :         {
     648 [ #  # ][ #  # ]:          0 :             String aStr = aValidationSrc.GetString();
     649 [ #  # ][ #  # ]:          0 :             xMatRef->PutString( aStr, 0);
                 [ #  # ]
     650                 :            :         }
     651                 :            : 
     652                 :          0 :         pValues = xMatRef.get();
     653                 :            :     }
     654                 :            : 
     655                 :            :     // which index matched.  We will want it eventually to pre-select that item.
     656                 :          0 :     rMatch = -1;
     657                 :            : 
     658         [ #  # ]:          0 :     SvNumberFormatter* pFormatter = GetDocument()->GetFormatTable();
     659                 :            : 
     660                 :          0 :     SCSIZE  nCol, nRow, nCols, nRows, n = 0;
     661         [ #  # ]:          0 :     pValues->GetDimensions( nCols, nRows );
     662                 :            : 
     663                 :          0 :     bool bRef = false;
     664                 :          0 :     ScRange aRange;
     665                 :            : 
     666                 :          0 :     ScTokenArray* pArr = (ScTokenArray*) &rTokArr;
     667                 :          0 :     pArr->Reset();
     668                 :          0 :     ScToken* t = NULL;
     669 [ #  # ][ #  # ]:          0 :     if (pArr->GetLen() == 1 && (t = static_cast<ScToken*>(pArr->GetNextReferenceOrName())) != NULL)
         [ #  # ][ #  # ]
     670                 :            :     {
     671         [ #  # ]:          0 :         if (t->GetOpCode() == ocDBArea)
     672                 :            :         {
     673 [ #  # ][ #  # ]:          0 :             if (const ScDBData* pDBData = pDocument->GetDBCollection()->getNamedDBs().findByIndex(t->GetIndex()))
         [ #  # ][ #  # ]
                 [ #  # ]
     674                 :            :             {
     675         [ #  # ]:          0 :                 pDBData->GetArea(aRange);
     676                 :          0 :                 bRef = true;
     677                 :            :             }
     678                 :            :         }
     679         [ #  # ]:          0 :         else if (t->GetOpCode() == ocName)
     680                 :            :         {
     681 [ #  # ][ #  # ]:          0 :             ScRangeData* pName = pDocument->GetRangeName()->findByIndex( t->GetIndex() );
                 [ #  # ]
     682 [ #  # ][ #  # ]:          0 :             if (pName && pName->IsReference(aRange))
         [ #  # ][ #  # ]
     683                 :            :             {
     684                 :          0 :                 bRef = true;
     685                 :            :             }
     686                 :            :         }
     687         [ #  # ]:          0 :         else if (t->GetType() != svIndex)
     688                 :            :         {
     689         [ #  # ]:          0 :             t->CalcAbsIfRel(rPos);
     690 [ #  # ][ #  # ]:          0 :             if (pArr->IsValidReference(aRange))
     691                 :            :             {
     692                 :          0 :                 bRef = true;
     693                 :            :             }
     694                 :            :         }
     695                 :            :     }
     696                 :            : 
     697                 :            :     /* XL artificially limits things to a single col or row in the UI but does
     698                 :            :      * not list the constraint in MOOXml. If a defined name or INDIRECT
     699                 :            :      * resulting in 1D is entered in the UI and the definition later modified
     700                 :            :      * to 2D, it is evaluated fine and also stored and loaded.  Lets get ahead
     701                 :            :      * of the curve and support 2d. In XL, values are listed row-wise, do the
     702                 :            :      * same. */
     703         [ #  # ]:          0 :     for( nRow = 0; nRow < nRows ; nRow++ )
     704                 :            :     {
     705         [ #  # ]:          0 :         for( nCol = 0; nCol < nCols ; nCol++ )
     706                 :            :         {
     707         [ #  # ]:          0 :             ScTokenArray         aCondTokArr;
     708                 :          0 :             ScTypedStrData*        pEntry = NULL;
     709         [ #  # ]:          0 :             String               aValStr;
     710         [ #  # ]:          0 :             ScMatrixValue nMatVal = pValues->Get( nCol, nRow);
     711                 :            : 
     712                 :            :             // strings and empties
     713         [ #  # ]:          0 :             if( ScMatrix::IsNonValueType( nMatVal.nType ) )
     714                 :            :             {
     715         [ #  # ]:          0 :                 aValStr = nMatVal.GetString();
     716                 :            : 
     717         [ #  # ]:          0 :                 if( NULL != pStrings )
     718 [ #  # ][ #  # ]:          0 :                     pEntry = new ScTypedStrData( aValStr, 0.0, ScTypedStrData::Standard);
                 [ #  # ]
     719                 :            : 
     720 [ #  # ][ #  # ]:          0 :                 if( pCell && rMatch < 0 )
     721         [ #  # ]:          0 :                     aCondTokArr.AddString( aValStr );
     722                 :            :             }
     723                 :            :             else
     724                 :            :             {
     725                 :          0 :                 sal_uInt16 nErr = nMatVal.GetError();
     726                 :            : 
     727         [ #  # ]:          0 :                 if( 0 != nErr )
     728                 :            :                 {
     729 [ #  # ][ #  # ]:          0 :                     aValStr = ScGlobal::GetErrorString( nErr );
                 [ #  # ]
     730                 :            :                 }
     731                 :            :                 else
     732                 :            :                 {
     733                 :            :                     // FIXME FIXME FIXME
     734                 :            :                     // Feature regression.  Date formats are lost passing through the matrix
     735                 :            :                     //pFormatter->GetInputLineString( pMatVal->fVal, 0, aValStr );
     736                 :            :                     //For external reference and a formula that results in an area or array, date formats are still lost.
     737         [ #  # ]:          0 :                     if ( bRef )
     738                 :            :                     {
     739                 :          0 :                         pDocument->GetInputString((SCCOL)(nCol+aRange.aStart.Col()),
     740         [ #  # ]:          0 :                             (SCROW)(nRow+aRange.aStart.Row()), aRange.aStart.Tab() , aValStr);
     741                 :            :                     }
     742                 :            :                     else
     743         [ #  # ]:          0 :                         pFormatter->GetInputLineString( nMatVal.fVal, 0, aValStr );
     744                 :            :                 }
     745                 :            : 
     746 [ #  # ][ #  # ]:          0 :                 if( pCell && rMatch < 0 )
     747                 :            :                 {
     748                 :            :                     // I am not sure errors will work here, but a user can no
     749                 :            :                     // manually enter an error yet so the point is somewhat moot.
     750         [ #  # ]:          0 :                     aCondTokArr.AddDouble( nMatVal.fVal );
     751                 :            :                 }
     752         [ #  # ]:          0 :                 if( NULL != pStrings )
     753 [ #  # ][ #  # ]:          0 :                     pEntry = new ScTypedStrData( aValStr, nMatVal.fVal, ScTypedStrData::Value);
                 [ #  # ]
     754                 :            :             }
     755                 :            : 
     756 [ #  # ][ #  # ]:          0 :             if( rMatch < 0 && NULL != pCell && IsEqualToTokenArray( pCell, rPos, aCondTokArr ) )
         [ #  # ][ #  # ]
                 [ #  # ]
     757                 :            :             {
     758                 :          0 :                 rMatch = n;
     759                 :            :                 // short circuit on the first match if not filling the list
     760         [ #  # ]:          0 :                 if( NULL == pStrings )
     761                 :          0 :                     return true;
     762                 :            :             }
     763                 :            : 
     764         [ #  # ]:          0 :             if( NULL != pEntry )
     765                 :            :             {
     766         [ #  # ]:          0 :                 pStrings->push_back(*pEntry);
     767         [ #  # ]:          0 :                 delete pEntry;
     768                 :          0 :                 n++;
     769                 :            :             }
     770 [ #  # ][ #  # ]:          0 :         }
         [ #  # ][ #  # ]
                 [ #  # ]
     771                 :            :     }
     772                 :            : 
     773                 :            :     // In case of no match needed and an error occurred, return that error
     774                 :            :     // entry as valid instead of silently failing.
     775 [ #  # ][ #  # ]:          0 :     return bOk || NULL == pCell;
         [ #  # ][ #  # ]
     776                 :            : }
     777                 :            : 
     778                 :          0 : bool ScValidationData::FillSelectionList(std::vector<ScTypedStrData>& rStrColl, const ScAddress& rPos) const
     779                 :            : {
     780                 :          0 :     bool bOk = false;
     781                 :            : 
     782         [ #  # ]:          0 :     if( HasSelectionList() )
     783                 :            :     {
     784         [ #  # ]:          0 :         boost::scoped_ptr<ScTokenArray> pTokArr( CreateTokenArry(0) );
     785                 :            : 
     786                 :            :         // *** try if formula is a string list ***
     787                 :            : 
     788         [ #  # ]:          0 :         sal_uInt32 nFormat = lclGetCellFormat( *GetDocument(), rPos );
     789                 :          0 :         ScStringTokenIterator aIt( *pTokArr );
     790 [ #  # ][ #  # ]:          0 :         for( const String* pString = aIt.First(); pString && aIt.Ok(); pString = aIt.Next() )
         [ #  # ][ #  # ]
                 [ #  # ]
     791                 :            :         {
     792                 :            :             double fValue;
     793 [ #  # ][ #  # ]:          0 :             bool bIsValue = GetDocument()->GetFormatTable()->IsNumberFormat( *pString, nFormat, fValue );
     794                 :            :             rStrColl.push_back(
     795                 :            :                 ScTypedStrData(
     796 [ #  # ][ #  # ]:          0 :                     *pString, fValue, bIsValue ? ScTypedStrData::Value : ScTypedStrData::Standard));
         [ #  # ][ #  # ]
     797                 :            :         }
     798                 :          0 :         bOk = aIt.Ok();
     799                 :            : 
     800                 :            :         // *** if not a string list, try if formula results in a cell range or
     801                 :            :         // anything else we recognize as valid ***
     802                 :            : 
     803         [ #  # ]:          0 :         if (!bOk)
     804                 :            :         {
     805                 :            :             int nMatch;
     806         [ #  # ]:          0 :             bOk = GetSelectionFromFormula( &rStrColl, NULL, rPos, *pTokArr, nMatch );
     807         [ #  # ]:          0 :         }
     808                 :            :     }
     809                 :            : 
     810                 :          0 :     return bOk;
     811                 :            : }
     812                 :            : 
     813                 :            : // ----------------------------------------------------------------------------
     814                 :            : 
     815                 :          0 : bool ScValidationData::IsEqualToTokenArray( ScBaseCell* pCell, const ScAddress& rPos, const ScTokenArray& rTokArr ) const
     816                 :            : {
     817                 :            :     // create a condition entry that tests on equality and set the passed token array
     818         [ #  # ]:          0 :     ScConditionEntry aCondEntry( SC_COND_EQUAL, &rTokArr, NULL, GetDocument(), rPos );
     819 [ #  # ][ #  # ]:          0 :     return aCondEntry.IsCellValid( pCell, rPos );
     820                 :            : }
     821                 :            : 
     822                 :          0 : bool ScValidationData::IsListValid( ScBaseCell* pCell, const ScAddress& rPos ) const
     823                 :            : {
     824                 :          0 :     bool bIsValid = false;
     825                 :            : 
     826                 :            :     /*  Compare input cell with all supported tokens from the formula.
     827                 :            :         Currently a formula may contain:
     828                 :            :         1)  A list of strings (at least one string).
     829                 :            :         2)  A single cell or range reference.
     830                 :            :         3)  A single defined name (must contain a cell/range reference, another
     831                 :            :             name, or DB range, or a formula resulting in a cell/range reference
     832                 :            :             or matrix/array).
     833                 :            :         4)  A single database range.
     834                 :            :         5)  A formula resulting in a cell/range reference or matrix/array.
     835                 :            :     */
     836                 :            : 
     837                 :            :     SAL_WNODEPRECATED_DECLARATIONS_PUSH
     838         [ #  # ]:          0 :     ::std::auto_ptr< ScTokenArray > pTokArr( CreateTokenArry( 0 ) );
     839                 :            :     SAL_WNODEPRECATED_DECLARATIONS_POP
     840                 :            : 
     841                 :            :     // *** try if formula is a string list ***
     842                 :            : 
     843         [ #  # ]:          0 :     sal_uInt32 nFormat = lclGetCellFormat( *GetDocument(), rPos );
     844                 :          0 :     ScStringTokenIterator aIt( *pTokArr );
     845 [ #  # ][ #  # ]:          0 :     for( const String* pString = aIt.First(); pString && aIt.Ok(); pString = aIt.Next() )
         [ #  # ][ #  # ]
                 [ #  # ]
     846                 :            :     {
     847                 :            :         /*  Do not break the loop, if a valid string has been found.
     848                 :            :             This is to find invalid tokens following in the formula. */
     849         [ #  # ]:          0 :         if( !bIsValid )
     850                 :            :         {
     851                 :            :             // create a formula containing a single string or number
     852         [ #  # ]:          0 :             ScTokenArray aCondTokArr;
     853                 :            :             double fValue;
     854 [ #  # ][ #  # ]:          0 :             if( GetDocument()->GetFormatTable()->IsNumberFormat( *pString, nFormat, fValue ) )
                 [ #  # ]
     855         [ #  # ]:          0 :                 aCondTokArr.AddDouble( fValue );
     856                 :            :             else
     857         [ #  # ]:          0 :                 aCondTokArr.AddString( *pString );
     858                 :            : 
     859 [ #  # ][ #  # ]:          0 :             bIsValid = IsEqualToTokenArray( pCell, rPos, aCondTokArr );
     860                 :            :         }
     861                 :            :     }
     862                 :            : 
     863         [ #  # ]:          0 :     if( !aIt.Ok() )
     864                 :          0 :         bIsValid = false;
     865                 :            : 
     866                 :            :     // *** if not a string list, try if formula results in a cell range or
     867                 :            :     // anything else we recognize as valid ***
     868                 :            : 
     869         [ #  # ]:          0 :     if (!bIsValid)
     870                 :            :     {
     871                 :            :         int nMatch;
     872         [ #  # ]:          0 :         bIsValid = GetSelectionFromFormula( NULL, pCell, rPos, *pTokArr, nMatch );
     873 [ #  # ][ #  # ]:          0 :         bIsValid = bIsValid && nMatch >= 0;
     874                 :            :     }
     875                 :            : 
     876         [ #  # ]:          0 :     return bIsValid;
     877                 :            : }
     878                 :            : 
     879                 :            : // ============================================================================
     880                 :            : // ============================================================================
     881                 :            : 
     882                 :          0 : ScValidationDataList::ScValidationDataList(const ScValidationDataList& rList) :
     883                 :          0 :     std::set<ScValidationData*, CompareScValidationDataPtr>()
     884                 :            : {
     885                 :            :     //  fuer Ref-Undo - echte Kopie mit neuen Tokens!
     886                 :            : 
     887 [ #  # ][ #  # ]:          0 :     for (const_iterator it = rList.begin(); it != rList.end(); ++it)
                 [ #  # ]
     888                 :            :     {
     889 [ #  # ][ #  # ]:          0 :         InsertNew( (*it)->Clone() );
                 [ #  # ]
     890                 :            :     }
     891                 :            : 
     892                 :            :     //!     sortierte Eintraege aus rList schneller einfuegen ???
     893                 :          0 : }
     894                 :            : 
     895                 :          0 : ScValidationDataList::ScValidationDataList(ScDocument* pNewDoc,
     896                 :          0 :                                             const ScValidationDataList& rList)
     897                 :            : {
     898                 :            :     //  fuer neues Dokument - echte Kopie mit neuen Tokens!
     899                 :            : 
     900 [ #  # ][ #  # ]:          0 :     for (const_iterator it = rList.begin(); it != rList.end(); ++it)
                 [ #  # ]
     901                 :            :     {
     902 [ #  # ][ #  # ]:          0 :         InsertNew( (*it)->Clone(pNewDoc) );
                 [ #  # ]
     903                 :            :     }
     904                 :            : 
     905                 :            :     //!     sortierte Eintraege aus rList schneller einfuegen ???
     906                 :          0 : }
     907                 :            : 
     908                 :        147 : ScValidationData* ScValidationDataList::GetData( sal_uInt32 nKey )
     909                 :            : {
     910                 :            :     //! binaer suchen
     911                 :            : 
     912 [ +  - ][ +  - ]:        228 :     for( iterator it = begin(); it != end(); ++it )
                 [ +  - ]
     913 [ +  - ][ +  + ]:        228 :         if( (*it)->GetKey() == nKey )
     914         [ +  - ]:        147 :             return *it;
     915                 :            : 
     916                 :            :     OSL_FAIL("ScValidationDataList: Eintrag nicht gefunden");
     917                 :        147 :     return NULL;
     918                 :            : }
     919                 :            : 
     920                 :          3 : void ScValidationDataList::CompileXML()
     921                 :            : {
     922 [ +  - ][ +  - ]:          9 :     for( iterator it = begin(); it != end(); ++it )
                 [ +  + ]
     923 [ +  - ][ +  - ]:          6 :         (*it)->CompileXML();
     924                 :          3 : }
     925                 :            : 
     926                 :          0 : void ScValidationDataList::UpdateReference( UpdateRefMode eUpdateRefMode,
     927                 :            :                                 const ScRange& rRange, SCsCOL nDx, SCsROW nDy, SCsTAB nDz )
     928                 :            : {
     929 [ #  # ][ #  # ]:          0 :     for( iterator it = begin(); it != end(); ++it )
                 [ #  # ]
     930 [ #  # ][ #  # ]:          0 :         (*it)->UpdateReference( eUpdateRefMode, rRange, nDx, nDy, nDz);
     931                 :          0 : }
     932                 :            : 
     933                 :          0 : void ScValidationDataList::UpdateMoveTab( SCTAB nOldPos, SCTAB nNewPos )
     934                 :            : {
     935 [ #  # ][ #  # ]:          0 :     for( iterator it = begin(); it != end(); ++it )
                 [ #  # ]
     936 [ #  # ][ #  # ]:          0 :         (*it)->UpdateMoveTab( nOldPos, nNewPos );
     937                 :          0 : }
     938                 :            : 
     939                 :          0 : sal_Bool ScValidationDataList::operator==( const ScValidationDataList& r ) const
     940                 :            : {
     941                 :            :     // fuer Ref-Undo - interne Variablen werden nicht verglichen
     942                 :            : 
     943                 :          0 :     sal_uInt16 nCount = size();
     944                 :          0 :     sal_Bool bEqual = ( nCount == r.size() );
     945 [ #  # ][ #  # ]:          0 :     for( const_iterator it1 = begin(), it2 = r.begin(); it1 != end() && bEqual; ++it1, ++it2 ) // Eintraege sind sortiert
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
           [ #  #  #  # ]
     946 [ #  # ][ #  # ]:          0 :         if ( !(*it1)->EqualEntries(**it2) )         // Eintraege unterschiedlich ?
         [ #  # ][ #  # ]
     947                 :          0 :             bEqual = sal_False;
     948                 :            : 
     949                 :          0 :     return bEqual;
     950                 :            : }
     951                 :            : 
     952                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10