diff options
author | Sarper Akdemir <sarper.akdemir.extern@allotropia.de> | 2024-04-04 07:18:38 +0300 |
---|---|---|
committer | Samuel Mehrbrodt <samuel.mehrbrodt@allotropia.de> | 2024-04-11 11:02:01 +0200 |
commit | 291919476294f62d7af9b8b7060d138728897ee7 (patch) | |
tree | fbefb7f2bf02ec5c2f9a333818af3bc918d1b60b /sd/source | |
parent | 8d85da5616bab28c1df226bcbf4fe777b14b363e (diff) |
tdf#33603: sd: rework notes panel
To be able to support various dispatch commands, sidebar, proper
user configuration, and more - reworked the previous notes panel
implementation as a sd::View/sd::ViewShell pair that plays nice
with Impress framework.
To be able to support TextObjectBar(Shell) functionality, without
having TextObjectBar as a SubShell (In the current sd::framework
implementation AFAICS, SubShells are only possible for the
MainViewShell - this doesn't work for notes panel which is never
used as the MainViewShell.).
A workaround is implemented where NotesPanel inherits dispatching
slots from TextObjectBar, and for these inherited slots forwards
the calls to TextObjectBar's implementation.
This workaround could be removed if/when, SubShell support
outside of MainViewShell is implemented.
Known issues/TODO:
- Drag & Drop crashes / doesn't work.
- Some notes placeholder syncing problems on page change, edit mode
change.
- A rendering issue related to resizing when ArrangeGUIElements
isn't called on resize.
Change-Id: I588a4854fbedf6556e001fee1693b32410cbc23f
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/165770
Tested-by: Jenkins
Reviewed-by: Samuel Mehrbrodt <samuel.mehrbrodt@allotropia.de>
Diffstat (limited to 'sd/source')
24 files changed, 2267 insertions, 126 deletions
diff --git a/sd/source/ui/app/sddll.cxx b/sd/source/ui/app/sddll.cxx index b21ce1c549e1..67019328b6e2 100644 --- a/sd/source/ui/app/sddll.cxx +++ b/sd/source/ui/app/sddll.cxx @@ -177,6 +177,7 @@ void SdDLL::RegisterControllers(SdModule* pMod) ::avmedia::MediaPlayer::RegisterChildWindow(false, pMod); #endif ::sd::LeftPaneImpressChildWindow::RegisterChildWindow(false, pMod); + ::sd::BottomPaneImpressChildWindow::RegisterChildWindow(false, pMod); ::sd::LeftPaneDrawChildWindow::RegisterChildWindow(false, pMod); ::sfx2::sidebar::SidebarChildWindow::RegisterChildWindow(false, pMod); ::sd::NotesChildWindow::RegisterChildWindow(false, pMod); diff --git a/sd/source/ui/dlg/PaneChildWindows.cxx b/sd/source/ui/dlg/PaneChildWindows.cxx index 320ce2a74b3d..5bbfa4eb2c4d 100644 --- a/sd/source/ui/dlg/PaneChildWindows.cxx +++ b/sd/source/ui/dlg/PaneChildWindows.cxx @@ -32,6 +32,7 @@ namespace sd { SFX_IMPL_DOCKINGWINDOW_WITHID(LeftPaneImpressChildWindow, SID_LEFT_PANE_IMPRESS) +SFX_IMPL_DOCKINGWINDOW_WITHID(BottomPaneImpressChildWindow, SID_BOTTOM_PANE_IMPRESS) SFX_IMPL_DOCKINGWINDOW_WITHID(LeftPaneDrawChildWindow, SID_LEFT_PANE_DRAW) //===== PaneChildWindow ======================================================= @@ -40,7 +41,8 @@ PaneChildWindow::PaneChildWindow ( sal_uInt16 nId, SfxBindings* pBindings, SfxChildWinInfo* pInfo, - TranslateId pTitleBarResId) + TranslateId pTitleBarResId, + SfxChildAlignment eAlignment) : SfxChildWindow (pParentWindow, nId) { SetWindow( VclPtr<TitledDockingWindow>::Create( @@ -48,7 +50,7 @@ PaneChildWindow::PaneChildWindow ( this, pParentWindow, SdResId(pTitleBarResId))); - SetAlignment(SfxChildAlignment::LEFT); + SetAlignment(eAlignment); SfxDockingWindow* pDockingWindow = static_cast<SfxDockingWindow*>(GetWindow()); pDockingWindow->EnableInput(); pDockingWindow->Initialize(pInfo); @@ -83,7 +85,24 @@ LeftPaneImpressChildWindow::LeftPaneImpressChildWindow ( nId, pBindings, pInfo, - STR_LEFT_PANE_IMPRESS_TITLE) + STR_LEFT_PANE_IMPRESS_TITLE, + SfxChildAlignment::LEFT) +{ +} + +//===== BottomPaneImpressChildWindow ============================================ +BottomPaneImpressChildWindow::BottomPaneImpressChildWindow ( + vcl::Window* pParentWindow, + sal_uInt16 nId, + SfxBindings* pBindings, + SfxChildWinInfo* pInfo) + : PaneChildWindow( + pParentWindow, + nId, + pBindings, + pInfo, + STR_NOTES_MODE, // TODO this isn't a specific translatable string for this view. + SfxChildAlignment::BOTTOM) { } @@ -98,7 +117,8 @@ LeftPaneDrawChildWindow::LeftPaneDrawChildWindow ( nId, pBindings, pInfo, - STR_LEFT_PANE_DRAW_TITLE) + STR_LEFT_PANE_DRAW_TITLE, + SfxChildAlignment::LEFT) { } diff --git a/sd/source/ui/dlg/PaneShells.cxx b/sd/source/ui/dlg/PaneShells.cxx index 77e411aaedc2..ab523bf7c83c 100644 --- a/sd/source/ui/dlg/PaneShells.cxx +++ b/sd/source/ui/dlg/PaneShells.cxx @@ -50,6 +50,23 @@ LeftImpressPaneShell::~LeftImpressPaneShell() { } +//===== BottomImpressPaneShell ================================================== + +static SfxSlot aBottomImpressPaneShellSlots_Impl[] + = { { 0, SfxGroupId::NONE, SfxSlotMode::NONE, 0, 0, nullptr, nullptr, nullptr, nullptr, nullptr, + 0, SfxDisableFlags::NONE, "" } }; + +SFX_IMPL_INTERFACE(BottomImpressPaneShell, SfxShell) + +void BottomImpressPaneShell::InitInterface_Impl() +{ + GetStaticInterface()->RegisterChildWindow(::sd::BottomPaneImpressChildWindow::GetChildWindowId()); +} + +BottomImpressPaneShell::BottomImpressPaneShell() { SetName("BottomImpressPane"); } + +BottomImpressPaneShell::~BottomImpressPaneShell() {} + //===== LeftDrawPaneShell ===================================================== static SfxSlot aLeftDrawPaneShellSlots_Impl[] = diff --git a/sd/source/ui/framework/factories/BasicPaneFactory.cxx b/sd/source/ui/framework/factories/BasicPaneFactory.cxx index 4ce694a2e7df..2168df8c7a8b 100644 --- a/sd/source/ui/framework/factories/BasicPaneFactory.cxx +++ b/sd/source/ui/framework/factories/BasicPaneFactory.cxx @@ -46,6 +46,7 @@ namespace { CenterPaneId, FullScreenPaneId, LeftImpressPaneId, + BottomImpressPaneId, LeftDrawPaneId }; @@ -119,6 +120,11 @@ BasicPaneFactory::BasicPaneFactory ( mpPaneContainer->push_back(aDescriptor); xCC->addResourceFactory(aDescriptor.msPaneURL, this); + aDescriptor.msPaneURL = FrameworkHelper::msBottomImpressPaneURL; + aDescriptor.mePaneId = BottomImpressPaneId; + mpPaneContainer->push_back(aDescriptor); + xCC->addResourceFactory(aDescriptor.msPaneURL, this); + aDescriptor.msPaneURL = FrameworkHelper::msLeftDrawPaneURL; aDescriptor.mePaneId = LeftDrawPaneId; mpPaneContainer->push_back(aDescriptor); @@ -222,6 +228,7 @@ Reference<XResource> SAL_CALL BasicPaneFactory::createResource ( break; case LeftImpressPaneId: + case BottomImpressPaneId: case LeftDrawPaneId: xPane = CreateChildWindowPane( rxPaneId, @@ -369,6 +376,11 @@ Reference<XResource> BasicPaneFactory::CreateChildWindowPane ( nChildWindowId = ::sd::LeftPaneImpressChildWindow::GetChildWindowId(); break; + case BottomImpressPaneId: + pShell.reset(new BottomImpressPaneShell()); + nChildWindowId = ::sd::BottomPaneImpressChildWindow::GetChildWindowId(); + break; + case LeftDrawPaneId: pShell.reset(new LeftDrawPaneShell()); nChildWindowId = ::sd::LeftPaneDrawChildWindow::GetChildWindowId(); diff --git a/sd/source/ui/framework/factories/BasicViewFactory.cxx b/sd/source/ui/framework/factories/BasicViewFactory.cxx index 3ea7e37f1f93..61118d650bbe 100644 --- a/sd/source/ui/framework/factories/BasicViewFactory.cxx +++ b/sd/source/ui/framework/factories/BasicViewFactory.cxx @@ -31,6 +31,7 @@ #include <DrawViewShell.hxx> #include <GraphicViewShell.hxx> #include <OutlineViewShell.hxx> +#include <NotesPanelViewShell.hxx> #include <PresentationViewShell.hxx> #include <SlideSorterViewShell.hxx> #include <FrameView.hxx> @@ -106,6 +107,7 @@ BasicViewFactory::BasicViewFactory (const rtl::Reference<::sd::DrawController>& mxConfigurationController->addResourceFactory(FrameworkHelper::msHandoutViewURL, this); mxConfigurationController->addResourceFactory(FrameworkHelper::msPresentationViewURL, this); mxConfigurationController->addResourceFactory(FrameworkHelper::msSlideSorterURL, this); + mxConfigurationController->addResourceFactory(FrameworkHelper::msNotesPanelViewURL, this); } catch (RuntimeException&) { @@ -367,6 +369,11 @@ std::shared_ptr<ViewShell> BasicViewFactory::CreateViewShell ( pFrameView); pViewShell->GetContentWindow()->set_id("slidesorter"); } + else if (rsViewURL == FrameworkHelper::msNotesPanelViewURL) + { + pViewShell = std::make_shared<NotesPanelViewShell>(&rFrame, *mpBase, &rWindow, pFrameView); + pViewShell->GetContentWindow()->set_id("notes_panel_win"); + } return pViewShell; } diff --git a/sd/source/ui/framework/tools/FrameworkHelper.cxx b/sd/source/ui/framework/tools/FrameworkHelper.cxx index 0a42649b1c85..d47ebc5fa8ac 100644 --- a/sd/source/ui/framework/tools/FrameworkHelper.cxx +++ b/sd/source/ui/framework/tools/FrameworkHelper.cxx @@ -174,6 +174,7 @@ namespace { const OUString FrameworkHelper::msCenterPaneURL( msPaneURLPrefix + "CenterPane"); const OUString FrameworkHelper::msFullScreenPaneURL( msPaneURLPrefix + "FullScreenPane"); const OUString FrameworkHelper::msLeftImpressPaneURL( msPaneURLPrefix + "LeftImpressPane"); +const OUString FrameworkHelper::msBottomImpressPaneURL( msPaneURLPrefix + "BottomImpressPane"); const OUString FrameworkHelper::msLeftDrawPaneURL( msPaneURLPrefix + "LeftDrawPane"); // View URLs. @@ -186,6 +187,7 @@ const OUString FrameworkHelper::msHandoutViewURL( msViewURLPrefix + "HandoutView const OUString FrameworkHelper::msSlideSorterURL( msViewURLPrefix + "SlideSorter"); const OUString FrameworkHelper::msPresentationViewURL( msViewURLPrefix + "PresentationView"); const OUString FrameworkHelper::msSidebarViewURL( msViewURLPrefix + "SidebarView"); +const OUString FrameworkHelper::msNotesPanelViewURL( msViewURLPrefix + "NotesPanelView"); // Tool bar URLs. @@ -434,6 +436,7 @@ ViewShell::ShellType FrameworkHelper::GetViewId (const OUString& rsViewURL) maViewURLMap[msSlideSorterURL] = ViewShell::ST_SLIDE_SORTER; maViewURLMap[msPresentationViewURL] = ViewShell::ST_PRESENTATION; maViewURLMap[msSidebarViewURL] = ViewShell::ST_SIDEBAR; + maViewURLMap[msNotesPanelViewURL] = ViewShell::ST_NOTESPANEL; } ViewURLMap::const_iterator iView (maViewURLMap.find(rsViewURL)); if (iView != maViewURLMap.end()) @@ -454,6 +457,7 @@ OUString FrameworkHelper::GetViewURL (ViewShell::ShellType eType) case ViewShell::ST_SLIDE_SORTER : return msSlideSorterURL; case ViewShell::ST_PRESENTATION : return msPresentationViewURL; case ViewShell::ST_SIDEBAR : return msSidebarViewURL; + case ViewShell::ST_NOTESPANEL: return msNotesPanelViewURL; default: return OUString(); } diff --git a/sd/source/ui/func/fuoltext.cxx b/sd/source/ui/func/fuoltext.cxx index fe64cac47dfb..0068f77d4053 100644 --- a/sd/source/ui/func/fuoltext.cxx +++ b/sd/source/ui/func/fuoltext.cxx @@ -82,25 +82,85 @@ const sal_uInt16 SidArray[] = { SID_SUMMARY_PAGE, 0 }; +void FuOutlineText::UpdateForKeyPress (const KeyEvent& rEvent) +{ + FuSimpleOutlinerText::UpdateForKeyPress(rEvent); + + bool bUpdatePreview = true; + switch (rEvent.GetKeyCode().GetCode()) + { + // When just the cursor has been moved the preview only changes when + // it moved to entries of another page. To prevent unnecessary + // updates we check this here. This is an early rejection test, so + // missing a key is not a problem. + case KEY_UP: + case KEY_DOWN: + case KEY_LEFT: + case KEY_RIGHT: + case KEY_HOME: + case KEY_END: + case KEY_PAGEUP: + case KEY_PAGEDOWN: + { + SdPage* pCurrentPage = pOutlineViewShell->GetActualPage(); + bUpdatePreview = (pCurrentPage != pOutlineViewShell->GetActualPage()); + } + break; + } + if (bUpdatePreview) + pOutlineViewShell->UpdatePreview (pOutlineViewShell->GetActualPage()); +} + +/** + * Process keyboard input + * @returns sal_True if a KeyEvent is being processed, sal_False otherwise + */ +bool FuOutlineText::KeyInput(const KeyEvent& rKEvt) +{ + sal_uInt16 nKeyGroup = rKEvt.GetKeyCode().GetGroup(); + if( !mpDocSh->IsReadOnly() || nKeyGroup == KEYGROUP_CURSOR ) + { + std::unique_ptr<OutlineViewModelChangeGuard, o3tl::default_delete<OutlineViewModelChangeGuard>> aGuard; + if( (nKeyGroup != KEYGROUP_CURSOR) && (nKeyGroup != KEYGROUP_FKEYS) ) + aGuard.reset( new OutlineViewModelChangeGuard( *static_cast<OutlineView*>(mpSimpleOutlinerView) ) ); + + return FuSimpleOutlinerText::KeyInput(rKEvt); + } + + return false; +} + +rtl::Reference<FuPoor> FuOutlineText::Create( ViewShell* pViewSh, ::sd::Window* pWin, ::sd::SimpleOutlinerView* pView, SdDrawDocument* pDoc, SfxRequest& rReq ) +{ + rtl::Reference<FuPoor> xFunc( new FuOutlineText( pViewSh, pWin, pView, pDoc, rReq ) ); + xFunc->DoExecute( rReq ); + return xFunc; +} FuOutlineText::FuOutlineText(ViewShell* pViewShell, ::sd::Window* pWindow, - ::sd::View* pView, SdDrawDocument* pDoc, + ::sd::SimpleOutlinerView* pView, SdDrawDocument* pDoc, + SfxRequest& rReq) + : FuSimpleOutlinerText(pViewShell, pWindow, pView, pDoc, rReq) +{} + +FuSimpleOutlinerText::FuSimpleOutlinerText(ViewShell* pViewShell, ::sd::Window* pWindow, + ::sd::SimpleOutlinerView* pView, SdDrawDocument* pDoc, SfxRequest& rReq) : FuPoor(pViewShell, pWindow, pView, pDoc, rReq), - pOutlineViewShell (static_cast<OutlineViewShell*>(pViewShell)), - pOutlineView (static_cast<OutlineView*>(pView)) + pOutlineViewShell (pViewShell), + mpSimpleOutlinerView (pView) { } /** * forward to OutlinerView */ -bool FuOutlineText::Command(const CommandEvent& rCEvt) +bool FuSimpleOutlinerText::Command(const CommandEvent& rCEvt) { bool bResult = false; - OutlinerView* pOlView = - static_cast<OutlineView*>(mpView)->GetViewByWindow(mpWindow); + OutlinerView* pOlView = mpSimpleOutlinerView->GetViewByWindow(mpWindow); + DBG_ASSERT (pOlView, "no OutlineView found"); if (pOlView) @@ -112,18 +172,18 @@ bool FuOutlineText::Command(const CommandEvent& rCEvt) } -rtl::Reference<FuPoor> FuOutlineText::Create( ViewShell* pViewSh, ::sd::Window* pWin, ::sd::View* pView, SdDrawDocument* pDoc, SfxRequest& rReq ) +rtl::Reference<FuPoor> FuSimpleOutlinerText::Create( ViewShell* pViewSh, ::sd::Window* pWin, ::sd::SimpleOutlinerView* pView, SdDrawDocument* pDoc, SfxRequest& rReq ) { - rtl::Reference<FuPoor> xFunc( new FuOutlineText( pViewSh, pWin, pView, pDoc, rReq ) ); + rtl::Reference<FuPoor> xFunc( new FuSimpleOutlinerText( pViewSh, pWin, pView, pDoc, rReq ) ); xFunc->DoExecute( rReq ); return xFunc; } -bool FuOutlineText::MouseButtonDown(const MouseEvent& rMEvt) +bool FuSimpleOutlinerText::MouseButtonDown(const MouseEvent& rMEvt) { mpWindow->GrabFocus(); - bool bReturn = pOutlineView->GetViewByWindow(mpWindow)->MouseButtonDown(rMEvt); + bool bReturn = mpSimpleOutlinerView->GetViewByWindow(mpWindow)->MouseButtonDown(rMEvt); if (bReturn) { @@ -138,9 +198,9 @@ bool FuOutlineText::MouseButtonDown(const MouseEvent& rMEvt) return bReturn; } -bool FuOutlineText::MouseMove(const MouseEvent& rMEvt) +bool FuSimpleOutlinerText::MouseMove(const MouseEvent& rMEvt) { - bool bReturn = pOutlineView->GetViewByWindow(mpWindow)->MouseMove(rMEvt); + bool bReturn = mpSimpleOutlinerView->GetViewByWindow(mpWindow)->MouseMove(rMEvt); if (!bReturn) { @@ -150,9 +210,9 @@ bool FuOutlineText::MouseMove(const MouseEvent& rMEvt) return bReturn; } -bool FuOutlineText::MouseButtonUp(const MouseEvent& rMEvt) +bool FuSimpleOutlinerText::MouseButtonUp(const MouseEvent& rMEvt) { - bool bReturn = pOutlineView->GetViewByWindow(mpWindow)->MouseButtonUp(rMEvt); + bool bReturn = mpSimpleOutlinerView->GetViewByWindow(mpWindow)->MouseButtonUp(rMEvt); if (bReturn) { @@ -161,7 +221,7 @@ bool FuOutlineText::MouseButtonUp(const MouseEvent& rMEvt) } else { - const SvxFieldItem* pFieldItem = pOutlineView->GetViewByWindow( mpWindow )->GetFieldUnderMousePointer(); + const SvxFieldItem* pFieldItem = mpSimpleOutlinerView->GetViewByWindow( mpWindow )->GetFieldUnderMousePointer(); if( pFieldItem ) { const SvxFieldData* pField = pFieldItem->GetField(); @@ -204,7 +264,7 @@ bool FuOutlineText::MouseButtonUp(const MouseEvent& rMEvt) * Process keyboard input * @returns sal_True if a KeyEvent is being processed, sal_False otherwise */ -bool FuOutlineText::KeyInput(const KeyEvent& rKEvt) +bool FuSimpleOutlinerText::KeyInput(const KeyEvent& rKEvt) { bool bReturn = false; @@ -213,11 +273,7 @@ bool FuOutlineText::KeyInput(const KeyEvent& rKEvt) { mpWindow->GrabFocus(); - std::unique_ptr<OutlineViewModelChangeGuard, o3tl::default_delete<OutlineViewModelChangeGuard>> aGuard; - if( (nKeyGroup != KEYGROUP_CURSOR) && (nKeyGroup != KEYGROUP_FKEYS) ) - aGuard.reset( new OutlineViewModelChangeGuard( *pOutlineView ) ); - - bReturn = pOutlineView->GetViewByWindow(mpWindow)->PostKeyEvent(rKEvt); + bReturn = mpSimpleOutlinerView->GetViewByWindow(mpWindow)->PostKeyEvent(rKEvt); if (bReturn) { @@ -232,74 +288,49 @@ bool FuOutlineText::KeyInput(const KeyEvent& rKEvt) return bReturn; } -void FuOutlineText::UpdateForKeyPress (const KeyEvent& rEvent) +void FuSimpleOutlinerText::UpdateForKeyPress (const KeyEvent& /*rEvent*/) { // Attributes at the current text position may have changed. mpViewShell->GetViewFrame()->GetBindings().Invalidate(SidArray); - - bool bUpdatePreview = true; - switch (rEvent.GetKeyCode().GetCode()) - { - // When just the cursor has been moved the preview only changes when - // it moved to entries of another page. To prevent unnecessary - // updates we check this here. This is an early rejection test, so - // missing a key is not a problem. - case KEY_UP: - case KEY_DOWN: - case KEY_LEFT: - case KEY_RIGHT: - case KEY_HOME: - case KEY_END: - case KEY_PAGEUP: - case KEY_PAGEDOWN: - { - SdPage* pCurrentPage = pOutlineViewShell->GetActualPage(); - bUpdatePreview = (pCurrentPage != pOutlineViewShell->GetActualPage()); - } - break; - } - if (bUpdatePreview) - pOutlineViewShell->UpdatePreview (pOutlineViewShell->GetActualPage()); } /** * Cut object to clipboard */ -void FuOutlineText::DoCut() +void FuSimpleOutlinerText::DoCut() { - pOutlineView->GetViewByWindow(mpWindow)->Cut(); + mpSimpleOutlinerView->GetViewByWindow(mpWindow)->Cut(); } /** * Copy object to clipboard */ -void FuOutlineText::DoCopy() +void FuSimpleOutlinerText::DoCopy() { - pOutlineView->GetViewByWindow(mpWindow)->Copy(); + mpSimpleOutlinerView->GetViewByWindow(mpWindow)->Copy(); } /** * Paste object from clipboard */ -void FuOutlineText::DoPaste() +void FuSimpleOutlinerText::DoPaste() { - pOutlineView->GetViewByWindow(mpWindow)->PasteSpecial(); + mpSimpleOutlinerView->GetViewByWindow(mpWindow)->PasteSpecial(); } /** * Paste object as unformatted text from clipboard */ -void FuOutlineText::DoPasteUnformatted() +void FuSimpleOutlinerText::DoPasteUnformatted() { TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( mpViewShell->GetActiveWindow() ) ); if (aDataHelper.GetTransferable().is()) { OUString aText; if (aDataHelper.GetString(SotClipboardFormatId::STRING, aText)) - pOutlineView->GetViewByWindow(mpWindow)->InsertText(aText); + mpSimpleOutlinerView->GetViewByWindow(mpWindow)->InsertText(aText); } } } // end of namespace sd - /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/inc/NotesPanelView.hxx b/sd/source/ui/inc/NotesPanelView.hxx new file mode 100644 index 000000000000..4bb94590acbb --- /dev/null +++ b/sd/source/ui/inc/NotesPanelView.hxx @@ -0,0 +1,96 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include "OutlineView.hxx" +#include <Outliner.hxx> + +class SdrTextObj; + +namespace sd::tools +{ +class EventMultiplexerEvent; +} + +namespace sd +{ +class DrawDocShell; +class NotesPanelViewShell; + +/** + * Derivative of ::sd::SimpleOutlinerView for the notes panel +|* +\************************************************************************/ + +class NotesPanelView final : public ::sd::SimpleOutlinerView +{ + NotesPanelViewShell& mrNotesPanelViewShell; + SdOutliner maOutliner; + OutlinerView maOutlinerView; + + Idle aModifyIdle; + + SdrTextObj* mpTextObj = nullptr; + bool mbFirstPaint = true; + bool mbIgnoreNotifications = false; + + /** stores the last used document color. + this is changed in onUpdateStyleSettings() + */ + Color maDocColor = COL_WHITE; + + void removeListener(); + void addListener(); + + void setListenerIgnored(bool bIgnore); + bool isListenerIgnored(); + + void getNotesFromDoc(); + void setNotesToDoc(); + +public: + NotesPanelView(DrawDocShell& rDocSh, vcl::Window* pWindow, + NotesPanelViewShell& rNotesPanelViewSh); + virtual ~NotesPanelView() override; + + void Paint(const ::tools::Rectangle& rRect, ::sd::Window const* pWin); + void onResize(); + + OutlinerView* GetOutlinerView(); + OutlinerView* GetViewByWindow(vcl::Window const* pWin) const override; + + SdOutliner& GetOutliner() { return maOutliner; } + + void FillOutliner(); + void onUpdateStyleSettings(bool bForceUpdate); + virtual SvtScriptType GetScriptType() const override; + + void SetLinks(); + void ResetLinks(); + virtual void Notify(SfxBroadcaster& rBC, const SfxHint& rHint) override; + + virtual void GetAttributes(SfxItemSet& rTargetSet, bool bOnlyHardAttr = false) const override; + virtual bool SetAttributes(const SfxItemSet& rSet, bool bReplaceAll = false, + bool bSlide = false, bool bMaster = false) override; + + // SdrObjEditView's Outliner access overrides to use TextObjectBar implementations. + virtual const SdrOutliner* GetTextEditOutliner() const override { return &maOutliner; } + virtual SdrOutliner* GetTextEditOutliner() override { return &maOutliner; } + virtual const OutlinerView* GetTextEditOutlinerView() const override { return &maOutlinerView; } + virtual OutlinerView* GetTextEditOutlinerView() override { return &maOutlinerView; } + + DECL_LINK(StatusEventHdl, EditStatus&, void); + DECL_LINK(EditModifiedHdl, LinkParamNone*, void); + DECL_LINK(ModifyTimerHdl, Timer*, void); + DECL_LINK(EventMultiplexerListener, tools::EventMultiplexerEvent&, void); +}; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/sd/source/ui/inc/NotesPanelViewShell.hxx b/sd/source/ui/inc/NotesPanelViewShell.hxx new file mode 100644 index 000000000000..e79ac899fe30 --- /dev/null +++ b/sd/source/ui/inc/NotesPanelViewShell.hxx @@ -0,0 +1,101 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include "ViewShell.hxx" +#include <glob.hxx> + +class SdPage; + +namespace sd +{ +class NotesPanelView; + +class NotesPanelViewShell final : public ViewShell +{ +public: + SFX_DECL_VIEWFACTORY(NotesPanelViewShell); + SFX_DECL_INTERFACE(SD_IF_SDNOTESPANELVIEWSHELL) + +private: + /// SfxInterface initializer. + static void InitInterface_Impl(); + +public: + /** Create a new view shell for the notes panel. + @param rViewShellBase + The new object will be stacked on this view shell base. + @param pFrameView + The frame view that makes it possible to pass information from + one view shell to the next. + */ + NotesPanelViewShell(SfxViewFrame* pFrame, ViewShellBase& rViewShellBase, + vcl::Window* pParentWindow, FrameView* pFrameView); + + virtual ~NotesPanelViewShell() override; + + virtual void Paint(const ::tools::Rectangle& rRect, ::sd::Window* pWin) override; + virtual bool PrepareClose(bool bUI = true) override; + virtual void UpdateScrollBars() override; + virtual void VirtHScrollHdl(ScrollAdaptor* pHScroll) override; + virtual void VirtVScrollHdl(ScrollAdaptor* pVScroll) override; + virtual void Activate(bool IsMDIActivate) override; + /** this method is called when the visible area of the view from this viewshell is changed */ + virtual void VisAreaChanged(const ::tools::Rectangle& rRect) override; + + virtual void ArrangeGUIElements() override; + virtual SdPage* GetActualPage() override; + virtual SdPage* getCurrentPage() const override; + virtual css::uno::Reference<css::drawing::XDrawSubController> CreateSubController() override; + + void ExecCtrl(SfxRequest& rReq); + void GetCtrlState(SfxItemSet& rSet); + void GetAttrState(SfxItemSet& rSet); + void GetState(SfxItemSet& rSet); + void GetCharState(SfxItemSet& rSet); + + static void ExecStatusBar(SfxRequest& rReq); + void GetStatusBarState(SfxItemSet& rSet); + + void FuTemporary(SfxRequest& rReq); + void FuTemporaryModify(SfxRequest& rReq); + void FuPermanent(SfxRequest& rReq); + void FuSupport(SfxRequest& rReq); + void Execute(SfxRequest& rReq); + void ExecChar(SfxRequest& rReq); + + virtual void Command(const CommandEvent& rCEvt, ::sd::Window* pWin) override; + virtual bool KeyInput(const KeyEvent& rKEvt, ::sd::Window* pWin) override; + virtual void MouseButtonUp(const MouseEvent& rMEvt, ::sd::Window* pWin) override; + + virtual void SetZoom(::tools::Long nZoom) override; + virtual void SetZoomRect(const ::tools::Rectangle& rZoomRect) override; + + virtual void ReadFrameViewData(FrameView* pView) override; + virtual void WriteFrameViewData() override; + virtual css::uno::Reference<css::accessibility::XAccessible> + CreateAccessibleDocumentView(::sd::Window* /*pWindow*/) override + { + // TODO + return {}; + } + +private: + std::unique_ptr<NotesPanelView> mpNotesPanelView; + bool mbInitialized = false; + + /** Initiates the shell with it's NotesPanelView instance + */ + void Construct(); +}; + +} // end of namespace sd + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/sd/source/ui/inc/OutlineView.hxx b/sd/source/ui/inc/OutlineView.hxx index 43dadf038664..75550bfe5f9f 100644 --- a/sd/source/ui/inc/OutlineView.hxx +++ b/sd/source/ui/inc/OutlineView.hxx @@ -46,12 +46,24 @@ class OutlineViewModelChangeGuard; const int MAX_OUTLINERVIEWS = 4; /** - * Derivative of ::sd::View for the outline mode + * Common base for OutlineView and NotesPanelView that only have a single Outliner in the view. +|* +\************************************************************************/ +class SimpleOutlinerView : public ::sd::View +{ +public: + SimpleOutlinerView(SdDrawDocument& rDrawDoc, OutputDevice* pOutDev, ViewShell* pViewSh) + : View(rDrawDoc, pOutDev, pViewSh) {} + virtual OutlinerView* GetViewByWindow(vcl::Window const* pWin) const = 0; +}; + +/** + * Derivative of ::sd::SimpleOutlinerView for the outline mode |* \************************************************************************/ class OutlineView final - : public ::sd::View + : public SimpleOutlinerView { friend class OutlineViewModelChangeGuard; public: @@ -78,7 +90,7 @@ public: virtual void AddDeviceToPaintView(OutputDevice& rDev, vcl::Window* pWindow) override; virtual void DeleteDeviceFromPaintView(OutputDevice& rDev) override; - OutlinerView* GetViewByWindow(vcl::Window const * pWin) const; + OutlinerView* GetViewByWindow(vcl::Window const * pWin) const override; SdOutliner& GetOutliner() { return mrOutliner; } Paragraph* GetPrevTitle(const Paragraph* pPara); diff --git a/sd/source/ui/inc/PaneChildWindows.hxx b/sd/source/ui/inc/PaneChildWindows.hxx index f96ede468bac..68989f3c01ce 100644 --- a/sd/source/ui/inc/PaneChildWindows.hxx +++ b/sd/source/ui/inc/PaneChildWindows.hxx @@ -34,7 +34,8 @@ public: sal_uInt16 nId, SfxBindings* pBindings, SfxChildWinInfo* pInfo, - TranslateId pTitleBarResId); + TranslateId pTitleBarResId, + SfxChildAlignment eAlignment); virtual ~PaneChildWindow() override; }; @@ -49,6 +50,16 @@ public: SFX_DECL_CHILDWINDOW_WITHID(LeftPaneImpressChildWindow); }; +/// The notes panel (on the bottom) in Impress. +class BottomPaneImpressChildWindow final : public PaneChildWindow +{ +public: + BottomPaneImpressChildWindow(vcl::Window* pParentWindow, sal_uInt16 nId, SfxBindings* pBindings, + SfxChildWinInfo* pInfo); + + SFX_DECL_CHILDWINDOW_WITHID(BottomPaneImpressChildWindow); +}; + /// The pages sidebar (on the left) in Draw. class LeftPaneDrawChildWindow final : public PaneChildWindow diff --git a/sd/source/ui/inc/PaneShells.hxx b/sd/source/ui/inc/PaneShells.hxx index 73f24909c2fd..e15ce2dd3d41 100644 --- a/sd/source/ui/inc/PaneShells.hxx +++ b/sd/source/ui/inc/PaneShells.hxx @@ -41,6 +41,23 @@ public: virtual ~LeftImpressPaneShell() override; }; +/** Shell that displays the bottom pane for Impress. The shell does not do + anything else and has especially no slots. +*/ +class BottomImpressPaneShell final : public SfxShell +{ +public: + SFX_DECL_INTERFACE(SD_IF_SDBOTTOMIMPRESSPANESHELL) + +private: + /// SfxInterface initializer. + static void InitInterface_Impl(); + +public: + BottomImpressPaneShell(); + virtual ~BottomImpressPaneShell() override; +}; + /** Shell that displays the left pane for Draw. The shell does not do anything else and has especially no slots. */ diff --git a/sd/source/ui/inc/TextObjectBar.hxx b/sd/source/ui/inc/TextObjectBar.hxx index 61394834fbc2..aaa008f04f93 100644 --- a/sd/source/ui/inc/TextObjectBar.hxx +++ b/sd/source/ui/inc/TextObjectBar.hxx @@ -45,8 +45,11 @@ public: virtual ~TextObjectBar() override; void GetAttrState( SfxItemSet& rSet ); + static void GetAttrStateImpl(ViewShell* mpViewShell, ::sd::View* mpView, SfxItemSet& rSet, SfxShell* pTextObjectBar); void GetCharState( SfxItemSet& rSet ); + static void GetCharStateImpl(ViewShell* mpViewShell, ::sd::View* mpView, SfxItemSet& rSet); void Execute( SfxRequest &rReq ); + static void ExecuteImpl(ViewShell* mpViewShell, ::sd::View* mpView, SfxRequest& rReq, SfxShell* pTextObjectBar); private: ViewShell* mpViewShell; diff --git a/sd/source/ui/inc/ViewShell.hxx b/sd/source/ui/inc/ViewShell.hxx index 89332537e94c..85bc43e86c09 100644 --- a/sd/source/ui/inc/ViewShell.hxx +++ b/sd/source/ui/inc/ViewShell.hxx @@ -100,7 +100,8 @@ public: ST_OUTLINE, ST_SLIDE_SORTER, ST_PRESENTATION, - ST_SIDEBAR + ST_SIDEBAR, + ST_NOTESPANEL }; static const int MAX_HSPLIT_CNT = 1; static const int MAX_VSPLIT_CNT = 1; diff --git a/sd/source/ui/inc/framework/FrameworkHelper.hxx b/sd/source/ui/inc/framework/FrameworkHelper.hxx index e5fe6f78cdc0..f25e5886ff9f 100644 --- a/sd/source/ui/inc/framework/FrameworkHelper.hxx +++ b/sd/source/ui/inc/framework/FrameworkHelper.hxx @@ -60,6 +60,7 @@ public: static const OUString msCenterPaneURL; static const OUString msFullScreenPaneURL; static const OUString msLeftImpressPaneURL; + static const OUString msBottomImpressPaneURL; static const OUString msLeftDrawPaneURL; // URLs of frequently used views. @@ -72,6 +73,7 @@ public: static const OUString msSlideSorterURL; static const OUString msPresentationViewURL; static const OUString msSidebarViewURL; + static const OUString msNotesPanelViewURL; // URLs of frequently used tool bars. static constexpr OUString msToolBarURLPrefix = u"private:resource/toolbar/"_ustr; diff --git a/sd/source/ui/inc/fuoltext.hxx b/sd/source/ui/inc/fuoltext.hxx index 288bcf190cb4..ddbada52734b 100644 --- a/sd/source/ui/inc/fuoltext.hxx +++ b/sd/source/ui/inc/fuoltext.hxx @@ -24,22 +24,19 @@ class SdDrawDocument; class SfxRequest; -namespace sd { +namespace sd +{ -class View; -class ViewShell; -class OutlineView; -class OutlineViewShell; +class SimpleOutlinerView; /** - * text functions in outline mode + * Functions class for shells that host only an Outliner e.g. NotesPanel + * */ -class FuOutlineText final - : public FuPoor +class FuSimpleOutlinerText : public FuPoor { public: - - static rtl::Reference<FuPoor> Create( ViewShell* pViewSh, ::sd::Window* pWin, ::sd::View* pView, SdDrawDocument* pDoc, SfxRequest& rReq ); + static rtl::Reference<FuPoor> Create( ViewShell* pViewSh, ::sd::Window* pWin, ::sd::SimpleOutlinerView* pView, SdDrawDocument* pDoc, SfxRequest& rReq ); virtual bool Command(const CommandEvent& rCEvt) override; @@ -53,22 +50,42 @@ public: virtual void DoPaste() override; virtual void DoPasteUnformatted() override; - /** Call this method when the text in the outliner (may) has changed. + /** Call this method when the text in the outliner (may) have changed. + It will invalidate some slots of the view frame. + */ + virtual void UpdateForKeyPress (const KeyEvent& rEvent); + +protected: + FuSimpleOutlinerText( + ViewShell* pViewShell, + ::sd::Window* pWin, + ::sd::SimpleOutlinerView* pView, + SdDrawDocument* pDoc, + SfxRequest& rReq); + + ViewShell* pOutlineViewShell; + SimpleOutlinerView* mpSimpleOutlinerView; +}; + +class FuOutlineText final : public FuSimpleOutlinerText +{ +public: + static rtl::Reference<FuPoor> Create( ViewShell* pViewSh, ::sd::Window* pWin, ::sd::SimpleOutlinerView* pView, SdDrawDocument* pDoc, SfxRequest& rReq ); + + virtual bool KeyInput(const KeyEvent& rKEvt) override; + /** Call this method when the text in the outliner (may) have changed. It will invalidate some slots of the view frame and update the preview in the slide sorter. */ - void UpdateForKeyPress (const KeyEvent& rEvent); + virtual void UpdateForKeyPress(const KeyEvent& rEvent) override; private: - FuOutlineText ( + FuOutlineText( ViewShell* pViewShell, ::sd::Window* pWin, - ::sd::View* pView, + ::sd::SimpleOutlinerView* pView, SdDrawDocument* pDoc, SfxRequest& rReq); - - OutlineViewShell* pOutlineViewShell; - OutlineView* pOutlineView; }; } // end of namespace sd diff --git a/sd/source/ui/view/NotesPanelView.cxx b/sd/source/ui/view/NotesPanelView.cxx new file mode 100644 index 000000000000..0cbc7149e8ae --- /dev/null +++ b/sd/source/ui/view/NotesPanelView.cxx @@ -0,0 +1,320 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <NotesPanelViewShell.hxx> +#include <NotesPanelView.hxx> +#include <OutlineView.hxx> +#include <ViewShellBase.hxx> +#include <editeng/editeng.hxx> +#include <editeng/outliner.hxx> +#include <sdresid.hxx> +#include <editeng/editund2.hxx> +#include <sdpage.hxx> +#include <DrawViewShell.hxx> +#include <DrawDocShell.hxx> +#include <Window.hxx> +#include <drawdoc.hxx> +#include <sdmod.hxx> +#include <officecfg/Office/Common.hxx> +#include <EventMultiplexer.hxx> +#include <app.hrc> +#include <strings.hrc> + +namespace sd +{ +NotesPanelView::NotesPanelView(DrawDocShell& rDocSh, vcl::Window* pWindow, + NotesPanelViewShell& rNotesPanelViewShell) + : ::sd::SimpleOutlinerView(*rDocSh.GetDoc(), pWindow->GetOutDev(), &rNotesPanelViewShell) + , mrNotesPanelViewShell(rNotesPanelViewShell) + , maOutliner(&mrDoc, OutlinerMode::TextObject) + , maOutlinerView(&maOutliner, pWindow) + , aModifyIdle("NotesEditWindow ModifyIdle") +{ + aModifyIdle.SetInvokeHandler(LINK(this, NotesPanelView, ModifyTimerHdl)); + aModifyIdle.SetPriority(TaskPriority::LOWEST); + + maOutliner.Init(OutlinerMode::OutlineView); + maOutliner.SetRefDevice(SD_MOD()->GetVirtualRefDevice()); + maOutliner.SetPaperSize(mrNotesPanelViewShell.GetActiveWindow()->GetViewSize()); + + maOutlinerView.SetOutputArea( + ::tools::Rectangle{ Point(0, 0), mrNotesPanelViewShell.GetActiveWindow()->GetViewSize() }); + maOutliner.InsertView(&maOutlinerView, EE_APPEND); + + onUpdateStyleSettings(true); + + // fill Outliner with contents + FillOutliner(); + + // TODO: UNDO + // sd::UndoManager* pDocUndoMgr = dynamic_cast<sd::UndoManager*>(mpDocSh->GetUndoManager()); + // if (pDocUndoMgr != nullptr) + // pDocUndoMgr->SetLinkedUndoManager(&maOutliner.GetUndoManager()); +} + +NotesPanelView::~NotesPanelView() +{ + ResetLinks(); + + // DisconnectFromApplication(); + // mpProgress.reset(); +} + +void NotesPanelView::FillOutliner() +{ + maOutliner.GetUndoManager().Clear(); + maOutliner.EnableUndo(false); + ResetLinks(); + removeListener(); + mpTextObj = nullptr; + maOutliner.Clear(); + + SdPage* pNotesPage = mrNotesPanelViewShell.getCurrentPage(); + if (!pNotesPage) + return; + + SdrObject* pNotesObj = pNotesPage->GetPresObj(PresObjKind::Notes); + if (!pNotesObj) + return; + + mpTextObj = dynamic_cast<SdrTextObj*>(pNotesObj); + addListener(); + getNotesFromDoc(); + SetLinks(); + maOutliner.EnableUndo(true); +} + +void NotesPanelView::SetLinks() +{ + maOutliner.SetStatusEventHdl(LINK(this, NotesPanelView, StatusEventHdl)); + mrNotesPanelViewShell.GetViewShellBase().GetEventMultiplexer()->AddEventListener( + LINK(this, NotesPanelView, EventMultiplexerListener)); +} + +void NotesPanelView::ResetLinks() +{ + maOutliner.SetStatusEventHdl(Link<EditStatus&, void>()); + mrNotesPanelViewShell.GetViewShellBase().GetEventMultiplexer()->RemoveEventListener( + LINK(this, NotesPanelView, EventMultiplexerListener)); +} + +void NotesPanelView::removeListener() +{ + if (mpTextObj) + mpTextObj->RemoveListener(*this); +} +void NotesPanelView::addListener() +{ + if (mpTextObj) + mpTextObj->AddListener(*this); +} + +void NotesPanelView::setListenerIgnored(bool bIgnore) { mbIgnoreNotifications = bIgnore; } +bool NotesPanelView::isListenerIgnored() { return mbIgnoreNotifications; } + +void NotesPanelView::getNotesFromDoc() +{ + if (!mpTextObj) + return; + + // Ignore notifications that will rebound from updating the text + maOutliner.SetModifyHdl(Link<LinkParamNone*, void>()); + setListenerIgnored(true); + + if (OutlinerParaObject* pPara = mpTextObj->GetOutlinerParaObject()) + maOutliner.SetText(*pPara); + + setListenerIgnored(false); + maOutliner.SetModifyHdl(LINK(this, NotesPanelView, EditModifiedHdl)); +} + +void NotesPanelView::setNotesToDoc() +{ + if (!mpTextObj) + return; + + setListenerIgnored(true); + + std::optional<OutlinerParaObject> pNewText = maOutliner.CreateParaObject(); + mpTextObj->SetOutlinerParaObject(std::move(pNewText)); + if (mpTextObj->IsEmptyPresObj()) + mpTextObj->SetEmptyPresObj(false); + + setListenerIgnored(false); +} + +void NotesPanelView::Paint(const ::tools::Rectangle& rRect, ::sd::Window const* /*pWin*/) +{ + OutlinerView* pOlView = GetOutlinerView(); + + if (pOlView) + { + pOlView->HideCursor(); + pOlView->Paint(rRect); + + pOlView->ShowCursor(mbFirstPaint); + mbFirstPaint = false; + } +} + +void NotesPanelView::Notify(SfxBroadcaster&, const SfxHint& rHint) +{ + if (isListenerIgnored()) + return; + + if (rHint.GetId() == SfxHintId::ThisIsAnSdrHint) + { + const SdrHint& rSdrHint = reinterpret_cast<const SdrHint&>(rHint); + switch (rSdrHint.GetKind()) + { + case SdrHintKind::ObjectRemoved: + case SdrHintKind::ModelCleared: + FillOutliner(); + break; + case SdrHintKind::ObjectChange: + case SdrHintKind::EndEdit: + FillOutliner(); + break; + default: + break; + } + } +} + +OutlinerView* NotesPanelView::GetOutlinerView() { return &maOutlinerView; } + +void NotesPanelView::onUpdateStyleSettings(bool bForceUpdate /* = false */) +{ + svtools::ColorConfig aColorConfig; + const Color aDocColor(aColorConfig.GetColorValue(svtools::DOCCOLOR).nColor); + if (!(bForceUpdate || (maDocColor != aDocColor))) + return; + + maOutlinerView.SetBackgroundColor(aDocColor); + if (vcl::Window* pWindow = maOutlinerView.GetWindow()) + pWindow->SetBackground(Wallpaper(aDocColor)); + + maOutliner.SetBackgroundColor(aDocColor); + maDocColor = aDocColor; +} + +void NotesPanelView::onResize() +{ + ::sd::Window* pWin = mrNotesPanelViewShell.GetActiveWindow(); + OutlinerView* pOutlinerView = GetOutlinerView(); + + Size aOutputSize = pWin->PixelToLogic(pWin->GetOutputSizePixel()); + + pOutlinerView->SetOutputArea({ Point(0, 0), aOutputSize }); + maOutliner.SetPaperSize(aOutputSize); + pOutlinerView->ShowCursor(); + + const ::tools::Long nMaxVisAreaStart = maOutliner.GetTextHeight() - aOutputSize.Height(); + + ::tools::Rectangle aVisArea(pOutlinerView->GetVisArea()); + + if (aVisArea.Top() > nMaxVisAreaStart) + { + aVisArea.SetTop(std::max<::tools::Long>(nMaxVisAreaStart, 0)); + aVisArea.SetSize(aOutputSize); + pOutlinerView->SetVisArea(aVisArea); + pOutlinerView->ShowCursor(); + } + + if (!aVisArea.IsEmpty()) // not when opening + { + mrNotesPanelViewShell.InitWindows(Point(0, 0), aVisArea.GetSize(), aVisArea.TopLeft()); + mrNotesPanelViewShell.UpdateScrollBars(); + } +} + +/** + * Handler for StatusEvents + */ +IMPL_LINK_NOARG(NotesPanelView, StatusEventHdl, EditStatus&, void) { onResize(); } + +IMPL_LINK_NOARG(NotesPanelView, EditModifiedHdl, LinkParamNone*, void) +{ + // EditEngine calls ModifyHdl many times in succession for some edits. + // (e.g. when deleting multiple lines) + // Debounce the rapid ModifyHdl calls using a timer. + aModifyIdle.Start(); + return; +} + +IMPL_LINK_NOARG(NotesPanelView, ModifyTimerHdl, Timer*, void) +{ + setNotesToDoc(); + aModifyIdle.Stop(); +} + +IMPL_LINK(NotesPanelView, EventMultiplexerListener, tools::EventMultiplexerEvent&, rEvent, void) +{ + switch (rEvent.meEventId) + { + case EventMultiplexerEventId::CurrentPageChanged: + case EventMultiplexerEventId::MainViewRemoved: + case EventMultiplexerEventId::MainViewAdded: + FillOutliner(); + break; + default: + break; + } +} + +OutlinerView* NotesPanelView::GetViewByWindow(vcl::Window const* /*pWin*/) const +{ + return const_cast<NotesPanelView*>(this)->GetOutlinerView(); +} + +/** + * Set attributes of the selected text + */ +bool NotesPanelView::SetAttributes(const SfxItemSet& rSet, bool /*bSlide*/, bool /*bReplaceAll*/, + bool /*bMaster*/) +{ + bool bOk = false; + + OutlinerView* pOlView = GetOutlinerView(); + + if (pOlView) + { + pOlView->SetAttribs(rSet); + bOk = true; + } + + mrNotesPanelViewShell.Invalidate(SID_PREVIEW_STATE); + + return bOk; +} + +/** + * Get attributes of the selected text + */ +void NotesPanelView::GetAttributes(SfxItemSet& rTargetSet, bool) const +{ + rTargetSet.Put(const_cast<OutlinerView&>(maOutlinerView).GetAttribs(), false); +} + +SvtScriptType NotesPanelView::GetScriptType() const +{ + SvtScriptType nScriptType = ::sd::View::GetScriptType(); + + std::optional<OutlinerParaObject> pTempOPObj = maOutliner.CreateParaObject(); + if (pTempOPObj) + { + nScriptType = pTempOPObj->GetTextObject().GetScriptType(); + } + + return nScriptType; +} + +} // end of namespace sd + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/sd/source/ui/view/NotesPanelViewShell.cxx b/sd/source/ui/view/NotesPanelViewShell.cxx new file mode 100644 index 000000000000..ec849a2484d9 --- /dev/null +++ b/sd/source/ui/view/NotesPanelViewShell.cxx @@ -0,0 +1,1448 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <NotesPanelViewShell.hxx> +#include <NotesPanelView.hxx> +#include <sal/log.hxx> + +#include <DrawController.hxx> +#include <DrawDocShell.hxx> +#include <DrawViewShell.hxx> +#include <FrameView.hxx> +#include <SpellDialogChildWindow.hxx> +#include <ViewShellBase.hxx> +#include <Window.hxx> +#include <app.hrc> +#include <com/sun/star/linguistic2/XThesaurus.hpp> +#include <drawdoc.hxx> +#include <editeng/editobj.hxx> +#include <editeng/editstat.hxx> +#include <editeng/editund2.hxx> +#include <editeng/eeitem.hxx> +#include <editeng/flditem.hxx> +#include <editeng/outlobj.hxx> +#include <editeng/unolingu.hxx> +#include <framework/FrameworkHelper.hxx> +#include <fubullet.hxx> +#include <fuchar.hxx> +#include <fucushow.hxx> +#include <fuexpand.hxx> +#include <fuinsfil.hxx> +#include <fuolbull.hxx> +#include <fuoltext.hxx> +#include <fuprobjs.hxx> +#include <fuscale.hxx> +#include <fusldlg.hxx> +#include <fusumry.hxx> +#include <futempl.hxx> +#include <futhes.hxx> +#include <memory> +#include <sdabstdlg.hxx> +#include <sdpage.hxx> +#include <sdresid.hxx> +#include <sfx2/bindings.hxx> +#include <sfx2/devtools/DevelopmentToolChildWindow.hxx> +#include <sfx2/dispatch.hxx> +#include <sfx2/docfile.hxx> +#include <sfx2/infobar.hxx> +#include <sfx2/objface.hxx> +#include <sfx2/request.hxx> +#include <sfx2/sidebar/SidebarChildWindow.hxx> +#include <sfx2/tplpitem.hxx> +#include <sfx2/viewfrm.hxx> +#include <sfx2/zoomitem.hxx> +#include <slideshow.hxx> +#include <sot/formats.hxx> +#include <stlsheet.hxx> +#include <strings.hrc> +#include <svl/cjkoptions.hxx> +#include <svl/srchitem.hxx> +#include <svl/stritem.hxx> +#include <svl/whiter.hxx> +#include <svtools/cliplistener.hxx> +#include <svx/hlnkitem.hxx> +#include <svx/hyperdlg.hxx> +#include <svx/svdoutl.hxx> +#include <svx/svxids.hrc> +#include <svx/zoomslideritem.hxx> +#include <unotools/useroptions.hxx> +#include <vcl/EnumContext.hxx> +#include <vcl/commandevent.hxx> +#include <zoomlist.hxx> + +#include <TextObjectBar.hxx> + +#include <memory> + +#define ShellClass_NotesPanelViewShell +using namespace sd; +#include <sdslots.hxx> + +namespace sd +{ +#define MIN_ZOOM 10 // minimum zoom factor +#define MAX_ZOOM 1000 // maximum zoom factor + +/** + * Declare SFX-Slotmap and standard interface + */ +SFX_IMPL_INTERFACE(NotesPanelViewShell, SfxShell) + +void NotesPanelViewShell::InitInterface_Impl() +{ + GetStaticInterface()->RegisterPopupMenu("drawtext"); + + GetStaticInterface()->RegisterChildWindow(SvxHlinkDlgWrapper::GetChildWindowId()); + GetStaticInterface()->RegisterChildWindow(::sd::SpellDialogChildWindow::GetChildWindowId()); + GetStaticInterface()->RegisterChildWindow(SID_SEARCH_DLG); + GetStaticInterface()->RegisterChildWindow( + sfx2::sidebar::SidebarChildWindow::GetChildWindowId()); + GetStaticInterface()->RegisterChildWindow(DevelopmentToolChildWindow::GetChildWindowId()); +} + +/** + * Default constructor, windows must not center themselves automatically + */ +NotesPanelViewShell::NotesPanelViewShell(SfxViewFrame* /*pFrame*/, ViewShellBase& rViewShellBase, + vcl::Window* pParentWindow, FrameView* pFrameViewArgument) + : ViewShell(pParentWindow, rViewShellBase) +{ + if (pFrameViewArgument != nullptr) + mpFrameView = pFrameViewArgument; + else + mpFrameView = new FrameView(GetDoc()); + + mpFrameView->Connect(); + + Construct(); + + SetContextName(vcl::EnumContext::GetContextName(vcl::EnumContext::Context::DrawText)); + + doShow(); + mpHorizontalScrollBar->Hide(); +} + +NotesPanelViewShell::~NotesPanelViewShell() +{ + DisposeFunctions(); + mpFrameView->Disconnect(); + // if ( mxClipEvtLstnr.is() ) + // { + // mxClipEvtLstnr->RemoveListener( GetActiveWindow() ); + // mxClipEvtLstnr->ClearCallbackLink(); // prevent callback if another thread is waiting + // } +} + +void NotesPanelViewShell::Construct() +{ + meShellType = ST_NOTESPANEL; + + Size aSize(29700, 21000); + Point aWinPos(0, 0); + Point aViewOrigin(0, 0); + GetActiveWindow()->SetMinZoomAutoCalc(false); + GetActiveWindow()->SetMinZoom(MIN_ZOOM); + GetActiveWindow()->SetMaxZoom(MAX_ZOOM); + InitWindows(aViewOrigin, aSize, aWinPos); + + mpNotesPanelView = std::make_unique<NotesPanelView>(*GetDocSh(), GetActiveWindow(), *this); + mpView = mpNotesPanelView.get(); + + SetPool(&GetDoc()->GetPool()); + SetZoom(70); + + // Apply settings of FrameView + ReadFrameViewData(mpFrameView); + + SetName("NotesPanelViewShell"); + // TODO: Help ID + // GetActiveWindow()->SetHelpId(HID_SDNOTESPANEL); +} + +void NotesPanelViewShell::Paint(const ::tools::Rectangle& rRect, ::sd::Window* pWin) +{ + if (mpNotesPanelView) + mpNotesPanelView->Paint(rRect, pWin); +} + +bool NotesPanelViewShell::PrepareClose(bool bUI) +{ + if (!ViewShell::PrepareClose(bUI)) + return false; + + return true; +} + +void NotesPanelViewShell::VirtHScrollHdl(ScrollAdaptor* /*pHScroll*/) +{ + // no horizontal scroll + return; +} + +void NotesPanelViewShell::UpdateScrollBars() +{ + if (!mpVerticalScrollBar) + return; + + OutlinerView* pOutlinerView = mpNotesPanelView->GetOutlinerView(); + const SdOutliner& rOutliner = mpNotesPanelView->GetOutliner(); + + int nVUpper = rOutliner.GetTextHeight(); + int nVCurrentDocPos = pOutlinerView->GetVisArea().Top(); + const Size aOut(pOutlinerView->GetOutputArea().GetSize()); + int nVStepIncrement = aOut.Height() * 2 / 10; + int nVPageIncrement = aOut.Height() * 8 / 10; + int nVPageSize = aOut.Height(); + + nVPageSize = std::min(nVPageSize, nVUpper); + + mpVerticalScrollBar->SetRange({ 0, nVUpper }); + mpVerticalScrollBar->SetVisibleSize(nVPageSize); + mpVerticalScrollBar->SetThumbPos(nVCurrentDocPos); + mpVerticalScrollBar->SetLineSize(nVStepIncrement); + mpVerticalScrollBar->SetPageSize(nVPageIncrement); + + // TODO: This is a workaround for the view going blank when overflow the current view with text. + // The extra faulty draw call still happens.. Should get rid of that before removing this. + VirtVScrollHdl(mpVerticalScrollBar); +} + +void NotesPanelViewShell::VirtVScrollHdl(ScrollAdaptor* /*pVScroll*/) +{ + OutlinerView* pOutlinerView = mpNotesPanelView->GetOutlinerView(); + + if (pOutlinerView) + { + pOutlinerView->SetVisArea({ Point(0, mpVerticalScrollBar->GetThumbPos()), + pOutlinerView->GetVisArea().GetSize() }); + pOutlinerView->GetEditView().Invalidate(); + + auto currentDocPos = pOutlinerView->GetVisArea().Top(); + auto nDiff = currentDocPos - mpVerticalScrollBar->GetThumbPos(); + pOutlinerView->Scroll(0, nDiff); + } +} + +void NotesPanelViewShell::VisAreaChanged(const ::tools::Rectangle& rRect) +{ + ViewShell::VisAreaChanged(rRect); + GetViewShellBase().GetDrawController()->FireVisAreaChanged(rRect); +} + +void NotesPanelViewShell::ArrangeGUIElements() +{ + // Retrieve the current size (thickness) of the scroll bars. That is + // the width of the vertical and the height of the horizontal scroll + // bar. + int nScrollBarSize = GetParentWindow()->GetSettings().GetStyleSettings().GetScrollBarSize(); + maScrBarWH = Size(nScrollBarSize, nScrollBarSize); + + ViewShell::ArrangeGUIElements(); + + ::sd::Window* pWindow = mpContentWindow.get(); + if (pWindow == nullptr) + return; + + pWindow->SetMinZoomAutoCalc(false); + mpNotesPanelView->onResize(); +} + +SdPage* NotesPanelViewShell::GetActualPage() { return getCurrentPage(); } + +SdPage* NotesPanelViewShell::getCurrentPage() const +{ + SdPage* pCurrentPage = nullptr; + + std::shared_ptr<ViewShell> pMainViewShell = GetViewShellBase().GetMainViewShell(); + if (pMainViewShell) + pCurrentPage = pMainViewShell->GetActualPage(); + + if (!pCurrentPage) + return nullptr; + + switch (pCurrentPage->GetPageKind()) + { + case PageKind::Standard: + return GetDoc()->GetSdPage((pCurrentPage->GetPageNum() - 1) >> 1, PageKind::Notes); + case PageKind::Notes: + return pCurrentPage; + case PageKind::Handout: + default: + return nullptr; + } +} + +css::uno::Reference<css::drawing::XDrawSubController> NotesPanelViewShell::CreateSubController() +{ + // SubController appears is only relevant for MainViewShell + // NotesPanel isn't meant as a MainViewShell + return {}; +} + +void NotesPanelViewShell::ReadFrameViewData(FrameView* /*pView*/) +{ + DrawController& rController(*GetViewShellBase().GetDrawController()); + rController.FireSelectionChangeListener(); +} + +void NotesPanelViewShell::WriteFrameViewData() {} + +/** + * Activate(): during the first invocation the fields get updated + */ +void NotesPanelViewShell::Activate(bool bIsMDIActivate) +{ + if (!mbInitialized) + { + mbInitialized = true; + SfxRequest aRequest(SID_EDIT_OUTLINER, SfxCallMode::SLOT, GetDoc()->GetItemPool()); + FuPermanent(aRequest); + } + + ViewShell::Activate(bIsMDIActivate); + SfxShell::BroadcastContextForActivation(true); + + if (bIsMDIActivate) + { + OutlinerView* pOutlinerView = mpNotesPanelView->GetOutlinerView(); + ::Outliner* pOutl = pOutlinerView->GetOutliner(); + pOutl->UpdateFields(); + } +} + +/** + * SfxRequests for permanent functions + */ +void NotesPanelViewShell::FuPermanent(SfxRequest& rReq) +{ + if (HasCurrentFunction()) + { + DeactivateCurrentFunction(true); + } + + switch (rReq.GetSlot()) + { + case SID_EDIT_OUTLINER: + { + ::Outliner& rOutl = mpNotesPanelView->GetOutliner(); + rOutl.GetUndoManager().Clear(); + rOutl.UpdateFields(); + + SetCurrentFunction(FuSimpleOutlinerText::Create( + this, GetActiveWindow(), mpNotesPanelView.get(), GetDoc(), rReq)); + + rReq.Done(); + } + break; + + default: + break; + } + + if (HasOldFunction()) + { + GetOldFunction()->Deactivate(); + SetOldFunction(nullptr); + } + + if (HasCurrentFunction()) + { + GetCurrentFunction()->Activate(); + SetOldFunction(GetCurrentFunction()); + } +} + +/** + * Zoom with zoom factor. Inform OutlinerView + */ +void NotesPanelViewShell::SetZoom(::tools::Long nZoom) +{ + ViewShell::SetZoom(nZoom); + + ::sd::Window* pWindow = mpContentWindow.get(); + if (pWindow) + mpNotesPanelView->onResize(); + + GetViewFrame()->GetBindings().Invalidate(SID_ATTR_ZOOM); + GetViewFrame()->GetBindings().Invalidate(SID_ATTR_ZOOMSLIDER); +} + +/** + * Zoom with zoom rectangle. Inform OutlinerView + */ +void NotesPanelViewShell::SetZoomRect(const ::tools::Rectangle& rZoomRect) +{ + ViewShell::SetZoomRect(rZoomRect); + + ::sd::Window* pWindow = mpContentWindow.get(); + if (pWindow) + mpNotesPanelView->onResize(); + + GetViewFrame()->GetBindings().Invalidate(SID_ATTR_ZOOM); + GetViewFrame()->GetBindings().Invalidate(SID_ATTR_ZOOMSLIDER); +} + +void NotesPanelViewShell::ExecCtrl(SfxRequest& rReq) +{ + sal_uInt16 nSlot = rReq.GetSlot(); + switch (nSlot) + { + case SID_MAIL_SCROLLBODY_PAGEDOWN: + { + ExecReq(rReq); + break; + } + + case SID_OPT_LOCALE_CHANGED: + { + mpNotesPanelView->GetOutliner().UpdateFields(); + rReq.Done(); + break; + } + + default: + break; + } +} + +void NotesPanelViewShell::GetCtrlState(SfxItemSet& rSet) +{ + if (SfxItemState::DEFAULT == rSet.GetItemState(SID_HYPERLINK_GETLINK)) + { + SvxHyperlinkItem aHLinkItem; + + OutlinerView* pOLV = mpNotesPanelView->GetOutlinerView(); + if (pOLV) + { + const SvxFieldItem* pFieldItem = pOLV->GetFieldAtSelection(); + if (pFieldItem) + { + ESelection aSel = pOLV->GetSelection(); + if (abs(aSel.nEndPos - aSel.nStartPos) == 1) + { + const SvxFieldData* pField = pFieldItem->GetField(); + if (auto pUrlField = dynamic_cast<const SvxURLField*>(pField)) + { + aHLinkItem.SetName(pUrlField->GetRepresentation()); + aHLinkItem.SetURL(pUrlField->GetURL()); + aHLinkItem.SetTargetFrame(pUrlField->GetTargetFrame()); + } + } + } + } + rSet.Put(aHLinkItem); + } + rSet.Put(SfxBoolItem(SID_READONLY_MODE, GetDocSh()->IsReadOnly())); + + if (SfxItemState::DEFAULT == rSet.GetItemState(SID_MAIL_SCROLLBODY_PAGEDOWN)) + rSet.Put(SfxBoolItem(SID_MAIL_SCROLLBODY_PAGEDOWN, true)); + + if (!(SfxItemState::DEFAULT == rSet.GetItemState(SID_TRANSLITERATE_HALFWIDTH) + || SfxItemState::DEFAULT == rSet.GetItemState(SID_TRANSLITERATE_FULLWIDTH) + || SfxItemState::DEFAULT == rSet.GetItemState(SID_TRANSLITERATE_HIRAGANA) + || SfxItemState::DEFAULT == rSet.GetItemState(SID_TRANSLITERATE_KATAKANA))) + return; + + if (!SvtCJKOptions::IsChangeCaseMapEnabled()) + { + GetViewFrame()->GetBindings().SetVisibleState(SID_TRANSLITERATE_HALFWIDTH, false); + GetViewFrame()->GetBindings().SetVisibleState(SID_TRANSLITERATE_FULLWIDTH, false); + GetViewFrame()->GetBindings().SetVisibleState(SID_TRANSLITERATE_HIRAGANA, false); + GetViewFrame()->GetBindings().SetVisibleState(SID_TRANSLITERATE_KATAKANA, false); + rSet.DisableItem(SID_TRANSLITERATE_HALFWIDTH); + rSet.DisableItem(SID_TRANSLITERATE_FULLWIDTH); + rSet.DisableItem(SID_TRANSLITERATE_HIRAGANA); + rSet.DisableItem(SID_TRANSLITERATE_KATAKANA); + } + else + { + GetViewFrame()->GetBindings().SetVisibleState(SID_TRANSLITERATE_HALFWIDTH, true); + GetViewFrame()->GetBindings().SetVisibleState(SID_TRANSLITERATE_FULLWIDTH, true); + GetViewFrame()->GetBindings().SetVisibleState(SID_TRANSLITERATE_HIRAGANA, true); + GetViewFrame()->GetBindings().SetVisibleState(SID_TRANSLITERATE_KATAKANA, true); + } +} + +void NotesPanelViewShell::GetAttrState(SfxItemSet& rSet) +{ + SfxWhichIter aIter(rSet); + sal_uInt16 nWhich = aIter.FirstWhich(); + SfxAllItemSet aAllSet(*rSet.GetPool()); + + while (nWhich) + { + sal_uInt16 nSlotId = SfxItemPool::IsWhich(nWhich) ? GetPool().GetSlotId(nWhich) : nWhich; + + switch (nSlotId) + { + case SID_STYLE_FAMILY2: + case SID_STYLE_FAMILY3: + { + rSet.DisableItem(nWhich); + } + break; + + case SID_STYLE_FAMILY5: + { + SfxStyleSheet* pStyleSheet = mpNotesPanelView->GetOutlinerView()->GetStyleSheet(); + + if (pStyleSheet) + { + pStyleSheet = static_cast<SdStyleSheet*>(pStyleSheet)->GetPseudoStyleSheet(); + + if (pStyleSheet) + { + SfxTemplateItem aItem(nWhich, pStyleSheet->GetName()); + aAllSet.Put(aItem); + } + } + + if (!pStyleSheet) + { + SfxTemplateItem aItem(nWhich, OUString()); + aAllSet.Put(aItem); + } + } + break; + + case SID_STYLE_EDIT: + { + std::unique_ptr<SfxUInt16Item> pFamilyItem; + GetViewFrame()->GetBindings().QueryState(SID_STYLE_FAMILY, pFamilyItem); + if (pFamilyItem + && static_cast<SfxStyleFamily>(pFamilyItem->GetValue()) + == SfxStyleFamily::Pseudo) + { + rSet.DisableItem(nWhich); + } + } + break; + + case SID_STYLE_UPDATE_BY_EXAMPLE: + { + OutlinerView* pOV = mpNotesPanelView->GetOutlinerView(); + ESelection aESel(pOV->GetSelection()); + + if (aESel.nStartPara != aESel.nEndPara || aESel.nStartPos != aESel.nEndPos) + // spanned selection, i.e. StyleSheet and/or + // attribution not necessarily unique + rSet.DisableItem(nWhich); + } + break; + + case SID_STYLE_NEW: + case SID_STYLE_DELETE: + case SID_STYLE_HIDE: + case SID_STYLE_SHOW: + case SID_STYLE_NEW_BY_EXAMPLE: + case SID_STYLE_WATERCAN: + { + rSet.DisableItem(nWhich); + } + break; + + default: + break; + } + + nWhich = aIter.NextWhich(); + } + + rSet.Put(aAllSet, false); + TextObjectBar::GetAttrStateImpl(this, mpView, rSet, nullptr); +} + +void NotesPanelViewShell::GetState(SfxItemSet& rSet) +{ + // Iterate over all requested items in the set. + SfxWhichIter aIter(rSet); + sal_uInt16 nWhich = aIter.FirstWhich(); + while (nWhich) + { + switch (nWhich) + { + case SID_SEARCH_ITEM: + case SID_SEARCH_OPTIONS: + // Call common (old) implementation in the document shell. + GetDocSh()->GetState(rSet); + break; + default: + SAL_WARN("sd", + "NotesPanelViewShell::GetState(): can not handle which id " << nWhich); + break; + } + nWhich = aIter.NextWhich(); + } +} + +void NotesPanelViewShell::GetCharState(SfxItemSet& rSet) +{ + TextObjectBar::GetCharStateImpl(this, mpView, rSet); +} + +void NotesPanelViewShell::ExecStatusBar(SfxRequest& /*rReq*/) {} + +void NotesPanelViewShell::GetStatusBarState(SfxItemSet& rSet) +{ + // Zoom-Item + if (SfxItemState::DEFAULT == rSet.GetItemState(SID_ATTR_ZOOM)) + { + sal_uInt16 nZoom = static_cast<sal_uInt16>(GetActiveWindow()->GetZoom()); + + std::unique_ptr<SvxZoomItem> pZoomItem(new SvxZoomItem(SvxZoomType::PERCENT, nZoom)); + + // limit area + SvxZoomEnableFlags nZoomValues = SvxZoomEnableFlags::ALL; + nZoomValues &= ~SvxZoomEnableFlags::OPTIMAL; + nZoomValues &= ~SvxZoomEnableFlags::WHOLEPAGE; + nZoomValues &= ~SvxZoomEnableFlags::PAGEWIDTH; + + pZoomItem->SetValueSet(nZoomValues); + rSet.Put(std::move(pZoomItem)); + } + + if (SfxItemState::DEFAULT == rSet.GetItemState(SID_ATTR_ZOOMSLIDER)) + { + if (GetDocSh()->IsUIActive() || !GetActiveWindow()) + { + rSet.DisableItem(SID_ATTR_ZOOMSLIDER); + } + else + { + sd::Window* pActiveWindow = GetActiveWindow(); + SvxZoomSliderItem aZoomItem(static_cast<sal_uInt16>(pActiveWindow->GetZoom()), + static_cast<sal_uInt16>(pActiveWindow->GetMinZoom()), + static_cast<sal_uInt16>(pActiveWindow->GetMaxZoom())); + aZoomItem.AddSnappingPoint(100); + rSet.Put(aZoomItem); + } + } + + // TODO: page view and layout strings + // rSet.Put( SfxStringItem( SID_STATUS_PAGE, aPageStr ) ); + // rSet.Put( SfxStringItem( SID_STATUS_LAYOUT, aLayoutStr ) ); +} + +void NotesPanelViewShell::FuTemporary(SfxRequest& rReq) +{ + DeactivateCurrentFunction(); + + OutlinerView* pOutlinerView = mpNotesPanelView->GetOutlinerView(); + sal_uInt16 nSId = rReq.GetSlot(); + + switch (nSId) + { + case SID_ATTR_ZOOM: + { + const SfxItemSet* pArgs = rReq.GetArgs(); + + if (pArgs) + { + SvxZoomType eZT = pArgs->Get(SID_ATTR_ZOOM).GetType(); + switch (eZT) + { + case SvxZoomType::PERCENT: + SetZoom(static_cast<::tools::Long>(pArgs->Get(SID_ATTR_ZOOM).GetValue())); + Invalidate(SID_ATTR_ZOOM); + Invalidate(SID_ATTR_ZOOMSLIDER); + break; + default: + break; + } + rReq.Done(); + } + else + { + // open the zoom dialog here + SetCurrentFunction(FuScale::Create(this, GetActiveWindow(), mpNotesPanelView.get(), + GetDoc(), rReq)); + } + Cancel(); + } + break; + + case SID_ATTR_ZOOMSLIDER: + { + const SfxItemSet* pArgs = rReq.GetArgs(); + + const SfxUInt16Item* pScale + = (pArgs && pArgs->Count() == 1) ? rReq.GetArg(SID_ATTR_ZOOMSLIDER) : nullptr; + if (pScale && CHECK_RANGE(5, pScale->GetValue(), 3000)) + { + SetZoom(pScale->GetValue()); + + SfxBindings& rBindings = GetViewFrame()->GetBindings(); + rBindings.Invalidate(SID_ATTR_ZOOM); + rBindings.Invalidate(SID_ZOOM_IN); + rBindings.Invalidate(SID_ZOOM_OUT); + rBindings.Invalidate(SID_ATTR_ZOOMSLIDER); + } + + Cancel(); + rReq.Done(); + break; + } + + case SID_ZOOM_IN: + { + SetZoom(std::min<::tools::Long>(GetActiveWindow()->GetZoom() * 2, + GetActiveWindow()->GetMaxZoom())); + ::tools::Rectangle aVisAreaWin = GetActiveWindow()->PixelToLogic( + ::tools::Rectangle(Point(0, 0), GetActiveWindow()->GetOutputSizePixel())); + mpZoomList->InsertZoomRect(aVisAreaWin); + Invalidate(SID_ATTR_ZOOM); + Invalidate(SID_ZOOM_IN); + Invalidate(SID_ZOOM_OUT); + Invalidate(SID_ATTR_ZOOMSLIDER); + Cancel(); + rReq.Done(); + } + break; + + case SID_SIZE_REAL: + { + SetZoom(100); + ::tools::Rectangle aVisAreaWin = GetActiveWindow()->PixelToLogic( + ::tools::Rectangle(Point(0, 0), GetActiveWindow()->GetOutputSizePixel())); + mpZoomList->InsertZoomRect(aVisAreaWin); + Invalidate(SID_ATTR_ZOOM); + Invalidate(SID_ATTR_ZOOMSLIDER); + Cancel(); + rReq.Done(); + } + break; + + case SID_ZOOM_OUT: + { + SetZoom(std::max<::tools::Long>(GetActiveWindow()->GetZoom() / 2, + GetActiveWindow()->GetMinZoom())); + ::tools::Rectangle aVisAreaWin = GetActiveWindow()->PixelToLogic( + ::tools::Rectangle(Point(0, 0), GetActiveWindow()->GetOutputSizePixel())); + mpZoomList->InsertZoomRect(aVisAreaWin); + Invalidate(SID_ATTR_ZOOM); + Invalidate(SID_ZOOM_OUT); + Invalidate(SID_ZOOM_IN); + Invalidate(SID_ATTR_ZOOMSLIDER); + Cancel(); + rReq.Done(); + } + break; + + case SID_SELECTALL: + { + ::Outliner& rOutl = mpNotesPanelView->GetOutliner(); + sal_Int32 nParaCount = rOutl.GetParagraphCount(); + if (nParaCount > 0) + { + pOutlinerView->SelectRange(0, nParaCount); + } + Cancel(); + } + break; + + case SID_PRESENTATION: + case SID_PRESENTATION_CURRENT_SLIDE: + case SID_REHEARSE_TIMINGS: + { + slideshowhelp::ShowSlideShow(rReq, *GetDoc()); + Cancel(); + rReq.Done(); + } + break; + + case SID_STYLE_EDIT: + case SID_STYLE_UPDATE_BY_EXAMPLE: + { + if (rReq.GetArgs()) + { + SetCurrentFunction(FuTemplate::Create(this, GetActiveWindow(), + mpNotesPanelView.get(), GetDoc(), rReq)); + Cancel(); + } + + rReq.Ignore(); + } + break; + + case SID_PRESENTATION_DLG: + { + SetCurrentFunction(FuSlideShowDlg::Create(this, GetActiveWindow(), + mpNotesPanelView.get(), GetDoc(), rReq)); + Cancel(); + } + break; + + case SID_REMOTE_DLG: + { +#ifdef ENABLE_SDREMOTE + SdAbstractDialogFactory* pFact = SdAbstractDialogFactory::Create(); + ScopedVclPtr<VclAbstractDialog> pDlg(pFact->CreateRemoteDialog(GetFrameWeld())); + pDlg->Execute(); +#endif + } + break; + + case SID_CUSTOMSHOW_DLG: + { + SetCurrentFunction(FuCustomShowDlg::Create(this, GetActiveWindow(), + mpNotesPanelView.get(), GetDoc(), rReq)); + Cancel(); + } + break; + + case SID_PHOTOALBUM: + { + SdAbstractDialogFactory* pFact = SdAbstractDialogFactory::Create(); + vcl::Window* pWin = GetActiveWindow(); + ScopedVclPtr<VclAbstractDialog> pDlg( + pFact->CreateSdPhotoAlbumDialog(pWin ? pWin->GetFrameWeld() : nullptr, GetDoc())); + + pDlg->Execute(); + + Cancel(); + rReq.Ignore(); + } + break; + } + + if (HasCurrentFunction()) + GetCurrentFunction()->Activate(); + + Invalidate(SID_CUT); + Invalidate(SID_COPY); + Invalidate(SID_PASTE); + Invalidate(SID_PASTE_UNFORMATTED); +} + +void NotesPanelViewShell::FuTemporaryModify(SfxRequest& rReq) +{ + DeactivateCurrentFunction(); + + OutlinerView* pOutlinerView = mpNotesPanelView->GetOutlinerView(); + + sal_uInt16 nSId = rReq.GetSlot(); + switch (nSId) + { + case SID_HYPERLINK_SETLINK: + { + const SfxItemSet* pReqArgs = rReq.GetArgs(); + + if (pReqArgs) + { + const SvxHyperlinkItem* pHLItem = &pReqArgs->Get(SID_HYPERLINK_SETLINK); + + SvxFieldItem aURLItem( + SvxURLField(pHLItem->GetURL(), pHLItem->GetName(), SvxURLFormat::Repr), + EE_FEATURE_FIELD); + ESelection aSel(pOutlinerView->GetSelection()); + pOutlinerView->InsertField(aURLItem); + if (aSel.nStartPos <= aSel.nEndPos) + aSel.nEndPos = aSel.nStartPos + 1; + else + aSel.nStartPos = aSel.nEndPos + 1; + pOutlinerView->SetSelection(aSel); + } + + Cancel(); + rReq.Ignore(); + } + break; + + case FN_INSERT_SOFT_HYPHEN: + case FN_INSERT_HARDHYPHEN: + case FN_INSERT_HARD_SPACE: + case FN_INSERT_NNBSP: + case SID_INSERT_RLM: + case SID_INSERT_LRM: + case SID_INSERT_WJ: + case SID_INSERT_ZWSP: + case SID_CHARMAP: + { + SetCurrentFunction( + FuBullet::Create(this, GetActiveWindow(), mpNotesPanelView.get(), GetDoc(), rReq)); + Cancel(); + } + break; + + case SID_OUTLINE_BULLET: + case FN_SVX_SET_BULLET: + case FN_SVX_SET_NUMBER: + { + SetCurrentFunction(FuBulletAndPosition::Create(this, GetActiveWindow(), + mpNotesPanelView.get(), GetDoc(), rReq)); + Cancel(); + } + break; + + case SID_THESAURUS: + { + SetCurrentFunction(FuThesaurus::Create(this, GetActiveWindow(), mpNotesPanelView.get(), + GetDoc(), rReq)); + Cancel(); + rReq.Ignore(); + } + break; + + case SID_CHAR_DLG_EFFECT: + case SID_CHAR_DLG: + { + SetCurrentFunction( + FuChar::Create(this, GetActiveWindow(), mpNotesPanelView.get(), GetDoc(), rReq)); + Cancel(); + } + break; + + case SID_INSERTFILE: + { + SetCurrentFunction(FuInsertFile::Create(this, GetActiveWindow(), mpNotesPanelView.get(), + GetDoc(), rReq)); + Cancel(); + } + break; + + case SID_PRESENTATIONOBJECT: + { + SetCurrentFunction(FuPresentationObjects::Create( + this, GetActiveWindow(), mpNotesPanelView.get(), GetDoc(), rReq)); + Cancel(); + } + break; + + case SID_SET_DEFAULT: + { + pOutlinerView->RemoveAttribs(true); // sal_True = also paragraph attributes + Cancel(); + rReq.Done(); + } + break; + + case SID_SUMMARY_PAGE: + { + SetCurrentFunction(FuSummaryPage::Create(this, GetActiveWindow(), + mpNotesPanelView.get(), GetDoc(), rReq)); + Cancel(); + } + break; + + case SID_EXPAND_PAGE: + { + SetCurrentFunction(FuExpandPage::Create(this, GetActiveWindow(), mpNotesPanelView.get(), + GetDoc(), rReq)); + Cancel(); + } + break; + + case SID_INSERT_FLD_DATE_FIX: + case SID_INSERT_FLD_DATE_VAR: + case SID_INSERT_FLD_TIME_FIX: + case SID_INSERT_FLD_TIME_VAR: + case SID_INSERT_FLD_AUTHOR: + case SID_INSERT_FLD_PAGE: + case SID_INSERT_FLD_PAGE_TITLE: + case SID_INSERT_FLD_PAGES: + case SID_INSERT_FLD_FILE: + { + std::unique_ptr<SvxFieldItem> pFieldItem; + + switch (nSId) + { + case SID_INSERT_FLD_DATE_FIX: + pFieldItem.reset(new SvxFieldItem( + SvxDateField(Date(Date::SYSTEM), SvxDateType::Fix), EE_FEATURE_FIELD)); + break; + + case SID_INSERT_FLD_DATE_VAR: + pFieldItem.reset(new SvxFieldItem(SvxDateField(), EE_FEATURE_FIELD)); + break; + + case SID_INSERT_FLD_TIME_FIX: + pFieldItem.reset(new SvxFieldItem( + SvxExtTimeField(::tools::Time(::tools::Time::SYSTEM), SvxTimeType::Fix), + EE_FEATURE_FIELD)); + break; + + case SID_INSERT_FLD_TIME_VAR: + pFieldItem.reset(new SvxFieldItem(SvxExtTimeField(), EE_FEATURE_FIELD)); + break; + + case SID_INSERT_FLD_AUTHOR: + { + SvtUserOptions aUserOptions; + pFieldItem.reset(new SvxFieldItem(SvxAuthorField(aUserOptions.GetFirstName(), + aUserOptions.GetLastName(), + aUserOptions.GetID()), + EE_FEATURE_FIELD)); + } + break; + + case SID_INSERT_FLD_PAGE: + pFieldItem.reset(new SvxFieldItem(SvxPageField(), EE_FEATURE_FIELD)); + break; + + case SID_INSERT_FLD_PAGE_TITLE: + pFieldItem.reset(new SvxFieldItem(SvxPageTitleField(), EE_FEATURE_FIELD)); + break; + + case SID_INSERT_FLD_PAGES: + pFieldItem.reset(new SvxFieldItem(SvxPagesField(), EE_FEATURE_FIELD)); + break; + + case SID_INSERT_FLD_FILE: + { + OUString aName; + if (GetDocSh()->HasName()) + aName = GetDocSh()->GetMedium()->GetName(); + pFieldItem.reset(new SvxFieldItem(SvxExtFileField(aName), EE_FEATURE_FIELD)); + } + break; + } + + const SvxFieldItem* pOldFldItem = pOutlinerView->GetFieldAtSelection(); + + if (pOldFldItem + && (nullptr != dynamic_cast<const SvxURLField*>(pOldFldItem->GetField()) + || nullptr != dynamic_cast<const SvxDateField*>(pOldFldItem->GetField()) + || nullptr != dynamic_cast<const SvxTimeField*>(pOldFldItem->GetField()) + || nullptr != dynamic_cast<const SvxExtTimeField*>(pOldFldItem->GetField()) + || nullptr != dynamic_cast<const SvxExtFileField*>(pOldFldItem->GetField()) + || nullptr != dynamic_cast<const SvxAuthorField*>(pOldFldItem->GetField()) + || nullptr != dynamic_cast<const SvxPageField*>(pOldFldItem->GetField()) + || nullptr != dynamic_cast<const SvxPagesField*>(pOldFldItem->GetField()))) + { + // select field, so it gets deleted on Insert + ESelection aSel = pOutlinerView->GetSelection(); + if (aSel.nStartPos == aSel.nEndPos) + aSel.nEndPos++; + pOutlinerView->SetSelection(aSel); + } + + if (pFieldItem) + pOutlinerView->InsertField(*pFieldItem); + + pFieldItem.reset(); + + Cancel(); + rReq.Ignore(); + } + break; + + case SID_MODIFY_FIELD: + { + const SvxFieldItem* pFldItem = pOutlinerView->GetFieldAtSelection(); + + if (pFldItem + && (nullptr != dynamic_cast<const SvxDateField*>(pFldItem->GetField()) + || nullptr != dynamic_cast<const SvxAuthorField*>(pFldItem->GetField()) + || nullptr != dynamic_cast<const SvxExtFileField*>(pFldItem->GetField()) + || nullptr != dynamic_cast<const SvxExtTimeField*>(pFldItem->GetField()))) + { + // Dialog... + SdAbstractDialogFactory* pFact = SdAbstractDialogFactory::Create(); + vcl::Window* pWin = GetActiveWindow(); + ScopedVclPtr<AbstractSdModifyFieldDlg> pDlg(pFact->CreateSdModifyFieldDlg( + pWin ? pWin->GetFrameWeld() : nullptr, pFldItem->GetField(), + pOutlinerView->GetAttribs())); + if (pDlg->Execute() == RET_OK) + { + std::unique_ptr<SvxFieldData> pField(pDlg->GetField()); + if (pField) + { + SvxFieldItem aFieldItem(*pField, EE_FEATURE_FIELD); + //pOLV->DeleteSelected(); <-- unfortunately missing! + // select field, so it gets deleted on Insert + ESelection aSel = pOutlinerView->GetSelection(); + bool bSel = true; + if (aSel.nStartPos == aSel.nEndPos) + { + bSel = false; + aSel.nEndPos++; + } + pOutlinerView->SetSelection(aSel); + + pOutlinerView->InsertField(aFieldItem); + + // reset selection to original state + if (!bSel) + aSel.nEndPos--; + pOutlinerView->SetSelection(aSel); + + pField.reset(); + } + + SfxItemSet aSet(pDlg->GetItemSet()); + if (aSet.Count()) + { + pOutlinerView->SetAttribs(aSet); + + ::Outliner* pOutliner = pOutlinerView->GetOutliner(); + if (pOutliner) + pOutliner->UpdateFields(); + } + } + } + + Cancel(); + rReq.Ignore(); + } + break; + } + + if (HasCurrentFunction()) + GetCurrentFunction()->Activate(); + + Invalidate(SID_CUT); + Invalidate(SID_COPY); + Invalidate(SID_PASTE); + Invalidate(SID_PASTE_UNFORMATTED); +} + +void NotesPanelViewShell::FuSupport(SfxRequest& rReq) +{ + if (rReq.GetSlot() == SID_STYLE_FAMILY && rReq.GetArgs()) + GetDocSh()->SetStyleFamily( + static_cast<SfxStyleFamily>(rReq.GetArgs()->Get(SID_STYLE_FAMILY).GetValue())); + + bool bPreviewState = false; + sal_uInt16 nSlot = rReq.GetSlot(); + + switch (nSlot) + { + case SID_CUT: + { + if (HasCurrentFunction()) + { + GetCurrentFunction()->DoCut(); + } + else if (mpNotesPanelView) + { + mpNotesPanelView->DoCut(); + } + rReq.Done(); + bPreviewState = true; + } + break; + + case SID_COPY: + { + if (HasCurrentFunction()) + { + GetCurrentFunction()->DoCopy(); + } + else if (mpNotesPanelView) + { + mpNotesPanelView->DoCopy(); + } + rReq.Done(); + bPreviewState = true; + } + break; + + case SID_PASTE: + { + if (HasCurrentFunction()) + { + GetCurrentFunction()->DoPaste(); + } + else if (mpNotesPanelView) + { + mpNotesPanelView->DoPaste(); + } + rReq.Done(); + bPreviewState = true; + } + break; + + case SID_PASTE_UNFORMATTED: + { + if (HasCurrentFunction()) + { + GetCurrentFunction()->DoPasteUnformatted(); + } + else if (mpNotesPanelView) + { + TransferableDataHelper aDataHelper( + TransferableDataHelper::CreateFromSystemClipboard(GetActiveWindow())); + if (aDataHelper.GetTransferable().is()) + { + sal_Int8 nAction = DND_ACTION_COPY; + mpNotesPanelView->InsertData( + aDataHelper, + GetActiveWindow()->PixelToLogic( + ::tools::Rectangle(Point(), GetActiveWindow()->GetOutputSizePixel()) + .Center()), + nAction, false, SotClipboardFormatId::STRING); + } + } + + rReq.Ignore(); + } + break; + case SID_DELETE: + { + if (mpNotesPanelView) + { + OutlinerView* pOutlView = mpNotesPanelView->GetOutlinerView(); + if (pOutlView) + { + vcl::KeyCode aKCode(KEY_DELETE); + KeyEvent aKEvt(0, aKCode); + pOutlView->PostKeyEvent(aKEvt); + + rtl::Reference<FuPoor> xFunc(GetCurrentFunction()); + FuOutlineText* pFuOutlineText = dynamic_cast<FuOutlineText*>(xFunc.get()); + if (pFuOutlineText) + pFuOutlineText->UpdateForKeyPress(aKEvt); + } + } + rReq.Done(); + bPreviewState = true; + } + break; + + case SID_DRAWINGMODE: + case SID_SLIDE_MASTER_MODE: + case SID_NOTES_MODE: + case SID_NOTES_MASTER_MODE: + case SID_HANDOUT_MASTER_MODE: + case SID_SLIDE_SORTER_MODE: + case SID_OUTLINE_MODE: + framework::FrameworkHelper::Instance(GetViewShellBase()) + ->HandleModeChangeSlot(nSlot, rReq); + rReq.Done(); + break; + + case SID_RULER: + SetRuler(!HasRuler()); + Invalidate(SID_RULER); + rReq.Done(); + break; + + case SID_ZOOM_PREV: + { + if (mpZoomList->IsPreviousPossible()) + { + SetZoomRect(mpZoomList->GetPreviousZoomRect()); + } + rReq.Done(); + } + break; + + case SID_ZOOM_NEXT: + { + if (mpZoomList->IsNextPossible()) + { + SetZoomRect(mpZoomList->GetNextZoomRect()); + } + rReq.Done(); + } + break; + + case SID_AUTOSPELL_CHECK: + { + GetDoc()->SetOnlineSpell(!GetDoc()->GetOnlineSpell()); + rReq.Done(); + } + break; + + case SID_TRANSLITERATE_SENTENCE_CASE: + case SID_TRANSLITERATE_TITLE_CASE: + case SID_TRANSLITERATE_TOGGLE_CASE: + case SID_TRANSLITERATE_UPPER: + case SID_TRANSLITERATE_LOWER: + case SID_TRANSLITERATE_HALFWIDTH: + case SID_TRANSLITERATE_FULLWIDTH: + case SID_TRANSLITERATE_HIRAGANA: + case SID_TRANSLITERATE_KATAKANA: + { + OutlinerView* pOLV = mpNotesPanelView ? mpNotesPanelView->GetOutlinerView() : nullptr; + if (pOLV) + { + TransliterationFlags nType = TransliterationFlags::NONE; + + switch (nSlot) + { + case SID_TRANSLITERATE_SENTENCE_CASE: + nType = TransliterationFlags::SENTENCE_CASE; + break; + case SID_TRANSLITERATE_TITLE_CASE: + nType = TransliterationFlags::TITLE_CASE; + break; + case SID_TRANSLITERATE_TOGGLE_CASE: + nType = TransliterationFlags::TOGGLE_CASE; + break; + case SID_TRANSLITERATE_UPPER: + nType = TransliterationFlags::LOWERCASE_UPPERCASE; + break; + case SID_TRANSLITERATE_LOWER: + nType = TransliterationFlags::UPPERCASE_LOWERCASE; + break; + case SID_TRANSLITERATE_HALFWIDTH: + nType = TransliterationFlags::FULLWIDTH_HALFWIDTH; + break; + case SID_TRANSLITERATE_FULLWIDTH: + nType = TransliterationFlags::HALFWIDTH_FULLWIDTH; + break; + case SID_TRANSLITERATE_HIRAGANA: + nType = TransliterationFlags::KATAKANA_HIRAGANA; + break; + case SID_TRANSLITERATE_KATAKANA: + nType = TransliterationFlags::HIRAGANA_KATAKANA; + break; + } + + pOLV->TransliterateText(nType); + } + + rReq.Done(); + bPreviewState = true; + } + break; + + // added Undo/Redo handling + case SID_UNDO: + { + ImpSidUndo(rReq); + } + break; + case SID_REDO: + { + ImpSidRedo(rReq); + } + break; + + default: + break; + } + + if (bPreviewState) + Invalidate(SID_PREVIEW_STATE); + + Invalidate(SID_CUT); + Invalidate(SID_COPY); + Invalidate(SID_PASTE); +} + +void NotesPanelViewShell::Execute(SfxRequest& rReq) +{ + bool bForwardCall = true; + + switch (rReq.GetSlot()) + { + case SID_SAVEDOC: + case SID_SAVEASDOC: + PrepareClose(); + break; + + case SID_SEARCH_ITEM: + // Forward this request to the common (old) code of the + // document shell. + GetDocSh()->Execute(rReq); + bForwardCall = false; + break; + + case SID_SPELL_DIALOG: + { + SfxViewFrame* pViewFrame = GetViewFrame(); + if (rReq.GetArgs() != nullptr) + pViewFrame->SetChildWindow( + SID_SPELL_DIALOG, + static_cast<const SfxBoolItem&>(rReq.GetArgs()->Get(SID_SPELL_DIALOG)) + .GetValue()); + else + pViewFrame->ToggleChildWindow(SID_SPELL_DIALOG); + + pViewFrame->GetBindings().Invalidate(SID_SPELL_DIALOG); + rReq.Done(); + bForwardCall = false; + } + break; + + default: + break; + } + + if (bForwardCall) + TextObjectBar::ExecuteImpl(this, mpView, rReq, nullptr); +} + +void NotesPanelViewShell::MouseButtonUp(const MouseEvent& rMEvt, ::sd::Window* pWin) +{ + // first the base classes + ViewShell::MouseButtonUp(rMEvt, pWin); + + Invalidate(SID_STYLE_EDIT); + Invalidate(SID_STYLE_NEW); + Invalidate(SID_STYLE_DELETE); + Invalidate(SID_STYLE_HIDE); + Invalidate(SID_STYLE_SHOW); + Invalidate(SID_STYLE_UPDATE_BY_EXAMPLE); + Invalidate(SID_STYLE_NEW_BY_EXAMPLE); + Invalidate(SID_STYLE_WATERCAN); + Invalidate(SID_STYLE_FAMILY5); +} + +void NotesPanelViewShell::Command(const CommandEvent& rCEvt, ::sd::Window* pWin) +{ + if (rCEvt.GetCommand() == CommandEventId::ContextMenu) + { + GetActiveWindow()->ReleaseMouse(); + + OutlinerView* pOLV = mpNotesPanelView->GetOutlinerView(); + Point aPos(rCEvt.GetMousePosPixel()); + + if (pOLV && pOLV->IsWrongSpelledWordAtPos(aPos)) + { + // Popup for Online-Spelling now handled by DrawDocShell + Link<SpellCallbackInfo&, void> aLink + = LINK(GetDocSh(), DrawDocShell, OnlineSpellCallback); + + pOLV->ExecuteSpellPopup(aPos, aLink); + pOLV->GetEditView().Invalidate(); + } + else + { + GetViewFrame()->GetDispatcher()->ExecutePopup("drawtext"); + } + } + else + { + ViewShell::Command(rCEvt, pWin); + } +} + +bool NotesPanelViewShell::KeyInput(const KeyEvent& rKEvt, ::sd::Window* pWin) +{ + bool bReturn = false; + + if (pWin == nullptr && HasCurrentFunction()) + { + bReturn = GetCurrentFunction()->KeyInput(rKEvt); + } + else + { + bReturn = ViewShell::KeyInput(rKEvt, pWin); + } + + Invalidate(SID_STYLE_EDIT); + Invalidate(SID_STYLE_NEW); + Invalidate(SID_STYLE_DELETE); + Invalidate(SID_STYLE_HIDE); + Invalidate(SID_STYLE_SHOW); + Invalidate(SID_STYLE_UPDATE_BY_EXAMPLE); + Invalidate(SID_STYLE_NEW_BY_EXAMPLE); + Invalidate(SID_STYLE_WATERCAN); + Invalidate(SID_STYLE_FAMILY5); + + vcl::KeyCode aKeyGroup(rKEvt.GetKeyCode().GetGroup()); + return bReturn; +} + +} // end of namespace sd + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/sd/source/ui/view/ToolBarManager.cxx b/sd/source/ui/view/ToolBarManager.cxx index 4be073bac612..7dd95c962499 100644 --- a/sd/source/ui/view/ToolBarManager.cxx +++ b/sd/source/ui/view/ToolBarManager.cxx @@ -993,6 +993,7 @@ void ToolBarRules::MainViewShellChanged (ViewShell::ShellType nShellType) ToolBarManager::msSlideSorterObjectBar); break; + case ViewShell::ST_NOTESPANEL: case ViewShell::ST_NONE: case ViewShell::ST_PRESENTATION: case ViewShell::ST_SIDEBAR: diff --git a/sd/source/ui/view/ViewShellBase.cxx b/sd/source/ui/view/ViewShellBase.cxx index 115beb928a19..eb9a1d4ad127 100644 --- a/sd/source/ui/view/ViewShellBase.cxx +++ b/sd/source/ui/view/ViewShellBase.cxx @@ -632,13 +632,11 @@ void ViewShellBase::Execute (SfxRequest& rRequest) break; case SID_NOTES_WINDOW: - { - SfxViewShell* pViewShell = SfxViewShell::Current(); - SfxViewFrame& rViewFrame = pViewShell->GetViewFrame(); - auto nID = rRequest.GetSlot(); - rViewFrame.ToggleChildWindow(nID); + mpImpl->SetPaneVisibility( + rRequest, + framework::FrameworkHelper::msBottomImpressPaneURL, + framework::FrameworkHelper::msNotesPanelViewURL); break; - } case SID_TOGGLE_TABBAR_VISIBILITY: { @@ -1344,19 +1342,10 @@ void ViewShellBase::Implementation::GetSlotState (SfxItemSet& rSet) break; case SID_NOTES_WINDOW: - { - bState = false; - auto* pViewShell = SfxViewShell::Current(); - if (pViewShell) - { - auto& rViewFrame = pViewShell->GetViewFrame(); - if (rViewFrame.KnowsChildWindow(nItemId)) - { - bState = rViewFrame.HasChildWindow(nItemId); - } - } + xResourceId = ResourceId::create( + xContext, FrameworkHelper::msBottomImpressPaneURL); + bState = xConfiguration->hasResource(xResourceId); break; - } case SID_DRAWINGMODE: case SID_NORMAL_MULTI_PANE_GUI: diff --git a/sd/source/ui/view/ViewShellImplementation.cxx b/sd/source/ui/view/ViewShellImplementation.cxx index 27d003cd0546..b894d4e48ee8 100644 --- a/sd/source/ui/view/ViewShellImplementation.cxx +++ b/sd/source/ui/view/ViewShellImplementation.cxx @@ -293,6 +293,7 @@ SfxInterfaceId ViewShell::Implementation::GetViewId() const // Since we have to return a view id for every possible shell type // and there is not (yet) a proper ViewShellBase sub class for the // remaining types we chose the Impress factory as a fall back. + case ViewShell::ST_NOTESPANEL: case ViewShell::ST_SIDEBAR: case ViewShell::ST_NONE: default: diff --git a/sd/source/ui/view/drtxtob.cxx b/sd/source/ui/view/drtxtob.cxx index 0a75f4dd5cef..a5b62e495033 100644 --- a/sd/source/ui/view/drtxtob.cxx +++ b/sd/source/ui/view/drtxtob.cxx @@ -121,6 +121,11 @@ TextObjectBar::~TextObjectBar() void TextObjectBar::GetCharState( SfxItemSet& rSet ) { + GetCharStateImpl(mpViewShell, mpView, rSet); +} + +void TextObjectBar::GetCharStateImpl(ViewShell* mpViewShell, ::sd::View* mpView, SfxItemSet& rSet) +{ SfxItemSet aCharAttrSet( mpView->GetDoc().GetPool() ); mpView->GetAttributes( aCharAttrSet ); @@ -140,10 +145,15 @@ void TextObjectBar::GetCharState( SfxItemSet& rSet ) } } +void TextObjectBar::GetAttrState( SfxItemSet& rSet ) +{ + GetAttrStateImpl(mpViewShell, mpView, rSet, this); +} + /** * Status of attribute items. */ -void TextObjectBar::GetAttrState( SfxItemSet& rSet ) +void TextObjectBar::GetAttrStateImpl(ViewShell* mpViewShell, ::sd::View* mpView, SfxItemSet& rSet, SfxShell* pTextObjectBar) { SfxWhichIter aIter( rSet ); sal_uInt16 nWhich = aIter.FirstWhich(); @@ -156,7 +166,7 @@ void TextObjectBar::GetAttrState( SfxItemSet& rSet ) while ( nWhich ) { sal_uInt16 nSlotId = SfxItemPool::IsWhich(nWhich) - ? GetPool().GetSlotId(nWhich) + ? mpView->GetDoc().GetPool().GetSlotId(nWhich) : nWhich; switch ( nSlotId ) @@ -170,7 +180,7 @@ void TextObjectBar::GetAttrState( SfxItemSet& rSet ) case SID_ATTR_CHAR_CASEMAP: { double stretchY = 1.0; - SvxScriptSetItem aSetItem( nSlotId, GetPool() ); + SvxScriptSetItem aSetItem( nSlotId, mpView->GetDoc().GetPool() ); aSetItem.GetItemSet().Put( aAttrSet, false ); SvtScriptType nScriptType = mpView->GetScriptType(); @@ -528,12 +538,15 @@ void TextObjectBar::GetAttrState( SfxItemSet& rSet ) break; } - Invalidate(SID_ATTR_PARA_ADJUST_LEFT); - Invalidate(SID_ATTR_PARA_ADJUST_CENTER); - Invalidate(SID_ATTR_PARA_ADJUST_RIGHT); - Invalidate(SID_ATTR_PARA_ADJUST_BLOCK); - Invalidate(SID_ATTR_PARA_LINESPACE); - Invalidate(SID_ATTR_PARA_ULSPACE); + if(pTextObjectBar) + { + pTextObjectBar->Invalidate(SID_ATTR_PARA_ADJUST_LEFT); + pTextObjectBar->Invalidate(SID_ATTR_PARA_ADJUST_CENTER); + pTextObjectBar->Invalidate(SID_ATTR_PARA_ADJUST_RIGHT); + pTextObjectBar->Invalidate(SID_ATTR_PARA_ADJUST_BLOCK); + pTextObjectBar->Invalidate(SID_ATTR_PARA_LINESPACE); + pTextObjectBar->Invalidate(SID_ATTR_PARA_ULSPACE); + } // paragraph text direction if( bDisableParagraphTextDirection ) @@ -587,7 +600,8 @@ void TextObjectBar::GetAttrState( SfxItemSet& rSet ) SvxLRSpaceItem aLRSpace = aAttrSet.Get( EE_PARA_LRSPACE ); aLRSpace.SetWhich(SID_ATTR_PARA_LRSPACE); rSet.Put(aLRSpace); - Invalidate(SID_ATTR_PARA_LRSPACE); + if (pTextObjectBar) + pTextObjectBar->Invalidate(SID_ATTR_PARA_LRSPACE); //Added by xuxu SfxItemState eState = aAttrSet.GetItemState( EE_PARA_LRSPACE ); diff --git a/sd/source/ui/view/drtxtob1.cxx b/sd/source/ui/view/drtxtob1.cxx index e7deb15750a3..44a63a3634d1 100644 --- a/sd/source/ui/view/drtxtob1.cxx +++ b/sd/source/ui/view/drtxtob1.cxx @@ -71,8 +71,12 @@ namespace sd { /** * Process SfxRequests */ +void TextObjectBar::Execute(SfxRequest& rReq) +{ + ExecuteImpl(mpViewShell, mpView, rReq, this); +} -void TextObjectBar::Execute( SfxRequest &rReq ) +void TextObjectBar::ExecuteImpl(ViewShell* mpViewShell, ::sd::View* mpView, SfxRequest& rReq, SfxShell* pTextObjectBar) { const SfxItemSet* pArgs = rReq.GetArgs(); sal_uInt16 nSlot = rReq.GetSlot(); @@ -169,7 +173,8 @@ void TextObjectBar::Execute( SfxRequest &rReq ) } rReq.Done(); - Invalidate(); + if(pTextObjectBar) + pTextObjectBar->Invalidate(); // to refresh preview (in outline mode), slot has to be invalidated: mpViewShell->GetViewFrame()->GetBindings().Invalidate( SID_PREVIEW_STATE, true ); @@ -274,7 +279,8 @@ void TextObjectBar::Execute( SfxRequest &rReq ) } rReq.Done(); - Invalidate(); + if (pTextObjectBar) + pTextObjectBar->Invalidate(); // to refresh preview (in outline mode), slot has to be invalidated: mpViewShell->GetViewFrame()->GetBindings().Invalidate( SID_PREVIEW_STATE, true ); mpViewShell->GetViewFrame()->GetBindings().Invalidate( SID_ATTR_PARA_ULSPACE, true ); @@ -288,7 +294,8 @@ void TextObjectBar::Execute( SfxRequest &rReq ) pOLV->AdjustDepth( -1 ); // Ensure bold/italic etc. icon state updates - Invalidate(); + if (pTextObjectBar) + pTextObjectBar->Invalidate(); // trigger preview refresh mpViewShell->GetViewFrame()->GetBindings().Invalidate( SID_PREVIEW_STATE, true ); } @@ -303,7 +310,8 @@ void TextObjectBar::Execute( SfxRequest &rReq ) pOLV->AdjustDepth( 1 ); // Ensure bold/italic etc. icon state updates - Invalidate(); + if (pTextObjectBar) + pTextObjectBar->Invalidate(); // trigger preview refresh mpViewShell->GetViewFrame()->GetBindings().Invalidate( SID_PREVIEW_STATE, true ); } @@ -316,19 +324,20 @@ void TextObjectBar::Execute( SfxRequest &rReq ) SvxLRSpaceItem aLRSpace = static_cast<const SvxLRSpaceItem&>(pArgs->Get( SID_ATTR_PARA_LRSPACE)); - SfxItemSetFixed<EE_PARA_LRSPACE, EE_PARA_LRSPACE> aEditAttr( GetPool() ); + SfxItemSetFixed<EE_PARA_LRSPACE, EE_PARA_LRSPACE> aEditAttr(mpView->GetDoc().GetPool()); aLRSpace.SetWhich( EE_PARA_LRSPACE ); aEditAttr.Put( aLRSpace ); mpView->SetAttributes( aEditAttr ); - Invalidate(SID_ATTR_PARA_LRSPACE); + if (pTextObjectBar) + pTextObjectBar->Invalidate(SID_ATTR_PARA_LRSPACE); } break; case SID_HANGING_INDENT: { - SfxItemSetFixed<EE_PARA_LRSPACE, EE_PARA_LRSPACE> aLRSpaceSet( GetPool() ); + SfxItemSetFixed<EE_PARA_LRSPACE, EE_PARA_LRSPACE> aLRSpaceSet(mpView->GetDoc().GetPool()); mpView->GetAttributes( aLRSpaceSet ); SvxLRSpaceItem aParaMargin( aLRSpaceSet.Get( EE_PARA_LRSPACE ) ); @@ -339,7 +348,8 @@ void TextObjectBar::Execute( SfxRequest &rReq ) aLRSpaceSet.Put( aNewMargin ); mpView->SetAttributes( aLRSpaceSet ); - Invalidate(SID_ATTR_PARA_LRSPACE); + if (pTextObjectBar) + pTextObjectBar->Invalidate(SID_ATTR_PARA_LRSPACE); } break; @@ -383,7 +393,8 @@ void TextObjectBar::Execute( SfxRequest &rReq ) SDRATTR_TEXTDIRECTION ) ); rReq.Done( aAttr ); mpView->SetAttributes( aAttr ); - Invalidate(); + if (pTextObjectBar) + pTextObjectBar->Invalidate(); mpViewShell->GetViewFrame()->GetBindings().Invalidate( SID_PREVIEW_STATE, true ); } break; @@ -700,7 +711,8 @@ void TextObjectBar::Execute( SfxRequest &rReq ) rReq.Done( aNewAttr ); pArgs = rReq.GetArgs(); - Invalidate( SID_RULER_TEXT_RIGHT_TO_LEFT ); + if (pTextObjectBar) + pTextObjectBar->Invalidate(SID_RULER_TEXT_RIGHT_TO_LEFT); } else if ( nSlot == SID_ATTR_CHAR_FONT || nSlot == SID_ATTR_CHAR_FONTHEIGHT || @@ -788,7 +800,8 @@ void TextObjectBar::Execute( SfxRequest &rReq ) // invalidate entire shell because of performance and // extension reasons - Invalidate(); + if (pTextObjectBar) + pTextObjectBar->Invalidate(); // to refresh preview (in outline mode), slot has to be invalidated: mpViewShell->GetViewFrame()->GetBindings().Invalidate( SID_PREVIEW_STATE, true ); @@ -802,10 +815,13 @@ void TextObjectBar::Execute( SfxRequest &rReq ) pOLV->GetWindow()->GrabFocus(); } - Invalidate( SID_OUTLINE_LEFT ); - Invalidate( SID_OUTLINE_RIGHT ); - Invalidate( SID_OUTLINE_UP ); - Invalidate( SID_OUTLINE_DOWN ); + if (pTextObjectBar) + { + pTextObjectBar->Invalidate(SID_OUTLINE_LEFT); + pTextObjectBar->Invalidate(SID_OUTLINE_RIGHT); + pTextObjectBar->Invalidate(SID_OUTLINE_UP); + pTextObjectBar->Invalidate(SID_OUTLINE_DOWN); + } } } // end of namespace sd diff --git a/sd/source/ui/view/outlview.cxx b/sd/source/ui/view/outlview.cxx index 087aa50ee86e..ddcbf362d3cf 100644 --- a/sd/source/ui/view/outlview.cxx +++ b/sd/source/ui/view/outlview.cxx @@ -71,7 +71,7 @@ namespace sd { #define PROCESS_WITH_PROGRESS_THRESHOLD 5 OutlineView::OutlineView( DrawDocShell& rDocSh, vcl::Window* pWindow, OutlineViewShell& rOutlineViewShell) -: ::sd::View(*rDocSh.GetDoc(), pWindow->GetOutDev(), &rOutlineViewShell) +: ::sd::SimpleOutlinerView(*rDocSh.GetDoc(), pWindow->GetOutDev(), &rOutlineViewShell) , mrOutlineViewShell(rOutlineViewShell) , mrOutliner(*mrDoc.GetOutliner()) , mnPagesToProcess(0) |