Bump version to 4.1-6
[LibreOffice.git] / sfx2 / source / dialog / infobar.cxx
blob82c2c3a56ceabfa16a73046a9d7bdbf7800fd4a5
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
10 #include <basegfx/polygon/b2dpolygon.hxx>
11 #include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
12 #include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
13 #include <drawinglayer/processor2d/baseprocessor2d.hxx>
14 #include <drawinglayer/processor2d/processorfromoutputdevice.hxx>
15 #include <sfx2/bindings.hxx>
16 #include <sfx2/dispatch.hxx>
17 #include <sfx2/infobar.hxx>
18 #include <sfx2/objsh.hxx>
19 #include <sfx2/sfx.hrc>
20 #include <sfx2/viewsh.hxx>
21 #include <vcl/svapp.hxx>
23 using namespace std;
25 namespace
27 class SfxCloseButton : public PushButton
29 public:
30 SfxCloseButton( Window* pParent ) : PushButton( pParent, 0 )
34 ~SfxCloseButton( ) { }
36 virtual void Paint( const Rectangle& rRect );
39 void SfxCloseButton::Paint( const Rectangle& )
41 const drawinglayer::geometry::ViewInformation2D aNewViewInfos;
42 drawinglayer::processor2d::BaseProcessor2D * pProcessor =
43 drawinglayer::processor2d::createBaseProcessor2DFromOutputDevice(
44 *this, aNewViewInfos );
46 const Rectangle aRect( Rectangle( Point( 0, 0 ), PixelToLogic( GetSizePixel() ) ) );
48 drawinglayer::primitive2d::Primitive2DSequence aSeq( 2 );
50 basegfx::BColor aLightColor( 1.0, 1.0, 191.0 / 255.0 );
51 basegfx::BColor aDarkColor( 217.0 / 255.0, 217.0 / 255.0, 78.0 / 255.0 );
53 const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
54 if ( rSettings.GetHighContrastMode() )
56 aLightColor = rSettings.GetLightColor( ).getBColor( );
57 aDarkColor = rSettings.GetDialogTextColor( ).getBColor( );
61 // Light background
62 basegfx::B2DPolygon aPolygon;
63 aPolygon.append( basegfx::B2DPoint( aRect.Left( ), aRect.Top( ) ) );
64 aPolygon.append( basegfx::B2DPoint( aRect.Right( ), aRect.Top( ) ) );
65 aPolygon.append( basegfx::B2DPoint( aRect.Right( ), aRect.Bottom( ) ) );
66 aPolygon.append( basegfx::B2DPoint( aRect.Left( ), aRect.Bottom( ) ) );
67 aPolygon.setClosed( true );
68 drawinglayer::primitive2d::PolyPolygonColorPrimitive2D* pBack =
69 new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D(
70 basegfx::B2DPolyPolygon( aPolygon ), aLightColor );
71 aSeq[0] = pBack;
73 drawinglayer::attribute::LineAttribute aLineAttribute( aDarkColor, 2.0 );
75 // Cross
76 basegfx::B2DPolyPolygon aCross;
77 basegfx::B2DPolygon aLine1;
78 aLine1.append( basegfx::B2DPoint( aRect.Left(), aRect.Top( ) ) );
79 aLine1.append( basegfx::B2DPoint( aRect.Right(), aRect.Bottom( ) ) );
80 aCross.append( aLine1 );
81 basegfx::B2DPolygon aLine2;
82 aLine2.append( basegfx::B2DPoint( aRect.Right(), aRect.Top( ) ) );
83 aLine2.append( basegfx::B2DPoint( aRect.Left(), aRect.Bottom( ) ) );
84 aCross.append( aLine2 );
86 drawinglayer::primitive2d::PolyPolygonStrokePrimitive2D * pCross =
87 new drawinglayer::primitive2d::PolyPolygonStrokePrimitive2D (
88 aCross, aLineAttribute, drawinglayer::attribute::StrokeAttribute( ) );
90 aSeq[1] = pCross;
92 pProcessor->process( aSeq );
93 delete pProcessor;
97 SfxInfoBarWindow::SfxInfoBarWindow( Window* pParent, const OUString& sId,
98 const OUString& sMessage, vector< PushButton* > aButtons ) :
99 Window( pParent, 0 ),
100 m_sId( sId ),
101 m_pMessage( NULL ),
102 m_pCloseBtn( NULL ),
103 m_aActionBtns( aButtons )
105 long nWidth = pParent->GetSizePixel().getWidth();
106 SetPosSizePixel( Point( 0, 0 ), Size( nWidth, 40 ) );
107 m_pMessage = new FixedText( this, 0 );
108 m_pMessage->SetText( sMessage );
109 m_pMessage->SetBackground( Wallpaper( Color( 255, 255, 191 ) ) );
110 m_pMessage->Show( );
112 m_pCloseBtn = new SfxCloseButton( this );
113 m_pCloseBtn->SetPosSizePixel( Point( nWidth - 25, 15 ), Size( 10, 10 ) );
114 m_pCloseBtn->SetClickHdl( LINK( this, SfxInfoBarWindow, CloseHandler ) );
115 m_pCloseBtn->Show( );
117 // Reparent the buttons and place them on the right of the bar
118 long nX = m_pCloseBtn->GetPosPixel( ).getX( ) - 15;
119 long nBtnGap = 5;
120 for ( vector< PushButton* >::iterator it = m_aActionBtns.begin( );
121 it != m_aActionBtns.end( ); ++it )
123 PushButton* pBtn = *it;
124 pBtn->SetParent( this );
125 long nBtnWidth = pBtn->GetSizePixel( ).getWidth();
126 nX -= nBtnWidth;
127 pBtn->SetPosSizePixel( Point( nX, 5 ), Size( nBtnWidth, 30 ) );
128 nX -= nBtnGap;
129 pBtn->Show( );
132 m_pMessage->SetPosSizePixel( Point( 10, 10 ), Size( nX - 20, 20 ) );
135 SfxInfoBarWindow::~SfxInfoBarWindow( )
137 delete m_pMessage;
138 delete m_pCloseBtn;
140 for ( vector< PushButton* >::iterator it = m_aActionBtns.begin( );
141 it != m_aActionBtns.end( ); ++it )
143 delete *it;
145 m_aActionBtns.clear( );
148 void SfxInfoBarWindow::Paint( const Rectangle& rPaintRect )
150 const drawinglayer::geometry::ViewInformation2D aNewViewInfos;
151 drawinglayer::processor2d::BaseProcessor2D * pProcessor =
152 drawinglayer::processor2d::createBaseProcessor2DFromOutputDevice(
153 *this, aNewViewInfos );
155 const Rectangle aRect( Rectangle( Point( 0, 0 ), PixelToLogic( GetSizePixel() ) ) );
157 drawinglayer::primitive2d::Primitive2DSequence aSeq( 2 );
159 basegfx::BColor aLightColor( 1.0, 1.0, 191.0 / 255.0 );
160 basegfx::BColor aDarkColor( 217.0 / 255.0, 217.0 / 255.0, 78.0 / 255.0 );
162 const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
163 if ( rSettings.GetHighContrastMode() )
165 aLightColor = rSettings.GetLightColor( ).getBColor( );
166 aDarkColor = rSettings.GetDialogTextColor( ).getBColor( );
169 // Update the label background color
170 m_pMessage->SetBackground( Wallpaper( Color( aLightColor ) ) );
172 // Light background
173 basegfx::B2DPolygon aPolygon;
174 aPolygon.append( basegfx::B2DPoint( aRect.Left( ), aRect.Top( ) ) );
175 aPolygon.append( basegfx::B2DPoint( aRect.Right( ), aRect.Top( ) ) );
176 aPolygon.append( basegfx::B2DPoint( aRect.Right( ), aRect.Bottom( ) ) );
177 aPolygon.append( basegfx::B2DPoint( aRect.Left( ), aRect.Bottom( ) ) );
178 aPolygon.setClosed( true );
179 drawinglayer::primitive2d::PolyPolygonColorPrimitive2D* pBack =
180 new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D(
181 basegfx::B2DPolyPolygon( aPolygon ), aLightColor );
182 aSeq[0] = pBack;
184 drawinglayer::attribute::LineAttribute aLineAttribute( aDarkColor, 1.0 );
186 // Bottom dark line
187 basegfx::B2DPolygon aPolygonBottom;
188 aPolygonBottom.append( basegfx::B2DPoint( aRect.Left(), aRect.Bottom( ) ) );
189 aPolygonBottom.append( basegfx::B2DPoint( aRect.Right(), aRect.Bottom( ) ) );
191 drawinglayer::primitive2d::PolygonStrokePrimitive2D * pLineBottom =
192 new drawinglayer::primitive2d::PolygonStrokePrimitive2D (
193 aPolygonBottom, aLineAttribute );
195 aSeq[1] = pLineBottom;
197 pProcessor->process( aSeq );
198 delete pProcessor;
200 Window::Paint( rPaintRect );
203 void SfxInfoBarWindow::Resize( )
205 long nWidth = GetSizePixel().getWidth();
206 m_pCloseBtn->SetPosSizePixel( Point( nWidth - 25, 15 ), Size( 10, 10 ) );
208 // Reparent the buttons and place them on the right of the bar
209 long nX = m_pCloseBtn->GetPosPixel( ).getX( ) - 15;
210 long nBtnGap = 5;
211 for ( vector< PushButton* >::iterator it = m_aActionBtns.begin( );
212 it != m_aActionBtns.end( ); ++it )
214 PushButton* pBtn = *it;
215 long nBtnWidth = pBtn->GetSizePixel( ).getWidth();
216 nX -= nBtnWidth;
217 pBtn->SetPosSizePixel( Point( nX, 5 ), Size( nBtnWidth, 30 ) );
218 nX -= nBtnGap;
221 m_pMessage->SetPosSizePixel( Point( 10, 10 ), Size( nX - 20, 20 ) );
224 IMPL_LINK_NOARG( SfxInfoBarWindow, CloseHandler )
226 ((SfxInfoBarContainerWindow*)GetParent())->removeInfoBar( this );
227 return 0;
230 SfxInfoBarContainerWindow::SfxInfoBarContainerWindow( SfxInfoBarContainerChild* pChildWin ) :
231 Window( pChildWin->GetParent( ), 0 ),
232 m_pChildWin( pChildWin ),
233 m_pInfoBars( )
237 SfxInfoBarContainerWindow::~SfxInfoBarContainerWindow( )
239 for ( vector< SfxInfoBarWindow* >::iterator it = m_pInfoBars.begin( );
240 it != m_pInfoBars.end( ); ++it )
242 delete *it;
244 m_pInfoBars.clear( );
247 void SfxInfoBarContainerWindow::appendInfoBar( const OUString& sId, const OUString& sMessage, vector< PushButton* > aButtons )
249 Size aSize = GetSizePixel( );
251 SfxInfoBarWindow* pInfoBar = new SfxInfoBarWindow( this, sId, sMessage, aButtons );
252 pInfoBar->SetPosPixel( Point( 0, aSize.getHeight( ) ) );
253 pInfoBar->Show( );
255 long nHeight = pInfoBar->GetSizePixel( ).getHeight( );
256 aSize.setHeight( aSize.getHeight() + nHeight );
257 SetSizePixel( aSize );
260 SfxInfoBarWindow* SfxInfoBarContainerWindow::getInfoBar( const OUString& sId )
262 SfxInfoBarWindow* pRet = NULL;
263 for ( vector< SfxInfoBarWindow* >::iterator it = m_pInfoBars.begin( );
264 it != m_pInfoBars.end( ) && pRet == NULL; ++it )
266 SfxInfoBarWindow* pBar = *it;
267 if ( pBar->getId( ) == sId )
268 pRet = pBar;
270 return pRet;
273 void SfxInfoBarContainerWindow::removeInfoBar( SfxInfoBarWindow* pInfoBar )
275 for ( vector< SfxInfoBarWindow* >::iterator it = m_pInfoBars.begin( );
276 it != m_pInfoBars.end( ); ++it )
278 if ( pInfoBar == *it )
280 m_pInfoBars.erase( it );
281 break;
284 delete pInfoBar;
286 long nY = 0;
287 for ( vector< SfxInfoBarWindow* >::iterator it = m_pInfoBars.begin( ); it != m_pInfoBars.end( ); ++it )
289 SfxInfoBarWindow* pBar = *it;
290 pBar->SetPosPixel( Point( 0, nY ) );
291 nY += pBar->GetSizePixel( ).getHeight( );
294 Size aSize = GetSizePixel( );
295 aSize.setHeight( nY );
296 SetSizePixel( aSize );
298 m_pChildWin->Update( );
301 void SfxInfoBarContainerWindow::Resize( )
303 // Only need to change the width of the infobars
304 long nWidth = GetSizePixel( ).getWidth( );
305 for ( vector< SfxInfoBarWindow * >::iterator it = m_pInfoBars.begin( );
306 it != m_pInfoBars.end( ); ++it )
308 SfxInfoBarWindow* pInfoBar = *it;
309 Size aSize = pInfoBar->GetSizePixel( );
310 aSize.setWidth( nWidth );
311 pInfoBar->SetSizePixel( aSize );
312 pInfoBar->Resize( );
316 SFX_IMPL_POS_CHILDWINDOW_WITHID( SfxInfoBarContainerChild, SID_INFOBARCONTAINER, SFX_OBJECTBAR_OBJECT );
318 SfxInfoBarContainerChild::SfxInfoBarContainerChild( Window* _pParent, sal_uInt16 nId, SfxBindings* pBindings, SfxChildWinInfo* ) :
319 SfxChildWindow( _pParent, nId ),
320 m_pBindings( pBindings )
322 pWindow = new SfxInfoBarContainerWindow( this );
323 pWindow->SetPosSizePixel( Point( 0, 0 ), Size( _pParent->GetSizePixel( ).getWidth(), 0 ) );
324 pWindow->Show( );
326 eChildAlignment = SFX_ALIGN_LOWESTTOP;
329 SfxInfoBarContainerChild::~SfxInfoBarContainerChild( )
333 SfxChildWinInfo SfxInfoBarContainerChild::GetInfo( ) const
335 SfxChildWinInfo aInfo = SfxChildWindow::GetInfo();
336 return aInfo;
339 void SfxInfoBarContainerChild::Update( )
341 // Refresh the frame to take the infobars container height change into account
342 const sal_uInt16 nId = GetChildWindowId();
343 SfxViewFrame* pVFrame = m_pBindings->GetDispatcher( )->GetFrame( );
344 pVFrame->ShowChildWindow( nId );
346 // Give the focus to the document view
347 pVFrame->GetWindow().GrabFocusToDocument();
350 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */