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