[Libreoffice-commits] .: Branch 'feature/tubes' - sc/source

Michael Meeks michael at kemper.freedesktop.org
Tue Mar 20 12:03:37 PDT 2012


 sc/source/ui/docshell/docfunc.cxx |  376 +++++++++++++++++++++++++++++++++++++-
 sc/source/ui/docshell/docsh.cxx   |   17 +
 sc/source/ui/inc/docfunc.hxx      |    5 
 sc/source/ui/view/viewfunc.cxx    |  374 +------------------------------------
 4 files changed, 405 insertions(+), 367 deletions(-)

New commits:
commit 2aeebf9060935101e2613da982ed7aed07ea83ed
Author: Michael Meeks <michael.meeks at suse.com>
Date:   Tue Mar 20 19:02:01 2012 +0000

    Horribly mangle the ScDocFunc to create a monster

diff --git a/sc/source/ui/docshell/docfunc.cxx b/sc/source/ui/docshell/docfunc.cxx
index 973968d..227d6f4 100644
--- a/sc/source/ui/docshell/docfunc.cxx
+++ b/sc/source/ui/docshell/docfunc.cxx
@@ -100,6 +100,8 @@
 #include "clipparam.hxx"
 #include "externalrefmgr.hxx"
 #include "undorangename.hxx"
+#include "funcdesc.hxx"
+#include "docuno.hxx"
 
 #include <memory>
 #include <basic/basmgr.hxx>
