sc/inc/rangeutl.hxx | 9 +++++++ sc/source/core/tool/rangeutl.cxx | 44 +++++++++++++++++++++++---------------- sc/source/ui/app/inputwin.cxx | 28 ++++++++++++++++++++---- sc/source/ui/view/tabvwsh3.cxx | 7 +++++- 4 files changed, 63 insertions(+), 25 deletions(-)
New commits: commit fb68609fadc7fd46c44f404ac611d87e2cc03ea0 Author: Eike Rathke <er...@redhat.com> AuthorDate: Tue Mar 30 19:04:55 2021 +0200 Commit: Eike Rathke <er...@redhat.com> CommitDate: Tue Mar 30 22:28:45 2021 +0200 Related: tdf#137577 Be able to select a global named range from Name Box ... if an identical sheet-local name exists. Change-Id: I6d92a7ed93e81da64f60c26fd81eb6775582b053 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/113384 Reviewed-by: Eike Rathke <er...@redhat.com> Tested-by: Jenkins diff --git a/sc/inc/rangeutl.hxx b/sc/inc/rangeutl.hxx index aca68c6c3def..2f4a988725be 100644 --- a/sc/inc/rangeutl.hxx +++ b/sc/inc/rangeutl.hxx @@ -32,7 +32,14 @@ class ScArea; class ScDocument; class ScRangeList; -enum RutlNameScope { RUTL_NONE=0, RUTL_NAMES, RUTL_DBASE }; +enum RutlNameScope +{ + RUTL_NONE = 0, + RUTL_NAMES, + RUTL_NAMES_LOCAL, + RUTL_NAMES_GLOBAL, + RUTL_DBASE +}; class SC_DLLPUBLIC ScRangeUtil { diff --git a/sc/source/core/tool/rangeutl.cxx b/sc/source/core/tool/rangeutl.cxx index 18473e0a3d5f..a80db03c56f1 100644 --- a/sc/source/core/tool/rangeutl.cxx +++ b/sc/source/core/tool/rangeutl.cxx @@ -248,35 +248,43 @@ bool ScRangeUtil::MakeRangeFromName ( SCROW nRowStart = 0; SCROW nRowEnd = 0; - if( eScope==RUTL_NAMES ) + if (eScope == RUTL_NAMES || eScope == RUTL_NAMES_LOCAL || eScope == RUTL_NAMES_GLOBAL) { OUString aName(rName); SCTAB nTable = nCurTab; - // First handle UI names like "local1 (Sheet1)", which point to a local - // range name. - const sal_Int32 nEndPos = aName.getLength() - 1; - if (rName[nEndPos] == ')') + if (eScope != RUTL_NAMES_GLOBAL) { - const sal_Int32 nStartPos = aName.indexOf(" ("); - if (nStartPos != -1) + // First handle UI names like "local1 (Sheet1)", which point to a + // local range name. + const sal_Int32 nEndPos = aName.getLength() - 1; + if (rName[nEndPos] == ')') { - OUString aSheetName = aName.copy(nStartPos+2, nEndPos-nStartPos-2); - if (rDoc.GetTable(aSheetName, nTable)) + const sal_Int32 nStartPos = aName.indexOf(" ("); + if (nStartPos != -1) { - aName = aName.copy(0, nStartPos); + OUString aSheetName = aName.copy(nStartPos+2, nEndPos-nStartPos-2); + if (rDoc.GetTable(aSheetName, nTable)) + { + aName = aName.copy(0, nStartPos); + eScope = RUTL_NAMES_LOCAL; + } + else + nTable = nCurTab; } - else - nTable = nCurTab; } } - // Then check for local range names. - ScRangeName* pRangeNames = rDoc.GetRangeName( nTable ); - ScRangeData* pData = nullptr; + aName = ScGlobal::getCharClassPtr()->uppercase(aName); - if ( pRangeNames ) - pData = pRangeNames->findByUpperName(aName); - if (!pData) + ScRangeData* pData = nullptr; + if (eScope != RUTL_NAMES_GLOBAL) + { + // Check for local range names. + ScRangeName* pRangeNames = rDoc.GetRangeName( nTable ); + if ( pRangeNames ) + pData = pRangeNames->findByUpperName(aName); + } + if (!pData && eScope != RUTL_NAMES_LOCAL) pData = rDoc.GetRangeName()->findByUpperName(aName); if (pData) { diff --git a/sc/source/ui/app/inputwin.cxx b/sc/source/ui/app/inputwin.cxx index 3473ffc48109..2b5a48c09d38 100644 --- a/sc/source/ui/app/inputwin.cxx +++ b/sc/source/ui/app/inputwin.cxx @@ -101,7 +101,8 @@ enum ScNameInputType { SC_NAME_INPUT_CELL, SC_NAME_INPUT_RANGE, - SC_NAME_INPUT_NAMEDRANGE, + SC_NAME_INPUT_NAMEDRANGE_LOCAL, + SC_NAME_INPUT_NAMEDRANGE_GLOBAL, SC_NAME_INPUT_DATABASE, SC_NAME_INPUT_ROW, SC_NAME_INPUT_SHEET, @@ -2323,14 +2324,23 @@ static ScNameInputType lcl_GetInputType( const OUString& rText ) SCTAB nNameTab; sal_Int32 nNumeric; + // From the context we know that when testing for a range name + // sheet-local scope names have " (sheetname)" appended and global + // names don't and can't contain ')', so we can force one or the other. + const RutlNameScope eNameScope = + ((!rText.isEmpty() && rText[rText.getLength()-1] == ')') ? RUTL_NAMES_LOCAL : RUTL_NAMES_GLOBAL); + if (rText == ScResId(STR_MANAGE_NAMES)) eRet = SC_MANAGE_NAMES; else if ( aRange.Parse( rText, rDoc, eConv ) & ScRefFlags::VALID ) eRet = SC_NAME_INPUT_RANGE; else if ( aAddress.Parse( rText, rDoc, eConv ) & ScRefFlags::VALID ) eRet = SC_NAME_INPUT_CELL; - else if ( ScRangeUtil::MakeRangeFromName( rText, rDoc, nTab, aRange, RUTL_NAMES, eConv ) ) - eRet = SC_NAME_INPUT_NAMEDRANGE; + else if ( ScRangeUtil::MakeRangeFromName( rText, rDoc, nTab, aRange, eNameScope, eConv ) ) + { + eRet = ((eNameScope == RUTL_NAMES_LOCAL) ? SC_NAME_INPUT_NAMEDRANGE_LOCAL : + SC_NAME_INPUT_NAMEDRANGE_GLOBAL); + } else if ( ScRangeUtil::MakeRangeFromName( rText, rDoc, nTab, aRange, RUTL_DBASE, eConv ) ) eRet = SC_NAME_INPUT_DATABASE; else if ( comphelper::string::isdigitAsciiString( rText ) && @@ -2375,7 +2385,8 @@ IMPL_LINK_NOARG(ScPosWnd, ModifyHdl, weld::ComboBox&, void) pStrId = STR_NAME_INPUT_CELL; break; case SC_NAME_INPUT_RANGE: - case SC_NAME_INPUT_NAMEDRANGE: + case SC_NAME_INPUT_NAMEDRANGE_LOCAL: + case SC_NAME_INPUT_NAMEDRANGE_GLOBAL: pStrId = STR_NAME_INPUT_RANGE; // named range or range reference break; case SC_NAME_INPUT_DATABASE: @@ -2483,6 +2494,7 @@ void ScPosWnd::DoEnter() } else { + bool bForceGlobalName = false; // for all selection types, execute the SID_CURRENTCELL slot. if (eType == SC_NAME_INPUT_CELL || eType == SC_NAME_INPUT_RANGE) { @@ -2492,13 +2504,19 @@ void ScPosWnd::DoEnter() aRange.ParseAny(aText, rDoc, rDoc.GetAddressConvention()); aText = aRange.Format(rDoc, ScRefFlags::RANGE_ABS_3D, ::formula::FormulaGrammar::CONV_OOO); } + else if (eType == SC_NAME_INPUT_NAMEDRANGE_GLOBAL) + { + bForceGlobalName = true; + } SfxStringItem aPosItem( SID_CURRENTCELL, aText ); SfxBoolItem aUnmarkItem( FN_PARAM_1, true ); // remove existing selection + // FN_PARAM_2 reserved for AlignToCursor + SfxBoolItem aForceGlobalName( FN_PARAM_3, bForceGlobalName ); pViewSh->GetViewData().GetDispatcher().ExecuteList( SID_CURRENTCELL, SfxCallMode::SYNCHRON | SfxCallMode::RECORD, - { &aPosItem, &aUnmarkItem }); + { &aPosItem, &aUnmarkItem, &aForceGlobalName }); } } } diff --git a/sc/source/ui/view/tabvwsh3.cxx b/sc/source/ui/view/tabvwsh3.cxx index e8fb0d8a413d..7bbbd9647a4e 100644 --- a/sc/source/ui/view/tabvwsh3.cxx +++ b/sc/source/ui/view/tabvwsh3.cxx @@ -313,6 +313,10 @@ void ScTabViewShell::Execute( SfxRequest& rReq ) if (pReqArgs->GetItemState(FN_PARAM_2, true, &pItem) == SfxItemState::SET) bAlignToCursor = static_cast<const SfxBoolItem*>(pItem)->GetValue(); + bool bForceGlobalName = false; + if (pReqArgs->GetItemState(FN_PARAM_3, true, &pItem) == SfxItemState::SET) + bForceGlobalName = static_cast<const SfxBoolItem*>(pItem)->GetValue(); + if ( nSlot == SID_JUMPTOMARK ) { // URL has to be decoded for escaped characters (%20) @@ -369,8 +373,9 @@ void ScTabViewShell::Execute( SfxRequest& rReq ) // Is it a named area (first named ranges then database ranges)? else { + const RutlNameScope eScope = (bForceGlobalName ? RUTL_NAMES_GLOBAL : RUTL_NAMES); formula::FormulaGrammar::AddressConvention eConv = rDoc.GetAddressConvention(); - if( ScRangeUtil::MakeRangeFromName( aAddress, rDoc, nTab, aScRange, RUTL_NAMES, eConv ) || + if( ScRangeUtil::MakeRangeFromName( aAddress, rDoc, nTab, aScRange, eScope, eConv ) || ScRangeUtil::MakeRangeFromName( aAddress, rDoc, nTab, aScRange, RUTL_DBASE, eConv ) ) { nResult |= ScRefFlags::VALID; _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits