Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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 : */
9 :
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>
22 :
23 : using namespace std;
24 :
25 : namespace
26 : {
27 : class SfxCloseButton : public PushButton
28 : {
29 : public:
30 0 : SfxCloseButton( Window* pParent ) : PushButton( pParent, 0 )
31 : {
32 0 : }
33 :
34 0 : ~SfxCloseButton( ) { }
35 :
36 : virtual void Paint( const Rectangle& rRect );
37 : };
38 :
39 0 : void SfxCloseButton::Paint( const Rectangle& )
40 : {
41 0 : const drawinglayer::geometry::ViewInformation2D aNewViewInfos;
42 : drawinglayer::processor2d::BaseProcessor2D * pProcessor =
43 : drawinglayer::processor2d::createBaseProcessor2DFromOutputDevice(
44 0 : *this, aNewViewInfos );
45 :
46 0 : const Rectangle aRect( Rectangle( Point( 0, 0 ), PixelToLogic( GetSizePixel() ) ) );
47 :
48 0 : drawinglayer::primitive2d::Primitive2DSequence aSeq( 2 );
49 :
50 0 : basegfx::BColor aLightColor( 1.0, 1.0, 191.0 / 255.0 );
51 0 : basegfx::BColor aDarkColor( 217.0 / 255.0, 217.0 / 255.0, 78.0 / 255.0 );
52 :
53 0 : const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
54 0 : if ( rSettings.GetHighContrastMode() )
55 : {
56 0 : aLightColor = rSettings.GetLightColor( ).getBColor( );
57 0 : aDarkColor = rSettings.GetDialogTextColor( ).getBColor( );
58 :
59 : }
60 :
61 : // Light background
62 0 : basegfx::B2DPolygon aPolygon;
63 0 : aPolygon.append( basegfx::B2DPoint( aRect.Left( ), aRect.Top( ) ) );
64 0 : aPolygon.append( basegfx::B2DPoint( aRect.Right( ), aRect.Top( ) ) );
65 0 : aPolygon.append( basegfx::B2DPoint( aRect.Right( ), aRect.Bottom( ) ) );
66 0 : aPolygon.append( basegfx::B2DPoint( aRect.Left( ), aRect.Bottom( ) ) );
67 0 : aPolygon.setClosed( true );
68 : drawinglayer::primitive2d::PolyPolygonColorPrimitive2D* pBack =
69 : new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D(
70 0 : basegfx::B2DPolyPolygon( aPolygon ), aLightColor );
71 0 : aSeq[0] = pBack;
72 :
73 0 : drawinglayer::attribute::LineAttribute aLineAttribute( aDarkColor, 2.0 );
74 :
75 : // Cross
76 0 : basegfx::B2DPolyPolygon aCross;
77 0 : basegfx::B2DPolygon aLine1;
78 0 : aLine1.append( basegfx::B2DPoint( aRect.Left(), aRect.Top( ) ) );
79 0 : aLine1.append( basegfx::B2DPoint( aRect.Right(), aRect.Bottom( ) ) );
80 0 : aCross.append( aLine1 );
81 0 : basegfx::B2DPolygon aLine2;
82 0 : aLine2.append( basegfx::B2DPoint( aRect.Right(), aRect.Top( ) ) );
83 0 : aLine2.append( basegfx::B2DPoint( aRect.Left(), aRect.Bottom( ) ) );
84 0 : aCross.append( aLine2 );
85 :
86 : drawinglayer::primitive2d::PolyPolygonStrokePrimitive2D * pCross =
87 : new drawinglayer::primitive2d::PolyPolygonStrokePrimitive2D (
88 0 : aCross, aLineAttribute, drawinglayer::attribute::StrokeAttribute( ) );
89 :
90 0 : aSeq[1] = pCross;
91 :
92 0 : pProcessor->process( aSeq );
93 0 : delete pProcessor;
94 0 : }
95 : }
96 :
97 0 : SfxInfoBarWindow::SfxInfoBarWindow( Window* pParent, const rtl::OUString& sId,
98 : const rtl::OUString& sMessage, vector< PushButton* > aButtons ) :
99 : Window( pParent, 0 ),
100 : m_sId( sId ),
101 : m_pMessage( NULL ),
102 : m_pCloseBtn( NULL ),
103 0 : m_aActionBtns( aButtons )
104 : {
105 0 : long nWidth = pParent->GetSizePixel().getWidth();
106 0 : SetPosSizePixel( Point( 0, 0 ), Size( nWidth, 40 ) );
107 0 : m_pMessage = new FixedText( this, 0 );
108 0 : m_pMessage->SetText( sMessage );
109 0 : m_pMessage->SetBackground( Wallpaper( Color( 255, 255, 191 ) ) );
110 0 : m_pMessage->Show( );
111 :
112 0 : m_pCloseBtn = new SfxCloseButton( this );
113 0 : m_pCloseBtn->SetPosSizePixel( Point( nWidth - 25, 15 ), Size( 10, 10 ) );
114 0 : m_pCloseBtn->SetClickHdl( LINK( this, SfxInfoBarWindow, CloseHandler ) );
115 0 : m_pCloseBtn->Show( );
116 :
117 : // Reparent the buttons and place them on the right of the bar
118 0 : long nX = m_pCloseBtn->GetPosPixel( ).getX( ) - 15;
119 0 : long nBtnGap = 5;
120 0 : for ( vector< PushButton* >::iterator it = m_aActionBtns.begin( );
121 0 : it != m_aActionBtns.end( ); ++it )
122 : {
123 0 : PushButton* pBtn = *it;
124 0 : pBtn->SetParent( this );
125 0 : long nBtnWidth = pBtn->GetSizePixel( ).getWidth();
126 0 : nX -= nBtnWidth;
127 0 : pBtn->SetPosSizePixel( Point( nX, 5 ), Size( nBtnWidth, 30 ) );
128 0 : nX -= nBtnGap;
129 0 : pBtn->Show( );
130 : }
131 :
132 0 : m_pMessage->SetPosSizePixel( Point( 10, 10 ), Size( nX - 20, 20 ) );
133 0 : }
134 :
135 0 : SfxInfoBarWindow::~SfxInfoBarWindow( )
136 : {
137 0 : delete m_pMessage;
138 0 : delete m_pCloseBtn;
139 :
140 0 : for ( vector< PushButton* >::iterator it = m_aActionBtns.begin( );
141 0 : it != m_aActionBtns.end( ); ++it )
142 : {
143 0 : delete *it;
144 : }
145 0 : m_aActionBtns.clear( );
146 0 : }
147 :
148 0 : void SfxInfoBarWindow::Paint( const Rectangle& rPaintRect )
149 : {
150 0 : const drawinglayer::geometry::ViewInformation2D aNewViewInfos;
151 : drawinglayer::processor2d::BaseProcessor2D * pProcessor =
152 : drawinglayer::processor2d::createBaseProcessor2DFromOutputDevice(
153 0 : *this, aNewViewInfos );
154 :
155 0 : const Rectangle aRect( Rectangle( Point( 0, 0 ), PixelToLogic( GetSizePixel() ) ) );
156 :
157 0 : drawinglayer::primitive2d::Primitive2DSequence aSeq( 2 );
158 :
159 0 : basegfx::BColor aLightColor( 1.0, 1.0, 191.0 / 255.0 );
160 0 : basegfx::BColor aDarkColor( 217.0 / 255.0, 217.0 / 255.0, 78.0 / 255.0 );
161 :
162 0 : const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
163 0 : if ( rSettings.GetHighContrastMode() )
164 : {
165 0 : aLightColor = rSettings.GetLightColor( ).getBColor( );
166 0 : aDarkColor = rSettings.GetDialogTextColor( ).getBColor( );
167 : }
168 :
169 : // Update the label background color
170 0 : m_pMessage->SetBackground( Wallpaper( Color( aLightColor ) ) );
171 :
172 : // Light background
173 0 : basegfx::B2DPolygon aPolygon;
174 0 : aPolygon.append( basegfx::B2DPoint( aRect.Left( ), aRect.Top( ) ) );
175 0 : aPolygon.append( basegfx::B2DPoint( aRect.Right( ), aRect.Top( ) ) );
176 0 : aPolygon.append( basegfx::B2DPoint( aRect.Right( ), aRect.Bottom( ) ) );
177 0 : aPolygon.append( basegfx::B2DPoint( aRect.Left( ), aRect.Bottom( ) ) );
178 0 : aPolygon.setClosed( true );
179 : drawinglayer::primitive2d::PolyPolygonColorPrimitive2D* pBack =
180 : new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D(
181 0 : basegfx::B2DPolyPolygon( aPolygon ), aLightColor );
182 0 : aSeq[0] = pBack;
183 :
184 0 : drawinglayer::attribute::LineAttribute aLineAttribute( aDarkColor, 1.0 );
185 :
186 : // Bottom dark line
187 0 : basegfx::B2DPolygon aPolygonBottom;
188 0 : aPolygonBottom.append( basegfx::B2DPoint( aRect.Left(), aRect.Bottom( ) ) );
189 0 : aPolygonBottom.append( basegfx::B2DPoint( aRect.Right(), aRect.Bottom( ) ) );
190 :
191 : drawinglayer::primitive2d::PolygonStrokePrimitive2D * pLineBottom =
192 : new drawinglayer::primitive2d::PolygonStrokePrimitive2D (
193 0 : aPolygonBottom, aLineAttribute );
194 :
195 0 : aSeq[1] = pLineBottom;
196 :
197 0 : pProcessor->process( aSeq );
198 0 : delete pProcessor;
199 :
200 0 : Window::Paint( rPaintRect );
201 0 : }
202 :
203 0 : void SfxInfoBarWindow::Resize( )
204 : {
205 0 : long nWidth = GetSizePixel().getWidth();
206 0 : m_pCloseBtn->SetPosSizePixel( Point( nWidth - 25, 15 ), Size( 10, 10 ) );
207 :
208 : // Reparent the buttons and place them on the right of the bar
209 0 : long nX = m_pCloseBtn->GetPosPixel( ).getX( ) - 15;
210 0 : long nBtnGap = 5;
211 0 : for ( vector< PushButton* >::iterator it = m_aActionBtns.begin( );
212 0 : it != m_aActionBtns.end( ); ++it )
213 : {
214 0 : PushButton* pBtn = *it;
215 0 : long nBtnWidth = pBtn->GetSizePixel( ).getWidth();
216 0 : nX -= nBtnWidth;
217 0 : pBtn->SetPosSizePixel( Point( nX, 5 ), Size( nBtnWidth, 30 ) );
218 0 : nX -= nBtnGap;
219 : }
220 :
221 0 : m_pMessage->SetPosSizePixel( Point( 10, 10 ), Size( nX - 20, 20 ) );
222 0 : }
223 :
224 0 : IMPL_LINK_NOARG( SfxInfoBarWindow, CloseHandler )
225 : {
226 0 : ((SfxInfoBarContainerWindow*)GetParent())->removeInfoBar( this );
227 0 : return 0;
228 : }
229 :
230 236 : SfxInfoBarContainerWindow::SfxInfoBarContainerWindow( SfxInfoBarContainerChild* pChildWin ) :
231 : Window( pChildWin->GetParent( ), 0 ),
232 : m_pChildWin( pChildWin ),
233 236 : m_pInfoBars( )
234 : {
235 236 : }
236 :
237 189 : SfxInfoBarContainerWindow::~SfxInfoBarContainerWindow( )
238 : {
239 189 : for ( vector< SfxInfoBarWindow* >::iterator it = m_pInfoBars.begin( );
240 126 : it != m_pInfoBars.end( ); ++it )
241 : {
242 0 : delete *it;
243 : }
244 63 : m_pInfoBars.clear( );
245 126 : }
246 :
247 0 : void SfxInfoBarContainerWindow::appendInfoBar( const rtl::OUString& sId, const rtl::OUString& sMessage, vector< PushButton* > aButtons )
248 : {
249 0 : Size aSize = GetSizePixel( );
250 :
251 0 : SfxInfoBarWindow* pInfoBar = new SfxInfoBarWindow( this, sId, sMessage, aButtons );
252 0 : pInfoBar->SetPosPixel( Point( 0, aSize.getHeight( ) ) );
253 0 : pInfoBar->Show( );
254 :
255 0 : long nHeight = pInfoBar->GetSizePixel( ).getHeight( );
256 0 : aSize.setHeight( aSize.getHeight() + nHeight );
257 0 : SetSizePixel( aSize );
258 0 : }
259 :
260 0 : SfxInfoBarWindow* SfxInfoBarContainerWindow::getInfoBar( const rtl::OUString& sId )
261 : {
262 0 : SfxInfoBarWindow* pRet = NULL;
263 0 : for ( vector< SfxInfoBarWindow* >::iterator it = m_pInfoBars.begin( );
264 0 : it != m_pInfoBars.end( ) && pRet == NULL; ++it )
265 : {
266 0 : SfxInfoBarWindow* pBar = *it;
267 0 : if ( pBar->getId( ) == sId )
268 0 : pRet = pBar;
269 : }
270 0 : return pRet;
271 : }
272 :
273 0 : void SfxInfoBarContainerWindow::removeInfoBar( SfxInfoBarWindow* pInfoBar )
274 : {
275 0 : for ( vector< SfxInfoBarWindow* >::iterator it = m_pInfoBars.begin( );
276 0 : it != m_pInfoBars.end( ); ++it )
277 : {
278 0 : if ( pInfoBar == *it )
279 : {
280 0 : m_pInfoBars.erase( it );
281 0 : break;
282 : }
283 : }
284 0 : delete pInfoBar;
285 :
286 0 : long nY = 0;
287 0 : for ( vector< SfxInfoBarWindow* >::iterator it = m_pInfoBars.begin( ); it != m_pInfoBars.end( ); ++it )
288 : {
289 0 : SfxInfoBarWindow* pBar = *it;
290 0 : pBar->SetPosPixel( Point( 0, nY ) );
291 0 : nY += pBar->GetSizePixel( ).getHeight( );
292 : }
293 :
294 0 : Size aSize = GetSizePixel( );
295 0 : aSize.setHeight( nY );
296 0 : SetSizePixel( aSize );
297 :
298 0 : m_pChildWin->Update( );
299 0 : }
300 :
301 280 : void SfxInfoBarContainerWindow::Resize( )
302 : {
303 : // Only need to change the width of the infobars
304 280 : long nWidth = GetSizePixel( ).getWidth( );
305 840 : for ( vector< SfxInfoBarWindow * >::iterator it = m_pInfoBars.begin( );
306 560 : it != m_pInfoBars.end( ); ++it )
307 : {
308 0 : SfxInfoBarWindow* pInfoBar = *it;
309 0 : Size aSize = pInfoBar->GetSizePixel( );
310 0 : aSize.setWidth( nWidth );
311 0 : pInfoBar->SetSizePixel( aSize );
312 0 : pInfoBar->Resize( );
313 : }
314 280 : }
315 :
316 286 : SFX_IMPL_POS_CHILDWINDOW_WITHID( SfxInfoBarContainerChild, SID_INFOBARCONTAINER, SFX_OBJECTBAR_OBJECT );
317 :
318 236 : SfxInfoBarContainerChild::SfxInfoBarContainerChild( Window* _pParent, sal_uInt16 nId, SfxBindings* pBindings, SfxChildWinInfo* ) :
319 : SfxChildWindow( _pParent, nId ),
320 236 : m_pBindings( pBindings )
321 : {
322 236 : pWindow = new SfxInfoBarContainerWindow( this );
323 236 : pWindow->SetPosSizePixel( Point( 0, 0 ), Size( _pParent->GetSizePixel( ).getWidth(), 0 ) );
324 236 : pWindow->Show( );
325 :
326 236 : eChildAlignment = SFX_ALIGN_LOWESTTOP;
327 236 : }
328 :
329 126 : SfxInfoBarContainerChild::~SfxInfoBarContainerChild( )
330 : {
331 126 : }
332 :
333 236 : SfxChildWinInfo SfxInfoBarContainerChild::GetInfo( ) const
334 : {
335 236 : SfxChildWinInfo aInfo = SfxChildWindow::GetInfo();
336 236 : return aInfo;
337 : }
338 :
339 0 : void SfxInfoBarContainerChild::Update( )
340 : {
341 : // Refresh the frame to take the infobars container height change into account
342 0 : const sal_uInt16 nId = GetChildWindowId();
343 0 : SfxViewFrame* pVFrame = m_pBindings->GetDispatcher( )->GetFrame( );
344 0 : pVFrame->ShowChildWindow( nId );
345 :
346 : // Give the focus to the document view
347 0 : pVFrame->GetWindow().GrabFocusToDocument();
348 0 : }
349 :
350 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|