comphelper/source/misc/documentinfo.cxx | 14 dbaccess/source/core/dataaccess/ModelImpl.cxx | 7 dbaccess/source/core/dataaccess/databasedocument.cxx | 25 - dbaccess/source/core/inc/ModelImpl.hxx | 2 editeng/source/accessibility/AccessibleEditableTextPara.cxx | 2 include/comphelper/documentinfo.hxx | 5 include/oox/ole/axcontrol.hxx | 2 include/sfx2/docmacromode.hxx | 7 include/sfx2/objsh.hxx | 3 include/xmloff/xmlimp.hxx | 3 oox/source/ole/vbaproject.cxx | 4 sc/source/filter/excel/xiescher.cxx | 36 + sc/source/filter/inc/xiescher.hxx | 11 sc/source/ui/docshell/docsh.cxx | 13 sc/source/ui/docshell/docsh4.cxx | 64 +-- sc/source/ui/docshell/externalrefmgr.cxx | 1 sc/source/ui/inc/docsh.hxx | 2 sc/source/ui/vba/vbasheetobject.cxx | 13 sc/source/ui/vba/vbasheetobject.hxx | 4 scripting/source/protocolhandler/scripthandler.cxx | 6 sfx2/source/doc/docmacromode.cxx | 2 sfx2/source/doc/objmisc.cxx | 15 sfx2/source/doc/objstor.cxx | 10 sfx2/source/doc/objxtor.cxx | 1 sfx2/source/doc/sfxbasemodel.cxx | 7 sfx2/source/inc/objshimp.hxx | 4 sfx2/source/notify/eventsupplier.cxx | 187 +++++----- svx/source/svdraw/svdopath.cxx | 71 ++- sw/inc/doc.hxx | 3 sw/inc/fesh.hxx | 2 sw/qa/extras/uiwriter/data2/tdf126784_distributeSelectedColumns.odt |binary sw/qa/extras/uiwriter/uiwriter2.cxx | 31 + sw/source/core/docnode/ndtbl1.cxx | 32 - sw/source/core/frmedt/fetab.cxx | 4 sw/source/core/inc/frame.hxx | 4 sw/source/core/layout/calcmove.cxx | 9 sw/source/core/layout/flowfrm.cxx | 6 sw/source/filter/html/htmlform.cxx | 16 sw/source/filter/html/htmlgrin.cxx | 19 + sw/source/filter/html/swhtml.cxx | 1 sw/source/filter/html/swhtml.hxx | 3 sw/source/filter/ww8/ww8par.cxx | 11 sw/source/filter/ww8/ww8par.hxx | 2 sw/source/filter/ww8/ww8par5.cxx | 2 sw/source/filter/ww8/ww8toolbar.cxx | 6 sw/source/uibase/shells/tabsh.cxx | 3 sw/uiconfig/swriter/ui/insertcaption.ui | 2 vcl/source/app/salvtables.cxx | 86 ++-- vcl/unx/gtk3/gtk3gtkinst.cxx | 62 ++- xmloff/source/core/xmlimp.cxx | 14 xmloff/source/script/XMLEventImportHelper.cxx | 3 51 files changed, 590 insertions(+), 252 deletions(-)
New commits: commit 929c06364065879cf1e0dab329e20991094580b2 Author: Eike Rathke <[email protected]> AuthorDate: Fri Aug 16 15:36:15 2019 +0200 Commit: Andras Timar <[email protected]> CommitDate: Thu Sep 5 12:32:35 2019 +0200 Resolves: tdf#126928 allow link updates in an intermediate linked document ... if link updates are allowed in the current document and that intermediate document resides in a trusted location. This works with both, the "Always (from trusted locations)" and the "On request" settings under Tools -> Options -> Calc -> General. It can't work with documents residing in a non-trusted location as there is no way to allow updates on demand for a such loaded document (hidden via formulas). Reviewed-on: https://gerrit.libreoffice.org/77588 Reviewed-by: Eike Rathke <[email protected]> Tested-by: Jenkins (cherry picked from commit 54bf84746a2a9a2e2aaf0df9e429b0cfd538f640) Conflicts: sc/source/ui/docshell/docsh4.cxx sc/source/ui/docshell/externalrefmgr.cxx Backported. Also includes commit 1663b1e8233db6c6d1c2b35639ad984961084009 CommitDate: Tue Feb 26 21:15:57 2019 +0100 tdf#120736: For Calc shared documents also check the original document URL Change-Id: Ie483f7743db7c6d5cf947dc16a9c3660855f3423 Reviewed-on: https://gerrit.libreoffice.org/77613 Tested-by: Jenkins Reviewed-by: Caolán McNamara <[email protected]> Tested-by: Caolán McNamara <[email protected]> diff --git a/sc/source/ui/docshell/docsh.cxx b/sc/source/ui/docshell/docsh.cxx index 789d69132f78..6c2df3d95b41 100644 --- a/sc/source/ui/docshell/docsh.cxx +++ b/sc/source/ui/docshell/docsh.cxx @@ -601,15 +601,22 @@ bool ScDocShell::Load( SfxMedium& rMedium ) bool bRet = SfxObjectShell::Load(rMedium); if (bRet) { - comphelper::EmbeddedObjectContainer& rEmbeddedObjectContainer = getEmbeddedObjectContainer(); - rEmbeddedObjectContainer.setUserAllowsLinkUpdate(false); - if (GetMedium()) { const SfxUInt16Item* pUpdateDocItem = SfxItemSet::GetItem<SfxUInt16Item>(rMedium.GetItemSet(), SID_UPDATEDOCMODE, false); m_nCanUpdate = pUpdateDocItem ? pUpdateDocItem->GetValue() : css::document::UpdateDocMode::NO_UPDATE; } + // GetLinkUpdateModeState() evaluates m_nCanUpdate so that must have + // been set first. Do not override an already forbidden LinkUpdate (the + // default is allow). + comphelper::EmbeddedObjectContainer& rEmbeddedObjectContainer = getEmbeddedObjectContainer(); + if (rEmbeddedObjectContainer.getUserAllowsLinkUpdate()) + { + // For anything else than LM_ALWAYS we need user confirmation. + rEmbeddedObjectContainer.setUserAllowsLinkUpdate( GetLinkUpdateModeState() == LM_ALWAYS); + } + { // prepare a valid document for XML filter // (for ConvertFrom, InitNew is called before) diff --git a/sc/source/ui/docshell/docsh4.cxx b/sc/source/ui/docshell/docsh4.cxx index 3676e384dde2..6c08b6a234cd 100644 --- a/sc/source/ui/docshell/docsh4.cxx +++ b/sc/source/ui/docshell/docsh4.cxx @@ -154,6 +154,41 @@ IMPL_LINK_NOARG( ScDocShell, ReloadAllLinksHdl, Button*, void ) SAL_WARN_IF(!pViewFrame, "sc", "expected there to be a ViewFrame"); } +ScLkUpdMode ScDocShell::GetLinkUpdateModeState() const +{ + const ScDocument& rDoc = GetDocument(); + + ScLkUpdMode nSet = rDoc.GetLinkMode(); + + if (nSet == LM_UNKNOWN) + { + ScAppOptions aAppOptions = SC_MOD()->GetAppOptions(); + nSet = aAppOptions.GetLinkMode(); + } + + if (m_nCanUpdate == css::document::UpdateDocMode::NO_UPDATE) + nSet = LM_NEVER; + else if (m_nCanUpdate == css::document::UpdateDocMode::FULL_UPDATE) + nSet = LM_ALWAYS; + + if (nSet == LM_ALWAYS + && !(SvtSecurityOptions().isTrustedLocationUriForUpdatingLinks( + GetMedium() == nullptr ? OUString() : GetMedium()->GetName()) + || (IsDocShared() + && SvtSecurityOptions().isTrustedLocationUriForUpdatingLinks( + GetSharedFileURL())))) + { + nSet = LM_ON_DEMAND; + } + if (m_nCanUpdate == css::document::UpdateDocMode::QUIET_UPDATE + && nSet == LM_ON_DEMAND) + { + nSet = LM_NEVER; + } + + return nSet; +} + void ScDocShell::Execute( SfxRequest& rReq ) { const SfxItemSet* pReqArgs = rReq.GetArgs(); @@ -451,34 +486,7 @@ void ScDocShell::Execute( SfxRequest& rReq ) break; case SID_UPDATETABLINKS: { - ScDocument& rDoc = GetDocument(); - - ScLkUpdMode nSet = rDoc.GetLinkMode(); - - if(nSet==LM_UNKNOWN) - { - ScAppOptions aAppOptions=SC_MOD()->GetAppOptions(); - nSet=aAppOptions.GetLinkMode(); - } - - if (m_nCanUpdate == css::document::UpdateDocMode::NO_UPDATE) - nSet = LM_NEVER; - else if (m_nCanUpdate == css::document::UpdateDocMode::FULL_UPDATE) - nSet = LM_ALWAYS; - - if (nSet == LM_ALWAYS - && !(SvtSecurityOptions() - .isTrustedLocationUriForUpdatingLinks( - GetMedium() == nullptr - ? OUString() : GetMedium()->GetName()))) - { - nSet = LM_ON_DEMAND; - } - if (m_nCanUpdate == css::document::UpdateDocMode::QUIET_UPDATE - && nSet == LM_ON_DEMAND) - { - nSet = LM_NEVER; - } + ScLkUpdMode nSet = GetLinkUpdateModeState(); if (nSet == LM_ALWAYS) { diff --git a/sc/source/ui/docshell/externalrefmgr.cxx b/sc/source/ui/docshell/externalrefmgr.cxx index 14b836327f85..940717d39771 100644 --- a/sc/source/ui/docshell/externalrefmgr.cxx +++ b/sc/source/ui/docshell/externalrefmgr.cxx @@ -62,6 +62,7 @@ #include <columnspanset.hxx> #include <column.hxx> #include <com/sun/star/document/MacroExecMode.hpp> +#include <com/sun/star/document/UpdateDocMode.hpp> #include <o3tl/make_unique.hxx> #include <sal/log.hxx> diff --git a/sc/source/ui/inc/docsh.hxx b/sc/source/ui/inc/docsh.hxx index 1e99ea3e6a73..3bb87d908002 100644 --- a/sc/source/ui/inc/docsh.hxx +++ b/sc/source/ui/inc/docsh.hxx @@ -219,6 +219,7 @@ public: void GetDocStat( ScDocStat& rDocStat ); + const ScDocument& GetDocument() const { return m_aDocument; } ScDocument& GetDocument() { return m_aDocument; } ScDocFunc& GetDocFunc() { return *m_pDocFunc; } @@ -301,6 +302,7 @@ public: void UpdateLinks() override; void ReloadAllLinks(); void ReloadTabLinks(); + ScLkUpdMode GetLinkUpdateModeState() const; void SetFormulaOptions( const ScFormulaOptions& rOpt, bool bForLoading = false ); /** commit 2453b7d621171b33c7dcef952f4dc44d22b617db Author: Caolán McNamara <[email protected]> AuthorDate: Mon Sep 2 16:00:28 2019 +0100 Commit: Andras Timar <[email protected]> CommitDate: Thu Sep 5 12:32:34 2019 +0200 assert on selecting text from end to start in shape with a11y enabled Change-Id: I0a135236cf5e5f291b6289cc76228290a6f77e98 Reviewed-on: https://gerrit.libreoffice.org/78409 Tested-by: Jenkins Reviewed-by: Michael Stahl <[email protected]> diff --git a/editeng/source/accessibility/AccessibleEditableTextPara.cxx b/editeng/source/accessibility/AccessibleEditableTextPara.cxx index b42e895f67e0..19e67b07469b 100644 --- a/editeng/source/accessibility/AccessibleEditableTextPara.cxx +++ b/editeng/source/accessibility/AccessibleEditableTextPara.cxx @@ -2038,7 +2038,7 @@ namespace accessibility if( nIndex <= aBoundary.endPos ) { nextWord = aBoundary.endPos; - if( sText[nextWord] == u' ' ) nextWord++; + if (nextWord < sText.getLength() && sText[nextWord] == u' ') nextWord++; bWord = implGetWordBoundary( sText, aBoundary, nextWord ); } commit ab72c996352611bb7123dd2ddc45d55aa6944256 Author: Caolán McNamara <[email protected]> AuthorDate: Thu Aug 15 20:29:40 2019 +0100 Commit: Andras Timar <[email protected]> CommitDate: Thu Sep 5 12:32:34 2019 +0200 tdf#126007 tdf#122355 online help won't look into a dialog notebook when the focus is on the help button, offline will through the help fallback route, but online will just fire and forget and let the server side do a fallback, which can't know what the current notebook page was. so bodge it to look at the notebook page right from the start if there is one and its the help button itself which starts the request Change-Id: Ida1d3101d838d99639dda12c438414c16b1ccda5 Reviewed-on: https://gerrit.libreoffice.org/77550 Tested-by: Jenkins Reviewed-by: Adolfo Jayme Barrientos <[email protected]> diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx index dd3a7f26bbe0..9b4ce8144916 100644 --- a/vcl/source/app/salvtables.cxx +++ b/vcl/source/app/salvtables.cxx @@ -765,27 +765,7 @@ public: return m_xWindow->GetText(); } - void help() - { - //show help for widget with keyboard focus - vcl::Window* pWidget = ImplGetSVData()->maWinData.mpFocusWin; - if (!pWidget) - pWidget = m_xWindow; - OString sHelpId = pWidget->GetHelpId(); - while (sHelpId.isEmpty()) - { - pWidget = pWidget->GetParent(); - if (!pWidget) - break; - sHelpId = pWidget->GetHelpId(); - } - std::unique_ptr<weld::Widget> xTemp(pWidget != m_xWindow ? new SalInstanceWidget(pWidget, m_pBuilder, false) : nullptr); - weld::Widget* pSource = xTemp ? xTemp.get() : this; - bool bRunNormalHelpRequest = !m_aHelpRequestHdl.IsSet() || m_aHelpRequestHdl.Call(*pSource); - Help* pHelp = bRunNormalHelpRequest ? Application::GetHelp() : nullptr; - if (pHelp) - pHelp->Start(OStringToOUString(sHelpId, RTL_TEXTENCODING_UTF8), pSource); - } + void help(); virtual void set_busy_cursor(bool bBusy) override { @@ -3718,6 +3698,17 @@ public: return o3tl::make_unique<SalInstanceSizeGroup>(); } + OString get_current_page_help_id() + { + TabControl *pCtrl = get_builder().get<TabControl>("tabcontrol"); + TabPage* pTabPage = pCtrl ? pCtrl->GetTabPage(pCtrl->GetCurPageId()) : nullptr; + vcl::Window *pTabChild = pTabPage ? pTabPage->GetWindow(GetWindowType::FirstChild) : nullptr; + pTabChild = pTabChild ? pTabChild->GetWindow(GetWindowType::FirstChild) : nullptr; + if (pTabChild) + return pTabChild->GetHelpId(); + return OString(); + } + virtual ~SalInstanceBuilder() override { if (VclBuilderContainer* pOwnedToplevel = dynamic_cast<VclBuilderContainer*>(m_aOwnedToplevel.get())) @@ -3747,6 +3738,43 @@ weld::Builder* Application::CreateInterimBuilder(weld::Widget* pParent, const OU return Application::CreateInterimBuilder(pParentWidget, rUIFile); } +void SalInstanceWindow::help() +{ + //show help for widget with keyboard focus + vcl::Window* pWidget = ImplGetSVData()->maWinData.mpFocusWin; + if (!pWidget) + pWidget = m_xWindow; + OString sHelpId = pWidget->GetHelpId(); + while (sHelpId.isEmpty()) + { + pWidget = pWidget->GetParent(); + if (!pWidget) + break; + sHelpId = pWidget->GetHelpId(); + } + std::unique_ptr<weld::Widget> xTemp(pWidget != m_xWindow ? new SalInstanceWidget(pWidget, m_pBuilder, false) : nullptr); + weld::Widget* pSource = xTemp ? xTemp.get() : this; + bool bRunNormalHelpRequest = !m_aHelpRequestHdl.IsSet() || m_aHelpRequestHdl.Call(*pSource); + Help* pHelp = bRunNormalHelpRequest ? Application::GetHelp() : nullptr; + if (pHelp) + { + // tdf#126007, there's a nice fallback route for offline help where + // the current page of a notebook will get checked when the help + // button is pressed and there was no help for the dialog found. + // + // But for online help that route doesn't get taken, so bodge this here + // by using the page help id if available and if the help button itself + // was the original id + if (m_pBuilder && sHelpId.endsWith("/help")) + { + OString sPageId = m_pBuilder->get_current_page_help_id(); + if (!sPageId.isEmpty()) + sHelpId = sPageId; + } + pHelp->Start(OStringToOUString(sHelpId, RTL_TEXTENCODING_UTF8), pSource); + } +} + //iterate upwards through the hierarchy from this widgets through its parents //calling func with their helpid until func returns true or we run out of parents void SalInstanceWidget::help_hierarchy_foreach(const std::function<bool(const OString&)>& func) @@ -3756,17 +3784,11 @@ void SalInstanceWidget::help_hierarchy_foreach(const std::function<bool(const OS { if (m_pBuilder && pParent->IsDialog()) { - // tdf#122355 During help fallback, before we ask a dialog for its help - // see if it has a TabControl and ask the active tab of that for help - TabControl *pCtrl = m_pBuilder->get_builder().get<TabControl>("tabcontrol"); - TabPage* pTabPage = pCtrl ? pCtrl->GetTabPage(pCtrl->GetCurPageId()) : nullptr; - vcl::Window *pTabChild = pTabPage ? pTabPage->GetWindow(GetWindowType::FirstChild) : nullptr; - pTabChild = pTabChild ? pTabChild->GetWindow(GetWindowType::FirstChild) : nullptr; - if (pTabChild) - { - if (func(pTabChild->GetHelpId())) - return; - } + // tdf#122355 before trying dialog help, check to see if there is a notebook + // called tabcontrol, and try the help for the current page of that first + OString sPageHelpId(m_pBuilder->get_current_page_help_id()); + if (!sPageHelpId.isEmpty() && func(sPageHelpId)) + return; } if (func(pParent->GetHelpId())) return; diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx index 9831762f4a43..532ec11ffe27 100644 --- a/vcl/unx/gtk3/gtk3gtkinst.cxx +++ b/vcl/unx/gtk3/gtk3gtkinst.cxx @@ -7851,6 +7851,31 @@ public: m_aMnemonicButtons.clear(); } + OString get_current_page_help_id() + { + OString sPageHelpId; + // check to see if there is a notebook called tabcontrol and get the + // helpid for the current page of that + std::unique_ptr<weld::Notebook> xNotebook(weld_notebook("tabcontrol", false)); + if (xNotebook) + { + if (GtkInstanceContainer* pPage = dynamic_cast<GtkInstanceContainer*>(xNotebook->get_page(xNotebook->get_current_page_ident()))) + { + GtkWidget* pContainer = pPage->getWidget(); + GList* pChildren = gtk_container_get_children(GTK_CONTAINER(pContainer)); + GList* pChild = g_list_first(pChildren); + if (pChild) + { + GtkWidget* pPageWidget = static_cast<GtkWidget*>(pChild->data); + sPageHelpId = ::get_help_id(pPageWidget); + } + g_list_free(pChildren); + } + } + return sPageHelpId; + } + + virtual ~GtkInstanceBuilder() override { g_slist_free(m_pObjectList); @@ -8147,7 +8172,22 @@ void GtkInstanceWindow::help() bool bRunNormalHelpRequest = !m_aHelpRequestHdl.IsSet() || m_aHelpRequestHdl.Call(*pSource); Help* pHelp = bRunNormalHelpRequest ? Application::GetHelp() : nullptr; if (pHelp) + { + // tdf#126007, there's a nice fallback route for offline help where + // the current page of a notebook will get checked when the help + // button is pressed and there was no help for the dialog found. + // + // But for online help that route doesn't get taken, so bodge this here + // by using the page help id if available and if the help button itself + // was the original id + if (m_pBuilder && sHelpId.endsWith("/help")) + { + OString sPageId = m_pBuilder->get_current_page_help_id(); + if (!sPageId.isEmpty()) + sHelpId = sPageId; + } pHelp->Start(OStringToOUString(sHelpId, RTL_TEXTENCODING_UTF8), pSource); + } } //iterate upwards through the hierarchy from this widgets through its parents @@ -8161,25 +8201,9 @@ void GtkInstanceWidget::help_hierarchy_foreach(const std::function<bool(const OS // called tabcontrol, and try the help for the current page of that first if (m_pBuilder && GTK_IS_DIALOG(pParent)) { - std::unique_ptr<weld::Notebook> xNotebook(m_pBuilder->weld_notebook("tabcontrol", false)); - if (xNotebook) - { - if (GtkInstanceContainer* pPage = dynamic_cast<GtkInstanceContainer*>(xNotebook->get_page(xNotebook->get_current_page_ident()))) - { - bool bFinished = false; - GtkWidget* pContainer = pPage->getWidget(); - GList* pChildren = gtk_container_get_children(GTK_CONTAINER(pContainer)); - GList* pChild = g_list_first(pChildren); - if (pChild) - { - GtkWidget* pPageWidget = static_cast<GtkWidget*>(pChild->data); - bFinished = func(::get_help_id(pPageWidget)); - } - g_list_free(pChildren); - if (bFinished) - return; - } - } + OString sPageHelpId(m_pBuilder->get_current_page_help_id()); + if (!sPageHelpId.isEmpty() && func(sPageHelpId)) + return; } if (func(::get_help_id(pParent))) return; commit 2b802429df9ef3f802da269b29f9e872dc254c0f Author: Caolán McNamara <[email protected]> AuthorDate: Wed Aug 7 17:37:11 2019 +0100 Commit: Andras Timar <[email protected]> CommitDate: Thu Sep 5 12:32:33 2019 +0200 warn on load when a document binds an event to a macro a) treat shared/Scripts equivalently to document scripts This doesn't automatically warn/block running those scripts when used in a freshly loaded document on its own however because DocumentMacroMode::checkMacrosOnLoading will see at... if ( m_xData->m_rDocumentAccess.documentStorageHasMacros() || hasMacroLibrary() ) that the document contains no macros and flip the allow macros flag to true so that potentially new uses of macros added by the user during the edit are allowed to run b) so, add an additional flag to indicate existence of use of macros in a document c) for odf import, set it when a script:event-listener tag is encountered d) for html import when registerScriptEvents or SwFormatINetFormat::SetMacroTable is called e) for doc import when Read_F_Macro or StoreMacroCmds is called as well for good measure f) for xls import when registerScriptEvent or ScMacroInfo::SetMacro is called g) for oox import when VbaProject::attachMacros is called Change-Id: Ic1203d8ec7dfc217aa217135033ae9db2888e19b Reviewed-on: https://gerrit.libreoffice.org/77387 Tested-by: Jenkins Reviewed-by: Christian Lohmaier <[email protected]> diff --git a/comphelper/source/misc/documentinfo.cxx b/comphelper/source/misc/documentinfo.cxx index 8d96d5f5e77e..2aceb182380a 100644 --- a/comphelper/source/misc/documentinfo.cxx +++ b/comphelper/source/misc/documentinfo.cxx @@ -158,6 +158,20 @@ namespace comphelper { return sTitle; } + void DocumentInfo::notifyMacroEventRead(const css::uno::Reference<css::frame::XModel>& rModel) + { + if (!rModel.is()) + return; + + // like BreakMacroSignature of XMLScriptContext use XModel::attachResource + // to propagate this notification + css::uno::Sequence<css::beans::PropertyValue> aMedDescr = rModel->getArgs(); + sal_Int32 nNewLen = aMedDescr.getLength() + 1; + aMedDescr.realloc(nNewLen); + aMedDescr[nNewLen-1].Name = "MacroEventRead"; + aMedDescr[nNewLen-1].Value <<= true; + rModel->attachResource(rModel->getURL(), aMedDescr); + } } // namespace comphelper diff --git a/dbaccess/source/core/dataaccess/ModelImpl.cxx b/dbaccess/source/core/dataaccess/ModelImpl.cxx index bbf82b903c61..4d7a25818b6a 100644 --- a/dbaccess/source/core/dataaccess/ModelImpl.cxx +++ b/dbaccess/source/core/dataaccess/ModelImpl.cxx @@ -374,6 +374,7 @@ ODatabaseModelImpl::ODatabaseModelImpl( const Reference< XComponentContext >& _r ,m_bSuppressVersionColumns(true) ,m_bModified(false) ,m_bDocumentReadOnly(false) + ,m_bMacroCallsSeenWhileLoading(false) ,m_pSharedConnectionManager(nullptr) ,m_nControllerLockCount(0) { @@ -407,6 +408,7 @@ ODatabaseModelImpl::ODatabaseModelImpl( ,m_bSuppressVersionColumns(true) ,m_bModified(false) ,m_bDocumentReadOnly(false) + ,m_bMacroCallsSeenWhileLoading(false) ,m_pSharedConnectionManager(nullptr) ,m_nControllerLockCount(0) { @@ -1270,6 +1272,11 @@ bool ODatabaseModelImpl::documentStorageHasMacros() const return ( *m_aEmbeddedMacros != eNoMacros ); } +bool ODatabaseModelImpl::macroCallsSeenWhileLoading() const +{ + return m_bMacroCallsSeenWhileLoading; +} + Reference< XEmbeddedScripts > ODatabaseModelImpl::getEmbeddedDocumentScripts() const { return Reference< XEmbeddedScripts >( getModel_noCreate(), UNO_QUERY ); diff --git a/dbaccess/source/core/dataaccess/databasedocument.cxx b/dbaccess/source/core/dataaccess/databasedocument.cxx index c79c303e508a..d3726084217b 100644 --- a/dbaccess/source/core/dataaccess/databasedocument.cxx +++ b/dbaccess/source/core/dataaccess/databasedocument.cxx @@ -747,15 +747,24 @@ sal_Bool SAL_CALL ODatabaseDocument::attachResource( const OUString& _rURL, cons bool ODatabaseDocument::impl_attachResource( const OUString& i_rLogicalDocumentURL, const Sequence< PropertyValue >& i_rMediaDescriptor, DocumentGuard& _rDocGuard ) { - if ( ( i_rLogicalDocumentURL == getURL() ) - && ( i_rMediaDescriptor.getLength() == 1 ) - && ( i_rMediaDescriptor[0].Name == "BreakMacroSignature" ) - ) + if (i_rLogicalDocumentURL == getURL()) { - // this is a BAD hack of the Basic importer code ... there should be a dedicated API for this, - // not this bad mis-using of existing interfaces - return false; - // (we do not support macro signatures, so we can ignore this call) + ::comphelper::NamedValueCollection aArgs(i_rMediaDescriptor); + + // this misuse of attachresource is a hack of the Basic importer code + // repurposing existing interfaces for uses it probably wasn't intended + // for + + // we do not support macro signatures, so we can ignore that request + aArgs.remove("BreakMacroSignature"); + + bool bMacroEventRead = false; + if ((aArgs.get( "MacroEventRead" ) >>= bMacroEventRead) && bMacroEventRead) + m_pImpl->m_bMacroCallsSeenWhileLoading = true; + aArgs.remove( "MacroEventRead" ); + + if (aArgs.empty()) + return false; } // if no URL has been provided, the caller was lazy enough to not call our getURL - which is not allowed anymore, diff --git a/dbaccess/source/core/inc/ModelImpl.hxx b/dbaccess/source/core/inc/ModelImpl.hxx index ab4276c4e5cf..bc97f4be969f 100644 --- a/dbaccess/source/core/inc/ModelImpl.hxx +++ b/dbaccess/source/core/inc/ModelImpl.hxx @@ -206,6 +206,7 @@ public: bool m_bSuppressVersionColumns : 1; bool m_bModified : 1; bool m_bDocumentReadOnly : 1; + bool m_bMacroCallsSeenWhileLoading : 1; css::uno::Reference< css::beans::XPropertyBag > m_xSettings; css::uno::Sequence< OUString > m_aTableFilter; @@ -434,6 +435,7 @@ public: virtual void setCurrentMacroExecMode( sal_uInt16 ) override; virtual OUString getDocumentLocation() const override; virtual bool documentStorageHasMacros() const override; + virtual bool macroCallsSeenWhileLoading() const override; virtual css::uno::Reference< css::document::XEmbeddedScripts > getEmbeddedDocumentScripts() const override; virtual SignatureState getScriptingSignatureState() override; virtual bool hasTrustedScriptingSignature( bool bAllowUIToAddAuthor ) override; diff --git a/include/comphelper/documentinfo.hxx b/include/comphelper/documentinfo.hxx index d47f1d02ea50..a195722b9169 100644 --- a/include/comphelper/documentinfo.hxx +++ b/include/comphelper/documentinfo.hxx @@ -37,8 +37,11 @@ namespace comphelper { /** retrieves the UI title of the given document */ COMPHELPER_DLLPUBLIC OUString getDocumentTitle( const css::uno::Reference< css::frame::XModel >& _rxDocument ); - } + /** notify that this document contains a macro event handler + */ + COMPHELPER_DLLPUBLIC void notifyMacroEventRead( const css::uno::Reference< css::frame::XModel >& _rxDocument ); + } } // namespace comphelper diff --git a/include/oox/ole/axcontrol.hxx b/include/oox/ole/axcontrol.hxx index b53988e2f908..968360a5b39b 100644 --- a/include/oox/ole/axcontrol.hxx +++ b/include/oox/ole/axcontrol.hxx @@ -334,6 +334,8 @@ public: PropertySet const & rPropSet, sal_Int32& nOrientation ); + const css::uno::Reference<css::frame::XModel> GetDocModel() const { return mxDocModel; } + private: css::uno::Reference< css::frame::XModel > mxDocModel; const GraphicHelper& mrGraphicHelper; diff --git a/include/sfx2/docmacromode.hxx b/include/sfx2/docmacromode.hxx index f043e36a26d3..7e1511625086 100644 --- a/include/sfx2/docmacromode.hxx +++ b/include/sfx2/docmacromode.hxx @@ -111,6 +111,12 @@ namespace sfx2 virtual bool documentStorageHasMacros() const = 0; + /** checks whether the document's contained calls to macros or scripts after loading + + */ + virtual bool + macroCallsSeenWhileLoading() const = 0; + /** provides access to the XEmbeddedScripts interface of the document Implementations are allowed to return <NULL/> here if and only if they @@ -272,6 +278,7 @@ namespace sfx2 @see isMacroExecutionDisallowed @see IMacroDocumentAccess::documentStorageHasMacros + @see IMacroDocumentAccess::macroCallsSeenWhileLoading @see hasMacroLibrary @see IMacroDocumentAccess::checkForBrokenScriptingSignatures */ diff --git a/include/sfx2/objsh.hxx b/include/sfx2/objsh.hxx index 027eedb860f6..c6e9b017a967 100644 --- a/include/sfx2/objsh.hxx +++ b/include/sfx2/objsh.hxx @@ -436,6 +436,9 @@ public: sal_uInt32 GetModifyPasswordHash() const; bool SetModifyPasswordHash( sal_uInt32 nHash ); + void SetMacroCallsSeenWhileLoading(); + bool GetMacroCallsSeenWhileLoading() const; + const css::uno::Sequence< css::beans::PropertyValue >& GetModifyPasswordInfo() const; bool SetModifyPasswordInfo( const css::uno::Sequence< css::beans::PropertyValue >& aInfo ); diff --git a/include/xmloff/xmlimp.hxx b/include/xmloff/xmlimp.hxx index 39415336591a..86af82e61fa5 100644 --- a/include/xmloff/xmlimp.hxx +++ b/include/xmloff/xmlimp.hxx @@ -241,6 +241,7 @@ class XMLOFF_DLLPUBLIC SvXMLImport : public cppu::WeakImplHelper< protected: bool mbIsFormsSupported; bool mbIsTableShapeSupported; + bool mbNotifyMacroEventRead; // Create top-level element context. // This method is called after the namespace map has been updated, but @@ -577,6 +578,8 @@ public: bool embeddedFontAlreadyProcessed( const OUString& url ); virtual void NotifyEmbeddedFontRead() {}; + // something referencing a macro/script was imported + void NotifyMacroEventRead(); bool needFixPositionAfterZ() const; }; diff --git a/oox/source/ole/vbaproject.cxx b/oox/source/ole/vbaproject.cxx index bba778658ae5..62ec72070b46 100644 --- a/oox/source/ole/vbaproject.cxx +++ b/oox/source/ole/vbaproject.cxx @@ -31,6 +31,7 @@ #include <com/sun/star/script/vba/XVBAMacroResolver.hpp> #include <com/sun/star/uno/XComponentContext.hpp> #include <comphelper/configurationhelper.hxx> +#include <comphelper/documentinfo.hxx> #include <comphelper/storagehelper.hxx> #include <osl/diagnose.h> #include <rtl/tencinfo.h> @@ -515,6 +516,8 @@ void VbaProject::attachMacros() { if( !maMacroAttachers.empty() && mxContext.is() ) try { + comphelper::DocumentInfo::notifyMacroEventRead(mxDocModel); + Reference< XMultiComponentFactory > xFactory( mxContext->getServiceManager(), UNO_SET_THROW ); Sequence< Any > aArgs( 2 ); aArgs[ 0 ] <<= mxDocModel; @@ -522,6 +525,7 @@ void VbaProject::attachMacros() Reference< XVBAMacroResolver > xResolver( xFactory->createInstanceWithArgumentsAndContext( "com.sun.star.script.vba.VBAMacroResolver", aArgs, mxContext ), UNO_QUERY_THROW ); maMacroAttachers.forEachMem( &VbaMacroAttacherBase::resolveAndAttachMacro, ::std::cref( xResolver ) ); + } catch(const Exception& ) { diff --git a/sc/source/filter/excel/xiescher.cxx b/sc/source/filter/excel/xiescher.cxx index 63387a275984..bcdf567e6684 100644 --- a/sc/source/filter/excel/xiescher.cxx +++ b/sc/source/filter/excel/xiescher.cxx @@ -48,6 +48,7 @@ #include <vcl/wmf.hxx> #include <comphelper/classids.hxx> #include <config_global.h> +#include <comphelper/documentinfo.hxx> #include <toolkit/helper/vclunohelper.hxx> #include <basegfx/point/b2dpoint.hxx> #include <basegfx/polygon/b2dpolygon.hxx> @@ -163,7 +164,8 @@ XclImpDrawObjBase::XclImpDrawObjBase( const XclImpRoot& rRoot ) : mbSimpleMacro( true ), mbProcessSdr( true ), mbInsertSdr( true ), - mbCustomDff( false ) + mbCustomDff( false ), + mbNotifyMacroEventRead( false ) { } @@ -499,7 +501,18 @@ SdrObjectUniquePtr XclImpDrawObjBase::CreateSdrObject( XclImpDffConverter& rDffC return xSdrObj; } -void XclImpDrawObjBase::PreProcessSdrObject( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const +void XclImpDrawObjBase::NotifyMacroEventRead() +{ + if (mbNotifyMacroEventRead) + return; + SfxObjectShell* pDocShell = GetDocShell(); + if (!pDocShell) + return; + comphelper::DocumentInfo::notifyMacroEventRead(pDocShell->GetModel()); + mbNotifyMacroEventRead = true; +} + +void XclImpDrawObjBase::PreProcessSdrObject( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) { // default: front layer, derived classes may have to set other layer in DoPreProcessSdrObj() rSdrObj.NbcSetLayer( SC_LAYER_FRONT ); @@ -526,7 +539,10 @@ void XclImpDrawObjBase::PreProcessSdrObject( XclImpDffConverter& rDffConv, SdrOb { if( ScMacroInfo* pInfo = ScDrawLayer::GetMacroInfo( &rSdrObj, true ) ) { - pInfo->SetMacro( XclTools::GetSbMacroUrl( maMacroName, GetDocShell() ) ); + OUString sMacro = XclTools::GetSbMacroUrl(maMacroName, GetDocShell()); + if (!sMacro.isEmpty()) + NotifyMacroEventRead(); + pInfo->SetMacro(sMacro); pInfo->SetHlink( maHyperlink ); } } @@ -3281,7 +3297,8 @@ static const OUStringLiteral gaStdFormName( "Standard" ); /// Standard name of c XclImpDffConverter::XclImpDffConverter( const XclImpRoot& rRoot, SvStream& rDffStrm ) : XclImpSimpleDffConverter( rRoot, rDffStrm ), oox::ole::MSConvertOCXControls( rRoot.GetDocShell()->GetModel() ), - mnOleImpFlags( 0 ) + mnOleImpFlags( 0 ), + mbNotifyMacroEventRead(false) { const SvtFilterOptions& rFilterOpt = SvtFilterOptions::Get(); if( rFilterOpt.IsMathType2Math() ) @@ -3338,7 +3355,7 @@ void XclImpDffConverter::InitializeDrawing( XclImpDrawing& rDrawing, SdrModel& r SetModel( &xConvData->mrSdrModel, 1440 ); } -void XclImpDffConverter::ProcessObject( SdrObjList& rObjList, const XclImpDrawObjBase& rDrawObj ) +void XclImpDffConverter::ProcessObject( SdrObjList& rObjList, XclImpDrawObjBase& rDrawObj ) { if( rDrawObj.IsProcessSdrObj() ) { @@ -3387,6 +3404,14 @@ void XclImpDffConverter::FinalizeDrawing() SetModel( &maDataStack.back()->mrSdrModel, 1440 ); } +void XclImpDffConverter::NotifyMacroEventRead() +{ + if (mbNotifyMacroEventRead) + return; + comphelper::DocumentInfo::notifyMacroEventRead(mxModel); + mbNotifyMacroEventRead = true; +} + SdrObjectUniquePtr XclImpDffConverter::CreateSdrObject( const XclImpTbxObjBase& rTbxObj, const tools::Rectangle& rAnchorRect ) { SdrObjectUniquePtr xSdrObj; @@ -3409,6 +3434,7 @@ SdrObjectUniquePtr XclImpDffConverter::CreateSdrObject( const XclImpTbxObjBase& ScriptEventDescriptor aDescriptor; if( (rConvData.mnLastCtrlIndex >= 0) && rTbxObj.FillMacroDescriptor( aDescriptor ) ) { + NotifyMacroEventRead(); Reference< XEventAttacherManager > xEventMgr( rConvData.mxCtrlForm, UNO_QUERY_THROW ); xEventMgr->registerScriptEvent( rConvData.mnLastCtrlIndex, aDescriptor ); } diff --git a/sc/source/filter/inc/xiescher.hxx b/sc/source/filter/inc/xiescher.hxx index f9e8d007724e..37f457920d57 100644 --- a/sc/source/filter/inc/xiescher.hxx +++ b/sc/source/filter/inc/xiescher.hxx @@ -125,7 +125,7 @@ public: SdrObjectUniquePtr CreateSdrObject( XclImpDffConverter& rDffConv, const tools::Rectangle& rAnchorRect, bool bIsDff ) const; /** Additional processing for the passed SdrObject before insertion into the drawing page (calls virtual DoPreProcessSdrObj() function). */ - void PreProcessSdrObject( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const; + void PreProcessSdrObject( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ); /** Additional processing for the passed SdrObject after insertion into the drawing page (calls virtual DoPostProcessSdrObj() function). */ void PostProcessSdrObject( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const; @@ -172,6 +172,9 @@ protected: virtual void DoPreProcessSdrObj( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const; /** Derived classes may perform additional processing for the passed SdrObject after insertion. */ virtual void DoPostProcessSdrObj( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const; + + /** Notify that the document contains a macro event handler */ + void NotifyMacroEventRead(); private: /** Reads the contents of a BIFF3 OBJ record. */ void ImplReadObj3( XclImpStream& rStrm ); @@ -202,6 +205,7 @@ private: bool mbProcessSdr; /// true = Object is valid, do processing and insertion. bool mbInsertSdr; /// true = Insert the SdrObject into draw page. bool mbCustomDff; /// true = Recreate SdrObject in DFF import. + bool mbNotifyMacroEventRead; /// true == If we have already seen a macro event }; class XclImpDrawObjVector @@ -928,7 +932,7 @@ public: /** Initially called before the objects of the passed drawing manager are converted. */ void InitializeDrawing( XclImpDrawing& rDrawing, SdrModel& rSdrModel, SdrPage& rSdrPage ); /** Processes BIFF5 drawing objects without DFF data, inserts into the passed object list. */ - void ProcessObject( SdrObjList& rObjList, const XclImpDrawObjBase& rDrawObj ); + void ProcessObject( SdrObjList& rObjList, XclImpDrawObjBase& rDrawObj ); /** Processes all objects in the passed list. */ void ProcessDrawing( const XclImpDrawObjVector& rDrawObjs ); /** Processes a drawing container in the passed DFF stream, converts all objects. */ @@ -1017,6 +1021,8 @@ private: void InsertSdrObject( SdrObjList& rObjList, const XclImpDrawObjBase& rDrawObj, SdrObject* pSdrObj ); /** Initializes the mxCtrlForm referring to the standard controls form. */ void InitControlForm(); + /** Notify that this document contains a macro event handler */ + void NotifyMacroEventRead(); private: typedef std::shared_ptr< ScfProgressBar > ScfProgressBarRef; @@ -1028,6 +1034,7 @@ private: XclImpDffConvDataStack maDataStack; /// Stack for registered drawing managers. sal_uInt32 mnOleImpFlags; /// Application OLE import settings. sal_Int32 mnDefTextMargin; /// Default margin in text boxes. + bool mbNotifyMacroEventRead; /// If we have already seen a macro event }; // Drawing manager ============================================================ diff --git a/sc/source/ui/vba/vbasheetobject.cxx b/sc/source/ui/vba/vbasheetobject.cxx index 9e5b7856d6c4..4dc0d65cc422 100644 --- a/sc/source/ui/vba/vbasheetobject.cxx +++ b/sc/source/ui/vba/vbasheetobject.cxx @@ -24,6 +24,7 @@ #include <com/sun/star/script/ScriptEventDescriptor.hpp> #include <com/sun/star/script/XEventAttacherManager.hpp> #include <com/sun/star/style/VerticalAlignment.hpp> +#include <comphelper/documentinfo.hxx> #include <ooo/vba/excel/Constants.hpp> #include <ooo/vba/excel/XlOrientation.hpp> #include <ooo/vba/excel/XlPlacement.hpp> @@ -296,7 +297,8 @@ ScVbaControlObjectBase::ScVbaControlObjectBase( ListenerType eListenerType ) : ScVbaControlObject_BASE( rxParent, rxContext, rxModel, uno::Reference< drawing::XShape >( rxControlShape, uno::UNO_QUERY_THROW ) ), mxFormIC( rxFormIC, uno::UNO_SET_THROW ), - mxControlProps( rxControlShape->getControl(), uno::UNO_QUERY_THROW ) + mxControlProps( rxControlShape->getControl(), uno::UNO_QUERY_THROW ), + mbNotifyMacroEventRead(false) { // set listener and event name to be used for OnAction attribute switch( eListenerType ) @@ -354,6 +356,14 @@ OUString SAL_CALL ScVbaControlObjectBase::getOnAction() return OUString(); } +void ScVbaControlObjectBase::NotifyMacroEventRead() +{ + if (mbNotifyMacroEventRead) + return; + comphelper::DocumentInfo::notifyMacroEventRead(mxModel); + mbNotifyMacroEventRead = true; +} + void SAL_CALL ScVbaControlObjectBase::setOnAction( const OUString& rMacroName ) { uno::Reference< script::XEventAttacherManager > xEventMgr( mxFormIC, uno::UNO_QUERY_THROW ); @@ -373,6 +383,7 @@ void SAL_CALL ScVbaControlObjectBase::setOnAction( const OUString& rMacroName ) aDescriptor.EventMethod = maEventMethod; aDescriptor.ScriptType = "Script"; aDescriptor.ScriptCode = makeMacroURL( aResolvedMacro.msResolvedMacro ); + NotifyMacroEventRead(); xEventMgr->registerScriptEvent( nIndex, aDescriptor ); } } diff --git a/sc/source/ui/vba/vbasheetobject.hxx b/sc/source/ui/vba/vbasheetobject.hxx index 357309e1a0f5..4799791a0443 100644 --- a/sc/source/ui/vba/vbasheetobject.hxx +++ b/sc/source/ui/vba/vbasheetobject.hxx @@ -164,6 +164,9 @@ public: virtual sal_Bool SAL_CALL getAutoSize() override; virtual void SAL_CALL setAutoSize( sal_Bool bAutoSize ) override; + /// Notify that the document contains a macro event handler + void NotifyMacroEventRead(); + protected: /// @throws css::uno::RuntimeException sal_Int32 getModelIndexInForm() const; @@ -173,6 +176,7 @@ protected: css::uno::Reference< css::beans::XPropertySet > mxControlProps; OUString maListenerType; OUString maEventMethod; + bool mbNotifyMacroEventRead; }; typedef ::cppu::ImplInheritanceHelper< ScVbaControlObjectBase, ov::excel::XButton > ScVbaButton_BASE; diff --git a/scripting/source/protocolhandler/scripthandler.cxx b/scripting/source/protocolhandler/scripthandler.cxx index 332d4833a6f2..07169b7edbe2 100644 --- a/scripting/source/protocolhandler/scripthandler.cxx +++ b/scripting/source/protocolhandler/scripthandler.cxx @@ -126,7 +126,6 @@ void SAL_CALL ScriptProtocolHandler::dispatchWithNotification( const URL& aURL, const Sequence < PropertyValue >& lArgs, const Reference< XDispatchResultListener >& xListener ) { - bool bSuccess = false; Any invokeResult; bool bCaughtException = false; @@ -163,12 +162,11 @@ void SAL_CALL ScriptProtocolHandler::dispatchWithNotification( { xListener->dispatchFinished( aEvent ) ; } - catch(RuntimeException & e) + catch(const RuntimeException &e) { SAL_WARN("scripting", "ScriptProtocolHandler::dispatchWithNotification: caught RuntimeException" - "while dispatchFinished with failure of the execution " - << e ); + "while dispatchFinished with failure of the execution" << e); } } return; diff --git a/sfx2/source/doc/docmacromode.cxx b/sfx2/source/doc/docmacromode.cxx index 4872fc90496b..570fc27ac43f 100644 --- a/sfx2/source/doc/docmacromode.cxx +++ b/sfx2/source/doc/docmacromode.cxx @@ -397,7 +397,7 @@ namespace sfx2 } else { - if ( m_xData->m_rDocumentAccess.documentStorageHasMacros() || hasMacroLibrary() ) + if (m_xData->m_rDocumentAccess.documentStorageHasMacros() || hasMacroLibrary() || m_xData->m_rDocumentAccess.macroCallsSeenWhileLoading()) { bAllow = adjustMacroMode( rxInteraction ); } diff --git a/sfx2/source/doc/objmisc.cxx b/sfx2/source/doc/objmisc.cxx index dd01995bf18e..0aad46e02258 100644 --- a/sfx2/source/doc/objmisc.cxx +++ b/sfx2/source/doc/objmisc.cxx @@ -1384,13 +1384,7 @@ ErrCode SfxObjectShell::CallXScript( const Reference< XInterface >& _rxScriptCon Any aException; try { - css::uno::Reference<css::uri::XUriReferenceFactory> urifac( - css::uri::UriReferenceFactory::create(comphelper::getProcessComponentContext())); - css::uno::Reference<css::uri::XVndSunStarScriptUrlReference> uri( - urifac->parse(_rScriptURL), css::uno::UNO_QUERY_THROW); - auto const loc = uri->getParameter("location"); - bool bIsDocumentScript = loc == "document"; - if ( bIsDocumentScript && !lcl_isScriptAccessAllowed_nothrow( _rxScriptContext ) ) + if ( !lcl_isScriptAccessAllowed_nothrow( _rxScriptContext ) ) return ERRCODE_IO_ACCESSDENIED; if ( UnTrustedScript(_rScriptURL) ) @@ -1758,6 +1752,11 @@ bool SfxObjectShell_Impl::documentStorageHasMacros() const return ::sfx2::DocumentMacroMode::storageHasMacros( m_xDocStorage ); } +bool SfxObjectShell_Impl::macroCallsSeenWhileLoading() const +{ + return rDocShell.GetMacroCallsSeenWhileLoading(); +} + Reference< XEmbeddedScripts > SfxObjectShell_Impl::getEmbeddedDocumentScripts() const { return Reference< XEmbeddedScripts >( rDocShell.GetModel(), UNO_QUERY ); diff --git a/sfx2/source/doc/objstor.cxx b/sfx2/source/doc/objstor.cxx index 53fe2e344214..bd8a69c50942 100644 --- a/sfx2/source/doc/objstor.cxx +++ b/sfx2/source/doc/objstor.cxx @@ -3591,6 +3591,16 @@ void SfxObjectShell::SetConfigOptionsChecked( bool bChecked ) pImpl->m_bConfigOptionsChecked = bChecked; } +void SfxObjectShell::SetMacroCallsSeenWhileLoading() +{ + pImpl->m_bMacroCallsSeenWhileLoading = true; +} + +bool SfxObjectShell::GetMacroCallsSeenWhileLoading() const +{ + return pImpl->m_bMacroCallsSeenWhileLoading; +} + bool SfxObjectShell::QuerySaveSizeExceededModules_Impl( const uno::Reference< task::XInteractionHandler >& xHandler ) { #if !HAVE_FEATURE_SCRIPTING diff --git a/sfx2/source/doc/objxtor.cxx b/sfx2/source/doc/objxtor.cxx index 8c0e1643a0fc..d3e83c67b6a2 100644 --- a/sfx2/source/doc/objxtor.cxx +++ b/sfx2/source/doc/objxtor.cxx @@ -231,6 +231,7 @@ SfxObjectShell_Impl::SfxObjectShell_Impl( SfxObjectShell& _rDocShell ) ,m_bSharedXMLFlag( false ) ,m_bAllowShareControlFileClean( true ) ,m_bConfigOptionsChecked( false ) + ,m_bMacroCallsSeenWhileLoading( false ) ,lErr(ERRCODE_NONE) ,nEventId ( SfxEventHintId::NONE ) ,pReloadTimer ( nullptr) diff --git a/sfx2/source/doc/sfxbasemodel.cxx b/sfx2/source/doc/sfxbasemodel.cxx index 27ba812a2449..41bd3494bdb6 100644 --- a/sfx2/source/doc/sfxbasemodel.cxx +++ b/sfx2/source/doc/sfxbasemodel.cxx @@ -879,8 +879,15 @@ sal_Bool SAL_CALL SfxBaseModel::attachResource( const OUString& pObjectShell->BreakMacroSign_Impl( bBreakMacroSign ); } + bool bMacroEventRead = false; + if ((aArgs.get("MacroEventRead") >>= bMacroEventRead) && bMacroEventRead) + { + pObjectShell->SetMacroCallsSeenWhileLoading(); + } + aArgs.remove( "WinExtent" ); aArgs.remove( "BreakMacroSignature" ); + aArgs.remove( "MacroEventRead" ); aArgs.remove( "Stream" ); aArgs.remove( "InputStream" ); aArgs.remove( "URL" ); diff --git a/sfx2/source/inc/objshimp.hxx b/sfx2/source/inc/objshimp.hxx index 006b938664ea..848775ef2f47 100644 --- a/sfx2/source/inc/objshimp.hxx +++ b/sfx2/source/inc/objshimp.hxx @@ -90,7 +90,8 @@ struct SfxObjectShell_Impl : public ::sfx2::IMacroDocumentAccess bSaveVersionOnClose:1, m_bSharedXMLFlag:1, // whether the document should be edited in shared mode m_bAllowShareControlFileClean:1, // whether the flag should be stored in xml file - m_bConfigOptionsChecked:1; // whether or not the user options are checked after the Options dialog is closed. + m_bConfigOptionsChecked:1, // whether or not the user options are checked after the Options dialog is closed. + m_bMacroCallsSeenWhileLoading:1; // whether or not the user options are checked after the Options dialog is closed. IndexBitSet aBitSet; ErrCode lErr; @@ -139,6 +140,7 @@ struct SfxObjectShell_Impl : public ::sfx2::IMacroDocumentAccess virtual void setCurrentMacroExecMode( sal_uInt16 nMacroMode ) override; virtual OUString getDocumentLocation() const override; virtual bool documentStorageHasMacros() const override; + virtual bool macroCallsSeenWhileLoading() const override; virtual css::uno::Reference< css::document::XEmbeddedScripts > getEmbeddedDocumentScripts() const override; virtual SignatureState getScriptingSignatureState() override; diff --git a/sfx2/source/notify/eventsupplier.cxx b/sfx2/source/notify/eventsupplier.cxx index 8ce1d7b9bfa7..6740c8c0eb1e 100644 --- a/sfx2/source/notify/eventsupplier.cxx +++ b/sfx2/source/notify/eventsupplier.cxx @@ -19,11 +19,13 @@ #include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/document/XEmbeddedScripts.hpp> +#include <com/sun/star/document/XScriptInvocationContext.hpp> #include <com/sun/star/util/URL.hpp> - #include <com/sun/star/frame/Desktop.hpp> #include <com/sun/star/util/URLTransformer.hpp> #include <com/sun/star/util/XURLTransformer.hpp> +#include <com/sun/star/uno/XInterface.hpp> #include <tools/urlobj.hxx> #include <tools/diagnose_ex.h> #include <svl/macitem.hxx> @@ -47,6 +49,8 @@ #include <macroloader.hxx> using namespace css; +using namespace ::com::sun::star; + // --- XNameReplace --- @@ -168,102 +172,129 @@ sal_Bool SAL_CALL SfxEvents_Impl::hasElements() return false; } +namespace +{ + bool lcl_isScriptAccessAllowed_nothrow(const uno::Reference<uno::XInterface>& rxScriptContext) + { + try + { + uno::Reference<document::XEmbeddedScripts> xScripts(rxScriptContext, uno::UNO_QUERY); + if (!xScripts.is()) + { + uno::Reference<document::XScriptInvocationContext> xContext(rxScriptContext, uno::UNO_QUERY_THROW); + xScripts.set(xContext->getScriptContainer(), uno::UNO_SET_THROW); + } + + return xScripts->getAllowMacroExecution(); + } + catch( const uno::Exception& ) + { + DBG_UNHANDLED_EXCEPTION("sfx.doc"); + } + return false; + } +} + void SfxEvents_Impl::Execute( uno::Any const & aEventData, const document::DocumentEvent& aTrigger, SfxObjectShell* pDoc ) { uno::Sequence < beans::PropertyValue > aProperties; - if ( aEventData >>= aProperties ) - { - OUString aType; - OUString aScript; - OUString aLibrary; - OUString aMacroName; + if ( !(aEventData >>= aProperties) ) + return; - sal_Int32 nCount = aProperties.getLength(); + OUString aType; + OUString aScript; + OUString aLibrary; + OUString aMacroName; - if ( !nCount ) - return; + sal_Int32 nCount = aProperties.getLength(); - sal_Int32 nIndex = 0; - while ( nIndex < nCount ) - { - if ( aProperties[ nIndex ].Name == PROP_EVENT_TYPE ) - aProperties[ nIndex ].Value >>= aType; - else if ( aProperties[ nIndex ].Name == PROP_SCRIPT ) - aProperties[ nIndex ].Value >>= aScript; - else if ( aProperties[ nIndex ].Name == PROP_LIBRARY ) - aProperties[ nIndex ].Value >>= aLibrary; - else if ( aProperties[ nIndex ].Name == PROP_MACRO_NAME ) - aProperties[ nIndex ].Value >>= aMacroName; - else { - OSL_FAIL("Unknown property value!"); - } - nIndex += 1; - } + if ( !nCount ) + return; - if (aType == STAR_BASIC && !aScript.isEmpty()) - { - uno::Any aAny; - SfxMacroLoader::loadMacro( aScript, aAny, pDoc ); + sal_Int32 nIndex = 0; + while ( nIndex < nCount ) + { + if ( aProperties[ nIndex ].Name == PROP_EVENT_TYPE ) + aProperties[ nIndex ].Value >>= aType; + else if ( aProperties[ nIndex ].Name == PROP_SCRIPT ) + aProperties[ nIndex ].Value >>= aScript; + else if ( aProperties[ nIndex ].Name == PROP_LIBRARY ) + aProperties[ nIndex ].Value >>= aLibrary; + else if ( aProperties[ nIndex ].Name == PROP_MACRO_NAME ) + aProperties[ nIndex ].Value >>= aMacroName; + else { + OSL_FAIL("Unknown property value!"); } - else if (aType == "Service" || - aType == "Script") - { - bool bAllowed = false; - util::URL aURL; - if (!aScript.isEmpty()) - { - uno::Reference < util::XURLTransformer > xTrans( util::URLTransformer::create( ::comphelper::getProcessComponentContext() ) ); + nIndex += 1; + } - aURL.Complete = aScript; - xTrans->parseStrict( aURL ); + if (aType.isEmpty()) + { + // Empty type means no active binding for the event. Just ignore do nothing. + return; + } - bAllowed = !SfxObjectShell::UnTrustedScript(aURL.Complete); - } + if (aScript.isEmpty()) + return; - if (bAllowed) - { - SfxViewFrame* pView = pDoc ? - SfxViewFrame::GetFirst( pDoc ) : - SfxViewFrame::Current(); + if (!pDoc) + pDoc = SfxObjectShell::Current(); - uno::Reference - < frame::XDispatchProvider > xProv; + if (pDoc && !lcl_isScriptAccessAllowed_nothrow(pDoc->GetModel())) + return; - if ( pView != nullptr ) - { - xProv = uno::Reference - < frame::XDispatchProvider > ( - pView->GetFrame().GetFrameInterface(), uno::UNO_QUERY ); - } - else - { - xProv.set( frame::Desktop::create( ::comphelper::getProcessComponentContext() ), - uno::UNO_QUERY ); - } + if (aType == STAR_BASIC) + { + uno::Any aAny; + SfxMacroLoader::loadMacro( aScript, aAny, pDoc ); + } + else if (aType == "Service" || aType == "Script") + { + util::URL aURL; + uno::Reference < util::XURLTransformer > xTrans( util::URLTransformer::create( ::comphelper::getProcessComponentContext() ) ); - uno::Reference < frame::XDispatch > xDisp; - if ( xProv.is() ) - xDisp = xProv->queryDispatch( aURL, OUString(), 0 ); + aURL.Complete = aScript; + xTrans->parseStrict( aURL ); - if ( xDisp.is() ) - { + bool bAllowed = !SfxObjectShell::UnTrustedScript(aURL.Complete); - beans::PropertyValue aEventParam; - aEventParam.Value <<= aTrigger; - uno::Sequence< beans::PropertyValue > aDispatchArgs( &aEventParam, 1 ); - xDisp->dispatch( aURL, aDispatchArgs ); - } - } - } - else if ( aType.isEmpty() ) - { - // Empty type means no active binding for the event. Just ignore do nothing. - } - else + if (bAllowed) { - SAL_WARN( "sfx.notify", "notifyEvent(): Unsupported event type" ); + SfxViewFrame* pView = SfxViewFrame::GetFirst(pDoc); + + uno::Reference + < frame::XDispatchProvider > xProv; + + if ( pView != nullptr ) + { + xProv = uno::Reference + < frame::XDispatchProvider > ( + pView->GetFrame().GetFrameInterface(), uno::UNO_QUERY ); + } + else + { + xProv.set( frame::Desktop::create( ::comphelper::getProcessComponentContext() ), + uno::UNO_QUERY ); + } + + uno::Reference < frame::XDispatch > xDisp; + if ( xProv.is() ) + xDisp = xProv->queryDispatch( aURL, OUString(), 0 ); + + if ( xDisp.is() ) + { + + beans::PropertyValue aEventParam; + aEventParam.Value <<= aTrigger; + uno::Sequence< beans::PropertyValue > aDispatchArgs( &aEventParam, 1 ); + xDisp->dispatch( aURL, aDispatchArgs ); + } } } + else + { + SAL_WARN( "sfx.notify", "notifyEvent(): Unsupported event type" ); + } } diff --git a/sw/source/filter/html/htmlform.cxx b/sw/source/filter/html/htmlform.cxx index d6b641ff8f52..54d0b0adba40 100644 --- a/sw/source/filter/html/htmlform.cxx +++ b/sw/source/filter/html/htmlform.cxx @@ -18,6 +18,7 @@ */ #include <hintids.hxx> +#include <comphelper/documentinfo.hxx> #include <comphelper/string.hxx> #include <vcl/svapp.hxx> #include <vcl/wrkwin.hxx> @@ -735,7 +736,7 @@ void SwHTMLParser::SetControlSize( const uno::Reference< drawing::XShape >& rSha rShape->setSize( aSz ); } -static void lcl_html_setEvents( +static bool lcl_html_setEvents( const uno::Reference< script::XEventAttacherManager > & rEvtMn, sal_uInt32 nPos, const SvxMacroTableDtor& rMacroTable, const std::vector<OUString>& rUnoMacroTable, @@ -764,7 +765,7 @@ static void lcl_html_setEvents( } if( 0==nEvents ) - return; + return false; Sequence<script::ScriptEventDescriptor> aDescs( nEvents ); script::ScriptEventDescriptor* pDescs = aDescs.getArray(); @@ -822,6 +823,7 @@ static void lcl_html_setEvents( } } rEvtMn->registerScriptEvents( nPos, aDescs ); + return true; } static void lcl_html_getEvents( const OUString& rOption, const OUString& rValue, @@ -1190,10 +1192,12 @@ uno::Reference< drawing::XShape > SwHTMLParser::InsertControl( // To prevent previous JavaScript-Events from being called, these events will only be set retroactively if( !rMacroTable.empty() || !rUnoMacroTable.empty() ) { - lcl_html_setEvents( m_pFormImpl->GetControlEventManager(), + bool bHasEvents = lcl_html_setEvents( m_pFormImpl->GetControlEventManager(), rFormComps->getCount() - 1, rMacroTable, rUnoMacroTable, rUnoMacroParamTable, GetScriptTypeString(m_pFormImpl->GetHeaderAttrs()) ); + if (bHasEvents) + NotifyMacroEventRead(); } if( bSetFCompPropSet ) @@ -1355,10 +1359,14 @@ void SwHTMLParser::NewForm( bool bAppend ) Any aAny( &xForm, cppu::UnoType<XForm>::get()); rForms->insertByIndex( rForms->getCount(), aAny ); if( !aMacroTable.empty() ) - lcl_html_setEvents( m_pFormImpl->GetFormEventManager(), + { + bool bHasEvents = lcl_html_setEvents( m_pFormImpl->GetFormEventManager(), rForms->getCount() - 1, aMacroTable, aUnoMacroTable, aUnoMacroParamTable, rDfltScriptType ); + if (bHasEvents) + NotifyMacroEventRead(); + } } void SwHTMLParser::EndForm( bool bAppend ) diff --git a/sw/source/filter/html/htmlgrin.cxx b/sw/source/filter/html/htmlgrin.cxx index 431099fa95f4..8f90266835e7 100644 --- a/sw/source/filter/html/htmlgrin.cxx +++ b/sw/source/filter/html/htmlgrin.cxx @@ -20,6 +20,7 @@ #include <memory> #include <hintids.hxx> #include <comphelper/string.hxx> +#include <comphelper/documentinfo.hxx> #include <vcl/svapp.hxx> #include <vcl/wrkwin.hxx> #include <svx/svxids.hrc> @@ -871,7 +872,10 @@ IMAGE_SETEVENT: } if( !aMacroItem.GetMacroTable().empty() ) + { + NotifyMacroEventRead(); pFlyFormat->SetFormatAttr( aMacroItem ); + } // tdf#87083 If the graphic has not been loaded yet, then load it now. // Otherwise it may be loaded during the first paint of the object and it @@ -1302,7 +1306,10 @@ ANCHOR_SETEVENT: aINetFormat.SetName( aName ); if( !aMacroTable.empty() ) + { + NotifyMacroEventRead(); aINetFormat.SetMacroTable( &aMacroTable ); + } // set the default attribute InsertAttr(&m_xAttrTab->pINetFormat, aINetFormat, xCntxt.get()); @@ -1514,4 +1521,16 @@ void SwHTMLParser::StripTrailingPara() } } +void SwHTMLParser::NotifyMacroEventRead() +{ + if (m_bNotifyMacroEventRead) + return; + SwDocShell *pDocSh = m_xDoc->GetDocShell(); + if (!pDocSh) + return; + uno::Reference<frame::XModel> const xModel(pDocSh->GetBaseModel()); + comphelper::DocumentInfo::notifyMacroEventRead(xModel); + m_bNotifyMacroEventRead = true; +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/filter/html/swhtml.cxx b/sw/source/filter/html/swhtml.cxx index daa5002b684c..85855be247e6 100644 --- a/sw/source/filter/html/swhtml.cxx +++ b/sw/source/filter/html/swhtml.cxx @@ -309,6 +309,7 @@ SwHTMLParser::SwHTMLParser( SwDoc* pD, SwPaM& rCursor, SvStream& rIn, m_bRemoveHidden( false ), m_bBodySeen( false ), m_bReadingHeaderOrFooter( false ), + m_bNotifyMacroEventRead( false ), m_isInTableStructure(false), m_nTableDepth( 0 ), m_pTempViewFrame(nullptr) diff --git a/sw/source/filter/html/swhtml.hxx b/sw/source/filter/html/swhtml.hxx index c0f3523f4303..baf039ef8e4e 100644 --- a/sw/source/filter/html/swhtml.hxx +++ b/sw/source/filter/html/swhtml.hxx @@ -453,6 +453,7 @@ class SwHTMLParser : public SfxHTMLParser, public SwClient bool m_bBodySeen : 1; bool m_bReadingHeaderOrFooter : 1; + bool m_bNotifyMacroEventRead : 1; bool m_isInTableStructure; sal_Int32 m_nTableDepth; @@ -924,6 +925,8 @@ public: bool IsReqIF() const; + void NotifyMacroEventRead(); + /// Strips query and fragment from a URL path if base URL is a file:// one. static OUString StripQueryFromPath(const OUString& rBase, const OUString& rPath); }; diff --git a/sw/source/filter/ww8/ww8par.cxx b/sw/source/filter/ww8/ww8par.cxx index 612d0c200958..1c3474a8b7a0 100644 --- a/sw/source/filter/ww8/ww8par.cxx +++ b/sw/source/filter/ww8/ww8par.cxx @@ -40,6 +40,7 @@ #include <unotools/tempfile.hxx> #include <comphelper/docpasswordrequest.hxx> +#include <comphelper/documentinfo.hxx> #include <comphelper/propertysequence.hxx> #include <editeng/outlobj.hxx> @@ -4299,6 +4300,7 @@ SwWW8ImplReader::SwWW8ImplReader(sal_uInt8 nVersionPara, SotStorage* pStorage, , m_aTOXEndCps() , m_aCurrAttrCP(-1) , m_bOnLoadingMain(false) + , m_bNotifyMacroEventRead(false) { m_pStrm->SetEndian( SvStreamEndian::LITTLE ); m_aApos.push_back(false); @@ -6548,4 +6550,13 @@ std::unique_ptr<SfxItemSet> SwWW8ImplReader::SetCurrentItemSet(std::unique_ptr<S return xRet; } +void SwWW8ImplReader::NotifyMacroEventRead() +{ + if (m_bNotifyMacroEventRead) + return; + uno::Reference<frame::XModel> const xModel(m_rDoc.GetDocShell()->GetBaseModel()); + comphelper::DocumentInfo::notifyMacroEventRead(xModel); + m_bNotifyMacroEventRead = true; +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/filter/ww8/ww8par.hxx b/sw/source/filter/ww8/ww8par.hxx index fc8ab8c5d2b7..ee5a8b68b795 100644 --- a/sw/source/filter/ww8/ww8par.hxx +++ b/sw/source/filter/ww8/ww8par.hxx @@ -1374,6 +1374,7 @@ private: cp_vector m_aEndParaPos; WW8_CP m_aCurrAttrCP; bool m_bOnLoadingMain:1; + bool m_bNotifyMacroEventRead:1; const SprmReadInfo& GetSprmReadInfo(sal_uInt16 nId) const; @@ -1904,6 +1905,7 @@ public: // really private, but can only be done public void PostProcessAttrs(); void ReadEmbeddedData(SvStream& rStrm, SwDocShell const * pDocShell, struct HyperLinksTable& hlStr); + void NotifyMacroEventRead(); }; bool CanUseRemoteLink(const OUString &rGrfName); diff --git a/sw/source/filter/ww8/ww8par5.cxx b/sw/source/filter/ww8/ww8par5.cxx index c77292333300..1d2430db8d69 100644 --- a/sw/source/filter/ww8/ww8par5.cxx +++ b/sw/source/filter/ww8/ww8par5.cxx @@ -2272,6 +2272,8 @@ eF_ResT SwWW8ImplReader::Read_F_Macro( WW8FieldDesc*, OUString& rStr) if( aName.isEmpty() ) return eF_ResT::TAGIGN; // makes no sense without Macro-Name + NotifyMacroEventRead(); + //try converting macro symbol according to macro name bool bApplyWingdings = ConvertMacroSymbol( aName, aVText ); aName = "StarOffice.Standard.Modul1." + aName; diff --git a/sw/source/filter/ww8/ww8toolbar.cxx b/sw/source/filter/ww8/ww8toolbar.cxx index eeb6f4212601..058e79e0a072 100644 --- a/sw/source/filter/ww8/ww8toolbar.cxx +++ b/sw/source/filter/ww8/ww8toolbar.cxx @@ -18,8 +18,10 @@ #include <com/sun/star/lang/XSingleComponentFactory.hpp> #include <com/sun/star/ui/ItemType.hpp> #include <fstream> +#include <comphelper/documentinfo.hxx> #include <comphelper/processfactory.hxx> #include <comphelper/sequence.hxx> +#include <sfx2/objsh.hxx> #include <unotools/configmgr.hxx> #include <vcl/graph.hxx> #include <map> @@ -710,6 +712,10 @@ bool Tcg255::ImportCustomToolBar( SfxObjectShell& rDocSh ) SwCTBWrapper* pCTBWrapper = dynamic_cast< SwCTBWrapper* > ( rSubStruct.get() ); if ( pCTBWrapper ) { + // tdf#127048 set this flag if we might import something + uno::Reference<frame::XModel> const xModel(rDocSh.GetBaseModel()); + comphelper::DocumentInfo::notifyMacroEventRead(xModel); + if ( !pCTBWrapper->ImportCustomToolBar( rDocSh ) ) return false; } diff --git a/xmloff/source/core/xmlimp.cxx b/xmloff/source/core/xmlimp.cxx index 556e39299454..0c5437b93ad9 100644 --- a/xmloff/source/core/xmlimp.cxx +++ b/xmloff/source/core/xmlimp.cxx @@ -58,6 +58,7 @@ #include <cppuhelper/supportsservice.hxx> #include <comphelper/extract.hxx> #include <comphelper/documentconstants.hxx> +#include <comphelper/documentinfo.hxx> #include <comphelper/storagehelper.hxx> #include <unotools/fontcvt.hxx> #include <o3tl/make_unique.hxx> @@ -398,7 +399,8 @@ SvXMLImport::SvXMLImport( isFastContext( false ), maNamespaceHandler( new SvXMLImportFastNamespaceHandler() ), mbIsFormsSupported( true ), - mbIsTableShapeSupported( false ) + mbIsTableShapeSupported( false ), + mbNotifyMacroEventRead( false ) { SAL_WARN_IF( !xContext.is(), "xmloff.core", "got no service manager" ); InitCtor_(); @@ -2163,6 +2165,16 @@ void SvXMLImport::registerNamespaces() } } +void SvXMLImport::NotifyMacroEventRead() +{ + if (mbNotifyMacroEventRead) + return; + + comphelper::DocumentInfo::notifyMacroEventRead(mxModel); + + mbNotifyMacroEventRead = true; +} + SvXMLImportFastNamespaceHandler::SvXMLImportFastNamespaceHandler() { } diff --git a/xmloff/source/script/XMLEventImportHelper.cxx b/xmloff/source/script/XMLEventImportHelper.cxx index 26048e86bacf..92e79af02433 100644 --- a/xmloff/source/script/XMLEventImportHelper.cxx +++ b/xmloff/source/script/XMLEventImportHelper.cxx @@ -36,7 +36,6 @@ XMLEventImportHelper::XMLEventImportHelper() : { } - XMLEventImportHelper::~XMLEventImportHelper() { // delete factories @@ -107,6 +106,8 @@ SvXMLImportContext* XMLEventImportHelper::CreateContext( const OUString& rXmlEventName, const OUString& rLanguage) { + rImport.NotifyMacroEventRead(); + SvXMLImportContext* pContext = nullptr; // translate event name form xml to api commit 4984dbdef324ebe709f03144ef2808dbef09ba83 Author: Justin Luth <[email protected]> AuthorDate: Wed Aug 21 19:41:17 2019 +0300 Commit: Andras Timar <[email protected]> CommitDate: Thu Sep 5 12:32:33 2019 +0200 tdf#126784 sw: only distribute across selected columns partial revert of LO6.2 commit ab18c17d70e1dcf5cf9db38256d35e6af479373e because MERGED cells had a very unexpected effect on the columns that were altered. Unselected columns are INCLUDED in the calculation IF they extend over the selected columns when SwTableSearchType::Col uses the entire table column. The last table in the unit test demonstrates why the regressive behaviour was included. A user can make an ugly layout if they don't choose a good set of columns. However, the merged cell really changes the way the calculation works, and since giving power to the user is ultimately the best, just revert the portion that tries to save the user from themself. I struggled then and now to get a good enough understanding to improve the documentation - which really is needed since reading it didn't help me a lot. However, since my understanding was and is obviously flawed, I'll just revert back to the original wording. Change-Id: Icf8f01f095652e2a023e0398852f43aa6b90332f Reviewed-on: https://gerrit.libreoffice.org/77985 Tested-by: Jenkins Reviewed-by: Miklos Vajna <[email protected]> diff --git a/sw/inc/doc.hxx b/sw/inc/doc.hxx index db3220f26f18..ce2311c59c09 100644 --- a/sw/inc/doc.hxx +++ b/sw/inc/doc.hxx @@ -1492,8 +1492,7 @@ public: /// Adjusts selected cell widths in such a way, that their content does not need to be wrapped (if possible). /// bBalance evenly re-distributes the available space regardless of content or wrapping. /// bNoShrink keeps table size the same by distributing excess space proportionately. - /// bColumnWidth tests the entire column for content width, not just selected cells. - void AdjustCellWidth( const SwCursor& rCursor, const bool bBalance, const bool bNoShrink, const bool bColumnWidth ); + void AdjustCellWidth( const SwCursor& rCursor, const bool bBalance, const bool bNoShrink ); SwChainRet Chainable( const SwFrameFormat &rSource, const SwFrameFormat &rDest ); SwChainRet Chain( SwFrameFormat &rSource, const SwFrameFormat &rDest ); diff --git a/sw/inc/fesh.hxx b/sw/inc/fesh.hxx index e5e3275bcbec..d4f2f0732983 100644 --- a/sw/inc/fesh.hxx +++ b/sw/inc/fesh.hxx @@ -706,7 +706,7 @@ public: bool IsInRepeatedHeadline() const { return CheckHeadline( true ); } bool IsInHeadline() const { return CheckHeadline( false ); } - void AdjustCellWidth( bool bBalance, const bool bNoShrink, const bool bColumnWidth ); + void AdjustCellWidth( const bool bBalance, const bool bNoShrink ); /// Not allowed if only empty cells are selected. bool IsAdjustCellWidthAllowed( bool bBalance = false ) const; diff --git a/sw/qa/extras/uiwriter/data2/tdf126784_distributeSelectedColumns.odt b/sw/qa/extras/uiwriter/data2/tdf126784_distributeSelectedColumns.odt new file mode 100644 index 000000000000..90c23c56a32d Binary files /dev/null and b/sw/qa/extras/uiwriter/data2/tdf126784_distributeSelectedColumns.odt differ diff --git a/sw/qa/extras/uiwriter/uiwriter2.cxx b/sw/qa/extras/uiwriter/uiwriter2.cxx index 04265e0644e7..b53b2faf4ccc 100644 --- a/sw/qa/extras/uiwriter/uiwriter2.cxx +++ b/sw/qa/extras/uiwriter/uiwriter2.cxx @@ -15,6 +15,7 @@ #include <boost/property_tree/json_parser.hpp> #include <com/sun/star/frame/DispatchHelper.hpp> +#include <com/sun/star/text/TableColumnSeparator.hpp> #include <comphelper/propertysequence.hxx> #include <LibreOfficeKit/LibreOfficeKitEnums.h> #include <svx/svdpage.hxx> @@ -69,6 +70,7 @@ public: void testTdf54819(); void testTdf109376_redline(); void testTdf109376(); + void testTdf126784_distributeSelectedColumns(); void testTdf108687_tabstop(); void testTdf119571(); void testTdf119019(); @@ -105,6 +107,7 @@ public: CPPUNIT_TEST(testTdf101534); CPPUNIT_TEST(testTdf54819); CPPUNIT_TEST(testTdf109376_redline); + CPPUNIT_TEST(testTdf126784_distributeSelectedColumns); CPPUNIT_TEST(testTdf109376); CPPUNIT_TEST(testTdf108687_tabstop); CPPUNIT_TEST(testTdf119571); @@ -423,6 +426,34 @@ void SwUiWriterTest2::testTdf109376() CPPUNIT_ASSERT_EQUAL(size_t(1), pWrtShell->GetFlyCount(FLYCNTTYPE_FRM)); } +void SwUiWriterTest2::testTdf126784_distributeSelectedColumns() +{ + SwDoc* pDoc = createDoc("tdf126784_distributeSelectedColumns.odt"); + SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell(); + + uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY); + uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(), + uno::UNO_QUERY); + uno::Reference<text::XTextTable> xTextTable(xTables->getByIndex(0), uno::UNO_QUERY); + uno::Reference<table::XTableRows> xTableRows = xTextTable->getRows(); + + auto aSeq = getProperty<uno::Sequence<text::TableColumnSeparator>>(xTableRows->getByIndex(0), + "TableColumnSeparators"); + sal_Int16 nOrigCol2Pos = aSeq[0].Position; + sal_Int16 nOrigCol3Pos = aSeq[1].Position; + + //Select column 1 and 2 + pWrtShell->Right(CRSR_SKIP_CHARS, /*bSelect=*/true, 1, /*bBasicCall=*/false); + + lcl_dispatchCommand(mxComponent, ".uno:DistributeColumns", {}); + + aSeq = getProperty<uno::Sequence<text::TableColumnSeparator>>(xTableRows->getByIndex(0), + "TableColumnSeparators"); + CPPUNIT_ASSERT_MESSAGE("Second column should shrink", nOrigCol2Pos < aSeq[0].Position); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Last column shouldn't change", nOrigCol3Pos, aSeq[1].Position); +} + void SwUiWriterTest2::testTdf108687_tabstop() { SwDoc* pDoc = createDoc("tdf108687_tabstop.odt"); diff --git a/sw/source/core/docnode/ndtbl1.cxx b/sw/source/core/docnode/ndtbl1.cxx index 582cb226dc55..9b152b500088 100644 --- a/sw/source/core/docnode/ndtbl1.cxx +++ b/sw/source/core/docnode/ndtbl1.cxx @@ -1365,24 +1365,25 @@ static void lcl_CalcSubColValues( std::vector<sal_uInt16> &rToFill, const SwTabC * We do not iterate over the TabCols' entries, but over the gaps that describe Cells. * We set TabCol entries for which we did not calculate Cells to 0. * - * @param bWishValues == true: Calculate the desired width of the content - * The highest desired value is returned. - * @param bWishValues == false: Calculate the minimum width of the content - * @param bColumnWidth == false: We calculate the desired value of all affected - * Cells for the current Selection only. - * @param bColumnWidth == true: The Selection is expanded vertically. - * We calculate the wish/minimum value for - * each cell in every Column that intersects - * with the Selection. + * @param bWishValues == true: We calculate the desired value of all affected + * Cells for the current Selection/current Cell. + * If more Cells are within a Column, the highest + * desired value is returned. + * We set TabCol entries for which we did not calculate + * Cells to 0. + * + * @param bWishValues == false: The Selection is expanded vertically. + * We calculate the minimum value for every + * Column in the TabCols that intersects with the + * Selection. */ static void lcl_CalcColValues( std::vector<sal_uInt16> &rToFill, const SwTabCols &rCols, const SwLayoutFrame *pStart, const SwLayoutFrame *pEnd, - bool bWishValues, - bool bColumnWidth ) + bool bWishValues ) { SwSelUnions aUnions; ::MakeSelUnions( aUnions, pStart, pEnd, - bColumnWidth ? SwTableSearchType::Col : SwTableSearchType::NONE ); + bWishValues ? SwTableSearchType::NONE : SwTableSearchType::Col ); for ( auto &rU : aUnions ) { @@ -1463,8 +1464,7 @@ static void lcl_CalcColValues( std::vector<sal_uInt16> &rToFill, const SwTabCols void SwDoc::AdjustCellWidth( const SwCursor& rCursor, const bool bBalance, - const bool bNoShrink, - const bool bColumnWidth ) + const bool bNoShrink ) { // Check whether the current Cursor has it's Point/Mark in a Table SwContentNode* pCntNd = rCursor.GetPoint()->nNode.GetNode().GetContentNode(); @@ -1492,7 +1492,7 @@ void SwDoc::AdjustCellWidth( const SwCursor& rCursor, std::vector<sal_uInt16> aWish(aTabCols.Count() + 1); std::vector<sal_uInt16> aMins(aTabCols.Count() + 1); - ::lcl_CalcColValues( aWish, aTabCols, pStart, pEnd, true, bColumnWidth ); + ::lcl_CalcColValues( aWish, aTabCols, pStart, pEnd, /*bWishValues=*/true ); // It's more robust if we calculate the minimum values for the whole Table const SwTabFrame *pTab = pStart->ImplFindTabFrame(); @@ -1500,7 +1500,7 @@ void SwDoc::AdjustCellWidth( const SwCursor& rCursor, pEnd = const_cast<SwLayoutFrame*>(pTab->FindLastContent()->GetUpper()); while( !pEnd->IsCellFrame() ) pEnd = pEnd->GetUpper(); - ::lcl_CalcColValues( aMins, aTabCols, pStart, pEnd, false, /*bColumnWidth=*/true ); + ::lcl_CalcColValues( aMins, aTabCols, pStart, pEnd, /*bWishValues=*/false ); sal_uInt16 nSelectedWidth = 0, nCols = 0; float fTotalWish = 0; diff --git a/sw/source/core/frmedt/fetab.cxx b/sw/source/core/frmedt/fetab.cxx index 0b50d6d938f4..aecff629e714 100644 --- a/sw/source/core/frmedt/fetab.cxx +++ b/sw/source/core/frmedt/fetab.cxx @@ -1107,7 +1107,7 @@ bool SwFEShell::CheckHeadline( bool bRepeat ) const return bRet; } -void SwFEShell::AdjustCellWidth( bool bBalance, const bool bNoShrink, const bool bColumnWidth ) +void SwFEShell::AdjustCellWidth( const bool bBalance, const bool bNoShrink ) { SET_CURR_SHELL( this ); StartAllAction(); @@ -1117,7 +1117,7 @@ void SwFEShell::AdjustCellWidth( bool bBalance, const bool bNoShrink, const bool TableWait aWait(std::numeric_limits<size_t>::max(), nullptr, *GetDoc()->GetDocShell()); - GetDoc()->AdjustCellWidth( *getShellCursor( false ), bBalance, bNoShrink, bColumnWidth ); + GetDoc()->AdjustCellWidth( *getShellCursor( false ), bBalance, bNoShrink ); EndAllActionAndCall(); } diff --git a/sw/source/uibase/shells/tabsh.cxx b/sw/source/uibase/shells/tabsh.cxx index 4b3c3dc78f41..ad1aa432dfb7 100644 --- a/sw/source/uibase/shells/tabsh.cxx +++ b/sw/source/uibase/shells/tabsh.cxx @@ -766,14 +766,13 @@ void SwTableShell::Execute(SfxRequest &rReq) { bool bBalance = (FN_TABLE_BALANCE_CELLS == nSlot); const bool bNoShrink = FN_TABLE_ADJUST_CELLS == nSlot; - const bool bSelectedWidth = SID_TABLE_MINIMAL_COLUMN_WIDTH == nSlot; if ( rSh.IsAdjustCellWidthAllowed(bBalance) ) { { // remove actions to make a valid table selection UnoActionRemoveContext aRemoveContext(rSh.GetDoc()); } - rSh.AdjustCellWidth(bBalance, bNoShrink, !bSelectedWidth); + rSh.AdjustCellWidth(bBalance, bNoShrink); } bCallDone = true; break; commit 8999bfde3ce7bbf5d3c1ff12ef7d938b3de8eba1 Author: Tomáš Chvátal <[email protected]> AuthorDate: Fri Aug 23 09:44:01 2019 +0200 Commit: Andras Timar <[email protected]> CommitDate: Thu Sep 5 12:32:32 2019 +0200 Fix old boost build for good With the previous approach the code could lead to crashes in the flowfrm.cxx Change-Id: I3b56ed46db9d37a606a1cd793a20b8aff22db6e2 Reviewed-on: https://gerrit.libreoffice.org/78001 Reviewed-by: Tomáš Chvátal <[email protected]> Tested-by: Tomáš Chvátal <[email protected]> Reviewed-by: Michael Stahl <[email protected]> diff --git a/sw/source/core/inc/frame.hxx b/sw/source/core/inc/frame.hxx index 5f9a2cfcf886..1e09dc389d05 100644 --- a/sw/source/core/inc/frame.hxx +++ b/sw/source/core/inc/frame.hxx @@ -1246,11 +1246,15 @@ public: m_pForbidFrame->ForbidDelete(); } + SwFrameDeleteGuard(const SwFrameDeleteGuard&) =delete; + ~SwFrameDeleteGuard() { if (m_pForbidFrame) m_pForbidFrame->AllowDelete(); } + + SwFrameDeleteGuard& operator=(const SwFrameDeleteGuard&) =delete; }; typedef long (SwFrame:: *SwFrameGet)() const; diff --git a/sw/source/core/layout/calcmove.cxx b/sw/source/core/layout/calcmove.cxx index 2f700131c2a9..759291dd5fb1 100644 --- a/sw/source/core/layout/calcmove.cxx +++ b/sw/source/core/layout/calcmove.cxx @@ -403,14 +403,19 @@ void SwFrame::PrepareCursor() const bool bTab = IsTabFrame(); bool bNoSect = IsInSct(); +#if BOOST_VERSION < 105600 + std::list<FlowFrameJoinLockGuard> tabGuard; + std::list<SwFrameDeleteGuard> rowGuard; +#else boost::optional<FlowFrameJoinLockGuard> tabGuard; boost::optional<SwFrameDeleteGuard> rowGuard; +#endif SwFlowFrame* pThis = bCnt ? static_cast<SwContentFrame*>(this) : nullptr; if ( bTab ) { #if BOOST_VERSION < 105600 - tabGuard.reset(static_cast<SwTabFrame*>(this)); // tdf#125741 + tabGuard.emplace_back(static_cast<SwTabFrame*>(this)); // tdf#125741 #else tabGuard.emplace(static_cast<SwTabFrame*>(this)); // tdf#125741 #endif @@ -419,7 +424,7 @@ void SwFrame::PrepareCursor() else if (IsRowFrame()) { #if BOOST_VERSION < 105600 - rowGuard.reset(SwFrameDeleteGuard(this)); // tdf#125741 keep this alive + rowGuard.emplace_back(this); // tdf#125741 keep this alive #else rowGuard.emplace(this); // tdf#125741 keep this alive #endif diff --git a/sw/source/core/layout/flowfrm.cxx b/sw/source/core/layout/flowfrm.cxx index dbe7d9c7feec..77617dc5cfa9 100644 --- a/sw/source/core/layout/flowfrm.cxx +++ b/sw/source/core/layout/flowfrm.cxx @@ -2517,7 +2517,11 @@ bool SwFlowFrame::MoveBwd( bool &rbReformat ) { auto const pOld = m_rThis.GetUpper(); +#if BOOST_VERSION < 105600 + std::list<SwFrameDeleteGuard> g; +#else ::boost::optional<SwFrameDeleteGuard> g; +#endif if (m_rThis.GetUpper()->IsCellFrame()) { // note: IsFollowFlowRow() is never set for new-style tables @@ -2528,7 +2532,7 @@ bool SwFlowFrame::MoveBwd( bool &rbReformat ) { // lock follow-flow-row (similar to sections above) #if BOOST_VERSION < 105600 - g.reset(SwFrameDeleteGuard(m_rThis.GetUpper()->GetUpper())); + g.emplace_back(m_rThis.GetUpper()->GetUpper()); #else g.emplace(m_rThis.GetUpper()->GetUpper()); #endif commit 4e5b6ebe92252e419315d27be755386cc504eaa8 Author: Stephan Bergmann <[email protected]> AuthorDate: Mon Aug 26 10:18:09 2019 +0200 Commit: Andras Timar <[email protected]> CommitDate: Thu Sep 5 12:32:32 2019 +0200 Improve check Change-Id: I8280a81eef2ced0ff0ace51ea9f094421abafe13 Reviewed-on: https://gerrit.libreoffice.org/78108 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <[email protected]> (cherry picked from commit 761e6dd25782420bf06e4a2ff3205a79b6cbb136) Reviewed-on: https://gerrit.libreoffice.org/78129 Reviewed-by: Michael Stahl <[email protected]> diff --git a/sfx2/source/doc/objmisc.cxx b/sfx2/source/doc/objmisc.cxx index 08f4d8c21297..dd01995bf18e 100644 --- a/sfx2/source/doc/objmisc.cxx +++ b/sfx2/source/doc/objmisc.cxx @@ -1364,7 +1364,7 @@ bool SfxObjectShell::UnTrustedScript(const OUString& rScriptURL) do { OUString aToken = sScript.getToken(0, '/', nIndex); - if (aToken.startsWithIgnoreAsciiCase("LibreLogo")) + if (aToken.startsWithIgnoreAsciiCase("LibreLogo") || aToken.indexOf('~') != -1) { return true; } commit 7e4e20335a1cbce42e3d48f08b6c2d733a6574a4 Author: Caolán McNamara <[email protected]> AuthorDate: Fri Aug 23 19:35:40 2019 +0100 Commit: Andras Timar <[email protected]> CommitDate: Thu Sep 5 12:32:32 2019 +0200 Resolves: tdf#126693 cannot put focus into combobox entry Change-Id: I52a316e5c88a41c66ef08be1bae8fcdd10d2ab8e Reviewed-on: https://gerrit.libreoffice.org/78032 Tested-by: Jenkins Reviewed-by: Adolfo Jayme Barrientos <[email protected]> diff --git a/sw/uiconfig/swriter/ui/insertcaption.ui b/sw/uiconfig/swriter/ui/insertcaption.ui index 3a858b3e0bec..dab2087f14ca 100644 --- a/sw/uiconfig/swriter/ui/insertcaption.ui +++ b/sw/uiconfig/swriter/ui/insertcaption.ui @@ -294,7 +294,7 @@ <property name="has_entry">True</property> <child internal-child="entry"> <object class="GtkEntry" id="comboboxtext-entry"> - <property name="can_focus">False</property> + <property name="can_focus">True</property> <property name="activates_default">True</property> </object> </child> commit fffe389036f17bf73c8343e452e1a47ba0130cc2 Author: Regina Henschel <[email protected]> AuthorDate: Wed Aug 21 14:11:23 2019 +0200 Commit: Andras Timar <[email protected]> CommitDate: Thu Sep 5 12:32:31 2019 +0200 tdf#126271 Revert "tdf120965 Simplify SdrPathObj::AddToHdlList()" This reverts commit 26001f4f84b0d921c8612d888856613735ba5314. Change-Id: Ib4df476b405e65be9203ab376c9c68b03198c040 Reviewed-on: https://gerrit.libreoffice.org/77882 Tested-by: Regina Henschel <[email protected]> Reviewed-by: Regina Henschel <[email protected]> (cherry picked from commit 59189f3e02acbdf4e5bbd35fc278252b30022f43) Reviewed-on: https://gerrit.libreoffice.org/77940 Tested-by: Jenkins diff --git a/svx/source/svdraw/svdopath.cxx b/svx/source/svdraw/svdopath.cxx index 63481a141248..eda7c34db46a 100644 --- a/svx/source/svdraw/svdopath.cxx +++ b/svx/source/svdraw/svdopath.cxx @@ -2008,45 +2008,62 @@ void SdrPathObj::AddToHdlList(SdrHdlList& rHdlList) const void SdrPathObj::AddToPlusHdlList(SdrHdlList& rHdlList, SdrHdl& rHdl) const { - // exclude some error situations - const XPolyPolygon aPathPolyPolygon(GetPathPoly()); + // keep old stuff to be able to keep old SdrHdl stuff, too + const XPolyPolygon aOldPathPolygon(GetPathPoly()); + sal_uInt16 nPnt = static_cast<sal_uInt16>(rHdl.GetPointNum()); sal_uInt16 nPolyNum = static_cast<sal_uInt16>(rHdl.GetPolyNum()); - if (nPolyNum>=aPathPolyPolygon.Count()) - return; - const XPolygon& rXPoly = aPathPolyPolygon[nPolyNum]; - sal_uInt16 nPntCount = rXPoly.GetPointCount(); - if (nPntCount<=0) + if (nPolyNum>=aOldPathPolygon.Count()) return; - sal_uInt16 nPnt = static_cast<sal_uInt16>(rHdl.GetPointNum()); - if (nPnt>=nPntCount) - return; + const XPolygon& rXPoly = aOldPathPolygon[nPolyNum]; + sal_uInt16 nPntMax = rXPoly.GetPointCount(); - if (rXPoly.IsControl(nPnt)) + if (nPntMax<=0) + return; + nPntMax--; + if (nPnt>nPntMax) return; - // segment before - if (nPnt==0 && IsClosed()) - nPnt=nPntCount-1; - if (nPnt>0 && rXPoly.IsControl(nPnt-1)) + // calculate the number of plus points + sal_uInt16 nCnt = 0; + if (rXPoly.GetFlags(nPnt)!=PolyFlags::Control) { - std::unique_ptr<SdrHdl> pHdl(new SdrHdlBezWgt(&rHdl)); - pHdl->SetPos(rXPoly[nPnt-1]); - pHdl->SetPointNum(nPnt-1); - pHdl->SetSourceHdlNum(rHdl.GetSourceHdlNum()); - pHdl->SetPlusHdl(true); - rHdlList.AddHdl(std::move(pHdl)); + if (nPnt==0 && IsClosed()) + nPnt=nPntMax; + if (nPnt>0 && rXPoly.GetFlags(nPnt-1)==PolyFlags::Control) + nCnt++; + if (nPnt==nPntMax && IsClosed()) + nPnt=0; + if (nPnt<nPntMax && rXPoly.GetFlags(nPnt+1)==PolyFlags::Control) + nCnt++; } - // segment after - if (nPnt==nPntCount-1 && IsClosed()) - nPnt=0; - if (nPnt<nPntCount-1 && rXPoly.IsControl(nPnt+1)) + // construct the plus points + for (sal_uInt32 nPlusNum = 0; nPlusNum < nCnt; ++nPlusNum) { + nPnt = static_cast<sal_uInt16>(rHdl.GetPointNum()); std::unique_ptr<SdrHdl> pHdl(new SdrHdlBezWgt(&rHdl)); - pHdl->SetPos(rXPoly[nPnt+1]); - pHdl->SetPointNum(nPnt+1); + pHdl->SetPolyNum(rHdl.GetPolyNum()); + + if (nPnt==0 && IsClosed()) + nPnt=nPntMax; + if (nPnt>0 && rXPoly.GetFlags(nPnt-1)==PolyFlags::Control && nPlusNum==0) + { + pHdl->SetPos(rXPoly[nPnt-1]); + pHdl->SetPointNum(nPnt-1); + } + else + { + if (nPnt==nPntMax && IsClosed()) + nPnt=0; + if (nPnt<rXPoly.GetPointCount()-1 && rXPoly.GetFlags(nPnt+1)==PolyFlags::Control) + { + pHdl->SetPos(rXPoly[nPnt+1]); + pHdl->SetPointNum(nPnt+1); + } + } + pHdl->SetSourceHdlNum(rHdl.GetSourceHdlNum()); pHdl->SetPlusHdl(true); rHdlList.AddHdl(std::move(pHdl)); _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
