Files
libreoffice/extensions/source/update/ui/updatecheckui.cxx

1027 lines
35 KiB
C++
Raw Normal View History

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
re-base on ALv2 code. Includes (at least) relevant parts of: linecap: Reintegrating finished LineCap feature Patch contributed by Regina Henschel http://svn.apache.org/viewvc?view=revision&revision=1232507 Patches contributed by Sven Jacobi impress212: #i81610# fixed animation export http://svn.apache.org/viewvc?view=revision&revision=1167620 impress212: drawinglayer gbuild environment changes http://svn.apache.org/viewvc?view=revision&revision=1167627 http://svn.apache.org/viewvc?view=revision&revision=1167628 impress212: DffPropSet -> minor code improvements, removing table http://svn.apache.org/viewvc?view=revision&revision=1167634 impress212: #158494# fixed excel import (text rotation) http://svn.apache.org/viewvc?view=revision&revision=1167638 Patches contributed by Armin Le Grand Svg: Reintegrated Svg replacement from /branches/alg/svgreplavement http://svn.apache.org/viewvc?view=revision&revision=1220836 #118728# changed indentifying definitions for Svg file detection http://svn.apache.org/viewvc?view=revision&revision=1229961 #118838# LineGeometry creation for complicated cases optimized to create single Polygons http://svn.apache.org/viewvc?view=revision&revision=1236232 #119176# corrected file type detection for SVG for svg files without xml header http://svn.apache.org/viewvc?view=revision&revision=1309445 #118728# Extended Svg file detection http://svn.apache.org/viewvc?view=revision&revision=1230531 #118529# solve break converters and convert commands for OLEs and images http://svn.apache.org/viewvc?view=revision&revision=1186168 svg: added WaE changes from branch svgreplacement to trunc http://svn.apache.org/viewvc?view=revision&revision=1222974 svg: corrected missing member initialization http://svn.apache.org/viewvc?view=revision&revision=1226134 fix for #118525#: Using primitives for chart sub-geometry visualisation http://svn.apache.org/viewvc?view=revision&revision=1226879 #118898# Adapted ImpGraphic::ImplGetBitmap to correctly convert metafiles to bitmapEx ... http://svn.apache.org/viewvc?view=revision&revision=1293316 fix for #118525#: removed no longer used variable maOriginalMapMode, one more exception eliminated http://svn.apache.org/viewvc?view=revision&revision=1227097 #16758# Added buffering to the VDev usages of the VclProcessor2D derivates... http://svn.apache.org/viewvc?view=revision&revision=1229521 #116758# Secured VDev buffer device to Vcl deinit http://svn.apache.org/viewvc?view=revision&revision=1230574 #116758# added remembering allocated VDevs for VDevBuffer to be able to also delete these when vcl goes down; it should never happen, but You never know http://svn.apache.org/viewvc?view=revision&revision=1230927 #118730# Changed SvgClipPathNode to use MaskPrimitive2D for primitive representation instead of TransparencePrimitive2D http://svn.apache.org/viewvc?view=revision&revision=1231198 #118822# secured 3D geometry creation (slices) by subdividing the 2D source polyPolygon early http://svn.apache.org/viewvc?view=revision&revision=1234749 #118829# enhanced Svg gradient quality, obstacles avoided http://svn.apache.org/viewvc?view=revision&revision=1235361 #118834# Unified usage of TextBreakupHelper as single tooling class for i18n text primitive breakup http://svn.apache.org/viewvc?view=revision&revision=1236110 #118853# added square pixel size limit to conversion of TransparencePrimitive2D to Metafile action http://svn.apache.org/viewvc?view=revision&revision=1237656 #118824# coreccted mirroring and boundrect when the graphicmanager is used for bitmap output http://svn.apache.org/viewvc?view=revision&revision=1240097 #115092# Corrected VclProcessor2D::RenderPolygonStrokePrimitive2D for various optimization scenarios http://svn.apache.org/viewvc?view=revision&revision=1241434 #118783# Corrected errors in ID strings, corrected Svg line/fill export, corrected polygon close state http://svn.apache.org/viewvc?view=revision&revision=1232006 #118796# corrected null-pointer usage in SVG text exporter http://svn.apache.org/viewvc?view=revision&revision=1240262 #118729# Use GraphicStreamUrl and GraphicUrl to allow multi image import with linked graphics, too http://svn.apache.org/viewvc?view=revision&revision=1229962 #118898# corrected error in GDIMetaFile::GetBoundRect in handling MetaFloatTransparentAction http://svn.apache.org/viewvc?view=revision&revision=1293349 #118855# Corrected handling of possibly created empty clipRegions after PolyPolygon clipping http://svn.apache.org/viewvc?view=revision&revision=1237725 #115962# Better (but not yet optimal, see comments in task) handling of MetaFloatTransparentAction in PDF export http://svn.apache.org/viewvc?view=revision&revision=1241078 IP clearance: #118466# This patch removes librsvg, libcroco, libgsf, ... http://svn.apache.org/viewvc?view=revision&revision=1200879 118779# Added svg content streaming in/out to ImpGraphic stream operators http://svn.apache.org/viewvc?view=revision&revision=1231908 linecap: correctons for WaE and mac drawing http://svn.apache.org/viewvc?view=revision&revision=1232793 svg: uses current system Dpi for Svg replacement image creation http://svn.apache.org/viewvc?view=revision&revision=1233948 Patches contributed by Mathias Bauer (and others) gnumake4 work variously http://svn.apache.org/viewvc?view=revision&revision=1394326 http://svn.apache.org/viewvc?view=revision&revision=1396797 http://svn.apache.org/viewvc?view=revision&revision=1397315 http://svn.apache.org/viewvc?view=revision&revision=1394326 Remove duplicate header includes. cws mba34issues01: #i117720#: convert assertion into warning http://svn.apache.org/viewvc?view=revision&revision=1172352 118485 - Styles for OLEs are not saved. Submitted by Armin Le Grand. http://svn.apache.org/viewvc?view=revision&revision=1182166 cws mba34issues01: #i117714#: remove assertion http://svn.apache.org/viewvc?view=revision&revision=1172357 Patch contributed by Jurgen Schmidt add some additional checks to ensure proper reading operations http://svn.apache.org/viewvc?view=revision&revision=1209022 mostly prefer our stream / bounds checking work. Patches contributed by Herbert Duerr #i118816# add clarifying comment regarding Font::*Color*() methods http://svn.apache.org/viewvc?view=revision&revision=1233833 extend macro->string handling for empty strings http://svn.apache.org/viewvc?view=revision&revision=1175801 avoid magic constants for SALCOLOR_NONE http://svn.apache.org/viewvc?view=revision&revision=1177543 initialize slant properly in ImplFontMetricData constructor (author=iorsh) http://svn.apache.org/viewvc?view=revision&revision=1177551 #i118675# make check for extension updates more stable http://svn.apache.org/viewvc?view=revision&revision=1214797 #a118617# remove VBasicEventListener.dll binary There are no known users depending on its CLSID http://svn.apache.org/viewvc?view=revision&revision=1203697 Patches contributed by Ariel Constenla-Haile Fix build breaker on Linux/gcc http://svn.apache.org/viewvc?view=revision&revision=1221104 Fix crash when trying to instantiate css.graphic.GraphicRasterizer_RSVG http://svn.apache.org/viewvc?view=revision&revision=1215559 Patches contributed by Oliver-Rainer Wittmann sw34bf06: #i117962# - method <SwFlyFrm::IsPaint(..)> - consider instances of <SwFlyDrawObj> http://svn.apache.org/viewvc?view=revision&revision=1172120 sw34bf06: #i117783# - Writer's implementation of XPagePrintable - apply print settings to new printing routines http://svn.apache.org/viewvc?view=revision&revision=1172115 gnumake4 work variously from Hans-Joachim Lankenau http://svn.apache.org/viewvc?view=revision&revision=1397315 http://svn.apache.org/viewvc?view=revision&revision=1396797 http://svn.apache.org/viewvc?view=revision&revision=1396782 http://svn.apache.org/viewvc?view=revision&revision=1394707 plus some amount of re-splitting of legacy headers. Patch contributed by Pavel Janik WaE: Remove unused variables. http://svn.apache.org/viewvc?view=revision&revision=1230697 Patches contributed by Takashi Ono mingwport35: i#117795: MinGW port fix for vcl2gnumake http://svn.apache.org/viewvc?view=revision&revision=1172091 mingwport35: i#117795: MinGW port fix for vcl2gnumake http://svn.apache.org/viewvc?view=revision&revision=1172091 Patch contributed by Christian Lippka impress212: #i98044# re enable Text menu for outline and title shapes http://svn.apache.org/viewvc?view=revision&revision=1167639 Patch contributed by Andre Fischer 118674: Made category B code optional and disabled by default. http://svn.apache.org/viewvc?view=revision&revision=1215131 118881: Ignore empty paragraphs after bullets. http://svn.apache.org/viewvc?view=revision&revision=1296205 Patches contributed by Philipp Lohmann ooo340fixes: #i117780# use rtl allocator http://svn.apache.org/viewvc?view=revision&revision=1172087 ooo34gsl02: #i117807# fix an off by one error (index actually inside the pfb section header) http://svn.apache.org/viewvc?view=revision&revision=1167576 various cleanups, related compilation fixes, warning cleanups, re-working of obsolete stl template pieces to use boost instead, changed string classes, re-adapt KDE about data, about dialog, fixing warnings, and other fixes & improvements. Disable svg import / render for about/ branding code-paths for now. Restore full icon theme set. Remove OS/2 conditionals and sources. Remove conflicting gtk/full-screen monitors support. Retain existing svg rasterizer files - temporarily disabled. Standardize stringificaiton and fixup dllpostfix issues. Rename SvgGradientHelper::== to equalTo to avoid overloading issues. Use the flat GdiPlus API for LineCaps calls.
2012-10-09 12:22:23 +01:00
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#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/frame/GlobalEventBroadcaster.hpp>
#include <com/sun/star/graphic/GraphicProvider.hpp>
#include <com/sun/star/graphic/XGraphicProvider.hpp>
#include <com/sun/star/task/XJob.hpp>
#include <comphelper/processfactory.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/button.hxx>
#include <vcl/settings.hxx>
#include <vcl/svapp.hxx>
#include <sfx2/sfx.hrc>
#include "rtl/ustrbuf.hxx"
#include "updatecheckui.hrc"
#define MSG_ERR_NO_WEBBROWSER_FOUND (RID_SFX_APP_START + 7)
#define PROPERTY_TITLE "BubbleHeading"
#define PROPERTY_TEXT "BubbleText"
#define PROPERTY_IMAGE "BubbleImageURL"
#define PROPERTY_SHOW_BUBBLE "BubbleVisible"
#define PROPERTY_CLICK_HDL "MenuClickHDL"
#define PROPERTY_SHOW_MENUICON "MenuIconVisible"
using namespace ::com::sun::star;
//------------------------------------------------------------------------------
static uno::Sequence< rtl::OUString > getServiceNames()
{
uno::Sequence< rtl::OUString > aServiceList(1);
aServiceList[0] = "com.sun.star.setup.UpdateCheckUI";
return aServiceList;
}
//------------------------------------------------------------------------------
static rtl::OUString getImplementationName()
{
return rtl::OUString("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( sal_Bool bVisible = sal_True, sal_uInt16 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;
sal_uInt16 mnIconID;
private:
DECL_LINK(ClickHdl, void *);
DECL_LINK( HighlightHdl, MenuBar::MenuBarButtonCallbackArg* );
DECL_LINK(WaitTimeOutHdl, void *);
DECL_LINK(TimeOutHdl, void *);
DECL_LINK(UserEventHdl, void *);
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(
"UpdateCheckUI: empty component context",
uno::Reference< uno::XInterface >() );
return uno::Reference<document::XEventBroadcaster> (
frame::GlobalEventBroadcaster::create(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();
2010-11-16 16:57:17 +00:00
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.isEmpty() )
{
uno::Reference< uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
if( !xContext.is() )
throw uno::RuntimeException(
"UpdateCheckUI: unable to obtain service manager from component context",
uno::Reference< uno::XInterface >() );
try
{
uno::Reference< graphic::XGraphicProvider > xGraphProvider(graphic::GraphicProvider::create(xContext));
uno::Sequence< beans::PropertyValue > aMediaProps( 1 );
aMediaProps[0].Name = ::rtl::OUString("URL");
aMediaProps[0].Value <<= rURL;
uno::Reference< graphic::XGraphic > xGraphic = xGraphProvider->queryGraphic( aMediaProps );
if ( xGraphic.is() )
{
aImage = Image( xGraphic );
}
}
2011-12-10 22:14:57 +09:00
catch( const uno::Exception& )
{
}
}
if ( aImage.GetSizePixel().Width() == 0 )
aImage = InfoBox::GetStandardImage();
return aImage;
}
//------------------------------------------------------------------------------
void UpdateCheckUI::AddMenuBarIcon( SystemWindow *pSysWin, bool bAddEventHdl )
{
if ( ! mbShowMenuIcon )
return;
SolarMutexGuard aGuard;
MenuBar *pActiveMBar = pSysWin->GetMenuBar();
if ( ( pSysWin != mpIconSysWin ) || ( pActiveMBar != mpIconMBar ) )
{
if ( bAddEventHdl && mpIconSysWin )
mpIconSysWin->RemoveEventListener( maWindowEventHdl );
RemoveBubbleWindow( true );
if ( pActiveMBar )
{
rtl::OUStringBuffer aBuf;
if( !maBubbleTitle.isEmpty() )
aBuf.append( maBubbleTitle );
if( !maBubbleText.isEmpty() )
{
if( !maBubbleTitle.isEmpty() )
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( sal_True );
maTimeoutTimer.Start();
}
mbShowBubble = false;
}
}
//------------------------------------------------------------------------------
void SAL_CALL UpdateCheckUI::notifyEvent(const document::EventObject& rEvent)
throw (uno::RuntimeException)
{
SolarMutexGuard aGuard;
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)
{
SolarMutexGuard aGuard;
rtl::OUString aString;
if( rPropertyName == PROPERTY_TITLE ) {
rValue >>= aString;
if ( aString != maBubbleTitle ) {
maBubbleTitle = aString;
mbBubbleChanged = true;
}
}
else if( rPropertyName == PROPERTY_TEXT ) {
rValue >>= aString;
if ( aString != maBubbleText ) {
maBubbleText = aString;
mbBubbleChanged = true;
}
}
else if( rPropertyName == PROPERTY_IMAGE ) {
rValue >>= aString;
if ( aString != maBubbleImageURL ) {
maBubbleImageURL = aString;
maBubbleImage = GetBubbleImage( maBubbleImageURL );
mbBubbleChanged = true;
}
}
else if( rPropertyName == PROPERTY_SHOW_BUBBLE ) {
rValue >>= mbShowBubble;
if ( mbShowBubble )
Application::PostUserEvent( LINK( this, UpdateCheckUI, UserEventHdl ) );
else if ( mpBubbleWin )
mpBubbleWin->Show( sal_False );
}
else if( rPropertyName == PROPERTY_CLICK_HDL ) {
uno::Reference< task::XJob > aJob;
rValue >>= aJob;
if ( aJob.is() )
mrJob = aJob;
else
throw lang::IllegalArgumentException();
}
else if (rPropertyName == PROPERTY_SHOW_MENUICON ) {
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( sal_False );
}
//------------------------------------------------------------------------------
uno::Any UpdateCheckUI::getPropertyValue(const rtl::OUString& rPropertyName)
throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException )
{
SolarMutexGuard aGuard;
uno::Any aRet;
if( rPropertyName == PROPERTY_TITLE )
aRet = uno::makeAny( maBubbleTitle );
else if( rPropertyName == PROPERTY_TEXT )
aRet = uno::makeAny( maBubbleText );
else if( rPropertyName == PROPERTY_SHOW_BUBBLE )
aRet = uno::makeAny( mbShowBubble );
else if( rPropertyName == PROPERTY_IMAGE )
aRet = uno::makeAny( maBubbleImageURL );
else if( rPropertyName == PROPERTY_CLICK_HDL )
aRet = uno::makeAny( mrJob );
else if( rPropertyName == PROPERTY_SHOW_MENUICON )
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 )
{
SolarMutexGuard aGuard;
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_NOARG(UpdateCheckUI, ClickHdl)
{
SolarMutexGuard aGuard;
maWaitTimer.Stop();
if ( mpBubbleWin )
mpBubbleWin->Show( sal_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_NOARG(UpdateCheckUI, WaitTimeOutHdl)
{
SolarMutexGuard aGuard;
mpBubbleWin = GetBubbleWindow();
if ( mpBubbleWin )
{
mpBubbleWin->Show();
}
return 0;
}
// -----------------------------------------------------------------------
IMPL_LINK_NOARG(UpdateCheckUI, TimeOutHdl)
{
RemoveBubbleWindow( false );
return 0;
}
// -----------------------------------------------------------------------
IMPL_LINK_NOARG(UpdateCheckUI, UserEventHdl)
{
SolarMutexGuard aGuard;
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 )
{
sal_uLong nEventID = pEvent->GetId();
if ( VCLEVENT_OBJECT_DYING == nEventID )
{
SolarMutexGuard aGuard;
if ( mpIconSysWin == pEvent->GetWindow() )
{
mpIconSysWin->RemoveEventListener( maWindowEventHdl );
RemoveBubbleWindow( true );
}
}
else if ( VCLEVENT_WINDOW_MENUBARADDED == nEventID )
{
SolarMutexGuard aGuard;
Window *pWindow = pEvent->GetWindow();
if ( pWindow )
{
SystemWindow *pSysWin = pWindow->GetSystemWindow();
if ( pSysWin )
{
AddMenuBarIcon( pSysWin, false );
}
}
}
else if ( VCLEVENT_WINDOW_MENUBARREMOVED == nEventID )
{
SolarMutexGuard aGuard;
MenuBar *pMBar = (MenuBar*) pEvent->GetData();
if ( pMBar && ( pMBar == mpIconMBar ) )
RemoveBubbleWindow( true );
}
else if ( ( nEventID == VCLEVENT_WINDOW_MOVE ) ||
( nEventID == VCLEVENT_WINDOW_RESIZE ) )
{
SolarMutexGuard aGuard;
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: {
SolarMutexGuard aGuard;
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
//------------------------------------------------------------------------------
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()
{
SolarMutexGuard aGuard;
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& )
{
SolarMutexGuard aGuard;
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( sal_False );
}
//------------------------------------------------------------------------------
void BubbleWindow::Show( sal_Bool bVisible, sal_uInt16 nFlags )
{
SolarMutexGuard aGuard;
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;
sal_Bool bFinished = sal_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 = sal_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" SAL_DLLPUBLIC_EXPORT void * SAL_CALL updchkui_component_getFactory(const sal_Char *pszImplementationName, void *pServiceManager, void *pRegistryKey)
{
return cppu::component_getFactoryHelper(
pszImplementationName,
pServiceManager,
pRegistryKey,
kImplementations_entries) ;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */