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.me...@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) _______________________________________________ Libreoffice-commits mailing list Libreoffice-commits@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits