sc/inc/globstr.hrc                  |    1 
 sc/source/ui/inc/namedefdlg.hxx     |    3 +
 sc/source/ui/inc/namedlg.hxx        |    1 
 sc/source/ui/namedlg/namedefdlg.cxx |   49 +++++++++++++++++++++++++++----
 sc/source/ui/namedlg/namedlg.cxx    |   56 ++++++++++++++++++++++++++----------
 5 files changed, 89 insertions(+), 21 deletions(-)

New commits:
commit bee09884a65013ab01584c71f70b37c99900a1bf
Author:     Andreas Heinisch <andreas.heini...@yahoo.de>
AuthorDate: Tue Mar 5 17:09:00 2024 +0100
Commit:     Andreas Heinisch <andreas.heini...@yahoo.de>
CommitDate: Fri Aug 23 14:52:49 2024 +0200

    tdf#140394 - Manage names dialog: check if formula is a valid print range
    
    Change-Id: I65572967987fcc2ef0cdf840eb1ba042b4f298e5
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/164434
    Reviewed-by: Andreas Heinisch <andreas.heini...@yahoo.de>
    Tested-by: Jenkins

diff --git a/sc/inc/globstr.hrc b/sc/inc/globstr.hrc
index 9a5409300f8c..e0838445e736 100644
--- a/sc/inc/globstr.hrc
+++ b/sc/inc/globstr.hrc
@@ -173,6 +173,7 @@
 #define STR_SAVE_DOC                            NC_("STR_SAVE_DOC", "Save 
document")
 #define STR_AREA_ALREADY_INSERTED               
NC_("STR_AREA_ALREADY_INSERTED", "This range has already been inserted.")
 #define STR_INVALID_TABREF                      NC_("STR_INVALID_TABREF", 
"Invalid sheet reference.")
+#define STR_INVALID_TABREF_PRINT_AREA           
NC_("STR_INVALID_TABREF_PRINT_AREA", "Invalid sheet reference. Ensure the 
inserted expression is a valid print range.")
 #define STR_INVALID_QUERYAREA                   NC_("STR_INVALID_QUERYAREA", 
"This range does not contain a valid query.")
 #define STR_REIMPORT_EMPTY                      NC_("STR_REIMPORT_EMPTY", 
"This range does not contain imported data.")
 #define STR_NOMULTISELECT                       NC_("STR_NOMULTISELECT", "This 
function cannot be used with multiple selections.")
diff --git a/sc/source/ui/inc/namedefdlg.hxx b/sc/source/ui/inc/namedefdlg.hxx
index fe05059e8007..63afb02645e3 100644
--- a/sc/source/ui/inc/namedefdlg.hxx
+++ b/sc/source/ui/inc/namedefdlg.hxx
@@ -30,6 +30,7 @@ private:
     const OUString maGlobalNameStr;
     const OUString maErrInvalidNameStr;
     const OUString maErrInvalidNameCellRefStr;
+    const OUString maErrInvalidSheetReference;
     const OUString maErrNameInUse;
 
     //hack to call this dialog from Manage Names
@@ -66,6 +67,8 @@ private:
     DECL_LINK(AddBtnHdl, weld::Button&, void);
     DECL_LINK(NameModifyHdl, weld::Entry&, void);
     DECL_LINK(AssignGetFocusHdl, formula::RefEdit&, void);
+    DECL_LINK(EdModifyCheckBoxHdl, weld::Toggleable&, void);
+    DECL_LINK(RefEdModifyHdl, formula::RefEdit&, void);
 
 protected:
     virtual void RefInputDone(bool bForced = false) override;
diff --git a/sc/source/ui/inc/namedlg.hxx b/sc/source/ui/inc/namedlg.hxx
index eadde5349618..4ee3592b7ceb 100644
--- a/sc/source/ui/inc/namedlg.hxx
+++ b/sc/source/ui/inc/namedlg.hxx
@@ -35,6 +35,7 @@ private:
     const OUString maGlobalNameStr;
     const OUString maErrInvalidNameStr;
     const OUString maErrNameInUse;
+    const OUString maErrInvalidSheetReference;
     const OUString maStrMultiSelect;
     OUString maStrInfoDefault;
 
diff --git a/sc/source/ui/namedlg/namedefdlg.cxx 
b/sc/source/ui/namedlg/namedefdlg.cxx
index 83e88ff1f549..b7101f49446b 100644
--- a/sc/source/ui/namedlg/namedefdlg.cxx
+++ b/sc/source/ui/namedlg/namedefdlg.cxx
@@ -35,6 +35,7 @@ ScNameDefDlg::ScNameDefDlg( SfxBindings* pB, SfxChildWindow* 
pCW, weld::Window*
     , maGlobalNameStr  ( ScResId(STR_GLOBAL_SCOPE) )
     , maErrInvalidNameStr( ScResId(STR_ERR_NAME_INVALID))
     , maErrInvalidNameCellRefStr( ScResId(STR_ERR_NAME_INVALID_CELL_REF))
+    , maErrInvalidSheetReference(ScResId(STR_INVALID_TABREF_PRINT_AREA))
     , maErrNameInUse   ( ScResId(STR_ERR_NAME_EXISTS))
     , maRangeMap( std::move(aRangeMap) )
     , m_xEdName(m_xBuilder->weld_entry(u"edit"_ustr))
@@ -70,6 +71,8 @@ ScNameDefDlg::ScNameDefDlg( SfxBindings* pB, SfxChildWindow* 
pCW, weld::Window*
     m_xBtnAdd->connect_clicked( LINK( this, ScNameDefDlg, AddBtnHdl ));
     m_xEdName->connect_changed( LINK( this, ScNameDefDlg, NameModifyHdl ));
     m_xEdRange->SetGetFocusHdl( LINK( this, ScNameDefDlg, AssignGetFocusHdl ) 
);
+    m_xEdRange->SetModifyHdl( LINK( this, ScNameDefDlg, RefEdModifyHdl ) );
+    m_xBtnPrintArea->connect_toggled(LINK(this, ScNameDefDlg, 
EdModifyCheckBoxHdl));
 
     m_xBtnAdd->set_sensitive(false); // empty name is invalid
 
@@ -102,17 +105,38 @@ void ScNameDefDlg::CancelPushed()
 
 bool ScNameDefDlg::IsFormulaValid()
 {
-    ScCompiler aComp(mrDoc, maCursorPos, mrDoc.GetGrammar());
-    std::unique_ptr<ScTokenArray> pCode = 
aComp.CompileString(m_xEdRange->GetText());
-    if (pCode->GetCodeError() != FormulaError::NONE)
+    const OUString aRangeOrFormulaExp = m_xEdRange->GetText();
+    // tdf#140394 - check if formula is a valid print range
+    if (m_xBtnPrintArea->get_active())
     {
-        //TODO: info message
-        return false;
+        const ScRefFlags nValidAddr  = ScRefFlags::VALID | 
ScRefFlags::ROW_VALID | ScRefFlags::COL_VALID;
+        const ScRefFlags nValidRange = nValidAddr | ScRefFlags::ROW2_VALID | 
ScRefFlags::COL2_VALID;
+        const formula::FormulaGrammar::AddressConvention eConv = 
mrDoc.GetAddressConvention();
+        const sal_Unicode sep = ScCompiler::GetNativeSymbolChar(ocSep);
+
+        ScAddress aAddr;
+        ScRange aRange;
+        for (sal_Int32 nIdx = 0; nIdx >= 0;)
+        {
+            const OUString aOne = aRangeOrFormulaExp.getToken(0, sep, nIdx);
+            ScRefFlags nResult = aRange.Parse(aOne, mrDoc, eConv);
+            if ((nResult & nValidRange) != nValidRange)
+            {
+                ScRefFlags nAddrResult = aAddr.Parse(aOne, mrDoc, eConv);
+                if ((nAddrResult & nValidAddr) != nValidAddr)
+                    return false;
+            }
+        }
     }
     else
     {
-        return true;
+        ScCompiler aComp(mrDoc, maCursorPos, mrDoc.GetGrammar());
+        std::unique_ptr<ScTokenArray> pCode = 
aComp.CompileString(m_xEdRange->GetText());
+        if (pCode->GetCodeError() != FormulaError::NONE)
+            return false;
     }
+
+    return true;
 }
 
 bool ScNameDefDlg::IsNameValid()
@@ -164,6 +188,9 @@ bool ScNameDefDlg::IsNameValid()
     if (!IsFormulaValid())
     {
         bIsNameValid = false;
+        if (m_xBtnPrintArea->get_active())
+            aHelpText = maErrInvalidSheetReference;
+        //TODO: info message for a non valid formula (print range not checked)
     }
 
     m_xEdName->set_tooltip_text(aHelpText);
@@ -328,4 +355,14 @@ IMPL_LINK_NOARG(ScNameDefDlg, AssignGetFocusHdl, 
formula::RefEdit&, void)
     IsNameValid();
 }
 
+IMPL_LINK_NOARG(ScNameDefDlg, EdModifyCheckBoxHdl, weld::Toggleable&, void)
+{
+    IsNameValid();
+}
+
+IMPL_LINK_NOARG(ScNameDefDlg, RefEdModifyHdl, formula::RefEdit&, void)
+{
+    IsNameValid();
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/namedlg/namedlg.cxx b/sc/source/ui/namedlg/namedlg.cxx
index bb03fd6f0dab..f5d6a9b881f9 100644
--- a/sc/source/ui/namedlg/namedlg.cxx
+++ b/sc/source/ui/namedlg/namedlg.cxx
@@ -50,6 +50,7 @@ ScNameDlg::ScNameDlg( SfxBindings* pB, SfxChildWindow* pCW, 
weld::Window* pParen
     , maGlobalNameStr(ScResId(STR_GLOBAL_SCOPE))
     , maErrInvalidNameStr(ScResId(STR_ERR_NAME_INVALID))
     , maErrNameInUse(ScResId(STR_ERR_NAME_EXISTS))
+    , maErrInvalidSheetReference(ScResId(STR_INVALID_TABREF_PRINT_AREA))
     , maStrMultiSelect(ScResId(STR_MULTI_SELECT))
 
     , mrViewData(rViewData)
@@ -259,23 +260,51 @@ bool ScNameDlg::IsNameValid()
         m_xFtInfo->set_label(maErrNameInUse);
         return false;
     }
-    m_xFtInfo->set_label( maStrInfoDefault );
     return true;
 }
 
 bool ScNameDlg::IsFormulaValid()
 {
-    ScCompiler aComp(mrDoc, maCursorPos, mrDoc.GetGrammar());
-    std::unique_ptr<ScTokenArray> pCode = 
aComp.CompileString(m_xEdAssign->GetText());
-    if (pCode->GetCodeError() != FormulaError::NONE)
+    const OUString aRangeOrFormulaExp = m_xEdAssign->GetText();
+    // tdf#140394 - check if formula is a valid print range
+    if (m_xBtnPrintArea->get_active())
     {
-        m_xFtInfo->set_label_type(weld::LabelType::Error);
-        return false;
+        const ScRefFlags nValidAddr  = ScRefFlags::VALID | 
ScRefFlags::ROW_VALID | ScRefFlags::COL_VALID;
+        const ScRefFlags nValidRange = nValidAddr | ScRefFlags::ROW2_VALID | 
ScRefFlags::COL2_VALID;
+        const formula::FormulaGrammar::AddressConvention eConv = 
mrDoc.GetAddressConvention();
+        const sal_Unicode sep = ScCompiler::GetNativeSymbolChar(ocSep);
+
+        ScAddress aAddr;
+        ScRange aRange;
+        for (sal_Int32 nIdx = 0; nIdx >= 0;)
+        {
+            const OUString aOne = aRangeOrFormulaExp.getToken(0, sep, nIdx);
+            ScRefFlags nResult = aRange.Parse(aOne, mrDoc, eConv);
+            if ((nResult & nValidRange) != nValidRange)
+            {
+                ScRefFlags nAddrResult = aAddr.Parse(aOne, mrDoc, eConv);
+                if ((nAddrResult & nValidAddr) != nValidAddr)
+                {
+                    m_xFtInfo->set_label_type(weld::LabelType::Error);
+                    m_xFtInfo->set_label(maErrInvalidSheetReference);
+                    return false;
+                }
+            }
+        }
     }
     else
     {
-        return true;
+        ScCompiler aComp(mrDoc, maCursorPos, mrDoc.GetGrammar());
+        std::unique_ptr<ScTokenArray> pCode = 
aComp.CompileString(aRangeOrFormulaExp);
+        if (pCode->GetCodeError() != FormulaError::NONE)
+        {
+            m_xFtInfo->set_label_type(weld::LabelType::Error);
+            //TODO: implement an info text
+            return false;
+        }
     }
+
+    return true;
 }
 
 ScRangeName* ScNameDlg::GetRangeName(const OUString& rScope)
@@ -348,22 +377,19 @@ void ScNameDlg::NameModified()
     OUString aOldName = aLine.aName;
     OUString aNewName = m_xEdName->get_text();
     aNewName = aNewName.trim();
-    m_xFtInfo->set_label_type(weld::LabelType::Normal);
+    m_xBtnOk->set_sensitive(false);
     if (aNewName != aOldName)
     {
         if (!IsNameValid())
             return;
     }
-    else
-    {
-        m_xFtInfo->set_label( maStrInfoDefault );
-    }
 
     if (!IsFormulaValid())
-    {
-        //TODO: implement an info text
         return;
-    }
+
+    m_xFtInfo->set_label_type(weld::LabelType::Normal);
+    m_xFtInfo->set_label(maStrInfoDefault);
+    m_xBtnOk->set_sensitive(true);
 
     OUString aOldScope = aLine.aScope;
     //empty table

Reply via email to