diff options
author | Attila Szűcs <attila.szucs@collabora.com> | 2023-07-31 04:37:07 +0200 |
---|---|---|
committer | Tomaž Vajngerl <quikee@gmail.com> | 2023-08-23 15:23:16 +0200 |
commit | 24cd55341bc3f3e8ed9d5ff23efd47a53532f283 (patch) | |
tree | e46a5314e5ef4e70212d2f05ab402a4392dfffc4 /sc/source | |
parent | a2d8f1dda7ce89ad9eef9f7c6da1024e607dc186 (diff) |
tdf#156611 SC: hyperlink option for MS behaviour
Added an options that can limit Calc to behave like MS excel in case
of inserting hyperlinks, when MS format document is used.
Tools -> Options -> LibreOfficeDev Calc -> Compatibility -> Hyperlinks
In MS excel, only cells can have a hyperlink, and only 1.
In Calc even textfields in a cell can have hyperlinks, so it can have
multiple links in a cell, but once saved as MS format, and reloaded,
textfield links will become cell links, if there was 1 link in the cell.
If there was more links in the cell, then all will be lost.
So, when MS excel format document is edited in calc, the ability to make
text field links is useless can be missleading, and confuse users.
If this option is set, and an MS file format is opened, then insering a
hyperlink will work like if we selected the whole cell to insert the
hyperlink.
Change-Id: I7174216d10cf250d48f23f71ae681c46f7610bbc
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/155079
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolan.mcnamara@collabora.com>
Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
Diffstat (limited to 'sc/source')
-rw-r--r-- | sc/source/core/tool/appoptio.cxx | 13 | ||||
-rw-r--r-- | sc/source/ui/app/scmod.cxx | 10 | ||||
-rw-r--r-- | sc/source/ui/inc/editsh.hxx | 1 | ||||
-rw-r--r-- | sc/source/ui/inc/tpcompatibility.hxx | 1 | ||||
-rw-r--r-- | sc/source/ui/optdlg/tpcompatibility.cxx | 15 | ||||
-rw-r--r-- | sc/source/ui/view/editsh.cxx | 95 |
6 files changed, 122 insertions, 13 deletions
diff --git a/sc/source/core/tool/appoptio.cxx b/sc/source/core/tool/appoptio.cxx index 9dbc85f310ae..516c1a67e91f 100644 --- a/sc/source/core/tool/appoptio.cxx +++ b/sc/source/core/tool/appoptio.cxx @@ -80,6 +80,7 @@ void ScAppOptions::SetDefaults() mbShowSharedDocumentWarning = true; meKeyBindingType = ScOptionsUtil::KEY_DEFAULT; + mbLinksInsertedLikeMSExcel = false; } ScAppOptions& ScAppOptions::operator=( const ScAppOptions& rCpy ) @@ -101,6 +102,7 @@ ScAppOptions& ScAppOptions::operator=( const ScAppOptions& rCpy ) nDefaultObjectSizeHeight = rCpy.nDefaultObjectSizeHeight; mbShowSharedDocumentWarning = rCpy.mbShowSharedDocumentWarning; meKeyBindingType = rCpy.meKeyBindingType; + mbLinksInsertedLikeMSExcel = rCpy.mbLinksInsertedLikeMSExcel; return *this; } @@ -192,6 +194,7 @@ constexpr OUStringLiteral CFGPATH_MISC = u"Office.Calc/Misc"; constexpr OUStringLiteral CFGPATH_COMPAT = u"Office.Calc/Compatibility"; #define SCCOMPATOPT_KEY_BINDING 0 +#define SCCOMPATOPT_LINK_LIKE_MS 1 // Default value of Layout/Other/StatusbarMultiFunction #define SCLAYOUTOPT_STATUSBARMULTI_DEFAULTVAL 514 @@ -258,7 +261,8 @@ Sequence<OUString> ScAppCfg::GetMiscPropertyNames() Sequence<OUString> ScAppCfg::GetCompatPropertyNames() { - return {"KeyBindings/BaseGroup"}; // SCCOMPATOPT_KEY_BINDING + return {"KeyBindings/BaseGroup", // SCCOMPATOPT_KEY_BINDING + "Links" }; // SCCOMPATOPT_LINK_LIKE_MS } ScAppCfg::ScAppCfg() : @@ -455,6 +459,10 @@ void ScAppCfg::ReadCompatCfg() sal_Int32 nIntVal = 0; // 0 = 'Default' aValues[SCCOMPATOPT_KEY_BINDING] >>= nIntVal; SetKeyBindingType(static_cast<ScOptionsUtil::KeyBindingType>(nIntVal)); + + if (aValues.getLength() > SCCOMPATOPT_LINK_LIKE_MS) + SetLinksInsertedLikeMSExcel( + ScUnoHelpFunctions::GetBoolFromAny(aValues[SCCOMPATOPT_LINK_LIKE_MS])); } IMPL_LINK_NOARG(ScAppCfg, LayoutCommitHdl, ScLinkConfigItem&, void) @@ -626,6 +634,9 @@ IMPL_LINK_NOARG(ScAppCfg, CompatCommitHdl, ScLinkConfigItem&, void) case SCCOMPATOPT_KEY_BINDING: pValues[nProp] <<= static_cast<sal_Int32>(GetKeyBindingType()); break; + case SCCOMPATOPT_LINK_LIKE_MS: + pValues[nProp] <<= GetLinksInsertedLikeMSExcel(); + break; } } aCompatItem.PutProperties(aNames, aValues); diff --git a/sc/source/ui/app/scmod.cxx b/sc/source/ui/app/scmod.cxx index b78d9fea6750..3cab82d17de6 100644 --- a/sc/source/ui/app/scmod.cxx +++ b/sc/source/ui/app/scmod.cxx @@ -982,6 +982,12 @@ void ScModule::ModifyOptions( const SfxItemSet& rOptSet ) } } + if (const SfxBoolItem* pItem = rOptSet.GetItemIfSet(SID_SC_OPT_LINKS)) + { + aAppOptions.SetLinksInsertedLikeMSExcel(pItem->GetValue()); + bSaveAppOptions = true; + } + // DefaultsOptions if (const ScTpDefaultsItem* pItem = rOptSet.GetItemIfSet(SID_SCDEFAULTSOPTIONS)) { @@ -1973,7 +1979,8 @@ std::optional<SfxItemSet> ScModule::CreateItemSet( sal_uInt16 nId ) SID_SC_INPUT_TEXTWYSIWYG, SID_SC_INPUT_TEXTWYSIWYG, SID_SC_INPUT_REPLCELLSWARN, SID_SC_INPUT_REPLCELLSWARN, // TP_VIEW: - SID_SC_OPT_SYNCZOOM, SID_SC_OPT_KEY_BINDING_COMPAT>); + SID_SC_OPT_SYNCZOOM, SID_SC_OPT_KEY_BINDING_COMPAT, + SID_SC_OPT_LINKS, SID_SC_OPT_LINKS>); const ScAppOptions& rAppOpt = GetAppOptions(); @@ -2046,6 +2053,7 @@ std::optional<SfxItemSet> ScModule::CreateItemSet( sal_uInt16 nId ) // TP_COMPATIBILITY pRet->Put( SfxUInt16Item( SID_SC_OPT_KEY_BINDING_COMPAT, rAppOpt.GetKeyBindingType() ) ); + pRet->Put( SfxBoolItem( SID_SC_OPT_LINKS, rAppOpt.GetLinksInsertedLikeMSExcel())); // TP_DEFAULTS pRet->Put( ScTpDefaultsItem( GetDefaultsOptions() ) ); diff --git a/sc/source/ui/inc/editsh.hxx b/sc/source/ui/inc/editsh.hxx index 5fb8a3c9ade8..01457c3b7f2a 100644 --- a/sc/source/ui/inc/editsh.hxx +++ b/sc/source/ui/inc/editsh.hxx @@ -49,6 +49,7 @@ private: std::optional<bool> moAtContextMenu_DisableEditHyperlink; const SvxURLField* GetURLField(); + const SvxURLField* GetFirstURLFieldFromCell(); ScInputHandler* GetMyInputHdl(); DECL_LINK( ClipboardChanged, TransferableDataHelper*, void ); diff --git a/sc/source/ui/inc/tpcompatibility.hxx b/sc/source/ui/inc/tpcompatibility.hxx index c2fe28358928..942564f02436 100644 --- a/sc/source/ui/inc/tpcompatibility.hxx +++ b/sc/source/ui/inc/tpcompatibility.hxx @@ -24,6 +24,7 @@ public: private: std::unique_ptr<weld::ComboBox> m_xLbKeyBindings; + std::unique_ptr<weld::CheckButton> m_xBtnLink; }; /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/ui/optdlg/tpcompatibility.cxx b/sc/source/ui/optdlg/tpcompatibility.cxx index f468a68f679e..a9333e3153ad 100644 --- a/sc/source/ui/optdlg/tpcompatibility.cxx +++ b/sc/source/ui/optdlg/tpcompatibility.cxx @@ -10,6 +10,7 @@ #undef SC_DLLIMPLEMENTATION #include <svl/intitem.hxx> +#include <svl/eitem.hxx> #include <tpcompatibility.hxx> #include <sc.hrc> @@ -18,6 +19,7 @@ ScTpCompatOptions::ScTpCompatOptions(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet &rCoreAttrs) : SfxTabPage(pPage, pController, "modules/scalc/ui/optcompatibilitypage.ui", "OptCompatibilityPage", &rCoreAttrs) , m_xLbKeyBindings(m_xBuilder->weld_combo_box("keybindings")) + , m_xBtnLink(m_xBuilder->weld_check_button("cellLinkCB")) { } @@ -40,6 +42,12 @@ bool ScTpCompatOptions::FillItemSet(SfxItemSet *rCoreAttrs) SID_SC_OPT_KEY_BINDING_COMPAT, m_xLbKeyBindings->get_active())); bRet = true; } + if (m_xBtnLink->get_state_changed_from_saved()) + { + rCoreAttrs->Put(SfxBoolItem(SID_SC_OPT_LINKS, m_xBtnLink->get_active())); + bRet = true; + } + return bRet; } @@ -62,8 +70,13 @@ void ScTpCompatOptions::Reset(const SfxItemSet *rCoreAttrs) ; } } - m_xLbKeyBindings->save_value(); + + if (const SfxBoolItem* pbItem = rCoreAttrs->GetItemIfSet(SID_SC_OPT_LINKS)) + { + m_xBtnLink->set_active(pbItem->GetValue()); + } + m_xBtnLink->save_state(); } DeactivateRC ScTpCompatOptions::DeactivatePage(SfxItemSet* /*pSet*/) diff --git a/sc/source/ui/view/editsh.cxx b/sc/source/ui/view/editsh.cxx index 34057df0e05f..99d84ca1518f 100644 --- a/sc/source/ui/view/editsh.cxx +++ b/sc/source/ui/view/editsh.cxx @@ -44,6 +44,8 @@ #include <editeng/wghtitem.hxx> #include <sfx2/bindings.hxx> #include <sfx2/dispatch.hxx> +#include <sfx2/docfile.hxx> +#include <sfx2/docfilt.hxx> #include <sfx2/msg.hxx> #include <sfx2/objface.hxx> #include <sfx2/objsh.hxx> @@ -59,6 +61,8 @@ #include <editsh.hxx> #include <global.hxx> +#include <appoptio.hxx> +#include <scmod.hxx> #include <sc.hrc> #include <scmod.hxx> #include <inputhdl.hxx> @@ -567,8 +571,12 @@ void ScEditShell::Execute( SfxRequest& rReq ) const OUString& rTarget = pHyper->GetTargetFrame(); SvxLinkInsertMode eMode = pHyper->GetInsertMode(); + bool bCellLinksOnly + = SC_MOD()->GetAppOptions().GetLinksInsertedLikeMSExcel() + && rViewData.GetSfxDocShell()->GetMedium()->GetFilter()->IsMSOFormat(); + bool bDone = false; - if ( eMode == HLINK_DEFAULT || eMode == HLINK_FIELD ) + if ( (eMode == HLINK_DEFAULT || eMode == HLINK_FIELD) && !bCellLinksOnly ) { const SvxURLField* pURLField = GetURLField(); if ( pURLField ) @@ -607,6 +615,17 @@ void ScEditShell::Execute( SfxRequest& rReq ) if (!bDone) { + if (bCellLinksOnly) + { + sal_Int32 nPar = pEngine->GetParagraphCount(); + if (nPar) + { + sal_Int32 nLen = pEngine->GetTextLen(nPar - 1); + pTableView->SetSelection(ESelection(0, 0, nPar - 1, nLen)); + if (pTopView) + pTopView->SetSelection(ESelection(0, 0, nPar - 1, nLen)); + } + } rViewData.GetViewShell()-> InsertURL( rName, rURL, rTarget, static_cast<sal_uInt16>(eMode) ); @@ -771,19 +790,43 @@ void ScEditShell::GetState( SfxItemSet& rSet ) case SID_HYPERLINK_GETLINK: { SvxHyperlinkItem aHLinkItem; + bool bCellLinksOnly + = SC_MOD()->GetAppOptions().GetLinksInsertedLikeMSExcel() + && rViewData.GetSfxDocShell()->GetMedium()->GetFilter()->IsMSOFormat(); const SvxURLField* pURLField = GetURLField(); - if ( pURLField ) + if (!bCellLinksOnly) { - aHLinkItem.SetName( pURLField->GetRepresentation() ); - aHLinkItem.SetURL( pURLField->GetURL() ); - aHLinkItem.SetTargetFrame( pURLField->GetTargetFrame() ); + if (pURLField) + { + aHLinkItem.SetName(pURLField->GetRepresentation()); + aHLinkItem.SetURL(pURLField->GetURL()); + aHLinkItem.SetTargetFrame(pURLField->GetTargetFrame()); + } + else if (pActiveView) + { + // use selected text as name for urls + OUString sReturn = pActiveView->GetSelected(); + sReturn = sReturn.copy( + 0, std::min(sReturn.getLength(), static_cast<sal_Int32>(255))); + aHLinkItem.SetName(comphelper::string::stripEnd(sReturn, ' ')); + } } - else if ( pActiveView ) + else { - // use selected text as name for urls - OUString sReturn = pActiveView->GetSelected(); - sReturn = sReturn.copy(0, std::min(sReturn.getLength(), static_cast<sal_Int32>(255))); - aHLinkItem.SetName(comphelper::string::stripEnd(sReturn, ' ')); + if (!pURLField) + { + pURLField = GetFirstURLFieldFromCell(); + } + if (pURLField) + { + aHLinkItem.SetURL(pURLField->GetURL()); + aHLinkItem.SetTargetFrame(pURLField->GetTargetFrame()); + } + ScDocument& rDoc = rViewData.GetDocument(); + SCCOL nPosX = rViewData.GetCurX(); + SCROW nPosY = rViewData.GetCurY(); + SCTAB nTab = rViewData.GetTabNo(); + aHLinkItem.SetName(rDoc.GetString(nPosX, nPosY, nTab)); } rSet.Put(aHLinkItem); } @@ -865,6 +908,38 @@ const SvxURLField* ScEditShell::GetURLField() return nullptr; } +const SvxURLField* ScEditShell::GetFirstURLFieldFromCell() +{ + EditEngine* pEE = GetEditView()->GetEditEngine(); + sal_Int32 nParaCount = pEE->GetParagraphCount(); + for (sal_Int32 nPara = 0; nPara < nParaCount; ++nPara) + { + ESelection aSel(nPara, 0); + std::vector<sal_Int32> aPosList; + pEE->GetPortions(nPara, aPosList); + for (const auto& rPos : aPosList) + { + aSel.nEndPos = rPos; + + SfxItemSet aEditSet(pEE->GetAttribs(aSel)); + if (aSel.nStartPos + 1 == aSel.nEndPos) + { + // test if the character is a text field + if (const SvxFieldItem* pItem = aEditSet.GetItemIfSet(EE_FEATURE_FIELD, false)) + { + const SvxFieldData* pField = pItem->GetField(); + if (const SvxURLField* pUrlField = dynamic_cast<const SvxURLField*>(pField)) + { + return pUrlField; + } + } + } + aSel.nStartPos = aSel.nEndPos; + } + } + return nullptr; +} + IMPL_LINK( ScEditShell, ClipboardChanged, TransferableDataHelper*, pDataHelper, void ) { bPastePossible = ( pDataHelper->HasFormat( SotClipboardFormatId::STRING ) |