cui/source/inc/numpages.hxx               |    2 
 cui/source/tabpages/numpages.cxx          |  353 --------------------------
 include/svx/numberingpreview.hxx          |   17 -
 sc/source/ui/inc/viewfunc.hxx             |    7 
 sc/source/ui/view/viewfunc.cxx            |  402 ++++++++++++++++++------------
 sd/source/ui/inc/BulletAndPositionDlg.hxx |    2 
 svx/source/dialog/pagenumberlistbox.cxx   |  385 ++++++++++++++++++++++++++++
 7 files changed, 643 insertions(+), 525 deletions(-)

New commits:
commit b39c6082aa975ed8e5696c3dc24c3025ed07bbb6
Author:     codewithvk <vivek.jav...@collabora.com>
AuthorDate: Thu Jan 11 10:27:27 2024 +0530
Commit:     Caolán McNamara <caolan.mcnam...@collabora.com>
CommitDate: Wed Jan 31 10:33:48 2024 +0100

    Implement Async AutoCorrectQuery Dialogs for Formula Check in calc
    
    Key changes include:
    
    1. Decomposition into Four Methods: The core logic of formula processing 
`ScViewFunc::EnterData` has been divided into four distinct methods: 
`parseAndCorrectFormula`, `runAutoCorrectQueryAsync`, 
`finalizeFormulaProcessing`, and `performAutoFormatAndUpdate`. This modular 
approach improves code readability and maintainability.
    
    2. Introduction of `FormulaProcessingContext` Struct: To manage the 
complexities of asynchronous behavior and parameter passing, a new struct 
`FormulaProcessingContext` has been introduced. It acts as a central state 
holder, ensuring parameter persistence throughout the asynchronous operations 
and avoiding scope-related errors.
    
    3. Recursive Dependency and Loop Replacement: The methods 
`parseAndCorrectFormula` and `runAutoCorrectQueryAsync` are interdependent and 
recursively call each other. This recursive strategy effectively replaces the 
previous `do while` loop in the code, streamlining the process of formula 
correction.
    
    4. Asynchronous Dialog Invocation: The `runAutoCorrectQueryAsync` method 
now handles the asynchronous triggering of AutoCorrectQuery dialogs. This 
change significantly improves the user experience by preventing UI freezes 
during formula processing.
    
    Overall, this commit achieves the goal of making AutoCorrectQuery dialogs 
asynchronous while refactoring `ScViewFunc::EnterData` for better code 
structure and performance.
    
    Signed-off-by: codewithvk <vivek.jav...@collabora.com>
    Change-Id: If159b98d54c0eaed41789eca7913a929b1e19c1c
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162740
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com>

diff --git a/sc/source/ui/inc/viewfunc.hxx b/sc/source/ui/inc/viewfunc.hxx
index 117cd407bbd8..82d202b2df8e 100644
--- a/sc/source/ui/inc/viewfunc.hxx
+++ b/sc/source/ui/inc/viewfunc.hxx
@@ -345,6 +345,10 @@ public:
     void            OnLOKInsertDeleteRow(SCROW nStartRow, tools::Long nOffset);
     void            OnLOKSetWidthOrHeight(SCCOLROW nStart, bool bWidth);
 
+    bool            TestFormatArea( SCCOL nCol, SCROW nRow, SCTAB nTab, bool 
bAttrChanged );
+    void            DoAutoAttributes( SCCOL nCol, SCROW nRow, SCTAB nTab,
+                                        bool bAttrChanged );
+
                                                 // Internal helper functions
 protected:
     static void     UpdateLineAttrs( ::editeng::SvxBorderLine&        rLine,
@@ -381,9 +385,6 @@ private:
     sal_uInt16      GetOptimalColWidth( SCCOL nCol, SCTAB nTab, bool bFormula 
);
 
     void            StartFormatArea();
-    bool            TestFormatArea( SCCOL nCol, SCROW nRow, SCTAB nTab, bool 
bAttrChanged );
-    void            DoAutoAttributes( SCCOL nCol, SCROW nRow, SCTAB nTab,
-                                        bool bAttrChanged );
 
     void            MarkAndJumpToRanges(const ScRangeList& rRanges);
     void            CopyAutoSpellData( FillDir eDir, SCCOL nStartCol, SCROW 
nStartRow,
diff --git a/sc/source/ui/view/viewfunc.cxx b/sc/source/ui/view/viewfunc.cxx
index a6d28ecbc37b..ed5de281b5bc 100644
--- a/sc/source/ui/view/viewfunc.cxx
+++ b/sc/source/ui/view/viewfunc.cxx
@@ -136,6 +136,46 @@ ScViewFunc::~ScViewFunc()
 
 namespace {
 
+struct FormulaProcessingContext
+{
+    std::shared_ptr<ScAddress> aPos;
+    std::shared_ptr<ScCompiler> aComp;
+    std::shared_ptr<ScDocShellModificator> aModificator;
+    std::shared_ptr<ScTokenArray> pArr;
+    std::shared_ptr<ScTokenArray> pArrFirst;
+
+    const EditTextObject* pData;
+    ScMarkData aMark;
+    ScViewFunc& rViewFunc;
+
+    OUString aCorrectedFormula;
+    OUString aFormula;
+    OUString aString;
+
+    SCCOL nCol;
+    SCROW nRow;
+    SCTAB nTab;
+
+    bool bMatrixExpand;
+    bool bNumFmtChanged;
+    bool bRecord;
+
+    ScViewData& GetViewData() const
+    {
+        return rViewFunc.GetViewData();
+    }
+
+    ScDocFunc& GetDocFunc() const
+    {
+        return GetViewData().GetDocFunc();
+    }
+
+    ScDocument& GetDoc() const
+    {
+        return GetViewData().GetDocument();
+    }
+};
+
 void collectUIInformation(std::map<OUString, OUString>&& aParameters, const 
OUString& rAction)
 {
     EventDescription aDescription;
@@ -358,7 +398,7 @@ static bool lcl_AddFunction( ScAppOptions& rAppOpt, 
sal_uInt16 nOpCode )
 
 namespace HelperNotifyChanges
 {
-    static void NotifyIfChangesListeners(const ScDocShell &rDocShell, 
ScMarkData& rMark,
+    static void NotifyIfChangesListeners(const ScDocShell &rDocShell, const 
ScMarkData& rMark,
                                          SCCOL nCol, SCROW nRow, const 
OUString& rType = "cell-change")
     {
         ScModelObj* pModelObj = rDocShell.GetModel();
@@ -398,134 +438,41 @@ namespace
         }
     };
 }
-
-//      actual functions
-
-//  input - undo OK
-void ScViewFunc::EnterData( SCCOL nCol, SCROW nRow, SCTAB nTab,
-                            const OUString& rString,
-                            const EditTextObject* pData,
-                            bool bMatrixExpand )
+namespace
 {
-    ScDocument& rDoc = GetViewData().GetDocument();
-    ScMarkData rMark(GetViewData().GetMarkData());
-    bool bRecord = rDoc.IsUndoEnabled();
-    SCTAB i;
+    void runAutoCorrectQueryAsync(std::shared_ptr<FormulaProcessingContext> 
context);
 
-    ScDocShell* pDocSh = GetViewData().GetDocShell();
-    ScDocFunc &rFunc = GetViewData().GetDocFunc();
-    ScDocShellModificator aModificator( *pDocSh );
-
-    ScEditableTester aTester( rDoc, nCol,nRow, nCol,nRow, rMark );
-    if (!aTester.IsEditable())
+    void performAutoFormatAndUpdate(std::u16string_view rString, const 
ScMarkData& rMark, SCCOL nCol,
+                                    SCROW nRow, SCTAB nTab, bool 
bNumFmtChanged, bool bRecord,
+                                    const 
std::shared_ptr<ScDocShellModificator>& pModificator,
+                                    ScViewFunc& rViewFunc)
     {
-        ErrorMessage(aTester.GetMessageId());
-        PaintArea(nCol, nRow, nCol, nRow);        // possibly the edit-engine 
is still painted there
-        return;
-    }
+        bool bAutoFormat = rViewFunc.TestFormatArea(nCol, nRow, nTab, 
bNumFmtChanged);
 
-    if ( bRecord )
-        rFunc.EnterListAction( STR_UNDO_ENTERDATA );
+        if (bAutoFormat)
+            rViewFunc.DoAutoAttributes(nCol, nRow, nTab, bNumFmtChanged);
 
-    bool bFormula = false;
+        ScViewData& rViewData = rViewFunc.GetViewData();
+        ScDocShell* pDocSh = rViewData.GetDocShell();
+        pDocSh->UpdateOle(rViewData);
 
-    // do not check formula if it is a text cell
-    sal_uInt32 format = rDoc.GetNumberFormat( nCol, nRow, nTab );
-    SvNumberFormatter* pFormatter = rDoc.GetFormatTable();
-    // a single '=' character is handled as string (needed for special filters)
-    if ( pFormatter->GetType(format) != SvNumFormatType::TEXT && 
rString.getLength() > 1 )
-    {
-        if ( rString[0] == '=' )
+        const OUString aType(rString.empty() ? u"delete-content" : 
u"cell-change");
+        HelperNotifyChanges::NotifyIfChangesListeners(*pDocSh, rMark, nCol, 
nRow, aType);
+
+        if (bRecord)
         {
-            // handle as formula
-            bFormula = true;
+            ScDocFunc &rFunc = rViewData.GetDocFunc();
+            rFunc.EndListAction();
         }
-        else if ( rString[0] == '+' || rString[0] == '-' )
-        {
-            // if there is more than one leading '+' or '-' character, remove 
the additional ones
-            sal_Int32 nIndex = 1;
-            sal_Int32 nLen = rString.getLength();
-            while ( nIndex < nLen && ( rString[ nIndex ] == '+' || rString[ 
nIndex ] == '-' ) )
-            {
-                ++nIndex;
-            }
-            OUString aString = rString.replaceAt( 1, nIndex - 1, u"" );
 
-            // if the remaining part without the leading '+' or '-' character
-            // is non-empty and not a number, handle as formula
-            if ( aString.getLength() > 1 )
-            {
-                double fNumber = 0;
-                if ( !pFormatter->IsNumberFormat( aString, format, fNumber ) )
-                {
-                    bFormula = true;
-                }
-            }
-        }
+        pModificator->SetDocumentModified();
+        ScDocument& rDoc = rViewData.GetDocument();
+        lcl_PostRepaintCondFormat(rDoc.GetCondFormat(nCol, nRow, nTab), 
pDocSh);
+        lcl_PostRepaintSparkLine(rDoc.GetSparklineList(nTab), ScRange(nCol, 
nRow, nTab), pDocSh);
     }
 
-    bool bNumFmtChanged = false;
-    if ( bFormula )
-    {   // formula, compile with autoCorrection
-        i = rMark.GetFirstSelected();
-        ScAddress aPos( nCol, nRow, i );
-        ScCompiler aComp( rDoc, aPos, rDoc.GetGrammar(), true, false );
-//2do: enable/disable autoCorrection via calcoptions
-        aComp.SetAutoCorrection( true );
-        if ( rString[0] == '+' || rString[0] == '-' )
-        {
-            aComp.SetExtendedErrorDetection( 
ScCompiler::EXTENDED_ERROR_DETECTION_NAME_BREAK );
-        }
-        OUString aFormula( rString );
-        std::unique_ptr< ScTokenArray > pArr;
-        bool bAgain;
-        do
-        {
-            bAgain = false;
-            bool bAddEqual = false;
-            pArr = aComp.CompileString( aFormula );
-            bool bCorrected = aComp.IsCorrected();
-            std::unique_ptr< ScTokenArray > pArrFirst;
-            if ( bCorrected )
-            {   // try to parse with first parser-correction
-                pArrFirst = std::move( pArr );
-                pArr = aComp.CompileString( aComp.GetCorrectedFormula() );
-            }
-            if ( pArr->GetCodeError() == FormulaError::NONE )
-            {
-                bAddEqual = true;
-                aComp.CompileTokenArray();
-                bCorrected |= aComp.IsCorrected();
-            }
-            if ( bCorrected )
-            {
-                OUString aCorrectedFormula;
-                if ( bAddEqual )
-                {
-                    aCorrectedFormula = "=" + aComp.GetCorrectedFormula();
-                }
-                else
-                    aCorrectedFormula = aComp.GetCorrectedFormula();
-                short nResult;
-                if ( aCorrectedFormula.getLength() == 1 )
-                    nResult = RET_NO;   // empty formula, just '='
-                else
-                {
-                    AutoCorrectQuery 
aQueryBox(GetViewData().GetDialogParent(), aCorrectedFormula);
-                    nResult = aQueryBox.run();
-                }
-                if ( nResult == RET_YES )
-                {
-                    aFormula = aCorrectedFormula;
-                    bAgain = true;
-                }
-                else
-                {
-                    if ( pArrFirst )
-                        pArr = std::move( pArrFirst );
-                }
-            }
-        } while ( bAgain );
+    void finalizeFormulaProcessing(std::shared_ptr<FormulaProcessingContext> 
context)
+    {
         // 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.
@@ -533,7 +480,7 @@ void ScViewFunc::EnterData( SCCOL nCol, SCROW nRow, SCTAB 
nTab,
         // cells 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))
-        FormulaError nError = pArr->GetCodeError();
+        FormulaError nError = context->pArr->GetCodeError();
         if ( nError == FormulaError::NONE )
         {
             //  update list of recent functions with all functions that
@@ -543,8 +490,8 @@ void ScViewFunc::EnterData( SCCOL nCol, SCROW nRow, SCTAB 
nTab,
             ScAppOptions aAppOpt = pScMod->GetAppOptions();
             bool bOptChanged = false;
 
-            formula::FormulaToken** ppToken = pArr->GetArray();
-            sal_uInt16 nTokens = pArr->GetLen();
+            formula::FormulaToken** ppToken = context->pArr->GetArray();
+            sal_uInt16 nTokens = context->pArr->GetLen();
             sal_uInt16 nLevel = 0;
             for (sal_uInt16 nTP=0; nTP<nTokens; nTP++)
             {
@@ -564,53 +511,55 @@ void ScViewFunc::EnterData( SCCOL nCol, SCROW nRow, SCTAB 
nTab,
                 pScMod->SetAppOptions(aAppOpt);
             }
 
-            if (bMatrixExpand)
+            if (context->bMatrixExpand)
             {
                 // If the outer function/operator returns an array/matrix then
                 // enter a matrix formula. ScViewFunc::EnterMatrix() takes care
                 // of selection/mark of the result dimensions or preselected
                 // mark. If the user wanted less or a single cell then should
                 // mark such prior to entering the formula.
-                const formula::FormulaToken* pToken = pArr->LastRPNToken();
+                const formula::FormulaToken* pToken = 
context->pArr->LastRPNToken();
                 if (pToken && (formula::FormulaCompiler::IsMatrixFunction( 
pToken->GetOpCode())
                             || pToken->IsInForceArray()))
                 {
                     // Discard this (still empty here) Undo action,
                     // EnterMatrix() will create its own.
-                    if (bRecord)
-                        rFunc.EndListAction();
+                    if (context->bRecord)
+                        context->GetDocFunc().EndListAction();
 
                     // Use corrected formula string.
-                    EnterMatrix( aFormula, rDoc.GetGrammar());
+                    context->rViewFunc.EnterMatrix( context->aFormula, 
context->GetDoc().GetGrammar());
 
                     return;
                 }
             }
         }
 
-        ScFormulaCell aCell(rDoc, aPos, std::move( pArr ), 
formula::FormulaGrammar::GRAM_DEFAULT, ScMatrixMode::NONE);
+        ScFormulaCell aCell(context->GetDoc(), *context->aPos, 
std::move(*context->pArr), formula::FormulaGrammar::GRAM_DEFAULT, 
ScMatrixMode::NONE);
 
-        for (const auto& rTab : rMark)
+        SCTAB i;
+        SvNumberFormatter* pFormatter = context->GetDoc().GetFormatTable();
+        for (const auto& rTab : context->aMark)
         {
             i = rTab;
-            aPos.SetTab( i );
-            const sal_uInt32 nIndex = rDoc.GetAttr(
-                        nCol, nRow, i, ATTR_VALUE_FORMAT )->GetValue();
+            context->aPos->SetTab( i );
+            const sal_uInt32 nIndex = context->GetDoc().GetAttr(
+                        context->nCol, context->nRow, i, ATTR_VALUE_FORMAT 
)->GetValue();
             const SvNumFormatType nType = pFormatter->GetType( nIndex);
             if (nType == SvNumFormatType::TEXT ||
-                    ((rString[0] == '+' || rString[0] == '-') && nError != 
FormulaError::NONE && rString == aFormula))
+                    ((context->aString[0] == '+' || context->aString[0] == 
'-') && nError != FormulaError::NONE && context->aString == context->aFormula))
             {
-                if ( pData )
+                if ( context->pData )
                 {
-                    // A clone of pData will be stored in the cell.
-                    rFunc.SetEditCell(aPos, *pData, true);
+                    // A clone of context->pData will be stored in the cell.
+                    context->GetDocFunc().SetEditCell(*(context->aPos), 
*context->pData, true);
                 }
                 else
-                    rFunc.SetStringCell(aPos, aFormula, true);
+                    context->GetDocFunc().SetStringCell(*(context->aPos), 
context->aFormula, true);
             }
             else
             {
-                ScFormulaCell* pCell = new ScFormulaCell( aCell, rDoc, aPos );
+                ScFormulaCell* pCell = new ScFormulaCell( aCell, 
context->GetDoc(), *(context->aPos) );
                 if ( nError != FormulaError::NONE )
                 {
                     pCell->GetCode()->DelRPN();
@@ -627,17 +576,166 @@ void ScViewFunc::EnterData( SCCOL nCol, SCROW nRow, 
SCTAB nTab,
                     const SvNumberformat* pEntry = pFormatter->GetEntry( 
nIndex);
                     const LanguageType nLang = (pEntry ? pEntry->GetLanguage() 
: ScGlobal::eLnge);
                     const sal_uInt32 nFormat = pFormatter->GetStandardFormat( 
SvNumFormatType::NUMBER, nLang);
-                    ScPatternAttr aPattern(rDoc.getCellAttributeHelper());
+                    ScPatternAttr 
aPattern(context->GetDoc().getCellAttributeHelper());
                     aPattern.GetItemSet().Put( SfxUInt32Item( 
ATTR_VALUE_FORMAT, nFormat));
-                    ScMarkData aMark(rDoc.GetSheetLimits());
+                    ScMarkData aMark(context->GetDoc().GetSheetLimits());
                     aMark.SelectTable( i, true);
-                    aMark.SetMarkArea( ScRange( aPos));
-                    rFunc.ApplyAttributes( aMark, aPattern, false);
-                    bNumFmtChanged = true;
+                    aMark.SetMarkArea( ScRange( *(context->aPos)));
+                    context->GetDocFunc().ApplyAttributes( aMark, aPattern, 
false);
+                    context->bNumFmtChanged = true;
                 }
-                rFunc.SetFormulaCell(aPos, pCell, true);
+                context->GetDocFunc().SetFormulaCell(*(context->aPos), pCell, 
true);
             }
         }
+
+        performAutoFormatAndUpdate(context->aString, context->aMark, 
context->nCol,
+                                   context->nRow, context->nTab, 
context->bNumFmtChanged,
+                                   context->bRecord, context->aModificator, 
context->rViewFunc);
+    }
+
+    void parseAndCorrectFormula(std::shared_ptr<FormulaProcessingContext> 
context)
+    {
+        bool bAddEqual = false;
+        context->pArr = context->aComp->CompileString(context->aFormula);
+        bool bCorrected = context->aComp->IsCorrected();
+
+        if (bCorrected) {
+            context->pArrFirst = context->pArr;
+            context->pArr = 
context->aComp->CompileString(context->aComp->GetCorrectedFormula());
+        }
+
+        if (context->pArr->GetCodeError() == FormulaError::NONE) {
+            bAddEqual = true;
+            context->aComp->CompileTokenArray();
+            bCorrected |= context->aComp->IsCorrected();
+        }
+
+        if (bCorrected) {
+            context->aCorrectedFormula = bAddEqual ? "=" + 
context->aComp->GetCorrectedFormula()
+                                                   : 
context->aComp->GetCorrectedFormula();
+            if (context->aCorrectedFormula.getLength() == 1) {
+                // empty formula, just '='
+                if (context->pArrFirst)
+                    context->pArr = context->pArrFirst;
+            }
+            else
+            {
+                runAutoCorrectQueryAsync(context);
+                return;
+            }
+        }
+        finalizeFormulaProcessing(context);
+    }
+
+    void runAutoCorrectQueryAsync(std::shared_ptr<FormulaProcessingContext> 
context)
+    {
+        auto aQueryBox = 
std::make_shared<AutoCorrectQuery>(context->GetViewData().GetDialogParent(), 
context->aCorrectedFormula);
+        weld::DialogController::runAsync(aQueryBox, [context] (int nResult)
+        {
+            if (nResult == RET_YES) {
+                context->aFormula = context->aCorrectedFormula;
+                parseAndCorrectFormula(context);
+            } else {
+                if (context->pArrFirst)
+                    context->pArr = context->pArrFirst;
+
+                finalizeFormulaProcessing(context);
+            }
+        });
+    }
+}
+
+//      actual functions
+
+//  input - undo OK
+void ScViewFunc::EnterData( SCCOL nCol, SCROW nRow, SCTAB nTab,
+                            const OUString& rString,
+                            const EditTextObject* pData,
+                            bool bMatrixExpand )
+{
+    ScDocument& rDoc = GetViewData().GetDocument();
+    ScMarkData rMark(GetViewData().GetMarkData());
+    bool bRecord = rDoc.IsUndoEnabled();
+    SCTAB i;
+
+    ScDocShell* pDocSh = GetViewData().GetDocShell();
+    ScDocFunc &rFunc = GetViewData().GetDocFunc();
+    std::shared_ptr<ScDocShellModificator> xModificator = 
std::make_shared<ScDocShellModificator>(*pDocSh);
+
+    ScEditableTester aTester( rDoc, nCol,nRow, nCol,nRow, rMark );
+    if (!aTester.IsEditable())
+    {
+        ErrorMessage(aTester.GetMessageId());
+        PaintArea(nCol, nRow, nCol, nRow);        // possibly the edit-engine 
is still painted there
+        return;
+    }
+
+    if ( bRecord )
+        rFunc.EnterListAction( STR_UNDO_ENTERDATA );
+
+    bool bFormula = false;
+
+    // do not check formula if it is a text cell
+    sal_uInt32 format = rDoc.GetNumberFormat( nCol, nRow, nTab );
+    SvNumberFormatter* pFormatter = rDoc.GetFormatTable();
+    // a single '=' character is handled as string (needed for special filters)
+    if ( pFormatter->GetType(format) != SvNumFormatType::TEXT && 
rString.getLength() > 1 )
+    {
+        if ( rString[0] == '=' )
+        {
+            // handle as formula
+            bFormula = true;
+        }
+        else if ( rString[0] == '+' || rString[0] == '-' )
+        {
+            // if there is more than one leading '+' or '-' character, remove 
the additional ones
+            sal_Int32 nIndex = 1;
+            sal_Int32 nLen = rString.getLength();
+            while ( nIndex < nLen && ( rString[ nIndex ] == '+' || rString[ 
nIndex ] == '-' ) )
+            {
+                ++nIndex;
+            }
+            OUString aString = rString.replaceAt( 1, nIndex - 1, u"" );
+
+            // if the remaining part without the leading '+' or '-' character
+            // is non-empty and not a number, handle as formula
+            if ( aString.getLength() > 1 )
+            {
+                double fNumber = 0;
+                if ( !pFormatter->IsNumberFormat( aString, format, fNumber ) )
+                {
+                    bFormula = true;
+                }
+            }
+        }
+    }
+
+    bool bNumFmtChanged = false;
+    if ( bFormula )
+    {   // formula, compile with autoCorrection
+        i = rMark.GetFirstSelected();
+        auto aPosPtr = std::make_shared<ScAddress>(nCol, nRow, i);
+        auto aCompPtr = std::make_shared<ScCompiler>(rDoc, *aPosPtr, 
rDoc.GetGrammar(), true, false);
+
+        //2do: enable/disable autoCorrection via calcoptions
+        aCompPtr->SetAutoCorrection( true );
+        if ( rString[0] == '+' || rString[0] == '-' )
+        {
+            aCompPtr->SetExtendedErrorDetection( 
ScCompiler::EXTENDED_ERROR_DETECTION_NAME_BREAK );
+        }
+
+        OUString aFormula( rString );
+        std::shared_ptr< ScTokenArray > pArr;
+
+        FormulaProcessingContext context_instance{
+            aPosPtr, aCompPtr, xModificator,  pArr,           nullptr,        
pData,
+            rMark,   *this,    OUString(),    aFormula,       rString,        
nCol,
+            nRow,    nTab,     bMatrixExpand, bNumFmtChanged, bRecord
+        };
+
+        std::shared_ptr<FormulaProcessingContext> context = 
std::make_shared<FormulaProcessingContext>(context_instance);
+
+        parseAndCorrectFormula(context);
     }
     else
     {
@@ -666,24 +764,8 @@ void ScViewFunc::EnterData( SCCOL nCol, SCROW nRow, SCTAB 
nTab,
                 bNumFmtChanged = true;
             }
         }
+        performAutoFormatAndUpdate(rString, rMark, nCol, nRow, nTab, 
bNumFmtChanged, bRecord, xModificator, *this);
     }
-
-    bool bAutoFormat = TestFormatArea(nCol, nRow, nTab, bNumFmtChanged);
-
-    if (bAutoFormat)
-        DoAutoAttributes(nCol, nRow, nTab, bNumFmtChanged);
-
-    pDocSh->UpdateOle(GetViewData());
-
-    const OUString aType(rString.isEmpty() ? u"delete-content" : 
u"cell-change");
-    HelperNotifyChanges::NotifyIfChangesListeners(*pDocSh, rMark, nCol, nRow, 
aType);
-
-    if ( bRecord )
-        rFunc.EndListAction();
-
-    aModificator.SetDocumentModified();
-    lcl_PostRepaintCondFormat( rDoc.GetCondFormat( nCol, nRow, nTab ), pDocSh 
);
-    lcl_PostRepaintSparkLine(rDoc.GetSparklineList(nTab), ScRange(nCol, nRow, 
nTab), pDocSh);
 }
 
 // enter value in single cell (on nTab only)
commit a830a34d6d21656d00996c002b0dedf37b7545c0
Author:     Caolán McNamara <caolan.mcnam...@collabora.com>
AuthorDate: Tue Jan 30 11:54:18 2024 +0000
Commit:     Caolán McNamara <caolan.mcnam...@collabora.com>
CommitDate: Wed Jan 31 10:33:37 2024 +0100

    move SvxNumberingPreview out of cui
    
    the point of cui was to have no headers, so move this
    SvxNumberingPreview out of cui and into svx
    
    Change-Id: I83edbcdc8d8b95dbea734bdef4a93f6ec8ee50e6
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162748
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com>

diff --git a/cui/source/inc/numpages.hxx b/cui/source/inc/numpages.hxx
index d693b9e0324f..ec7b72ac71fb 100644
--- a/cui/source/inc/numpages.hxx
+++ b/cui/source/inc/numpages.hxx
@@ -25,9 +25,9 @@
 #include <editeng/numdef.hxx>
 #include <editeng/svxenum.hxx>
 #include <svtools/ctrlbox.hxx>
+#include <svx/numberingpreview.hxx>
 #include <vcl/customweld.hxx>
 #include <vcl/timer.hxx>
-#include <cui/numberingpreview.hxx>
 
 #define MN_GALLERY_ENTRY 100
 
diff --git a/cui/source/tabpages/numpages.cxx b/cui/source/tabpages/numpages.cxx
index caf44cb7ecfd..7fbe8b393608 100644
--- a/cui/source/tabpages/numpages.cxx
+++ b/cui/source/tabpages/numpages.cxx
@@ -2151,359 +2151,6 @@ void SvxNumOptionsTabPage::EditModifyHdl_Impl(const 
weld::Entry* pEdit)
     SetModified();
 }
 
-static tools::Long lcl_DrawGraphic(VirtualDevice& rVDev, const SvxNumberFormat 
&rFmt, tools::Long nXStart,
-                        tools::Long nYMiddle, tools::Long nDivision)
-{
-    const SvxBrushItem* pBrushItem = rFmt.GetBrush();
-    tools::Long nRet = 0;
-    if(pBrushItem)
-    {
-        const Graphic* pGrf = pBrushItem->GetGraphic();
-        if(pGrf)
-        {
-            Size aGSize( rFmt.GetGraphicSize() );
-            aGSize.setWidth( aGSize.Width() / nDivision );
-            nRet = aGSize.Width();
-            aGSize.setHeight( aGSize.Height() / nDivision );
-            pGrf->Draw(rVDev, Point(nXStart,nYMiddle - ( aGSize.Height() / 2) 
),
-                       rVDev.PixelToLogic( aGSize ) );
-        }
-    }
-    return nRet;
-
-}
-
-static tools::Long lcl_DrawBullet(VirtualDevice* pVDev,
-            const SvxNumberFormat& rFmt, tools::Long nXStart,
-            tools::Long nYStart, const Size& rSize)
-{
-    vcl::Font aTmpFont(pVDev->GetFont());
-
-    // via Uno it's possible that no font has been set!
-    vcl::Font aFont(rFmt.GetBulletFont() ? *rFmt.GetBulletFont() : aTmpFont);
-    Size aTmpSize(rSize);
-    aTmpSize.setWidth( aTmpSize.Width() * ( rFmt.GetBulletRelSize()) );
-    aTmpSize.setWidth( aTmpSize.Width() / 100 ) ;
-    aTmpSize.setHeight( aTmpSize.Height() * ( rFmt.GetBulletRelSize()) );
-    aTmpSize.setHeight( aTmpSize.Height() / 100 ) ;
-    // in case of a height of zero it is drawn in original height
-    if(!aTmpSize.Height())
-        aTmpSize.setHeight( 1 );
-    aFont.SetFontSize(aTmpSize);
-    aFont.SetTransparent(true);
-    Color aBulletColor = rFmt.GetBulletColor();
-    if (aBulletColor == COL_AUTO)
-        aBulletColor = pVDev->GetBackgroundColor().IsDark() ? COL_WHITE : 
COL_BLACK;
-    else if (pVDev->GetBackgroundColor().IsDark() == aBulletColor.IsDark())
-        aBulletColor = pVDev->GetBackgroundColor().IsDark() ? COL_WHITE : 
COL_BLACK;
-    aFont.SetColor(aBulletColor);
-    pVDev->SetFont( aFont );
-    sal_UCS4 cChar = rFmt.GetBulletChar();
-    OUString aText(&cChar, 1);
-    tools::Long nY = nYStart;
-    nY -= ((aTmpSize.Height() - rSize.Height())/ 2);
-    pVDev->DrawText( Point(nXStart, nY), aText );
-    tools::Long nRet = pVDev->GetTextWidth(aText);
-
-    pVDev->SetFont(aTmpFont);
-    return nRet;
-}
-
-SvxNumberingPreview::SvxNumberingPreview()
-    : pActNum(nullptr)
-    , bPosition(false)
-    , nActLevel(SAL_MAX_UINT16)
-{
-}
-
-// paint preview of numeration
-void SvxNumberingPreview::Paint(vcl::RenderContext& rRenderContext, const 
::tools::Rectangle& /*rRect*/)
-{
-    Size aSize(rRenderContext.PixelToLogic(GetOutputSizePixel()));
-
-    // Use default document and font colors to create preview
-    const Color aBackColor = 
svtools::ColorConfig().GetColorValue(svtools::DOCCOLOR).nColor;
-    const Color aTextColor = 
svtools::ColorConfig().GetColorValue(svtools::FONTCOLOR).nColor;
-
-    ScopedVclPtrInstance<VirtualDevice> pVDev(rRenderContext);
-    pVDev->EnableRTL(rRenderContext.IsRTLEnabled());
-    pVDev->SetMapMode(rRenderContext.GetMapMode());
-    pVDev->SetOutputSize(aSize);
-
-    Color aLineColor(COL_LIGHTGRAY);
-    if (aLineColor == aBackColor)
-        aLineColor.Invert();
-    pVDev->SetLineColor(aLineColor);
-    pVDev->SetFillColor(aBackColor);
-    pVDev->SetBackground(Wallpaper(aBackColor));
-    pVDev->DrawWallpaper(pVDev->GetOutputRectPixel(), pVDev->GetBackground());
-
-    if (pActNum)
-    {
-        tools::Long nWidthRelation = 30; // chapter dialog
-
-        // height per level
-        tools::Long nXStep = aSize.Width() / (pActNum->GetLevelCount() > 1 ? 3 
* pActNum->GetLevelCount() : 3);
-        if (pActNum->GetLevelCount() < 10)
-            nXStep /= 2;
-        tools::Long nYStart = 4;
-        // the whole height mustn't be used for a single level
-        tools::Long nYStep = (aSize.Height() - 6)/ (pActNum->GetLevelCount() > 
1 ? pActNum->GetLevelCount() : 5);
-
-        aStdFont = OutputDevice::GetDefaultFont(DefaultFontType::UI_SANS, 
MsLangId::getConfiguredSystemLanguage(), GetDefaultFontFlags::OnlyOne);
-        aStdFont.SetColor(aTextColor);
-        aStdFont.SetFillColor(aBackColor);
-
-        tools::Long nFontHeight = nYStep * 6 / 10;
-        if (bPosition)
-            nFontHeight = nYStep * 15 / 10;
-        aStdFont.SetFontSize(Size( 0, nFontHeight ));
-
-        SvxNodeNum aNum;
-        sal_uInt16 nPreNum = pActNum->GetLevel(0).GetStart();
-
-        if (bPosition)
-        {
-            // When bPosition == true, draw the preview used in the Writer's 
"Position" tab
-            // This is not used in Impress/Draw
-
-            tools::Long nLineHeight = nFontHeight * 8 / 7;
-            sal_uInt8 nStart = 0;
-            while (!(nActLevel & (1<<nStart)))
-            {
-                nStart++;
-            }
-            if (nStart)
-                nStart--;
-            sal_uInt8 nEnd = std::min(sal_uInt8(nStart + 3), 
sal_uInt8(pActNum->GetLevelCount()));
-            for (sal_uInt8 nLevel = nStart; nLevel < nEnd; ++nLevel)
-            {
-                const SvxNumberFormat &rFmt = pActNum->GetLevel(nLevel);
-                aNum.GetLevelVal()[nLevel] = rFmt.GetStart();
-
-                tools::Long nXStart( 0 );
-                short nTextOffset( 0 );
-                tools::Long nNumberXPos( 0 );
-                if (rFmt.GetPositionAndSpaceMode() == 
SvxNumberFormat::LABEL_WIDTH_AND_POSITION)
-                {
-                    nXStart = rFmt.GetAbsLSpace() / nWidthRelation;
-                    nTextOffset = rFmt.GetCharTextDistance() / nWidthRelation;
-                    nNumberXPos = nXStart;
-                    tools::Long nFirstLineOffset = 
(-rFmt.GetFirstLineOffset()) / nWidthRelation;
-
-                    if (nFirstLineOffset <= nNumberXPos)
-                        nNumberXPos = nNumberXPos - nFirstLineOffset;
-                    else
-                        nNumberXPos = 0;
-                    // in draw this is valid
-                    if (nTextOffset < 0)
-                        nNumberXPos = nNumberXPos + nTextOffset;
-                }
-                else if (rFmt.GetPositionAndSpaceMode() == 
SvxNumberFormat::LABEL_ALIGNMENT)
-                {
-                    const tools::Long nTmpNumberXPos((rFmt.GetIndentAt() + 
rFmt.GetFirstLineIndent() ) / nWidthRelation);
-                    if (nTmpNumberXPos < 0)
-                    {
-                        nNumberXPos = 0;
-                    }
-                    else
-                    {
-                        nNumberXPos = nTmpNumberXPos;
-                    }
-                }
-
-                tools::Long nBulletWidth = 0;
-                if (SVX_NUM_BITMAP == (rFmt.GetNumberingType() &(~LINK_TOKEN)))
-                {
-                    tools::Long nYMiddle = nYStart + ( nFontHeight / 2 );
-                    nBulletWidth = rFmt.IsShowSymbol() ? 
lcl_DrawGraphic(*pVDev, rFmt, nNumberXPos, nYMiddle, nWidthRelation) : 0;
-                }
-                else if (SVX_NUM_CHAR_SPECIAL == rFmt.GetNumberingType())
-                {
-                    nBulletWidth =  rFmt.IsShowSymbol() ? 
lcl_DrawBullet(pVDev.get(), rFmt, nNumberXPos, nYStart, aStdFont.GetFontSize()) 
: 0;
-                }
-                else
-                {
-                    pVDev->SetFont(aStdFont);
-                    aNum.SetLevel(nLevel);
-                    if (pActNum->IsContinuousNumbering())
-                        aNum.GetLevelVal()[nLevel] = nPreNum;
-                    OUString aText(pActNum->MakeNumString( aNum ));
-                    vcl::Font aSaveFont = pVDev->GetFont();
-                    vcl::Font aColorFont(aSaveFont);
-                    Color aTmpBulletColor = rFmt.GetBulletColor();
-                    if (aTmpBulletColor == COL_AUTO)
-                        aTmpBulletColor = pVDev->GetBackgroundColor().IsDark() 
? COL_WHITE : COL_BLACK;
-                    else if (pVDev->GetBackgroundColor().IsDark() == 
aTmpBulletColor.IsDark())
-                        aTmpBulletColor = pVDev->GetBackgroundColor().IsDark() 
? COL_WHITE : COL_BLACK;
-                    aColorFont.SetColor(aTmpBulletColor);
-                    pVDev->SetFont(aColorFont);
-                    pVDev->DrawText(Point(nNumberXPos, nYStart), aText);
-                    pVDev->SetFont(aSaveFont);
-                    nBulletWidth = pVDev->GetTextWidth(aText);
-                    nPreNum++;
-                }
-                if (rFmt.GetPositionAndSpaceMode() == 
SvxNumberFormat::LABEL_ALIGNMENT &&
-                    rFmt.GetLabelFollowedBy() == SvxNumberFormat::SPACE )
-                {
-                    pVDev->SetFont(aStdFont);
-                    OUString aText(' ');
-                    pVDev->DrawText( Point(nNumberXPos, nYStart), aText );
-                    nBulletWidth = nBulletWidth + pVDev->GetTextWidth(aText);
-                }
-
-                tools::Long nTextXPos( 0 );
-                if (rFmt.GetPositionAndSpaceMode() == 
SvxNumberFormat::LABEL_WIDTH_AND_POSITION)
-                {
-                    nTextXPos = nXStart;
-                    if (nTextOffset < 0)
-                         nTextXPos = nTextXPos + nTextOffset;
-                    if (nNumberXPos + nBulletWidth + nTextOffset > nTextXPos)
-                        nTextXPos = nNumberXPos + nBulletWidth + nTextOffset;
-                }
-                else if (rFmt.GetPositionAndSpaceMode() == 
SvxNumberFormat::LABEL_ALIGNMENT)
-                {
-                    switch (rFmt.GetLabelFollowedBy())
-                    {
-                        case SvxNumberFormat::LISTTAB:
-                        {
-                            nTextXPos = rFmt.GetListtabPos() / nWidthRelation;
-                            if (nTextXPos < nNumberXPos + nBulletWidth)
-                            {
-                                nTextXPos = nNumberXPos + nBulletWidth;
-                            }
-                        }
-                        break;
-                        case SvxNumberFormat::SPACE:
-                        case SvxNumberFormat::NOTHING:
-                        case SvxNumberFormat::NEWLINE:
-                        {
-                            nTextXPos = nNumberXPos + nBulletWidth;
-                        }
-                        break;
-                    }
-
-                    nXStart = rFmt.GetIndentAt() / nWidthRelation;
-                }
-
-                ::tools::Rectangle aRect1(Point(nTextXPos, nYStart + 
nFontHeight / 2), Size(aSize.Width() / 2, 2));
-                pVDev->SetFillColor(aBackColor);
-                pVDev->DrawRect(aRect1);
-
-                ::tools::Rectangle aRect2(Point(nXStart, nYStart + nLineHeight 
+ nFontHeight / 2 ), Size(aSize.Width() / 2, 2));
-                pVDev->DrawRect(aRect2);
-                nYStart += 2 * nLineHeight;
-            }
-        }
-        else
-        {
-            // When bPosition == false, draw the preview used in Writer's 
"Customize" tab
-            // and in Impress' "Bullets and Numbering" dialog
-
-            //#i5153# painting gray or black rectangles as 'normal' numbering 
text
-            tools::Long nWidth = pVDev->GetTextWidth("Preview");
-            tools::Long nTextHeight = pVDev->GetTextHeight();
-            tools::Long nRectHeight = nTextHeight * 2 / 3;
-            tools::Long nTopOffset = nTextHeight - nRectHeight;
-            Color aSelRectColor = pVDev->GetBackgroundColor().IsDark() ? 
COL_WHITE : COL_BLACK;
-
-            for (sal_uInt16 nLevel = 0; nLevel < pActNum->GetLevelCount(); 
++nLevel, nYStart = nYStart + nYStep)
-            {
-                const SvxNumberFormat &rFmt = pActNum->GetLevel(nLevel);
-                aNum.GetLevelVal()[ nLevel ] = rFmt.GetStart();
-                tools::Long nXStart( 0 );
-                pVDev->SetFillColor( aBackColor );
-
-                if (rFmt.GetPositionAndSpaceMode() == 
SvxNumberFormat::LABEL_WIDTH_AND_POSITION)
-                {
-                    nXStart = rFmt.GetAbsLSpace() / nWidthRelation;
-                }
-                else if (rFmt.GetPositionAndSpaceMode() == 
SvxNumberFormat::LABEL_ALIGNMENT)
-                {
-                    const tools::Long nTmpXStart((rFmt.GetIndentAt() + 
rFmt.GetFirstLineIndent() ) / nWidthRelation);
-                    if (nTmpXStart < 0)
-                    {
-                        nXStart = 0;
-                    }
-                    else
-                    {
-                        nXStart = nTmpXStart;
-                    }
-                }
-                nXStart /= 2;
-                nXStart += 2;
-                tools::Long nTextOffset = 2 * nXStep;
-                if (SVX_NUM_BITMAP == (rFmt.GetNumberingType()&(~LINK_TOKEN)))
-                {
-                    if (rFmt.IsShowSymbol())
-                    {
-                        tools::Long nYMiddle = nYStart + ( nFontHeight / 2 );
-                        nTextOffset = lcl_DrawGraphic(*pVDev, rFmt, nXStart, 
nYMiddle, nWidthRelation);
-                        nTextOffset = nTextOffset + nXStep;
-                    }
-                }
-                else if (SVX_NUM_CHAR_SPECIAL == rFmt.GetNumberingType())
-                {
-                    if (rFmt.IsShowSymbol())
-                    {
-                        nTextOffset =  lcl_DrawBullet(pVDev.get(), rFmt, 
nXStart, nYStart, aStdFont.GetFontSize());
-                        nTextOffset = nTextOffset + nXStep;
-                    }
-                }
-                else
-                {
-                    vcl::Font aFont(aStdFont);
-                    Size aTmpSize(aStdFont.GetFontSize());
-                    
if(pActNum->IsFeatureSupported(SvxNumRuleFlags::BULLET_REL_SIZE))
-                    {
-                        aTmpSize.setWidth( aTmpSize.Width() * ( 
rFmt.GetBulletRelSize()) );
-                        aTmpSize.setWidth( aTmpSize.Width() / 100 ) ;
-                        aTmpSize.setHeight( aTmpSize.Height() * ( 
rFmt.GetBulletRelSize()) );
-                        aTmpSize.setHeight( aTmpSize.Height() / 100 ) ;
-                    }
-                    if(!aTmpSize.Height())
-                        aTmpSize.setHeight( 1 );
-                    aFont.SetFontSize(aTmpSize);
-                    Color aTmpBulletColor = rFmt.GetBulletColor();
-                    if (aTmpBulletColor == COL_AUTO)
-                        aTmpBulletColor = pVDev->GetBackgroundColor().IsDark() 
? COL_WHITE : COL_BLACK;
-                    else if (pVDev->GetBackgroundColor().IsDark() == 
aTmpBulletColor.IsDark())
-                        aTmpBulletColor = pVDev->GetBackgroundColor().IsDark() 
? COL_WHITE : COL_BLACK;
-                    aFont.SetColor(aTmpBulletColor);
-                    pVDev->SetFont(aFont);
-                    aNum.SetLevel( nLevel );
-                    if (pActNum->IsContinuousNumbering())
-                        aNum.GetLevelVal()[nLevel] = nPreNum;
-                    OUString aText(pActNum->MakeNumString(aNum));
-                    tools::Long nY = nYStart;
-                    nY -= (pVDev->GetTextHeight() - nTextHeight - 
pVDev->GetFontMetric().GetDescent());
-                    pVDev->DrawText(Point(nXStart, nY), aText);
-                    nTextOffset = pVDev->GetTextWidth(aText);
-                    nTextOffset = nTextOffset + nXStep;
-                    nPreNum++;
-                    pVDev->SetFont(aStdFont);
-                }
-                //#i5153# the selected rectangle(s) should be black
-                if (0 != (nActLevel & (1<<nLevel)))
-                {
-                    pVDev->SetFillColor( aSelRectColor );
-                    pVDev->SetLineColor( aSelRectColor );
-                }
-                else
-                {
-                    //#i5153# unselected levels are gray
-                    pVDev->SetFillColor( aLineColor );
-                    pVDev->SetLineColor( aLineColor );
-                }
-                ::tools::Rectangle aRect1(Point(nXStart + nTextOffset, nYStart 
+ nTopOffset), Size(nWidth, nRectHeight));
-                pVDev->DrawRect(aRect1);
-            }
-        }
-    }
-    rRenderContext.DrawOutDev(Point(), aSize, Point(), aSize, *pVDev);
-}
-
-
 //See uiconfig/swriter/ui/outlinepositionpage.ui for effectively a duplicate
 //dialog to this one, except with a different preview window impl.
 //TODO, determine if SwNumPositionTabPage and SvxNumPositionTabPage can be
diff --git a/include/cui/numberingpreview.hxx b/include/svx/numberingpreview.hxx
similarity index 52%
rename from include/cui/numberingpreview.hxx
rename to include/svx/numberingpreview.hxx
index 8a7883522bf0..ac2285c1c643 100644
--- a/include/cui/numberingpreview.hxx
+++ b/include/svx/numberingpreview.hxx
@@ -1,12 +1,19 @@
-#ifndef INCLUDED_CUI_NUMBERINGPREVIEW_HXX
-#define INCLUDED_CUI_NUMBERINGPREVIEW_HXX
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+#pragma once
 
-#include <cui/cuidllapi.h>
+#include <svx/svxdllapi.h>
 #include <editeng/numitem.hxx>
 #include <vcl/customweld.hxx>
 
 /// Provides the preview to show how looks bullet or numbering format before 
the apply.
-class CUI_DLLPUBLIC SvxNumberingPreview final : public 
weld::CustomWidgetController
+class SVXCORE_DLLPUBLIC SvxNumberingPreview final : public 
weld::CustomWidgetController
 {
     const SvxNumRule* pActNum;
     vcl::Font aStdFont;
@@ -28,4 +35,4 @@ public:
     void SetLevel(sal_uInt16 nSet) { nActLevel = nSet; }
 };
 
-#endif
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/sd/source/ui/inc/BulletAndPositionDlg.hxx 
b/sd/source/ui/inc/BulletAndPositionDlg.hxx
index 35a35412bce0..9d1393f13919 100644
--- a/sd/source/ui/inc/BulletAndPositionDlg.hxx
+++ b/sd/source/ui/inc/BulletAndPositionDlg.hxx
@@ -26,7 +26,7 @@
 #include <editeng/svxenum.hxx>
 #include <vcl/weld.hxx>
 #include "View.hxx"
-#include <cui/numberingpreview.hxx>
+#include <svx/numberingpreview.hxx>
 
 #define MN_GALLERY_ENTRY 100
 
diff --git a/svx/source/dialog/pagenumberlistbox.cxx 
b/svx/source/dialog/pagenumberlistbox.cxx
index 076da12e123e..1b53e1d26350 100644
--- a/svx/source/dialog/pagenumberlistbox.cxx
+++ b/svx/source/dialog/pagenumberlistbox.cxx
@@ -17,12 +17,20 @@
  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
  */
 
+#include <editeng/brushitem.hxx>
+#include <editeng/numitem.hxx>
+#include <i18nlangtag/mslangid.hxx>
+#include <svtools/colorcfg.hxx>
 #include <svx/dialmgr.hxx>
+#include <svx/numberingpreview.hxx>
 #include <svx/pagenumberlistbox.hxx>
-#include <editeng/numitem.hxx>
-#include <com/sun/star/style/NumberingType.hpp>
+#include <vcl/graph.hxx>
+#include <vcl/metric.hxx>
+#include <vcl/virdev.hxx>
 #include <numberingtype.hrc>
 
+#include <com/sun/star/style/NumberingType.hpp>
+
 SvxPageNumberListBox::SvxPageNumberListBox(std::unique_ptr<weld::ComboBox> 
pControl)
     : m_xControl(std::move(pControl))
 {
@@ -49,4 +57,377 @@ 
SvxPageNumberListBox::SvxPageNumberListBox(std::unique_ptr<weld::ComboBox> pCont
     }
 }
 
+SvxNumberingPreview::SvxNumberingPreview()
+    : pActNum(nullptr)
+    , bPosition(false)
+    , nActLevel(SAL_MAX_UINT16)
+{
+}
+
+static tools::Long lcl_DrawGraphic(VirtualDevice& rVDev, const 
SvxNumberFormat& rFmt,
+                                   tools::Long nXStart, tools::Long nYMiddle, 
tools::Long nDivision)
+{
+    const SvxBrushItem* pBrushItem = rFmt.GetBrush();
+    tools::Long nRet = 0;
+    if (pBrushItem)
+    {
+        const Graphic* pGrf = pBrushItem->GetGraphic();
+        if (pGrf)
+        {
+            Size aGSize(rFmt.GetGraphicSize());
+            aGSize.setWidth(aGSize.Width() / nDivision);
+            nRet = aGSize.Width();
+            aGSize.setHeight(aGSize.Height() / nDivision);
+            pGrf->Draw(rVDev, Point(nXStart, nYMiddle - (aGSize.Height() / 2)),
+                       rVDev.PixelToLogic(aGSize));
+        }
+    }
+    return nRet;
+}
+
+static tools::Long lcl_DrawBullet(VirtualDevice* pVDev, const SvxNumberFormat& 
rFmt,
+                                  tools::Long nXStart, tools::Long nYStart, 
const Size& rSize)
+{
+    vcl::Font aTmpFont(pVDev->GetFont());
+
+    // via Uno it's possible that no font has been set!
+    vcl::Font aFont(rFmt.GetBulletFont() ? *rFmt.GetBulletFont() : aTmpFont);
+    Size aTmpSize(rSize);
+    aTmpSize.setWidth(aTmpSize.Width() * (rFmt.GetBulletRelSize()));
+    aTmpSize.setWidth(aTmpSize.Width() / 100);
+    aTmpSize.setHeight(aTmpSize.Height() * (rFmt.GetBulletRelSize()));
+    aTmpSize.setHeight(aTmpSize.Height() / 100);
+    // in case of a height of zero it is drawn in original height
+    if (!aTmpSize.Height())
+        aTmpSize.setHeight(1);
+    aFont.SetFontSize(aTmpSize);
+    aFont.SetTransparent(true);
+    Color aBulletColor = rFmt.GetBulletColor();
+    if (aBulletColor == COL_AUTO)
+        aBulletColor = pVDev->GetBackgroundColor().IsDark() ? COL_WHITE : 
COL_BLACK;
+    else if (pVDev->GetBackgroundColor().IsDark() == aBulletColor.IsDark())
+        aBulletColor = pVDev->GetBackgroundColor().IsDark() ? COL_WHITE : 
COL_BLACK;
+    aFont.SetColor(aBulletColor);
+    pVDev->SetFont(aFont);
+    sal_UCS4 cChar = rFmt.GetBulletChar();
+    OUString aText(&cChar, 1);
+    tools::Long nY = nYStart;
+    nY -= ((aTmpSize.Height() - rSize.Height()) / 2);
+    pVDev->DrawText(Point(nXStart, nY), aText);
+    tools::Long nRet = pVDev->GetTextWidth(aText);
+
+    pVDev->SetFont(aTmpFont);
+    return nRet;
+}
+
+// paint preview of numeration
+void SvxNumberingPreview::Paint(vcl::RenderContext& rRenderContext,
+                                const ::tools::Rectangle& /*rRect*/)
+{
+    Size aSize(rRenderContext.PixelToLogic(GetOutputSizePixel()));
+
+    // Use default document and font colors to create preview
+    const Color aBackColor = 
svtools::ColorConfig().GetColorValue(svtools::DOCCOLOR).nColor;
+    const Color aTextColor = 
svtools::ColorConfig().GetColorValue(svtools::FONTCOLOR).nColor;
+
+    ScopedVclPtrInstance<VirtualDevice> pVDev(rRenderContext);
+    pVDev->EnableRTL(rRenderContext.IsRTLEnabled());
+    pVDev->SetMapMode(rRenderContext.GetMapMode());
+    pVDev->SetOutputSize(aSize);
+
+    Color aLineColor(COL_LIGHTGRAY);
+    if (aLineColor == aBackColor)
+        aLineColor.Invert();
+    pVDev->SetLineColor(aLineColor);
+    pVDev->SetFillColor(aBackColor);
+    pVDev->SetBackground(Wallpaper(aBackColor));
+    pVDev->DrawWallpaper(pVDev->GetOutputRectPixel(), pVDev->GetBackground());
+
+    if (pActNum)
+    {
+        tools::Long nWidthRelation = 30; // chapter dialog
+
+        // height per level
+        tools::Long nXStep
+            = aSize.Width() / (pActNum->GetLevelCount() > 1 ? 3 * 
pActNum->GetLevelCount() : 3);
+        if (pActNum->GetLevelCount() < 10)
+            nXStep /= 2;
+        tools::Long nYStart = 4;
+        // the whole height mustn't be used for a single level
+        tools::Long nYStep
+            = (aSize.Height() - 6) / (pActNum->GetLevelCount() > 1 ? 
pActNum->GetLevelCount() : 5);
+
+        aStdFont = OutputDevice::GetDefaultFont(DefaultFontType::UI_SANS,
+                                                
MsLangId::getConfiguredSystemLanguage(),
+                                                GetDefaultFontFlags::OnlyOne);
+        aStdFont.SetColor(aTextColor);
+        aStdFont.SetFillColor(aBackColor);
+
+        tools::Long nFontHeight = nYStep * 6 / 10;
+        if (bPosition)
+            nFontHeight = nYStep * 15 / 10;
+        aStdFont.SetFontSize(Size(0, nFontHeight));
+
+        SvxNodeNum aNum;
+        sal_uInt16 nPreNum = pActNum->GetLevel(0).GetStart();
+
+        if (bPosition)
+        {
+            // When bPosition == true, draw the preview used in the Writer's 
"Position" tab
+            // This is not used in Impress/Draw
+
+            tools::Long nLineHeight = nFontHeight * 8 / 7;
+            sal_uInt8 nStart = 0;
+            while (!(nActLevel & (1 << nStart)))
+            {
+                nStart++;
+            }
+            if (nStart)
+                nStart--;
+            sal_uInt8 nEnd = std::min(sal_uInt8(nStart + 3), 
sal_uInt8(pActNum->GetLevelCount()));
+            for (sal_uInt8 nLevel = nStart; nLevel < nEnd; ++nLevel)
+            {
+                const SvxNumberFormat& rFmt = pActNum->GetLevel(nLevel);
+                aNum.GetLevelVal()[nLevel] = rFmt.GetStart();
+
+                tools::Long nXStart(0);
+                short nTextOffset(0);
+                tools::Long nNumberXPos(0);
+                if (rFmt.GetPositionAndSpaceMode() == 
SvxNumberFormat::LABEL_WIDTH_AND_POSITION)
+                {
+                    nXStart = rFmt.GetAbsLSpace() / nWidthRelation;
+                    nTextOffset = rFmt.GetCharTextDistance() / nWidthRelation;
+                    nNumberXPos = nXStart;
+                    tools::Long nFirstLineOffset = 
(-rFmt.GetFirstLineOffset()) / nWidthRelation;
+
+                    if (nFirstLineOffset <= nNumberXPos)
+                        nNumberXPos = nNumberXPos - nFirstLineOffset;
+                    else
+                        nNumberXPos = 0;
+                    // in draw this is valid
+                    if (nTextOffset < 0)
+                        nNumberXPos = nNumberXPos + nTextOffset;
+                }
+                else if (rFmt.GetPositionAndSpaceMode() == 
SvxNumberFormat::LABEL_ALIGNMENT)
+                {
+                    const tools::Long nTmpNumberXPos(
+                        (rFmt.GetIndentAt() + rFmt.GetFirstLineIndent()) / 
nWidthRelation);
+                    if (nTmpNumberXPos < 0)
+                    {
+                        nNumberXPos = 0;
+                    }
+                    else
+                    {
+                        nNumberXPos = nTmpNumberXPos;
+                    }
+                }
+
+                tools::Long nBulletWidth = 0;
+                if (SVX_NUM_BITMAP == (rFmt.GetNumberingType() & 
(~LINK_TOKEN)))
+                {
+                    tools::Long nYMiddle = nYStart + (nFontHeight / 2);
+                    nBulletWidth = rFmt.IsShowSymbol() ? 
lcl_DrawGraphic(*pVDev, rFmt, nNumberXPos,
+                                                                         
nYMiddle, nWidthRelation)
+                                                       : 0;
+                }
+                else if (SVX_NUM_CHAR_SPECIAL == rFmt.GetNumberingType())
+                {
+                    nBulletWidth = rFmt.IsShowSymbol()
+                                       ? lcl_DrawBullet(pVDev.get(), rFmt, 
nNumberXPos, nYStart,
+                                                        aStdFont.GetFontSize())
+                                       : 0;
+                }
+                else
+                {
+                    pVDev->SetFont(aStdFont);
+                    aNum.SetLevel(nLevel);
+                    if (pActNum->IsContinuousNumbering())
+                        aNum.GetLevelVal()[nLevel] = nPreNum;
+                    OUString aText(pActNum->MakeNumString(aNum));
+                    vcl::Font aSaveFont = pVDev->GetFont();
+                    vcl::Font aColorFont(aSaveFont);
+                    Color aTmpBulletColor = rFmt.GetBulletColor();
+                    if (aTmpBulletColor == COL_AUTO)
+                        aTmpBulletColor
+                            = pVDev->GetBackgroundColor().IsDark() ? COL_WHITE 
: COL_BLACK;
+                    else if (pVDev->GetBackgroundColor().IsDark() == 
aTmpBulletColor.IsDark())
+                        aTmpBulletColor
+                            = pVDev->GetBackgroundColor().IsDark() ? COL_WHITE 
: COL_BLACK;
+                    aColorFont.SetColor(aTmpBulletColor);
+                    pVDev->SetFont(aColorFont);
+                    pVDev->DrawText(Point(nNumberXPos, nYStart), aText);
+                    pVDev->SetFont(aSaveFont);
+                    nBulletWidth = pVDev->GetTextWidth(aText);
+                    nPreNum++;
+                }
+                if (rFmt.GetPositionAndSpaceMode() == 
SvxNumberFormat::LABEL_ALIGNMENT
+                    && rFmt.GetLabelFollowedBy() == SvxNumberFormat::SPACE)
+                {
+                    pVDev->SetFont(aStdFont);
+                    OUString aText(' ');
+                    pVDev->DrawText(Point(nNumberXPos, nYStart), aText);
+                    nBulletWidth = nBulletWidth + pVDev->GetTextWidth(aText);
+                }
+
+                tools::Long nTextXPos(0);
+                if (rFmt.GetPositionAndSpaceMode() == 
SvxNumberFormat::LABEL_WIDTH_AND_POSITION)
+                {
+                    nTextXPos = nXStart;
+                    if (nTextOffset < 0)
+                        nTextXPos = nTextXPos + nTextOffset;
+                    if (nNumberXPos + nBulletWidth + nTextOffset > nTextXPos)
+                        nTextXPos = nNumberXPos + nBulletWidth + nTextOffset;
+                }
+                else if (rFmt.GetPositionAndSpaceMode() == 
SvxNumberFormat::LABEL_ALIGNMENT)
+                {
+                    switch (rFmt.GetLabelFollowedBy())
+                    {
+                        case SvxNumberFormat::LISTTAB:
+                        {
+                            nTextXPos = rFmt.GetListtabPos() / nWidthRelation;
+                            if (nTextXPos < nNumberXPos + nBulletWidth)
+                            {
+                                nTextXPos = nNumberXPos + nBulletWidth;
+                            }
+                        }
+                        break;
+                        case SvxNumberFormat::SPACE:
+                        case SvxNumberFormat::NOTHING:
+                        case SvxNumberFormat::NEWLINE:
+                        {
+                            nTextXPos = nNumberXPos + nBulletWidth;
+                        }
+                        break;
+                    }
+
+                    nXStart = rFmt.GetIndentAt() / nWidthRelation;
+                }
+
+                ::tools::Rectangle aRect1(Point(nTextXPos, nYStart + 
nFontHeight / 2),
+                                          Size(aSize.Width() / 2, 2));
+                pVDev->SetFillColor(aBackColor);
+                pVDev->DrawRect(aRect1);
+
+                ::tools::Rectangle aRect2(Point(nXStart, nYStart + nLineHeight 
+ nFontHeight / 2),
+                                          Size(aSize.Width() / 2, 2));
+                pVDev->DrawRect(aRect2);
+                nYStart += 2 * nLineHeight;
+            }
+        }
+        else
+        {
+            // When bPosition == false, draw the preview used in Writer's 
"Customize" tab
+            // and in Impress' "Bullets and Numbering" dialog
+
+            //#i5153# painting gray or black rectangles as 'normal' numbering 
text
+            tools::Long nWidth = pVDev->GetTextWidth("Preview");
+            tools::Long nTextHeight = pVDev->GetTextHeight();
+            tools::Long nRectHeight = nTextHeight * 2 / 3;
+            tools::Long nTopOffset = nTextHeight - nRectHeight;
+            Color aSelRectColor = pVDev->GetBackgroundColor().IsDark() ? 
COL_WHITE : COL_BLACK;
+
+            for (sal_uInt16 nLevel = 0; nLevel < pActNum->GetLevelCount();
+                 ++nLevel, nYStart = nYStart + nYStep)
+            {
+                const SvxNumberFormat& rFmt = pActNum->GetLevel(nLevel);
+                aNum.GetLevelVal()[nLevel] = rFmt.GetStart();
+                tools::Long nXStart(0);
+                pVDev->SetFillColor(aBackColor);
+
+                if (rFmt.GetPositionAndSpaceMode() == 
SvxNumberFormat::LABEL_WIDTH_AND_POSITION)
+                {
+                    nXStart = rFmt.GetAbsLSpace() / nWidthRelation;
+                }
+                else if (rFmt.GetPositionAndSpaceMode() == 
SvxNumberFormat::LABEL_ALIGNMENT)
+                {
+                    const tools::Long nTmpXStart((rFmt.GetIndentAt() + 
rFmt.GetFirstLineIndent())
+                                                 / nWidthRelation);
+                    if (nTmpXStart < 0)
+                    {
+                        nXStart = 0;
+                    }
+                    else
+                    {
+                        nXStart = nTmpXStart;
+                    }
+                }
+                nXStart /= 2;
+                nXStart += 2;
+                tools::Long nTextOffset = 2 * nXStep;
+                if (SVX_NUM_BITMAP == (rFmt.GetNumberingType() & 
(~LINK_TOKEN)))
+                {
+                    if (rFmt.IsShowSymbol())
+                    {
+                        tools::Long nYMiddle = nYStart + (nFontHeight / 2);
+                        nTextOffset
+                            = lcl_DrawGraphic(*pVDev, rFmt, nXStart, nYMiddle, 
nWidthRelation);
+                        nTextOffset = nTextOffset + nXStep;
+                    }
+                }
+                else if (SVX_NUM_CHAR_SPECIAL == rFmt.GetNumberingType())
+                {
+                    if (rFmt.IsShowSymbol())
+                    {
+                        nTextOffset = lcl_DrawBullet(pVDev.get(), rFmt, 
nXStart, nYStart,
+                                                     aStdFont.GetFontSize());
+                        nTextOffset = nTextOffset + nXStep;
+                    }
+                }
+                else
+                {
+                    vcl::Font aFont(aStdFont);
+                    Size aTmpSize(aStdFont.GetFontSize());
+                    if 
(pActNum->IsFeatureSupported(SvxNumRuleFlags::BULLET_REL_SIZE))
+                    {
+                        aTmpSize.setWidth(aTmpSize.Width() * 
(rFmt.GetBulletRelSize()));
+                        aTmpSize.setWidth(aTmpSize.Width() / 100);
+                        aTmpSize.setHeight(aTmpSize.Height() * 
(rFmt.GetBulletRelSize()));
+                        aTmpSize.setHeight(aTmpSize.Height() / 100);
+                    }
+                    if (!aTmpSize.Height())
+                        aTmpSize.setHeight(1);
+                    aFont.SetFontSize(aTmpSize);
+                    Color aTmpBulletColor = rFmt.GetBulletColor();
+                    if (aTmpBulletColor == COL_AUTO)
+                        aTmpBulletColor
+                            = pVDev->GetBackgroundColor().IsDark() ? COL_WHITE 
: COL_BLACK;
+                    else if (pVDev->GetBackgroundColor().IsDark() == 
aTmpBulletColor.IsDark())
+                        aTmpBulletColor
+                            = pVDev->GetBackgroundColor().IsDark() ? COL_WHITE 
: COL_BLACK;
+                    aFont.SetColor(aTmpBulletColor);
+                    pVDev->SetFont(aFont);
+                    aNum.SetLevel(nLevel);
+                    if (pActNum->IsContinuousNumbering())
+                        aNum.GetLevelVal()[nLevel] = nPreNum;
+                    OUString aText(pActNum->MakeNumString(aNum));
+                    tools::Long nY = nYStart;
+                    nY -= (pVDev->GetTextHeight() - nTextHeight
+                           - pVDev->GetFontMetric().GetDescent());
+                    pVDev->DrawText(Point(nXStart, nY), aText);
+                    nTextOffset = pVDev->GetTextWidth(aText);
+                    nTextOffset = nTextOffset + nXStep;
+                    nPreNum++;
+                    pVDev->SetFont(aStdFont);
+                }
+                //#i5153# the selected rectangle(s) should be black
+                if (0 != (nActLevel & (1 << nLevel)))
+                {
+                    pVDev->SetFillColor(aSelRectColor);
+                    pVDev->SetLineColor(aSelRectColor);
+                }
+                else
+                {
+                    //#i5153# unselected levels are gray
+                    pVDev->SetFillColor(aLineColor);
+                    pVDev->SetLineColor(aLineColor);
+                }
+                ::tools::Rectangle aRect1(Point(nXStart + nTextOffset, nYStart 
+ nTopOffset),
+                                          Size(nWidth, nRectHeight));
+                pVDev->DrawRect(aRect1);
+            }
+        }
+    }
+    rRenderContext.DrawOutDev(Point(), aSize, Point(), aSize, *pVDev);
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Reply via email to