1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: updatecheckui.cxx,v $
10 * $Revision: 1.19.18.2 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_extensions.hxx"
36 #include <cppuhelper/implbase3.hxx>
37 #include <cppuhelper/implementationentry.hxx>
38 #include <com/sun/star/lang/XServiceInfo.hpp>
39 #include <com/sun/star/lang/XComponent.hpp>
40 #include <com/sun/star/document/XEventListener.hpp>
41 #include <com/sun/star/document/XEventBroadcaster.hpp>
42 #include <com/sun/star/beans/XPropertySet.hpp>
43 #include <com/sun/star/graphic/XGraphicProvider.hpp>
44 #include <com/sun/star/task/XJob.hpp>
46 #include <comphelper/processfactory.hxx>
48 #include <vos/mutex.hxx>
49 #include <osl/mutex.hxx>
51 #include <vcl/window.hxx>
52 #include <vcl/floatwin.hxx>
53 #include <vcl/timer.hxx>
54 #include <vcl/menu.hxx>
55 #include <vcl/outdev.hxx>
56 #include <vcl/msgbox.hxx>
57 #include <vcl/lineinfo.hxx>
58 #include <vcl/imagebtn.hxx>
59 #include <vcl/settings.hxx>
60 #include <vcl/svapp.hxx>
61 #include <sfx2/sfx.hrc>
62 #include "rtl/ustrbuf.hxx"
64 #include "updatecheckui.hrc"
66 #define UNISTRING(s) rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(s))
68 #define MSG_ERR_NO_WEBBROWSER_FOUND (RID_SFX_APP_START + 7)
69 #define DEFAULT_MENUBAR_HEIGHT 24
71 #define PROPERTY_TITLE RTL_CONSTASCII_STRINGPARAM("BubbleHeading")
72 #define PROPERTY_TEXT RTL_CONSTASCII_STRINGPARAM("BubbleText")
73 #define PROPERTY_IMAGE RTL_CONSTASCII_STRINGPARAM("BubbleImageURL")
74 #define PROPERTY_SHOW_BUBBLE RTL_CONSTASCII_STRINGPARAM("BubbleVisible")
75 #define PROPERTY_CLICK_HDL RTL_CONSTASCII_STRINGPARAM("MenuClickHDL")
76 #define PROPERTY_SHOW_MENUICON RTL_CONSTASCII_STRINGPARAM("MenuIconVisible")
80 using namespace ::com::sun::star
;
82 //------------------------------------------------------------------------------
84 static uno::Sequence
< rtl::OUString
> getServiceNames()
86 uno::Sequence
< rtl::OUString
> aServiceList(1);
87 aServiceList
[0] = UNISTRING( "com.sun.star.setup.UpdateCheckUI");
91 //------------------------------------------------------------------------------
93 static rtl::OUString
getImplementationName()
95 return UNISTRING( "vnd.sun.UpdateCheckUI");
98 //------------------------------------------------------------------------------
103 //------------------------------------------------------------------------------
104 class BubbleWindow
: public FloatingWindow
110 XubString maBubbleTitle
;
111 XubString maBubbleText
;
114 Rectangle maTitleRect
;
115 Rectangle maTextRect
;
119 void RecalcTextRects();
122 BubbleWindow( Window
* pParent
, const XubString
& rTitle
,
123 const XubString
& rText
, const Image
& rImage
);
126 virtual void MouseButtonDown( const MouseEvent
& rMEvt
);
127 virtual void Paint( const Rectangle
& rRect
);
129 void Show( BOOL bVisible
= TRUE
, USHORT nFlags
= SHOW_NOACTIVATE
);
130 void SetTipPosPixel( const Point
& rTipPos
) { maTipPos
= rTipPos
; }
131 void SetTitleAndText( const XubString
& rTitle
, const XubString
& rText
,
132 const Image
& rImage
);
135 //------------------------------------------------------------------------------
136 class UpdateCheckUI
: public ::cppu::WeakImplHelper3
137 < lang::XServiceInfo
, document::XEventListener
, beans::XPropertySet
>
139 uno::Reference
< uno::XComponentContext
> m_xContext
;
140 uno::Reference
< task::XJob
> mrJob
;
141 rtl::OUString maBubbleTitle
;
142 rtl::OUString maBubbleText
;
143 rtl::OUString maBubbleImageURL
;
145 BubbleWindow
* mpBubbleWin
;
146 SystemWindow
* mpIconSysWin
;
151 Timer maTimeoutTimer
;
152 Link maWindowEventHdl
;
153 Link maApplicationEventHdl
;
156 bool mbBubbleChanged
;
160 DECL_LINK( ClickHdl
, USHORT
* );
161 DECL_LINK( HighlightHdl
, MenuBar::MenuBarButtonCallbackArg
* );
162 DECL_LINK( WaitTimeOutHdl
, Timer
* );
163 DECL_LINK( TimeOutHdl
, Timer
* );
164 DECL_LINK( UserEventHdl
, UpdateCheckUI
* );
165 DECL_LINK( WindowEventHdl
, VclWindowEvent
* );
166 DECL_LINK( ApplicationEventHdl
, VclSimpleEvent
* );
168 BubbleWindow
* GetBubbleWindow();
169 void RemoveBubbleWindow( bool bRemoveIcon
);
170 Image
GetMenuBarIcon( MenuBar
* pMBar
);
171 void AddMenuBarIcon( SystemWindow
* pSysWin
, bool bAddEventHdl
);
172 Image
GetBubbleImage( ::rtl::OUString
&rURL
);
174 uno::Reference
< document::XEventBroadcaster
> getGlobalEventBroadcaster() const
175 throw (uno::RuntimeException
);
178 UpdateCheckUI(const uno::Reference
<uno::XComponentContext
>&);
179 virtual ~UpdateCheckUI();
182 virtual rtl::OUString SAL_CALL
getImplementationName()
183 throw (uno::RuntimeException
);
184 virtual sal_Bool SAL_CALL
supportsService(rtl::OUString
const & serviceName
)
185 throw (uno::RuntimeException
);
186 virtual uno::Sequence
< rtl::OUString
> SAL_CALL
getSupportedServiceNames()
187 throw (uno::RuntimeException
);
190 virtual void SAL_CALL
notifyEvent(const document::EventObject
& Event
)
191 throw (uno::RuntimeException
);
192 virtual void SAL_CALL
disposing(const lang::EventObject
& Event
)
193 throw (uno::RuntimeException
);
196 virtual uno::Reference
< beans::XPropertySetInfo
> SAL_CALL
getPropertySetInfo(void)
197 throw ( uno::RuntimeException
);
198 virtual void SAL_CALL
setPropertyValue(const rtl::OUString
& PropertyName
, const uno::Any
& aValue
)
199 throw( beans::UnknownPropertyException
, beans::PropertyVetoException
,
200 lang::IllegalArgumentException
, lang::WrappedTargetException
, uno::RuntimeException
);
201 virtual uno::Any SAL_CALL
getPropertyValue(const rtl::OUString
& PropertyName
)
202 throw ( beans::UnknownPropertyException
, lang::WrappedTargetException
, uno::RuntimeException
);
203 virtual void SAL_CALL
addPropertyChangeListener(const rtl::OUString
& PropertyName
,
204 const uno::Reference
< beans::XPropertyChangeListener
> & aListener
)
205 throw( beans::UnknownPropertyException
, lang::WrappedTargetException
, uno::RuntimeException
);
206 virtual void SAL_CALL
removePropertyChangeListener(const rtl::OUString
& PropertyName
,
207 const uno::Reference
< beans::XPropertyChangeListener
> & aListener
)
208 throw( beans::UnknownPropertyException
, lang::WrappedTargetException
, uno::RuntimeException
);
209 virtual void SAL_CALL
addVetoableChangeListener(const rtl::OUString
& PropertyName
,
210 const uno::Reference
< beans::XVetoableChangeListener
> & aListener
)
211 throw( beans::UnknownPropertyException
, lang::WrappedTargetException
, uno::RuntimeException
);
212 virtual void SAL_CALL
removeVetoableChangeListener(const rtl::OUString
& PropertyName
,
213 const uno::Reference
< beans::XVetoableChangeListener
> & aListener
)
214 throw( beans::UnknownPropertyException
, lang::WrappedTargetException
, uno::RuntimeException
);
217 //------------------------------------------------------------------------------
218 UpdateCheckUI::UpdateCheckUI(const uno::Reference
<uno::XComponentContext
>& xContext
) :
220 , mpBubbleWin( NULL
)
221 , mpIconSysWin( NULL
)
223 , mbShowBubble( false )
224 , mbShowMenuIcon( false )
225 , mbBubbleChanged( false )
228 mpUpdResMgr
= ResMgr::CreateResMgr( "updchk" );
229 mpSfxResMgr
= ResMgr::CreateResMgr( "sfx" );
231 maBubbleImage
= GetBubbleImage( maBubbleImageURL
);
233 maWaitTimer
.SetTimeout( 400 );
234 maWaitTimer
.SetTimeoutHdl( LINK( this, UpdateCheckUI
, WaitTimeOutHdl
) );
236 maTimeoutTimer
.SetTimeout( 10000 );
237 maTimeoutTimer
.SetTimeoutHdl( LINK( this, UpdateCheckUI
, TimeOutHdl
) );
239 uno::Reference
< document::XEventBroadcaster
> xBroadcaster( getGlobalEventBroadcaster() );
240 xBroadcaster
->addEventListener( this );
242 maWindowEventHdl
= LINK( this, UpdateCheckUI
, WindowEventHdl
);
243 maApplicationEventHdl
= LINK( this, UpdateCheckUI
, ApplicationEventHdl
);
244 Application::AddEventListener( maApplicationEventHdl
);
247 //------------------------------------------------------------------------------
248 UpdateCheckUI::~UpdateCheckUI()
250 Application::RemoveEventListener( maApplicationEventHdl
);
251 RemoveBubbleWindow( true );
256 //------------------------------------------------------------------------------
257 uno::Reference
<document::XEventBroadcaster
>
258 UpdateCheckUI::getGlobalEventBroadcaster() const throw (uno::RuntimeException
)
260 if( !m_xContext
.is() )
261 throw uno::RuntimeException(
262 UNISTRING( "UpdateCheckUI: empty component context" ),
263 uno::Reference
< uno::XInterface
>() );
265 uno::Reference
< lang::XMultiComponentFactory
> xServiceManager(m_xContext
->getServiceManager());
267 if( !xServiceManager
.is() )
268 throw uno::RuntimeException(
269 UNISTRING( "UpdateCheckUI: unable to obtain service manager from component context" ),
270 uno::Reference
< uno::XInterface
>() );
272 return uno::Reference
<document::XEventBroadcaster
> (
273 xServiceManager
->createInstanceWithContext(
274 UNISTRING( "com.sun.star.frame.GlobalEventBroadcaster" ),
276 uno::UNO_QUERY_THROW
);
279 //------------------------------------------------------------------------------
280 rtl::OUString SAL_CALL
281 UpdateCheckUI::getImplementationName() throw (uno::RuntimeException
)
283 return ::getImplementationName();
286 //------------------------------------------------------------------------------
287 uno::Sequence
< rtl::OUString
> SAL_CALL
288 UpdateCheckUI::getSupportedServiceNames() throw (uno::RuntimeException
)
290 return ::getServiceNames();
293 //------------------------------------------------------------------------------
295 UpdateCheckUI::supportsService( rtl::OUString
const & serviceName
) throw (uno::RuntimeException
)
297 uno::Sequence
< rtl::OUString
> aServiceNameList
= ::getServiceNames();
299 for( sal_Int32 n
=0; n
< aServiceNameList
.getLength(); n
++ )
300 if( aServiceNameList
[n
].equals(serviceName
) )
306 //------------------------------------------------------------------------------
307 Image
UpdateCheckUI::GetMenuBarIcon( MenuBar
* pMBar
)
310 Window
*pMBarWin
= pMBar
->GetWindow();
311 sal_uInt32 nMBarHeight
= 20;
314 nMBarHeight
= pMBarWin
->GetOutputSizePixel().getHeight();
316 if ( Application::GetSettings().GetStyleSettings().GetHighContrastMode() ) {
317 if ( nMBarHeight
>= 35 )
318 nResID
= RID_UPDATE_AVAILABLE_26_HC
;
320 nResID
= RID_UPDATE_AVAILABLE_16_HC
;
322 if ( nMBarHeight
>= 35 )
323 nResID
= RID_UPDATE_AVAILABLE_26
;
325 nResID
= RID_UPDATE_AVAILABLE_16
;
328 return Image( ResId( nResID
, *mpUpdResMgr
) );
331 //------------------------------------------------------------------------------
332 Image
UpdateCheckUI::GetBubbleImage( ::rtl::OUString
&rURL
)
336 if ( maBubbleImageURL
.getLength() != 0 )
338 uno::Reference
< lang::XMultiServiceFactory
> xServiceManager
= ::comphelper::getProcessServiceFactory();
340 if( !xServiceManager
.is() )
341 throw uno::RuntimeException(
342 UNISTRING( "UpdateCheckUI: unable to obtain service manager from component context" ),
343 uno::Reference
< uno::XInterface
>() );
347 uno::Reference
< graphic::XGraphicProvider
> xGraphProvider(
348 xServiceManager
->createInstance(
349 ::rtl::OUString::createFromAscii( "com.sun.star.graphic.GraphicProvider" ) ),
351 if ( xGraphProvider
.is() )
353 uno::Sequence
< beans::PropertyValue
> aMediaProps( 1 );
354 aMediaProps
[0].Name
= ::rtl::OUString::createFromAscii( "URL" );
355 aMediaProps
[0].Value
<<= rURL
;
357 uno::Reference
< graphic::XGraphic
> xGraphic
= xGraphProvider
->queryGraphic( aMediaProps
);
360 aImage
= Image( xGraphic
);
364 catch( uno::Exception
& )
369 if ( aImage
.GetSizePixel().Width() == 0 )
370 aImage
= InfoBox::GetStandardImage();
375 //------------------------------------------------------------------------------
376 void UpdateCheckUI::AddMenuBarIcon( SystemWindow
*pSysWin
, bool bAddEventHdl
)
378 if ( ! mbShowMenuIcon
)
381 vos::OGuard
aGuard( Application::GetSolarMutex() );
383 MenuBar
*pActiveMBar
= pSysWin
->GetMenuBar();
384 if ( ( pSysWin
!= mpIconSysWin
) || ( pActiveMBar
!= mpIconMBar
) )
386 if ( bAddEventHdl
&& mpIconSysWin
)
387 mpIconSysWin
->RemoveEventListener( maWindowEventHdl
);
389 RemoveBubbleWindow( true );
393 rtl::OUStringBuffer aBuf
;
394 if( maBubbleTitle
.getLength() )
395 aBuf
.append( maBubbleTitle
);
396 if( maBubbleText
.getLength() )
398 if( maBubbleTitle
.getLength() )
399 aBuf
.appendAscii( "\n\n" );
400 aBuf
.append( maBubbleText
);
403 Image aImage
= GetMenuBarIcon( pActiveMBar
);
404 mnIconID
= pActiveMBar
->AddMenuBarButton( aImage
,
405 LINK( this, UpdateCheckUI
, ClickHdl
),
406 aBuf
.makeStringAndClear()
408 pActiveMBar
->SetMenuBarButtonHighlightHdl( mnIconID
,
409 LINK( this, UpdateCheckUI
, HighlightHdl
) );
411 mpIconMBar
= pActiveMBar
;
412 mpIconSysWin
= pSysWin
;
413 if ( bAddEventHdl
&& mpIconSysWin
)
414 mpIconSysWin
->AddEventListener( maWindowEventHdl
);
417 if ( mbShowBubble
&& pActiveMBar
)
419 mpBubbleWin
= GetBubbleWindow();
422 mpBubbleWin
->Show( TRUE
);
423 maTimeoutTimer
.Start();
425 mbShowBubble
= false;
429 //------------------------------------------------------------------------------
430 void SAL_CALL
UpdateCheckUI::notifyEvent(const document::EventObject
& rEvent
)
431 throw (uno::RuntimeException
)
433 vos::OGuard
aGuard( Application::GetSolarMutex() );
435 if( rEvent
.EventName
.compareToAscii( RTL_CONSTASCII_STRINGPARAM("OnPrepareViewClosing") ) == 0 )
437 RemoveBubbleWindow( true );
441 //------------------------------------------------------------------------------
442 void SAL_CALL
UpdateCheckUI::disposing(const lang::EventObject
&)
443 throw (uno::RuntimeException
)
447 //------------------------------------------------------------------------------
448 uno::Reference
< beans::XPropertySetInfo
> UpdateCheckUI::getPropertySetInfo(void)
449 throw ( uno::RuntimeException
)
454 //------------------------------------------------------------------------------
455 void UpdateCheckUI::setPropertyValue(const rtl::OUString
& rPropertyName
,
456 const uno::Any
& rValue
)
457 throw( beans::UnknownPropertyException
, beans::PropertyVetoException
,
458 lang::IllegalArgumentException
, lang::WrappedTargetException
, uno::RuntimeException
)
460 vos::OGuard
aGuard( Application::GetSolarMutex() );
462 rtl::OUString aString
;
464 if( rPropertyName
.compareToAscii( PROPERTY_TITLE
) == 0 ) {
466 if ( aString
!= maBubbleTitle
) {
467 maBubbleTitle
= aString
;
468 mbBubbleChanged
= true;
471 else if( rPropertyName
.compareToAscii( PROPERTY_TEXT
) == 0 ) {
473 if ( aString
!= maBubbleText
) {
474 maBubbleText
= aString
;
475 mbBubbleChanged
= true;
478 else if( rPropertyName
.compareToAscii( PROPERTY_IMAGE
) == 0 ) {
480 if ( aString
!= maBubbleImageURL
) {
481 maBubbleImageURL
= aString
;
482 maBubbleImage
= GetBubbleImage( maBubbleImageURL
);
483 mbBubbleChanged
= true;
486 else if( rPropertyName
.compareToAscii( PROPERTY_SHOW_BUBBLE
) == 0 ) {
487 rValue
>>= mbShowBubble
;
489 Application::PostUserEvent( LINK( this, UpdateCheckUI
, UserEventHdl
) );
490 else if ( mpBubbleWin
)
491 mpBubbleWin
->Show( FALSE
);
493 else if( rPropertyName
.compareToAscii( PROPERTY_CLICK_HDL
) == 0 ) {
494 uno::Reference
< task::XJob
> aJob
;
499 throw lang::IllegalArgumentException();
501 else if (rPropertyName
.compareToAscii( PROPERTY_SHOW_MENUICON
) == 0) {
502 bool bShowMenuIcon
= sal_False
;
503 rValue
>>= bShowMenuIcon
;
504 if ( bShowMenuIcon
!= mbShowMenuIcon
)
506 mbShowMenuIcon
= bShowMenuIcon
;
508 Application::PostUserEvent( LINK( this, UpdateCheckUI
, UserEventHdl
) );
510 RemoveBubbleWindow( true );
514 throw beans::UnknownPropertyException();
516 if ( mbBubbleChanged
&& mpBubbleWin
)
517 mpBubbleWin
->Show( FALSE
);
520 //------------------------------------------------------------------------------
521 uno::Any
UpdateCheckUI::getPropertyValue(const rtl::OUString
& rPropertyName
)
522 throw( beans::UnknownPropertyException
, lang::WrappedTargetException
, uno::RuntimeException
)
524 vos::OGuard
aGuard( Application::GetSolarMutex() );
528 if( rPropertyName
.compareToAscii( PROPERTY_TITLE
) == 0 )
529 aRet
= uno::makeAny( maBubbleTitle
);
530 else if( rPropertyName
.compareToAscii( PROPERTY_TEXT
) == 0 )
531 aRet
= uno::makeAny( maBubbleText
);
532 else if( rPropertyName
.compareToAscii( PROPERTY_SHOW_BUBBLE
) == 0 )
533 aRet
= uno::makeAny( mbShowBubble
);
534 else if( rPropertyName
.compareToAscii( PROPERTY_IMAGE
) == 0 )
535 aRet
= uno::makeAny( maBubbleImageURL
);
536 else if( rPropertyName
.compareToAscii( PROPERTY_CLICK_HDL
) == 0 )
537 aRet
= uno::makeAny( mrJob
);
538 else if( rPropertyName
.compareToAscii( PROPERTY_SHOW_MENUICON
) == 0 )
539 aRet
= uno::makeAny( mbShowMenuIcon
);
541 throw beans::UnknownPropertyException();
546 //------------------------------------------------------------------------------
547 void UpdateCheckUI::addPropertyChangeListener( const rtl::OUString
& /*aPropertyName*/,
548 const uno::Reference
< beans::XPropertyChangeListener
> & /*aListener*/)
549 throw( beans::UnknownPropertyException
, lang::WrappedTargetException
, uno::RuntimeException
)
551 //no bound properties
554 //------------------------------------------------------------------------------
555 void UpdateCheckUI::removePropertyChangeListener( const rtl::OUString
& /*aPropertyName*/,
556 const uno::Reference
< beans::XPropertyChangeListener
> & /*aListener*/)
557 throw( beans::UnknownPropertyException
, lang::WrappedTargetException
, uno::RuntimeException
)
559 //no bound properties
562 //------------------------------------------------------------------------------
563 void UpdateCheckUI::addVetoableChangeListener( const rtl::OUString
& /*aPropertyName*/,
564 const uno::Reference
< beans::XVetoableChangeListener
> & /*aListener*/)
565 throw( beans::UnknownPropertyException
, lang::WrappedTargetException
, uno::RuntimeException
)
567 //no vetoable properties
570 //------------------------------------------------------------------------------
571 void UpdateCheckUI::removeVetoableChangeListener( const rtl::OUString
& /*aPropertyName*/,
572 const uno::Reference
< beans::XVetoableChangeListener
> & /*aListener*/)
573 throw( beans::UnknownPropertyException
, lang::WrappedTargetException
, uno::RuntimeException
)
575 //no vetoable properties
579 //------------------------------------------------------------------------------
580 //------------------------------------------------------------------------------
581 //------------------------------------------------------------------------------
582 BubbleWindow
* UpdateCheckUI::GetBubbleWindow()
587 Rectangle aIconRect
= mpIconMBar
->GetMenuBarButtonRectPixel( mnIconID
);
588 if( aIconRect
.IsEmpty() )
591 BubbleWindow
* pBubbleWin
= mpBubbleWin
;
594 pBubbleWin
= new BubbleWindow( mpIconSysWin
,
595 XubString( maBubbleTitle
),
596 XubString( maBubbleText
),
598 mbBubbleChanged
= false;
600 else if ( mbBubbleChanged
) {
601 pBubbleWin
->SetTitleAndText( XubString( maBubbleTitle
),
602 XubString( maBubbleText
),
604 mbBubbleChanged
= false;
607 Point aWinPos
= aIconRect
.BottomCenter();
609 pBubbleWin
->SetTipPosPixel( aWinPos
);
614 //------------------------------------------------------------------------------
615 void UpdateCheckUI::RemoveBubbleWindow( bool bRemoveIcon
)
617 vos::OGuard
aGuard( Application::GetSolarMutex() );
620 maTimeoutTimer
.Stop();
631 if ( mpIconMBar
&& ( mnIconID
!= 0 ) )
633 mpIconMBar
->RemoveMenuBarButton( mnIconID
);
647 // -----------------------------------------------------------------------
648 IMPL_LINK( UpdateCheckUI
, ClickHdl
, USHORT
*, EMPTYARG
)
650 vos::OGuard
aGuard( Application::GetSolarMutex() );
654 mpBubbleWin
->Show( FALSE
);
659 uno::Sequence
<beans::NamedValue
> aEmpty
;
660 mrJob
->execute( aEmpty
);
662 catch(const uno::Exception
&) {
663 ErrorBox( NULL
, ResId( MSG_ERR_NO_WEBBROWSER_FOUND
, *mpSfxResMgr
)).Execute();
670 // -----------------------------------------------------------------------
671 IMPL_LINK( UpdateCheckUI
, HighlightHdl
, MenuBar::MenuBarButtonCallbackArg
*, pData
)
673 if ( pData
->bHighlight
)
676 RemoveBubbleWindow( false );
681 // -----------------------------------------------------------------------
682 IMPL_LINK( UpdateCheckUI
, WaitTimeOutHdl
, Timer
*, EMPTYARG
)
684 vos::OGuard
aGuard( Application::GetSolarMutex() );
686 mpBubbleWin
= GetBubbleWindow();
696 // -----------------------------------------------------------------------
697 IMPL_LINK( UpdateCheckUI
, TimeOutHdl
, Timer
*, EMPTYARG
)
699 RemoveBubbleWindow( false );
704 // -----------------------------------------------------------------------
705 IMPL_LINK( UpdateCheckUI
, UserEventHdl
, UpdateCheckUI
*, EMPTYARG
)
707 vos::OGuard
aGuard( Application::GetSolarMutex() );
709 Window
*pTopWin
= Application::GetFirstTopLevelWindow();
710 Window
*pActiveWin
= Application::GetActiveTopWindow();
711 SystemWindow
*pActiveSysWin
= NULL
;
713 Window
*pBubbleWin
= NULL
;
715 pBubbleWin
= mpBubbleWin
;
717 if ( pActiveWin
&& ( pActiveWin
!= pBubbleWin
) && pActiveWin
->IsTopWindow() )
718 pActiveSysWin
= pActiveWin
->GetSystemWindow();
720 if ( pActiveWin
== pBubbleWin
)
721 pActiveSysWin
= NULL
;
723 while ( !pActiveSysWin
&& pTopWin
)
725 if ( ( pTopWin
!= pBubbleWin
) && pTopWin
->IsTopWindow() )
726 pActiveSysWin
= pTopWin
->GetSystemWindow();
727 if ( !pActiveSysWin
)
728 pTopWin
= Application::GetNextTopLevelWindow( pTopWin
);
732 AddMenuBarIcon( pActiveSysWin
, true );
737 // -----------------------------------------------------------------------
738 IMPL_LINK( UpdateCheckUI
, WindowEventHdl
, VclWindowEvent
*, pEvent
)
740 ULONG nEventID
= pEvent
->GetId();
742 if ( VCLEVENT_OBJECT_DYING
== nEventID
)
744 vos::OGuard
aGuard( Application::GetSolarMutex() );
745 if ( mpIconSysWin
== pEvent
->GetWindow() )
747 mpIconSysWin
->RemoveEventListener( maWindowEventHdl
);
748 RemoveBubbleWindow( true );
751 else if ( VCLEVENT_WINDOW_MENUBARADDED
== nEventID
)
753 vos::OGuard
aGuard( Application::GetSolarMutex() );
754 Window
*pWindow
= pEvent
->GetWindow();
757 SystemWindow
*pSysWin
= pWindow
->GetSystemWindow();
760 AddMenuBarIcon( pSysWin
, false );
764 else if ( VCLEVENT_WINDOW_MENUBARREMOVED
== nEventID
)
766 vos::OGuard
aGuard( Application::GetSolarMutex() );
767 MenuBar
*pMBar
= (MenuBar
*) pEvent
->GetData();
768 if ( pMBar
&& ( pMBar
== mpIconMBar
) )
769 RemoveBubbleWindow( true );
771 else if ( ( nEventID
== VCLEVENT_WINDOW_MOVE
) ||
772 ( nEventID
== VCLEVENT_WINDOW_RESIZE
) )
774 vos::OGuard
aGuard( Application::GetSolarMutex() );
775 if ( ( mpIconSysWin
== pEvent
->GetWindow() ) &&
776 ( mpBubbleWin
!= NULL
) && ( mpIconMBar
!= NULL
) )
778 Rectangle aIconRect
= mpIconMBar
->GetMenuBarButtonRectPixel( mnIconID
);
779 Point aWinPos
= aIconRect
.BottomCenter();
780 mpBubbleWin
->SetTipPosPixel( aWinPos
);
781 if ( mpBubbleWin
->IsVisible() )
782 mpBubbleWin
->Show(); // This will recalc the screen positon of the bubble
789 //------------------------------------------------------------------------------
790 IMPL_LINK( UpdateCheckUI
, ApplicationEventHdl
, VclSimpleEvent
*, pEvent
)
792 switch (pEvent
->GetId())
794 case VCLEVENT_WINDOW_SHOW
:
795 case VCLEVENT_WINDOW_ACTIVATE
:
796 case VCLEVENT_WINDOW_GETFOCUS
: {
797 vos::OGuard
aGuard( Application::GetSolarMutex() );
799 Window
*pWindow
= static_cast< VclWindowEvent
* >(pEvent
)->GetWindow();
800 if ( pWindow
&& pWindow
->IsTopWindow() )
802 SystemWindow
*pSysWin
= pWindow
->GetSystemWindow();
803 MenuBar
*pMBar
= pSysWin
->GetMenuBar();
804 if ( pSysWin
&& pMBar
)
806 AddMenuBarIcon( pSysWin
, true );
814 //------------------------------------------------------------------------------
815 //------------------------------------------------------------------------------
816 //------------------------------------------------------------------------------
818 #define TIP_HEIGHT 15
820 #define TIP_RIGHT_OFFSET 18
821 #define BUBBLE_BORDER 10
822 #define TEXT_MAX_WIDTH 300
823 #define TEXT_MAX_HEIGHT 200
824 #define INITIAL_SHOW_TIME 10000
826 //------------------------------------------------------------------------------
827 BubbleWindow::BubbleWindow( Window
* pParent
, const XubString
& rTitle
,
828 const XubString
& rText
, const Image
& rImage
)
829 : FloatingWindow( pParent
, WB_SYSTEMWINDOW
830 | WB_OWNERDRAWDECORATION
833 , maBubbleTitle( rTitle
)
834 , maBubbleText( rText
)
835 , maBubbleImage( rImage
)
836 , maMaxTextSize( TEXT_MAX_WIDTH
, TEXT_MAX_HEIGHT
)
839 SetBackground( Wallpaper( GetSettings().GetStyleSettings().GetHelpColor() ) );
842 //------------------------------------------------------------------------------
843 BubbleWindow::~BubbleWindow()
847 //------------------------------------------------------------------------------
848 void BubbleWindow::Resize()
850 vos::OGuard
aGuard( Application::GetSolarMutex() );
852 FloatingWindow::Resize();
854 Size aSize
= GetSizePixel();
856 if ( ( aSize
.Height() < 20 ) || ( aSize
.Width() < 60 ) )
859 Rectangle
aRect( 0, TIP_HEIGHT
, aSize
.Width(), aSize
.Height() - TIP_HEIGHT
);
860 maRectPoly
= Polygon( aRect
, 6, 6 );
861 Region
aRegion( maRectPoly
);
862 long nTipOffset
= aSize
.Width() - TIP_RIGHT_OFFSET
+ mnTipOffset
;
865 aPointArr
[0] = Point( nTipOffset
, TIP_HEIGHT
);
866 aPointArr
[1] = Point( nTipOffset
, 0 );
867 aPointArr
[2] = Point( nTipOffset
+ TIP_WIDTH
, TIP_HEIGHT
);
868 aPointArr
[3] = Point( nTipOffset
, TIP_HEIGHT
);
869 maTriPoly
= Polygon( 4, aPointArr
);
870 Region
aTriRegion( maTriPoly
);
872 aRegion
.Union( aTriRegion
);
875 SetWindowRegionPixel( maBounds
);
878 //------------------------------------------------------------------------------
879 void BubbleWindow::SetTitleAndText( const XubString
& rTitle
,
880 const XubString
& rText
,
881 const Image
& rImage
)
883 maBubbleTitle
= rTitle
;
884 maBubbleText
= rText
;
885 maBubbleImage
= rImage
;
890 //------------------------------------------------------------------------------
891 void BubbleWindow::Paint( const Rectangle
& )
893 vos::OGuard
aGuard( Application::GetSolarMutex() );
895 LineInfo
aThickLine( LINE_SOLID
, 2 );
897 DrawPolyLine( maRectPoly
, aThickLine
);
898 DrawPolyLine( maTriPoly
);
900 Color aOldLine
= GetLineColor();
901 Size aSize
= GetSizePixel();
902 long nTipOffset
= aSize
.Width() - TIP_RIGHT_OFFSET
+ mnTipOffset
;
904 SetLineColor( GetSettings().GetStyleSettings().GetHelpColor() );
905 DrawLine( Point( nTipOffset
+2, TIP_HEIGHT
),
906 Point( nTipOffset
+ TIP_WIDTH
-1 , TIP_HEIGHT
),
908 SetLineColor( aOldLine
);
910 //Image aImage = InfoBox::GetStandardImage();
911 Size aImgSize
= maBubbleImage
.GetSizePixel();
913 DrawImage( Point( BUBBLE_BORDER
, BUBBLE_BORDER
+ TIP_HEIGHT
), maBubbleImage
);
915 Font aOldFont
= GetFont();
916 Font aBoldFont
= aOldFont
;
917 aBoldFont
.SetWeight( WEIGHT_BOLD
);
919 SetFont( aBoldFont
);
920 Rectangle aTitleRect
= maTitleRect
;
921 aTitleRect
.Move( aImgSize
.Width(), 0 );
922 DrawText( aTitleRect
, maBubbleTitle
, TEXT_DRAW_MULTILINE
| TEXT_DRAW_WORDBREAK
);
925 Rectangle aTextRect
= maTextRect
;
926 aTextRect
.Move( aImgSize
.Width(), 0 );
927 DrawText( aTextRect
, maBubbleText
, TEXT_DRAW_MULTILINE
| TEXT_DRAW_WORDBREAK
);
930 //------------------------------------------------------------------------------
931 void BubbleWindow::MouseButtonDown( const MouseEvent
& )
936 //------------------------------------------------------------------------------
937 void BubbleWindow::Show( BOOL bVisible
, USHORT nFlags
)
939 vos::OGuard
aGuard( Application::GetSolarMutex() );
943 FloatingWindow::Show( bVisible
);
947 // don't show bubbles without a text
948 if ( ( maBubbleTitle
.Len() == 0 ) && ( maBubbleText
.Len() == 0 ) )
951 Size aWindowSize
= GetSizePixel();
953 // Image aImage = InfoBox::GetStandardImage();
954 Size aImgSize
= maBubbleImage
.GetSizePixel();
958 aWindowSize
.setHeight( maTitleRect
.GetHeight() * 7 / 4+ maTextRect
.GetHeight() +
959 3 * BUBBLE_BORDER
+ TIP_HEIGHT
);
961 if ( maTitleRect
.GetWidth() > maTextRect
.GetWidth() )
962 aWindowSize
.setWidth( maTitleRect
.GetWidth() );
964 aWindowSize
.setWidth( maTextRect
.GetWidth() );
966 aWindowSize
.setWidth( aWindowSize
.Width() + 3 * BUBBLE_BORDER
+ aImgSize
.Width() );
968 if ( aWindowSize
.Height() < aImgSize
.Height() + TIP_HEIGHT
+ 2 * BUBBLE_BORDER
)
969 aWindowSize
.setHeight( aImgSize
.Height() + TIP_HEIGHT
+ 2 * BUBBLE_BORDER
);
972 aPos
.X() = maTipPos
.X() - aWindowSize
.Width() + TIP_RIGHT_OFFSET
;
973 aPos
.Y() = maTipPos
.Y();
974 Point aScreenPos
= GetParent()->OutputToAbsoluteScreenPixel( aPos
);
975 if ( aScreenPos
.X() < 0 )
977 mnTipOffset
= aScreenPos
.X();
978 aPos
.X() -= mnTipOffset
;
980 SetPosSizePixel( aPos
, aWindowSize
);
982 FloatingWindow::Show( bVisible
, nFlags
);
985 //------------------------------------------------------------------------------
986 void BubbleWindow::RecalcTextRects()
989 BOOL bFinished
= FALSE
;
990 Font aOldFont
= GetFont();
991 Font aBoldFont
= aOldFont
;
993 aBoldFont
.SetWeight( WEIGHT_BOLD
);
997 SetFont( aBoldFont
);
999 maTitleRect
= GetTextRect( Rectangle( Point( 0, 0 ), maMaxTextSize
),
1001 TEXT_DRAW_MULTILINE
| TEXT_DRAW_WORDBREAK
);
1003 SetFont( aOldFont
);
1004 maTextRect
= GetTextRect( Rectangle( Point( 0, 0 ), maMaxTextSize
),
1006 TEXT_DRAW_MULTILINE
| TEXT_DRAW_WORDBREAK
);
1008 if ( maTextRect
.GetHeight() < 10 )
1009 maTextRect
.setHeight( 10 );
1011 aTotalSize
.setHeight( maTitleRect
.GetHeight() +
1012 aBoldFont
.GetHeight() * 3 / 4 +
1013 maTextRect
.GetHeight() +
1014 3 * BUBBLE_BORDER
+ TIP_HEIGHT
);
1015 if ( aTotalSize
.Height() > maMaxTextSize
.Height() )
1017 maMaxTextSize
.Width() = maMaxTextSize
.Width() * 3 / 2;
1018 maMaxTextSize
.Height() = maMaxTextSize
.Height() * 3 / 2;
1023 maTitleRect
.Move( 2*BUBBLE_BORDER
, BUBBLE_BORDER
+ TIP_HEIGHT
);
1024 maTextRect
.Move( 2*BUBBLE_BORDER
, BUBBLE_BORDER
+ TIP_HEIGHT
+ maTitleRect
.GetHeight() + aBoldFont
.GetHeight() * 3 / 4 );
1026 //------------------------------------------------------------------------------
1027 //------------------------------------------------------------------------------
1028 //------------------------------------------------------------------------------
1030 } // anonymous namespace
1032 //------------------------------------------------------------------------------
1034 static uno::Reference
<uno::XInterface
> SAL_CALL
1035 createInstance(const uno::Reference
<uno::XComponentContext
>& xContext
)
1037 return *new UpdateCheckUI(xContext
);
1040 //------------------------------------------------------------------------------
1042 static const cppu::ImplementationEntry kImplementations_entries
[] =
1046 getImplementationName
,
1048 cppu::createSingleComponentFactory
,
1052 { NULL
, NULL
, NULL
, NULL
, NULL
, 0 }
1055 //------------------------------------------------------------------------------
1057 extern "C" void SAL_CALL
1058 component_getImplementationEnvironment( const sal_Char
**aEnvTypeName
, uno_Environment
**)
1060 *aEnvTypeName
= CPPU_CURRENT_LANGUAGE_BINDING_NAME
;
1063 //------------------------------------------------------------------------------
1065 extern "C" sal_Bool SAL_CALL
1066 component_writeInfo(void *pServiceManager
, void *pRegistryKey
)
1068 return cppu::component_writeInfoHelper(
1071 kImplementations_entries
1075 //------------------------------------------------------------------------------
1078 component_getFactory(const sal_Char
*pszImplementationName
, void *pServiceManager
, void *pRegistryKey
)
1080 return cppu::component_getFactoryHelper(
1081 pszImplementationName
,
1084 kImplementations_entries
) ;