@@ -3770,6 +3772,378 @@ bool ScDocFunc::AutoFormat( const ScRange& rRange, const ScMarkData* pTabMark,
 
 //------------------------------------------------------------------------
 
+#ifndef LRU_MAX
+#define LRU_MAX 10
+#endif
+
+/*
+ * FIXME: this function detection / auto-entry code should be
+ * pushed up back into the view before this goes to master !
+ */
+
+sal_Bool lcl_FunctionKnown( sal_uInt16 nOpCode )
+{
+    const ScFunctionList* pFuncList = ScGlobal::GetStarCalcFunctionList();
+    if ( pFuncList )
+    {
+        sal_uLong nCount = pFuncList->GetCount();
+        for (sal_uLong i=0; i<nCount; i++)
+            if ( pFuncList->GetFunction(i)->nFIndex == nOpCode )
+                return sal_True;
+    }
+    return false;
+}
+
+sal_Bool lcl_AddFunction( ScAppOptions& rAppOpt, sal_uInt16 nOpCode )
+{
+    sal_uInt16 nOldCount = rAppOpt.GetLRUFuncListCount();
+    sal_uInt16* pOldList = rAppOpt.GetLRUFuncList();
+    sal_uInt16 nPos;
+    for (nPos=0; nPos<nOldCount; nPos++)
+        if (pOldList[nPos] == nOpCode)          // is the function already in the list?
+        {
+            if ( nPos == 0 )
+                return false;                   // already at the top -> no change
+
+            //  count doesn't change, so the original array is modified
+
+            for (sal_uInt16 nCopy=nPos; nCopy>0; nCopy--)
+                pOldList[nCopy] = pOldList[nCopy-1];
+            pOldList[0] = nOpCode;
+
+            return sal_True;                        // list has changed
+        }
+
+    if ( !lcl_FunctionKnown( nOpCode ) )
+        return false;                           // not in function list -> no change
+
+    sal_uInt16 nNewCount = Min( (sal_uInt16)(nOldCount + 1), (sal_uInt16)LRU_MAX );
+    sal_uInt16 nNewList[LRU_MAX];
+    nNewList[0] = nOpCode;
+    for (nPos=1; nPos<nNewCount; nPos++)
+        nNewList[nPos] = pOldList[nPos-1];
+    rAppOpt.SetLRUFuncList( nNewList, nNewCount );
+
+    return sal_True;                                // list has changed
+}
+
+/**
+ * Enter user data across marked tabs at given row / column
+ *
+ * FIXME: this -badly- needs decomposing into some sane series
+ *        of smaller operations.
+ */
+void ScDocFunc::EnterUserDataTabs( SCCOL nCol, SCROW nRow, SCTAB nTab,
+                                   const ScMarkData &rMark,
+                                   const String& rString,
+                                   sal_Bool bRecord, const EditTextObject* pData )
+{
+    ScDocShellModificator aModificator( rDocShell );
+
+    SCTAB nSelCount = rMark.GetSelectCount();
+    SCTAB i;
+    sal_Bool bEditDeleted = false;
+    sal_uInt8 nOldScript = 0;
+    ScDocument* pDoc = rDocShell.GetDocument();
+
+    ScBaseCell** ppOldCells = NULL;
+    sal_Bool* pHasFormat        = NULL;
+    sal_uLong* pOldFormats      = NULL;
+    SCTAB* pTabs            = NULL;
+    SCTAB nUndoPos = 0;
+    EditTextObject* pUndoData = NULL;
+    if ( bRecord )
+    {
+        ppOldCells      = new ScBaseCell*[nSelCount];
+        pHasFormat      = new sal_Bool[nSelCount];
+        pOldFormats     = new sal_uLong[nSelCount];
+        pTabs           = new SCTAB[nSelCount];
+        nUndoPos = 0;
+
+        ScMarkData::iterator itr = rMark.begin(), itrEnd = rMark.end();
+        for (; itr != itrEnd; ++itr)
+        {
+            i = *itr;
+            pTabs[nUndoPos] = i;
+            ScBaseCell* pDocCell;
+            pDoc->GetCell( nCol, nRow, i, pDocCell );
+            if ( pDocCell )
+            {
+                ppOldCells[nUndoPos] = pDocCell->Clone( *pDoc );
+                if ( pDocCell->GetCellType() == CELLTYPE_EDIT )
+                    bEditDeleted = sal_True;
+
+                sal_uInt8 nDocScript = pDoc->GetScriptType( nCol, nRow, i, pDocCell );
+                if ( nOldScript == 0 )
+                    nOldScript = nDocScript;
+                else if ( nDocScript != nOldScript )
+                    bEditDeleted = sal_True;
+            }
+            else
+                ppOldCells[nUndoPos] = NULL;
+
+            const SfxPoolItem* pItem;
+            const ScPatternAttr* pPattern = pDoc->GetPattern(nCol, nRow, i);
+            if ( SFX_ITEM_SET == pPattern->GetItemSet().GetItemState(
+                                       ATTR_VALUE_FORMAT,false,&pItem) )
+            {
+                pHasFormat[nUndoPos] = sal_True;
+                pOldFormats[nUndoPos] = ((const SfxUInt32Item*)pItem)->GetValue();
+            }
+            else
+                pHasFormat[nUndoPos] = false;
+
+            ++nUndoPos;
+        }
+
+            OSL_ENSURE( nUndoPos==nSelCount, "nUndoPos!=nSelCount" );
+
+            pUndoData = ( pData ? pData->Clone() : NULL );
+        }
+
+    bool bFormula = false;
+
+    // a single '=' character is handled as string (needed for special filters)
+    if ( rString.Len() > 1 )
+    {
+        if ( rString.GetChar(0) == '=' )
+        {
+            // handle as formula
+            bFormula = true;
+        }
+        else if ( rString.GetChar(0) == '+' || rString.GetChar(0) == '-' )
+        {
+            // if there is more than one leading '+' or '-' character, remove the additional ones
+            String aString( rString );
+            xub_StrLen nIndex = 1;
+            xub_StrLen nLen = aString.Len();
+            while ( nIndex < nLen && ( aString.GetChar( nIndex ) == '+' || aString.GetChar( nIndex ) == '-' ) )
+            {
+                ++nIndex;
+            }
+            aString.Erase( 1, nIndex - 1 );
+
+            // if the remaining part without the leading '+' or '-' character
+            // is non-empty and not a number, handle as formula
+            if ( aString.Len() > 1 )
+            {
+                sal_uInt32 nFormat = 0;
+                pDoc->GetNumberFormat( nCol, nRow, nTab, nFormat );
+                SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
+                double fNumber = 0;
+                if ( !pFormatter->IsNumberFormat( aString, nFormat, fNumber ) )
+                    bFormula = true;
+            }
+        }
+    }
+
+    sal_Bool bNumFmtChanged = false;
+    if ( bFormula )
+    {   // formula, compile with autoCorrection
+        i = rMark.GetFirstSelected();
+        ScAddress aPos( nCol, nRow, i );
+        ScCompiler aComp( pDoc, aPos);
+        aComp.SetGrammar(pDoc->GetGrammar());
+        //2do: enable/disable autoCorrection via calcoptions
+        aComp.SetAutoCorrection( sal_True );
+        if ( rString.GetChar(0) == '+' || rString.GetChar(0) == '-' )
+            aComp.SetExtendedErrorDetection( ScCompiler::EXTENDED_ERROR_DETECTION_NAME_BREAK );
+
+        String aFormula( rString );
+        ScTokenArray* pArr;
+        sal_Bool bAgain;
+        do
+        {
+            bAgain = false;
+            bool bAddEqual = false;
+            ScTokenArray* pArrFirst = pArr = aComp.CompileString( aFormula );
+            bool bCorrected = aComp.IsCorrected();
+            if ( bCorrected )
+            {   // try to parse with first parser-correction
+                pArr = aComp.CompileString( aComp.GetCorrectedFormula() );
+            }
+            if ( !pArr->GetCodeError() )
+            {
+                bAddEqual = true;
+                aComp.CompileTokenArray();
+                bCorrected |= aComp.IsCorrected();
+            }
+            if ( bCorrected )
+            {
+                String aCorrectedFormula;
+                if ( bAddEqual )
+                {
+                    aCorrectedFormula = '=';
+                    aCorrectedFormula += aComp.GetCorrectedFormula();
+                }
+                else
+                    aCorrectedFormula = aComp.GetCorrectedFormula();
+                short nResult;
+                if ( aCorrectedFormula.Len() == 1 )
+                    nResult = RET_NO;   // empty formula, just '='
+                else
+                {
+                    String aMessage( ScResId( SCSTR_FORMULA_AUTOCORRECTION ) );
+                    aMessage += aCorrectedFormula;
+                    nResult = QueryBox( rDocShell.GetActiveDialogParent(),
+                                        WinBits(WB_YES_NO | WB_DEF_YES),
+                                        aMessage ).Execute();
+                }
+                if ( nResult == RET_YES )
+                {
+                    aFormula = aCorrectedFormula;
+                    if ( pArr != pArrFirst )
+                        delete pArrFirst;
+                    bAgain = sal_True;
+                }
+                else
+                {
+                    if ( pArr != pArrFirst )
+                    {
+                        delete pArr;
+                        pArr = pArrFirst;
+                    }
+                }
+            }
+        } while ( bAgain );
+        // to be used in multiple tabs, the formula must be compiled anew
+        // via ScFormulaCell copy-ctor because of RangeNames,
+        // the same code-array for all cells is not possible.
+        // If the array has an error, (it) must be RPN-erased in the newly generated
+        // cellst and the error be set explicitly, so that
+        // via FormulaCell copy-ctor and Interpreter it will be, when possible,
+        // ironed out again, too intelligent.. e.g.: =1))
+        sal_uInt16 nError = pArr->GetCodeError();
+        if ( !nError )
+        {
+            //  update list of recent functions with all functions that
+            //  are not within parentheses
+
+            ScModule* pScMod = SC_MOD();
+            ScAppOptions aAppOpt = pScMod->GetAppOptions();
+            sal_Bool bOptChanged = false;
+
+            formula::FormulaToken** ppToken = pArr->GetArray();
+            sal_uInt16 nTokens = pArr->GetLen();
+            sal_uInt16 nLevel = 0;
+            for (sal_uInt16 nTP=0; nTP<nTokens; nTP++)
+            {
+                formula::FormulaToken* pTok = ppToken[nTP];
+                OpCode eOp = pTok->GetOpCode();
+                if ( eOp == ocOpen )
+                    ++nLevel;
+                else if ( eOp == ocClose && nLevel )
+                    --nLevel;
+                if ( nLevel == 0 && pTok->IsFunction() &&
+                     lcl_AddFunction( aAppOpt, sal::static_int_cast<sal_uInt16>( eOp ) ) )
+                    bOptChanged = sal_True;
+            }
+
+            if ( bOptChanged )
+            {
+                pScMod->SetAppOptions(aAppOpt);
+                pScMod->RecentFunctionsChanged();
+            }
+        }
+
+        ScFormulaCell aCell( pDoc, aPos, pArr,formula::FormulaGrammar::GRAM_DEFAULT, MM_NONE );
+        delete pArr;
+        sal_Bool bAutoCalc = pDoc->GetAutoCalc();
+        SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
+        ScMarkData::iterator itr = rMark.begin(), itrEnd = rMark.end();
+        for (; itr != itrEnd; ++itr)
+        {
+            i = *itr;
+            aPos.SetTab( i );
+            sal_uLong nIndex = (sal_uLong) ((SfxUInt32Item*) pDoc->GetAttr(
+                                                nCol, nRow, i, ATTR_VALUE_FORMAT ))->GetValue();
+            if ( pFormatter->GetType( nIndex ) == NUMBERFORMAT_TEXT ||
+                 ( ( rString.GetChar(0) == '+' || rString.GetChar(0) == '-' ) && nError && rString.Equals( aFormula ) ) )
+            {
+                if ( pData )
+                {
+                    ScEditCell* pCell = new ScEditCell( pData, pDoc, NULL );
+                    pDoc->PutCell( aPos, pCell );
+                }
+                else
+                {
+                    ScStringCell* pCell = new ScStringCell( aFormula );
+                    pDoc->PutCell( aPos, pCell );
+                }
+            }
+            else
+            {
+                DELETEZ(pUndoData);
+                ScFormulaCell* pCell = new ScFormulaCell( aCell, *pDoc, aPos );
+                if ( nError )
+                {
+                    pCell->GetCode()->DelRPN();
+                    pCell->SetErrCode( nError );
+                    if(pCell->GetCode()->IsHyperLink())
+                        pCell->GetCode()->SetHyperLink(false);
+                }
+                pDoc->PutCell( aPos, pCell );
+                if ( !bAutoCalc )
+                {   // calculate just the cell once and set Dirty again
+                    pCell->Interpret();
+                    pCell->SetDirtyVar();
+                    pDoc->PutInFormulaTree( pCell );
+                }
+            }
+        }
+    }
+    else
+    {
+        ScMarkData::iterator itr = rMark.begin(), itrEnd = rMark.end();
+        for (; itr != itrEnd; ++itr)
+            if (pDoc->SetString( nCol, nRow, *itr, rString ))
+                bNumFmtChanged = true;
+    }
+
+    //  row height must be changed if new text has a different script type
+    ScMarkData::iterator itr = rMark.begin(), itrEnd = rMark.end();
+    for (; itr != itrEnd && !bEditDeleted; ++itr)
+        if ( pDoc->GetScriptType( nCol, nRow, *itr ) != nOldScript )
+            bEditDeleted = true;
+
+    if (bEditDeleted || pDoc->HasAttrib( nCol, nRow, nTab, nCol, nRow, nTab, HASATTR_NEEDHEIGHT ))
+        AdjustRowHeight(ScRange( 0, nRow, nTab, nRow, MAXCOL, nTab ) );
+
+#ifdef MEEKS_HACK
+    sal_Bool bAutoFormat = TestFormatArea(nCol, nRow, nTab, bNumFmtChanged);
+    if (bAutoFormat)
+        DoAutoAttributes(nCol, nRow, nTab, bNumFmtChanged, bRecord);
+#else
+    (void)bNumFmtChanged;
+#endif
+
+    if ( bRecord )
+    {   // because of ChangeTrack current first
+        rDocShell.GetUndoManager()->AddUndoAction(
+               new ScUndoEnterData( &rDocShell, nCol, nRow, nTab, nUndoPos, pTabs,
+                                    ppOldCells, pHasFormat, pOldFormats,
+                                    rString, pUndoData ) );
+    }
+
+    itr = rMark.begin();
+    for (; itr != itrEnd; ++itr)
+        rDocShell.PostPaintCell( nCol, nRow, *itr );
+
+    // #i97876# Spreadsheet data changes are not notified
+    ScModelObj* pModelObj = ScModelObj::getImplementation( rDocShell.GetModel() );
+    if ( pModelObj && pModelObj->HasChangesListeners() )
+    {
+        ScRangeList aChangeRanges;
+        itr = rMark.begin();
+        for (; itr != itrEnd; ++itr)
+            aChangeRanges.Append( ScRange( nCol, nRow, *itr ) );
+        pModelObj->NotifyChanges( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "cell-change" ) ), aChangeRanges );
+    }
+    aModificator.SetDocumentModified();
+}
+
+//------------------------------------------------------------------------
+
 sal_Bool ScDocFunc::EnterMatrix( const ScRange& rRange, const ScMarkData* pTabMark,
         const ScTokenArray* pTokenArray, const String& rString, sal_Bool bApi, sal_Bool bEnglish,
         const String& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammar )
@@ -4949,8 +5323,6 @@ sal_Bool ScDocFunc::InsertAreaLink( const String& rFile, const String& rFilter,
                                 const ScRange& rDestRange, sal_uLong nRefresh,
                                 sal_Bool bFitBlock, sal_Bool bApi )
 {
-    //! auch fuer ScViewFunc::InsertAreaLink benutzen!
-
     ScDocument* pDoc = rDocShell.GetDocument();
     sal_Bool bUndo (pDoc->IsUndoEnabled());
 
diff --git a/sc/source/ui/docshell/docsh.cxx b/sc/source/ui/docshell/docsh.cxx
index 0bf22e3..b030bc2 100644
--- a/sc/source/ui/docshell/docsh.cxx
+++ b/sc/source/ui/docshell/docsh.cxx
@@ -2537,10 +2537,25 @@ public:
     virtual sal_Bool PutCell( const ScAddress& rPos, ScBaseCell* pNewCell, sal_Bool bApi )
     {
         fprintf( stderr, "put cell string '%p' %d\n", pNewCell, bApi );
-//                 rtl::OUStringToOString( rText, RTL_TEXTENCODING_UTF8 ).getStr() );
         return ScDocFunc::PutCell( rPos, pNewCell, bApi );
     }
 
+    virtual sal_Bool PutData( const ScAddress& rPos, ScEditEngineDefaulter& rEngine,
+                              sal_Bool bInterpret, sal_Bool bApi )
+    {
+        fprintf( stderr, "put data\n" );
+        return ScDocFunc::PutData( rPos, rEngine, bInterpret, bApi );
+    }
+
+    virtual void EnterUserDataTabs( SCCOL nCol, SCROW nRow, SCTAB nTab,
+                                    const ScMarkData &rMark, const String& rString,
+                                    sal_Bool bRecord, const EditTextObject* pData )
+    {
+        fprintf( stderr, "Enter user data tabs '%s'\n",
+                 rtl::OUStringToOString( rString, RTL_TEXTENCODING_UTF8 ).getStr() );
+        return ScDocFunc::EnterUserDataTabs( nCol, nRow, nTab, rMark, rString, bRecord, pData );
+    }
+
     virtual sal_Bool SetCellText( const ScAddress& rPos, const String& rText,
                                   sal_Bool bInterpret, sal_Bool bEnglish, sal_Bool bApi,
                                   const String& rFormulaNmsp,
diff --git a/sc/source/ui/inc/docfunc.hxx b/sc/source/ui/inc/docfunc.hxx
index e7f6b4d..1c87c0d 100644
--- a/sc/source/ui/inc/docfunc.hxx
+++ b/sc/source/ui/inc/docfunc.hxx
@@ -156,6 +156,11 @@ public:
     virtual bool            AutoFormat( const ScRange& rRange, const ScMarkData* pTabMark,
                                         sal_uInt16 nFormatNo, bool bRecord, bool bApi );
 
+    virtual void            EnterUserDataTabs( SCCOL nCol, SCROW nRow, SCTAB nTab,
+                                               const ScMarkData &rMark,
+                                               const String& rString,
+                                               sal_Bool bRecord, const EditTextObject* pData );
+
     virtual sal_Bool        EnterMatrix( const ScRange& rRange, const ScMarkData* pTabMark,
                                          const ScTokenArray* pTokenArray,
                                          const String& rString, sal_Bool bApi, sal_Bool bEnglish,
diff --git a/sc/source/ui/view/viewfunc.cxx b/sc/source/ui/view/viewfunc.cxx
index cf1b9db..54a598e 100644
--- a/sc/source/ui/view/viewfunc.cxx
+++ b/sc/source/ui/view/viewfunc.cxx
@@ -299,56 +299,6 @@ sal_Bool ScViewFunc::SelectionEditable( bool* pOnlyNotBecauseOfMatrix /* = NULL
     return bRet;
 }
 
-#ifndef LRU_MAX
-#define LRU_MAX 10
-#endif
-
-sal_Bool lcl_FunctionKnown( sal_uInt16 nOpCode )
-{
-    const ScFunctionList* pFuncList = ScGlobal::GetStarCalcFunctionList();
-    if ( pFuncList )
-    {
-        sal_uLong nCount = pFuncList->GetCount();
-        for (sal_uLong i=0; i<nCount; i++)
-            if ( pFuncList->GetFunction(i)->nFIndex == nOpCode )
-                return sal_True;
-    }
-    return false;
-}
-
-sal_Bool lcl_AddFunction( ScAppOptions& rAppOpt, sal_uInt16 nOpCode )
-{
-    sal_uInt16 nOldCount = rAppOpt.GetLRUFuncListCount();
-    sal_uInt16* pOldList = rAppOpt.GetLRUFuncList();
-    sal_uInt16 nPos;
-    for (nPos=0; nPos<nOldCount; nPos++)
-        if (pOldList[nPos] == nOpCode)          // is the function already in the list?
-        {
-            if ( nPos == 0 )
-                return false;                   // already at the top -> no change
-
-            //  count doesn't change, so the original array is modified
-
-            for (sal_uInt16 nCopy=nPos; nCopy>0; nCopy--)
-                pOldList[nCopy] = pOldList[nCopy-1];
-            pOldList[0] = nOpCode;
-
-            return sal_True;                        // list has changed
-        }
-
-    if ( !lcl_FunctionKnown( nOpCode ) )
-        return false;                           // not in function list -> no change
-
-    sal_uInt16 nNewCount = Min( (sal_uInt16)(nOldCount + 1), (sal_uInt16)LRU_MAX );
-    sal_uInt16 nNewList[LRU_MAX];
-    nNewList[0] = nOpCode;
-    for (nPos=1; nPos<nNewCount; nPos++)
-        nNewList[nPos] = pOldList[nPos-1];
-    rAppOpt.SetLRUFuncList( nNewList, nNewCount );
-
-    return sal_True;                                // list has changed
-}
-
 //      actual functions
 
 //  input - undo OK
@@ -358,331 +308,27 @@ void ScViewFunc::EnterData( SCCOL nCol, SCROW nRow, SCTAB nTab, const String& rS
 {
     ScDocument* pDoc = GetViewData()->GetDocument();
     ScMarkData& rMark = GetViewData()->GetMarkData();
-    SCTAB nSelCount = rMark.GetSelectCount();
-    SCTAB i;
     if (bRecord && !pDoc->IsUndoEnabled())
         bRecord = false;
 
+    fprintf( stderr, "EnterData '%s'\n",
+             rtl::OUStringToOString( rString, RTL_TEXTENCODING_UTF8 ).getStr() );
+
     ScDocShell* pDocSh = GetViewData()->GetDocShell();
     ScDocShellModificator aModificator( *pDocSh );
 
     ScEditableTester aTester( pDoc, nCol,nRow, nCol,nRow, rMark );
-    if (aTester.IsEditable())
-    {
-        sal_Bool bEditDeleted = false;
-        sal_uInt8 nOldScript = 0;
-
-        ScBaseCell** ppOldCells = NULL;
-        sal_Bool* pHasFormat        = NULL;
-        sal_uLong* pOldFormats      = NULL;
-        SCTAB* pTabs            = NULL;
-        SCTAB nUndoPos = 0;
-        EditTextObject* pUndoData = NULL;
-        if ( bRecord )
-        {
-            ppOldCells      = new ScBaseCell*[nSelCount];
-            pHasFormat      = new sal_Bool[nSelCount];
-            pOldFormats     = new sal_uLong[nSelCount];
-            pTabs           = new SCTAB[nSelCount];
-            nUndoPos = 0;
-
-            ScMarkData::iterator itr = rMark.begin(), itrEnd = rMark.end();
-            for (; itr != itrEnd; ++itr)
-            {
-                i = *itr;
-                pTabs[nUndoPos] = i;
-                ScBaseCell* pDocCell;
-                pDoc->GetCell( nCol, nRow, i, pDocCell );
-                if ( pDocCell )
-                {
-                    ppOldCells[nUndoPos] = pDocCell->Clone( *pDoc );
-                    if ( pDocCell->GetCellType() == CELLTYPE_EDIT )
-                        bEditDeleted = sal_True;
-
-                    sal_uInt8 nDocScript = pDoc->GetScriptType( nCol, nRow, i, pDocCell );
-                    if ( nOldScript == 0 )
-                        nOldScript = nDocScript;
-                    else if ( nDocScript != nOldScript )
-                        bEditDeleted = sal_True;
-                }
-                else
-                {
-                    ppOldCells[nUndoPos] = NULL;
-                }
-
-                const SfxPoolItem* pItem;
-                const ScPatternAttr* pPattern = pDoc->GetPattern(nCol, nRow, i);
-                if ( SFX_ITEM_SET == pPattern->GetItemSet().GetItemState(
-                                        ATTR_VALUE_FORMAT,false,&pItem) )
-                {
-                    pHasFormat[nUndoPos] = sal_True;
-                    pOldFormats[nUndoPos] = ((const SfxUInt32Item*)pItem)->GetValue();
-                }
-                else
-                    pHasFormat[nUndoPos] = false;
-
-                ++nUndoPos;
-            }
-
-            OSL_ENSURE( nUndoPos==nSelCount, "nUndoPos!=nSelCount" );
-
-            pUndoData = ( pData ? pData->Clone() : NULL );
-        }
-
-        bool bFormula = false;
-
-        // a single '=' character is handled as string (needed for special filters)
-        if ( rString.Len() > 1 )
-        {
-            if ( rString.GetChar(0) == '=' )
-            {
-                // handle as formula
-                bFormula = true;
-            }
-            else if ( rString.GetChar(0) == '+' || rString.GetChar(0) == '-' )
-            {
-                // if there is more than one leading '+' or '-' character, remove the additional ones
-                String aString( rString );
-                xub_StrLen nIndex = 1;
-                xub_StrLen nLen = aString.Len();
-                while ( nIndex < nLen && ( aString.GetChar( nIndex ) == '+' || aString.GetChar( nIndex ) == '-' ) )
-                {
-                    ++nIndex;
-                }
-                aString.Erase( 1, nIndex - 1 );
-
-                // if the remaining part without the leading '+' or '-' character
-                // is non-empty and not a number, handle as formula
-                if ( aString.Len() > 1 )
-                {
-                    sal_uInt32 nFormat = 0;
-                    pDoc->GetNumberFormat( nCol, nRow, nTab, nFormat );
-                    SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
-                    double fNumber = 0;
-                    if ( !pFormatter->IsNumberFormat( aString, nFormat, fNumber ) )
-                    {
-                        bFormula = true;
-                    }
-                }
-            }
-        }
-
-        sal_Bool bNumFmtChanged = false;
-        if ( bFormula )
-        {   // formula, compile with autoCorrection
-            i = rMark.GetFirstSelected();
-            ScAddress aPos( nCol, nRow, i );
-            ScCompiler aComp( pDoc, aPos);
-            aComp.SetGrammar(pDoc->GetGrammar());
-//2do: enable/disable autoCorrection via calcoptions
-            aComp.SetAutoCorrection( sal_True );
-            if ( rString.GetChar(0) == '+' || rString.GetChar(0) == '-' )
-            {
-                aComp.SetExtendedErrorDetection( ScCompiler::EXTENDED_ERROR_DETECTION_NAME_BREAK );
-            }
-            String aFormula( rString );
-            ScTokenArray* pArr;
-            sal_Bool bAgain;
-            do
-            {
-                bAgain = false;
-                bool bAddEqual = false;
-                ScTokenArray* pArrFirst = pArr = aComp.CompileString( aFormula );
-                bool bCorrected = aComp.IsCorrected();
-                if ( bCorrected )
-                {   // try to parse with first parser-correction
-                    pArr = aComp.CompileString( aComp.GetCorrectedFormula() );
-                }
-                if ( !pArr->GetCodeError() )
-                {
-                    bAddEqual = true;
-                    aComp.CompileTokenArray();
-                    bCorrected |= aComp.IsCorrected();
-                }
-                if ( bCorrected )
-                {
-                    String aCorrectedFormula;
-                    if ( bAddEqual )
-                    {
-                        aCorrectedFormula = '=';
-                        aCorrectedFormula += aComp.GetCorrectedFormula();
-                    }
-                    else
-                        aCorrectedFormula = aComp.GetCorrectedFormula();
-                    short nResult;
-                    if ( aCorrectedFormula.Len() == 1 )
-                        nResult = RET_NO;   // empty formula, just '='
-                    else
-                    {
-                        String aMessage( ScResId( SCSTR_FORMULA_AUTOCORRECTION ) );
-                        aMessage += aCorrectedFormula;
-                        nResult = QueryBox( GetViewData()->GetDialogParent(),
-                                                WinBits(WB_YES_NO | WB_DEF_YES),
-                                                aMessage ).Execute();
-                    }
-                    if ( nResult == RET_YES )
-                    {
-                        aFormula = aCorrectedFormula;
-                        if ( pArr != pArrFirst )
-                            delete pArrFirst;
-                        bAgain = sal_True;
-                    }
-                    else
-                    {
-                        if ( pArr != pArrFirst )
-                        {
-                            delete pArr;
-                            pArr = pArrFirst;
-                        }
-                    }
-                }
-            } while ( bAgain );
-            // to be used in multiple tabs, the formula must be compiled anew
-            // via ScFormulaCell copy-ctor because of RangeNames,
-            // the same code-array for all cells is not possible.
-            // If the array has an error, (it) must be RPN-erased in the newly generated
-            // cellst and the error be set explicitly, so that
-            // via FormulaCell copy-ctor and Interpreter it will be, when possible,
-            // ironed out again, too intelligent.. e.g.: =1))
-            sal_uInt16 nError = pArr->GetCodeError();
-            if ( !nError )
-            {
-                //  update list of recent functions with all functions that
-                //  are not within parentheses
-
-                ScModule* pScMod = SC_MOD();
-                ScAppOptions aAppOpt = pScMod->GetAppOptions();
-                sal_Bool bOptChanged = false;
-
-                formula::FormulaToken** ppToken = pArr->GetArray();
-                sal_uInt16 nTokens = pArr->GetLen();
-                sal_uInt16 nLevel = 0;
-                for (sal_uInt16 nTP=0; nTP<nTokens; nTP++)
-                {
-                    formula::FormulaToken* pTok = ppToken[nTP];
-                    OpCode eOp = pTok->GetOpCode();
-                    if ( eOp == ocOpen )
-                        ++nLevel;
-                    else if ( eOp == ocClose && nLevel )
-                        --nLevel;
-                    if ( nLevel == 0 && pTok->IsFunction() &&
-                            lcl_AddFunction( aAppOpt, sal::static_int_cast<sal_uInt16>( eOp ) ) )
-                        bOptChanged = sal_True;
-                }
-
-                if ( bOptChanged )
-                {
-                    pScMod->SetAppOptions(aAppOpt);
-                    pScMod->RecentFunctionsChanged();
-                }
-            }
-
-            ScFormulaCell aCell( pDoc, aPos, pArr,formula::FormulaGrammar::GRAM_DEFAULT, MM_NONE );
-            delete pArr;
-            sal_Bool bAutoCalc = pDoc->GetAutoCalc();
-            SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
-            ScMarkData::iterator itr = rMark.begin(), itrEnd = rMark.end();
-            for (; itr != itrEnd; ++itr)
-            {
-                i = *itr;
-                aPos.SetTab( i );
-                sal_uLong nIndex = (sal_uLong) ((SfxUInt32Item*) pDoc->GetAttr(
-                    nCol, nRow, i, ATTR_VALUE_FORMAT ))->GetValue();
-                if ( pFormatter->GetType( nIndex ) == NUMBERFORMAT_TEXT ||
-                     ( ( rString.GetChar(0) == '+' || rString.GetChar(0) == '-' ) && nError && rString.Equals( aFormula ) ) )
-                {
-                    if ( pData )
-                    {
-                        ScEditCell* pCell = new ScEditCell( pData, pDoc, NULL );
-                        pDoc->PutCell( aPos, pCell );
-                    }
-                    else
-                    {
-                        ScStringCell* pCell = new ScStringCell( aFormula );
-                        pDoc->PutCell( aPos, pCell );
-                    }
-                }
-                else
-                {
-                    DELETEZ(pUndoData);
-                    ScFormulaCell* pCell = new ScFormulaCell( aCell, *pDoc, aPos );
-                    if ( nError )
-                    {
-                        pCell->GetCode()->DelRPN();
-                        pCell->SetErrCode( nError );
-                        if(pCell->GetCode()->IsHyperLink())
-                            pCell->GetCode()->SetHyperLink(false);
-                    }
-                    pDoc->PutCell( aPos, pCell );
-                    if ( !bAutoCalc )
-                    {   // calculate just the cell once and set Dirty again
-                        pCell->Interpret();
-                        pCell->SetDirtyVar();
-                        pDoc->PutInFormulaTree( pCell );
-                    }
-                }
-            }
-        }
-        else
-        {
-            ScMarkData::iterator itr = rMark.begin(), itrEnd = rMark.end();
-            for (; itr != itrEnd; ++itr)
-                if (pDoc->SetString( nCol, nRow, *itr, rString ))
-                    bNumFmtChanged = true;
-        }
-
-        //  row height must be changed if new text has a different script type
-        ScMarkData::iterator itr = rMark.begin(), itrEnd = rMark.end();
-        for (; itr != itrEnd && !bEditDeleted; ++itr)
-            if ( pDoc->GetScriptType( nCol, nRow, *itr ) != nOldScript )
-                bEditDeleted = true;
-
-        HideAllCursors();
-
-        if (bEditDeleted || pDoc->HasAttrib( nCol, nRow, nTab, nCol, nRow, nTab, HASATTR_NEEDHEIGHT ))
-            AdjustRowHeight(nRow,nRow);
-
-        sal_Bool bAutoFormat = TestFormatArea(nCol, nRow, nTab, bNumFmtChanged);
-        if (bAutoFormat)
-            DoAutoAttributes(nCol, nRow, nTab, bNumFmtChanged, bRecord);
-
-        if ( bRecord )
-        {   // because of ChangeTrack current first
-             pDocSh->GetUndoManager()->AddUndoAction(
-                new ScUndoEnterData( pDocSh, nCol, nRow, nTab, nUndoPos, pTabs,
-                                     ppOldCells, pHasFormat, pOldFormats,
-                                     rString, pUndoData ) );
-        }
-
-        itr = rMark.begin();
-        for (; itr != itrEnd; ++itr)
-            pDocSh->PostPaintCell( nCol, nRow, *itr );
-
-        ShowAllCursors();
-
-        pDocSh->UpdateOle(GetViewData());
-
-        // #i97876# Spreadsheet data changes are not notified
-        ScModelObj* pModelObj = ScModelObj::getImplementation( pDocSh->GetModel() );
-        if ( pModelObj && pModelObj->HasChangesListeners() )
-        {
-            ScRangeList aChangeRanges;
-            itr = rMark.begin();
-            for (; itr != itrEnd; ++itr)
-            {
-                aChangeRanges.Append( ScRange( nCol, nRow, *itr ) );
-            }
-            pModelObj->NotifyChanges( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "cell-change" ) ), aChangeRanges );
-        }
-
-        aModificator.SetDocumentModified();
-        lcl_PostRepaintCondFormat( pDoc->GetCondFormat( nCol, nRow, nTab ), pDocSh );
-    }
-    else
+    if (!aTester.IsEditable())
     {
         ErrorMessage(aTester.GetMessageId());
         PaintArea( nCol, nRow, nCol, nRow );        // possibly the edit-engine is still painted there
+        return;
     }
+    pDocSh->GetDocFunc().EnterUserDataTabs( nCol, nRow, nTab, rMark, rString, bRecord, pData );
+
+    pDocSh->UpdateOle(GetViewData());
+    aModificator.SetDocumentModified();
+    lcl_PostRepaintCondFormat( pDoc->GetCondFormat( nCol, nRow, nTab ), pDocSh );
 }
 
 // enter value in single cell (on nTab only)


More information about the Libreoffice-commits mailing list