diff options
author | Cédric Bosdonnat <cedric.bosdonnat@free.fr> | 2012-10-05 15:37:26 +0200 |
---|---|---|
committer | Cédric Bosdonnat <cedric.bosdonnat@free.fr> | 2012-10-11 17:31:17 +0200 |
commit | 97aa108f2b595145d63b00d515489030a849957e (patch) | |
tree | a7c0354f5699e9e059ae1baf9eb157ab143d71a4 /sfx2 | |
parent | b66a72cba2f38c3ddc9e7c91a1afd5d8a2279ed8 (diff) |
InfoBars: first implementation
Change-Id: I4b18f19f5cf13d648a8d10cc31c63bb330a86b6f
Diffstat (limited to 'sfx2')
-rw-r--r-- | sfx2/Library_sfx.mk | 1 | ||||
-rw-r--r-- | sfx2/Package_inc.mk | 1 | ||||
-rw-r--r-- | sfx2/inc/sfx2/infobar.hxx | 77 | ||||
-rw-r--r-- | sfx2/inc/sfx2/sfxsids.hrc | 1 | ||||
-rw-r--r-- | sfx2/inc/sfx2/viewfrm.hxx | 8 | ||||
-rw-r--r-- | sfx2/source/appl/appreg.cxx | 2 | ||||
-rw-r--r-- | sfx2/source/dialog/infobar.cxx | 283 | ||||
-rw-r--r-- | sfx2/source/view/viewfrm.cxx | 11 |
8 files changed, 384 insertions, 0 deletions
diff --git a/sfx2/Library_sfx.mk b/sfx2/Library_sfx.mk index baf71388e393..eae3511b8511 100644 --- a/sfx2/Library_sfx.mk +++ b/sfx2/Library_sfx.mk @@ -153,6 +153,7 @@ $(eval $(call gb_Library_add_exception_objects,sfx,\ sfx2/source/dialog/filedlghelper \ sfx2/source/dialog/filtergrouping \ sfx2/source/dialog/itemconnect \ + sfx2/source/dialog/infobar \ sfx2/source/dialog/inputdlg \ sfx2/source/dialog/mailmodel \ sfx2/source/dialog/bluthsnd \ diff --git a/sfx2/Package_inc.mk b/sfx2/Package_inc.mk index 4156354412aa..3292506364fb 100644 --- a/sfx2/Package_inc.mk +++ b/sfx2/Package_inc.mk @@ -63,6 +63,7 @@ $(eval $(call gb_Package_add_file,sfx2_inc,inc/sfx2/htmlmode.hxx,sfx2/htmlmode.h $(eval $(call gb_Package_add_file,sfx2_inc,inc/sfx2/imagemgr.hxx,sfx2/imagemgr.hxx)) $(eval $(call gb_Package_add_file,sfx2_inc,inc/sfx2/imgdef.hxx,sfx2/imgdef.hxx)) $(eval $(call gb_Package_add_file,sfx2_inc,inc/sfx2/imgmgr.hxx,sfx2/imgmgr.hxx)) +$(eval $(call gb_Package_add_file,sfx2_inc,inc/sfx2/infobar.hxx,sfx2/infobar.hxx)) $(eval $(call gb_Package_add_file,sfx2_inc,inc/sfx2/ipclient.hxx,sfx2/ipclient.hxx)) $(eval $(call gb_Package_add_file,sfx2_inc,inc/sfx2/itemconnect.hxx,sfx2/itemconnect.hxx)) $(eval $(call gb_Package_add_file,sfx2_inc,inc/sfx2/itemwrapper.hxx,sfx2/itemwrapper.hxx)) diff --git a/sfx2/inc/sfx2/infobar.hxx b/sfx2/inc/sfx2/infobar.hxx new file mode 100644 index 000000000000..00d521f7749b --- /dev/null +++ b/sfx2/inc/sfx2/infobar.hxx @@ -0,0 +1,77 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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/. + */ +#ifndef _SFX2_MESSAGEBAR_HXX_ +#define _SFX2_MESSAGEBAR_HXX_ + +#include <vector> + +#include <vcl/button.hxx> +#include <vcl/fixed.hxx> + +#include <sfx2/dllapi.h> +#include <sfx2/childwin.hxx> + +/** SfxChildWindow for positioning the InfoBar in the view. + */ +class SFX2_DLLPUBLIC SfxInfoBarContainerChild : public SfxChildWindow +{ + private: + SfxBindings* m_pBindings; + + public: + SfxInfoBarContainerChild( Window* pParent, + sal_uInt16 nId, + SfxBindings* pBindings, + SfxChildWinInfo* pInfo ); + virtual ~SfxInfoBarContainerChild(); + + SFX_DECL_CHILDWINDOW_WITHID( SfxInfoBarContainerChild ); + + void Update( ); +}; + +/** Class representing a single InfoBar to be added in a SfxInfoBarContainerWindow. + */ +class SfxInfoBarWindow : public Window +{ + private: + FixedText* m_pMessage; + Button* m_pCloseBtn; + std::vector< PushButton* > m_aActionBtns; + + public: + SfxInfoBarWindow( Window* parent, + const rtl::OUString& sMessage, + std::vector< PushButton* > aButtons ); + ~SfxInfoBarWindow( ); + + virtual void Paint( const Rectangle& ); + + private: + DECL_LINK( CloseHandler, void* ); +}; + +class SfxInfoBarContainerWindow : public Window +{ + private: + SfxInfoBarContainerChild* m_pChildWin; + std::vector< SfxInfoBarWindow* > m_pInfoBars; + + public: + SfxInfoBarContainerWindow( SfxInfoBarContainerChild* pChildWin ); + ~SfxInfoBarContainerWindow( ); + + void appendInfoBar( const rtl::OUString& sMessage, std::vector< PushButton* > aButtons ); + void removeInfoBar( SfxInfoBarWindow* pInfoBar ); +}; + + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sfx2/inc/sfx2/sfxsids.hrc b/sfx2/inc/sfx2/sfxsids.hrc index 549ac0ee4139..0d3522bd7b14 100644 --- a/sfx2/inc/sfx2/sfxsids.hrc +++ b/sfx2/inc/sfx2/sfxsids.hrc @@ -592,6 +592,7 @@ #define SID_HYPERLINK_GETLINK (SID_SVX_START + 361) #define SID_HYPERLINK_SETLINK (SID_SVX_START + 362) #define SID_NAVIGATOR (SID_SVX_START + 366) +#define SID_INFOBARCONTAINER (SID_SVX_START + 367) #define SID_TASKPANE (SID_SVX_START + 370) #define SID_ZOOM_NEXT (SID_SVX_START + 402) #define SID_ZOOM_PREV (SID_SVX_START + 403) diff --git a/sfx2/inc/sfx2/viewfrm.hxx b/sfx2/inc/sfx2/viewfrm.hxx index ce8622e0d6a8..26b5e47ca584 100644 --- a/sfx2/inc/sfx2/viewfrm.hxx +++ b/sfx2/inc/sfx2/viewfrm.hxx @@ -28,6 +28,7 @@ #include <sfx2/shell.hxx> #include <sfx2/sfxsids.hrc> #include <svl/poolitem.hxx> +#include <vcl/button.hxx> #include <com/sun/star/frame/status/Verb.hpp> #include <com/sun/star/frame/XModel.hpp> #include <com/sun/star/frame/XController2.hpp> @@ -184,6 +185,13 @@ public: void ChildWindowExecute(SfxRequest&); void ChildWindowState(SfxItemSet&); + /** Append a new InfoBar (see https://wiki.documentfoundation.org/Design/Whiteboards/Infobar). + + The buttons will be added from Right to Left at the right of the info bar. The parent, size + and position of each button will be changed: only the width will remain unchanged. + */ + void AppendInfoBar( const rtl::OUString& sMessage, std::vector< PushButton* > aButtons ); + SAL_DLLPRIVATE void SetDowning_Impl(); SAL_DLLPRIVATE void GetDocNumber_Impl(); SAL_DLLPRIVATE sal_Bool IsDowning_Impl() const; diff --git a/sfx2/source/appl/appreg.cxx b/sfx2/source/appl/appreg.cxx index c407d7330bff..0c54aa81fe97 100644 --- a/sfx2/source/appl/appreg.cxx +++ b/sfx2/source/appl/appreg.cxx @@ -27,6 +27,7 @@ #include <sfx2/templdlg.hxx> #include "inettbc.hxx" #include "sfx2/stbitem.hxx" +#include <sfx2/infobar.hxx> #include <sfx2/navigat.hxx> #include <sfx2/taskpane.hxx> #include <sfx2/module.hxx> @@ -56,6 +57,7 @@ void SfxApplication::Registrations_Impl() SfxPartChildWnd_Impl::RegisterChildWindow(); SfxTemplateDialogWrapper::RegisterChildWindow(sal_True); SfxDockingWrapper::RegisterChildWindow(); + SfxInfoBarContainerChild::RegisterChildWindow( sal_True, NULL, SFX_CHILDWIN_NEVERHIDE ); // Controller SfxToolBoxControl::RegisterControl(SID_REPEAT); diff --git a/sfx2/source/dialog/infobar.cxx b/sfx2/source/dialog/infobar.cxx new file mode 100644 index 000000000000..e72468ca4a47 --- /dev/null +++ b/sfx2/source/dialog/infobar.cxx @@ -0,0 +1,283 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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 <basegfx/polygon/b2dpolygon.hxx> +#include <drawinglayer/primitive2d/polygonprimitive2d.hxx> +#include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx> +#include <drawinglayer/processor2d/baseprocessor2d.hxx> +#include <drawinglayer/processor2d/processorfromoutputdevice.hxx> +#include <sfx2/bindings.hxx> +#include <sfx2/dispatch.hxx> +#include <sfx2/infobar.hxx> +#include <sfx2/objsh.hxx> +#include <sfx2/sfx.hrc> +#include <sfx2/viewsh.hxx> + +using namespace std; + +namespace +{ + class SfxCloseButton : public PushButton + { + public: + SfxCloseButton( Window* pParent ) : PushButton( pParent, 0 ) + { + } + + ~SfxCloseButton( ) { } + + virtual void Paint( const Rectangle& rRect ); + }; + + void SfxCloseButton::Paint( const Rectangle& ) + { + const drawinglayer::geometry::ViewInformation2D aNewViewInfos; + drawinglayer::processor2d::BaseProcessor2D * pProcessor = + drawinglayer::processor2d::createBaseProcessor2DFromOutputDevice( + *this, aNewViewInfos ); + + const Rectangle aRect( Rectangle( Point( 0, 0 ), PixelToLogic( GetSizePixel() ) ) ); + + drawinglayer::primitive2d::Primitive2DSequence aSeq( 2 ); + + basegfx::BColor aLightColor( 1.0, 1.0, 191.0 / 255.0 ); + basegfx::BColor aDarkColor( 217.0 / 255.0, 217.0 / 255.0, 78.0 / 255.0 ); + + // Light background + basegfx::B2DPolygon aPolygon; + aPolygon.append( basegfx::B2DPoint( aRect.Left( ), aRect.Top( ) ) ); + aPolygon.append( basegfx::B2DPoint( aRect.Right( ), aRect.Top( ) ) ); + aPolygon.append( basegfx::B2DPoint( aRect.Right( ), aRect.Bottom( ) ) ); + aPolygon.append( basegfx::B2DPoint( aRect.Left( ), aRect.Bottom( ) ) ); + aPolygon.setClosed( true ); + drawinglayer::primitive2d::PolyPolygonColorPrimitive2D* pBack = + new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D( + basegfx::B2DPolyPolygon( aPolygon ), aLightColor ); + aSeq[0] = pBack; + + drawinglayer::attribute::LineAttribute aLineAttribute( aDarkColor, 2.0 ); + + // Cross + basegfx::B2DPolyPolygon aCross; + basegfx::B2DPolygon aLine1; + aLine1.append( basegfx::B2DPoint( aRect.Left(), aRect.Top( ) ) ); + aLine1.append( basegfx::B2DPoint( aRect.Right(), aRect.Bottom( ) ) ); + aCross.append( aLine1 ); + basegfx::B2DPolygon aLine2; + aLine2.append( basegfx::B2DPoint( aRect.Right(), aRect.Top( ) ) ); + aLine2.append( basegfx::B2DPoint( aRect.Left(), aRect.Bottom( ) ) ); + aCross.append( aLine2 ); + + drawinglayer::primitive2d::PolyPolygonStrokePrimitive2D * pCross = + new drawinglayer::primitive2d::PolyPolygonStrokePrimitive2D ( + aCross, aLineAttribute, drawinglayer::attribute::StrokeAttribute( ) ); + + aSeq[1] = pCross; + + pProcessor->process( aSeq ); + delete pProcessor; + } +} + +SfxInfoBarWindow::SfxInfoBarWindow( Window* pParent, const rtl::OUString& sMessage, + vector< PushButton* > aButtons ) : + Window( pParent, 0 ), + m_pMessage( NULL ), + m_pCloseBtn( NULL ), + m_aActionBtns( aButtons ) +{ + long nWidth = pParent->GetSizePixel().getWidth(); + SetPosSizePixel( Point( 0, 0 ), Size( nWidth, 40 ) ); + m_pMessage = new FixedText( this, 0 ); + m_pMessage->SetText( sMessage ); + m_pMessage->SetBackground( Wallpaper( Color( 255, 255, 191 ) ) ); + m_pMessage->Show( ); + + m_pCloseBtn = new SfxCloseButton( this ); + m_pCloseBtn->SetPosSizePixel( Point( nWidth - 25, 15 ), Size( 10, 10 ) ); + m_pCloseBtn->SetClickHdl( LINK( this, SfxInfoBarWindow, CloseHandler ) ); + m_pCloseBtn->Show( ); + + // Reparent the buttons and place them on the right of the bar + long nX = m_pCloseBtn->GetPosPixel( ).getX( ) - 15; + long nBtnGap = 5; + for ( vector< PushButton* >::iterator it = m_aActionBtns.begin( ); + it != m_aActionBtns.end( ); ++it ) + { + PushButton* pBtn = *it; + pBtn->SetParent( this ); + long nBtnWidth = pBtn->GetSizePixel( ).getWidth(); + nX -= nBtnWidth; + pBtn->SetPosSizePixel( Point( nX, 5 ), Size( nBtnWidth, 30 ) ); + nX -= nBtnGap; + pBtn->Show( ); + } + + m_pMessage->SetPosSizePixel( Point( 10, 10 ), Size( nX - 20, 20 ) ); +} + +SfxInfoBarWindow::~SfxInfoBarWindow( ) +{ + delete m_pMessage; + delete m_pCloseBtn; + + for ( vector< PushButton* >::iterator it = m_aActionBtns.begin( ); + it != m_aActionBtns.end( ); ++it ) + { + delete *it; + } + m_aActionBtns.clear( ); +} + +void SfxInfoBarWindow::Paint( const Rectangle& rPaintRect ) +{ + const drawinglayer::geometry::ViewInformation2D aNewViewInfos; + drawinglayer::processor2d::BaseProcessor2D * pProcessor = + drawinglayer::processor2d::createBaseProcessor2DFromOutputDevice( + *this, aNewViewInfos ); + + const Rectangle aRect( Rectangle( Point( 0, 0 ), PixelToLogic( GetSizePixel() ) ) ); + + drawinglayer::primitive2d::Primitive2DSequence aSeq( 2 ); + + basegfx::BColor aLightColor( 1.0, 1.0, 191.0 / 255.0 ); + basegfx::BColor aDarkColor( 217.0 / 255.0, 217.0 / 255.0, 78.0 / 255.0 ); + + // Light background + basegfx::B2DPolygon aPolygon; + aPolygon.append( basegfx::B2DPoint( aRect.Left( ), aRect.Top( ) ) ); + aPolygon.append( basegfx::B2DPoint( aRect.Right( ), aRect.Top( ) ) ); + aPolygon.append( basegfx::B2DPoint( aRect.Right( ), aRect.Bottom( ) ) ); + aPolygon.append( basegfx::B2DPoint( aRect.Left( ), aRect.Bottom( ) ) ); + aPolygon.setClosed( true ); + drawinglayer::primitive2d::PolyPolygonColorPrimitive2D* pBack = + new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D( + basegfx::B2DPolyPolygon( aPolygon ), aLightColor ); + aSeq[0] = pBack; + + drawinglayer::attribute::LineAttribute aLineAttribute( aDarkColor, 1.0 ); + + // Bottom dark line + basegfx::B2DPolygon aPolygonBottom; + aPolygonBottom.append( basegfx::B2DPoint( aRect.Left(), aRect.Bottom( ) ) ); + aPolygonBottom.append( basegfx::B2DPoint( aRect.Right(), aRect.Bottom( ) ) ); + + drawinglayer::primitive2d::PolygonStrokePrimitive2D * pLineBottom = + new drawinglayer::primitive2d::PolygonStrokePrimitive2D ( + aPolygonBottom, aLineAttribute ); + + aSeq[1] = pLineBottom; + + pProcessor->process( aSeq ); + delete pProcessor; + + Window::Paint( rPaintRect ); +} + +IMPL_LINK_NOARG( SfxInfoBarWindow, CloseHandler ) +{ + ((SfxInfoBarContainerWindow*)GetParent())->removeInfoBar( this ); + return 0; +} + +SfxInfoBarContainerWindow::SfxInfoBarContainerWindow( SfxInfoBarContainerChild* pChildWin ) : + Window( pChildWin->GetParent( ), 0 ), + m_pChildWin( pChildWin ), + m_pInfoBars( ) +{ +} + +SfxInfoBarContainerWindow::~SfxInfoBarContainerWindow( ) +{ + for ( vector< SfxInfoBarWindow* >::iterator it = m_pInfoBars.begin( ); + it != m_pInfoBars.end( ); ++it ) + { + delete *it; + } + m_pInfoBars.clear( ); +} + +void SfxInfoBarContainerWindow::appendInfoBar( const rtl::OUString& sMessage, vector< PushButton* > aButtons ) +{ + Size aSize = GetSizePixel( ); + + SfxInfoBarWindow* pInfoBar = new SfxInfoBarWindow( this, sMessage, aButtons ); + pInfoBar->SetPosPixel( Point( 0, aSize.getHeight( ) ) ); + m_pInfoBars.push_back( pInfoBar ); + pInfoBar->Show( ); + + long nHeight = pInfoBar->GetSizePixel( ).getHeight( ); + aSize.setHeight( aSize.getHeight() + nHeight ); + SetSizePixel( aSize ); +} + +void SfxInfoBarContainerWindow::removeInfoBar( SfxInfoBarWindow* pInfoBar ) +{ + for ( vector< SfxInfoBarWindow* >::iterator it = m_pInfoBars.begin( ); + it != m_pInfoBars.end( ); ++it ) + { + if ( pInfoBar == *it ) + { + m_pInfoBars.erase( it ); + break; + } + } + delete pInfoBar; + + long nY = 0; + for ( vector< SfxInfoBarWindow* >::iterator it = m_pInfoBars.begin( ); it != m_pInfoBars.end( ); ++it ) + { + SfxInfoBarWindow* pBar = *it; + pBar->SetPosPixel( Point( 0, nY ) ); + nY += pBar->GetSizePixel( ).getHeight( ); + } + + Size aSize = GetSizePixel( ); + aSize.setHeight( nY ); + SetSizePixel( aSize ); + + m_pChildWin->Update( ); +} + + +SFX_IMPL_POS_CHILDWINDOW_WITHID( SfxInfoBarContainerChild, SID_INFOBARCONTAINER, SFX_OBJECTBAR_OBJECT ); + +SfxInfoBarContainerChild::SfxInfoBarContainerChild( Window* _pParent, sal_uInt16 nId, SfxBindings* pBindings, SfxChildWinInfo* ) : + SfxChildWindow( _pParent, nId ), + m_pBindings( pBindings ) +{ + pWindow = new SfxInfoBarContainerWindow( this ); + pWindow->SetPosSizePixel( Point( 0, 0 ), Size( _pParent->GetSizePixel( ).getWidth(), 0 ) ); + pWindow->Show( ); + + eChildAlignment = SFX_ALIGN_LOWESTTOP; +} + +SfxInfoBarContainerChild::~SfxInfoBarContainerChild( ) +{ +} + +SfxChildWinInfo SfxInfoBarContainerChild::GetInfo( ) const +{ + SfxChildWinInfo aInfo = SfxChildWindow::GetInfo(); + return aInfo; +} + +void SfxInfoBarContainerChild::Update( ) +{ + // Refresh the frame to take the infobars container height change into account + const sal_uInt16 nId = GetChildWindowId(); + SfxViewFrame* pVFrame = m_pBindings->GetDispatcher( )->GetFrame( ); + pVFrame->ShowChildWindow( nId ); + + // Give the focus to the document view + pVFrame->GetWindow().GrabFocusToDocument(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sfx2/source/view/viewfrm.cxx b/sfx2/source/view/viewfrm.cxx index 83c10ea3f0bb..ad8dfc729128 100644 --- a/sfx2/source/view/viewfrm.cxx +++ b/sfx2/source/view/viewfrm.cxx @@ -20,6 +20,7 @@ #include <stdio.h> +#include <sfx2/infobar.hxx> #include <sfx2/viewfrm.hxx> #include <com/sun/star/document/MacroExecMode.hpp> #include <com/sun/star/frame/XLoadable.hpp> @@ -3349,4 +3350,14 @@ void SfxViewFrame::ActivateToolPanel_Impl( const ::rtl::OUString& i_rPanelURL ) pPanelAccess->ActivateToolPanel( i_rPanelURL ); } +void SfxViewFrame::AppendInfoBar( const rtl::OUString& sMessage, std::vector< PushButton* > aButtons ) +{ + const sal_uInt16 nId = SfxInfoBarContainerChild::GetChildWindowId(); + ShowChildWindow( nId ); + SfxChildWindow* pChild = GetChildWindow( nId ); + SfxInfoBarContainerWindow* pInfoBars = ( SfxInfoBarContainerWindow* )pChild->GetWindow(); + pInfoBars->appendInfoBar( sMessage, aButtons ); + ShowChildWindow( nId ); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |