summaryrefslogtreecommitdiff
path: root/sfx2
diff options
context:
space:
mode:
authorCédric Bosdonnat <cedric.bosdonnat@free.fr>2012-10-05 15:37:26 +0200
committerCédric Bosdonnat <cedric.bosdonnat@free.fr>2012-10-11 17:31:17 +0200
commit97aa108f2b595145d63b00d515489030a849957e (patch)
treea7c0354f5699e9e059ae1baf9eb157ab143d71a4 /sfx2
parentb66a72cba2f38c3ddc9e7c91a1afd5d8a2279ed8 (diff)
InfoBars: first implementation
Change-Id: I4b18f19f5cf13d648a8d10cc31c63bb330a86b6f
Diffstat (limited to 'sfx2')
-rw-r--r--sfx2/Library_sfx.mk1
-rw-r--r--sfx2/Package_inc.mk1
-rw-r--r--sfx2/inc/sfx2/infobar.hxx77
-rw-r--r--sfx2/inc/sfx2/sfxsids.hrc1
-rw-r--r--sfx2/inc/sfx2/viewfrm.hxx8
-rw-r--r--sfx2/source/appl/appreg.cxx2
-rw-r--r--sfx2/source/dialog/infobar.cxx283
-rw-r--r--sfx2/source/view/viewfrm.cxx11
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: */