[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