diff options
Diffstat (limited to 'extensions/source/update/ui')
-rw-r--r-- | extensions/source/update/ui/makefile.mk | 74 | ||||
-rw-r--r-- | extensions/source/update/ui/updatecheckui.cxx | 1083 | ||||
-rw-r--r-- | extensions/source/update/ui/updatecheckui.hrc | 36 | ||||
-rw-r--r-- | extensions/source/update/ui/updatecheckui.src | 51 | ||||
-rw-r--r-- | extensions/source/update/ui/updchkui.xml | 34 |
5 files changed, 1278 insertions, 0 deletions
diff --git a/extensions/source/update/ui/makefile.mk b/extensions/source/update/ui/makefile.mk new file mode 100644 index 000000000000..c4826efba9ca --- /dev/null +++ b/extensions/source/update/ui/makefile.mk @@ -0,0 +1,74 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* +PRJ=..$/..$/.. + +PRJNAME=extensions +TARGET=updchkui + +LIBTARGET=NO +ENABLE_EXCEPTIONS=TRUE + +# --- Settings --- + +.INCLUDE : settings.mk + +# --- Files --- + +SLOFILES=\ + $(SLO)$/updatecheckui.obj + +SRS1NAME=$(TARGET) +SRC1FILES=\ + updatecheckui.src + +RESLIB1NAME=updchk +RESLIB1IMAGES=$(PRJ)$/source$/update$/ui +RESLIB1SRSFILES= $(SRS)$/updchkui.srs +RESLIB1DEPN= updatecheckui.src updatecheckui.hrc + +SHL1NOCHECK=TRUE +SHL1TARGET=updchk$(DLLPOSTFIX) +SHL1OBJS=$(SLOFILES) +SHL1DEF=$(MISC)$/$(SHL1TARGET).def + +SHL1IMPLIB=i$(SHL1TARGET) +SHL1STDLIBS= \ + $(COMPHELPERLIB) \ + $(CPPUHELPERLIB) \ + $(CPPULIB) \ + $(SALLIB) \ + $(VCLLIB) \ + $(TOOLSLIB) + +SHL1VERSIONMAP=$(SOLARENV)/src/component.map +SHL1DEF=$(MISC)$/$(SHL1TARGET).def +DEF1NAME=$(SHL1TARGET) + +# --- Targets --- + +.INCLUDE : target.mk + diff --git a/extensions/source/update/ui/updatecheckui.cxx b/extensions/source/update/ui/updatecheckui.cxx new file mode 100644 index 000000000000..a2a8c31908fc --- /dev/null +++ b/extensions/source/update/ui/updatecheckui.cxx @@ -0,0 +1,1083 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_extensions.hxx" + +#include <list> + +#include <cppuhelper/implbase3.hxx> +#include <cppuhelper/implementationentry.hxx> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/document/XEventListener.hpp> +#include <com/sun/star/document/XEventBroadcaster.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/graphic/XGraphicProvider.hpp> +#include <com/sun/star/task/XJob.hpp> + +#include <comphelper/processfactory.hxx> + +#include <vos/mutex.hxx> +#include <osl/mutex.hxx> + +#include <vcl/window.hxx> +#include <vcl/floatwin.hxx> +#include <vcl/timer.hxx> +#include <vcl/menu.hxx> +#include <vcl/outdev.hxx> +#include <vcl/msgbox.hxx> +#include <vcl/lineinfo.hxx> +#include <vcl/imagebtn.hxx> +#include <vcl/settings.hxx> +#include <vcl/svapp.hxx> +#include <sfx2/sfx.hrc> +#include "rtl/ustrbuf.hxx" + +#include "updatecheckui.hrc" + +#define UNISTRING(s) rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(s)) + +#define MSG_ERR_NO_WEBBROWSER_FOUND (RID_SFX_APP_START + 7) +#define DEFAULT_MENUBAR_HEIGHT 24 + +#define PROPERTY_TITLE RTL_CONSTASCII_STRINGPARAM("BubbleHeading") +#define PROPERTY_TEXT RTL_CONSTASCII_STRINGPARAM("BubbleText") +#define PROPERTY_IMAGE RTL_CONSTASCII_STRINGPARAM("BubbleImageURL") +#define PROPERTY_SHOW_BUBBLE RTL_CONSTASCII_STRINGPARAM("BubbleVisible") +#define PROPERTY_CLICK_HDL RTL_CONSTASCII_STRINGPARAM("MenuClickHDL") +#define PROPERTY_SHOW_MENUICON RTL_CONSTASCII_STRINGPARAM("MenuIconVisible") + +#define START_TIMER 1 + +using namespace ::com::sun::star; + +//------------------------------------------------------------------------------ + +static uno::Sequence< rtl::OUString > getServiceNames() +{ + uno::Sequence< rtl::OUString > aServiceList(1); + aServiceList[0] = UNISTRING( "com.sun.star.setup.UpdateCheckUI"); + return aServiceList; +} + +//------------------------------------------------------------------------------ + +static rtl::OUString getImplementationName() +{ + return UNISTRING( "vnd.sun.UpdateCheckUI"); +} + +//------------------------------------------------------------------------------ + +namespace +{ + +//------------------------------------------------------------------------------ +class BubbleWindow : public FloatingWindow +{ + Point maTipPos; + Region maBounds; + Polygon maRectPoly; + Polygon maTriPoly; + XubString maBubbleTitle; + XubString maBubbleText; + Image maBubbleImage; + Size maMaxTextSize; + Rectangle maTitleRect; + Rectangle maTextRect; + long mnTipOffset; + +private: + void RecalcTextRects(); + +public: + BubbleWindow( Window* pParent, const XubString& rTitle, + const XubString& rText, const Image& rImage ); + ~BubbleWindow(); + + virtual void MouseButtonDown( const MouseEvent& rMEvt ); + virtual void Paint( const Rectangle& rRect ); + void Resize(); + void Show( BOOL bVisible = TRUE, USHORT nFlags = SHOW_NOACTIVATE ); + void SetTipPosPixel( const Point& rTipPos ) { maTipPos = rTipPos; } + void SetTitleAndText( const XubString& rTitle, const XubString& rText, + const Image& rImage ); +}; + +//------------------------------------------------------------------------------ +class UpdateCheckUI : public ::cppu::WeakImplHelper3 + < lang::XServiceInfo, document::XEventListener, beans::XPropertySet > +{ + uno::Reference< uno::XComponentContext > m_xContext; + uno::Reference< task::XJob > mrJob; + rtl::OUString maBubbleTitle; + rtl::OUString maBubbleText; + rtl::OUString maBubbleImageURL; + Image maBubbleImage; + BubbleWindow* mpBubbleWin; + SystemWindow* mpIconSysWin; + MenuBar* mpIconMBar; + ResMgr* mpUpdResMgr; + ResMgr* mpSfxResMgr; + Timer maWaitTimer; + Timer maTimeoutTimer; + Link maWindowEventHdl; + Link maApplicationEventHdl; + bool mbShowBubble; + bool mbShowMenuIcon; + bool mbBubbleChanged; + USHORT mnIconID; + +private: + DECL_LINK( ClickHdl, USHORT* ); + DECL_LINK( HighlightHdl, MenuBar::MenuBarButtonCallbackArg* ); + DECL_LINK( WaitTimeOutHdl, Timer* ); + DECL_LINK( TimeOutHdl, Timer* ); + DECL_LINK( UserEventHdl, UpdateCheckUI* ); + DECL_LINK( WindowEventHdl, VclWindowEvent* ); + DECL_LINK( ApplicationEventHdl, VclSimpleEvent* ); + + BubbleWindow* GetBubbleWindow(); + void RemoveBubbleWindow( bool bRemoveIcon ); + Image GetMenuBarIcon( MenuBar* pMBar ); + void AddMenuBarIcon( SystemWindow* pSysWin, bool bAddEventHdl ); + Image GetBubbleImage( ::rtl::OUString &rURL ); + + uno::Reference< document::XEventBroadcaster > getGlobalEventBroadcaster() const + throw (uno::RuntimeException); + +public: + UpdateCheckUI(const uno::Reference<uno::XComponentContext>&); + virtual ~UpdateCheckUI(); + + // XServiceInfo + virtual rtl::OUString SAL_CALL getImplementationName() + throw (uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsService(rtl::OUString const & serviceName) + throw (uno::RuntimeException); + virtual uno::Sequence< rtl::OUString > SAL_CALL getSupportedServiceNames() + throw (uno::RuntimeException); + + // XEventListener + virtual void SAL_CALL notifyEvent(const document::EventObject& Event) + throw (uno::RuntimeException); + virtual void SAL_CALL disposing(const lang::EventObject& Event) + throw (uno::RuntimeException); + + //XPropertySet + virtual uno::Reference< beans::XPropertySetInfo > SAL_CALL getPropertySetInfo(void) + throw ( uno::RuntimeException ); + virtual void SAL_CALL setPropertyValue(const rtl::OUString& PropertyName, const uno::Any& aValue) + throw( beans::UnknownPropertyException, beans::PropertyVetoException, + lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException ); + virtual uno::Any SAL_CALL getPropertyValue(const rtl::OUString& PropertyName) + throw ( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException ); + virtual void SAL_CALL addPropertyChangeListener(const rtl::OUString& PropertyName, + const uno::Reference< beans::XPropertyChangeListener > & aListener) + throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException ); + virtual void SAL_CALL removePropertyChangeListener(const rtl::OUString& PropertyName, + const uno::Reference< beans::XPropertyChangeListener > & aListener) + throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException ); + virtual void SAL_CALL addVetoableChangeListener(const rtl::OUString& PropertyName, + const uno::Reference< beans::XVetoableChangeListener > & aListener) + throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException ); + virtual void SAL_CALL removeVetoableChangeListener(const rtl::OUString& PropertyName, + const uno::Reference< beans::XVetoableChangeListener > & aListener) + throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException ); +}; + +//------------------------------------------------------------------------------ +UpdateCheckUI::UpdateCheckUI(const uno::Reference<uno::XComponentContext>& xContext) : + m_xContext(xContext) + , mpBubbleWin( NULL ) + , mpIconSysWin( NULL ) + , mpIconMBar( NULL ) + , mbShowBubble( false ) + , mbShowMenuIcon( false ) + , mbBubbleChanged( false ) + , mnIconID( 0 ) +{ + mpUpdResMgr = ResMgr::CreateResMgr( "updchk" ); + mpSfxResMgr = ResMgr::CreateResMgr( "sfx" ); + + maBubbleImage = GetBubbleImage( maBubbleImageURL ); + + maWaitTimer.SetTimeout( 400 ); + maWaitTimer.SetTimeoutHdl( LINK( this, UpdateCheckUI, WaitTimeOutHdl ) ); + + maTimeoutTimer.SetTimeout( 10000 ); + maTimeoutTimer.SetTimeoutHdl( LINK( this, UpdateCheckUI, TimeOutHdl ) ); + + uno::Reference< document::XEventBroadcaster > xBroadcaster( getGlobalEventBroadcaster() ); + xBroadcaster->addEventListener( this ); + + maWindowEventHdl = LINK( this, UpdateCheckUI, WindowEventHdl ); + maApplicationEventHdl = LINK( this, UpdateCheckUI, ApplicationEventHdl ); + Application::AddEventListener( maApplicationEventHdl ); +} + +//------------------------------------------------------------------------------ +UpdateCheckUI::~UpdateCheckUI() +{ + Application::RemoveEventListener( maApplicationEventHdl ); + RemoveBubbleWindow( true ); + delete mpUpdResMgr; + delete mpSfxResMgr; +} + +//------------------------------------------------------------------------------ +uno::Reference<document::XEventBroadcaster> +UpdateCheckUI::getGlobalEventBroadcaster() const throw (uno::RuntimeException) +{ + if( !m_xContext.is() ) + throw uno::RuntimeException( + UNISTRING( "UpdateCheckUI: empty component context" ), + uno::Reference< uno::XInterface >() ); + + uno::Reference< lang::XMultiComponentFactory > xServiceManager(m_xContext->getServiceManager()); + + if( !xServiceManager.is() ) + throw uno::RuntimeException( + UNISTRING( "UpdateCheckUI: unable to obtain service manager from component context" ), + uno::Reference< uno::XInterface >() ); + + return uno::Reference<document::XEventBroadcaster> ( + xServiceManager->createInstanceWithContext( + UNISTRING( "com.sun.star.frame.GlobalEventBroadcaster" ), + m_xContext), + uno::UNO_QUERY_THROW); +} + +//------------------------------------------------------------------------------ +rtl::OUString SAL_CALL +UpdateCheckUI::getImplementationName() throw (uno::RuntimeException) +{ + return ::getImplementationName(); +} + +//------------------------------------------------------------------------------ +uno::Sequence< rtl::OUString > SAL_CALL +UpdateCheckUI::getSupportedServiceNames() throw (uno::RuntimeException) +{ + return ::getServiceNames(); +} + +//------------------------------------------------------------------------------ +sal_Bool SAL_CALL +UpdateCheckUI::supportsService( rtl::OUString const & serviceName ) throw (uno::RuntimeException) +{ + uno::Sequence< rtl::OUString > aServiceNameList = ::getServiceNames(); + + for( sal_Int32 n=0; n < aServiceNameList.getLength(); n++ ) + if( aServiceNameList[n].equals(serviceName) ) + return sal_True; + + return sal_False; +} + +//------------------------------------------------------------------------------ +Image UpdateCheckUI::GetMenuBarIcon( MenuBar* pMBar ) +{ + sal_uInt32 nResID; + Window *pMBarWin = pMBar->GetWindow(); + sal_uInt32 nMBarHeight = 20; + + if ( pMBarWin ) + nMBarHeight = pMBarWin->GetOutputSizePixel().getHeight(); + + if ( Application::GetSettings().GetStyleSettings().GetHighContrastMode() ) { + if ( nMBarHeight >= 35 ) + nResID = RID_UPDATE_AVAILABLE_26_HC; + else + nResID = RID_UPDATE_AVAILABLE_16_HC; + } else { + if ( nMBarHeight >= 35 ) + nResID = RID_UPDATE_AVAILABLE_26; + else + nResID = RID_UPDATE_AVAILABLE_16; + } + + return Image( ResId( nResID, *mpUpdResMgr ) ); +} + +//------------------------------------------------------------------------------ +Image UpdateCheckUI::GetBubbleImage( ::rtl::OUString &rURL ) +{ + Image aImage; + + if ( maBubbleImageURL.getLength() != 0 ) + { + uno::Reference< lang::XMultiServiceFactory > xServiceManager = ::comphelper::getProcessServiceFactory(); + + if( !xServiceManager.is() ) + throw uno::RuntimeException( + UNISTRING( "UpdateCheckUI: unable to obtain service manager from component context" ), + uno::Reference< uno::XInterface >() ); + + try + { + uno::Reference< graphic::XGraphicProvider > xGraphProvider( + xServiceManager->createInstance( + ::rtl::OUString::createFromAscii( "com.sun.star.graphic.GraphicProvider" ) ), + uno::UNO_QUERY ); + if ( xGraphProvider.is() ) + { + uno::Sequence< beans::PropertyValue > aMediaProps( 1 ); + aMediaProps[0].Name = ::rtl::OUString::createFromAscii( "URL" ); + aMediaProps[0].Value <<= rURL; + + uno::Reference< graphic::XGraphic > xGraphic = xGraphProvider->queryGraphic( aMediaProps ); + if ( xGraphic.is() ) + { + aImage = Image( xGraphic ); + } + } + } + catch( uno::Exception& ) + { + } + } + + if ( aImage.GetSizePixel().Width() == 0 ) + aImage = InfoBox::GetStandardImage(); + + return aImage; +} + +//------------------------------------------------------------------------------ +void UpdateCheckUI::AddMenuBarIcon( SystemWindow *pSysWin, bool bAddEventHdl ) +{ + if ( ! mbShowMenuIcon ) + return; + + vos::OGuard aGuard( Application::GetSolarMutex() ); + + MenuBar *pActiveMBar = pSysWin->GetMenuBar(); + if ( ( pSysWin != mpIconSysWin ) || ( pActiveMBar != mpIconMBar ) ) + { + if ( bAddEventHdl && mpIconSysWin ) + mpIconSysWin->RemoveEventListener( maWindowEventHdl ); + + RemoveBubbleWindow( true ); + + if ( pActiveMBar ) + { + rtl::OUStringBuffer aBuf; + if( maBubbleTitle.getLength() ) + aBuf.append( maBubbleTitle ); + if( maBubbleText.getLength() ) + { + if( maBubbleTitle.getLength() ) + aBuf.appendAscii( "\n\n" ); + aBuf.append( maBubbleText ); + } + + Image aImage = GetMenuBarIcon( pActiveMBar ); + mnIconID = pActiveMBar->AddMenuBarButton( aImage, + LINK( this, UpdateCheckUI, ClickHdl ), + aBuf.makeStringAndClear() + ); + pActiveMBar->SetMenuBarButtonHighlightHdl( mnIconID, + LINK( this, UpdateCheckUI, HighlightHdl ) ); + } + mpIconMBar = pActiveMBar; + mpIconSysWin = pSysWin; + if ( bAddEventHdl && mpIconSysWin ) + mpIconSysWin->AddEventListener( maWindowEventHdl ); + } + + if ( mbShowBubble && pActiveMBar ) + { + mpBubbleWin = GetBubbleWindow(); + if ( mpBubbleWin ) + { + mpBubbleWin->Show( TRUE ); + maTimeoutTimer.Start(); + } + mbShowBubble = false; + } +} + +//------------------------------------------------------------------------------ +void SAL_CALL UpdateCheckUI::notifyEvent(const document::EventObject& rEvent) + throw (uno::RuntimeException) +{ + vos::OGuard aGuard( Application::GetSolarMutex() ); + + if( rEvent.EventName.compareToAscii( RTL_CONSTASCII_STRINGPARAM("OnPrepareViewClosing") ) == 0 ) + { + RemoveBubbleWindow( true ); + } +} + +//------------------------------------------------------------------------------ +void SAL_CALL UpdateCheckUI::disposing(const lang::EventObject&) + throw (uno::RuntimeException) +{ +} + +//------------------------------------------------------------------------------ +uno::Reference< beans::XPropertySetInfo > UpdateCheckUI::getPropertySetInfo(void) + throw ( uno::RuntimeException ) +{ + return NULL; +} + +//------------------------------------------------------------------------------ +void UpdateCheckUI::setPropertyValue(const rtl::OUString& rPropertyName, + const uno::Any& rValue) + throw( beans::UnknownPropertyException, beans::PropertyVetoException, + lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException) +{ + vos::OGuard aGuard( Application::GetSolarMutex() ); + + rtl::OUString aString; + + if( rPropertyName.compareToAscii( PROPERTY_TITLE ) == 0 ) { + rValue >>= aString; + if ( aString != maBubbleTitle ) { + maBubbleTitle = aString; + mbBubbleChanged = true; + } + } + else if( rPropertyName.compareToAscii( PROPERTY_TEXT ) == 0 ) { + rValue >>= aString; + if ( aString != maBubbleText ) { + maBubbleText = aString; + mbBubbleChanged = true; + } + } + else if( rPropertyName.compareToAscii( PROPERTY_IMAGE ) == 0 ) { + rValue >>= aString; + if ( aString != maBubbleImageURL ) { + maBubbleImageURL = aString; + maBubbleImage = GetBubbleImage( maBubbleImageURL ); + mbBubbleChanged = true; + } + } + else if( rPropertyName.compareToAscii( PROPERTY_SHOW_BUBBLE ) == 0 ) { + rValue >>= mbShowBubble; + if ( mbShowBubble ) + Application::PostUserEvent( LINK( this, UpdateCheckUI, UserEventHdl ) ); + else if ( mpBubbleWin ) + mpBubbleWin->Show( FALSE ); + } + else if( rPropertyName.compareToAscii( PROPERTY_CLICK_HDL ) == 0 ) { + uno::Reference< task::XJob > aJob; + rValue >>= aJob; + if ( aJob.is() ) + mrJob = aJob; + else + throw lang::IllegalArgumentException(); + } + else if (rPropertyName.compareToAscii( PROPERTY_SHOW_MENUICON ) == 0) { + bool bShowMenuIcon = sal_False; + rValue >>= bShowMenuIcon; + if ( bShowMenuIcon != mbShowMenuIcon ) + { + mbShowMenuIcon = bShowMenuIcon; + if ( bShowMenuIcon ) + Application::PostUserEvent( LINK( this, UpdateCheckUI, UserEventHdl ) ); + else + RemoveBubbleWindow( true ); + } + } + else + throw beans::UnknownPropertyException(); + + if ( mbBubbleChanged && mpBubbleWin ) + mpBubbleWin->Show( FALSE ); +} + +//------------------------------------------------------------------------------ +uno::Any UpdateCheckUI::getPropertyValue(const rtl::OUString& rPropertyName) + throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException ) +{ + vos::OGuard aGuard( Application::GetSolarMutex() ); + + uno::Any aRet; + + if( rPropertyName.compareToAscii( PROPERTY_TITLE ) == 0 ) + aRet = uno::makeAny( maBubbleTitle ); + else if( rPropertyName.compareToAscii( PROPERTY_TEXT ) == 0 ) + aRet = uno::makeAny( maBubbleText ); + else if( rPropertyName.compareToAscii( PROPERTY_SHOW_BUBBLE ) == 0 ) + aRet = uno::makeAny( mbShowBubble ); + else if( rPropertyName.compareToAscii( PROPERTY_IMAGE ) == 0 ) + aRet = uno::makeAny( maBubbleImageURL ); + else if( rPropertyName.compareToAscii( PROPERTY_CLICK_HDL ) == 0 ) + aRet = uno::makeAny( mrJob ); + else if( rPropertyName.compareToAscii( PROPERTY_SHOW_MENUICON ) == 0 ) + aRet = uno::makeAny( mbShowMenuIcon ); + else + throw beans::UnknownPropertyException(); + + return aRet; +} + +//------------------------------------------------------------------------------ +void UpdateCheckUI::addPropertyChangeListener( const rtl::OUString& /*aPropertyName*/, + const uno::Reference< beans::XPropertyChangeListener > & /*aListener*/) + throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException ) +{ + //no bound properties +} + +//------------------------------------------------------------------------------ +void UpdateCheckUI::removePropertyChangeListener( const rtl::OUString& /*aPropertyName*/, + const uno::Reference< beans::XPropertyChangeListener > & /*aListener*/) + throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException ) +{ + //no bound properties +} + +//------------------------------------------------------------------------------ +void UpdateCheckUI::addVetoableChangeListener( const rtl::OUString& /*aPropertyName*/, + const uno::Reference< beans::XVetoableChangeListener > & /*aListener*/) + throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException ) +{ + //no vetoable properties +} + +//------------------------------------------------------------------------------ +void UpdateCheckUI::removeVetoableChangeListener( const rtl::OUString& /*aPropertyName*/, + const uno::Reference< beans::XVetoableChangeListener > & /*aListener*/) + throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException ) +{ + //no vetoable properties +} + + +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ +BubbleWindow * UpdateCheckUI::GetBubbleWindow() +{ + if ( !mpIconSysWin ) + return NULL; + + Rectangle aIconRect = mpIconMBar->GetMenuBarButtonRectPixel( mnIconID ); + if( aIconRect.IsEmpty() ) + return NULL; + + BubbleWindow* pBubbleWin = mpBubbleWin; + + if ( !pBubbleWin ) { + pBubbleWin = new BubbleWindow( mpIconSysWin, + XubString( maBubbleTitle ), + XubString( maBubbleText ), + maBubbleImage ); + mbBubbleChanged = false; + } + else if ( mbBubbleChanged ) { + pBubbleWin->SetTitleAndText( XubString( maBubbleTitle ), + XubString( maBubbleText ), + maBubbleImage ); + mbBubbleChanged = false; + } + + Point aWinPos = aIconRect.BottomCenter(); + + pBubbleWin->SetTipPosPixel( aWinPos ); + + return pBubbleWin; +} + +//------------------------------------------------------------------------------ +void UpdateCheckUI::RemoveBubbleWindow( bool bRemoveIcon ) +{ + vos::OGuard aGuard( Application::GetSolarMutex() ); + + maWaitTimer.Stop(); + maTimeoutTimer.Stop(); + + if ( mpBubbleWin ) + { + delete mpBubbleWin; + mpBubbleWin = NULL; + } + + if ( bRemoveIcon ) + { + try { + if ( mpIconMBar && ( mnIconID != 0 ) ) + { + mpIconMBar->RemoveMenuBarButton( mnIconID ); + mpIconMBar = NULL; + mnIconID = 0; + } + } + catch ( ... ) { + mpIconMBar = NULL; + mnIconID = 0; + } + + mpIconSysWin = NULL; + } +} + +// ----------------------------------------------------------------------- +IMPL_LINK( UpdateCheckUI, ClickHdl, USHORT*, EMPTYARG ) +{ + vos::OGuard aGuard( Application::GetSolarMutex() ); + + maWaitTimer.Stop(); + if ( mpBubbleWin ) + mpBubbleWin->Show( FALSE ); + + if ( mrJob.is() ) + { + try { + uno::Sequence<beans::NamedValue> aEmpty; + mrJob->execute( aEmpty ); + } + catch(const uno::Exception&) { + ErrorBox( NULL, ResId( MSG_ERR_NO_WEBBROWSER_FOUND, *mpSfxResMgr )).Execute(); + } + } + + return 0; +} + +// ----------------------------------------------------------------------- +IMPL_LINK( UpdateCheckUI, HighlightHdl, MenuBar::MenuBarButtonCallbackArg*, pData ) +{ + if ( pData->bHighlight ) + maWaitTimer.Start(); + else + RemoveBubbleWindow( false ); + + return 0; +} + +// ----------------------------------------------------------------------- +IMPL_LINK( UpdateCheckUI, WaitTimeOutHdl, Timer*, EMPTYARG ) +{ + vos::OGuard aGuard( Application::GetSolarMutex() ); + + mpBubbleWin = GetBubbleWindow(); + + if ( mpBubbleWin ) + { + mpBubbleWin->Show(); + } + + return 0; +} + +// ----------------------------------------------------------------------- +IMPL_LINK( UpdateCheckUI, TimeOutHdl, Timer*, EMPTYARG ) +{ + RemoveBubbleWindow( false ); + + return 0; +} + +// ----------------------------------------------------------------------- +IMPL_LINK( UpdateCheckUI, UserEventHdl, UpdateCheckUI*, EMPTYARG ) +{ + vos::OGuard aGuard( Application::GetSolarMutex() ); + + Window *pTopWin = Application::GetFirstTopLevelWindow(); + Window *pActiveWin = Application::GetActiveTopWindow(); + SystemWindow *pActiveSysWin = NULL; + + Window *pBubbleWin = NULL; + if ( mpBubbleWin ) + pBubbleWin = mpBubbleWin; + + if ( pActiveWin && ( pActiveWin != pBubbleWin ) && pActiveWin->IsTopWindow() ) + pActiveSysWin = pActiveWin->GetSystemWindow(); + + if ( pActiveWin == pBubbleWin ) + pActiveSysWin = NULL; + + while ( !pActiveSysWin && pTopWin ) + { + if ( ( pTopWin != pBubbleWin ) && pTopWin->IsTopWindow() ) + pActiveSysWin = pTopWin->GetSystemWindow(); + if ( !pActiveSysWin ) + pTopWin = Application::GetNextTopLevelWindow( pTopWin ); + } + + if ( pActiveSysWin ) + AddMenuBarIcon( pActiveSysWin, true ); + + return 0; +} + +// ----------------------------------------------------------------------- +IMPL_LINK( UpdateCheckUI, WindowEventHdl, VclWindowEvent*, pEvent ) +{ + ULONG nEventID = pEvent->GetId(); + + if ( VCLEVENT_OBJECT_DYING == nEventID ) + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + if ( mpIconSysWin == pEvent->GetWindow() ) + { + mpIconSysWin->RemoveEventListener( maWindowEventHdl ); + RemoveBubbleWindow( true ); + } + } + else if ( VCLEVENT_WINDOW_MENUBARADDED == nEventID ) + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + Window *pWindow = pEvent->GetWindow(); + if ( pWindow ) + { + SystemWindow *pSysWin = pWindow->GetSystemWindow(); + if ( pSysWin ) + { + AddMenuBarIcon( pSysWin, false ); + } + } + } + else if ( VCLEVENT_WINDOW_MENUBARREMOVED == nEventID ) + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + MenuBar *pMBar = (MenuBar*) pEvent->GetData(); + if ( pMBar && ( pMBar == mpIconMBar ) ) + RemoveBubbleWindow( true ); + } + else if ( ( nEventID == VCLEVENT_WINDOW_MOVE ) || + ( nEventID == VCLEVENT_WINDOW_RESIZE ) ) + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + if ( ( mpIconSysWin == pEvent->GetWindow() ) && + ( mpBubbleWin != NULL ) && ( mpIconMBar != NULL ) ) + { + Rectangle aIconRect = mpIconMBar->GetMenuBarButtonRectPixel( mnIconID ); + Point aWinPos = aIconRect.BottomCenter(); + mpBubbleWin->SetTipPosPixel( aWinPos ); + if ( mpBubbleWin->IsVisible() ) + mpBubbleWin->Show(); // This will recalc the screen positon of the bubble + } + } + + return 0; +} + +//------------------------------------------------------------------------------ +IMPL_LINK( UpdateCheckUI, ApplicationEventHdl, VclSimpleEvent *, pEvent) +{ + switch (pEvent->GetId()) + { + case VCLEVENT_WINDOW_SHOW: + case VCLEVENT_WINDOW_ACTIVATE: + case VCLEVENT_WINDOW_GETFOCUS: { + vos::OGuard aGuard( Application::GetSolarMutex() ); + + Window *pWindow = static_cast< VclWindowEvent * >(pEvent)->GetWindow(); + if ( pWindow && pWindow->IsTopWindow() ) + { + SystemWindow *pSysWin = pWindow->GetSystemWindow(); + MenuBar *pMBar = pSysWin->GetMenuBar(); + if ( pSysWin && pMBar ) + { + AddMenuBarIcon( pSysWin, true ); + } + } + break; + } + } + return 0; +} +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ + +#define TIP_HEIGHT 15 +#define TIP_WIDTH 7 +#define TIP_RIGHT_OFFSET 18 +#define BUBBLE_BORDER 10 +#define TEXT_MAX_WIDTH 300 +#define TEXT_MAX_HEIGHT 200 +#define INITIAL_SHOW_TIME 10000 + +//------------------------------------------------------------------------------ +BubbleWindow::BubbleWindow( Window* pParent, const XubString& rTitle, + const XubString& rText, const Image& rImage ) + : FloatingWindow( pParent, WB_SYSTEMWINDOW + | WB_OWNERDRAWDECORATION + | WB_NOBORDER + ) + , maBubbleTitle( rTitle ) + , maBubbleText( rText ) + , maBubbleImage( rImage ) + , maMaxTextSize( TEXT_MAX_WIDTH, TEXT_MAX_HEIGHT ) + , mnTipOffset( 0 ) +{ + SetBackground( Wallpaper( GetSettings().GetStyleSettings().GetHelpColor() ) ); +} + +//------------------------------------------------------------------------------ +BubbleWindow::~BubbleWindow() +{ +} + +//------------------------------------------------------------------------------ +void BubbleWindow::Resize() +{ + vos::OGuard aGuard( Application::GetSolarMutex() ); + + FloatingWindow::Resize(); + + Size aSize = GetSizePixel(); + + if ( ( aSize.Height() < 20 ) || ( aSize.Width() < 60 ) ) + return; + + Rectangle aRect( 0, TIP_HEIGHT, aSize.Width(), aSize.Height() - TIP_HEIGHT ); + maRectPoly = Polygon( aRect, 6, 6 ); + Region aRegion( maRectPoly ); + long nTipOffset = aSize.Width() - TIP_RIGHT_OFFSET + mnTipOffset; + + Point aPointArr[4]; + aPointArr[0] = Point( nTipOffset, TIP_HEIGHT ); + aPointArr[1] = Point( nTipOffset, 0 ); + aPointArr[2] = Point( nTipOffset + TIP_WIDTH , TIP_HEIGHT ); + aPointArr[3] = Point( nTipOffset, TIP_HEIGHT ); + maTriPoly = Polygon( 4, aPointArr ); + Region aTriRegion( maTriPoly ); + + aRegion.Union( aTriRegion); + maBounds = aRegion; + + SetWindowRegionPixel( maBounds ); +} + +//------------------------------------------------------------------------------ +void BubbleWindow::SetTitleAndText( const XubString& rTitle, + const XubString& rText, + const Image& rImage ) +{ + maBubbleTitle = rTitle; + maBubbleText = rText; + maBubbleImage = rImage; + + Resize(); +} + +//------------------------------------------------------------------------------ +void BubbleWindow::Paint( const Rectangle& ) +{ + vos::OGuard aGuard( Application::GetSolarMutex() ); + + LineInfo aThickLine( LINE_SOLID, 2 ); + + DrawPolyLine( maRectPoly, aThickLine ); + DrawPolyLine( maTriPoly ); + + Color aOldLine = GetLineColor(); + Size aSize = GetSizePixel(); + long nTipOffset = aSize.Width() - TIP_RIGHT_OFFSET + mnTipOffset; + + SetLineColor( GetSettings().GetStyleSettings().GetHelpColor() ); + DrawLine( Point( nTipOffset+2, TIP_HEIGHT ), + Point( nTipOffset + TIP_WIDTH -1 , TIP_HEIGHT ), + aThickLine ); + SetLineColor( aOldLine ); + + //Image aImage = InfoBox::GetStandardImage(); + Size aImgSize = maBubbleImage.GetSizePixel(); + + DrawImage( Point( BUBBLE_BORDER, BUBBLE_BORDER + TIP_HEIGHT ), maBubbleImage ); + + Font aOldFont = GetFont(); + Font aBoldFont = aOldFont; + aBoldFont.SetWeight( WEIGHT_BOLD ); + + SetFont( aBoldFont ); + Rectangle aTitleRect = maTitleRect; + aTitleRect.Move( aImgSize.Width(), 0 ); + DrawText( aTitleRect, maBubbleTitle, TEXT_DRAW_MULTILINE | TEXT_DRAW_WORDBREAK ); + + SetFont( aOldFont ); + Rectangle aTextRect = maTextRect; + aTextRect.Move( aImgSize.Width(), 0 ); + DrawText( aTextRect, maBubbleText, TEXT_DRAW_MULTILINE | TEXT_DRAW_WORDBREAK ); +} + +//------------------------------------------------------------------------------ +void BubbleWindow::MouseButtonDown( const MouseEvent& ) +{ + Show( FALSE ); +} + +//------------------------------------------------------------------------------ +void BubbleWindow::Show( BOOL bVisible, USHORT nFlags ) +{ + vos::OGuard aGuard( Application::GetSolarMutex() ); + + if ( !bVisible ) + { + FloatingWindow::Show( bVisible ); + return; + } + + // don't show bubbles without a text + if ( ( maBubbleTitle.Len() == 0 ) && ( maBubbleText.Len() == 0 ) ) + return; + + Size aWindowSize = GetSizePixel(); + + // Image aImage = InfoBox::GetStandardImage(); + Size aImgSize = maBubbleImage.GetSizePixel(); + + RecalcTextRects(); + + aWindowSize.setHeight( maTitleRect.GetHeight() * 7 / 4+ maTextRect.GetHeight() + + 3 * BUBBLE_BORDER + TIP_HEIGHT ); + + if ( maTitleRect.GetWidth() > maTextRect.GetWidth() ) + aWindowSize.setWidth( maTitleRect.GetWidth() ); + else + aWindowSize.setWidth( maTextRect.GetWidth() ); + + aWindowSize.setWidth( aWindowSize.Width() + 3 * BUBBLE_BORDER + aImgSize.Width() ); + + if ( aWindowSize.Height() < aImgSize.Height() + TIP_HEIGHT + 2 * BUBBLE_BORDER ) + aWindowSize.setHeight( aImgSize.Height() + TIP_HEIGHT + 2 * BUBBLE_BORDER ); + + Point aPos; + aPos.X() = maTipPos.X() - aWindowSize.Width() + TIP_RIGHT_OFFSET; + aPos.Y() = maTipPos.Y(); + Point aScreenPos = GetParent()->OutputToAbsoluteScreenPixel( aPos ); + if ( aScreenPos.X() < 0 ) + { + mnTipOffset = aScreenPos.X(); + aPos.X() -= mnTipOffset; + } + SetPosSizePixel( aPos, aWindowSize ); + + FloatingWindow::Show( bVisible, nFlags ); +} + +//------------------------------------------------------------------------------ +void BubbleWindow::RecalcTextRects() +{ + Size aTotalSize; + BOOL bFinished = FALSE; + Font aOldFont = GetFont(); + Font aBoldFont = aOldFont; + + aBoldFont.SetWeight( WEIGHT_BOLD ); + + while ( !bFinished ) + { + SetFont( aBoldFont ); + + maTitleRect = GetTextRect( Rectangle( Point( 0, 0 ), maMaxTextSize ), + maBubbleTitle, + TEXT_DRAW_MULTILINE | TEXT_DRAW_WORDBREAK ); + + SetFont( aOldFont ); + maTextRect = GetTextRect( Rectangle( Point( 0, 0 ), maMaxTextSize ), + maBubbleText, + TEXT_DRAW_MULTILINE | TEXT_DRAW_WORDBREAK ); + + if ( maTextRect.GetHeight() < 10 ) + maTextRect.setHeight( 10 ); + + aTotalSize.setHeight( maTitleRect.GetHeight() + + aBoldFont.GetHeight() * 3 / 4 + + maTextRect.GetHeight() + + 3 * BUBBLE_BORDER + TIP_HEIGHT ); + if ( aTotalSize.Height() > maMaxTextSize.Height() ) + { + maMaxTextSize.Width() = maMaxTextSize.Width() * 3 / 2; + maMaxTextSize.Height() = maMaxTextSize.Height() * 3 / 2; + } + else + bFinished = TRUE; + } + maTitleRect.Move( 2*BUBBLE_BORDER, BUBBLE_BORDER + TIP_HEIGHT ); + maTextRect.Move( 2*BUBBLE_BORDER, BUBBLE_BORDER + TIP_HEIGHT + maTitleRect.GetHeight() + aBoldFont.GetHeight() * 3 / 4 ); +} +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ + +} // anonymous namespace + +//------------------------------------------------------------------------------ + +static uno::Reference<uno::XInterface> SAL_CALL +createInstance(const uno::Reference<uno::XComponentContext>& xContext) +{ + return *new UpdateCheckUI(xContext); +} + +//------------------------------------------------------------------------------ + +static const cppu::ImplementationEntry kImplementations_entries[] = +{ + { + createInstance, + getImplementationName, + getServiceNames, + cppu::createSingleComponentFactory, + NULL, + 0 + }, + { NULL, NULL, NULL, NULL, NULL, 0 } +} ; + +//------------------------------------------------------------------------------ + +extern "C" void SAL_CALL +component_getImplementationEnvironment( const sal_Char **aEnvTypeName, uno_Environment **) +{ + *aEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME ; +} + +//------------------------------------------------------------------------------ + +extern "C" sal_Bool SAL_CALL +component_writeInfo(void *pServiceManager, void *pRegistryKey) +{ + return cppu::component_writeInfoHelper( + pServiceManager, + pRegistryKey, + kImplementations_entries + ); +} + +//------------------------------------------------------------------------------ + +extern "C" void * +component_getFactory(const sal_Char *pszImplementationName, void *pServiceManager, void *pRegistryKey) +{ + return cppu::component_getFactoryHelper( + pszImplementationName, + pServiceManager, + pRegistryKey, + kImplementations_entries) ; +} + diff --git a/extensions/source/update/ui/updatecheckui.hrc b/extensions/source/update/ui/updatecheckui.hrc new file mode 100644 index 000000000000..3d92e4579f58 --- /dev/null +++ b/extensions/source/update/ui/updatecheckui.hrc @@ -0,0 +1,36 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + #define RID_UPDATECHECKUI_START 1100 + + #define RID_UPDATE_AVAIL_IMAGES RID_UPDATECHECKUI_START + 1 + + #define RID_UPDATE_AVAILABLE_16 RID_UPDATECHECKUI_START + 1 + #define RID_UPDATE_AVAILABLE_26 RID_UPDATECHECKUI_START + 2 + #define RID_UPDATE_AVAILABLE_16_HC RID_UPDATECHECKUI_START + 3 + #define RID_UPDATE_AVAILABLE_26_HC RID_UPDATECHECKUI_START + 4 + diff --git a/extensions/source/update/ui/updatecheckui.src b/extensions/source/update/ui/updatecheckui.src new file mode 100644 index 000000000000..39b6f44dce4d --- /dev/null +++ b/extensions/source/update/ui/updatecheckui.src @@ -0,0 +1,51 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "updatecheckui.hrc" + +#define STD_MASK_COLOR MaskColor = Color { Red = 0xFFFF; Green = 0x0000; Blue = 0xFFFF; }; + + Image RID_UPDATE_AVAILABLE_16 + { + ImageBitmap = Bitmap{ file = "onlineupdate_16.png"; }; + STD_MASK_COLOR + }; + Image RID_UPDATE_AVAILABLE_26 + { + ImageBitmap = Bitmap{ file = "onlineupdate_26.png"; }; + STD_MASK_COLOR + }; + Image RID_UPDATE_AVAILABLE_16_HC + { + ImageBitmap = Bitmap{ file = "onlineupdate_16_h.png"; }; + STD_MASK_COLOR + }; + Image RID_UPDATE_AVAILABLE_26_HC + { + ImageBitmap = Bitmap{ file = "onlineupdate_26_h.png"; }; + STD_MASK_COLOR + }; diff --git a/extensions/source/update/ui/updchkui.xml b/extensions/source/update/ui/updchkui.xml new file mode 100644 index 000000000000..a9005d8b255f --- /dev/null +++ b/extensions/source/update/ui/updchkui.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE module-description PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "module-description.dtd"> +<module-description xmlns:xlink="http://www.w3.org/1999/xlink"> + <module-name>updchkui</module-name> + <component-description> + <author> Oliver Braun </author> + <name>vnd.sun.UpdateCheck</name> + <description> The </description> + <loader-name>com.sun.star.loader.SharedLibrary</loader-name> + <language>c++</language> + <status value="beta"/> + <supported-service>com.sun.star.setup.UpdateCheckUI</supported-service> + <service-dependency>...</service-dependency> + <type>com.sun.star.document.XEventBroadcaster</type> + <type>com.sun.star.document.XEventListener</type> + <type>com.sun.star.lang.XEventListener</type> + <type>com.sun.star.lang.XMultiComponentFactory</type> + <type>com.sun.star.lang.XServiceInfo</type> + <type>com.sun.star.lang.XSingleComponentFactory</type> + <type>com.sun.star.lang.XTypeProvider</type> + <type>com.sun.star.uno.TypeClass</type> + <type>com.sun.star.uno.XAggregation</type> + <type>com.sun.star.uno.XComponentContext</type> + <type>com.sun.star.uno.XCurrentContext</type> + <type>com.sun.star.uno.XWeak</type> + <type>com.sun.star.registry.XRegistryKey</type> + </component-description> + <project-build-dependency>cppuhelper</project-build-dependency> + <project-build-dependency>cppu</project-build-dependency> + <project-build-dependency>sal</project-build-dependency> + <runtime-module-dependency>cppuhelper3$(COM)</runtime-module-dependency> + <runtime-module-dependency>cppu3</runtime-module-dependency> + <runtime-module-dependency>sal3</runtime-module-dependency> +</module-description> |