desktop/source/lib/init.cxx | 224 +++++++++++++++++++ include/sfx2/sidebar/AsynchronousCall.hxx | 1 include/sfx2/sidebar/SidebarController.hxx | 2 include/sfx2/sidebar/SidebarDockingWindow.hxx | 6 sfx2/source/sidebar/AsynchronousCall.cxx | 8 sfx2/source/sidebar/SidebarController.cxx | 7 sfx2/source/sidebar/SidebarDockingWindow.cxx | 6 svx/source/sidebar/ContextChangeEventMultiplexer.cxx | 14 - 8 files changed, 259 insertions(+), 9 deletions(-)
New commits: commit 8fb87e03488647e6e0402052cf5d66014c0d47c6 Author: Michael Meeks <michael.me...@collabora.com> AuthorDate: Thu Dec 19 11:16:15 2019 +0000 Commit: Michael Meeks <michael.me...@collabora.com> CommitDate: Sat May 9 15:20:15 2020 +0100 sidebar: bring new sidebar commands in-house & be more assertive with sfx2 Force the sidebar to do it's asynchronous things synchronously to help keep things sane. Also emit our (in-process on Android / iOS) context change notification after everyone else got it & updated their panels. Change-Id: If94de6c83f1b783d7deee515fc2ee9a8d3754765 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/86088 Tested-by: Jenkins Reviewed-by: Michael Meeks <michael.me...@collabora.com> diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx index c34fc8eaf4d6..7256050ea2c6 100644 --- a/desktop/source/lib/init.cxx +++ b/desktop/source/lib/init.cxx @@ -106,6 +106,8 @@ #include <sfx2/dispatch.hxx> #include <sfx2/lokcharthelper.hxx> #include <sfx2/DocumentSigner.hxx> +#include <sfx2/sidebar/SidebarChildWindow.hxx> +#include <sfx2/sidebar/SidebarDockingWindow.hxx> #include <svx/dialmgr.hxx> #include <svx/dialogs.hrc> #include <svx/strings.hrc> @@ -140,6 +142,7 @@ #include <osl/module.hxx> #include <comphelper/sequence.hxx> #include <sfx2/sfxbasemodel.hxx> +#include <svl/eitem.hxx> #include <svl/undo.hxx> #include <unotools/datetime.hxx> #include <i18nlangtag/mslangid.hxx> @@ -853,6 +856,57 @@ void ExecuteOrientationChange() mxUndoManager->leaveUndoContext(); } +void setupSidebar(bool bShow) +{ + SfxViewShell* pViewShell = SfxViewShell::Current(); + SfxViewFrame* pViewFrame = pViewShell? pViewShell->GetViewFrame(): nullptr; + if (pViewFrame) + { + if (bShow && !pViewFrame->GetChildWindow(SID_SIDEBAR)) + pViewFrame->SetChildWindow(SID_SIDEBAR, false /* create it */, true /* focus */); + + pViewFrame->ShowChildWindow(SID_SIDEBAR, bShow); + + if (!bShow) + return; + + // Force synchronous population of panels + SfxChildWindow *pChild = pViewFrame->GetChildWindow(SID_SIDEBAR); + if (!pChild) + return; + + auto pDockingWin = dynamic_cast<sfx2::sidebar::SidebarDockingWindow *>(pChild->GetWindow()); + if (!pDockingWin) + return; + pDockingWin->SyncUpdate(); + } + else + SetLastExceptionMsg("No view shell or sidebar"); +} + +VclPtr<Window> getSidebarWindow() +{ + VclPtr<Window> xRet; + + setupSidebar(true); + SfxViewShell* pViewShell = SfxViewShell::Current(); + SfxViewFrame* pViewFrame = pViewShell? pViewShell->GetViewFrame(): nullptr; + if (!pViewFrame) + return xRet; + + // really a SidebarChildWindow + SfxChildWindow *pChild = pViewFrame->GetChildWindow(SID_SIDEBAR); + if (!pChild) + return xRet; + + // really a SidebarDockingWindow + vcl::Window *pWin = pChild->GetWindow(); + if (!pWin) + return xRet; + xRet = pWin; + return xRet; +} + } // end anonymous namespace // Could be anonymous in principle, but for the unit testing purposes, we @@ -3460,6 +3514,10 @@ static void doc_sendDialogEvent(LibreOfficeKitDocument* /*pThis*/, unsigned nWin StringMap aMap(jsonToStringMap(pArguments)); VclPtr<Window> pWindow = vcl::Window::FindLOKWindow(nWindowId); + + if (!pWindow && nWindowId >= 1000000000 /* why unsigned? */) + pWindow = getSidebarWindow(); + if (!pWindow) { SetLastExceptionMsg("Document doesn't support dialog rendering, or window not found."); @@ -3672,6 +3730,16 @@ static void doc_postUnoCommand(LibreOfficeKitDocument* pThis, const char* pComma return; } } + else if (gImpl && aCommand == ".uno:SidebarShow") + { + setupSidebar(true); + return; + } + else if (gImpl && aCommand == ".uno:SidebarHide") + { + setupSidebar(false); + return; + } bool bResult = false; if (bNotifyWhenFinished && pDocument->mpCallbackFlushHandlers.count(nView)) diff --git a/include/sfx2/sidebar/AsynchronousCall.hxx b/include/sfx2/sidebar/AsynchronousCall.hxx index b05c90dc86db..b2c868b653ec 100644 --- a/include/sfx2/sidebar/AsynchronousCall.hxx +++ b/include/sfx2/sidebar/AsynchronousCall.hxx @@ -40,6 +40,7 @@ public: void RequestCall(); void CancelRequest(); + void Sync(); private: Action const maAction; diff --git a/include/sfx2/sidebar/SidebarController.hxx b/include/sfx2/sidebar/SidebarController.hxx index 596382a36888..eb459b1a708f 100644 --- a/include/sfx2/sidebar/SidebarController.hxx +++ b/include/sfx2/sidebar/SidebarController.hxx @@ -169,6 +169,8 @@ public: void saveDeckState(); + void SyncUpdate(); + private: SidebarController(SidebarDockingWindow* pParentWindow, const SfxViewFrame* pViewFrame); diff --git a/include/sfx2/sidebar/SidebarDockingWindow.hxx b/include/sfx2/sidebar/SidebarDockingWindow.hxx index 0a02de481216..d722f363e81b 100644 --- a/include/sfx2/sidebar/SidebarDockingWindow.hxx +++ b/include/sfx2/sidebar/SidebarDockingWindow.hxx @@ -30,10 +30,9 @@ namespace svt { class AcceleratorExecute; } namespace sfx2 { namespace sidebar { class SidebarChildWindow; - class SidebarController; -class SidebarDockingWindow final : public SfxDockingWindow +class SFX2_DLLPUBLIC SidebarDockingWindow final : public SfxDockingWindow { public: SidebarDockingWindow(SfxBindings* pBindings, SidebarChildWindow& rChildWindow, @@ -46,6 +45,9 @@ public: void SetReadyToDrag( bool bStartDrag ) { mbIsReadyToDrag = bStartDrag; } bool IsReadyToDrag() const { return mbIsReadyToDrag; } + /// Force generation of all panels by completion. + void SyncUpdate(); + void NotifyResize(); using SfxDockingWindow::Close; diff --git a/sfx2/source/sidebar/AsynchronousCall.cxx b/sfx2/source/sidebar/AsynchronousCall.cxx index 495d62f8eb7b..0013ea5e5ceb 100644 --- a/sfx2/source/sidebar/AsynchronousCall.cxx +++ b/sfx2/source/sidebar/AsynchronousCall.cxx @@ -57,6 +57,14 @@ void AsynchronousCall::CancelRequest() } } +void AsynchronousCall::Sync() +{ + if (mnCallId != nullptr) { + maAction(); + CancelRequest(); + } +} + IMPL_LINK_NOARG(AsynchronousCall, HandleUserCall, void*, void ) { mnCallId = nullptr; diff --git a/sfx2/source/sidebar/SidebarController.cxx b/sfx2/source/sidebar/SidebarController.cxx index 081835fd6f91..5cd73cc422cf 100644 --- a/sfx2/source/sidebar/SidebarController.cxx +++ b/sfx2/source/sidebar/SidebarController.cxx @@ -495,6 +495,13 @@ void SidebarController::ProcessNewWidth (const sal_Int32 nNewWidth) } } +void SidebarController::SyncUpdate() +{ + maPropertyChangeForwarder.Sync(); + maContextChangeUpdate.Sync(); + maAsynchronousDeckSwitch.Sync(); +} + void SidebarController::UpdateConfigurations() { if (maCurrentContext == maRequestedContext diff --git a/sfx2/source/sidebar/SidebarDockingWindow.cxx b/sfx2/source/sidebar/SidebarDockingWindow.cxx index c354da362d74..8d5eb08b9d2b 100644 --- a/sfx2/source/sidebar/SidebarDockingWindow.cxx +++ b/sfx2/source/sidebar/SidebarDockingWindow.cxx @@ -111,6 +111,12 @@ void SidebarDockingWindow::Resize() NotifyResize(); } +void SidebarDockingWindow::SyncUpdate() +{ + if (mpSidebarController.is()) + mpSidebarController->SyncUpdate(); +} + void SidebarDockingWindow::NotifyResize() { if (comphelper::LibreOfficeKit::isActive() && SfxViewShell::Current() && mbSidebarVisibleInLOK) diff --git a/svx/source/sidebar/ContextChangeEventMultiplexer.cxx b/svx/source/sidebar/ContextChangeEventMultiplexer.cxx index 321a56c5024e..af804342fa34 100644 --- a/svx/source/sidebar/ContextChangeEventMultiplexer.cxx +++ b/svx/source/sidebar/ContextChangeEventMultiplexer.cxx @@ -39,13 +39,6 @@ void ContextChangeEventMultiplexer::NotifyContextChange ( { if (rxController.is() && rxController->getFrame().is()) { - // notify the LOK too - if (comphelper::LibreOfficeKit::isActive()) - { - if (SfxViewShell* pViewShell = SfxViewShell::Get(rxController)) - SfxLokHelper::notifyContextChange(pViewShell, GetModuleName(rxController->getFrame()), vcl::EnumContext::GetContextName(eContext)); - } - const css::ui::ContextChangeEventObject aEvent( rxController, GetModuleName(rxController->getFrame()), @@ -56,6 +49,13 @@ void ContextChangeEventMultiplexer::NotifyContextChange ( ::comphelper::getProcessComponentContext())); if (xMultiplexer.is()) xMultiplexer->broadcastContextChangeEvent(aEvent, rxController); + + // notify the LOK too after all the change have taken effect. + if (comphelper::LibreOfficeKit::isActive()) + { + if (SfxViewShell* pViewShell = SfxViewShell::Get(rxController)) + SfxLokHelper::notifyContextChange(pViewShell, GetModuleName(rxController->getFrame()), vcl::EnumContext::GetContextName(eContext)); + } } } commit 8afeb4f945f95c3b9e13de43b4c9c57c4822b996 Author: Muhammet Kara <muhammet.k...@collabora.com> AuthorDate: Fri Dec 20 22:24:49 2019 +0300 Commit: Michael Meeks <michael.me...@collabora.com> CommitDate: Sat May 9 15:16:59 2020 +0100 lok: Add pseudo uno command ToggleOrientation Toggles orientation of the Writer page Change-Id: Ifcd5ca96bd16e50e5a4fa304f82f60e2425bd8f0 Reviewed-on: https://gerrit.libreoffice.org/85638 Tested-by: Jenkins Reviewed-by: Muhammet Kara <muhammet.k...@collabora.com> diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx index 324467a586e5..c34fc8eaf4d6 100644 --- a/desktop/source/lib/init.cxx +++ b/desktop/source/lib/init.cxx @@ -149,6 +149,13 @@ #include <tools/diagnose_ex.h> #include <vcl/uitest/uiobject.hxx> +// Needed for getUndoManager() +#include <com/sun/star/document/XUndoManager.hpp> +#include <com/sun/star/document/XUndoManagerSupplier.hpp> +#include <editeng/sizeitem.hxx> +#include <svx/rulritem.hxx> +#include <svx/pageitem.hxx> + #include <app.hxx> #include "../app/cmdlineargs.hxx" @@ -702,6 +709,150 @@ std::string extractPrivateKey(const std::string & privateKey) return privateKey.substr(pos1, pos2); } +// Gets an undo manager to enter and exit undo context. Needed by ToggleOrientation +css::uno::Reference< css::document::XUndoManager > getUndoManager( const css::uno::Reference< css::frame::XFrame >& rxFrame ) +{ + const css::uno::Reference< css::frame::XController >& xController = rxFrame->getController(); + if ( xController.is() ) + { + const css::uno::Reference< css::frame::XModel >& xModel = xController->getModel(); + if ( xModel.is() ) + { + const css::uno::Reference< css::document::XUndoManagerSupplier > xSuppUndo( xModel, css::uno::UNO_QUERY_THROW ); + return css::uno::Reference< css::document::XUndoManager >( xSuppUndo->getUndoManager(), css::uno::UNO_SET_THROW ); + } + } + + return css::uno::Reference< css::document::XUndoManager > (); +} + +// Adjusts page margins for Writer doc. Needed by ToggleOrientation +void ExecuteMarginLRChange( + const long nPageLeftMargin, + const long nPageRightMargin, + std::shared_ptr<SvxLongLRSpaceItem> mpPageLRMarginItem) +{ + mpPageLRMarginItem->SetLeft( nPageLeftMargin ); + mpPageLRMarginItem->SetRight( nPageRightMargin ); + SfxViewShell::Current()->GetDispatcher()->ExecuteList(SID_ATTR_PAGE_LRSPACE, + SfxCallMode::RECORD, { mpPageLRMarginItem.get() }); +} + +// Adjusts page margins for Writer doc. Needed by ToggleOrientation +void ExecuteMarginULChange( + const long nPageTopMargin, + const long nPageBottomMargin, + std::shared_ptr<SvxLongULSpaceItem> mpPageULMarginItem) +{ + mpPageULMarginItem->SetUpper( nPageTopMargin ); + mpPageULMarginItem->SetLower( nPageBottomMargin ); + SfxViewShell::Current()->GetDispatcher()->ExecuteList(SID_ATTR_PAGE_ULSPACE, + SfxCallMode::RECORD, { mpPageULMarginItem.get() }); +} + +// Main function which toggles page orientation of the Writer doc. Needed by ToggleOrientation +void ExecuteOrientationChange() +{ + std::unique_ptr<SvxPageItem> mpPageItem(new SvxPageItem(SID_ATTR_PAGE)); + std::unique_ptr<SvxSizeItem> mpPageSizeItem(new SvxSizeItem(SID_ATTR_PAGE_SIZE)); + std::shared_ptr<SvxLongLRSpaceItem> mpPageLRMarginItem(new SvxLongLRSpaceItem( 0, 0, SID_ATTR_PAGE_LRSPACE )); + std::shared_ptr<SvxLongULSpaceItem> mpPageULMarginItem(new SvxLongULSpaceItem( 0, 0, SID_ATTR_PAGE_ULSPACE )); + // 1mm in twips rounded + // This should be in sync with MINBODY in sw/source/uibase/sidebar/PageMarginControl.hxx + const long MINBODY = 56; + bool bIsLandscape = false; + + css::uno::Reference< css::document::XUndoManager > mxUndoManager( + getUndoManager( SfxViewFrame::Current()->GetFrame().GetFrameInterface() ) ); + + if ( mxUndoManager.is() ) + mxUndoManager->enterUndoContext( "" ); + + + const SfxPoolItem* pItem; + + + SfxViewFrame::Current()->GetBindings().GetDispatcher()->QueryState(SID_ATTR_PAGE_SIZE, pItem); + mpPageSizeItem.reset( static_cast<SvxSizeItem*>(pItem->Clone()) ); + + + + SfxViewFrame::Current()->GetBindings().GetDispatcher()->QueryState(SID_ATTR_PAGE_LRSPACE, pItem); + mpPageLRMarginItem.reset( static_cast<SvxLongLRSpaceItem*>(pItem->Clone()) ); + + + + SfxViewFrame::Current()->GetBindings().GetDispatcher()->QueryState(SID_ATTR_PAGE_ULSPACE, pItem); + mpPageULMarginItem.reset( static_cast<SvxLongULSpaceItem*>(pItem->Clone()) ); + + + { + if ( mpPageSizeItem->GetSize().Width() > mpPageSizeItem->GetSize().Height()) + bIsLandscape = true; + + // toggle page orientation + mpPageItem->SetLandscape(!bIsLandscape); + + + // swap the width and height of the page size + const long nRotatedWidth = mpPageSizeItem->GetSize().Height(); + const long nRotatedHeight = mpPageSizeItem->GetSize().Width(); + mpPageSizeItem->SetSize(Size(nRotatedWidth, nRotatedHeight)); + + + // apply changed attributes + if (SfxViewShell::Current()) + { + SfxViewShell::Current()->GetDispatcher()->ExecuteList(SID_ATTR_PAGE_SIZE, + SfxCallMode::RECORD, { mpPageSizeItem.get(), mpPageItem.get() }); + } + } + + + // check, if margin values still fit to the changed page size. + // if not, adjust margin values + { + const long nML = mpPageLRMarginItem->GetLeft(); + const long nMR = mpPageLRMarginItem->GetRight(); + const long nTmpPW = nML + nMR + MINBODY; + + const long nPW = mpPageSizeItem->GetSize().Width(); + + if ( nTmpPW > nPW ) + { + if ( nML <= nMR ) + { + ExecuteMarginLRChange( mpPageLRMarginItem->GetLeft(), nMR - (nTmpPW - nPW ), mpPageLRMarginItem ); + } + else + { + ExecuteMarginLRChange( nML - (nTmpPW - nPW ), mpPageLRMarginItem->GetRight(), mpPageLRMarginItem ); + } + } + + const long nMT = mpPageULMarginItem->GetUpper(); + const long nMB = mpPageULMarginItem->GetLower(); + const long nTmpPH = nMT + nMB + MINBODY; + + const long nPH = mpPageSizeItem->GetSize().Height(); + + if ( nTmpPH > nPH ) + { + if ( nMT <= nMB ) + { + ExecuteMarginULChange( mpPageULMarginItem->GetUpper(), nMB - ( nTmpPH - nPH ), mpPageULMarginItem ); + } + else + { + ExecuteMarginULChange( nMT - ( nTmpPH - nPH ), mpPageULMarginItem->GetLower(), mpPageULMarginItem ); + } + } + } + + if ( mxUndoManager.is() ) + mxUndoManager->leaveUndoContext(); +} + } // end anonymous namespace // Could be anonymous in principle, but for the unit testing purposes, we @@ -3406,6 +3557,11 @@ static void doc_postUnoCommand(LibreOfficeKitDocument* pThis, const char* pComma comphelper::LibreOfficeKit::setMobile(nView, false); return; } + else if (gImpl && aCommand == ".uno:ToggleOrientation") + { + ExecuteOrientationChange(); + return; + } // handle potential interaction if (gImpl && aCommand == ".uno:Save") _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits