diff options
author | Caolán McNamara <caolanm@redhat.com> | 2021-02-09 12:07:27 +0000 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2021-02-12 17:22:14 +0100 |
commit | a39a3f1ad1e5e39b09ce474c0f4c0f9f4e174bbe (patch) | |
tree | 35c36f536d5eea1f6296c37f5f161e9b96f64794 | |
parent | 1e3198931e6e230791e863272082c1d437975008 (diff) |
weld impress annotation window
Change-Id: Idc89f4e382392103d373b6a84edaae10abd56056
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/110650
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
-rw-r--r-- | include/vcl/weld.hxx | 2 | ||||
-rw-r--r-- | sd/UIConfig_simpress.mk | 2 | ||||
-rw-r--r-- | sd/source/ui/annotations/annotationmanager.cxx | 150 | ||||
-rw-r--r-- | sd/source/ui/annotations/annotationmanagerimpl.hxx | 7 | ||||
-rw-r--r-- | sd/source/ui/annotations/annotationtag.cxx | 60 | ||||
-rw-r--r-- | sd/source/ui/annotations/annotationtag.hxx | 2 | ||||
-rw-r--r-- | sd/source/ui/annotations/annotationwindow.cxx | 860 | ||||
-rw-r--r-- | sd/source/ui/annotations/annotationwindow.hxx | 158 | ||||
-rw-r--r-- | sd/uiconfig/simpress/ui/annotation.ui | 164 | ||||
-rw-r--r-- | sd/uiconfig/simpress/ui/annotationmenu.ui | 117 | ||||
-rw-r--r-- | sd/uiconfig/simpress/ui/annotationtagmenu.ui | 10 | ||||
-rw-r--r-- | solenv/sanitizers/ui/modules/simpress.suppr | 1 | ||||
-rw-r--r-- | sw/source/uibase/docvw/AnnotationWin.cxx | 1 | ||||
-rw-r--r-- | sw/source/uibase/docvw/AnnotationWin2.cxx | 8 | ||||
-rw-r--r-- | vcl/inc/salvtables.hxx | 2 | ||||
-rw-r--r-- | vcl/source/app/salvtables.cxx | 10 | ||||
-rw-r--r-- | vcl/unx/gtk3/gtk3gtkinst.cxx | 6 |
17 files changed, 769 insertions, 791 deletions
diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx index c33bd97a098a..29f20ffef966 100644 --- a/include/vcl/weld.hxx +++ b/include/vcl/weld.hxx @@ -2220,7 +2220,7 @@ public: virtual void insert(int pos, const OUString& rId, const OUString& rStr, const OUString* pIconName, VirtualDevice* pImageSurface, - const css::uno::Reference<css::graphic::XGraphic>* pImage, + const css::uno::Reference<css::graphic::XGraphic>& rImage, TriState eCheckRadioFalse) = 0; diff --git a/sd/UIConfig_simpress.mk b/sd/UIConfig_simpress.mk index 92d12d7ecc5c..d6b96e034661 100644 --- a/sd/UIConfig_simpress.mk +++ b/sd/UIConfig_simpress.mk @@ -104,7 +104,7 @@ $(eval $(call gb_UIConfig_add_toolbarfiles,modules/simpress,\ )) $(eval $(call gb_UIConfig_add_uifiles,modules/simpress,\ - sd/uiconfig/simpress/ui/annotationmenu \ + sd/uiconfig/simpress/ui/annotation \ sd/uiconfig/simpress/ui/annotationtagmenu \ sd/uiconfig/simpress/ui/clientboxfragment \ sd/uiconfig/simpress/ui/currentmastermenu \ diff --git a/sd/source/ui/annotations/annotationmanager.cxx b/sd/source/ui/annotations/annotationmanager.cxx index d72dba3d8181..7bb4a0857968 100644 --- a/sd/source/ui/annotations/annotationmanager.cxx +++ b/sd/source/ui/annotations/annotationmanager.cxx @@ -168,7 +168,6 @@ AnnotationManagerImpl::AnnotationManagerImpl( ViewShellBase& rViewShellBase ) , mrBase( rViewShellBase ) , mpDoc( rViewShellBase.GetDocument() ) , mbShowAnnotations( true ) -, mbPopupMenuActive( false ) , mnUpdateTagsEvent( nullptr ) { SdOptions* pOptions = SD_MOD()->GetSdOptions(mpDoc->GetDocumentType()); @@ -1036,35 +1035,7 @@ IMPL_LINK(AnnotationManagerImpl,EventMultiplexerListener, } } -namespace -{ - sal_uInt16 IdentToSID(std::string_view rIdent) - { - if (rIdent == "reply") - return SID_REPLYTO_POSTIT; - else if (rIdent == "delete") - return SID_DELETE_POSTIT; - else if (rIdent == "deleteby") - return SID_DELETEALLBYAUTHOR_POSTIT; - else if (rIdent == "deleteall") - return SID_DELETEALL_POSTIT; - else if (rIdent == "copy") - return SID_COPY; - else if (rIdent == "paste") - return SID_PASTE; - else if (rIdent == "bold") - return SID_ATTR_CHAR_WEIGHT; - else if (rIdent == "italic") - return SID_ATTR_CHAR_POSTURE; - else if (rIdent == "underline") - return SID_ATTR_CHAR_UNDERLINE; - else if (rIdent == "strike") - return SID_ATTR_CHAR_STRIKEOUT; - return 0; - } -} - -void AnnotationManagerImpl::ExecuteAnnotationContextMenu( const Reference< XAnnotation >& xAnnotation, vcl::Window* pParent, const ::tools::Rectangle& rContextRect, bool bButtonMenu /* = false */ ) +void AnnotationManagerImpl::ExecuteAnnotationTagContextMenu(const Reference<XAnnotation>& xAnnotation, weld::Widget* pParent, const ::tools::Rectangle& rContextRect) { SfxDispatcher* pDispatcher( getDispatcher( mrBase ) ); if( !pDispatcher ) @@ -1072,141 +1043,50 @@ void AnnotationManagerImpl::ExecuteAnnotationContextMenu( const Reference< XAnno const bool bReadOnly = mrBase.GetDocShell()->IsReadOnly(); - AnnotationWindow* pAnnotationWindow = bButtonMenu ? nullptr : dynamic_cast< AnnotationWindow* >( pParent ); - - if( bReadOnly && !pAnnotationWindow ) + if (bReadOnly) return; - OUString sUIFile; - if (pAnnotationWindow) - sUIFile = "modules/simpress/ui/annotationmenu.ui"; - else - sUIFile = "modules/simpress/ui/annotationtagmenu.ui"; - VclBuilder aBuilder(nullptr, AllSettings::GetUIRootDir(), sUIFile, ""); - VclPtr<PopupMenu> pMenu(aBuilder.get_menu("menu")); + std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(pParent, "modules/simpress/ui/annotationtagmenu.ui")); + std::unique_ptr<weld::Menu> xMenu(xBuilder->weld_menu("menu")); SvtUserOptions aUserOptions; OUString sCurrentAuthor( aUserOptions.GetFullName() ); OUString sAuthor( xAnnotation->getAuthor() ); - OUString aStr(pMenu->GetItemText(pMenu->GetItemId("deleteby"))); + OUString aStr(xMenu->get_label(".uno:DeleteAllAnnotationByAuthor")); OUString aReplace( sAuthor ); if( aReplace.isEmpty() ) aReplace = SdResId( STR_ANNOTATION_NOAUTHOR ); aStr = aStr.replaceFirst("%1", aReplace); - pMenu->SetItemText(pMenu->GetItemId("deleteby"), aStr); - pMenu->EnableItem(pMenu->GetItemId("reply"), (sAuthor != sCurrentAuthor) && !bReadOnly); - pMenu->EnableItem(pMenu->GetItemId("delete"), xAnnotation.is() && !bReadOnly); - pMenu->EnableItem(pMenu->GetItemId("deleteby"), !bReadOnly); - pMenu->EnableItem(pMenu->GetItemId("deleteall"), !bReadOnly); - - if( pAnnotationWindow ) - { - if( pAnnotationWindow->IsProtected() || bReadOnly ) - { - pMenu->EnableItem(pMenu->GetItemId("bold"), false); - pMenu->EnableItem(pMenu->GetItemId("italic"), false); - pMenu->EnableItem(pMenu->GetItemId("underline"), false); - pMenu->EnableItem(pMenu->GetItemId("strike"), false); - pMenu->EnableItem(pMenu->GetItemId("paste"), false); - } - else - { - SfxItemSet aSet(pAnnotationWindow->getView()->GetAttribs()); - - if ( aSet.GetItemState( EE_CHAR_WEIGHT ) == SfxItemState::SET ) - { - if( aSet.Get( EE_CHAR_WEIGHT ).GetWeight() == WEIGHT_BOLD ) - pMenu->CheckItem("bold"); - } - - if ( aSet.GetItemState( EE_CHAR_ITALIC ) == SfxItemState::SET ) - { - if( aSet.Get( EE_CHAR_ITALIC ).GetPosture() != ITALIC_NONE ) - pMenu->CheckItem("italic"); - - } - if ( aSet.GetItemState( EE_CHAR_UNDERLINE ) == SfxItemState::SET ) - { - if( aSet.Get( EE_CHAR_UNDERLINE ).GetLineStyle() != LINESTYLE_NONE ) - pMenu->CheckItem("underline"); - } - - if ( aSet.GetItemState( EE_CHAR_STRIKEOUT ) == SfxItemState::SET ) - { - if( aSet.Get( EE_CHAR_STRIKEOUT ).GetStrikeout() != STRIKEOUT_NONE ) - pMenu->CheckItem("strike"); - } - TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pAnnotationWindow ) ); - pMenu->EnableItem(pMenu->GetItemId("paste"), aDataHelper.GetFormatCount() != 0); - } - - pMenu->EnableItem(pMenu->GetItemId("copy"), pAnnotationWindow->getView()->HasSelection()); - } - - // set slot images - Reference< css::frame::XFrame > xFrame( mrBase.GetMainViewShell()->GetViewFrame()->GetFrame().GetFrameInterface() ); - if( xFrame.is() ) - { - for( sal_uInt16 nPos = 0; nPos < pMenu->GetItemCount(); nPos++ ) - { - sal_uInt16 nId = pMenu->GetItemId( nPos ); - if (!pMenu->IsItemEnabled(nId)) - continue; - - Image aImage( vcl::CommandInfoProvider::GetImageForCommand( pMenu->GetItemCommand( nId ), xFrame ) ); - if( !!aImage ) - pMenu->SetItemImage( nId, aImage ); - } - } - - // tdf#99388 and tdf#99712 make known that PopupMenu is active at parent to - // allow suppressing closing of that window if needed - setPopupMenuActive(true); + xMenu->set_label(".uno:DeleteAllAnnotationByAuthor", aStr); - sal_uInt16 nId = pMenu->Execute( pParent, rContextRect, PopupMenuFlags::ExecuteDown|PopupMenuFlags::NoMouseUpClose ); - nId = IdentToSID(pMenu->GetItemIdent(nId)); + bool bShowReply = sAuthor != sCurrentAuthor; + xMenu->set_visible(".uno:ReplyToAnnotation", bShowReply); + xMenu->set_visible("separator", bShowReply); + xMenu->set_visible(".uno:DeleteAnnotation", xAnnotation.is()); - // tdf#99388 and tdf#99712 reset flag, need to be done before reacting - // since closing it is one possible reaction - setPopupMenuActive(false); + auto sId = xMenu->popup_at_rect(pParent, rContextRect); - switch( nId ) - { - case SID_REPLYTO_POSTIT: + if (sId == ".uno:ReplyToAnnotation") { const SfxUnoAnyItem aItem( SID_REPLYTO_POSTIT, Any( xAnnotation ) ); pDispatcher->ExecuteList(SID_REPLYTO_POSTIT, SfxCallMode::ASYNCHRON, { &aItem }); - break; } - case SID_DELETE_POSTIT: + else if (sId == ".uno:DeleteAnnotation") { const SfxUnoAnyItem aItem( SID_DELETE_POSTIT, Any( xAnnotation ) ); pDispatcher->ExecuteList(SID_DELETE_POSTIT, SfxCallMode::ASYNCHRON, { &aItem }); - break; } - case SID_DELETEALLBYAUTHOR_POSTIT: + else if (sId == ".uno:DeleteAllAnnotationByAuthor") { const SfxStringItem aItem( SID_DELETEALLBYAUTHOR_POSTIT, sAuthor ); pDispatcher->ExecuteList( SID_DELETEALLBYAUTHOR_POSTIT, SfxCallMode::ASYNCHRON, { &aItem }); - break; } - case SID_DELETEALL_POSTIT: + else if (sId == ".uno:DeleteAllAnnotation") pDispatcher->Execute( SID_DELETEALL_POSTIT ); - break; - case SID_COPY: - case SID_PASTE: - case SID_ATTR_CHAR_WEIGHT: - case SID_ATTR_CHAR_POSTURE: - case SID_ATTR_CHAR_UNDERLINE: - case SID_ATTR_CHAR_STRIKEOUT: - if( pAnnotationWindow ) - pAnnotationWindow->ExecuteSlot( nId ); - break; - } } Color AnnotationManagerImpl::GetColor(sal_uInt16 aAuthorIndex) diff --git a/sd/source/ui/annotations/annotationmanagerimpl.hxx b/sd/source/ui/annotations/annotationmanagerimpl.hxx index a00fc0e1882b..ab5904146807 100644 --- a/sd/source/ui/annotations/annotationmanagerimpl.hxx +++ b/sd/source/ui/annotations/annotationmanagerimpl.hxx @@ -82,7 +82,7 @@ public: void DeleteAnnotationsByAuthor( std::u16string_view sAuthor ); void DeleteAllAnnotations(); - void ExecuteAnnotationContextMenu( const css::uno::Reference< css::office::XAnnotation >& xAnnotation, vcl::Window* pParent, const ::tools::Rectangle& rContextRect, bool bButtonMenu = false ); + void ExecuteAnnotationTagContextMenu(const css::uno::Reference<css::office::XAnnotation>& xAnnotation, weld::Widget* pParent, const ::tools::Rectangle& rContextRect); static Color GetColorDark(sal_uInt16 aAuthorIndex); static Color GetColorLight(sal_uInt16 aAuthorIndex); @@ -114,10 +114,6 @@ public: void ShowAnnotations(bool bShow); - // tdf#99388 and tdf#99712 flag to transport if the PopupMenu is active - bool getPopupMenuActive() const { return mbPopupMenuActive; } - void setPopupMenuActive(bool bNew) { mbPopupMenuActive = bNew; } - private: ViewShellBase& mrBase; SdDrawDocument* mpDoc; @@ -129,7 +125,6 @@ private: css::uno::Reference< css::office::XAnnotation > mxSelectedAnnotation; bool mbShowAnnotations; - bool mbPopupMenuActive; ImplSVEvent * mnUpdateTagsEvent; vcl::Font maFont; diff --git a/sd/source/ui/annotations/annotationtag.cxx b/sd/source/ui/annotations/annotationtag.cxx index 9b5540dc73fb..09ddc22ce0be 100644 --- a/sd/source/ui/annotations/annotationtag.cxx +++ b/sd/source/ui/annotations/annotationtag.cxx @@ -25,6 +25,7 @@ #include <vcl/commandevent.hxx> #include <vcl/svapp.hxx> #include <vcl/settings.hxx> +#include <vcl/weldutils.hxx> #include <svx/sdr/overlay/overlayanimatedbitmapex.hxx> #include <svx/sdr/overlay/overlaybitmapex.hxx> @@ -279,7 +280,6 @@ AnnotationTag::AnnotationTag( AnnotationManagerImpl& rManager, ::sd::View& rView , maColor( rColor ) , mnIndex( nIndex ) , mrFont( rFont ) -, mnClosePopupEvent( nullptr ) , mpListenWindow( nullptr ) { } @@ -367,17 +367,15 @@ bool AnnotationTag::KeyInput( const KeyEvent& rKEvt ) /** returns true if the SmartTag consumes this event. */ bool AnnotationTag::Command( const CommandEvent& rCEvt ) { - if ( rCEvt.GetCommand() == CommandEventId::ContextMenu ) + if (rCEvt.GetCommand() != CommandEventId::ContextMenu) + return false; + if (vcl::Window* pWindow = mrView.GetViewShell()->GetActiveWindow()) { - vcl::Window* pWindow = mrView.GetViewShell()->GetActiveWindow(); - if( pWindow ) - { - ::tools::Rectangle aContextRect(rCEvt.GetMousePosPixel(),Size(1,1)); - mrManager.ExecuteAnnotationContextMenu( mxAnnotation, pWindow, aContextRect ); - return true; - } + ::tools::Rectangle aContextRect(rCEvt.GetMousePosPixel(),Size(1,1)); + weld::Window* pParent = weld::GetPopupParent(*pWindow, aContextRect); + mrManager.ExecuteAnnotationTagContextMenu(mxAnnotation, pParent, aContextRect); + return true; } - return false; } @@ -490,12 +488,6 @@ void AnnotationTag::disposing() mpListenWindow->RemoveEventListener( LINK(this, AnnotationTag, WindowEventHandler)); } - if( mnClosePopupEvent ) - { - Application::RemoveUserEvent( mnClosePopupEvent ); - mnClosePopupEvent = nullptr; - } - mxAnnotation.clear(); ClosePopup(); SmartTag::disposing(); @@ -594,8 +586,9 @@ void AnnotationTag::OpenPopup( bool bEdit ) ::tools::Rectangle aRect( aPos, maSize ); mpAnnotationWindow.reset( VclPtr<AnnotationWindow>::Create( mrManager, mrView.GetDocSh(), pWindow->GetWindow(GetWindowType::Frame) ) ); - mpAnnotationWindow->InitControls(); - mpAnnotationWindow->setAnnotation(mxAnnotation); + AnnotationContents& rAnnotation = mpAnnotationWindow->GetContents(); + rAnnotation.InitControls(); + rAnnotation.setAnnotation(mxAnnotation); sal_uInt16 nArrangeIndex = 0; Point aPopupPos( FloatingWindow::CalcFloatingPosition( mpAnnotationWindow.get(), aRect, FloatWinPopupFlags::Right, nArrangeIndex ) ); @@ -610,8 +603,8 @@ void AnnotationTag::OpenPopup( bool bEdit ) } } - if( bEdit && mpAnnotationWindow ) - mpAnnotationWindow->StartEdit(); + if (bEdit && mpAnnotationWindow) + mpAnnotationWindow->GetContents().StartEdit(); } void AnnotationTag::ClosePopup() @@ -619,7 +612,8 @@ void AnnotationTag::ClosePopup() if( mpAnnotationWindow ) { mpAnnotationWindow->RemoveEventListener( LINK(this, AnnotationTag, WindowEventHandler)); - mpAnnotationWindow->Deactivate(); + AnnotationContents& rAnnotation = mpAnnotationWindow->GetContents(); + rAnnotation.SaveToDocument(); mpAnnotationWindow.disposeAndClear(); } } @@ -631,23 +625,7 @@ IMPL_LINK(AnnotationTag, WindowEventHandler, VclWindowEvent&, rEvent, void) if( !pWindow ) return; - if( pWindow == mpAnnotationWindow.get() ) - { - if( rEvent.GetId() == VclEventId::WindowDeactivate ) - { - // tdf#99388 and tdf#99712 if PopupMenu is active, suppress - // deletion of the AnnotationWindow which is triggered by - // it losing focus - if (!mrManager.getPopupMenuActive()) - { - if( mnClosePopupEvent ) - Application::RemoveUserEvent( mnClosePopupEvent ); - - mnClosePopupEvent = Application::PostUserEvent( LINK( this, AnnotationTag, ClosePopupHdl ) ); - } - } - } - else if( pWindow == mpListenWindow ) + if( pWindow == mpListenWindow ) { switch( rEvent.GetId() ) { @@ -687,12 +665,6 @@ IMPL_LINK(AnnotationTag, WindowEventHandler, VclWindowEvent&, rEvent, void) } } -IMPL_LINK_NOARG(AnnotationTag, ClosePopupHdl, void*, void) -{ - mnClosePopupEvent = nullptr; - ClosePopup(); -} - } // end of namespace sd /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/annotations/annotationtag.hxx b/sd/source/ui/annotations/annotationtag.hxx index f05b62cd8380..7a02e304078c 100644 --- a/sd/source/ui/annotations/annotationtag.hxx +++ b/sd/source/ui/annotations/annotationtag.hxx @@ -70,7 +70,6 @@ private: virtual void deselect() override; DECL_LINK( WindowEventHandler, VclWindowEvent&, void ); - DECL_LINK( ClosePopupHdl, void*, void ); AnnotationManagerImpl& mrManager; css::uno::Reference< css::office::XAnnotation > mxAnnotation; @@ -79,7 +78,6 @@ private: int mnIndex; const vcl::Font& mrFont; Size maSize; - ImplSVEvent * mnClosePopupEvent; VclPtr<vcl::Window> mpListenWindow; Point maMouseDownPos; }; diff --git a/sd/source/ui/annotations/annotationwindow.cxx b/sd/source/ui/annotations/annotationwindow.cxx index b9297961f82a..36e7c28f0e3b 100644 --- a/sd/source/ui/annotations/annotationwindow.cxx +++ b/sd/source/ui/annotations/annotationwindow.cxx @@ -34,8 +34,10 @@ #include <sfx2/viewfrm.hxx> #include <sfx2/bindings.hxx> #include <sfx2/dispatch.hxx> +#include <svl/stritem.hxx> #include <vcl/commandevent.hxx> +#include <vcl/commandinfoprovider.hxx> #include <vcl/vclenum.hxx> #include <vcl/scrbar.hxx> #include <vcl/svapp.hxx> @@ -64,387 +66,407 @@ using namespace ::com::sun::star::text; #define METABUTTON_WIDTH 16 #define METABUTTON_HEIGHT 18 -#define METABUTTON_AREA_WIDTH 30 #define POSTIT_META_HEIGHT sal_Int32(30) namespace sd { -static Color ColorFromAlphaColor(sal_uInt8 aTransparency, Color const &aFront, Color const &aBack ) +void AnnotationTextWindow::Paint(vcl::RenderContext& rRenderContext, const ::tools::Rectangle& rRect) { - return Color(static_cast<sal_uInt8>(aFront.GetRed() * aTransparency/double(255) + aBack.GetRed() * (1-aTransparency/double(255))), - static_cast<sal_uInt8>(aFront.GetGreen() * aTransparency/double(255) + aBack.GetGreen() * (1-aTransparency/double(255))), - static_cast<sal_uInt8>(aFront.GetBlue() * aTransparency/double(255) + aBack.GetBlue() * (1-aTransparency/double(255)))); -} - -/************ AnnotationTextWindow **********************************/ - -AnnotationTextWindow::AnnotationTextWindow( AnnotationWindow* pParent, WinBits nBits ) -: Control(pParent, nBits) -, mpOutlinerView(nullptr) -, mpAnnotationWindow( pParent ) -{ -} + Size aSize = GetOutputSizePixel(); -AnnotationTextWindow::~AnnotationTextWindow() -{ - disposeOnce(); -} - -void AnnotationTextWindow::dispose() -{ - mpAnnotationWindow.clear(); - Control::dispose(); -} - -void AnnotationTextWindow::Paint( vcl::RenderContext& /*rRenderContext*/, const ::tools::Rectangle& rRect) -{ const bool bHighContrast = Application::GetSettings().GetStyleSettings().GetHighContrastMode(); - if ( !bHighContrast ) + if (!bHighContrast) { - DrawGradient(::tools::Rectangle(Point(0,0),PixelToLogic(GetSizePixel())), - Gradient(GradientStyle::Linear,mpAnnotationWindow->maColorLight,mpAnnotationWindow->maColor)); - } - - if( mpOutlinerView ) - { - Color aBackgroundColor( mpAnnotationWindow->maColor ); - if( bHighContrast ) - { - aBackgroundColor = GetSettings().GetStyleSettings().GetWindowColor(); - } + rRenderContext.DrawGradient(::tools::Rectangle(Point(0,0), rRenderContext.PixelToLogic(aSize)), + Gradient(GradientStyle::Linear, mrContents.maColorLight, mrContents.maColor)); + } - mpOutlinerView->SetBackgroundColor( aBackgroundColor ); + DoPaint(rRenderContext, rRect); +} - mpOutlinerView->Paint( rRect ); - } +void AnnotationTextWindow::EditViewScrollStateChange() +{ + mrContents.SetScrollbar(); } -void AnnotationTextWindow::KeyInput( const KeyEvent& rKeyEvt ) +bool AnnotationTextWindow::KeyInput(const KeyEvent& rKeyEvt) { const vcl::KeyCode& rKeyCode = rKeyEvt.GetKeyCode(); sal_uInt16 nKey = rKeyCode.GetCode(); + bool bDone = false; + if ((rKeyCode.IsMod1() && rKeyCode.IsMod2()) && ((nKey == KEY_PAGEUP) || (nKey == KEY_PAGEDOWN))) { - SfxDispatcher* pDispatcher = mpAnnotationWindow->DocShell()->GetViewShell()->GetViewFrame()->GetDispatcher(); + SfxDispatcher* pDispatcher = mrContents.DocShell()->GetViewShell()->GetViewFrame()->GetDispatcher(); if( pDispatcher ) pDispatcher->Execute( nKey == KEY_PAGEDOWN ? SID_NEXT_POSTIT : SID_PREVIOUS_POSTIT ); + bDone = true; } else if (nKey == KEY_INSERT) { if (!rKeyCode.IsMod1() && !rKeyCode.IsMod2()) - mpAnnotationWindow->ToggleInsMode(); + mrContents.ToggleInsMode(); + bDone = true; } else { - ::tools::Long aOldHeight = mpAnnotationWindow->GetPostItTextHeight(); - bool bDone = false; + ::tools::Long aOldHeight = mrContents.GetPostItTextHeight(); /// HACK: need to switch off processing of Undo/Redo in Outliner if ( !( (nKey == KEY_Z || nKey == KEY_Y) && rKeyCode.IsMod1()) ) { - bool bIsProtected = mpAnnotationWindow->IsProtected(); + bool bIsProtected = mrContents.IsProtected(); if (!bIsProtected || !EditEngine::DoesKeyChangeText(rKeyEvt) ) - - bDone = mpOutlinerView->PostKeyEvent( rKeyEvt ); + { + if (EditView* pEditView = GetEditView()) + { + bDone = pEditView->PostKeyEvent(rKeyEvt); + } + } } if (bDone) { - mpAnnotationWindow->ResizeIfNecessary(aOldHeight,mpAnnotationWindow->GetPostItTextHeight()); - } - else - { - Control::KeyInput(rKeyEvt); + mrContents.ResizeIfNecessary(aOldHeight, mrContents.GetPostItTextHeight()); } } -} -void AnnotationTextWindow::MouseMove( const MouseEvent& rMEvt ) -{ - if ( mpOutlinerView ) - { - mpOutlinerView->MouseMove( rMEvt ); - SetPointer( mpOutlinerView->GetPointer( rMEvt.GetPosPixel() ) ); - } + return bDone; } -void AnnotationTextWindow::MouseButtonDown( const MouseEvent& rMEvt ) +/************** AnnotationWindow***********************************++*/ +AnnotationWindow::AnnotationWindow(AnnotationManagerImpl& rManager, DrawDocShell* pDocShell, vcl::Window* pParent) + : FloatingWindow(pParent, WB_BORDER) + , mrManager( rManager ) + , mpDocShell( pDocShell ) + , mpDoc( pDocShell->GetDoc() ) + , mxContents(VclPtr<AnnotationContents>::Create(this, pDocShell)) { - GrabFocus(); - if ( mpOutlinerView ) - mpOutlinerView->MouseButtonDown( rMEvt ); + EnableAlwaysOnTop(); } -void AnnotationTextWindow::MouseButtonUp( const MouseEvent& rMEvt ) +AnnotationWindow::~AnnotationWindow() { - if ( mpOutlinerView ) - mpOutlinerView->MouseButtonUp( rMEvt ); + disposeOnce(); } -void AnnotationTextWindow::Command( const CommandEvent& rCEvt ) +AnnotationTextWindow::AnnotationTextWindow(AnnotationContents& rContents) + : mrContents(rContents) { - if ( rCEvt.GetCommand() == CommandEventId::ContextMenu ) - { - mpAnnotationWindow->Command(rCEvt); - } - else - { - if ( mpOutlinerView ) - mpOutlinerView->Command( rCEvt ); - else - Window::Command(rCEvt); - } } -OUString AnnotationTextWindow::GetSurroundingText() const +EditView* AnnotationTextWindow::GetEditView() const { - if( mpOutlinerView ) - { - EditEngine *aEditEngine = mpOutlinerView->GetEditView().GetEditEngine(); - if( mpOutlinerView->HasSelection() ) - return mpOutlinerView->GetSelected(); - else - { - ESelection aSelection = mpOutlinerView->GetEditView().GetSelection(); - return aEditEngine->GetText(aSelection.nStartPara); - } - } - return OUString(); + OutlinerView* pOutlinerView = mrContents.GetOutlinerView(); + if (!pOutlinerView) + return nullptr; + return &pOutlinerView->GetEditView(); } -Selection AnnotationTextWindow::GetSurroundingTextSelection() const +EditEngine* AnnotationTextWindow::GetEditEngine() const { - if( mpOutlinerView ) - { - if( mpOutlinerView->HasSelection() ) - return Selection( 0, mpOutlinerView->GetSelected().getLength() ); - else - { - ESelection aSelection = mpOutlinerView->GetEditView().GetSelection(); - return Selection( aSelection.nStartPos, aSelection.nEndPos ); - } - } - else - return Selection( 0, 0 ); + OutlinerView* pOutlinerView = mrContents.GetOutlinerView(); + if (!pOutlinerView) + return nullptr; + return pOutlinerView->GetEditView().GetEditEngine(); } -bool AnnotationTextWindow::DeleteSurroundingText(const Selection& rSelection) +void AnnotationTextWindow::SetDrawingArea(weld::DrawingArea* pDrawingArea) { - if( mpOutlinerView ) - return mpOutlinerView->DeleteSurroundingText(rSelection); - return false; -} + Size aSize(0, 0); + pDrawingArea->set_size_request(aSize.Width(), aSize.Height()); -/************** AnnotationWindow***********************************++*/ + SetOutputSizePixel(aSize); + + weld::CustomWidgetController::SetDrawingArea(pDrawingArea); + + EnableRTL(false); -AnnotationWindow::AnnotationWindow( AnnotationManagerImpl& rManager, DrawDocShell* pDocShell, vcl::Window* pParent ) -: FloatingWindow(pParent, WB_BORDER) -, mrManager( rManager ) -, mpDocShell( pDocShell ) -, mpDoc( pDocShell->GetDoc() ) -, mpVScrollbar(nullptr) -, mbReadonly(pDocShell->IsReadOnly()) -, mbProtected(false) -, mbMouseOverButton(false) -, mpTextWindow(nullptr) -, mpMeta(nullptr) + const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings(); + Color aBgColor = rStyleSettings.GetWindowColor(); + + OutputDevice& rDevice = pDrawingArea->get_ref_device(); + + rDevice.SetMapMode(MapMode(MapUnit::Map100thMM)); + rDevice.SetBackground(aBgColor); + + Size aOutputSize(rDevice.PixelToLogic(aSize)); + aSize = aOutputSize; + aSize.setHeight(aSize.Height()); + + EditView* pEditView = GetEditView(); + pEditView->setEditViewCallbacks(this); + + EditEngine* pEditEngine = GetEditEngine(); + pEditEngine->SetPaperSize(aSize); + pEditEngine->SetRefDevice(&rDevice); + + pEditView->SetOutputArea(::tools::Rectangle(Point(0, 0), aOutputSize)); + pEditView->SetBackgroundColor(aBgColor); + + pDrawingArea->set_cursor(PointerStyle::Text); + + InitAccessible(); +} + +// see SwAnnotationWin in sw for something similar +AnnotationContents::AnnotationContents(vcl::Window* pParent, DrawDocShell* pDocShell) + : InterimItemWindow(pParent, "modules/simpress/ui/annotation.ui", "Annotation") + , mpDocShell(pDocShell) + , mpDoc(pDocShell->GetDoc()) + , mbReadonly(pDocShell->IsReadOnly()) + , mbProtected(false) { - EnableAlwaysOnTop(); } -AnnotationWindow::~AnnotationWindow() +void AnnotationContents::dispose() { - disposeOnce(); + mxTextControlWin.reset(); + mxTextControl.reset(); + + mxMeta.reset(); + mxVScrollbar.reset(); + + mxMenuButton.reset(); + + mpOutliner.reset(); + mpOutlinerView.reset(); + + InterimItemWindow::dispose(); } void AnnotationWindow::dispose() { - mpMeta.disposeAndClear(); - mpOutlinerView.reset(); - mpOutliner.reset(); - mpOutliner = nullptr; - mpVScrollbar.disposeAndClear(); - mpTextWindow.disposeAndClear(); + mxContents.disposeAndClear(); FloatingWindow::dispose(); } -void AnnotationWindow::InitControls() +void AnnotationContents::InitControls() { - // actual window which holds the user text - mpTextWindow = VclPtr<AnnotationTextWindow>::Create(this, WB_NODIALOGCONTROL); - mpTextWindow->SetPointer(PointerStyle::Text); - // window control for author and date - mpMeta = VclPtr<FixedText>::Create(this); - mpMeta->EnableRTL(AllSettings::GetLayoutRTL()); + mxMeta = m_xBuilder->weld_label("meta"); + mxMeta->set_direction(AllSettings::GetLayoutRTL()); + + maLabelFont = Application::GetSettings().GetStyleSettings().GetLabelFont(); + maLabelFont.SetFontHeight(8); // we should leave this setting alone, but for this we need a better layout algo // with variable meta size height - AllSettings aSettings = mpMeta->GetSettings(); - StyleSettings aStyleSettings = aSettings.GetStyleSettings(); - vcl::Font aFont = aStyleSettings.GetLabelFont(); - aFont.SetFontHeight(8); - aStyleSettings.SetLabelFont(aFont); - aSettings.SetStyleSettings(aStyleSettings); - mpMeta->SetSettings(aSettings); + mxMeta->set_font(maLabelFont); mpOutliner.reset( new ::Outliner(GetAnnotationPool(),OutlinerMode::TextObject) ); SdDrawDocument::SetCalcFieldValueHdl( mpOutliner.get() ); mpOutliner->SetUpdateMode( true ); Rescale(); - OutputDevice* pDev = Doc()->GetRefDevice(); - if( pDev ) - { + if (OutputDevice* pDev = mpDoc->GetRefDevice()) mpOutliner->SetRefDevice( pDev ); - } - mpTextWindow->EnableRTL( false ); - mpOutlinerView.reset( new OutlinerView ( mpOutliner.get(), mpTextWindow ) ); + mpOutlinerView.reset( new OutlinerView ( mpOutliner.get(), nullptr) ); mpOutliner->InsertView(mpOutlinerView.get() ); - mpTextWindow->SetOutlinerView(mpOutlinerView.get()); - mpOutlinerView->SetOutputArea( PixelToLogic( ::tools::Rectangle(0,0,1,1) ) ); //create Scrollbars - mpVScrollbar = VclPtr<ScrollBar>::Create(this, WB_3DLOOK |WB_VSCROLL|WB_DRAG); - mpVScrollbar->EnableNativeWidget(false); - mpVScrollbar->EnableRTL( false ); - mpVScrollbar->SetScrollHdl(LINK(this, AnnotationWindow, ScrollHdl)); - mpVScrollbar->EnableDrag(); + mxVScrollbar = m_xBuilder->weld_scrolled_window("scrolledwindow", true); + + // actual window which holds the user text + mxTextControl.reset(new AnnotationTextWindow(*this)); + mxTextControlWin.reset(new weld::CustomWeld(*m_xBuilder, "editview", *mxTextControl)); + mxTextControl->SetPointer(PointerStyle::Text); + + mxVScrollbar->set_direction(false); + mxVScrollbar->connect_vadjustment_changed(LINK(this, AnnotationContents, ScrollHdl)); + + mpOutlinerView->SetBackgroundColor(COL_TRANSPARENT); + mpOutlinerView->SetOutputArea( PixelToLogic( ::tools::Rectangle(0,0,1,1) ) ); + + mxMenuButton = m_xBuilder->weld_menu_button("menubutton"); + if (mbReadonly) + mxMenuButton->hide(); + else + { + mxMenuButton->set_size_request(METABUTTON_WIDTH, METABUTTON_HEIGHT); + mxMenuButton->connect_toggled(LINK(this, AnnotationContents, MenuButtonToggledHdl)); + mxMenuButton->connect_selected(LINK(this, AnnotationContents, MenuItemSelectedHdl)); + } EEControlBits nCntrl = mpOutliner->GetControlWord(); nCntrl |= EEControlBits::PASTESPECIAL | EEControlBits::AUTOCORRECT | EEControlBits::USECHARATTRIBS | EEControlBits::NOCOLORS; mpOutliner->SetControlWord(nCntrl); - Engine()->SetModifyHdl( Link<LinkParamNone*,void>() ); - Engine()->EnableUndo( false ); + mpOutliner->SetModifyHdl( Link<LinkParamNone*,void>() ); + mpOutliner->EnableUndo( false ); - Engine()->ClearModifyFlag(); - Engine()->GetUndoManager().Clear(); - Engine()->EnableUndo( true ); + mpOutliner->ClearModifyFlag(); + mpOutliner->GetUndoManager().Clear(); + mpOutliner->EnableUndo( true ); - Invalidate(); + SetLanguage(SvxLanguageItem(mpDoc->GetLanguage(EE_CHAR_LANGUAGE), SID_ATTR_LANGUAGE)); + + mxTextControl->GrabFocus(); +} + +IMPL_LINK(AnnotationContents, MenuItemSelectedHdl, const OString&, rIdent, void) +{ + SfxDispatcher* pDispatcher = mpDocShell->GetViewShell()->GetViewFrame()->GetDispatcher(); + if (!pDispatcher) + return; + + if (rIdent == ".uno:ReplyToAnnotation") + { + const SfxUnoAnyItem aItem( SID_REPLYTO_POSTIT, Any( mxAnnotation ) ); + pDispatcher->ExecuteList(SID_REPLYTO_POSTIT, + SfxCallMode::ASYNCHRON, { &aItem }); + } + else if (rIdent == ".uno:DeleteAnnotation") + { + const SfxUnoAnyItem aItem( SID_DELETE_POSTIT, Any( mxAnnotation ) ); + pDispatcher->ExecuteList(SID_DELETE_POSTIT, SfxCallMode::ASYNCHRON, + { &aItem }); + } + else if (rIdent == ".uno:DeleteAllAnnotationByAuthor") + { + const SfxStringItem aItem( SID_DELETEALLBYAUTHOR_POSTIT, mxAnnotation->getAuthor() ); + pDispatcher->ExecuteList( SID_DELETEALLBYAUTHOR_POSTIT, + SfxCallMode::ASYNCHRON, { &aItem }); + } + else if (rIdent == ".uno:DeleteAllAnnotation") + pDispatcher->Execute( SID_DELETEALL_POSTIT ); +} - SetLanguage(SvxLanguageItem( Doc()->GetLanguage( EE_CHAR_LANGUAGE ), SID_ATTR_LANGUAGE )); +IMPL_LINK_NOARG(AnnotationContents, MenuButtonToggledHdl, weld::ToggleButton&, void) +{ + if (!mxMenuButton->get_active()) + return; + + SvtUserOptions aUserOptions; + OUString sCurrentAuthor( aUserOptions.GetFullName() ); + OUString sAuthor( mxAnnotation->getAuthor() ); - mpMeta->Show(); - mpVScrollbar->Show(); - mpTextWindow->Show(); + OUString aStr(mxMenuButton->get_item_label(".uno:DeleteAllAnnotationByAuthor")); + OUString aReplace( sAuthor ); + if( aReplace.isEmpty() ) + aReplace = SdResId( STR_ANNOTATION_NOAUTHOR ); + aStr = aStr.replaceFirst("%1", aReplace); + mxMenuButton->set_item_label(".uno:DeleteAllAnnotationByAuthor", aStr); + + bool bShowReply = sAuthor != sCurrentAuthor && !mbReadonly; + mxMenuButton->set_item_visible(".uno:ReplyToAnnotation", bShowReply); + mxMenuButton->set_item_visible("separator", bShowReply); + mxMenuButton->set_item_visible(".uno:DeleteAnnotation", mxAnnotation.is() && !mbReadonly); + mxMenuButton->set_item_visible(".uno:DeleteAllAnnotationByAuthor", !mbReadonly); + mxMenuButton->set_item_visible(".uno:DeleteAllAnnotation", !mbReadonly); } -void AnnotationWindow::StartEdit() +void AnnotationContents::StartEdit() { - getView()->SetSelection(ESelection(EE_PARA_MAX_COUNT,EE_TEXTPOS_MAX_COUNT,EE_PARA_MAX_COUNT,EE_TEXTPOS_MAX_COUNT)); - getView()->ShowCursor(); + GetOutlinerView()->SetSelection(ESelection(EE_PARA_MAX_COUNT,EE_TEXTPOS_MAX_COUNT,EE_PARA_MAX_COUNT,EE_TEXTPOS_MAX_COUNT)); + GetOutlinerView()->ShowCursor(); } -void AnnotationWindow::Rescale() +void AnnotationContents::Rescale() { MapMode aMode(MapUnit::Map100thMM); aMode.SetOrigin( Point() ); mpOutliner->SetRefMapMode( aMode ); SetMapMode( aMode ); - mpTextWindow->SetMapMode( aMode ); - if ( mpMeta ) + + if (mxMeta) { - vcl::Font aFont( mpMeta->GetSettings().GetStyleSettings().GetLabelFont() ); + vcl::Font aFont = maLabelFont; sal_Int32 nHeight = ::tools::Long(aFont.GetFontHeight() * aMode.GetScaleY()); aFont.SetFontHeight( nHeight ); - mpMeta->SetControlFont( aFont ); + mxMeta->set_font(aFont); } } void AnnotationWindow::DoResize() { - unsigned long aWidth = GetSizePixel().Width(); - ::tools::Long aHeight = GetSizePixel().Height() - POSTIT_META_HEIGHT; + mxContents->SetSizePixel(GetSizePixel()); + mxContents->Show(); - mpOutliner->SetPaperSize( PixelToLogic( Size(aWidth,aHeight) ) ) ; - ::tools::Long aTextHeight = LogicToPixel( mpOutliner->CalcTextSize()).Height(); + mxContents->DoResize(); +} + +void AnnotationContents::DoResize() +{ + ::tools::Long aTextHeight = LogicToPixel( mpOutliner->CalcTextSize()).Height(); + ::tools::Long aHeight = GetSizePixel().Height(); + ::tools::ULong aWidth = GetSizePixel().Width(); + + aHeight -= POSTIT_META_HEIGHT; if( aTextHeight > aHeight ) - { // we need vertical scrollbars and have to reduce the width - aWidth -= GetScrollbarWidth(); - mpVScrollbar->Show(); + { + // we need vertical scrollbars and have to reduce the width + aWidth -= mxVScrollbar->get_vscroll_width(); + mxVScrollbar->set_vpolicy(VclPolicyType::ALWAYS); } else { - mpVScrollbar->Hide(); + mxVScrollbar->set_vpolicy(VclPolicyType::NEVER); } - mpTextWindow->setPosSizePixel(0,0,aWidth, aHeight); - - if( mbReadonly ) - mpMeta->setPosSizePixel(0,aHeight,GetSizePixel().Width(),POSTIT_META_HEIGHT); - else - mpMeta->setPosSizePixel(0,aHeight,GetSizePixel().Width()-METABUTTON_AREA_WIDTH,POSTIT_META_HEIGHT); - mpOutliner->SetPaperSize( PixelToLogic( Size(aWidth,aHeight) ) ) ; - mpOutlinerView->SetOutputArea( PixelToLogic( ::tools::Rectangle(0,0,aWidth,aHeight) ) ); - if (!mpVScrollbar->IsVisible()) - { // if we do not have a scrollbar anymore, we want to see the complete text - mpOutlinerView->SetVisArea( PixelToLogic( ::tools::Rectangle(0,0,aWidth,aHeight) ) ); + + ::tools::Rectangle aOutputArea = PixelToLogic(::tools::Rectangle(0, 0, aWidth, aHeight)); + if (mxVScrollbar->get_vpolicy() == VclPolicyType::NEVER) + { + // if we do not have a scrollbar anymore, we want to see the complete text + mpOutlinerView->SetVisArea(aOutputArea); } - mpVScrollbar->setPosSizePixel( 0 + aWidth, 0, GetScrollbarWidth(), aHeight ); - mpVScrollbar->SetVisibleSize( PixelToLogic(Size(0,aHeight)).Height() ); - mpVScrollbar->SetPageSize( PixelToLogic(Size(0,aHeight)).Height() * 8 / 10 ); - mpVScrollbar->SetLineSize( mpOutliner->GetTextHeight() / 10 ); - SetScrollbar(); - mpVScrollbar->SetRange( Range(0, mpOutliner->GetTextHeight())); + mpOutlinerView->SetOutputArea(aOutputArea); + mpOutlinerView->ShowCursor(true, true); + + int nUpper = mpOutliner->GetTextHeight(); + int nCurrentDocPos = mpOutlinerView->GetVisArea().Top(); + int nStepIncrement = mpOutliner->GetTextHeight() / 10; + int nPageIncrement = PixelToLogic(Size(0,aHeight)).Height() * 8 / 10; + int nPageSize = PixelToLogic(Size(0,aHeight)).Height(); + + /* limit the page size to below nUpper because gtk's gtk_scrolled_window_start_deceleration has + effectively... - Point aPos( mpMeta->GetPosPixel()); - Point aBase( aPos.X() + aPos.X() + GetSizePixel().Width(), aPos.Y() ); - Point aLeft = PixelToLogic( Point( aBase.X() - (METABUTTON_WIDTH+5), aBase.Y()+17 ) ); - Point aRight = PixelToLogic( Point( aBase.X() - (METABUTTON_WIDTH-1), aBase.Y()+17 ) ); - Point aBottom = PixelToLogic( Point( aBase.X() - (METABUTTON_WIDTH+2), aBase.Y()+20 ) ); + lower = gtk_adjustment_get_lower + upper = gtk_adjustment_get_upper - gtk_adjustment_get_page_size - maPopupTriangle.clear(); - maPopupTriangle.append(basegfx::B2DPoint(aLeft.X(),aLeft.Y())); - maPopupTriangle.append(basegfx::B2DPoint(aRight.X(),aRight.Y())); - maPopupTriangle.append(basegfx::B2DPoint(aBottom.X(),aBottom.Y())); - maPopupTriangle.setClosed(true); - maRectMetaButton = PixelToLogic( ::tools::Rectangle( Point( - aPos.X()+GetSizePixel().Width()-(METABUTTON_WIDTH+10), - aPos.Y()+5 ), - Size( METABUTTON_WIDTH, METABUTTON_HEIGHT ) ) ); + and requires that upper > lower or the deceleration animation never ends + */ + nPageSize = std::min(nPageSize, nUpper); + mxVScrollbar->vadjustment_configure(nCurrentDocPos, 0, nUpper, + nStepIncrement, nPageIncrement, nPageSize); } -void AnnotationWindow::SetScrollbar() +void AnnotationContents::SetScrollbar() { - mpVScrollbar->SetThumbPos(mpOutlinerView->GetVisArea().Top()); + mxVScrollbar->vadjustment_set_value(mpOutlinerView->GetVisArea().Top()); } -void AnnotationWindow::ResizeIfNecessary(::tools::Long aOldHeight, ::tools::Long aNewHeight) +void AnnotationContents::ResizeIfNecessary(::tools::Long aOldHeight, ::tools::Long aNewHeight) { if (aOldHeight != aNewHeight) - { DoResize(); - Invalidate(); - } else - { SetScrollbar(); - } } -void AnnotationWindow::SetLanguage(const SvxLanguageItem &aNewItem) +void AnnotationContents::SetLanguage(const SvxLanguageItem &aNewItem) { - Engine()->SetModifyHdl( Link<LinkParamNone*,void>() ); - ESelection aOld = getView()->GetSelection(); + mpOutliner->SetModifyHdl( Link<LinkParamNone*,void>() ); + ESelection aOld = GetOutlinerView()->GetSelection(); - ESelection aNewSelection( 0, 0, Engine()->GetParagraphCount()-1, EE_TEXTPOS_ALL ); - getView()->SetSelection( aNewSelection ); - SfxItemSet aEditAttr(getView()->GetAttribs()); + ESelection aNewSelection( 0, 0, mpOutliner->GetParagraphCount()-1, EE_TEXTPOS_ALL ); + GetOutlinerView()->SetSelection( aNewSelection ); + SfxItemSet aEditAttr(GetOutlinerView()->GetAttribs()); aEditAttr.Put(aNewItem); - getView()->SetAttribs( aEditAttr ); + GetOutlinerView()->SetAttribs( aEditAttr ); - getView()->SetSelection(aOld); + GetOutlinerView()->SetSelection(aOld); Invalidate(); } -void AnnotationWindow::ToggleInsMode() +void AnnotationContents::ToggleInsMode() { if( mpOutlinerView ) { @@ -454,15 +476,15 @@ void AnnotationWindow::ToggleInsMode() } } -::tools::Long AnnotationWindow::GetPostItTextHeight() +::tools::Long AnnotationContents::GetPostItTextHeight() { return mpOutliner ? LogicToPixel(mpOutliner->CalcTextSize()).Height() : 0; } -IMPL_LINK(AnnotationWindow, ScrollHdl, ScrollBar*, pScroll, void) +IMPL_LINK(AnnotationContents, ScrollHdl, weld::ScrolledWindow&, rScrolledWindow, void) { - ::tools::Long nDiff = getView()->GetEditView().GetVisArea().Top() - pScroll->GetThumbPos(); - getView()->Scroll( 0, nDiff ); + ::tools::Long nDiff = GetOutlinerView()->GetEditView().GetVisArea().Top() - rScrolledWindow.vadjustment_get_value(); + GetOutlinerView()->Scroll( 0, nDiff ); } TextApiObject* getTextApiObject( const Reference< XAnnotation >& xAnnotation ) @@ -475,7 +497,7 @@ TextApiObject* getTextApiObject( const Reference< XAnnotation >& xAnnotation ) return nullptr; } -void AnnotationWindow::setAnnotation( const Reference< XAnnotation >& xAnnotation ) +void AnnotationContents::setAnnotation( const Reference< XAnnotation >& xAnnotation ) { if( (xAnnotation == mxAnnotation) || !xAnnotation.is() ) return; @@ -487,17 +509,17 @@ void AnnotationWindow::setAnnotation( const Reference< XAnnotation >& xAnnotatio SvtUserOptions aUserOptions; mbProtected = aUserOptions.GetFullName() != xAnnotation->getAuthor(); - Engine()->Clear(); + mpOutliner->Clear(); TextApiObject* pTextApi = getTextApiObject( mxAnnotation ); if( pTextApi ) { std::unique_ptr< OutlinerParaObject > pOPO( pTextApi->CreateText() ); - Engine()->SetText(*pOPO); + mpOutliner->SetText(*pOPO); } - Engine()->ClearModifyFlag(); - Engine()->GetUndoManager().Clear(); + mpOutliner->ClearModifyFlag(); + mpOutliner->GetUndoManager().Clear(); Invalidate(); @@ -511,10 +533,10 @@ void AnnotationWindow::setAnnotation( const Reference< XAnnotation >& xAnnotatio sMeta += sDateTime; } - mpMeta->SetText(sMeta); + mxMeta->set_label(sMeta); } -void AnnotationWindow::SetColor() +void AnnotationContents::SetColor() { sal_uInt16 nAuthorIdx = mpDoc->GetAnnotationAuthorIndex( mxAnnotation->getAuthor() ); @@ -534,51 +556,40 @@ void AnnotationWindow::SetColor() maColorLight = AnnotationManagerImpl::GetColorLight( nAuthorIdx ); } - mpOutlinerView->SetBackgroundColor(maColor); - Engine()->SetBackgroundColor(maColor); - { SvtAccessibilityOptions aOptions; - Engine()->ForceAutoColor( bHighContrast || aOptions.GetIsAutomaticFontColor() ); + mpOutliner->ForceAutoColor( bHighContrast || aOptions.GetIsAutomaticFontColor() ); } - mpMeta->SetControlBackground(maColor); - AllSettings aSettings = mpMeta->GetSettings(); - StyleSettings aStyleSettings = aSettings.GetStyleSettings(); - aStyleSettings.SetLabelTextColor( bHighContrast ? maColorLight : maColorDark); - aSettings.SetStyleSettings(aStyleSettings); - mpMeta->SetSettings(aSettings); + m_xContainer->set_background(maColor); + mxMenuButton->set_background(maColor); - AllSettings aSettings2 = mpVScrollbar->GetSettings(); - StyleSettings aStyleSettings2 = aSettings2.GetStyleSettings(); - aStyleSettings2.SetButtonTextColor(Color(0,0,0)); - aStyleSettings2.SetCheckedColor(maColorLight); //hintergund - aStyleSettings2.SetShadowColor(maColorDark); - aStyleSettings2.SetFaceColor(maColor); - aSettings2.SetStyleSettings(aStyleSettings2); - mpVScrollbar->SetSettings(aSettings2); + mxMeta->set_font_color(bHighContrast ? maColorLight : maColorDark); + + mxVScrollbar->customize_scrollbars(maColorLight, + maColorDark, + maColor, + GetPrefScrollbarWidth()); } -void AnnotationWindow::Deactivate() +void AnnotationContents::GetFocus() { - //tdf#99388 and tdf#99712, don't deactivate if we lose focus because of our - //own popup - if (mrManager.getPopupMenuActive()) - return; - - if (!mpOutliner) //in dispose - return; + if (mxTextControl) + mxTextControl->GrabFocus(); +} +void AnnotationContents::SaveToDocument() +{ Reference< XAnnotation > xAnnotation( mxAnnotation ); // write changed text back to annotation - if ( Engine()->IsModified() ) + if (mpOutliner->IsModified()) { TextApiObject* pTextApi = getTextApiObject( xAnnotation ); if( pTextApi ) { - std::unique_ptr<OutlinerParaObject> pOPO = Engine()->CreateParaObject(); + std::unique_ptr<OutlinerParaObject> pOPO = mpOutliner->CreateParaObject(); if( pOPO ) { if( mpDoc->IsUndoEnabled() ) @@ -598,157 +609,212 @@ void AnnotationWindow::Deactivate() } } - Engine()->ClearModifyFlag(); + mpOutliner->ClearModifyFlag(); - Engine()->GetUndoManager().Clear(); + mpOutliner->GetUndoManager().Clear(); } -void AnnotationWindow::Paint(vcl::RenderContext& rRenderContext, const ::tools::Rectangle& rRect) +bool AnnotationTextWindow::Command(const CommandEvent& rCEvt) { - FloatingWindow::Paint(rRenderContext, rRect); + if (rCEvt.GetCommand() == CommandEventId::ContextMenu) + { + const bool bReadOnly = mrContents.DocShell()->IsReadOnly(); + if (bReadOnly) + return true; - if(!mpMeta->IsVisible() || mbReadonly) - return; + SfxDispatcher* pDispatcher = mrContents.DocShell()->GetViewShell()->GetViewFrame()->GetDispatcher(); + if( !pDispatcher ) + return true; - const bool bHighContrast = Application::GetSettings().GetStyleSettings().GetHighContrastMode(); - //draw left over space - if ( bHighContrast ) - SetFillColor(COL_BLACK); - else - SetFillColor(maColor); - SetLineColor(); - DrawRect(PixelToLogic(::tools::Rectangle(Point(mpMeta->GetPosPixel().X()+mpMeta->GetSizePixel().Width(),mpMeta->GetPosPixel().Y()),Size(METABUTTON_AREA_WIDTH,mpMeta->GetSizePixel().Height())))); + if (IsMouseCaptured()) + { + // so the menu can capture it and the EditView doesn't get the button release and change its + // selection on a successful button click + ReleaseMouse(); + } - if ( bHighContrast ) - { - //draw rect around button - SetFillColor(COL_BLACK); - SetLineColor(COL_WHITE); - } - else - { - //draw button - Gradient aGradient; - if (mbMouseOverButton) - aGradient = Gradient(GradientStyle::Linear,ColorFromAlphaColor(80,maColorDark,maColor),ColorFromAlphaColor(15,maColorDark,maColor)); - else - aGradient = Gradient(GradientStyle::Linear,ColorFromAlphaColor(15,maColorDark,maColor),ColorFromAlphaColor(80,maColorDark,maColor)); - DrawGradient(maRectMetaButton,aGradient); - //draw rect around button - SetFillColor(); - SetLineColor(ColorFromAlphaColor(90,maColorDark,maColor)); - } - DrawRect(maRectMetaButton); + ::tools::Rectangle aRect(rCEvt.GetMousePosPixel(), Size(1, 1)); + weld::Widget* pPopupParent = GetDrawingArea(); + std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(pPopupParent, "modules/simpress/ui/annotationtagmenu.ui")); + std::unique_ptr<weld::Menu> xMenu(xBuilder->weld_menu("menu")); - //draw arrow - if( bHighContrast ) - SetFillColor(COL_WHITE); - else - SetFillColor(COL_BLACK); - SetLineColor(); - DrawPolygon( ::tools::Polygon(maPopupTriangle)); -} + auto xAnnotation = mrContents.getAnnotation(); -void AnnotationWindow::MouseMove( const MouseEvent& rMEvt ) -{ - if( mbReadonly ) - return; + SvtUserOptions aUserOptions; + OUString sCurrentAuthor( aUserOptions.GetFullName() ); + OUString sAuthor( xAnnotation->getAuthor() ); - if (maRectMetaButton.IsInside(PixelToLogic(rMEvt.GetPosPixel()))) - { - if (!mbMouseOverButton) + OUString aStr(xMenu->get_label(".uno:DeleteAllAnnotationByAuthor")); + OUString aReplace( sAuthor ); + if( aReplace.isEmpty() ) + aReplace = SdResId( STR_ANNOTATION_NOAUTHOR ); + aStr = aStr.replaceFirst("%1", aReplace); + xMenu->set_label(".uno:DeleteAllAnnotationByAuthor", aStr); + + bool bShowReply = sAuthor != sCurrentAuthor && !bReadOnly; + xMenu->set_visible(".uno:ReplyToAnnotation", bShowReply); + xMenu->set_visible("separator", bShowReply); + xMenu->set_visible(".uno:DeleteAnnotation", xAnnotation.is() && !bReadOnly); + xMenu->set_visible(".uno:DeleteAllAnnotationByAuthor", !bReadOnly); + xMenu->set_visible(".uno:DeleteAllAnnotation", !bReadOnly); + + int nInsertPos = 2; + + auto xFrame = mrContents.DocShell()->GetViewShell()->GetViewFrame()->GetFrame().GetFrameInterface(); + OUString aModuleName(vcl::CommandInfoProvider::GetModuleIdentifier(xFrame)); + + bool bEditable = !mrContents.IsProtected() && !bReadOnly; + if (bEditable) { - Invalidate(maRectMetaButton); - mbMouseOverButton = true; + SfxItemSet aSet(mrContents.GetOutlinerView()->GetAttribs()); + + xMenu->insert(nInsertPos++, ".uno:Bold", + vcl::CommandInfoProvider::GetMenuLabelForCommand( + vcl::CommandInfoProvider::GetCommandProperties(".uno:Bold", aModuleName)), + nullptr, nullptr, vcl::CommandInfoProvider::GetXGraphicForCommand(".uno:Bold", xFrame), + TRISTATE_TRUE); + + if ( aSet.GetItemState( EE_CHAR_WEIGHT ) == SfxItemState::SET ) + { + if( aSet.Get( EE_CHAR_WEIGHT ).GetWeight() == WEIGHT_BOLD ) + xMenu->set_active(".uno:Bold", true); + } + + xMenu->insert(nInsertPos++, ".uno:Italic", + vcl::CommandInfoProvider::GetMenuLabelForCommand( + vcl::CommandInfoProvider::GetCommandProperties(".uno:Italic", aModuleName)), + nullptr, nullptr, vcl::CommandInfoProvider::GetXGraphicForCommand(".uno:Italic", xFrame), + TRISTATE_TRUE); + + if ( aSet.GetItemState( EE_CHAR_ITALIC ) == SfxItemState::SET ) + { + if( aSet.Get( EE_CHAR_ITALIC ).GetPosture() != ITALIC_NONE ) + xMenu->set_active(".uno:Italic", true); + + } + + xMenu->insert(nInsertPos++, ".uno:Underline", + vcl::CommandInfoProvider::GetMenuLabelForCommand( + vcl::CommandInfoProvider::GetCommandProperties(".uno:Underline", aModuleName)), + nullptr, nullptr, vcl::CommandInfoProvider::GetXGraphicForCommand(".uno:Underline", xFrame), + TRISTATE_TRUE); + + if ( aSet.GetItemState( EE_CHAR_UNDERLINE ) == SfxItemState::SET ) + { + if( aSet.Get( EE_CHAR_UNDERLINE ).GetLineStyle() != LINESTYLE_NONE ) + xMenu->set_active(".uno:Underline", true); + } + + xMenu->insert(nInsertPos++, ".uno:Strikeout", + vcl::CommandInfoProvider::GetMenuLabelForCommand( + vcl::CommandInfoProvider::GetCommandProperties(".uno:Strikeout", aModuleName)), + nullptr, nullptr, vcl::CommandInfoProvider::GetXGraphicForCommand(".uno:Strikeout", xFrame), + TRISTATE_TRUE); + + if ( aSet.GetItemState( EE_CHAR_STRIKEOUT ) == SfxItemState::SET ) + { + if( aSet.Get( EE_CHAR_STRIKEOUT ).GetStrikeout() != STRIKEOUT_NONE ) + xMenu->set_active(".uno:Strikeout", true); + } + + xMenu->insert_separator(nInsertPos++, "separator2"); } - } - else - { - if (mbMouseOverButton) + + xMenu->insert(nInsertPos++, ".uno:Copy", + vcl::CommandInfoProvider::GetMenuLabelForCommand( + vcl::CommandInfoProvider::GetCommandProperties(".uno:Copy", aModuleName)), + nullptr, nullptr, vcl::CommandInfoProvider::GetXGraphicForCommand(".uno:Copy", xFrame), + TRISTATE_INDET); + + xMenu->insert(nInsertPos++, ".uno:Paste", + vcl::CommandInfoProvider::GetMenuLabelForCommand( + vcl::CommandInfoProvider::GetCommandProperties(".uno:Paste", aModuleName)), + nullptr, nullptr, vcl::CommandInfoProvider::GetXGraphicForCommand(".uno:Paste", xFrame), + TRISTATE_INDET); + + bool bCanPaste = false; + if (bEditable) { - Invalidate(maRectMetaButton); - mbMouseOverButton = false; + TransferableDataHelper aDataHelper(TransferableDataHelper::CreateFromClipboard(GetSystemClipboard())); + bCanPaste = aDataHelper.GetFormatCount() != 0; } - } -} -void AnnotationWindow::MouseButtonDown( const MouseEvent& rMEvt ) -{ - if (!mbReadonly && maRectMetaButton.IsInside(PixelToLogic(rMEvt.GetPosPixel())) && rMEvt.IsLeft()) - { - // context menu - ::tools::Rectangle aRect(LogicToPixel(maRectMetaButton.BottomLeft()),LogicToPixel(maRectMetaButton.BottomLeft())); - mrManager.ExecuteAnnotationContextMenu( mxAnnotation, static_cast<vcl::Window*>(this), aRect, true ); - } -} + xMenu->insert_separator(nInsertPos++, "separator3"); -void AnnotationWindow::Command( const CommandEvent& rCEvt ) -{ - if ( rCEvt.GetCommand() == CommandEventId::ContextMenu ) - { - if( mpMeta->IsVisible() &&(mpMeta->GetPosPixel().Y() < rCEvt.GetMousePosPixel().Y()) ) - return; - mrManager.ExecuteAnnotationContextMenu( mxAnnotation, this, ::tools::Rectangle(rCEvt.GetMousePosPixel(),Size(1,1)) ); - } - else - { - FloatingWindow::Command(rCEvt); - } -} + xMenu->set_sensitive(".uno:Copy", mrContents.GetOutlinerView()->HasSelection()); + xMenu->set_sensitive(".uno:Paste", bCanPaste); -void AnnotationWindow::GetFocus() -{ - if( mpTextWindow ) - mpTextWindow->GrabFocus(); - else - FloatingWindow::GetFocus(); -} + auto sId = xMenu->popup_at_rect(pPopupParent, aRect); -void AnnotationWindow::ExecuteSlot( sal_uInt16 nSID ) -{ - if( nSID == SID_COPY ) - { - getView()->Copy(); - } - else if( nSID == SID_PASTE ) - { - getView()->PasteSpecial(); - DoResize(); - } - else - { - SfxItemSet aEditAttr(getView()->GetAttribs()); - SfxItemSet aNewAttr(mpOutliner->GetEmptyItemSet()); - - switch( nSID ) + if (sId == ".uno:ReplyToAnnotation") { - case SID_ATTR_CHAR_WEIGHT: + const SfxUnoAnyItem aItem( SID_REPLYTO_POSTIT, Any( xAnnotation ) ); + pDispatcher->ExecuteList(SID_REPLYTO_POSTIT, + SfxCallMode::ASYNCHRON, { &aItem }); + } + else if (sId == ".uno:DeleteAnnotation") { - FontWeight eFW = aEditAttr.Get( EE_CHAR_WEIGHT ).GetWeight(); - aNewAttr.Put( SvxWeightItem( eFW == WEIGHT_NORMAL ? WEIGHT_BOLD : WEIGHT_NORMAL, EE_CHAR_WEIGHT ) ); + const SfxUnoAnyItem aItem( SID_DELETE_POSTIT, Any( xAnnotation ) ); + pDispatcher->ExecuteList(SID_DELETE_POSTIT, SfxCallMode::ASYNCHRON, + { &aItem }); } - break; - case SID_ATTR_CHAR_POSTURE: + else if (sId == ".uno:DeleteAllAnnotationByAuthor") { - FontItalic eFI = aEditAttr.Get( EE_CHAR_ITALIC ).GetPosture(); - aNewAttr.Put( SvxPostureItem( eFI == ITALIC_NORMAL ? ITALIC_NONE : ITALIC_NORMAL, EE_CHAR_ITALIC ) ); + const SfxStringItem aItem( SID_DELETEALLBYAUTHOR_POSTIT, sAuthor ); + pDispatcher->ExecuteList( SID_DELETEALLBYAUTHOR_POSTIT, + SfxCallMode::ASYNCHRON, { &aItem }); } - break; - case SID_ATTR_CHAR_UNDERLINE: + else if (sId == ".uno:DeleteAllAnnotation") + pDispatcher->Execute( SID_DELETEALL_POSTIT ); + else if (sId == ".uno:Copy") { - FontLineStyle eFU = aEditAttr. Get( EE_CHAR_UNDERLINE ).GetLineStyle(); - aNewAttr.Put( SvxUnderlineItem( eFU == LINESTYLE_SINGLE ? LINESTYLE_NONE : LINESTYLE_SINGLE, EE_CHAR_UNDERLINE ) ); + mrContents.GetOutlinerView()->Copy(); } - break; - case SID_ATTR_CHAR_STRIKEOUT: + else if (sId == ".uno:Paste") { - FontStrikeout eFSO = aEditAttr.Get( EE_CHAR_STRIKEOUT ).GetStrikeout(); - aNewAttr.Put( SvxCrossedOutItem( eFSO == STRIKEOUT_SINGLE ? STRIKEOUT_NONE : STRIKEOUT_SINGLE, EE_CHAR_STRIKEOUT ) ); + mrContents.GetOutlinerView()->PasteSpecial(); + mrContents.DoResize(); } - break; + else if (!sId.isEmpty()) + { + SfxItemSet aEditAttr(mrContents.GetOutlinerView()->GetAttribs()); + SfxItemSet aNewAttr(mrContents.GetOutliner()->GetEmptyItemSet()); + + if (sId == ".uno:Bold") + { + FontWeight eFW = aEditAttr.Get( EE_CHAR_WEIGHT ).GetWeight(); + aNewAttr.Put( SvxWeightItem( eFW == WEIGHT_NORMAL ? WEIGHT_BOLD : WEIGHT_NORMAL, EE_CHAR_WEIGHT ) ); + } + else if (sId == ".uno:Italic") + { + FontItalic eFI = aEditAttr.Get( EE_CHAR_ITALIC ).GetPosture(); + aNewAttr.Put( SvxPostureItem( eFI == ITALIC_NORMAL ? ITALIC_NONE : ITALIC_NORMAL, EE_CHAR_ITALIC ) ); + } + else if (sId == ".uno:Underline") + { + FontLineStyle eFU = aEditAttr. Get( EE_CHAR_UNDERLINE ).GetLineStyle(); + aNewAttr.Put( SvxUnderlineItem( eFU == LINESTYLE_SINGLE ? LINESTYLE_NONE : LINESTYLE_SINGLE, EE_CHAR_UNDERLINE ) ); + } + else if (sId == ".uno:Strikeout") + { + FontStrikeout eFSO = aEditAttr.Get( EE_CHAR_STRIKEOUT ).GetStrikeout(); + aNewAttr.Put( SvxCrossedOutItem( eFSO == STRIKEOUT_SINGLE ? STRIKEOUT_NONE : STRIKEOUT_SINGLE, EE_CHAR_STRIKEOUT ) ); + } + + mrContents.GetOutlinerView()->SetAttribs( aNewAttr ); } - getView()->SetAttribs( aNewAttr ); + + return true; } + return WeldEditView::Command(rCEvt); +} + +void AnnotationWindow::GetFocus() +{ + if (mxContents) + mxContents->GrabFocus(); + else + FloatingWindow::GetFocus(); } } diff --git a/sd/source/ui/annotations/annotationwindow.hxx b/sd/source/ui/annotations/annotationwindow.hxx index 3d84202023f2..c976322af652 100644 --- a/sd/source/ui/annotations/annotationwindow.hxx +++ b/sd/source/ui/annotations/annotationwindow.hxx @@ -17,15 +17,14 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ -#ifndef INCLUDED_SD_SOURCE_UI_ANNOTATIONS_ANNOTATIONWINDOW_HXX -#define INCLUDED_SD_SOURCE_UI_ANNOTATIONS_ANNOTATIONWINDOW_HXX +#pragma once #include <vcl/ctrl.hxx> #include <vcl/floatwin.hxx> -#include <vcl/fixed.hxx> -#include <vcl/scrbar.hxx> +#include <vcl/InterimItemWindow.hxx> #include <tools/long.hxx> #include <basegfx/polygon/b2dpolygon.hxx> +#include <svx/weldeditview.hxx> namespace com::sun::star::office { class XAnnotation; } @@ -41,30 +40,96 @@ class AnnotationWindow; class DrawDocShell; class TextApiObject; -class AnnotationTextWindow : public Control +class AnnotationContents; + +class AnnotationTextWindow : public WeldEditView { private: - OutlinerView* mpOutlinerView; - VclPtr<AnnotationWindow> mpAnnotationWindow; + AnnotationContents& mrContents; + +public: + AnnotationTextWindow(AnnotationContents& rContents); + + virtual EditView* GetEditView() const override; + + virtual EditEngine* GetEditEngine() const override; + + virtual void EditViewScrollStateChange() override; -protected: - virtual void Paint( vcl::RenderContext& /*rRenderContext*/, const ::tools::Rectangle& rRect) override; - virtual void KeyInput( const KeyEvent& rKeyEvt ) override; - virtual void MouseMove( const MouseEvent& rMEvt ) override; - virtual void MouseButtonDown( const MouseEvent& rMEvt ) override; - virtual void MouseButtonUp( const MouseEvent& rMEvt ) override; - virtual void Command( const CommandEvent& rCEvt ) override; + void SetDrawingArea(weld::DrawingArea* pDrawingArea) override; + + virtual void Paint(vcl::RenderContext& rRenderContext, const ::tools::Rectangle& rRect) override; + virtual bool KeyInput(const KeyEvent& rKeyEvt) override; + virtual bool Command(const CommandEvent& rCEvt) override; +}; + +class AnnotationContents final : public InterimItemWindow +{ +private: + DrawDocShell* mpDocShell; + SdDrawDocument* mpDoc; + bool mbReadonly; + bool mbProtected; + + css::uno::Reference< css::office::XAnnotation > mxAnnotation; + +public: + Color maColor; + Color maColorDark; + Color maColorLight; + +private: + vcl::Font maLabelFont; + + std::unique_ptr<OutlinerView> mpOutlinerView; + std::unique_ptr<::Outliner> mpOutliner; + + std::unique_ptr<weld::ScrolledWindow> mxVScrollbar; + std::unique_ptr<WeldEditView> mxTextControl; + std::unique_ptr<weld::CustomWeld> mxTextControlWin; + std::unique_ptr<weld::Label> mxMeta; + std::unique_ptr<weld::MenuButton> mxMenuButton; + + DECL_LINK(ScrollHdl, weld::ScrolledWindow&, void); + DECL_LINK(MenuItemSelectedHdl, const OString&, void); + DECL_LINK(MenuButtonToggledHdl, weld::ToggleButton&, void); + + static sal_Int32 GetPrefScrollbarWidth() { return 16; } public: - AnnotationTextWindow( AnnotationWindow* pParent, WinBits nBits ); - virtual ~AnnotationTextWindow() override; + AnnotationContents(vcl::Window* pParent, DrawDocShell* pDocShell); + + void InitControls(); + void DoResize(); + void ResizeIfNecessary(::tools::Long aOldHeight, ::tools::Long aNewHeight); + void SetScrollbar(); + void StartEdit(); + + void setAnnotation(const css::uno::Reference<css::office::XAnnotation>& xAnnotation); + const css::uno::Reference<css::office::XAnnotation>& getAnnotation() const { return mxAnnotation; } + + void SaveToDocument(); + + ::tools::Long GetPostItTextHeight(); + + DrawDocShell* DocShell() { return mpDocShell; } + + void SetLanguage(const SvxLanguageItem &aNewItem); + + void Rescale(); + + void ToggleInsMode(); + + bool IsProtected() const { return mbProtected; } + + OutlinerView* GetOutlinerView() { return mpOutlinerView.get();} + ::Outliner* GetOutliner() { return mpOutliner.get();} + virtual ~AnnotationContents() override { disposeOnce(); } virtual void dispose() override; - void SetOutlinerView( OutlinerView* pOutlinerView ) { mpOutlinerView = pOutlinerView; } + virtual void GetFocus() override; - virtual OUString GetSurroundingText() const override; - virtual Selection GetSurroundingTextSelection() const override; - virtual bool DeleteSurroundingText(const Selection& rSelection) override; + void SetColor(); }; class AnnotationWindow : public FloatingWindow @@ -74,66 +139,19 @@ class AnnotationWindow : public FloatingWindow DrawDocShell* mpDocShell; SdDrawDocument* mpDoc; - std::unique_ptr<OutlinerView> mpOutlinerView; - std::unique_ptr<::Outliner> mpOutliner; - VclPtr<ScrollBar> mpVScrollbar; - css::uno::Reference< css::office::XAnnotation > mxAnnotation; - bool mbReadonly; - bool mbProtected; - bool mbMouseOverButton; - VclPtr<AnnotationTextWindow> mpTextWindow; - VclPtr<FixedText> mpMeta; - ::tools::Rectangle maRectMetaButton; - basegfx::B2DPolygon maPopupTriangle; - - protected: - DECL_LINK(ScrollHdl, ScrollBar*, void); + VclPtr<AnnotationContents> mxContents; public: AnnotationWindow( AnnotationManagerImpl& rManager, DrawDocShell* pDocShell, vcl::Window* pParent ); virtual ~AnnotationWindow() override; virtual void dispose() override; - void StartEdit(); - - void setAnnotation( const css::uno::Reference< css::office::XAnnotation >& xAnnotation ); - - void ExecuteSlot( sal_uInt16 nSID ); - - DrawDocShell* DocShell() { return mpDocShell; } - OutlinerView* getView() { return mpOutlinerView.get(); } - ::Outliner* Engine() { return mpOutliner.get(); } - SdDrawDocument* Doc() { return mpDoc; } - - ::tools::Long GetPostItTextHeight(); + AnnotationContents& GetContents() const { return *mxContents; } void InitControls(); void DoResize(); - void ResizeIfNecessary(::tools::Long aOldHeight, ::tools::Long aNewHeight); - void SetScrollbar(); - - void Rescale(); - - bool IsProtected() const { return mbProtected; } - - void SetLanguage(const SvxLanguageItem &aNewItem); - static sal_Int32 GetScrollbarWidth() { return 16; } - - void ToggleInsMode(); - - virtual void Deactivate() override; - virtual void Paint( vcl::RenderContext& /*rRenderContext*/, const ::tools::Rectangle& rRect) override; - virtual void MouseMove( const MouseEvent& rMEvt ) override; - virtual void MouseButtonDown( const MouseEvent& rMEvt ) override; - virtual void Command( const CommandEvent& rCEvt ) override; virtual void GetFocus() override; - - void SetColor(); - - Color maColor; - Color maColorDark; - Color maColorLight; }; TextApiObject* getTextApiObject( const css::uno::Reference< css::office::XAnnotation >& xAnnotation ); @@ -141,6 +159,4 @@ TextApiObject* getTextApiObject( const css::uno::Reference< css::office::XAnnota } // namespace sd -#endif - /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/uiconfig/simpress/ui/annotation.ui b/sd/uiconfig/simpress/ui/annotation.ui new file mode 100644 index 000000000000..9daa415d28c7 --- /dev/null +++ b/sd/uiconfig/simpress/ui/annotation.ui @@ -0,0 +1,164 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Generated with glade 3.38.2 --> +<interface domain="sd"> + <requires lib="gtk+" version="3.20"/> + <object class="GtkMenu" id="menu"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <child> + <object class="GtkMenuItem" id=".uno:ReplyToAnnotation"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes" context="annotationmenu|reply">_Reply</property> + <property name="use_underline">True</property> + </object> + </child> + <child> + <object class="GtkSeparatorMenuItem" id="separator"> + <property name="visible">True</property> + <property name="can_focus">False</property> + </object> + </child> + <child> + <object class="GtkMenuItem" id=".uno:DeleteAnnotation"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes" context="annotationmenu|delete">_Delete Comment</property> + <property name="use_underline">True</property> + </object> + </child> + <child> + <object class="GtkMenuItem" id=".uno:DeleteAllAnnotationByAuthor"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes" context="annotationmenu|deleteby">Delete All Comments b_y %1</property> + <property name="use_underline">True</property> + </object> + </child> + <child> + <object class="GtkMenuItem" id=".uno:DeleteAllAnnotation"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes" context="annotationmenu|deleteall">Delete _All Comments</property> + <property name="use_underline">True</property> + </object> + </child> + </object> + <object class="GtkBox" id="Annotation"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="events">GDK_BUTTON_MOTION_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_STRUCTURE_MASK</property> + <property name="hexpand">True</property> + <property name="vexpand">True</property> + <property name="orientation">vertical</property> + <child> + <object class="GtkScrolledWindow" id="scrolledwindow"> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="hexpand">True</property> + <property name="vexpand">True</property> + <property name="hscrollbar-policy">never</property> + <child> + <object class="GtkViewport"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="hexpand">True</property> + <property name="vexpand">True</property> + <child> + <object class="GtkBox"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="hexpand">True</property> + <property name="vexpand">True</property> + <property name="orientation">vertical</property> + <child> + <object class="GtkDrawingArea" id="editview"> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="events">GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_FOCUS_CHANGE_MASK | GDK_STRUCTURE_MASK</property> + <property name="hexpand">True</property> + <property name="vexpand">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + </object> + </child> + </object> + </child> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkBox"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <child> + <object class="GtkBox"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="hexpand">True</property> + <property name="orientation">vertical</property> + <child> + <object class="GtkLabel" id="meta"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="label">label</property> + <property name="xalign">0</property> + <property name="yalign">0</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkMenuButton" id="menubutton"> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="focus-on-click">False</property> + <property name="label" translatable="no"></property> + <property name="receives-default">True</property> + <property name="valign">start</property> + <property name="margin-end">10</property> + <property name="margin-top">5</property> + <property name="relief">none</property> + <property name="draw-indicator">True</property> + <property name="popup">menu</property> + <child> + <placeholder/> + </child> + <style> + <class name="small-button"/> + </style> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> +</interface> diff --git a/sd/uiconfig/simpress/ui/annotationmenu.ui b/sd/uiconfig/simpress/ui/annotationmenu.ui deleted file mode 100644 index f617663f104b..000000000000 --- a/sd/uiconfig/simpress/ui/annotationmenu.ui +++ /dev/null @@ -1,117 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- Generated with glade 3.20.0 --> -<interface domain="sd"> - <requires lib="gtk+" version="3.20"/> - <object class="GtkMenu" id="menu"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <child> - <object class="GtkMenuItem" id="reply"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="action_name">.uno:ReplyToAnnotation</property> - <property name="label" translatable="yes" context="annotationmenu|reply">_Reply</property> - <property name="use_underline">True</property> - </object> - </child> - <child> - <object class="GtkSeparatorMenuItem" id="menuitem1"> - <property name="visible">True</property> - <property name="can_focus">False</property> - </object> - </child> - <child> - <object class="GtkCheckMenuItem" id="bold"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="action_name">.uno:Bold</property> - <property name="label" translatable="yes" context="annotationmenu|bold">_Bold</property> - <property name="use_underline">True</property> - </object> - </child> - <child> - <object class="GtkCheckMenuItem" id="italic"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="action_name">.uno:Italic</property> - <property name="label" translatable="yes" context="annotationmenu|italic">_Italic</property> - <property name="use_underline">True</property> - </object> - </child> - <child> - <object class="GtkCheckMenuItem" id="underline"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="action_name">.uno:Underline</property> - <property name="label" translatable="yes" context="annotationmenu|underline">_Underline</property> - <property name="use_underline">True</property> - </object> - </child> - <child> - <object class="GtkCheckMenuItem" id="strike"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="action_name">.uno:Strikeout</property> - <property name="label" translatable="yes" context="annotationmenu|strike">_Strikethrough</property> - <property name="use_underline">True</property> - </object> - </child> - <child> - <object class="GtkSeparatorMenuItem" id="menuitem2"> - <property name="visible">True</property> - <property name="can_focus">False</property> - </object> - </child> - <child> - <object class="GtkMenuItem" id="copy"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="action_name">.uno:Copy</property> - <property name="label" translatable="yes" context="annotationmenu|copy">_Copy</property> - <property name="use_underline">True</property> - </object> - </child> - <child> - <object class="GtkMenuItem" id="paste"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="action_name">.uno:Paste</property> - <property name="label" translatable="yes" context="annotationmenu|paste">_Paste</property> - <property name="use_underline">True</property> - </object> - </child> - <child> - <object class="GtkSeparatorMenuItem" id="menuitem3"> - <property name="visible">True</property> - <property name="can_focus">False</property> - </object> - </child> - <child> - <object class="GtkMenuItem" id="delete"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="action_name">.uno:DeleteAnnotation</property> - <property name="label" translatable="yes" context="annotationmenu|delete">_Delete Comment</property> - <property name="use_underline">True</property> - </object> - </child> - <child> - <object class="GtkMenuItem" id="deleteby"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="action_name">.uno:DeleteAllAnnotationByAuthor</property> - <property name="label" translatable="yes" context="annotationmenu|deleteby">Delete All Comments b_y %1</property> - <property name="use_underline">True</property> - </object> - </child> - <child> - <object class="GtkMenuItem" id="deleteall"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="action_name">.uno:DeleteAllAnnotation</property> - <property name="label" translatable="yes" context="annotationmenu|deleteall">Delete _All Comments</property> - <property name="use_underline">True</property> - </object> - </child> - </object> -</interface> diff --git a/sd/uiconfig/simpress/ui/annotationtagmenu.ui b/sd/uiconfig/simpress/ui/annotationtagmenu.ui index 1048e8f45a12..9996b5730efa 100644 --- a/sd/uiconfig/simpress/ui/annotationtagmenu.ui +++ b/sd/uiconfig/simpress/ui/annotationtagmenu.ui @@ -6,7 +6,7 @@ <property name="visible">True</property> <property name="can_focus">False</property> <child> - <object class="GtkMenuItem" id="reply"> + <object class="GtkMenuItem" id=".uno:ReplyToAnnotation"> <property name="visible">True</property> <property name="can_focus">False</property> <property name="label" translatable="yes" context="annotationtagmenu|reply">_Reply</property> @@ -14,13 +14,13 @@ </object> </child> <child> - <object class="GtkSeparatorMenuItem" id="menuitem1"> + <object class="GtkSeparatorMenuItem" id="separator"> <property name="visible">True</property> <property name="can_focus">False</property> </object> </child> <child> - <object class="GtkMenuItem" id="delete"> + <object class="GtkMenuItem" id=".uno:DeleteAnnotation"> <property name="visible">True</property> <property name="can_focus">False</property> <property name="label" translatable="yes" context="annotationtagmenu|delete">_Delete Comment</property> @@ -28,7 +28,7 @@ </object> </child> <child> - <object class="GtkMenuItem" id="deleteby"> + <object class="GtkMenuItem" id=".uno:DeleteAllAnnotationByAuthor"> <property name="visible">True</property> <property name="can_focus">False</property> <property name="label" translatable="yes" context="annotationtagmenu|deleteby">Delete All Comments b_y %1</property> @@ -36,7 +36,7 @@ </object> </child> <child> - <object class="GtkMenuItem" id="deleteall"> + <object class="GtkMenuItem" id=".uno:DeleteAllAnnotation"> <property name="visible">True</property> <property name="can_focus">False</property> <property name="label" translatable="yes" context="annotationtagmenu|deleteall">Delete _All Comments</property> diff --git a/solenv/sanitizers/ui/modules/simpress.suppr b/solenv/sanitizers/ui/modules/simpress.suppr index 2c0949d1a6a9..33453296bdea 100644 --- a/solenv/sanitizers/ui/modules/simpress.suppr +++ b/solenv/sanitizers/ui/modules/simpress.suppr @@ -1,3 +1,4 @@ +sd/uiconfig/simpress/ui/annotation.ui://GtkDrawingArea[@id='editview'] no-labelled-by sd/uiconfig/simpress/ui/customanimationfragment.ui://GtkSpinButton[@id='fontsize'] no-labelled-by sd/uiconfig/simpress/ui/customanimationfragment.ui://GtkSpinButton[@id='rotate'] no-labelled-by sd/uiconfig/simpress/ui/customanimationfragment.ui://GtkSpinButton[@id='transparent'] no-labelled-by diff --git a/sw/source/uibase/docvw/AnnotationWin.cxx b/sw/source/uibase/docvw/AnnotationWin.cxx index 084aa066bf03..19565529d607 100644 --- a/sw/source/uibase/docvw/AnnotationWin.cxx +++ b/sw/source/uibase/docvw/AnnotationWin.cxx @@ -81,6 +81,7 @@ void collectUIInformation( const OUString& aevent , const OUString& aID ) namespace sw::annotation { +// see AnnotationContents in sd for something similar SwAnnotationWin::SwAnnotationWin( SwEditWin& rEditWin, SwPostItMgr& aMgr, SwSidebarItem& rSidebarItem, diff --git a/sw/source/uibase/docvw/AnnotationWin2.cxx b/sw/source/uibase/docvw/AnnotationWin2.cxx index 8e43d4d62f84..e65ef1254933 100644 --- a/sw/source/uibase/docvw/AnnotationWin2.cxx +++ b/sw/source/uibase/docvw/AnnotationWin2.cxx @@ -702,11 +702,13 @@ void SwAnnotationWin::DoResize() mpOutliner->SetPaperSize( PixelToLogic( Size(aWidth,aHeight) ) ) ; + + tools::Rectangle aOutputArea = PixelToLogic(tools::Rectangle(0, 0, aWidth, aHeight)); if (mxVScrollbar->get_vpolicy() == VclPolicyType::NEVER) - { // if we do not have a scrollbar anymore, we want to see the complete text - mpOutlinerView->SetVisArea( PixelToLogic( tools::Rectangle(0,0,aWidth,aHeight) ) ); + { + // if we do not have a scrollbar anymore, we want to see the complete text + mpOutlinerView->SetVisArea(aOutputArea); } - tools::Rectangle aOutputArea = PixelToLogic(tools::Rectangle(0, 0, aWidth, aHeight)); mpOutlinerView->SetOutputArea(aOutputArea); mpOutlinerView->ShowCursor(true, true); diff --git a/vcl/inc/salvtables.hxx b/vcl/inc/salvtables.hxx index 2416aa6ab696..3e09d2b12f0d 100644 --- a/vcl/inc/salvtables.hxx +++ b/vcl/inc/salvtables.hxx @@ -153,7 +153,7 @@ public: virtual void clear() override; virtual void insert(int pos, const OUString& rId, const OUString& rStr, const OUString* pIconName, VirtualDevice* pImageSurface, - const css::uno::Reference<css::graphic::XGraphic>* pImage, + const css::uno::Reference<css::graphic::XGraphic>& rImage, TriState eCheckRadioFalse) override; virtual void insert_separator(int pos, const OUString& rId) override; virtual void remove(const OString& rId) override; diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx index c5fba71e2b1a..867781476a18 100644 --- a/vcl/source/app/salvtables.cxx +++ b/vcl/source/app/salvtables.cxx @@ -694,7 +694,7 @@ Image createImage(const VirtualDevice& rDevice) sal_uInt16 insert_to_menu(sal_uInt16 nLastId, PopupMenu* pMenu, int pos, std::u16string_view rId, const OUString& rStr, const OUString* pIconName, const VirtualDevice* pImageSurface, - const css::uno::Reference<css::graphic::XGraphic>* pImage, + const css::uno::Reference<css::graphic::XGraphic>& rImage, TriState eCheckRadioFalse) { const sal_uInt16 nNewid = nLastId + 1; @@ -717,9 +717,9 @@ sal_uInt16 insert_to_menu(sal_uInt16 nLastId, PopupMenu* pMenu, int pos, std::u1 { pMenu->SetItemImage(nNewid, createImage(*pImageSurface)); } - else if (pImage) + else if (rImage) { - pMenu->SetItemImage(nNewid, Image(*pImage)); + pMenu->SetItemImage(nNewid, Image(rImage)); } return nNewid; } @@ -772,10 +772,10 @@ void SalInstanceMenu::set_visible(const OString& rIdent, bool bShow) void SalInstanceMenu::clear() { m_xMenu->Clear(); } void SalInstanceMenu::insert(int pos, const OUString& rId, const OUString& rStr, const OUString* pIconName, VirtualDevice* pImageSurface, - const css::uno::Reference<css::graphic::XGraphic>* pImage, + const css::uno::Reference<css::graphic::XGraphic>& rImage, TriState eCheckRadioFalse) { - m_nLastId = insert_to_menu(m_nLastId, m_xMenu, pos, rId, rStr, pIconName, pImageSurface, pImage, + m_nLastId = insert_to_menu(m_nLastId, m_xMenu, pos, rId, rStr, pIconName, pImageSurface, rImage, eCheckRadioFalse); } void SalInstanceMenu::insert_separator(int pos, const OUString& rId) diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx index c5b47e5080e3..2091c41d4135 100644 --- a/vcl/unx/gtk3/gtk3gtkinst.cxx +++ b/vcl/unx/gtk3/gtk3gtkinst.cxx @@ -8282,7 +8282,7 @@ public: virtual void insert(int pos, const OUString& rId, const OUString& rStr, const OUString* pIconName, VirtualDevice* pImageSurface, - const css::uno::Reference<css::graphic::XGraphic>* pGraphic, + const css::uno::Reference<css::graphic::XGraphic>& rGraphic, TriState eCheckRadioFalse) override { GtkWidget* pImage = nullptr; @@ -8298,9 +8298,9 @@ public: { pImage = image_new_from_virtual_device(*pImageSurface); } - else if (pGraphic) + else if (rGraphic) { - if (GdkPixbuf* pixbuf = getPixbuf(*pGraphic)) + if (GdkPixbuf* pixbuf = getPixbuf(rGraphic)) { pImage = gtk_image_new_from_pixbuf(pixbuf); g_object_unref(pixbuf); |