include/svx/svdedxv.hxx | 8 officecfg/registry/data/org/openoffice/Office/UI/DrawImpressCommands.xcu | 8 sd/Library_sd.mk | 2 sd/UIConfig_simpress.mk | 2 sd/inc/app.hrc | 3 sd/inc/glob.hxx | 2 sd/inc/strings.hrc | 1 sd/sdi/NotesPanelView.sdi | 514 +++ sd/sdi/ViewShellBase.sdi | 2 sd/sdi/sdraw.sdi | 10 sd/sdi/sdslots.sdi | 1 sd/source/ui/app/sddll.cxx | 1 sd/source/ui/dlg/PaneChildWindows.cxx | 28 sd/source/ui/dlg/PaneShells.cxx | 17 sd/source/ui/framework/factories/BasicPaneFactory.cxx | 12 sd/source/ui/framework/factories/BasicViewFactory.cxx | 7 sd/source/ui/framework/tools/FrameworkHelper.cxx | 4 sd/source/ui/func/fuoltext.cxx | 141 sd/source/ui/inc/NotesPanelView.hxx | 103 sd/source/ui/inc/NotesPanelViewShell.hxx | 103 sd/source/ui/inc/OutlineView.hxx | 18 sd/source/ui/inc/PaneChildWindows.hxx | 13 sd/source/ui/inc/PaneShells.hxx | 17 sd/source/ui/inc/TextObjectBar.hxx | 3 sd/source/ui/inc/ViewShell.hxx | 17 sd/source/ui/inc/framework/FrameworkHelper.hxx | 2 sd/source/ui/inc/fuoltext.hxx | 51 sd/source/ui/view/GraphicViewShellBase.cxx | 2 sd/source/ui/view/NotesPanelView.cxx | 354 ++ sd/source/ui/view/NotesPanelViewShell.cxx | 1452 ++++++++++ sd/source/ui/view/ToolBarManager.cxx | 1 sd/source/ui/view/ViewShellBase.cxx | 13 sd/source/ui/view/ViewShellImplementation.cxx | 1 sd/source/ui/view/drtxtob.cxx | 34 sd/source/ui/view/drtxtob1.cxx | 48 sd/source/ui/view/drvwshrg.cxx | 2 sd/source/ui/view/outlview.cxx | 2 sd/source/ui/view/sdwindow.cxx | 4 sd/uiconfig/simpress/menubar/menubar.xml | 1 sd/uiconfig/simpress/ui/noteschildwindow.ui | 41 sd/uiconfig/simpress/ui/notespanelcontextmenu.ui | 9 41 files changed, 2933 insertions(+), 121 deletions(-)
New commits: commit 57084baf1dfb150700fcf385003d989b08e2104a Author: Sarper Akdemir <sarper.akdemir.ext...@allotropia.de> AuthorDate: Fri Apr 19 00:40:28 2024 +0200 Commit: Thorsten Behrens <thorsten.behr...@allotropia.de> CommitDate: Wed May 1 15:00:33 2024 +0200 related tdf#33603: sd: do not assume there's always a viewshell Change-Id: I171639150a84372e7e25b5246d4882c467edd58b Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166271 Tested-by: Jenkins Reviewed-by: Sarper Akdemir <sarper.akdemir.ext...@allotropia.de> diff --git a/sd/source/ui/view/sdwindow.cxx b/sd/source/ui/view/sdwindow.cxx index 5c64e4d1dda4..753e6921e461 100644 --- a/sd/source/ui/view/sdwindow.cxx +++ b/sd/source/ui/view/sdwindow.cxx @@ -738,7 +738,8 @@ void Window::LoseFocus() { mnTicks = 0; vcl::Window::LoseFocus (); - GetViewShell()->onLoseFocus(); + if (mpViewShell) + mpViewShell->onLoseFocus(); } /** @@ -748,7 +749,8 @@ void Window::GrabFocus() { mnTicks = 0; vcl::Window::GrabFocus (); - GetViewShell()->onGrabFocus(); + if (mpViewShell) + mpViewShell->onGrabFocus(); } void Window::DataChanged( const DataChangedEvent& rDCEvt ) commit ca42eb73d360471b4259fd200aa86e547d237f0a Author: Sarper Akdemir <sarper.akdemir.ext...@allotropia.de> AuthorDate: Tue Apr 16 17:09:28 2024 +0200 Commit: Thorsten Behrens <thorsten.behr...@allotropia.de> CommitDate: Wed May 1 15:00:33 2024 +0200 tdf#33603: make the notes pane handle placeholder text on focus Change-Id: Id2bca2b8a8bafa9da44a5f97a8e763b512078ef7 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166152 Tested-by: Jenkins Reviewed-by: Sarper Akdemir <sarper.akdemir.ext...@allotropia.de> diff --git a/sd/source/ui/inc/NotesPanelView.hxx b/sd/source/ui/inc/NotesPanelView.hxx index 810cddd6af71..9f2b71523c09 100644 --- a/sd/source/ui/inc/NotesPanelView.hxx +++ b/sd/source/ui/inc/NotesPanelView.hxx @@ -39,6 +39,7 @@ class NotesPanelView final : public ::sd::SimpleOutlinerView SdrTextObj* mpTextObj = nullptr; bool mbIgnoreNotifications = false; + bool mbInFocus = false; /** stores the last used document color. this is changed in onUpdateStyleSettings() @@ -61,6 +62,8 @@ public: void Paint(const ::tools::Rectangle& rRect, ::sd::Window const* pWin); void onResize(); + void onGrabFocus(); + void onLoseFocus(); OutlinerView* GetOutlinerView(); OutlinerView* GetViewByWindow(vcl::Window const* pWin) const override; diff --git a/sd/source/ui/inc/NotesPanelViewShell.hxx b/sd/source/ui/inc/NotesPanelViewShell.hxx index e79ac899fe30..39901d6e4faa 100644 --- a/sd/source/ui/inc/NotesPanelViewShell.hxx +++ b/sd/source/ui/inc/NotesPanelViewShell.hxx @@ -49,6 +49,8 @@ public: 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 onGrabFocus() override; + virtual void onLoseFocus() override; virtual void ArrangeGUIElements() override; virtual SdPage* GetActualPage() override; diff --git a/sd/source/ui/inc/ViewShell.hxx b/sd/source/ui/inc/ViewShell.hxx index 9892540c03aa..9e5e8e068160 100644 --- a/sd/source/ui/inc/ViewShell.hxx +++ b/sd/source/ui/inc/ViewShell.hxx @@ -413,6 +413,20 @@ public: SdPage* pPage, const sal_Int32 nInsertPosition = -1); + /** Called by sd::Window::LoseFocus to enable sd::ViewShell to take action + when focus is lost. + + e.g. overriden by NotesPanelViewShell + */ + virtual void onLoseFocus(){}; + + /** Called by sd::Window::GrabFocus to enable sd::ViewShell to take action + when focus is grabbed. + + e.g. overriden by NotesPanelViewShell + */ + virtual void onGrabFocus(){}; + /// Allows adjusting the point or mark of the selection to a document coordinate. void SetCursorMm100Position(const Point& rPosition, bool bPoint, bool bClearMark); /// Gets the current selection diff --git a/sd/source/ui/view/NotesPanelView.cxx b/sd/source/ui/view/NotesPanelView.cxx index 2822a8df4c02..a2ae58e48331 100644 --- a/sd/source/ui/view/NotesPanelView.cxx +++ b/sd/source/ui/view/NotesPanelView.cxx @@ -224,6 +224,40 @@ void NotesPanelView::onResize() } } +void NotesPanelView::onGrabFocus() +{ + if (mbInFocus) + return; + mbInFocus = true; + + if (mpTextObj && mpTextObj->IsEmptyPresObj()) + { + // clear the "Click to add Notes" text on entering the window. + maOutliner.SetToEmptyText(); + } +} + +void NotesPanelView::onLoseFocus() +{ + if (!mbInFocus) + return; + mbInFocus = false; + + aModifyIdle.Stop(); + if (mpTextObj) + { + if (maOutliner.GetEditEngine().GetText().getLength() == 0) + { + // if the notes are empty restore the placeholder text and state. + SdPage* pPage = dynamic_cast<SdPage*>(mpTextObj->getSdrPageFromSdrObject()); + if (pPage) + pPage->RestoreDefaultText(mpTextObj); + } + else + setNotesToDoc(); + } +} + /** * Handler for StatusEvents */ diff --git a/sd/source/ui/view/NotesPanelViewShell.cxx b/sd/source/ui/view/NotesPanelViewShell.cxx index ec849a2484d9..5b7bdcf6329f 100644 --- a/sd/source/ui/view/NotesPanelViewShell.cxx +++ b/sd/source/ui/view/NotesPanelViewShell.cxx @@ -235,6 +235,10 @@ void NotesPanelViewShell::VisAreaChanged(const ::tools::Rectangle& rRect) GetViewShellBase().GetDrawController()->FireVisAreaChanged(rRect); } +void NotesPanelViewShell::onGrabFocus() { mpNotesPanelView->onGrabFocus(); } + +void NotesPanelViewShell::onLoseFocus() { mpNotesPanelView->onLoseFocus(); } + void NotesPanelViewShell::ArrangeGUIElements() { // Retrieve the current size (thickness) of the scroll bars. That is diff --git a/sd/source/ui/view/sdwindow.cxx b/sd/source/ui/view/sdwindow.cxx index ee795017c30c..5c64e4d1dda4 100644 --- a/sd/source/ui/view/sdwindow.cxx +++ b/sd/source/ui/view/sdwindow.cxx @@ -738,6 +738,7 @@ void Window::LoseFocus() { mnTicks = 0; vcl::Window::LoseFocus (); + GetViewShell()->onLoseFocus(); } /** @@ -747,6 +748,7 @@ void Window::GrabFocus() { mnTicks = 0; vcl::Window::GrabFocus (); + GetViewShell()->onGrabFocus(); } void Window::DataChanged( const DataChangedEvent& rDCEvt ) commit 8401681e8de550ec67c94d796cf9613f17bb4df9 Author: Samuel Mehrbrodt <samuel.mehrbr...@allotropia.de> AuthorDate: Thu Apr 11 11:24:22 2024 +0200 Commit: Thorsten Behrens <thorsten.behr...@allotropia.de> CommitDate: Wed May 1 15:00:33 2024 +0200 tdf#33603 Typo: 'Notes Panel' -> 'Notes Pane' Similiar to 'Slide Pane' Change-Id: If96afc4c054bbbff7c9bf8c5f4309e8eeb419d77 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166005 Tested-by: Jenkins Reviewed-by: Adolfo Jayme Barrientos <fit...@ubuntu.com> Reviewed-by: Sarper Akdemir <sarper.akdemir.ext...@allotropia.de> diff --git a/officecfg/registry/data/org/openoffice/Office/UI/DrawImpressCommands.xcu b/officecfg/registry/data/org/openoffice/Office/UI/DrawImpressCommands.xcu index 77b1987ecb6f..860761255ad6 100644 --- a/officecfg/registry/data/org/openoffice/Office/UI/DrawImpressCommands.xcu +++ b/officecfg/registry/data/org/openoffice/Office/UI/DrawImpressCommands.xcu @@ -26,7 +26,7 @@ </node> <node oor:name=".uno:BottomPaneImpress" oor:op="replace"> <prop oor:name="Label" oor:type="xs:string"> - <value xml:lang="en-US">Notes Panel</value> + <value xml:lang="en-US">Notes Pane</value> </prop> <prop oor:name="Properties" oor:type="xs:int"> <value>1</value> commit 944a92a98913766c2ed36f67f1e04c2bc8cb48da Author: Samuel Mehrbrodt <samuel.mehrbr...@allotropia.de> AuthorDate: Thu Apr 11 10:55:31 2024 +0200 Commit: Thorsten Behrens <thorsten.behr...@allotropia.de> CommitDate: Wed May 1 15:00:33 2024 +0200 tdf#33603 Allow adding Notes Panel to toolbar/menubar/keyboard shortcuts Change-Id: Ic3e8f6b5a0cc8697c62e8f10f69ff53859f33d3a Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166004 Tested-by: Jenkins Reviewed-by: Sarper Akdemir <sarper.akdemir.ext...@allotropia.de> diff --git a/sd/sdi/sdraw.sdi b/sd/sdi/sdraw.sdi index e8affd0db0fb..1077dc0c0b77 100644 --- a/sd/sdi/sdraw.sdi +++ b/sd/sdi/sdraw.sdi @@ -4385,9 +4385,9 @@ SfxBoolItem BottomPaneImpress SID_BOTTOM_PANE_IMPRESS Asynchron; - AccelConfig = FALSE, - MenuConfig = FALSE, - ToolBoxConfig = FALSE, + AccelConfig = TRUE, + MenuConfig = TRUE, + ToolBoxConfig = TRUE, GroupId = SfxGroupId::View; ] commit 8e29e7feeaaabe106d04bbf6bb48c231f649715a Author: Samuel Mehrbrodt <samuel.mehrbr...@allotropia.de> AuthorDate: Thu Apr 11 10:55:01 2024 +0200 Commit: Thorsten Behrens <thorsten.behr...@allotropia.de> CommitDate: Wed May 1 15:00:32 2024 +0200 tdf#33603 Make notes panel available in readonly mode Change-Id: I2dd10802f3798b2e87833d3cd8ebd21366e0f546 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166003 Tested-by: Jenkins Reviewed-by: Sarper Akdemir <sarper.akdemir.ext...@allotropia.de> diff --git a/sd/sdi/sdraw.sdi b/sd/sdi/sdraw.sdi index cf13bb3f4d1a..e8affd0db0fb 100644 --- a/sd/sdi/sdraw.sdi +++ b/sd/sdi/sdraw.sdi @@ -4377,7 +4377,7 @@ SfxBoolItem BottomPaneImpress SID_BOTTOM_PANE_IMPRESS [ AutoUpdate = TRUE, FastCall = FALSE, - ReadOnlyDoc = FALSE, + ReadOnlyDoc = TRUE, Toggle = FALSE, Container = TRUE, RecordAbsolute = FALSE, commit 7e577d36c884da0b5a41b9f89d582565131034f4 Author: Sarper Akdemir <sarper.akdemir.ext...@allotropia.de> AuthorDate: Fri Apr 5 09:39:24 2024 +0300 Commit: Thorsten Behrens <thorsten.behr...@allotropia.de> CommitDate: Wed May 1 15:00:32 2024 +0200 related tdf#33603: sd: fix notespanel crash on drag and drop Change-Id: I067fd3f3eccd8e0fa0d13795f660fe43410b0aa3 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/165809 Tested-by: Jenkins Reviewed-by: Samuel Mehrbrodt <samuel.mehrbr...@allotropia.de> diff --git a/sd/source/ui/inc/NotesPanelView.hxx b/sd/source/ui/inc/NotesPanelView.hxx index 82b3631f3f50..810cddd6af71 100644 --- a/sd/source/ui/inc/NotesPanelView.hxx +++ b/sd/source/ui/inc/NotesPanelView.hxx @@ -85,6 +85,11 @@ public: virtual const OutlinerView* GetTextEditOutlinerView() const override { return &maOutlinerView; } virtual OutlinerView* GetTextEditOutlinerView() override { return &maOutlinerView; } + virtual sal_Int8 AcceptDrop(const AcceptDropEvent& rEvt, DropTargetHelper& rTargetHelper, + SdrLayerID nLayer) override; + virtual sal_Int8 ExecuteDrop(const ExecuteDropEvent& rEvt, ::sd::Window* pTargetWindow, + sal_uInt16 nPage, SdrLayerID nLayer) override; + DECL_LINK(StatusEventHdl, EditStatus&, void); DECL_LINK(EditModifiedHdl, LinkParamNone*, void); DECL_LINK(ModifyTimerHdl, Timer*, void); diff --git a/sd/source/ui/view/NotesPanelView.cxx b/sd/source/ui/view/NotesPanelView.cxx index 7aa10d0c1f31..2822a8df4c02 100644 --- a/sd/source/ui/view/NotesPanelView.cxx +++ b/sd/source/ui/view/NotesPanelView.cxx @@ -305,6 +305,16 @@ SvtScriptType NotesPanelView::GetScriptType() const return nScriptType; } +sal_Int8 NotesPanelView::AcceptDrop(const AcceptDropEvent&, DropTargetHelper&, SdrLayerID) +{ + return DND_ACTION_NONE; +} + +sal_Int8 NotesPanelView::ExecuteDrop(const ExecuteDropEvent&, ::sd::Window*, sal_uInt16, SdrLayerID) +{ + return DND_ACTION_NONE; +} + } // end of namespace sd /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ commit a38a7684df4b48e9c3ac3acb5b0108e775e41ed8 Author: Sarper Akdemir <sarper.akdemir.ext...@allotropia.de> AuthorDate: Fri Apr 5 09:23:55 2024 +0300 Commit: Thorsten Behrens <thorsten.behr...@allotropia.de> CommitDate: Wed May 1 15:00:32 2024 +0200 related tdf#33603: sd: force invalidate notespanel This is likely not the correct thing to do here, but is a working solution that fixes the view lagging behind the resize for now. Change-Id: I662e59cfd0f1259eeb10a49b6e9c5fd616afa7a0 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/165808 Tested-by: Jenkins Reviewed-by: Samuel Mehrbrodt <samuel.mehrbr...@allotropia.de> diff --git a/sd/source/ui/inc/NotesPanelView.hxx b/sd/source/ui/inc/NotesPanelView.hxx index 4bb94590acbb..82b3631f3f50 100644 --- a/sd/source/ui/inc/NotesPanelView.hxx +++ b/sd/source/ui/inc/NotesPanelView.hxx @@ -38,7 +38,6 @@ class NotesPanelView final : public ::sd::SimpleOutlinerView Idle aModifyIdle; SdrTextObj* mpTextObj = nullptr; - bool mbFirstPaint = true; bool mbIgnoreNotifications = false; /** stores the last used document color. diff --git a/sd/source/ui/view/NotesPanelView.cxx b/sd/source/ui/view/NotesPanelView.cxx index 49fa38a05d88..7aa10d0c1f31 100644 --- a/sd/source/ui/view/NotesPanelView.cxx +++ b/sd/source/ui/view/NotesPanelView.cxx @@ -149,16 +149,7 @@ void NotesPanelView::setNotesToDoc() 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; - } + maOutlinerView.Paint(rRect); } void NotesPanelView::Notify(SfxBroadcaster&, const SfxHint& rHint) @@ -227,7 +218,8 @@ void NotesPanelView::onResize() if (!aVisArea.IsEmpty()) // not when opening { - mrNotesPanelViewShell.InitWindows(Point(0, 0), aVisArea.GetSize(), aVisArea.TopLeft()); + mrNotesPanelViewShell.InitWindows(Point(0, 0), aVisArea.GetSize(), aVisArea.TopLeft(), + true); mrNotesPanelViewShell.UpdateScrollBars(); } } commit 0f1b0cef8d105f55af73770ed39c2e32da33542b Author: Sarper Akdemir <sarper.akdemir.ext...@allotropia.de> AuthorDate: Thu Apr 4 18:41:33 2024 +0300 Commit: Thorsten Behrens <thorsten.behr...@allotropia.de> CommitDate: Wed May 1 15:00:32 2024 +0200 related tdf#33603: fix notespanel missing outliner on mode change When MainViewShell changed editing mode, two EventMultipexerEvents arrive in succession - if while processing the first one links are reset, second one was ignored. Do not remove EventMultiplexer listener on FillOutliner() Change-Id: I9c41c823ca74574238d1199ed38f92d9c75a113e Reviewed-on: https://gerrit.libreoffice.org/c/core/+/165807 Tested-by: Jenkins Reviewed-by: Samuel Mehrbrodt <samuel.mehrbr...@allotropia.de> diff --git a/sd/source/ui/view/NotesPanelView.cxx b/sd/source/ui/view/NotesPanelView.cxx index 0cbc7149e8ae..49fa38a05d88 100644 --- a/sd/source/ui/view/NotesPanelView.cxx +++ b/sd/source/ui/view/NotesPanelView.cxx @@ -52,6 +52,9 @@ NotesPanelView::NotesPanelView(DrawDocShell& rDocSh, vcl::Window* pWindow, // fill Outliner with contents FillOutliner(); + mrNotesPanelViewShell.GetViewShellBase().GetEventMultiplexer()->AddEventListener( + LINK(this, NotesPanelView, EventMultiplexerListener)); + // TODO: UNDO // sd::UndoManager* pDocUndoMgr = dynamic_cast<sd::UndoManager*>(mpDocSh->GetUndoManager()); // if (pDocUndoMgr != nullptr) @@ -60,8 +63,10 @@ NotesPanelView::NotesPanelView(DrawDocShell& rDocSh, vcl::Window* pWindow, NotesPanelView::~NotesPanelView() { - ResetLinks(); + mrNotesPanelViewShell.GetViewShellBase().GetEventMultiplexer()->RemoveEventListener( + LINK(this, NotesPanelView, EventMultiplexerListener)); + ResetLinks(); // DisconnectFromApplication(); // mpProgress.reset(); } @@ -93,16 +98,9 @@ void NotesPanelView::FillOutliner() 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::ResetLinks() { maOutliner.SetStatusEventHdl(Link<EditStatus&, void>()); } void NotesPanelView::removeListener() { commit 587a3e995fce280f89e71ce6b7be956713e38a04 Author: Sarper Akdemir <sarper.akdemir.ext...@allotropia.de> AuthorDate: Thu Nov 9 20:18:44 2023 +0300 Commit: Thorsten Behrens <thorsten.behr...@allotropia.de> CommitDate: Wed May 1 15:00:32 2024 +0200 tdf#33603: introduce reworked notes panel this commit is the squash of the four commits below instead of introducing the initial NotesPanel implementation and then deleting the left-over implementation (at commit ede2f1e6eefbc6471f0163c21430c2f747bb0e67 on master) provides all the relevant notes panel new implementation patches into one. ===== tdf#33603: sd: add notes panel for normal view Reviewed-on: https://gerrit.libreoffice.org/c/core/+/159288 Tested-by: Jenkins Reviewed-by: Thorsten Behrens <thorsten.behr...@allotropia.de> related tdf#33603: do not register NotesChildWindow for Draw Draw doesn't need the notes panel introduced in c4c1ca58bb587a56a30c7f4817c346054ce37f2a, so don't register that for it's shell (GraphicViewShell). Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163775 Tested-by: Jenkins Reviewed-by: Thorsten Behrens <thorsten.behr...@allotropia.de> 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. Reviewed-on: https://gerrit.libreoffice.org/c/core/+/165770 Tested-by: Jenkins Reviewed-by: Samuel Mehrbrodt <samuel.mehrbr...@allotropia.de> tdf#33603 Fix Close button not working in Notes Pane Remove duplicate command and now unused NotesChildWindow Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166002 Tested-by: Jenkins Reviewed-by: Sarper Akdemir <sarper.akdemir.ext...@allotropia.de> ===== Change-Id: Ifea0921b59635611656783ef14ed1a399d84fc7a diff --git a/include/svx/svdedxv.hxx b/include/svx/svdedxv.hxx index 6c6a37f108a7..17d167d0e82c 100644 --- a/include/svx/svdedxv.hxx +++ b/include/svx/svdedxv.hxx @@ -253,19 +253,19 @@ public: // Now at this outliner, events can be send, attributes can be set, // call Cut/Copy/Paste, call Undo/Redo, and so on... - const SdrOutliner* GetTextEditOutliner() const + virtual const SdrOutliner* GetTextEditOutliner() const { return mpTextEditOutliner.get(); } - SdrOutliner* GetTextEditOutliner() + virtual SdrOutliner* GetTextEditOutliner() { return mpTextEditOutliner.get(); } - const OutlinerView* GetTextEditOutlinerView() const + virtual const OutlinerView* GetTextEditOutlinerView() const { return mpTextEditOutlinerView; } - OutlinerView* GetTextEditOutlinerView() + virtual OutlinerView* GetTextEditOutlinerView() { return mpTextEditOutlinerView; } diff --git a/officecfg/registry/data/org/openoffice/Office/UI/DrawImpressCommands.xcu b/officecfg/registry/data/org/openoffice/Office/UI/DrawImpressCommands.xcu index 6de8e0058a52..77b1987ecb6f 100644 --- a/officecfg/registry/data/org/openoffice/Office/UI/DrawImpressCommands.xcu +++ b/officecfg/registry/data/org/openoffice/Office/UI/DrawImpressCommands.xcu @@ -24,6 +24,14 @@ <value xml:lang="en-US">S~lide</value> </prop> </node> + <node oor:name=".uno:BottomPaneImpress" oor:op="replace"> + <prop oor:name="Label" oor:type="xs:string"> + <value xml:lang="en-US">Notes Panel</value> + </prop> + <prop oor:name="Properties" oor:type="xs:int"> + <value>1</value> + </prop> + </node> <node oor:name=".uno:PageMenu" oor:op="replace"> <prop oor:name="Label" oor:type="xs:string"> <value xml:lang="en-US">~Page</value> diff --git a/sd/Library_sd.mk b/sd/Library_sd.mk index 01c546ad3dca..b633ee26f7d6 100644 --- a/sd/Library_sd.mk +++ b/sd/Library_sd.mk @@ -515,6 +515,8 @@ $(eval $(call gb_Library_add_exception_objects,sd,\ sd/source/ui/view/viewshe3 \ sd/source/ui/view/viewshel \ sd/source/ui/view/zoomlist \ + sd/source/ui/view/NotesPanelView \ + sd/source/ui/view/NotesPanelViewShell \ )) ifeq ($(ENABLE_SDREMOTE),TRUE) diff --git a/sd/UIConfig_simpress.mk b/sd/UIConfig_simpress.mk index 9d98d611de82..ee778eaeb91a 100644 --- a/sd/UIConfig_simpress.mk +++ b/sd/UIConfig_simpress.mk @@ -148,6 +148,8 @@ $(eval $(call gb_UIConfig_add_uifiles,modules/simpress,\ sd/uiconfig/simpress/ui/notebookbar_groupedbar_full \ sd/uiconfig/simpress/ui/notebookbar_groupedbar_compact \ sd/uiconfig/simpress/ui/notebookbar_online \ + sd/uiconfig/simpress/ui/noteschildwindow \ + sd/uiconfig/simpress/ui/notespanelcontextmenu \ sd/uiconfig/simpress/ui/optimpressgeneralpage \ sd/uiconfig/simpress/ui/pagesfieldbox \ sd/uiconfig/simpress/ui/photoalbum \ diff --git a/sd/inc/app.hrc b/sd/inc/app.hrc index e275e4688258..e17fb0b6eba1 100644 --- a/sd/inc/app.hrc +++ b/sd/inc/app.hrc @@ -421,8 +421,7 @@ #define SID_LEFT_PANE_IMPRESS (SID_SD_START+414) #define SID_LEFT_PANE_DRAW (SID_SD_START+415) - // FREE -#define SID_NOTES_WINDOW (SID_SD_START+417) +#define SID_BOTTOM_PANE_IMPRESS (SID_SD_START+416) // FREE #define SID_NORMAL_MULTI_PANE_GUI TypedWhichId<SfxBoolItem>(SID_SD_START+420) #define SID_SLIDE_SORTER_MULTI_PANE_GUI (SID_SD_START+421) diff --git a/sd/inc/glob.hxx b/sd/inc/glob.hxx index a6ddf50705e5..ad4ce9f3584c 100644 --- a/sd/inc/glob.hxx +++ b/sd/inc/glob.hxx @@ -39,6 +39,8 @@ #define SD_IF_SDDRAWTABLEOBJECTBAR SFX_INTERFACE_SD_START + SfxInterfaceId(27) #define SD_IF_SDTOOLPANELPANESHELL SFX_INTERFACE_SD_START + SfxInterfaceId(29) #define SD_IF_SDTOOLPANELSHELL SFX_INTERFACE_SD_START + SfxInterfaceId(30) +#define SD_IF_SDBOTTOMIMPRESSPANESHELL SFX_INTERFACE_SD_START + SfxInterfaceId(31) +#define SD_IF_SDNOTESPANELVIEWSHELL SFX_INTERFACE_SD_START + SfxInterfaceId(32) // Object-Ids for StarDraw UserData diff --git a/sd/inc/strings.hrc b/sd/inc/strings.hrc index d449ccf01cbe..64c3abdde805 100644 --- a/sd/inc/strings.hrc +++ b/sd/inc/strings.hrc @@ -287,6 +287,7 @@ #define STR_PRESOBJ_OUTLINE NC_("STR_PRESOBJ_OUTLINE", "Click to add Text" ) #define STR_PRESOBJ_TEXT NC_("STR_PRESOBJ_TEXT", "Click to add Text" ) #define STR_PRESOBJ_NOTESTEXT NC_("STR_PRESOBJ_NOTESTEXT", "Click to add Notes" ) +#define STR_PRESOBJ_NOTESTEXT_MISSING NC_("STR_PRESOBJ_NOTESTEXT_MISSING", "Notes placeholder object is missing for the current slide." ) #define STR_PRESOBJ_TITLE_MOBILE NC_("STR_PRESOBJ_TITLE_MOBILE", "Double-tap to add Title" ) #define STR_PRESOBJ_OUTLINE_MOBILE NC_("STR_PRESOBJ_OUTLINE_MOBILE", "Double-tap to add Text" ) #define STR_PRESOBJ_TEXT_MOBILE NC_("STR_PRESOBJ_TEXT_MOBILE", "Double-tap to add Text" ) diff --git a/sd/sdi/NotesPanelView.sdi b/sd/sdi/NotesPanelView.sdi new file mode 100644 index 000000000000..90217efaa4e8 --- /dev/null +++ b/sd/sdi/NotesPanelView.sdi @@ -0,0 +1,514 @@ +/* + * 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/. + */ + +interface NotesPanelView +{ + SID_CUT // ole : no, status : ? + [ + ExecMethod = FuSupport ; + StateMethod = GetMenuState ; + ] + SID_COPY // ole : no, status : ? + [ + ExecMethod = FuSupport ; + StateMethod = GetMenuState ; + ] + SID_PASTE // ole : no, status : ? + [ + ExecMethod = FuSupport ; + StateMethod = GetMenuState ; + ] + SID_PASTE_UNFORMATTED // ole : no, status : ? + [ + ExecMethod = FuSupport ; + StateMethod = GetMenuState ; + ] + SID_DELETE // ole : no, status : ? + [ + ExecMethod = FuSupport ; + StateMethod = GetMenuState ; + Asynchron ; + ] + SID_DRAWINGMODE // ole : no, status : play rec + [ + ExecMethod = FuSupport ; + StateMethod = GetMenuState ; + ] + SID_ZOOM_NEXT // ole : no, status : play rec + [ + ExecMethod = FuSupport ; + StateMethod = GetMenuState ; + ] + SID_ZOOM_PREV // ole : no, status : play rec + [ + ExecMethod = FuSupport ; + StateMethod = GetMenuState ; + ] + SID_ZOOM_TOOLBOX // ole : no, status : ? + [ + ExecMethod = FuTemporary ; + StateMethod = GetStatusBarState ; + ] + SID_ATTR_ZOOM // ole : no, status : ? + [ + ExecMethod = FuTemporary ; + StateMethod = GetStatusBarState ; + ] + SID_ATTR_ZOOMSLIDER // status() + [ + ExecMethod = FuTemporary ; + StateMethod = GetStatusBarState ; + ] + SID_ZOOM_OUT // ole : no, status : play rec + [ + ExecMethod = FuTemporary ; + StateMethod = GetMenuState ; + ] + SID_ZOOM_IN // ole : no, status : play rec + [ + ExecMethod = FuTemporary ; + StateMethod = GetMenuState ; + ] + SID_SIZE_REAL // ole : no, status : play rec + [ + ExecMethod = FuTemporary ; + StateMethod = GetMenuState ; + ] + SID_SIZE_VISAREA // ole : no, status : no + [ + ExecMethod = FuTemporary ; + StateMethod = GetMenuState ; + ] + SID_HYPERLINK_SETLINK // ole : no, status : no + [ + ExecMethod = FuTemporaryModify ; + ] + SID_HYPERLINK_GETLINK // ole : no, status : no + [ + StateMethod = GetCtrlState ; + ] + SID_READONLY_MODE // ole : no, status : no + [ + StateMethod = GetCtrlState ; + ] + SID_CHARMAP // ole : no, status : ? + [ + ExecMethod = FuTemporaryModify ; + StateMethod = GetMenuState ; + ] + SID_CHARMAP_CONTROL // ole : no, status : ? + [ + ExecMethod = FuTemporaryModify ; + StateMethod = GetMenuState ; + ] + FN_INSERT_SOFT_HYPHEN // status(final|play) + [ + ExecMethod = FuTemporaryModify ; + StateMethod = GetMenuState ; + ] + FN_INSERT_HARDHYPHEN // status() + [ + ExecMethod = FuTemporaryModify ; + StateMethod = GetMenuState ; + ] + FN_INSERT_HARD_SPACE // status(final|play) + [ + ExecMethod = FuTemporaryModify ; + StateMethod = GetMenuState ; + ] + FN_INSERT_NNBSP // status(final|play) + [ + ExecMethod = FuTemporaryModify ; + StateMethod = GetMenuState ; + ] + SID_INSERT_RLM + [ + ExecMethod = FuTemporary ; + StateMethod = GetMenuState ; + ] + SID_INSERT_LRM + [ + ExecMethod = FuTemporaryModify ; + StateMethod = GetMenuState ; + ] + SID_INSERT_ZWSP + [ + ExecMethod = FuTemporaryModify ; + StateMethod = GetMenuState ; + ] + SID_INSERT_WJ + [ + ExecMethod = FuTemporaryModify ; + StateMethod = GetMenuState ; + ] + FN_SVX_SET_BULLET + [ + ExecMethod = FuTemporaryModify ; + ] + FN_SVX_SET_NUMBER + [ + ExecMethod = FuTemporaryModify ; + ] + SID_OUTLINE_BULLET // ole : no, status : ? + [ + ExecMethod = FuTemporaryModify ; + StateMethod = GetMenuState ; + ] + SID_CHAR_DLG // ole : no, status : ? + [ + ExecMethod = FuTemporaryModify ; + StateMethod = GetMenuState ; + ] + SID_CHAR_DLG_EFFECT // wj for sym2_1876 + [ + ExecMethod = FuTemporaryModify ; + StateMethod = GetMenuState ; + ] + SID_SELECTALL // ole : no, status : ? + [ + ExecMethod = FuTemporary ; + StateMethod = GetMenuState ; + GroupId = SfxGroupId::Document ; + ] + SID_INSERTFILE // ole : no, status : ? + [ + ExecMethod = FuTemporaryModify ; + StateMethod = GetMenuState ; + ] + SID_PRESENTATION // ole : no, status : ? + [ + ExecMethod = FuTemporary ; + StateMethod = GetMenuState ; + ] + SID_PRESENTATION_CURRENT_SLIDE // ole : no, status : ? + [ + ExecMethod = FuTemporary ; + StateMethod = GetMenuState ; + ] + SID_EDIT_OUTLINER // ole : no, status : ? + [ + ExecMethod = FuPermanent ; + StateMethod = GetMenuState ; + ] + SID_SAVEDOC // ole : no, status : ? + [ + ExecMethod = Execute ; + StateMethod = GetMenuState ; + GroupId = SfxGroupId::Document ; + ] + SID_SAVEASDOC // ole : no, status : ? + [ + ExecMethod = Execute ; + GroupId = SfxGroupId::Document ; + ] + SID_RULER // ole : no, status : ? + [ + ExecMethod = FuSupport ; + StateMethod = GetMenuState ; + ] + SID_STATUS_PAGE // ole : no, status : ? + [ + ExecMethod = ExecStatusBar ; + StateMethod = GetStatusBarState ; + ] + SID_STATUS_LAYOUT // ole : no, status : ? + [ + ExecMethod = ExecStatusBar ; + StateMethod = GetStatusBarState ; + ] + SID_SCALE // ole : no, status : ? + [ + ExecMethod = ExecStatusBar ; + StateMethod = GetStatusBarState ; + ] + SID_THESAURUS // ole : no, status : ? + [ + ExecMethod = FuTemporaryModify ; + StateMethod = GetMenuState ; + ] + SID_SET_DEFAULT // ole : no, status : ? + [ + ExecMethod = FuTemporaryModify ; + StateMethod = GetMenuState ; + ] + SID_PRESENTATIONOBJECT + [ + ExecMethod = FuTemporaryModify ; + StateMethod = GetMenuState ; + ] + // Templates + // no menu entry + SID_STYLE_FAMILY2 // ole : no, status : ? + [ + ExecMethod = FuTemporary ; + StateMethod = GetAttrState ; + GroupId = SfxGroupId::Document ; + ] + SID_STYLE_FAMILY3 // ole : no, status : ? + [ + ExecMethod = FuTemporary ; + StateMethod = GetAttrState ; + GroupId = SfxGroupId::Document ; + ] + // Templates + // no menu entry + SID_STYLE_FAMILY5 // ole : no, status : ? + [ + ExecMethod = FuTemporary ; + StateMethod = GetAttrState ; + ] + // no menu entry + SID_STYLE_EDIT // ole : no, status : ? + [ + ExecMethod = FuTemporary ; + StateMethod = GetAttrState ; + GroupId = SfxGroupId::Document ; + ] + // no menu entry + SID_STYLE_UPDATE_BY_EXAMPLE // ole : no, status : ? + [ + ExecMethod = FuTemporary ; + StateMethod = GetAttrState ; + GroupId = SfxGroupId::Document ; + ] + // no menu entry + SID_STYLE_WATERCAN // ole : no, status : ? + [ + ExecMethod = FuTemporary ; + StateMethod = GetAttrState ; + GroupId = SfxGroupId::Document ; + ] + // no menu entry + SID_STYLE_NEW_BY_EXAMPLE // ole : no, status : ? + [ + ExecMethod = FuTemporary ; + StateMethod = GetAttrState ; + GroupId = SfxGroupId::Document ; + ] + // no menu entry + SID_STYLE_NEW // ole : no, status : ? + [ + ExecMethod = FuTemporary ; + StateMethod = GetAttrState ; + GroupId = SfxGroupId::Document ; + ] + // no menu entry + SID_STYLE_DELETE // ole : no, status : ? + [ + ExecMethod = FuTemporary ; + StateMethod = GetAttrState ; + GroupId = SfxGroupId::Document ; + ] + SID_STYLE_HIDE + [ + ExecMethod = FuTemporary ; + StateMethod = GetAttrState ; + GroupId = SfxGroupId::Document ; + ] + SID_STYLE_SHOW + [ + ExecMethod = FuTemporary ; + StateMethod = GetAttrState ; + GroupId = SfxGroupId::Document ; + ] + SID_AUTOSPELL_CHECK // ole : no, status : play rec + [ + ExecMethod = FuSupport ; + StateMethod = GetMenuState ; + ] + SID_PREVIEW_STATE // ole : no, status : ? + [ + ExecMethod = FuTemporary ; + StateMethod = GetMenuState ; + ] + SID_PRESENTATION_DLG + [ + ExecMethod = FuTemporary ; + ] + SID_REMOTE_DLG + [ + ExecMethod = FuTemporary ; + StateMethod = GetMenuState ; + ] + SID_CUSTOMSHOW_DLG + [ + ExecMethod = FuTemporary ; + ] + SID_EXPAND_PAGE // ole : no, status : ? + [ + ExecMethod = FuTemporaryModify ; + StateMethod = GetMenuState ; + ] + SID_SUMMARY_PAGE // ole : no, status : ? + [ + ExecMethod = FuTemporaryModify ; + StateMethod = GetMenuState ; + ] + SID_INSERT_FLD_DATE_FIX // ole : no, status : play rec + [ + ExecMethod = FuTemporaryModify ; + StateMethod = GetMenuState ; + ] + SID_INSERT_FLD_DATE_VAR // ole : no, status : play rec + [ + ExecMethod = FuTemporaryModify ; + StateMethod = GetMenuState ; + ] + SID_INSERT_FLD_TIME_FIX // ole : no, status : play rec + [ + ExecMethod = FuTemporaryModify ; + StateMethod = GetMenuState ; + ] + SID_INSERT_FLD_TIME_VAR // ole : no, status : play rec + [ + ExecMethod = FuTemporaryModify ; + StateMethod = GetMenuState ; + ] + SID_INSERT_FLD_PAGE_TITLE // ole : no, status : play rec + [ + ExecMethod = FuTemporaryModify ; + StateMethod = GetMenuState ; + ] + SID_INSERT_FLD_PAGE // ole : no, status : play rec + [ + ExecMethod = FuTemporaryModify ; + StateMethod = GetMenuState ; + ] + SID_INSERT_FLD_PAGES // ole : no, status : play rec + [ + ExecMethod = FuTemporaryModify ; + StateMethod = GetMenuState ; + ] + SID_INSERT_FLD_FILE // ole : no, status : play rec + [ + ExecMethod = FuTemporaryModify ; + StateMethod = GetMenuState ; + ] + SID_INSERT_FLD_AUTHOR // ole : no, status : play rec + [ + ExecMethod = FuTemporaryModify ; + StateMethod = GetMenuState ; + ] + SID_MODIFY_FIELD // ole : no, status : play rec + [ + ExecMethod = FuTemporaryModify ; + StateMethod = GetMenuState ; + ] + + SID_MAIL_SCROLLBODY_PAGEDOWN // ole : no, status : ? + [ + ExecMethod = ExecCtrl ; + StateMethod = GetCtrlState ; + ] + SID_STYLE_FAMILY + [ + ExecMethod = FuSupport ; + StateMethod = GetMenuState ; + ] + SID_TRANSLITERATE_SENTENCE_CASE // ole : no, status : ? + [ + ExecMethod = FuSupport ; + StateMethod = GetCtrlState ; + ] + SID_TRANSLITERATE_TITLE_CASE // ole : no, status : ? + [ + ExecMethod = FuSupport ; + StateMethod = GetCtrlState ; + ] + SID_TRANSLITERATE_TOGGLE_CASE // ole : no, status : ? + [ + ExecMethod = FuSupport ; + StateMethod = GetCtrlState ; + ] + SID_TRANSLITERATE_UPPER // ole : no, status : ? + [ + ExecMethod = FuSupport ; + StateMethod = GetCtrlState ; + ] + SID_TRANSLITERATE_LOWER // ole : no, status : ? + [ + ExecMethod = FuSupport ; + StateMethod = GetCtrlState ; + ] + SID_TRANSLITERATE_HALFWIDTH // ole : no, status : ? + [ + ExecMethod = FuSupport ; + StateMethod = GetCtrlState ; + ] + SID_TRANSLITERATE_FULLWIDTH // ole : no, status : ? + [ + ExecMethod = FuSupport ; + StateMethod = GetCtrlState ; + ] + SID_TRANSLITERATE_HIRAGANA // ole : no, status : ? + [ + ExecMethod = FuSupport ; + StateMethod = GetCtrlState ; + ] + SID_TRANSLITERATE_KATAKANA // ole : no, status : ? + [ + ExecMethod = FuSupport ; + StateMethod = GetCtrlState ; + ] + SID_OPT_LOCALE_CHANGED // ole : no, status : ? + [ + ExecMethod = ExecCtrl ; + StateMethod = GetCtrlState ; + ] + + SID_GETUNDOSTRINGS // ole : no, status : ? + [ + ExecMethod = FuSupport ; + StateMethod = GetMenuState ; + ] + SID_UNDO // ole : no, status : ? + [ + ExecMethod = FuSupport ; + StateMethod = GetMenuState ; + ] + SID_GETREDOSTRINGS // ole : no, status : ? + [ + ExecMethod = FuSupport ; + StateMethod = GetMenuState ; + ] + SID_REDO // ole : no, status : ? + [ + ExecMethod = FuSupport ; + StateMethod = GetMenuState ; + ] + + SID_SEARCH_OPTIONS // ole : ?, status : ? + [ + ExecMethod = Execute ; + StateMethod = GetState ; + GroupId = SfxGroupId::Document ; + ] + SID_SEARCH_ITEM // ole : ?, status : ? + [ + ExecMethod = Execute ; + StateMethod = GetState ; + ] + SID_SPELL_DIALOG // ole : no, status : ? + [ + ExecMethod = Execute ; + StateMethod = GetMenuState ; + ] + SID_PHOTOALBUM + [ + ExecMethod = FuTemporary ; + StateMethod = GetMenuState ; + ] +} + +include "drtxtob.sdi" + +shell NotesPanelViewShell +{ + import NotesPanelView; + import TextObjectBar; +} diff --git a/sd/sdi/ViewShellBase.sdi b/sd/sdi/ViewShellBase.sdi index f39368368f1d..f196e549ba25 100644 --- a/sd/sdi/ViewShellBase.sdi +++ b/sd/sdi/ViewShellBase.sdi @@ -32,7 +32,7 @@ interface ViewShellBaseView ExecMethod = Execute; StateMethod = GetState; ] - SID_NOTES_WINDOW + SID_BOTTOM_PANE_IMPRESS [ ExecMethod = Execute; StateMethod = GetState; diff --git a/sd/sdi/sdraw.sdi b/sd/sdi/sdraw.sdi index 7bb752c687ac..cf13bb3f4d1a 100644 --- a/sd/sdi/sdraw.sdi +++ b/sd/sdi/sdraw.sdi @@ -4372,7 +4372,7 @@ SfxBoolItem LeftPaneDraw SID_LEFT_PANE_DRAW GroupId = SfxGroupId::Modify; ] -SfxVoidItem NotesChildWindow SID_NOTES_WINDOW +SfxBoolItem BottomPaneImpress SID_BOTTOM_PANE_IMPRESS [ AutoUpdate = TRUE, diff --git a/sd/sdi/sdslots.sdi b/sd/sdi/sdslots.sdi index 751c09901fa8..95ed6d6ab152 100644 --- a/sd/sdi/sdslots.sdi +++ b/sd/sdi/sdslots.sdi @@ -88,4 +88,5 @@ module StarDraw include "ViewShellBase.sdi" include "mediaob.sdi" include "tables.sdi" + include "NotesPanelView.sdi" } diff --git a/sd/source/ui/app/sddll.cxx b/sd/source/ui/app/sddll.cxx index b4734310a39b..8ede1234dffe 100644 --- a/sd/source/ui/app/sddll.cxx +++ b/sd/source/ui/app/sddll.cxx @@ -176,6 +176,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); DevelopmentToolChildWindow::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 e112ac4c315a..5700de9583bd 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, @@ -368,6 +375,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 03625257ebee..9892540c03aa 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/GraphicViewShellBase.cxx b/sd/source/ui/view/GraphicViewShellBase.cxx index a3f8ece26c11..72df33e98f2e 100644 --- a/sd/source/ui/view/GraphicViewShellBase.cxx +++ b/sd/source/ui/view/GraphicViewShellBase.cxx @@ -61,7 +61,7 @@ void GraphicViewShellBase::Execute(SfxRequest& rRequest) switch (nSlotId) { - case SID_NOTES_WINDOW: + case SID_BOTTOM_PANE_IMPRESS: case SID_SLIDE_SORTER_MULTI_PANE_GUI: case SID_SLIDE_SORTER_MODE: case SID_SLIDE_MASTER_MODE: 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: -e ... etc. - the rest is truncated