diff options
Diffstat (limited to 'framework/source/helper')
23 files changed, 6511 insertions, 0 deletions
diff --git a/framework/source/helper/acceleratorinfo.cxx b/framework/source/helper/acceleratorinfo.cxx new file mode 100644 index 000000000000..a89bc9198c17 --- /dev/null +++ b/framework/source/helper/acceleratorinfo.cxx @@ -0,0 +1,74 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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_framework.hxx" + +#include <helper/acceleratorinfo.hxx> + +namespace framework +{ + +static pfunc_getCommandURLFromKeyCode _pGetCommandURLFromKeyCode = NULL; +static pfunc_getKeyCodeFromCommandURL _pGetKeyCodeFromCommandURL = NULL; + +pfunc_getCommandURLFromKeyCode SAL_CALL SetCommandURLFromKeyCode( pfunc_getCommandURLFromKeyCode pNewFunc ) +{ + pfunc_getCommandURLFromKeyCode pOldFunc = _pGetCommandURLFromKeyCode; + _pGetCommandURLFromKeyCode = pNewFunc; + + return pOldFunc; +} + +::rtl::OUString SAL_CALL GetCommandURLFromKeyCode( const KeyCode& aKeyCode ) +{ + if ( _pGetCommandURLFromKeyCode ) + return _pGetCommandURLFromKeyCode( aKeyCode ); + else + return rtl::OUString(); +} + +pfunc_getKeyCodeFromCommandURL SAL_CALL SetKeyCodeFromCommandURL( pfunc_getKeyCodeFromCommandURL pNewFunc ) +{ + pfunc_getKeyCodeFromCommandURL pOldFunc = _pGetKeyCodeFromCommandURL; + _pGetKeyCodeFromCommandURL = pNewFunc; + + return pOldFunc; +} + +KeyCode SAL_CALL GetKeyCodeFromCommandURL( ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& rFrame, const rtl::OUString& aCommandURL ) +{ + if ( _pGetKeyCodeFromCommandURL ) + return _pGetKeyCodeFromCommandURL( rFrame, aCommandURL ); + else + return KeyCode(); +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/framework/source/helper/actiontriggerhelper.cxx b/framework/source/helper/actiontriggerhelper.cxx new file mode 100644 index 000000000000..a5e0a1438a1e --- /dev/null +++ b/framework/source/helper/actiontriggerhelper.cxx @@ -0,0 +1,407 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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_framework.hxx" +#include <helper/actiontriggerhelper.hxx> +#include <classes/actiontriggerseparatorpropertyset.hxx> +#include <classes/rootactiontriggercontainer.hxx> +#include <classes/imagewrapper.hxx> +#include <classes/addonsoptions.hxx> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/awt/XBitmap.hpp> +#include <vcl/svapp.hxx> +#include <osl/mutex.hxx> +#include <tools/stream.hxx> +#include <cppuhelper/weak.hxx> +#include <comphelper/processfactory.hxx> + + +const USHORT START_ITEMID = 1000; + +using namespace rtl; +using namespace com::sun::star::awt; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::beans; +using namespace com::sun::star::container; + +namespace framework +{ + +// ---------------------------------------------------------------------------- +// implementation helper ( menu => ActionTrigger ) +// ---------------------------------------------------------------------------- + +sal_Bool IsSeparator( Reference< XPropertySet > xPropertySet ) +{ + Reference< XServiceInfo > xServiceInfo( xPropertySet, UNO_QUERY ); + try + { + return xServiceInfo->supportsService( OUString( RTL_CONSTASCII_USTRINGPARAM( SERVICENAME_ACTIONTRIGGERSEPARATOR )) ); + } + catch ( Exception& ) + { + } + + return sal_False; +} + +void GetMenuItemAttributes( Reference< XPropertySet > xActionTriggerPropertySet, + OUString& aMenuLabel, + OUString& aCommandURL, + OUString& aHelpURL, + Reference< XBitmap >& xBitmap, + Reference< XIndexContainer >& xSubContainer ) +{ + Any a; + + try + { + // mandatory properties + a = xActionTriggerPropertySet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "Text" )) ); + a >>= aMenuLabel; + a = xActionTriggerPropertySet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "CommandURL" )) ); + a >>= aCommandURL; + a = xActionTriggerPropertySet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "Image" )) ); + a >>= xBitmap; + a = xActionTriggerPropertySet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "SubContainer" )) ); + a >>= xSubContainer; + } + catch ( Exception& ) + { + } + + // optional properties + try + { + a = xActionTriggerPropertySet->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "HelpURL" )) ); + a >>= aHelpURL; + } + catch ( Exception& ) + { + } +} + +void InsertSubMenuItems( Menu* pSubMenu, USHORT& nItemId, Reference< XIndexContainer > xActionTriggerContainer ) +{ + Reference< XIndexAccess > xIndexAccess( xActionTriggerContainer, UNO_QUERY ); + if ( xIndexAccess.is() ) + { + AddonsOptions aAddonOptions; + OUString aSlotURL( RTL_CONSTASCII_USTRINGPARAM( "slot:" )); + + for ( sal_Int32 i = 0; i < xIndexAccess->getCount(); i++ ) + { + try + { + Reference< XPropertySet > xPropSet; + if (( xIndexAccess->getByIndex( i ) >>= xPropSet ) && ( xPropSet.is() )) + { + if ( IsSeparator( xPropSet )) + { + // Separator + SolarMutexGuard aGuard; + pSubMenu->InsertSeparator(); + } + else + { + // Menu item + OUString aLabel; + OUString aCommandURL; + OUString aHelpURL; + Reference< XBitmap > xBitmap; + Reference< XIndexContainer > xSubContainer; + sal_Bool bSpecialItemId = sal_False; + + USHORT nNewItemId = nItemId++; + GetMenuItemAttributes( xPropSet, aLabel, aCommandURL, aHelpURL, xBitmap, xSubContainer ); + + SolarMutexGuard aGuard; + { + // insert new menu item + sal_Int32 nIndex = aCommandURL.indexOf( aSlotURL ); + if ( nIndex >= 0 ) + { + // Special code for our menu implementation: some menu items don't have a + // command url but uses the item id as a unqiue identifier. These entries + // got a special url during conversion from menu=>actiontriggercontainer. + // Now we have to extract this special url and set the correct item id!!! + bSpecialItemId = sal_True; + nNewItemId = (USHORT)aCommandURL.copy( nIndex+aSlotURL.getLength() ).toInt32(); + pSubMenu->InsertItem( nNewItemId, aLabel ); + } + else + { + pSubMenu->InsertItem( nNewItemId, aLabel ); + pSubMenu->SetItemCommand( nNewItemId, aCommandURL ); + } + + // handle bitmap + if ( xBitmap.is() ) + { + sal_Bool bImageSet = sal_False; + + Reference< XUnoTunnel > xUnoTunnel( xBitmap, UNO_QUERY ); + if ( xUnoTunnel.is() ) + { + // Try to get implementation pointer through XUnoTunnel + sal_Int64 nPointer = xUnoTunnel->getSomething( ImageWrapper::GetUnoTunnelId() ); + if ( nPointer ) + { + // This is our own optimized implementation of menu images! + ImageWrapper* pImageWrapper = reinterpret_cast< ImageWrapper * >( nPointer ); + Image aMenuImage = pImageWrapper->GetImage(); + + if ( !!aMenuImage ) + pSubMenu->SetItemImage( nNewItemId, aMenuImage ); + + bImageSet = sal_True; + } + } + + if ( !bImageSet ) + { + // This is an unknown implementation of a XBitmap interface. We have to + // use a more time consuming way to build an Image! + Image aImage; + Bitmap aBitmap; + + Sequence< sal_Int8 > aDIBSeq; + { + aDIBSeq = xBitmap->getDIB(); + SvMemoryStream aMem( (void *)aDIBSeq.getConstArray(), aDIBSeq.getLength(), STREAM_READ ); + aMem >> aBitmap; + } + + aDIBSeq = xBitmap->getMaskDIB(); + if ( aDIBSeq.getLength() > 0 ) + { + Bitmap aMaskBitmap; + SvMemoryStream aMem( (void *)aDIBSeq.getConstArray(), aDIBSeq.getLength(), STREAM_READ ); + aMem >> aMaskBitmap; + aImage = Image( aBitmap, aMaskBitmap ); + } + else + aImage = Image( aBitmap ); + + if ( !!aImage ) + pSubMenu->SetItemImage( nNewItemId, aImage ); + } + } + else + { + // Support add-on images for context menu interceptors + Image aImage = aAddonOptions.GetImageFromURL( aCommandURL, sal_False, sal_True ); + if ( !!aImage ) + pSubMenu->SetItemImage( nNewItemId, aImage ); + } + + if ( xSubContainer.is() ) + { + PopupMenu* pNewSubMenu = new PopupMenu; + + // Sub menu (recursive call CreateSubMenu ) + InsertSubMenuItems( pNewSubMenu, nItemId, xSubContainer ); + pSubMenu->SetPopupMenu( nNewItemId, pNewSubMenu ); + } + } + } + } + } + catch ( IndexOutOfBoundsException ) + { + return; + } + catch ( WrappedTargetException ) + { + return; + } + catch ( RuntimeException ) + { + return; + } + } + } +} + + +// ---------------------------------------------------------------------------- +// implementation helper ( ActionTrigger => menu ) +// ---------------------------------------------------------------------------- + +Reference< XPropertySet > CreateActionTrigger( USHORT nItemId, const Menu* pMenu, const Reference< XIndexContainer >& rActionTriggerContainer ) throw ( RuntimeException ) +{ + Reference< XPropertySet > xPropSet; + + Reference< XMultiServiceFactory > xMultiServiceFactory( rActionTriggerContainer, UNO_QUERY ); + if ( xMultiServiceFactory.is() ) + { + xPropSet = Reference< XPropertySet >( xMultiServiceFactory->createInstance( + OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ui.ActionTrigger" )) ), + UNO_QUERY ); + + Any a; + + try + { + // Retrieve the menu attributes and set them in our PropertySet + OUString aLabel = pMenu->GetItemText( nItemId ); + a <<= aLabel; + xPropSet->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "Text" )), a ); + + OUString aCommandURL = pMenu->GetItemCommand( nItemId ); + + if ( aCommandURL.getLength() == 0 ) + { + aCommandURL = OUString( RTL_CONSTASCII_USTRINGPARAM( "slot:" )); + aCommandURL += OUString::valueOf( (sal_Int32)nItemId ); + } + + a <<= aCommandURL; + xPropSet->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "CommandURL" )), a ); + + Image aImage = pMenu->GetItemImage( nItemId ); + if ( !!aImage ) + { + // We use our own optimized XBitmap implementation + Reference< XBitmap > xBitmap( static_cast< cppu::OWeakObject* >( new ImageWrapper( aImage )), UNO_QUERY ); + a <<= xBitmap; + xPropSet->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "Image" )), a ); + } + } + catch ( Exception& ) + { + } + } + + return xPropSet; +} + +Reference< XPropertySet > CreateActionTriggerSeparator( const Reference< XIndexContainer >& rActionTriggerContainer ) throw ( RuntimeException ) +{ + Reference< XMultiServiceFactory > xMultiServiceFactory( rActionTriggerContainer, UNO_QUERY ); + if ( xMultiServiceFactory.is() ) + { + return Reference< XPropertySet >( xMultiServiceFactory->createInstance( + OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ui.ActionTriggerSeparator" )) ), + UNO_QUERY ); + } + + return Reference< XPropertySet >(); +} + +Reference< XIndexContainer > CreateActionTriggerContainer( const Reference< XIndexContainer >& rActionTriggerContainer ) throw ( RuntimeException ) +{ + Reference< XMultiServiceFactory > xMultiServiceFactory( rActionTriggerContainer, UNO_QUERY ); + if ( xMultiServiceFactory.is() ) + { + return Reference< XIndexContainer >( xMultiServiceFactory->createInstance( + OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ui.ActionTriggerContainer" )) ), + UNO_QUERY ); + } + + return Reference< XIndexContainer >(); +} + +void FillActionTriggerContainerWithMenu( const Menu* pMenu, Reference< XIndexContainer >& rActionTriggerContainer ) +{ + SolarMutexGuard aGuard; + + for ( USHORT nPos = 0; nPos < pMenu->GetItemCount(); nPos++ ) + { + USHORT nItemId = pMenu->GetItemId( nPos ); + MenuItemType nType = pMenu->GetItemType( nPos ); + + try + { + Any a; + Reference< XPropertySet > xPropSet; + + if ( nType == MENUITEM_SEPARATOR ) + { + xPropSet = CreateActionTriggerSeparator( rActionTriggerContainer ); + + a <<= xPropSet; + rActionTriggerContainer->insertByIndex( nPos, a ); + } + else + { + xPropSet = CreateActionTrigger( nItemId, pMenu, rActionTriggerContainer ); + + a <<= xPropSet; + rActionTriggerContainer->insertByIndex( nPos, a ); + + PopupMenu* pPopupMenu = pMenu->GetPopupMenu( nItemId ); + if ( pPopupMenu ) + { + // recursive call to build next sub menu + Reference< XIndexContainer > xSubContainer = CreateActionTriggerContainer( rActionTriggerContainer ); + + a <<= xSubContainer; + xPropSet->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "SubContainer" )), a ); + FillActionTriggerContainerWithMenu( pPopupMenu, xSubContainer ); + } + } + } + catch ( Exception& ) + { + } + } +} + +void ActionTriggerHelper::CreateMenuFromActionTriggerContainer( + Menu* pNewMenu, + const Reference< XIndexContainer >& rActionTriggerContainer ) +{ + USHORT nItemId = START_ITEMID; + + if ( rActionTriggerContainer.is() ) + InsertSubMenuItems( pNewMenu, nItemId, rActionTriggerContainer ); +} + +void ActionTriggerHelper::FillActionTriggerContainerFromMenu( + Reference< XIndexContainer >& xActionTriggerContainer, + const Menu* pMenu ) +{ + FillActionTriggerContainerWithMenu( pMenu, xActionTriggerContainer ); +} + +Reference< XIndexContainer > ActionTriggerHelper::CreateActionTriggerContainerFromMenu( + // #110897# + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceFactory, + const Menu* pMenu, + const ::rtl::OUString* pMenuIdentifier ) +{ + return new RootActionTriggerContainer( pMenu, pMenuIdentifier, xServiceFactory ); +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/framework/source/helper/configimporter.cxx b/framework/source/helper/configimporter.cxx new file mode 100644 index 000000000000..afc739070032 --- /dev/null +++ b/framework/source/helper/configimporter.cxx @@ -0,0 +1,96 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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_framework.hxx" + +#include <helper/configimporter.hxx> +#include <xml/toolboxconfiguration.hxx> +#include <com/sun/star/embed/ElementModes.hpp> + +#include <rtl/ustrbuf.hxx> + +using namespace ::com::sun::star; + +namespace framework +{ + +sal_Bool UIConfigurationImporterOOo1x::ImportCustomToolbars( + const uno::Reference< ui::XUIConfigurationManager >& rContainerFactory, + uno::Sequence< uno::Reference< container::XIndexContainer > >& rSeqContainer, + const uno::Reference< lang::XMultiServiceFactory >& rServiceManager, + const uno::Reference< embed::XStorage >& rToolbarStorage ) +{ + const char USERDEFTOOLBOX[] = "userdeftoolbox0.xml"; + uno::Reference< lang::XMultiServiceFactory > rSrvMgr( rServiceManager ); + + sal_Bool bResult ( sal_False ); + if ( rToolbarStorage.is() && rContainerFactory.is() ) + { + try + { + for ( sal_uInt16 i = 1; i <= 4; i++ ) + { + rtl::OUStringBuffer aCustomTbxName( 20 ); + aCustomTbxName.appendAscii( USERDEFTOOLBOX ); + aCustomTbxName.setCharAt( 14, aCustomTbxName.charAt( 14 ) + i ); + + rtl::OUString aTbxStreamName( aCustomTbxName.makeStringAndClear() ); + uno::Reference< io::XStream > xStream = rToolbarStorage->openStreamElement( aTbxStreamName, embed::ElementModes::READ ); + if ( xStream.is() ) + { + uno::Reference< io::XInputStream > xInputStream = xStream->getInputStream(); + if ( xInputStream.is() ) + { + uno::Reference< container::XIndexContainer > xContainer = rContainerFactory->createSettings(); + if ( ToolBoxConfiguration::LoadToolBox( rSrvMgr, xInputStream, xContainer )) + { + sal_uInt32 nIndex = rSeqContainer.getLength(); + rSeqContainer.realloc( nIndex+1 ); + rSeqContainer[nIndex] = xContainer; + bResult = sal_True; + } + } + } + } + } + catch ( uno::RuntimeException& ) + { + throw; + } + catch ( uno::Exception& ) + { + } + } + + return bResult; +} + +} // namespace framework + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/framework/source/helper/dockingareadefaultacceptor.cxx b/framework/source/helper/dockingareadefaultacceptor.cxx new file mode 100644 index 000000000000..d0b6a1abaab4 --- /dev/null +++ b/framework/source/helper/dockingareadefaultacceptor.cxx @@ -0,0 +1,189 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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_framework.hxx" + +//_________________________________________________________________________________________________________________ +// my own includes +//_________________________________________________________________________________________________________________ +#include <helper/dockingareadefaultacceptor.hxx> +#include <threadhelp/resetableguard.hxx> + +//_________________________________________________________________________________________________________________ +// interface includes +//_________________________________________________________________________________________________________________ +#include <com/sun/star/awt/XDevice.hpp> +#include <com/sun/star/awt/PosSize.hpp> +#include <com/sun/star/awt/XLayoutConstrains.hpp> + +//_________________________________________________________________________________________________________________ +// includes of other projects +//_________________________________________________________________________________________________________________ + +#include <vcl/svapp.hxx> + +//_________________________________________________________________________________________________________________ +// namespace +//_________________________________________________________________________________________________________________ + +namespace framework{ + +using namespace ::com::sun::star::container ; +using namespace ::com::sun::star::frame ; +using namespace ::com::sun::star::lang ; +using namespace ::com::sun::star::uno ; +using namespace ::cppu ; +using namespace ::osl ; + +//_________________________________________________________________________________________________________________ +// non exported const +//_________________________________________________________________________________________________________________ + +//_________________________________________________________________________________________________________________ +// non exported definitions +//_________________________________________________________________________________________________________________ + +//_________________________________________________________________________________________________________________ +// declarations +//_________________________________________________________________________________________________________________ + +//***************************************************************************************************************** +// constructor +//***************************************************************************************************************** +DockingAreaDefaultAcceptor::DockingAreaDefaultAcceptor( const Reference< XFrame >& xOwner ) + // Init baseclasses first + : ThreadHelpBase ( &Application::GetSolarMutex() ) + // Init member + , m_xOwner ( xOwner ) +{ +} + +//***************************************************************************************************************** +// destructor +//***************************************************************************************************************** +DockingAreaDefaultAcceptor::~DockingAreaDefaultAcceptor() +{ +} + +//***************************************************************************************************************** +// XDockingAreaAcceptor +//***************************************************************************************************************** +css::uno::Reference< css::awt::XWindow > SAL_CALL DockingAreaDefaultAcceptor::getContainerWindow() throw (css::uno::RuntimeException) +{ + // Ready for multithreading + ResetableGuard aGuard( m_aLock ); + + // Try to "lock" the frame for access to taskscontainer. + Reference< XFrame > xFrame( m_xOwner.get(), UNO_QUERY ); + Reference< css::awt::XWindow > xContainerWindow( xFrame->getContainerWindow() ); + + return xContainerWindow; +} + +sal_Bool SAL_CALL DockingAreaDefaultAcceptor::requestDockingAreaSpace( const css::awt::Rectangle& RequestedSpace ) throw (css::uno::RuntimeException) +{ + // Ready for multithreading + ResetableGuard aGuard( m_aLock ); + + // Try to "lock" the frame for access to taskscontainer. + Reference< XFrame > xFrame( m_xOwner.get(), UNO_QUERY ); + aGuard.unlock(); + + if ( xFrame.is() == sal_True ) + { + Reference< css::awt::XWindow > xContainerWindow( xFrame->getContainerWindow() ); + Reference< css::awt::XWindow > xComponentWindow( xFrame->getComponentWindow() ); + + if (( xContainerWindow.is() == sal_True ) && + ( xComponentWindow.is() == sal_True ) ) + { + css::uno::Reference< css::awt::XDevice > xDevice( xContainerWindow, css::uno::UNO_QUERY ); + // Convert relativ size to output size. + css::awt::Rectangle aRectangle = xContainerWindow->getPosSize(); + css::awt::DeviceInfo aInfo = xDevice->getInfo(); + css::awt::Size aSize ( aRectangle.Width - aInfo.LeftInset - aInfo.RightInset , + aRectangle.Height - aInfo.TopInset - aInfo.BottomInset ); + + // client size of container window +// css::uno::Reference< css::awt::XLayoutConstrains > xLayoutContrains( xComponentWindow, css::uno::UNO_QUERY ); + css::awt::Size aMinSize( 0, 0 ); // = xLayoutContrains->getMinimumSize(); + + // Check if request border space would decrease component window size below minimum size + if ((( aSize.Width - RequestedSpace.X - RequestedSpace.Width ) < aMinSize.Width ) || + (( aSize.Height - RequestedSpace.Y - RequestedSpace.Height ) < aMinSize.Height ) ) + return sal_False; + + return sal_True; + } + } + + return sal_False; +} + +void SAL_CALL DockingAreaDefaultAcceptor::setDockingAreaSpace( const css::awt::Rectangle& BorderSpace ) throw (css::uno::RuntimeException) +{ + // Ready for multithreading + ResetableGuard aGuard( m_aLock ); + + // Try to "lock" the frame for access to taskscontainer. + Reference< XFrame > xFrame( m_xOwner.get(), UNO_QUERY ); + if ( xFrame.is() == sal_True ) + { + Reference< css::awt::XWindow > xContainerWindow( xFrame->getContainerWindow() ); + Reference< css::awt::XWindow > xComponentWindow( xFrame->getComponentWindow() ); + + if (( xContainerWindow.is() == sal_True ) && + ( xComponentWindow.is() == sal_True ) ) + { + css::uno::Reference< css::awt::XDevice > xDevice( xContainerWindow, css::uno::UNO_QUERY ); + // Convert relativ size to output size. + css::awt::Rectangle aRectangle = xContainerWindow->getPosSize(); + css::awt::DeviceInfo aInfo = xDevice->getInfo(); + css::awt::Size aSize ( aRectangle.Width - aInfo.LeftInset - aInfo.RightInset , + aRectangle.Height - aInfo.TopInset - aInfo.BottomInset ); + // client size of container window +// css::uno::Reference< css::awt::XLayoutConstrains > xLayoutContrains( xComponentWindow, css::uno::UNO_QUERY ); + css::awt::Size aMinSize( 0, 0 );// = xLayoutContrains->getMinimumSize(); + + // Check if request border space would decrease component window size below minimum size + sal_Int32 nWidth = aSize.Width - BorderSpace.X - BorderSpace.Width; + sal_Int32 nHeight = aSize.Height - BorderSpace.Y - BorderSpace.Height; + + if (( nWidth > aMinSize.Width ) && ( nHeight > aMinSize.Height )) + { + // Resize our component window. + xComponentWindow->setPosSize( BorderSpace.X, BorderSpace.Y, nWidth, nHeight, css::awt::PosSize::POSSIZE ); + } + } + } +} + +} // namespace framework + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/framework/source/helper/imageproducer.cxx b/framework/source/helper/imageproducer.cxx new file mode 100644 index 000000000000..e6435d822e06 --- /dev/null +++ b/framework/source/helper/imageproducer.cxx @@ -0,0 +1,62 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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_framework.hxx" + +#include <helper/imageproducer.hxx> + +namespace framework +{ + +static pfunc_getImage _pGetImageFunc = NULL; + +pfunc_getImage SAL_CALL SetImageProducer( pfunc_getImage pNewGetImageFunc ) +{ + pfunc_getImage pOldFunc = _pGetImageFunc; + _pGetImageFunc = pNewGetImageFunc; + + return pOldFunc; +} + + +Image SAL_CALL GetImageFromURL( + const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& rFrame, + const ::rtl::OUString& aURL, + BOOL bBig +) +{ + if ( _pGetImageFunc ) + return _pGetImageFunc( rFrame, aURL, bBig ); + else + return Image(); +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/framework/source/helper/makefile.mk b/framework/source/helper/makefile.mk new file mode 100644 index 000000000000..ed54c381160c --- /dev/null +++ b/framework/source/helper/makefile.mk @@ -0,0 +1,69 @@ +#************************************************************************* +# +# 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= framework +TARGET= fwk_helper +USE_DEFFILE= TRUE +ENABLE_EXCEPTIONS= TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +# --- defines ------------------------------------------------------ + +CDEFS+=-DCOMPMOD_NAMESPACE=framework + +# --- Generate ----------------------------------------------------- + +SLOFILES= $(SLO)$/ocomponentaccess.obj \ + $(SLO)$/ocomponentenumeration.obj \ + $(SLO)$/oframes.obj \ + $(SLO)$/statusindicatorfactory.obj \ + $(SLO)$/statusindicator.obj \ + $(SLO)$/imageproducer.obj \ + $(SLO)$/propertysetcontainer.obj \ + $(SLO)$/actiontriggerhelper.obj \ + $(SLO)$/persistentwindowstate.obj \ + $(SLO)$/networkdomain.obj \ + $(SLO)$/acceleratorinfo.obj \ + $(SLO)$/uielementwrapperbase.obj \ + $(SLO)$/dockingareadefaultacceptor.obj \ + $(SLO)$/uiconfigelementwrapperbase.obj \ + $(SLO)$/shareablemutex.obj \ + $(SLO)$/vclstatusindicator.obj \ + $(SLO)$/wakeupthread.obj \ + $(SLO)$/configimporter.obj \ + $(SLO)$/tagwindowasmodified.obj \ + $(SLO)$/titlebarupdate.obj \ + $(SLO)$/titlehelper.obj \ + $(SLO)$/mischelper.obj + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk diff --git a/framework/source/helper/mischelper.cxx b/framework/source/helper/mischelper.cxx new file mode 100644 index 000000000000..0f021a453cbb --- /dev/null +++ b/framework/source/helper/mischelper.cxx @@ -0,0 +1,241 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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_framework.hxx" + +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/document/XDocumentLanguages.hpp> +#include <com/sun/star/frame/XModuleManager.hpp> +#include <com/sun/star/beans/PropertyValue.hpp> + +#include <tools/debug.hxx> +#include <vcl/settings.hxx> +#include <vcl/svapp.hxx> +#include <i18npool/mslangid.hxx> +#include <svtools/langtab.hxx> +#include <comphelper/processfactory.hxx> +#include <helper/mischelper.hxx> +#include <services.h> + + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::frame; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::container; +using namespace ::com::sun::star::lang; + +using ::rtl::OUString; + + +namespace framework +{ + +uno::Reference< linguistic2::XLanguageGuessing > LanguageGuessingHelper::GetGuesser() const +{ + if (!m_xLanguageGuesser.is()) + { + try + { + m_xLanguageGuesser = uno::Reference< linguistic2::XLanguageGuessing >( + m_xServiceManager->createInstance( + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.linguistic2.LanguageGuessing")) ), + uno::UNO_QUERY ); + } + catch (uno::Exception &r) + { + (void) r; + DBG_ASSERT( 0, "failed to get language guessing component" ); + } + } + return m_xLanguageGuesser; +} + +//////////////////////////////////////////////////////////// + +::rtl::OUString RetrieveLabelFromCommand( + const ::rtl::OUString& aCmdURL, + const uno::Reference< lang::XMultiServiceFactory >& _xServiceFactory, + uno::Reference< container::XNameAccess >& _xUICommandLabels, + const uno::Reference< frame::XFrame >& _xFrame, + ::rtl::OUString& _rModuleIdentifier, + sal_Bool& _rIni, + const sal_Char* _pName) +{ + ::rtl::OUString aLabel; + + // Retrieve popup menu labels + if ( !_xUICommandLabels.is() ) + { + try + { + if ( !_rIni ) + { + _rIni = sal_True; + Reference< XModuleManager > xModuleManager( _xServiceFactory->createInstance( SERVICENAME_MODULEMANAGER ), UNO_QUERY_THROW ); + + try + { + _rModuleIdentifier = xModuleManager->identify( _xFrame ); + } + catch( Exception& ) + { + } + } + + Reference< XNameAccess > xNameAccess( _xServiceFactory->createInstance( SERVICENAME_UICOMMANDDESCRIPTION ), UNO_QUERY ); + if ( xNameAccess.is() ) + { + xNameAccess->getByName( _rModuleIdentifier ) >>= _xUICommandLabels; + } + } + catch ( Exception& ) + { + } + } + + if ( _xUICommandLabels.is() ) + { + try + { + if ( aCmdURL.getLength() > 0 ) + { + rtl::OUString aStr; + Sequence< PropertyValue > aPropSeq; + if ( _xUICommandLabels->getByName( aCmdURL ) >>= aPropSeq ) + { + for ( sal_Int32 i = 0; i < aPropSeq.getLength(); i++ ) + { + if ( aPropSeq[i].Name.equalsAscii( _pName/*"Label"*/ )) + { + aPropSeq[i].Value >>= aStr; + break; + } + } + } + aLabel = aStr; + } + } + catch ( com::sun::star::uno::Exception& ) + { + } + } + + return aLabel; +} + +//////////////////////////////////////////////////////////// + +void FillLangItems( std::set< OUString > &rLangItems, + const SvtLanguageTable & rLanguageTable, + const uno::Reference< frame::XFrame > & rxFrame, + const LanguageGuessingHelper & rLangGuessHelper, + sal_Int16 nScriptType, + const OUString & rCurLang, + const OUString & rKeyboardLang, + const OUString & rGuessedTextLang ) +{ + rLangItems.clear(); + + //1--add current language + if( rCurLang != OUString() && + LANGUAGE_DONTKNOW != rLanguageTable.GetType( rCurLang )) + rLangItems.insert( rCurLang ); + + //2--System + const AllSettings& rAllSettings = Application::GetSettings(); + LanguageType rSystemLanguage = rAllSettings.GetLanguage(); + if( rSystemLanguage != LANGUAGE_DONTKNOW ) + { + if ( IsScriptTypeMatchingToLanguage( nScriptType, rSystemLanguage )) + rLangItems.insert( OUString( rLanguageTable.GetString( rSystemLanguage )) ); + } + + //3--UI + LanguageType rUILanguage = rAllSettings.GetUILanguage(); + if( rUILanguage != LANGUAGE_DONTKNOW ) + { + if ( IsScriptTypeMatchingToLanguage( nScriptType, rUILanguage )) + rLangItems.insert( OUString( rLanguageTable.GetString( rUILanguage )) ); + } + + //4--guessed language + uno::Reference< linguistic2::XLanguageGuessing > xLangGuesser( rLangGuessHelper.GetGuesser() ); + if ( xLangGuesser.is() && rGuessedTextLang.getLength() > 0) + { + ::com::sun::star::lang::Locale aLocale(xLangGuesser->guessPrimaryLanguage( rGuessedTextLang, 0, rGuessedTextLang.getLength()) ); + LanguageType nLang = MsLangId::convertLocaleToLanguageWithFallback( aLocale ); + if (nLang != LANGUAGE_DONTKNOW && nLang != LANGUAGE_NONE && nLang != LANGUAGE_SYSTEM + && IsScriptTypeMatchingToLanguage( nScriptType, nLang )) + rLangItems.insert( rLanguageTable.GetString( nLang )); + } + + //5--keyboard language + if( rKeyboardLang != OUString()) + { + if ( IsScriptTypeMatchingToLanguage( nScriptType, rLanguageTable.GetType( rKeyboardLang ))) + rLangItems.insert( rKeyboardLang ); + } + + //6--all languages used in current document + Reference< com::sun::star::frame::XModel > xModel; + if ( rxFrame.is() ) + { + Reference< com::sun::star::frame::XController > xController( rxFrame->getController(), UNO_QUERY ); + if ( xController.is() ) + xModel = xController->getModel(); + } + Reference< document::XDocumentLanguages > xDocumentLanguages( xModel, UNO_QUERY ); + /*the description of nScriptType + LATIN : 0x001 + ASIAN : 0x002 + COMPLEX: 0x004 + */ + const sal_Int16 nMaxCount = 7; + if ( xDocumentLanguages.is() ) + { + Sequence< Locale > rLocales( xDocumentLanguages->getDocumentLanguages( nScriptType, nMaxCount )); + if ( rLocales.getLength() > 0 ) + { + for ( USHORT i = 0; i < rLocales.getLength(); ++i ) + { + if ( rLangItems.size() == static_cast< size_t >(nMaxCount) ) + break; + const Locale& rLocale=rLocales[i]; + if( IsScriptTypeMatchingToLanguage( nScriptType, rLanguageTable.GetType( rLocale.Language ))) + rLangItems.insert( OUString( rLocale.Language ) ); + } + } + } +} + +} // namespace framework + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/framework/source/helper/networkdomain.cxx b/framework/source/helper/networkdomain.cxx new file mode 100644 index 000000000000..fb4bc20f5077 --- /dev/null +++ b/framework/source/helper/networkdomain.cxx @@ -0,0 +1,298 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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_framework.hxx" +#include <helper/networkdomain.hxx> + +namespace framework +{ + +#ifdef WNT +//_________________________________________________________________________________________________________________ +// Windows +//_________________________________________________________________________________________________________________ + +#define UNICODE +#if defined _MSC_VER +#pragma warning(push, 1) +#endif +#include <windows.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif + +//_________________________________________________________________________________________________________________ +// Win NT, Win 2000, Win XP +//_________________________________________________________________________________________________________________ + +static DWORD WINAPI GetUserDomainW_NT( LPWSTR lpBuffer, DWORD nSize ) +{ + return GetEnvironmentVariable( TEXT("USERDOMAIN"), lpBuffer, nSize ); +} + +//_________________________________________________________________________________________________________________ +// Win 9x,Win ME +//_________________________________________________________________________________________________________________ + +static DWORD WINAPI GetUserDomainW_WINDOWS( LPWSTR lpBuffer, DWORD nSize ) +{ + HKEY hkeyLogon; + HKEY hkeyWorkgroup; + DWORD dwResult = 0; + + + if ( ERROR_SUCCESS == RegOpenKeyEx( + HKEY_LOCAL_MACHINE, + TEXT("Network\\Logon"), + 0, KEY_READ, &hkeyLogon ) ) + { + DWORD dwLogon = 0; + DWORD dwLogonSize = sizeof(dwLogon); + RegQueryValueEx( hkeyLogon, TEXT("LMLogon"), 0, NULL, (LPBYTE)&dwLogon, &dwLogonSize ); + RegCloseKey( hkeyLogon ); + + if ( dwLogon ) + { + HKEY hkeyNetworkProvider; + + if ( ERROR_SUCCESS == RegOpenKeyEx( + HKEY_LOCAL_MACHINE, + TEXT("SYSTEM\\CurrentControlSet\\Services\\MSNP32\\NetworkProvider"), + 0, KEY_READ, &hkeyNetworkProvider ) ) + { + DWORD dwBufferSize = nSize; + LONG lResult = RegQueryValueEx( hkeyNetworkProvider, TEXT("AuthenticatingAgent"), 0, NULL, (LPBYTE)lpBuffer, &dwBufferSize ); + + if ( ERROR_SUCCESS == lResult || ERROR_MORE_DATA == lResult ) + dwResult = dwBufferSize / sizeof(TCHAR); + + RegCloseKey( hkeyNetworkProvider ); + } + } + } + else if ( ERROR_SUCCESS == RegOpenKeyEx( + HKEY_LOCAL_MACHINE, + TEXT("SYSTEM\\CurrentControlSet\\Services\\VxD\\VNETSUP"), + 0, KEY_READ, &hkeyWorkgroup ) ) + { + DWORD dwBufferSize = nSize; + LONG lResult = RegQueryValueEx( hkeyWorkgroup, TEXT("Workgroup"), 0, NULL, (LPBYTE)lpBuffer, &dwBufferSize ); + + if ( ERROR_SUCCESS == lResult || ERROR_MORE_DATA == lResult ) + dwResult = dwBufferSize / sizeof(TCHAR); + + RegCloseKey( hkeyWorkgroup ); + } + + + return dwResult; +} + +static rtl::OUString GetUserDomain() +{ + sal_Unicode aBuffer[256]; + + long nVersion = GetVersion(); + DWORD nResult; + + if ( nVersion < 0 ) + nResult = GetUserDomainW_WINDOWS( reinterpret_cast<LPWSTR>(aBuffer), sizeof( aBuffer ) ); + else + nResult = GetUserDomainW_NT( reinterpret_cast<LPWSTR>(aBuffer), sizeof( aBuffer ) ); + + if ( nResult > 0 ) + return rtl::OUString( aBuffer ); + else + return rtl::OUString(); +} + +//_________________________________________________________________________________________________________________ +// Windows +//_________________________________________________________________________________________________________________ + +rtl::OUString NetworkDomain::GetYPDomainName() +{ + return ::rtl::OUString(); +} + +rtl::OUString NetworkDomain::GetNTDomainName() +{ + return GetUserDomain(); +} + +#elif defined( UNIX ) + +#include <rtl/ustring.h> +#include <stdlib.h> +#include <errno.h> +#include <osl/thread.h> + +//_________________________________________________________________________________________________________________ +// Unix +//_________________________________________________________________________________________________________________ + +#if defined( SOLARIS ) + +//_________________________________________________________________________________________________________________ +// Solaris +//_________________________________________________________________________________________________________________ + +#include <sys/systeminfo.h> +#include <sal/alloca.h> + +static rtl_uString *getDomainName() +{ + /* Initialize and assume failure */ + rtl_uString *ustrDomainName = NULL; + + char szBuffer[256]; + + long nCopied = sizeof(szBuffer); + char *pBuffer = szBuffer; + long nBufSize; + + do + { + nBufSize = nCopied; + nCopied = sysinfo( SI_SRPC_DOMAIN, pBuffer, nBufSize ); + + /* If nCopied is greater than buffersize we need to allocate + a buffer with suitable size */ + + if ( nCopied > nBufSize ) + pBuffer = (char *)alloca( nCopied ); + + } while ( nCopied > nBufSize ); + + if ( -1 != nCopied ) + { + rtl_string2UString( + &ustrDomainName, + pBuffer, + nCopied - 1, + osl_getThreadTextEncoding(), + OSTRING_TO_OUSTRING_CVTFLAGS ); + } + + return ustrDomainName; +} + +#elif defined( LINUX ) /* endif SOLARIS */ + +//_________________________________________________________________________________________________________________ +// Linux +//_________________________________________________________________________________________________________________ + +#include <unistd.h> +#include <string.h> + +static rtl_uString *getDomainName() +{ + /* Initialize and assume failure */ + rtl_uString *ustrDomainName = NULL; + + char *pBuffer; + int result; + size_t nBufSize = 0; + + do + { + nBufSize += 256; /* Increase buffer size by steps of 256 bytes */ + pBuffer = (char *)alloca( nBufSize ); + result = getdomainname( pBuffer, nBufSize ); + /* If buffersize in not large enough -1 is returned and errno + is set to EINVAL. This only applies to libc. With glibc the name + is truncated. */ + } while ( -1 == result && EINVAL == errno ); + + if ( 0 == result ) + { + rtl_string2UString( + &ustrDomainName, + pBuffer, + strlen( pBuffer ), + osl_getThreadTextEncoding(), + OSTRING_TO_OUSTRING_CVTFLAGS ); + } + + return ustrDomainName; +} + +#else /* LINUX */ + +//_________________________________________________________________________________________________________________ +// Other Unix +//_________________________________________________________________________________________________________________ + +static rtl_uString *getDomainName() +{ + return NULL; +} + +#endif + +//_________________________________________________________________________________________________________________ +// Unix +//_________________________________________________________________________________________________________________ + +rtl::OUString NetworkDomain::GetYPDomainName() +{ + rtl_uString* pResult = getDomainName(); + if ( pResult ) + return rtl::OUString( pResult ); + else + return rtl::OUString(); +} + +rtl::OUString NetworkDomain::GetNTDomainName() +{ + return ::rtl::OUString(); +} + +#else /* UNIX */ + +//_________________________________________________________________________________________________________________ +// Other operating systems (non-Windows and non-Unix) +//_________________________________________________________________________________________________________________ + +rtl::OUString NetworkDomain::GetYPDomainName() +{ + return rtl::OUString(); +} + +rtl::OUString NetworkDomain::GetNTDomainName() +{ + return rtl::OUString(); +} + +#endif + +} // namespace framework + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/framework/source/helper/ocomponentaccess.cxx b/framework/source/helper/ocomponentaccess.cxx new file mode 100644 index 000000000000..7a93630ad3b5 --- /dev/null +++ b/framework/source/helper/ocomponentaccess.cxx @@ -0,0 +1,263 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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_framework.hxx" + +//_________________________________________________________________________________________________________________ +// my own includes +//_________________________________________________________________________________________________________________ +#include <helper/ocomponentaccess.hxx> +#include <helper/ocomponentenumeration.hxx> + +#include <threadhelp/resetableguard.hxx> + +//_________________________________________________________________________________________________________________ +// interface includes +//_________________________________________________________________________________________________________________ +#include <com/sun/star/frame/FrameSearchFlag.hpp> + +//_________________________________________________________________________________________________________________ +// includes of other projects +//_________________________________________________________________________________________________________________ +#include <vcl/svapp.hxx> + +//_________________________________________________________________________________________________________________ +// namespace +//_________________________________________________________________________________________________________________ + +namespace framework{ + +using namespace ::com::sun::star::container ; +using namespace ::com::sun::star::frame ; +using namespace ::com::sun::star::lang ; +using namespace ::com::sun::star::uno ; +using namespace ::cppu ; +using namespace ::osl ; +using namespace ::rtl ; + +//_________________________________________________________________________________________________________________ +// non exported const +//_________________________________________________________________________________________________________________ + +//_________________________________________________________________________________________________________________ +// non exported definitions +//_________________________________________________________________________________________________________________ + +//_________________________________________________________________________________________________________________ +// declarations +//_________________________________________________________________________________________________________________ + +//***************************************************************************************************************** +// constructor +//***************************************************************************************************************** +OComponentAccess::OComponentAccess( const Reference< XDesktop >& xOwner ) + // Init baseclasses first + : ThreadHelpBase ( &Application::GetSolarMutex() ) + // Init member + , m_xOwner ( xOwner ) +{ + // Safe impossible cases + LOG_ASSERT( impldbg_checkParameter_OComponentAccessCtor( xOwner ), "OComponentAccess::OComponentAccess()\nInvalid parameter detected!\n" ) +} + +//***************************************************************************************************************** +// destructor +//***************************************************************************************************************** +OComponentAccess::~OComponentAccess() +{ +} + +//***************************************************************************************************************** +// XEnumerationAccess +//***************************************************************************************************************** +Reference< XEnumeration > SAL_CALL OComponentAccess::createEnumeration() throw( RuntimeException ) +{ + // Ready for multithreading + ResetableGuard aGuard( m_aLock ); + + // Set default return value, if method failed. + // If no desktop exist and there is no task container - return an empty enumeration! + Reference< XEnumeration > xReturn = Reference< XEnumeration >(); + + // Try to "lock" the desktop for access to task container. + Reference< XInterface > xLock = m_xOwner.get(); + if ( xLock.is() == sal_True ) + { + // Desktop exist => pointer to task container must be valid. + // Initialize a new enumeration ... if some tasks and his components exist! + // (OTasksEnumeration will make an assert, if we initialize the new instance without valid values!) + + Sequence< Reference< XComponent > > seqComponents; + impl_collectAllChildComponents( Reference< XFramesSupplier >( xLock, UNO_QUERY ), seqComponents ); + OComponentEnumeration* pEnumeration = new OComponentEnumeration( seqComponents ); + xReturn = Reference< XEnumeration >( (OWeakObject*)pEnumeration, UNO_QUERY ); + } + + // Return result of this operation. + return xReturn; +} + +//***************************************************************************************************************** +// XElementAccess +//***************************************************************************************************************** +Type SAL_CALL OComponentAccess::getElementType() throw( RuntimeException ) +{ + // Elements in list an enumeration are components! + // Return the uno-type of XComponent. + return ::getCppuType((const Reference< XComponent >*)NULL); +} + +//***************************************************************************************************************** +// XElementAccess +//***************************************************************************************************************** +sal_Bool SAL_CALL OComponentAccess::hasElements() throw( RuntimeException ) +{ + // Ready for multithreading + ResetableGuard aGuard( m_aLock ); + + // Set default return value, if method failed. + sal_Bool bReturn = sal_False; + + // Try to "lock" the desktop for access to task container. + Reference< XFramesSupplier > xLock( m_xOwner.get(), UNO_QUERY ); + if ( xLock.is() == sal_True ) + { + // Ask container of owner for existing elements. + bReturn = xLock->getFrames()->hasElements(); + } + + // Return result of this operation. + return bReturn; +} + +//***************************************************************************************************************** +// private method +//***************************************************************************************************************** +void OComponentAccess::impl_collectAllChildComponents( const Reference< XFramesSupplier >& xNode , + Sequence< Reference< XComponent > >& seqComponents ) +{ + // If valid node was given ... + if( xNode.is() == sal_True ) + { + // ... continue collection at these. + + // Get the container of current node, collect the components of existing child frames + // and go down to next level in tree (recursive!). + + sal_Int32 nComponentCount = seqComponents.getLength(); + + const Reference< XFrames > xContainer = xNode->getFrames(); + const Sequence< Reference< XFrame > > seqFrames = xContainer->queryFrames( FrameSearchFlag::CHILDREN ); + + const sal_Int32 nFrameCount = seqFrames.getLength(); + for( sal_Int32 nFrame=0; nFrame<nFrameCount; ++nFrame ) + { + Reference< XComponent > xComponent = impl_getFrameComponent( seqFrames[nFrame] ); + if( xComponent.is() == sal_True ) + { + nComponentCount++; + seqComponents.realloc( nComponentCount ); + seqComponents[nComponentCount-1] = xComponent; + } + } + } + // ... otherwise break a recursive path and go back at current stack! +} + +//***************************************************************************************************************** +// private method +//***************************************************************************************************************** +Reference< XComponent > OComponentAccess::impl_getFrameComponent( const Reference< XFrame >& xFrame ) const +{ + // Set default return value, if method failed. + Reference< XComponent > xComponent = Reference< XComponent >(); + // Does no controller exists? + Reference< XController > xController = xFrame->getController(); + if ( xController.is() == sal_False ) + { + // Controller not exist - use the VCL-component. + xComponent = Reference< XComponent >( xFrame->getComponentWindow(), UNO_QUERY ); + } + else + { + // Does no model exists? + Reference< XModel > xModel( xController->getModel(), UNO_QUERY ); + if ( xModel.is() == sal_True ) + { + // Model exist - use the model as component. + xComponent = Reference< XComponent >( xModel, UNO_QUERY ); + } + else + { + // Model not exist - use the controller as component. + xComponent = Reference< XComponent >( xController, UNO_QUERY ); + } + } + + return xComponent; +} + +//_________________________________________________________________________________________________________________ +// debug methods +//_________________________________________________________________________________________________________________ + +/*----------------------------------------------------------------------------------------------------------------- + The follow methods checks the parameter for other functions. If a parameter or his value is non valid, + we return "sal_False". (else sal_True) This mechanism is used to throw an ASSERT! + + ATTENTION + + If you miss a test for one of this parameters, contact the autor or add it himself !(?) + But ... look for right testing! See using of this methods! +-----------------------------------------------------------------------------------------------------------------*/ + +#ifdef ENABLE_ASSERTIONS + +//***************************************************************************************************************** +sal_Bool OComponentAccess::impldbg_checkParameter_OComponentAccessCtor( const Reference< XDesktop >& xOwner ) +{ + // Set default return value. + sal_Bool bOK = sal_True; + // Check parameter. + if ( + ( &xOwner == NULL ) || + ( xOwner.is() == sal_False ) + ) + { + bOK = sal_False ; + } + // Return result of check. + return bOK ; +} + +#endif // #ifdef ENABLE_ASSERTIONS + +} // namespace framework + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/framework/source/helper/ocomponentenumeration.cxx b/framework/source/helper/ocomponentenumeration.cxx new file mode 100644 index 000000000000..4f889899c47f --- /dev/null +++ b/framework/source/helper/ocomponentenumeration.cxx @@ -0,0 +1,238 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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_framework.hxx" + +//_________________________________________________________________________________________________________________ +// my own includes +//_________________________________________________________________________________________________________________ +#include <helper/ocomponentenumeration.hxx> + +#include <threadhelp/resetableguard.hxx> + +//_________________________________________________________________________________________________________________ +// interface includes +//_________________________________________________________________________________________________________________ + +//_________________________________________________________________________________________________________________ +// includes of other projects +//_________________________________________________________________________________________________________________ +#include <vcl/svapp.hxx> + +//_________________________________________________________________________________________________________________ +// namespace +//_________________________________________________________________________________________________________________ + +namespace framework{ + +using namespace ::com::sun::star::container ; +using namespace ::com::sun::star::lang ; +using namespace ::com::sun::star::uno ; +using namespace ::cppu ; +using namespace ::osl ; +using namespace ::rtl ; + +//_________________________________________________________________________________________________________________ +// non exported const +//_________________________________________________________________________________________________________________ + +//_________________________________________________________________________________________________________________ +// non exported definitions +//_________________________________________________________________________________________________________________ + +//_________________________________________________________________________________________________________________ +// declarations +//_________________________________________________________________________________________________________________ + +//***************************************************************************************************************** +// constructor +//***************************************************************************************************************** +OComponentEnumeration::OComponentEnumeration( const Sequence< Reference< XComponent > >& seqComponents ) + // Init baseclasses first + // Attention: + // Don't change order of initialization! + // ThreadHelpBase is a struct with a mutex as member. We can't use a mutex as member, while + // we must garant right initialization and a valid value of this! First initialize + // baseclasses and then members. And we need the mutex for other baseclasses !!! + : ThreadHelpBase ( &Application::GetSolarMutex() ) + // Init member + , m_nPosition ( 0 ) // 0 is the first position for a valid list and the right value for an invalid list to! + , m_seqComponents ( seqComponents ) +{ + // Safe impossible states + // "Method" not defined for ALL parameters! + LOG_ASSERT( impldbg_checkParameter_OComponentEnumerationCtor( seqComponents ), "OComponentEnumeration::OComponentEnumeration()\nInvalid parameter detected!\n" ) +} + +//***************************************************************************************************************** +// destructor +//***************************************************************************************************************** +OComponentEnumeration::~OComponentEnumeration() +{ + // Reset instance, free memory .... + impl_resetObject(); +} + +//***************************************************************************************************************** +// XEventListener +//***************************************************************************************************************** +void SAL_CALL OComponentEnumeration::disposing( const EventObject& +#if OSL_DEBUG_LEVEL > 0 +aEvent +#endif +) throw( RuntimeException ) +{ + // Ready for multithreading + ResetableGuard aGuard( m_aLock ); + + // Safe impossible cases + // This method is not specified for all incoming parameters. + LOG_ASSERT( impldbg_checkParameter_disposing( aEvent ), "OComponentEnumeration::disposing()\nInvalid parameter detected!\n" ) + + // Reset instance to defaults, release references and free memory. + impl_resetObject(); +} + +//***************************************************************************************************************** +// XEnumeration +//***************************************************************************************************************** +sal_Bool SAL_CALL OComponentEnumeration::hasMoreElements() throw( RuntimeException ) +{ + // Ready for multithreading + ResetableGuard aGuard( m_aLock ); + + // First position in a valid list is 0. + // => The last one is getLength() - 1! + // m_nPosition's current value is the position for the next element, which will be return, if user call "nextElement()" + // => We have more elements if current position less then the length of the list! + return ( m_nPosition < (sal_uInt32)(m_seqComponents.getLength()) ); +} + +//***************************************************************************************************************** +// XEnumeration +//***************************************************************************************************************** +Any SAL_CALL OComponentEnumeration::nextElement() throw( NoSuchElementException , + WrappedTargetException , + RuntimeException ) +{ + // Ready for multithreading + ResetableGuard aGuard( m_aLock ); + + // If we have no elements or end of enumeration is arrived ... + if ( hasMoreElements() == sal_False ) + { + // .. throw an exception! + throw NoSuchElementException(); + } + + // Else; Get next element from list ... + Any aComponent; + aComponent <<= m_seqComponents[m_nPosition]; + // ... and step to next element! + ++m_nPosition; + + // Return listitem. + return aComponent; +} + +//***************************************************************************************************************** +// proteced method +//***************************************************************************************************************** +void OComponentEnumeration::impl_resetObject() +{ + // Attention: + // Write this for multiple calls - NOT AT THE SAME TIME - but for more then one call again)! + // It exist two ways to call this method. From destructor and from disposing(). + // I can't say, which one is the first. Normaly the disposing-call - but other way .... + + // Delete list of components. + m_seqComponents.realloc( 0 ); + // Reset position in list. + // The list has no elements anymore. m_nPosition is normaly the current position in list for nextElement! + // But a position of 0 in a list of 0 items is an invalid state. This constellation can't work in future. + // End of enumeration is arrived! + // (see hasMoreElements() for more details...) + m_nPosition = 0 ; +} + +//_________________________________________________________________________________________________________________ +// debug methods +//_________________________________________________________________________________________________________________ + +/*----------------------------------------------------------------------------------------------------------------- + The follow methods checks the parameter for other functions. If a parameter or his value is non valid, + we return "sal_False". (else sal_True) This mechanism is used to throw an ASSERT! + + ATTENTION + + If you miss a test for one of this parameters, contact the autor or add it himself !(?) + But ... look for right testing! See using of this methods! +-----------------------------------------------------------------------------------------------------------------*/ + +#ifdef ENABLE_ASSERTIONS + +//***************************************************************************************************************** +// An empty list is allowed ... hasMoreElements() will return false then! +sal_Bool OComponentEnumeration::impldbg_checkParameter_OComponentEnumerationCtor( const Sequence< Reference< XComponent > >& seqComponents ) +{ + // Set default return value. + sal_Bool bOK = sal_True; + // Check parameter. + if ( + ( &seqComponents == NULL ) + ) + { + bOK = sal_False ; + } + // Return result of check. + return bOK ; +} + +//***************************************************************************************************************** +sal_Bool OComponentEnumeration::impldbg_checkParameter_disposing( const EventObject& aEvent ) +{ + // Set default return value. + sal_Bool bOK = sal_True; + // Check parameter. + if ( + ( &aEvent == NULL ) || + ( aEvent.Source.is() == sal_False ) + ) + { + bOK = sal_False ; + } + // Return result of check. + return bOK ; +} + +#endif // #ifdef ENABLE_ASSERTIONS + +} // namespace framework + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/framework/source/helper/oframes.cxx b/framework/source/helper/oframes.cxx new file mode 100644 index 000000000000..bcd61affb6ea --- /dev/null +++ b/framework/source/helper/oframes.cxx @@ -0,0 +1,525 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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_framework.hxx" + +//_________________________________________________________________________________________________________________ +// my own includes +//_________________________________________________________________________________________________________________ +#include <helper/oframes.hxx> + +#include <threadhelp/resetableguard.hxx> + +//_________________________________________________________________________________________________________________ +// interface includes +//_________________________________________________________________________________________________________________ +#include <com/sun/star/frame/XDesktop.hpp> +#include <com/sun/star/frame/FrameSearchFlag.hpp> + +//_________________________________________________________________________________________________________________ +// includes of other projects +//_________________________________________________________________________________________________________________ +#include <vcl/svapp.hxx> + +//_________________________________________________________________________________________________________________ +// namespace +//_________________________________________________________________________________________________________________ + +namespace framework{ + +using namespace ::com::sun::star::container ; +using namespace ::com::sun::star::frame ; +using namespace ::com::sun::star::lang ; +using namespace ::com::sun::star::uno ; +using namespace ::cppu ; +using namespace ::osl ; +using namespace ::std ; + +using rtl::OUString; + +//_________________________________________________________________________________________________________________ +// non exported const +//_________________________________________________________________________________________________________________ + +//_________________________________________________________________________________________________________________ +// non exported definitions +//_________________________________________________________________________________________________________________ + +//_________________________________________________________________________________________________________________ +// declarations +//_________________________________________________________________________________________________________________ + +//***************************************************************************************************************** +// constructor +//***************************************************************************************************************** +OFrames::OFrames( const Reference< XMultiServiceFactory >& xFactory , + const Reference< XFrame >& xOwner , + FrameContainer* pFrameContainer ) + // Init baseclasses first + : ThreadHelpBase ( &Application::GetSolarMutex() ) + // Init member + , m_xFactory ( xFactory ) + , m_xOwner ( xOwner ) + , m_pFrameContainer ( pFrameContainer ) + , m_bRecursiveSearchProtection( sal_False ) +{ + // Safe impossible cases + // Method is not defined for ALL incoming parameters! + LOG_ASSERT( impldbg_checkParameter_OFramesCtor( xFactory, xOwner, pFrameContainer ), "OFrames::OFrames()\nInvalid parameter detected!\n" ) +} + +//***************************************************************************************************************** +// (proteced!) destructor +//***************************************************************************************************************** +OFrames::~OFrames() +{ + // Reset instance, free memory .... + impl_resetObject(); +} + +//***************************************************************************************************************** +// XFrames +//***************************************************************************************************************** +void SAL_CALL OFrames::append( const Reference< XFrame >& xFrame ) throw( RuntimeException ) +{ + // Ready for multithreading + ResetableGuard aGuard( m_aLock ); + + // Safe impossible cases + // Method is not defined for ALL incoming parameters! + LOG_ASSERT( impldbg_checkParameter_append( xFrame ), "OFrames::append()\nInvalid parameter detected!\n" ) + + // Do the follow only, if owner instance valid! + // Lock owner for follow operations - make a "hard reference"! + Reference< XFramesSupplier > xOwner( m_xOwner.get(), UNO_QUERY ); + if ( xOwner.is() == sal_True ) + { + // Append frame to the end of the container ... + m_pFrameContainer->append( xFrame ); + // Set owner of this instance as parent of the new frame in container! + xFrame->setCreator( xOwner ); + } + // Else; Do nothing! Ouer owner is dead. + LOG_ASSERT( !(xOwner.is()==sal_False), "OFrames::append()\nOuer owner is dead - you can't append any frames ...!\n" ) +} + +//***************************************************************************************************************** +// XFrames +//***************************************************************************************************************** +void SAL_CALL OFrames::remove( const Reference< XFrame >& xFrame ) throw( RuntimeException ) +{ + // Ready for multithreading + ResetableGuard aGuard( m_aLock ); + + // Safe impossible cases + // Method is not defined for ALL incoming parameters! + LOG_ASSERT( impldbg_checkParameter_remove( xFrame ), "OFrames::remove()\nInvalid parameter detected!\n" ) + + // Do the follow only, if owner instance valid! + // Lock owner for follow operations - make a "hard reference"! + Reference< XFramesSupplier > xOwner( m_xOwner.get(), UNO_QUERY ); + if ( xOwner.is() == sal_True ) + { + // Search frame and remove it from container ... + m_pFrameContainer->remove( xFrame ); + // Don't reset owner-property of removed frame! + // This must do the caller of this method himself. + // See documentation of interface XFrames for further informations. + } + // Else; Do nothing! Ouer owner is dead. + LOG_ASSERT( !(xOwner.is()==sal_False), "OFrames::remove()\nOuer owner is dead - you can't remove any frames ...!\n" ) +} + +//***************************************************************************************************************** +// XFrames +//***************************************************************************************************************** +Sequence< Reference< XFrame > > SAL_CALL OFrames::queryFrames( sal_Int32 nSearchFlags ) throw( RuntimeException ) +{ + // Ready for multithreading + ResetableGuard aGuard( m_aLock ); + + // Safe impossible cases + // Method is not defined for ALL incoming parameters! + LOG_ASSERT( impldbg_checkParameter_queryFrames( nSearchFlags ), "OFrames::queryFrames()\nInvalid parameter detected!\n" ) + + // Set default return value. (empty sequence) + Sequence< Reference< XFrame > > seqFrames; + + // Do the follow only, if owner instance valid. + // Lock owner for follow operations - make a "hard reference"! + Reference< XFrame > xOwner( m_xOwner.get(), UNO_QUERY ); + if ( xOwner.is() == sal_True ) + { + // Work only, if search was not started here ...! + if( m_bRecursiveSearchProtection == sal_False ) + { + // This class is a helper for services, which must implement XFrames. + // His parent and childs are MY parent and childs to. + // All searchflags are supported by this implementation! + // If some flags should not be supported - don't call me with this flags!!! + + //_____________________________________________________________________________________________________________ + // Search with AUTO-flag is not supported yet! + // We think about right implementation. + LOG_ASSERT( !(nSearchFlags & FrameSearchFlag::AUTO), "OFrames::queryFrames()\nSearch with AUTO-flag is not supported yet!\nWe think about right implementation.\n" ) + // If searched for tasks ... + // Its not supported yet. + LOG_ASSERT( !(nSearchFlags & FrameSearchFlag::AUTO), "OFrames::queryFrames()\nSearch for tasks not supported yet!\n" ) + + //_____________________________________________________________________________________________________________ + // Search for ALL and GLOBAL is superflous! + // We support all necessary flags, from which these two flags are derived. + // ALL = PARENT + SELF + CHILDREN + SIBLINGS + // GLOBAL = ALL + TASKS + + //_____________________________________________________________________________________________________________ + // Add parent to list ... if any exist! + if( nSearchFlags & FrameSearchFlag::PARENT ) + { + Reference< XFrame > xParent( xOwner->getCreator(), UNO_QUERY ); + if( xParent.is() == sal_True ) + { + Sequence< Reference< XFrame > > seqParent( 1 ); + seqParent[0] = xParent; + impl_appendSequence( seqFrames, seqParent ); + } + } + + //_____________________________________________________________________________________________________________ + // Add owner to list if SELF is searched. + if( nSearchFlags & FrameSearchFlag::SELF ) + { + Sequence< Reference< XFrame > > seqSelf( 1 ); + seqSelf[0] = xOwner; + impl_appendSequence( seqFrames, seqSelf ); + } + + //_____________________________________________________________________________________________________________ + // Add SIBLINGS to list. + if( nSearchFlags & FrameSearchFlag::SIBLINGS ) + { + // Else; start a new search. + // Protect this instance against recursive calls from parents. + m_bRecursiveSearchProtection = sal_True; + // Ask parent of my owner for frames and append results to return list. + Reference< XFramesSupplier > xParent( xOwner->getCreator(), UNO_QUERY ); + // If a parent exist ... + if ( xParent.is() == sal_True ) + { + // ... ask him for right frames. + impl_appendSequence( seqFrames, xParent->getFrames()->queryFrames( nSearchFlags ) ); + } + // We have all searched informations. + // Reset protection-mode. + m_bRecursiveSearchProtection = sal_False; + } + + //_____________________________________________________________________________________________________________ + // If searched for children, step over all elements in container and collect the informations. + if ( nSearchFlags & FrameSearchFlag::CHILDREN ) + { + // Don't search for parents, siblings and self at childrens! + // These things are supported by this instance himself. + sal_Int32 nChildSearchFlags = FrameSearchFlag::SELF | FrameSearchFlag::CHILDREN; + // Step over all items of container and ask childrens for frames. + sal_uInt32 nCount = m_pFrameContainer->getCount(); + for ( sal_uInt32 nIndex=0; nIndex<nCount; ++nIndex ) + { + // We don't must control this conversion. + // We have done this at append()! + Reference< XFramesSupplier > xItem( (*m_pFrameContainer)[nIndex], UNO_QUERY ); + impl_appendSequence( seqFrames, xItem->getFrames()->queryFrames( nChildSearchFlags ) ); + } + } + } + } + // Else; Do nothing! Ouer owner is dead. + LOG_ASSERT( !(xOwner.is()==sal_False), "OFrames::queryFrames()\nOuer owner is dead - you can't query for frames ...!\n" ) + + // Resturn result of this operation. + return seqFrames; +} + +//***************************************************************************************************************** +// XIndexAccess +//***************************************************************************************************************** +sal_Int32 SAL_CALL OFrames::getCount() throw( RuntimeException ) +{ + // Ready for multithreading + ResetableGuard aGuard( m_aLock ); + + // Set default return value. + sal_Int32 nCount = 0; + + // Do the follow only, if owner instance valid. + // Lock owner for follow operations - make a "hard reference"! + Reference< XFrame > xOwner( m_xOwner.get(), UNO_QUERY ); + if ( xOwner.is() == sal_True ) + { + // Set CURRENT size of container for return. + nCount = m_pFrameContainer->getCount(); + } + + // Return result. + return nCount; +} + +//***************************************************************************************************************** +// XIndexAccess +//***************************************************************************************************************** +Any SAL_CALL OFrames::getByIndex( sal_Int32 nIndex ) throw( IndexOutOfBoundsException , + WrappedTargetException , + RuntimeException ) +{ + // Ready for multithreading + ResetableGuard aGuard( m_aLock ); + + sal_uInt32 nCount = m_pFrameContainer->getCount(); + if ( nIndex < 0 || ( sal::static_int_cast< sal_uInt32 >( nIndex ) >= nCount )) + throw IndexOutOfBoundsException( OUString(RTL_CONSTASCII_USTRINGPARAM("OFrames::getByIndex - Index out of bounds")), + (OWeakObject *)this ); + + // Set default return value. + Any aReturnValue; + + // Do the follow only, if owner instance valid. + // Lock owner for follow operations - make a "hard reference"! + Reference< XFrame > xOwner( m_xOwner.get(), UNO_QUERY ); + if ( xOwner.is() == sal_True ) + { + // Get element form container. + // (If index not valid, FrameContainer return NULL!) + aReturnValue <<= (*m_pFrameContainer)[nIndex]; + } + + // Return result of this operation. + return aReturnValue; +} + +//***************************************************************************************************************** +// XElementAccess +//***************************************************************************************************************** +Type SAL_CALL OFrames::getElementType() throw( RuntimeException ) +{ + // This "container" support XFrame-interfaces only! + return ::getCppuType( (const Reference< XFrame >*)NULL ); +} + +//***************************************************************************************************************** +// XElementAccess +//***************************************************************************************************************** +sal_Bool SAL_CALL OFrames::hasElements() throw( RuntimeException ) +{ + // Ready for multithreading + ResetableGuard aGuard( m_aLock ); + + // Set default return value. + sal_Bool bHasElements = sal_False; + // Do the follow only, if owner instance valid. + // Lock owner for follow operations - make a "hard reference"! + Reference< XFrame > xOwner( m_xOwner.get(), UNO_QUERY ); + if ( xOwner.is() == sal_True ) + { + // If some elements exist ... + if ( m_pFrameContainer->getCount() > 0 ) + { + // ... change this state value! + bHasElements = sal_True; + } + } + // Return result of this operation. + return bHasElements; +} + +//***************************************************************************************************************** +// proteced method +//***************************************************************************************************************** +void OFrames::impl_resetObject() +{ + // Attention: + // Write this for multiple calls - NOT AT THE SAME TIME - but for more then one call again)! + // It exist two ways to call this method. From destructor and from disposing(). + // I can't say, which one is the first. Normaly the disposing-call - but other way .... + + // This instance can't work if the weakreference to owner is invalid! + // Destroy this to reset this object. + m_xOwner = WeakReference< XFrame >(); + // Reset pointer to shared container to! + m_pFrameContainer = NULL; +} + +//***************************************************************************************************************** +// private method +//***************************************************************************************************************** +void OFrames::impl_appendSequence( Sequence< Reference< XFrame > >& seqDestination , + const Sequence< Reference< XFrame > >& seqSource ) +{ + // Get some informations about the sequences. + sal_Int32 nSourceCount = seqSource.getLength(); + sal_Int32 nDestinationCount = seqDestination.getLength(); + const Reference< XFrame >* pSourceAccess = seqSource.getConstArray(); + Reference< XFrame >* pDestinationAccess = seqDestination.getArray(); + + // Get memory for result list. + Sequence< Reference< XFrame > > seqResult ( nSourceCount + nDestinationCount ); + Reference< XFrame >* pResultAccess = seqResult.getArray(); + sal_Int32 nResultPosition = 0; + + // Copy all items from first sequence. + for ( sal_Int32 nSourcePosition=0; nSourcePosition<nSourceCount; ++nSourcePosition ) + { + pResultAccess[nResultPosition] = pSourceAccess[nSourcePosition]; + ++nResultPosition; + } + + // Don't manipulate nResultPosition between these two loops! + // Its the current position in the result list. + + // Copy all items from second sequence. + for ( sal_Int32 nDestinationPosition=0; nDestinationPosition<nDestinationCount; ++nDestinationPosition ) + { + pResultAccess[nResultPosition] = pDestinationAccess[nDestinationPosition]; + ++nResultPosition; + } + + // Return result of this operation. + seqDestination.realloc( 0 ); + seqDestination = seqResult; +} + +//_________________________________________________________________________________________________________________ +// debug methods +//_________________________________________________________________________________________________________________ + +/*----------------------------------------------------------------------------------------------------------------- + The follow methods checks the parameter for other functions. If a parameter or his value is non valid, + we return "sal_False". (else sal_True) This mechanism is used to throw an ASSERT! + + ATTENTION + + If you miss a test for one of this parameters, contact the autor or add it himself !(?) + But ... look for right testing! See using of this methods! +-----------------------------------------------------------------------------------------------------------------*/ + +#ifdef ENABLE_ASSERTIONS + +//***************************************************************************************************************** +// An instance of this class can only work with valid initialization. +// We share the mutex with ouer owner class, need a valid factory to instanciate new services and +// use the access to ouer owner for some operations. +sal_Bool OFrames::impldbg_checkParameter_OFramesCtor( const Reference< XMultiServiceFactory >& xFactory , + const Reference< XFrame >& xOwner , + FrameContainer* pFrameContainer ) +{ + // Set default return value. + sal_Bool bOK = sal_True; + // Check parameter. + if ( + ( &xFactory == NULL ) || + ( &xOwner == NULL ) || + ( xFactory.is() == sal_False ) || + ( xOwner.is() == sal_False ) || + ( pFrameContainer == NULL ) + ) + { + bOK = sal_False ; + } + // Return result of check. + return bOK ; +} + +//***************************************************************************************************************** +// Its only allowed to add valid references to container. +// AND - alle frames must support XFrames-interface! +sal_Bool OFrames::impldbg_checkParameter_append( const Reference< XFrame >& xFrame ) +{ + // Set default return value. + sal_Bool bOK = sal_True; + // Check parameter. + if ( + ( &xFrame == NULL ) || + ( xFrame.is() == sal_False ) + ) + { + bOK = sal_False ; + } + // Return result of check. + return bOK ; +} + +//***************************************************************************************************************** +// Its only allowed to add valid references to container... +// ... => You can only delete valid references! +sal_Bool OFrames::impldbg_checkParameter_remove( const Reference< XFrame >& xFrame ) +{ + // Set default return value. + sal_Bool bOK = sal_True; + // Check parameter. + if ( + ( &xFrame == NULL ) || + ( xFrame.is() == sal_False ) + ) + { + bOK = sal_False ; + } + // Return result of check. + return bOK ; +} + +//***************************************************************************************************************** +// A search for frames must initiate with right flags. +// Some one are superflous and not supported yet. But here we control only the range of incoming parameter! +sal_Bool OFrames::impldbg_checkParameter_queryFrames( sal_Int32 nSearchFlags ) +{ + // Set default return value. + sal_Bool bOK = sal_True; + // Check parameter. + if ( + ( nSearchFlags != FrameSearchFlag::AUTO ) && + ( !( nSearchFlags & FrameSearchFlag::PARENT ) ) && + ( !( nSearchFlags & FrameSearchFlag::SELF ) ) && + ( !( nSearchFlags & FrameSearchFlag::CHILDREN ) ) && + ( !( nSearchFlags & FrameSearchFlag::CREATE ) ) && + ( !( nSearchFlags & FrameSearchFlag::SIBLINGS ) ) && + ( !( nSearchFlags & FrameSearchFlag::TASKS ) ) && + ( !( nSearchFlags & FrameSearchFlag::ALL ) ) && + ( !( nSearchFlags & FrameSearchFlag::GLOBAL ) ) + ) + { + bOK = sal_False ; + } + // Return result of check. + return bOK ; +} + +#endif // #ifdef ENABLE_ASSERTIONS + +} // namespace framework + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/framework/source/helper/persistentwindowstate.cxx b/framework/source/helper/persistentwindowstate.cxx new file mode 100644 index 000000000000..e285a8510a6d --- /dev/null +++ b/framework/source/helper/persistentwindowstate.cxx @@ -0,0 +1,347 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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_framework.hxx" + +//_________________________________________________________________________________________________________________ +// my own includes +//_________________________________________________________________________________________________________________ +#include <pattern/window.hxx> +#include <helper/persistentwindowstate.hxx> +#include <threadhelp/writeguard.hxx> +#include <threadhelp/readguard.hxx> +#include <macros/generic.hxx> +#include <services.h> + +//_________________________________________________________________________________________________________________ +// interface includes +//_________________________________________________________________________________________________________________ +#include <com/sun/star/awt/XWindow.hpp> + +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/IllegalArgumentException.hpp> +#include <com/sun/star/frame/XModuleManager.hpp> + +//_________________________________________________________________________________________________________________ +// other includes +//_________________________________________________________________________________________________________________ +#include <comphelper/configurationhelper.hxx> +#include <vcl/window.hxx> +#include <vcl/syswin.hxx> + +#include <toolkit/unohlp.hxx> +#include <vcl/svapp.hxx> +#include <vcl/wrkwin.hxx> + +//_________________________________________________________________________________________________________________ +// namespace + +namespace framework{ + +//_________________________________________________________________________________________________________________ +// definitions + +//***************************************************************************************************************** +// XInterface, XTypeProvider + +DEFINE_XINTERFACE_4(PersistentWindowState , + OWeakObject , + DIRECT_INTERFACE (css::lang::XTypeProvider ), + DIRECT_INTERFACE (css::lang::XInitialization ), + DIRECT_INTERFACE (css::frame::XFrameActionListener ), + DERIVED_INTERFACE(css::lang::XEventListener,css::frame::XFrameActionListener)) + +DEFINE_XTYPEPROVIDER_4(PersistentWindowState , + css::lang::XTypeProvider , + css::lang::XInitialization , + css::frame::XFrameActionListener, + css::lang::XEventListener ) + +//***************************************************************************************************************** +PersistentWindowState::PersistentWindowState(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR) + : ThreadHelpBase (&Application::GetSolarMutex()) + , m_xSMGR (xSMGR ) + , m_bWindowStateAlreadySet(sal_False ) +{ +} + +//***************************************************************************************************************** +PersistentWindowState::~PersistentWindowState() +{ +} + +//***************************************************************************************************************** +void SAL_CALL PersistentWindowState::initialize(const css::uno::Sequence< css::uno::Any >& lArguments) + throw(css::uno::Exception , + css::uno::RuntimeException) +{ + // check arguments + css::uno::Reference< css::frame::XFrame > xFrame; + if (lArguments.getLength() < 1) + throw css::lang::IllegalArgumentException( + DECLARE_ASCII("Empty argument list!"), + static_cast< ::cppu::OWeakObject* >(this), + 1); + + lArguments[0] >>= xFrame; + if (!xFrame.is()) + throw css::lang::IllegalArgumentException( + DECLARE_ASCII("No valid frame specified!"), + static_cast< ::cppu::OWeakObject* >(this), + 1); + + // SAFE -> ---------------------------------- + WriteGuard aWriteLock(m_aLock); + // hold the frame as weak reference(!) so it can die everytimes :-) + m_xFrame = xFrame; + aWriteLock.unlock(); + // <- SAFE ---------------------------------- + + // start listening + xFrame->addFrameActionListener(this); +} + +//***************************************************************************************************************** +void SAL_CALL PersistentWindowState::frameAction(const css::frame::FrameActionEvent& aEvent) + throw(css::uno::RuntimeException) +{ + // SAFE -> ---------------------------------- + ReadGuard aReadLock(m_aLock); + css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR ; + css::uno::Reference< css::frame::XFrame > xFrame(m_xFrame.get(), css::uno::UNO_QUERY); + sal_Bool bRestoreWindowState = !m_bWindowStateAlreadySet; + aReadLock.unlock(); + // <- SAFE ---------------------------------- + + // frame already gone ? We hold it weak only ... + if (!xFrame.is()) + return; + + // no window -> no position and size available + css::uno::Reference< css::awt::XWindow > xWindow = xFrame->getContainerWindow(); + if (!xWindow.is()) + return; + + // unknown module -> no configuration available! + ::rtl::OUString sModuleName = PersistentWindowState::implst_identifyModule(xSMGR, xFrame); + if (!sModuleName.getLength()) + return; + + switch(aEvent.Action) + { + case css::frame::FrameAction_COMPONENT_ATTACHED : + { + if (bRestoreWindowState) + { + ::rtl::OUString sWindowState = PersistentWindowState::implst_getWindowStateFromConfig(xSMGR, sModuleName); + PersistentWindowState::implst_setWindowStateOnWindow(xWindow,sWindowState); + // SAFE -> ---------------------------------- + WriteGuard aWriteLock(m_aLock); + m_bWindowStateAlreadySet = sal_True; + aWriteLock.unlock(); + // <- SAFE ---------------------------------- + } + } + break; + + case css::frame::FrameAction_COMPONENT_REATTACHED : + { + // nothing todo here, because its not allowed to change position and size + // of an alredy existing frame! + } + break; + + case css::frame::FrameAction_COMPONENT_DETACHING : + { + ::rtl::OUString sWindowState = PersistentWindowState::implst_getWindowStateFromWindow(xWindow); + PersistentWindowState::implst_setWindowStateOnConfig(xSMGR, sModuleName, sWindowState); + } + break; + default: + break; + } +} + +//***************************************************************************************************************** +void SAL_CALL PersistentWindowState::disposing(const css::lang::EventObject&) + throw(css::uno::RuntimeException) +{ + // nothing todo here - because we hold the frame as weak reference only +} + +//***************************************************************************************************************** +::rtl::OUString PersistentWindowState::implst_identifyModule(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR , + const css::uno::Reference< css::frame::XFrame >& xFrame) +{ + ::rtl::OUString sModuleName; + + css::uno::Reference< css::frame::XModuleManager > xModuleManager( + xSMGR->createInstance(SERVICENAME_MODULEMANAGER), + css::uno::UNO_QUERY_THROW); + + try + { + sModuleName = xModuleManager->identify(xFrame); + } + catch(const css::uno::RuntimeException& exRun) + { throw exRun; } + catch(const css::uno::Exception&) + { sModuleName = ::rtl::OUString(); } + + return sModuleName; +} + +//***************************************************************************************************************** +::rtl::OUString PersistentWindowState::implst_getWindowStateFromConfig(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR , + const ::rtl::OUString& sModuleName) +{ + ::rtl::OUString sWindowState; + + ::rtl::OUStringBuffer sRelPathBuf(256); + sRelPathBuf.appendAscii("Office/Factories/*[\""); + sRelPathBuf.append (sModuleName ); + sRelPathBuf.appendAscii("\"]" ); + + ::rtl::OUString sPackage(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Setup/")); + ::rtl::OUString sRelPath = sRelPathBuf.makeStringAndClear(); + ::rtl::OUString sKey(RTL_CONSTASCII_USTRINGPARAM("ooSetupFactoryWindowAttributes")); + + try + { + ::comphelper::ConfigurationHelper::readDirectKey(xSMGR, + sPackage, + sRelPath, + sKey, + ::comphelper::ConfigurationHelper::E_READONLY) >>= sWindowState; + } + catch(const css::uno::RuntimeException& exRun) + { throw exRun; } + catch(const css::uno::Exception&) + { sWindowState = ::rtl::OUString(); } + + return sWindowState; +} + +//***************************************************************************************************************** +void PersistentWindowState::implst_setWindowStateOnConfig(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR , + const ::rtl::OUString& sModuleName , + const ::rtl::OUString& sWindowState) +{ + ::rtl::OUStringBuffer sRelPathBuf(256); + sRelPathBuf.appendAscii("Office/Factories/*[\""); + sRelPathBuf.append (sModuleName ); + sRelPathBuf.appendAscii("\"]" ); + + ::rtl::OUString sPackage(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Setup/")); + ::rtl::OUString sRelPath = sRelPathBuf.makeStringAndClear(); + ::rtl::OUString sKey(RTL_CONSTASCII_USTRINGPARAM("ooSetupFactoryWindowAttributes")); + + try + { + ::comphelper::ConfigurationHelper::writeDirectKey(xSMGR, + sPackage, + sRelPath, + sKey, + css::uno::makeAny(sWindowState), + ::comphelper::ConfigurationHelper::E_STANDARD); + } + catch(const css::uno::RuntimeException& exRun) + { throw exRun; } + catch(const css::uno::Exception&) + {} +} + +//***************************************************************************************************************** +::rtl::OUString PersistentWindowState::implst_getWindowStateFromWindow(const css::uno::Reference< css::awt::XWindow >& xWindow) +{ + ::rtl::OUString sWindowState; + + if (xWindow.is()) + { + // SOLAR SAFE -> ------------------------ + SolarMutexGuard aSolarGuard; + + Window* pWindow = VCLUnoHelper::GetWindow(xWindow); + // check for system window is neccessary to guarantee correct pointer cast! + if ( + (pWindow ) && + (pWindow->IsSystemWindow()) + ) + { + ULONG nMask = WINDOWSTATE_MASK_ALL; + nMask &= ~(WINDOWSTATE_MASK_MINIMIZED); + sWindowState = B2U_ENC( + ((SystemWindow*)pWindow)->GetWindowState(nMask), + RTL_TEXTENCODING_UTF8); + } + // <- SOLAR SAFE ------------------------ + } + + return sWindowState; +} + + +//********************************************************************************************************* +void PersistentWindowState::implst_setWindowStateOnWindow(const css::uno::Reference< css::awt::XWindow >& xWindow , + const ::rtl::OUString& sWindowState) +{ + if ( + (!xWindow.is() ) || + ( sWindowState.getLength() < 1) + ) + return; + + // SOLAR SAFE -> ------------------------ + SolarMutexGuard aSolarGuard; + + Window* pWindow = VCLUnoHelper::GetWindow(xWindow); + if (!pWindow) + return; + + // check for system and work window - its neccessary to guarantee correct pointer cast! + sal_Bool bSystemWindow = pWindow->IsSystemWindow(); + sal_Bool bWorkWindow = (pWindow->GetType() == WINDOW_WORKWINDOW); + + if (!bSystemWindow && !bWorkWindow) + return; + + SystemWindow* pSystemWindow = (SystemWindow*)pWindow; + WorkWindow* pWorkWindow = (WorkWindow* )pWindow; + + // dont save this special state! + if (pWorkWindow->IsMinimized()) + return; + + pSystemWindow->SetWindowState(U2B_ENC(sWindowState,RTL_TEXTENCODING_UTF8)); + // <- SOLAR SAFE ------------------------ +} + +} // namespace framework + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/framework/source/helper/propertysetcontainer.cxx b/framework/source/helper/propertysetcontainer.cxx new file mode 100644 index 000000000000..a21a634a9106 --- /dev/null +++ b/framework/source/helper/propertysetcontainer.cxx @@ -0,0 +1,198 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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_framework.hxx" +#include <helper/propertysetcontainer.hxx> +#include <threadhelp/resetableguard.hxx> + +#include <vcl/svapp.hxx> + +#define WRONG_TYPE_EXCEPTION "Only XPropertSet allowed!" + +using namespace rtl; +using namespace cppu; +using namespace com::sun::star::uno; +using namespace com::sun::star::container; +using namespace com::sun::star::lang; +using namespace com::sun::star::beans; + +namespace framework +{ + +PropertySetContainer::PropertySetContainer( const Reference< XMultiServiceFactory >& ) + : ThreadHelpBase( &Application::GetSolarMutex() ) + , OWeakObject() + +{ +} + + +PropertySetContainer::~PropertySetContainer() +{ +} + + +// XInterface +void SAL_CALL PropertySetContainer::acquire() throw () +{ + OWeakObject::acquire(); +} + +void SAL_CALL PropertySetContainer::release() throw () +{ + OWeakObject::release(); +} + +Any SAL_CALL PropertySetContainer::queryInterface( const Type& rType ) +throw ( RuntimeException ) +{ + Any a = ::cppu::queryInterface( + rType , + SAL_STATIC_CAST( XIndexContainer*, this ), + SAL_STATIC_CAST( XIndexReplace*, this ), + SAL_STATIC_CAST( XIndexAccess*, this ), + SAL_STATIC_CAST( XElementAccess*, this ) ); + + if( a.hasValue() ) + { + return a; + } + + return OWeakObject::queryInterface( rType ); +} + +// XIndexContainer +void SAL_CALL PropertySetContainer::insertByIndex( sal_Int32 Index, const ::com::sun::star::uno::Any& Element ) + throw ( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException ) +{ + ResetableGuard aGuard( m_aLock ); + + sal_Int32 nSize = m_aPropertySetVector.size(); + + if ( nSize >= Index ) + { + Reference< XPropertySet > aPropertySetElement; + + if ( Element >>= aPropertySetElement ) + { + if ( nSize == Index ) + m_aPropertySetVector.push_back( aPropertySetElement ); + else + { + PropertySetVector::iterator aIter = m_aPropertySetVector.begin(); + aIter += Index; + m_aPropertySetVector.insert( aIter, aPropertySetElement ); + } + } + else + { + throw IllegalArgumentException( + OUString( RTL_CONSTASCII_USTRINGPARAM( WRONG_TYPE_EXCEPTION )), + (OWeakObject *)this, 2 ); + } + } + else + throw IndexOutOfBoundsException( OUString(), (OWeakObject *)this ); +} + +void SAL_CALL PropertySetContainer::removeByIndex( sal_Int32 Index ) + throw ( IndexOutOfBoundsException, WrappedTargetException, RuntimeException ) +{ + ResetableGuard aGuard( m_aLock ); + + if ( (sal_Int32)m_aPropertySetVector.size() > Index ) + { + PropertySetVector::iterator aIter = m_aPropertySetVector.begin(); + aIter += Index; + m_aPropertySetVector.erase( aIter ); + } + else + throw IndexOutOfBoundsException( OUString(), (OWeakObject *)this ); +} + +// XIndexReplace +void SAL_CALL PropertySetContainer::replaceByIndex( sal_Int32 Index, const ::com::sun::star::uno::Any& Element ) + throw ( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException) +{ + if ( (sal_Int32)m_aPropertySetVector.size() > Index ) + { + Reference< XPropertySet > aPropertySetElement; + + if ( Element >>= aPropertySetElement ) + { + m_aPropertySetVector[ Index ] = aPropertySetElement; + } + else + { + throw IllegalArgumentException( + OUString( RTL_CONSTASCII_USTRINGPARAM( WRONG_TYPE_EXCEPTION )), + (OWeakObject *)this, 2 ); + } + } + else + throw IndexOutOfBoundsException( OUString(), (OWeakObject *)this ); +} + +// XIndexAccess +sal_Int32 SAL_CALL PropertySetContainer::getCount() + throw ( RuntimeException ) +{ + ResetableGuard aGuard( m_aLock ); + + return m_aPropertySetVector.size(); +} + +Any SAL_CALL PropertySetContainer::getByIndex( sal_Int32 Index ) + throw ( IndexOutOfBoundsException, WrappedTargetException, RuntimeException ) +{ + ResetableGuard aGuard( m_aLock ); + + if ( (sal_Int32)m_aPropertySetVector.size() > Index ) + { + Any a; + + a <<= m_aPropertySetVector[ Index ]; + return a; + } + else + throw IndexOutOfBoundsException( OUString(), (OWeakObject *)this ); +} + +// XElementAccess +sal_Bool SAL_CALL PropertySetContainer::hasElements() + throw (::com::sun::star::uno::RuntimeException) +{ + ResetableGuard aGuard( m_aLock ); + + return !( m_aPropertySetVector.empty() ); +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/framework/source/helper/shareablemutex.cxx b/framework/source/helper/shareablemutex.cxx new file mode 100644 index 000000000000..1cc9a0acd8b9 --- /dev/null +++ b/framework/source/helper/shareablemutex.cxx @@ -0,0 +1,84 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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_framework.hxx" +#include <helper/shareablemutex.hxx> + +namespace framework +{ + +ShareableMutex::ShareableMutex() +{ + pMutexRef = new MutexRef; + pMutexRef->acquire(); +} + +ShareableMutex::ShareableMutex( const ShareableMutex& rShareableMutex ) +{ + pMutexRef = rShareableMutex.pMutexRef; + if ( pMutexRef ) + pMutexRef->acquire(); +} + +const ShareableMutex& ShareableMutex::operator=( const ShareableMutex& rShareableMutex ) +{ + if ( rShareableMutex.pMutexRef ) + rShareableMutex.pMutexRef->acquire(); + if ( pMutexRef ) + pMutexRef->release(); + pMutexRef = rShareableMutex.pMutexRef; + return *this; +} + +ShareableMutex::~ShareableMutex() +{ + if ( pMutexRef ) + pMutexRef->release(); +} + +void ShareableMutex::acquire() +{ + if ( pMutexRef ) + pMutexRef->m_oslMutex.acquire(); +} + +void ShareableMutex::release() +{ + if ( pMutexRef ) + pMutexRef->m_oslMutex.release(); +} + +::osl::Mutex& ShareableMutex::getShareableOslMutex() +{ + return pMutexRef->m_oslMutex; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/framework/source/helper/statusindicator.cxx b/framework/source/helper/statusindicator.cxx new file mode 100644 index 000000000000..a73d63fa14e0 --- /dev/null +++ b/framework/source/helper/statusindicator.cxx @@ -0,0 +1,155 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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_framework.hxx" + +//_______________________________________________ +// include files of own module +#include <helper/statusindicator.hxx> +#include <threadhelp/readguard.hxx> +#include <threadhelp/writeguard.hxx> + +//_______________________________________________ +// namespace + +namespace framework{ + +//_______________________________________________ +// declarations + +//*********************************************** +// XInterface +DEFINE_XINTERFACE_2(StatusIndicator , + OWeakObject , + DIRECT_INTERFACE(css::lang::XTypeProvider ), + DIRECT_INTERFACE(css::task::XStatusIndicator)) + +//*********************************************** +// XInterface +DEFINE_XTYPEPROVIDER_2(StatusIndicator , + css::lang::XTypeProvider , + css::task::XStatusIndicator) + +//*********************************************** +StatusIndicator::StatusIndicator(StatusIndicatorFactory* pFactory) + : ThreadHelpBase ( ) + , ::cppu::OWeakObject( ) + , m_xFactory (pFactory) +{ +} + +//*********************************************** +StatusIndicator::~StatusIndicator() +{ +} + +//*********************************************** +void SAL_CALL StatusIndicator::start(const ::rtl::OUString& sText , + sal_Int32 nRange) + throw(css::uno::RuntimeException) +{ + // SAFE -> + ReadGuard aReadLock(m_aLock); + css::uno::Reference< css::task::XStatusIndicatorFactory > xFactory(m_xFactory.get(), css::uno::UNO_QUERY); + aReadLock.unlock(); + // <- SAFE + if (xFactory.is()) + { + StatusIndicatorFactory* pFactory = (StatusIndicatorFactory*)xFactory.get(); + pFactory->start(this, sText, nRange); + } +} + +//*********************************************** +void SAL_CALL StatusIndicator::end() + throw(css::uno::RuntimeException) +{ + // SAFE -> + ReadGuard aReadLock(m_aLock); + css::uno::Reference< css::task::XStatusIndicatorFactory > xFactory(m_xFactory.get(), css::uno::UNO_QUERY); + aReadLock.unlock(); + // <- SAFE + if (xFactory.is()) + { + StatusIndicatorFactory* pFactory = (StatusIndicatorFactory*)xFactory.get(); + pFactory->end(this); + } +} + +//*********************************************** +void SAL_CALL StatusIndicator::reset() + throw(css::uno::RuntimeException) +{ + // SAFE -> + ReadGuard aReadLock(m_aLock); + css::uno::Reference< css::task::XStatusIndicatorFactory > xFactory(m_xFactory.get(), css::uno::UNO_QUERY); + aReadLock.unlock(); + // <- SAFE + if (xFactory.is()) + { + StatusIndicatorFactory* pFactory = (StatusIndicatorFactory*)xFactory.get(); + pFactory->reset(this); + } +} + +//*********************************************** +void SAL_CALL StatusIndicator::setText(const ::rtl::OUString& sText) + throw(css::uno::RuntimeException) +{ + // SAFE -> + ReadGuard aReadLock(m_aLock); + css::uno::Reference< css::task::XStatusIndicatorFactory > xFactory(m_xFactory.get(), css::uno::UNO_QUERY); + aReadLock.unlock(); + // <- SAFE + if (xFactory.is()) + { + StatusIndicatorFactory* pFactory = (StatusIndicatorFactory*)xFactory.get(); + pFactory->setText(this, sText); + } +} + +//*********************************************** +void SAL_CALL StatusIndicator::setValue(sal_Int32 nValue) + throw(css::uno::RuntimeException) +{ + // SAFE -> + ReadGuard aReadLock(m_aLock); + css::uno::Reference< css::task::XStatusIndicatorFactory > xFactory(m_xFactory.get(), css::uno::UNO_QUERY); + aReadLock.unlock(); + // <- SAFE + if (xFactory.is()) + { + StatusIndicatorFactory* pFactory = (StatusIndicatorFactory*)xFactory.get(); + pFactory->setValue(this, nValue); + } +} + +} // namespace framework + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/framework/source/helper/statusindicatorfactory.cxx b/framework/source/helper/statusindicatorfactory.cxx new file mode 100644 index 000000000000..0180d9cee95a --- /dev/null +++ b/framework/source/helper/statusindicatorfactory.cxx @@ -0,0 +1,653 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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_framework.hxx" + +//----------------------------------------------- +// my own includes + +#include <algorithm> +#include <helper/statusindicatorfactory.hxx> +#include <helper/statusindicator.hxx> +#include <helper/vclstatusindicator.hxx> +#include <threadhelp/writeguard.hxx> +#include <threadhelp/readguard.hxx> +#include <services.h> +#include <properties.h> + +//----------------------------------------------- +// interface includes +#include <com/sun/star/awt/Rectangle.hpp> + +#include <com/sun/star/awt/XControl.hpp> +#include <com/sun/star/awt/XLayoutConstrains.hpp> +#include <com/sun/star/awt/DeviceInfo.hpp> +#include <com/sun/star/awt/PosSize.hpp> +#include <com/sun/star/awt/WindowAttribute.hpp> +#include <com/sun/star/awt/XTopWindow.hpp> +#include <com/sun/star/awt/XWindow2.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/frame/XLayoutManager.hpp> + +#include <toolkit/unohlp.hxx> + +//----------------------------------------------- +// includes of other projects +#include <comphelper/sequenceashashmap.hxx> +#include <comphelper/mediadescriptor.hxx> +#include <comphelper/configurationhelper.hxx> +#include <vcl/svapp.hxx> +#include <osl/mutex.hxx> + +//----------------------------------------------- +// namespace + +namespace framework{ + +//----------------------------------------------- +// definitions + +sal_Int32 StatusIndicatorFactory::m_nInReschedule = 0; /// static counter for rescheduling +static ::rtl::OUString PROGRESS_RESOURCE(RTL_CONSTASCII_USTRINGPARAM("private:resource/progressbar/progressbar")); + +//----------------------------------------------- +DEFINE_XINTERFACE_5(StatusIndicatorFactory , + OWeakObject , + DIRECT_INTERFACE(css::lang::XTypeProvider ), + DIRECT_INTERFACE(css::lang::XServiceInfo ), + DIRECT_INTERFACE(css::lang::XInitialization ), + DIRECT_INTERFACE(css::task::XStatusIndicatorFactory), + DIRECT_INTERFACE(css::util::XUpdatable )) + +DEFINE_XTYPEPROVIDER_5(StatusIndicatorFactory , + css::lang::XTypeProvider , + css::lang::XServiceInfo , + css::lang::XInitialization , + css::task::XStatusIndicatorFactory, + css::util::XUpdatable ) + +DEFINE_XSERVICEINFO_MULTISERVICE(StatusIndicatorFactory , + ::cppu::OWeakObject , + SERVICENAME_STATUSINDICATORFACTORY , + IMPLEMENTATIONNAME_STATUSINDICATORFACTORY) + +DEFINE_INIT_SERVICE(StatusIndicatorFactory, + { + /*Attention + I think we don't need any mutex or lock here ... because we are called by our own static method impl_createInstance() + to create a new instance of this class by our own supported service factory. + see macro DEFINE_XSERVICEINFO_MULTISERVICE and "impl_initService()" for further informations! + */ + } + ) + +//----------------------------------------------- +StatusIndicatorFactory::StatusIndicatorFactory(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR) + : ThreadHelpBase ( ) + , ::cppu::OWeakObject ( ) + , m_xSMGR (xSMGR ) + , m_pWakeUp (0 ) + , m_bAllowReschedule (sal_False) + , m_bAllowParentShow (sal_False) + , m_bDisableReschedule(sal_False) +{ +} + +//----------------------------------------------- +StatusIndicatorFactory::~StatusIndicatorFactory() +{ + impl_stopWakeUpThread(); +} + +//----------------------------------------------- +void SAL_CALL StatusIndicatorFactory::initialize(const css::uno::Sequence< css::uno::Any >& lArguments) + throw(css::uno::Exception , + css::uno::RuntimeException) +{ + ::comphelper::SequenceAsHashMap lArgs(lArguments); + + // SAFE -> ---------------------------------- + WriteGuard aWriteLock(m_aLock); + + m_xFrame = lArgs.getUnpackedValueOrDefault(STATUSINDICATORFACTORY_PROPNAME_FRAME , css::uno::Reference< css::frame::XFrame >()); + m_xPluggWindow = lArgs.getUnpackedValueOrDefault(STATUSINDICATORFACTORY_PROPNAME_WINDOW , css::uno::Reference< css::awt::XWindow >() ); + m_bAllowParentShow = lArgs.getUnpackedValueOrDefault(STATUSINDICATORFACTORY_PROPNAME_ALLOWPARENTSHOW , (sal_Bool)sal_False ); + m_bDisableReschedule = lArgs.getUnpackedValueOrDefault(STATUSINDICATORFACTORY_PROPNAME_DISABLERESCHEDULE, (sal_Bool)sal_False ); + + aWriteLock.unlock(); + // <- SAFE ---------------------------------- + + impl_createProgress(); +} + +//----------------------------------------------- +css::uno::Reference< css::task::XStatusIndicator > SAL_CALL StatusIndicatorFactory::createStatusIndicator() + throw(css::uno::RuntimeException) +{ + StatusIndicator* pIndicator = new StatusIndicator(this); + css::uno::Reference< css::task::XStatusIndicator > xIndicator(static_cast< ::cppu::OWeakObject* >(pIndicator), css::uno::UNO_QUERY_THROW); + + return xIndicator; +} + +//----------------------------------------------- +void SAL_CALL StatusIndicatorFactory::update() + throw(css::uno::RuntimeException) +{ + // SAFE -> ---------------------------------- + WriteGuard aWriteLock(m_aLock); + m_bAllowReschedule = sal_True; + aWriteLock.unlock(); + // <- SAFE ---------------------------------- +} + +//----------------------------------------------- +void StatusIndicatorFactory::start(const css::uno::Reference< css::task::XStatusIndicator >& xChild, + const ::rtl::OUString& sText , + sal_Int32 nRange) +{ + // SAFE -> ---------------------------------- + WriteGuard aWriteLock(m_aLock); + + // create new info structure for this child or move it to the front of our stack + IndicatorStack::iterator pItem = ::std::find(m_aStack.begin(), m_aStack.end(), xChild); + if (pItem != m_aStack.end()) + m_aStack.erase(pItem); + IndicatorInfo aInfo(xChild, sText, nRange); + m_aStack.push_back (aInfo ); + + m_xActiveChild = xChild; + css::uno::Reference< css::task::XStatusIndicator > xProgress = m_xProgress; + + aWriteLock.unlock(); + // <- SAFE ---------------------------------- + + implts_makeParentVisibleIfAllowed(); + + if (xProgress.is()) + xProgress->start(sText, nRange); + + impl_startWakeUpThread(); + impl_reschedule(sal_True); +} + +//----------------------------------------------- +void StatusIndicatorFactory::reset(const css::uno::Reference< css::task::XStatusIndicator >& xChild) +{ + // SAFE -> ---------------------------------- + ReadGuard aReadLock(m_aLock); + + // reset the internal info structure related to this child + IndicatorStack::iterator pItem = ::std::find(m_aStack.begin(), m_aStack.end(), xChild); + if (pItem != m_aStack.end()) + { + pItem->m_nValue = 0; + pItem->m_sText = ::rtl::OUString(); + } + + css::uno::Reference< css::task::XStatusIndicator > xActive = m_xActiveChild; + css::uno::Reference< css::task::XStatusIndicator > xProgress = m_xProgress; + + aReadLock.unlock(); + // <- SAFE ---------------------------------- + + // not the top most child => dont change UI + // But dont forget Reschedule! + if ( + (xChild == xActive) && + (xProgress.is() ) + ) + xProgress->reset(); + + impl_reschedule(sal_True); +} + +//----------------------------------------------- +void StatusIndicatorFactory::end(const css::uno::Reference< css::task::XStatusIndicator >& xChild) +{ + // SAFE -> ---------------------------------- + WriteGuard aWriteLock(m_aLock); + + // remove this child from our stack + IndicatorStack::iterator pItem = ::std::find(m_aStack.begin(), m_aStack.end(), xChild); + if (pItem != m_aStack.end()) + m_aStack.erase(pItem); + + // activate next child ... or finish the progress if there is no further one. + m_xActiveChild.clear(); + ::rtl::OUString sText; + sal_Int32 nValue = 0; + IndicatorStack::reverse_iterator pNext = m_aStack.rbegin(); + if (pNext != m_aStack.rend()) + { + m_xActiveChild = pNext->m_xIndicator; + sText = pNext->m_sText; + nValue = pNext->m_nValue; + } + + css::uno::Reference< css::task::XStatusIndicator > xActive = m_xActiveChild; + css::uno::Reference< css::task::XStatusIndicator > xProgress = m_xProgress; + + aWriteLock.unlock(); + // <- SAFE ---------------------------------- + + if (xActive.is()) + { + // There is at least one further child indicator. + // Actualize our progress, so it shows these values from now. + if (xProgress.is()) + { + xProgress->setText (sText ); + xProgress->setValue(nValue); + } + } + else + { + // Our stack is empty. No further child exists. + // Se we must "end" our progress realy + if (xProgress.is()) + xProgress->end(); + // Now hide the progress bar again. + impl_hideProgress(); + + impl_stopWakeUpThread(); + } + + impl_reschedule(sal_True); +} + +//----------------------------------------------- +void StatusIndicatorFactory::setText(const css::uno::Reference< css::task::XStatusIndicator >& xChild, + const ::rtl::OUString& sText ) +{ + // SAFE -> ---------------------------------- + WriteGuard aWriteLock(m_aLock); + + IndicatorStack::iterator pItem = ::std::find(m_aStack.begin(), m_aStack.end(), xChild); + if (pItem != m_aStack.end()) + pItem->m_sText = sText; + + css::uno::Reference< css::task::XStatusIndicator > xActive = m_xActiveChild; + css::uno::Reference< css::task::XStatusIndicator > xProgress = m_xProgress; + + aWriteLock.unlock(); + // SAFE -> ---------------------------------- + + // paint only the top most indicator + // but dont forget to Reschedule! + if ( + (xChild == xActive) && + (xProgress.is() ) + ) + { + xProgress->setText(sText); + } + + impl_reschedule(sal_True); +} + +//----------------------------------------------- +void StatusIndicatorFactory::setValue( const css::uno::Reference< css::task::XStatusIndicator >& xChild , + sal_Int32 nValue ) +{ + // SAFE -> ---------------------------------- + WriteGuard aWriteLock(m_aLock); + + sal_Int32 nOldValue = 0; + IndicatorStack::iterator pItem = ::std::find(m_aStack.begin(), m_aStack.end(), xChild); + if (pItem != m_aStack.end()) + { + nOldValue = pItem->m_nValue; + pItem->m_nValue = nValue; + } + + css::uno::Reference< css::task::XStatusIndicator > xActive = m_xActiveChild; + css::uno::Reference< css::task::XStatusIndicator > xProgress = m_xProgress; + + aWriteLock.unlock(); + // SAFE -> ---------------------------------- + + if ( + (xChild == xActive) && + (nOldValue != nValue ) && + (xProgress.is() ) + ) + { + xProgress->setValue(nValue); + } + + impl_reschedule(sal_False); +} + +//----------------------------------------------- +void StatusIndicatorFactory::implts_makeParentVisibleIfAllowed() +{ + // SAFE -> ---------------------------------- + ReadGuard aReadLock(m_aLock); + + if (!m_bAllowParentShow) + return; + + css::uno::Reference< css::frame::XFrame > xFrame (m_xFrame.get() , css::uno::UNO_QUERY); + css::uno::Reference< css::awt::XWindow > xPluggWindow(m_xPluggWindow.get(), css::uno::UNO_QUERY); + css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR( m_xSMGR.get(), css::uno::UNO_QUERY); + + aReadLock.unlock(); + // <- SAFE ---------------------------------- + + css::uno::Reference< css::awt::XWindow > xParentWindow; + if (xFrame.is()) + xParentWindow = xFrame->getContainerWindow(); + else + xParentWindow = xPluggWindow; + + // dont disturb user in case he put the loading document into the background! + // Supress any setVisible() or toFront() call in case the initial show was + // already made. + css::uno::Reference< css::awt::XWindow2 > xVisibleCheck(xParentWindow, css::uno::UNO_QUERY); + sal_Bool bIsVisible = sal_False; + if (xVisibleCheck.is()) + bIsVisible = xVisibleCheck->isVisible(); + + if (bIsVisible) + { + impl_showProgress(); + return; + } + + // Check if the layout manager has been set to invisible state. It this case we are also + // not allowed to set the frame visible! + css::uno::Reference< css::beans::XPropertySet > xPropSet(xFrame, css::uno::UNO_QUERY); + if (xPropSet.is()) + { + css::uno::Reference< css::frame::XLayoutManager > xLayoutManager; + xPropSet->getPropertyValue(FRAME_PROPNAME_LAYOUTMANAGER) >>= xLayoutManager; + if (xLayoutManager.is()) + { + if ( !xLayoutManager->isVisible() ) + return; + } + } + + // Ok the window should be made visible ... becuase it isnt currently visible. + // BUT ..! + // We need a Hack for our applications: They get her progress from the frame directly + // on saving documents. Because there is no progress set on the MediaDescriptor. + // But that's wrong. In case the document was opened hidden, they shouldnt use any progress .-( + // They only possible workaround: dont show the parent window here, if the document was opened hidden. + sal_Bool bHiddenDoc = sal_False; + if (xFrame.is()) + { + css::uno::Reference< css::frame::XController > xController; + css::uno::Reference< css::frame::XModel > xModel ; + xController = xFrame->getController(); + if (xController.is()) + xModel = xController->getModel(); + if (xModel.is()) + { + ::comphelper::MediaDescriptor lDocArgs(xModel->getArgs()); + bHiddenDoc = lDocArgs.getUnpackedValueOrDefault( + ::comphelper::MediaDescriptor::PROP_HIDDEN(), + (sal_Bool)sal_False); + } + } + + if (bHiddenDoc) + return; + + // OK: The document was not opened in hidden mode ... + // and the window isnt already visible. + // Show it and bring it to front. + // But before we have to be sure, that our internal used helper progress + // is visible too. + impl_showProgress(); + + SolarMutexGuard aSolarGuard; + Window* pWindow = VCLUnoHelper::GetWindow(xParentWindow); + if ( pWindow ) + { + bool bForceFrontAndFocus(false); + ::comphelper::ConfigurationHelper::readDirectKey( + xSMGR, + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Office.Common/View")), + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("NewDocumentHandling")), + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ForceFocusAndToFront")), + ::comphelper::ConfigurationHelper::E_READONLY) >>= bForceFrontAndFocus; + + pWindow->Show(sal_True, bForceFrontAndFocus ? SHOW_FOREGROUNDTASK : 0 ); + } + + /* + #i75167# dont disturb window manager handling .-) + css::uno::Reference< css::awt::XTopWindow > xParentWindowTop(xParentWindow, css::uno::UNO_QUERY); + if (xParentWindowTop.is()) + xParentWindowTop->toFront(); + */ +} + +//----------------------------------------------- +void StatusIndicatorFactory::impl_createProgress() +{ + // SAFE -> ---------------------------------- + ReadGuard aReadLock(m_aLock); + + css::uno::Reference< css::frame::XFrame > xFrame (m_xFrame.get() , css::uno::UNO_QUERY); + css::uno::Reference< css::awt::XWindow > xWindow(m_xPluggWindow.get(), css::uno::UNO_QUERY); + css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR; + + aReadLock.lock(); + // <- SAFE ---------------------------------- + + css::uno::Reference< css::task::XStatusIndicator > xProgress; + + if (xWindow.is()) + { + // use vcl based progress implementation in plugged mode + VCLStatusIndicator* pVCLProgress = new VCLStatusIndicator(xSMGR, xWindow); + xProgress = css::uno::Reference< css::task::XStatusIndicator >(static_cast< css::task::XStatusIndicator* >(pVCLProgress), css::uno::UNO_QUERY); + } + else + if (xFrame.is()) + { + // use frame layouted progress implementation + css::uno::Reference< css::beans::XPropertySet > xPropSet(xFrame, css::uno::UNO_QUERY); + if (xPropSet.is()) + { + css::uno::Reference< css::frame::XLayoutManager > xLayoutManager; + xPropSet->getPropertyValue(FRAME_PROPNAME_LAYOUTMANAGER) >>= xLayoutManager; + if (xLayoutManager.is()) + { + xLayoutManager->lock(); + xLayoutManager->createElement( PROGRESS_RESOURCE ); + xLayoutManager->hideElement( PROGRESS_RESOURCE ); + + css::uno::Reference< css::ui::XUIElement > xProgressBar = xLayoutManager->getElement(PROGRESS_RESOURCE); + if (xProgressBar.is()) + xProgress = css::uno::Reference< css::task::XStatusIndicator >(xProgressBar->getRealInterface(), css::uno::UNO_QUERY); + xLayoutManager->unlock(); + } + } + } + + // SAFE -> ---------------------------------- + WriteGuard aWriteLock(m_aLock); + m_xProgress = xProgress; + aWriteLock.lock(); + // <- SAFE ---------------------------------- +} + +//----------------------------------------------- +void StatusIndicatorFactory::impl_showProgress() +{ + // SAFE -> ---------------------------------- + ReadGuard aReadLock(m_aLock); + + css::uno::Reference< css::frame::XFrame > xFrame (m_xFrame.get() , css::uno::UNO_QUERY); + css::uno::Reference< css::awt::XWindow > xWindow(m_xPluggWindow.get(), css::uno::UNO_QUERY); + css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR; + + aReadLock.lock(); + // <- SAFE ---------------------------------- + + css::uno::Reference< css::task::XStatusIndicator > xProgress; + + if (xFrame.is()) + { + // use frame layouted progress implementation + css::uno::Reference< css::beans::XPropertySet > xPropSet(xFrame, css::uno::UNO_QUERY); + if (xPropSet.is()) + { + css::uno::Reference< css::frame::XLayoutManager > xLayoutManager; + xPropSet->getPropertyValue(FRAME_PROPNAME_LAYOUTMANAGER) >>= xLayoutManager; + if (xLayoutManager.is()) + { + // Be sure that we have always a progress. It can be that our frame + // was recycled and therefore the progress was destroyed! + // CreateElement does nothing if there is already a valid progress. + xLayoutManager->createElement( PROGRESS_RESOURCE ); + xLayoutManager->showElement( PROGRESS_RESOURCE ); + + css::uno::Reference< css::ui::XUIElement > xProgressBar = xLayoutManager->getElement(PROGRESS_RESOURCE); + if (xProgressBar.is()) + xProgress = css::uno::Reference< css::task::XStatusIndicator >(xProgressBar->getRealInterface(), css::uno::UNO_QUERY); + } + } + + // SAFE -> ---------------------------------- + WriteGuard aWriteLock(m_aLock); + m_xProgress = xProgress; + aWriteLock.lock(); + // <- SAFE ---------------------------------- + } +} + +//----------------------------------------------- +void StatusIndicatorFactory::impl_hideProgress() +{ + // SAFE -> ---------------------------------- + ReadGuard aReadLock(m_aLock); + + css::uno::Reference< css::frame::XFrame > xFrame (m_xFrame.get() , css::uno::UNO_QUERY); + css::uno::Reference< css::awt::XWindow > xWindow(m_xPluggWindow.get(), css::uno::UNO_QUERY); + css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR; + + aReadLock.lock(); + // <- SAFE ---------------------------------- + + if (xFrame.is()) + { + // use frame layouted progress implementation + css::uno::Reference< css::beans::XPropertySet > xPropSet(xFrame, css::uno::UNO_QUERY); + if (xPropSet.is()) + { + css::uno::Reference< css::frame::XLayoutManager > xLayoutManager; + xPropSet->getPropertyValue(FRAME_PROPNAME_LAYOUTMANAGER) >>= xLayoutManager; + if (xLayoutManager.is()) + xLayoutManager->hideElement( PROGRESS_RESOURCE ); + } + } +} + +//----------------------------------------------- +void StatusIndicatorFactory::impl_reschedule(sal_Bool bForce) +{ + // SAFE -> + ReadGuard aReadLock(m_aLock); + if (m_bDisableReschedule) + return; + aReadLock.unlock(); + // <- SAFE + + sal_Bool bReschedule = bForce; + if (!bReschedule) + { + // SAFE -> + WriteGuard aWriteLock(m_aLock); + bReschedule = m_bAllowReschedule; + m_bAllowReschedule = sal_False; + aWriteLock.unlock(); + // <- SAFE + } + + if (!bReschedule) + return; + + // SAFE -> + WriteGuard aGlobalLock(LockHelper::getGlobalLock()); + + if (m_nInReschedule == 0) + { + ++m_nInReschedule; + aGlobalLock.unlock(); + // <- SAFE + + Application::Reschedule(true); + + // SAFE -> + aGlobalLock.lock(); + --m_nInReschedule; + } +} + +//----------------------------------------------- +void StatusIndicatorFactory::impl_startWakeUpThread() +{ + // SAFE -> + WriteGuard aWriteLock(m_aLock); + + if (m_bDisableReschedule) + return; + + if (!m_pWakeUp) + { + m_pWakeUp = new WakeUpThread(this); + m_pWakeUp->create(); + } + aWriteLock.unlock(); + // <- SAFE +} + +//----------------------------------------------- +void StatusIndicatorFactory::impl_stopWakeUpThread() +{ + // SAFE -> + WriteGuard aWriteLock(m_aLock); + if (m_pWakeUp) + { + // Thread kill itself after terminate()! + m_pWakeUp->terminate(); + m_pWakeUp = 0; + } + aWriteLock.unlock(); + // <- SAFE +} + +} // namespace framework + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/framework/source/helper/tagwindowasmodified.cxx b/framework/source/helper/tagwindowasmodified.cxx new file mode 100644 index 000000000000..1ce45a0046ad --- /dev/null +++ b/framework/source/helper/tagwindowasmodified.cxx @@ -0,0 +1,253 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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_framework.hxx" + +//_________________________________________________________________________________________________________________ +// my own includes +//_________________________________________________________________________________________________________________ +#include <helper/tagwindowasmodified.hxx> +#include <pattern/window.hxx> +#include <threadhelp/writeguard.hxx> +#include <threadhelp/readguard.hxx> +#include <macros/generic.hxx> +#include <services.h> + +//_________________________________________________________________________________________________________________ +// interface includes +//_________________________________________________________________________________________________________________ +#include <com/sun/star/awt/XWindow.hpp> + +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/util/XModifyBroadcaster.hpp> +#include <com/sun/star/util/XModifiable.hpp> +#include <com/sun/star/frame/FrameAction.hpp> + +//_________________________________________________________________________________________________________________ +// other includes +//_________________________________________________________________________________________________________________ + +#include <toolkit/unohlp.hxx> +#include <vcl/window.hxx> +#include <vcl/syswin.hxx> +#include <vcl/svapp.hxx> +#include <vcl/wrkwin.hxx> +#include <vcl/wintypes.hxx> + +//_________________________________________________________________________________________________________________ +// namespace + +namespace framework{ + +//_________________________________________________________________________________________________________________ +// definitions + +//***************************************************************************************************************** +// XInterface, XTypeProvider + +DEFINE_XINTERFACE_4(TagWindowAsModified , + OWeakObject , + DIRECT_INTERFACE (css::lang::XTypeProvider ), + DIRECT_INTERFACE (css::lang::XInitialization ), + DIRECT_INTERFACE (css::util::XModifyListener ), + DERIVED_INTERFACE(css::lang::XEventListener, css::util::XModifyListener)) + +DEFINE_XTYPEPROVIDER_4(TagWindowAsModified , + css::lang::XTypeProvider , + css::lang::XInitialization , + css::util::XModifyListener , + css::lang::XEventListener ) + +//***************************************************************************************************************** +TagWindowAsModified::TagWindowAsModified(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR) + : ThreadHelpBase (&Application::GetSolarMutex()) + , m_xSMGR (xSMGR ) +{ +} + +//***************************************************************************************************************** +TagWindowAsModified::~TagWindowAsModified() +{ +} + +//***************************************************************************************************************** +void SAL_CALL TagWindowAsModified::initialize(const css::uno::Sequence< css::uno::Any >& lArguments) + throw(css::uno::Exception , + css::uno::RuntimeException) +{ + css::uno::Reference< css::frame::XFrame > xFrame; + + if (lArguments.getLength() > 0) + lArguments[0] >>= xFrame; + + if ( ! xFrame.is ()) + return; + + // SAFE -> ---------------------------------- + WriteGuard aWriteLock(m_aLock); + m_xFrame = xFrame ; + aWriteLock.unlock(); + // <- SAFE ---------------------------------- + + xFrame->addFrameActionListener(this); + impl_update (xFrame); +} + +//***************************************************************************************************************** +void SAL_CALL TagWindowAsModified::modified(const css::lang::EventObject& aEvent) + throw(css::uno::RuntimeException) +{ + // SAFE -> ---------------------------------- + ReadGuard aReadLock(m_aLock); + + css::uno::Reference< css::util::XModifiable > xModel (m_xModel.get (), css::uno::UNO_QUERY); + css::uno::Reference< css::awt::XWindow > xWindow(m_xWindow.get(), css::uno::UNO_QUERY); + if ( + ( ! xModel.is () ) || + ( ! xWindow.is () ) || + (aEvent.Source != xModel) + ) + return; + + aReadLock.unlock(); + // <- SAFE ---------------------------------- + + ::sal_Bool bModified = xModel->isModified (); + + // SYNCHRONIZED -> + SolarMutexGuard aSolarGuard; + + Window* pWindow = VCLUnoHelper::GetWindow(xWindow); + if ( ! pWindow) + return; + + sal_Bool bSystemWindow = pWindow->IsSystemWindow(); + sal_Bool bWorkWindow = (pWindow->GetType() == WINDOW_WORKWINDOW); + if (!bSystemWindow && !bWorkWindow) + return; + + if (bModified) + pWindow->SetExtendedStyle(WB_EXT_DOCMODIFIED); + else + pWindow->SetExtendedStyle( ! WB_EXT_DOCMODIFIED); + // <- SYNCHRONIZED +} + +//***************************************************************************************************************** +void SAL_CALL TagWindowAsModified::frameAction(const css::frame::FrameActionEvent& aEvent) + throw(css::uno::RuntimeException) +{ + if ( + (aEvent.Action != css::frame::FrameAction_COMPONENT_REATTACHED) && + (aEvent.Action != css::frame::FrameAction_COMPONENT_ATTACHED ) + ) + return; + + // SAFE -> ---------------------------------- + WriteGuard aWriteLock(m_aLock); + + css::uno::Reference< css::frame::XFrame > xFrame(m_xFrame.get(), css::uno::UNO_QUERY); + if ( + ( ! xFrame.is () ) || + (aEvent.Source != xFrame) + ) + return; + + aWriteLock.unlock(); + // <- SAFE ---------------------------------- + + impl_update (xFrame); +} + +//***************************************************************************************************************** +void SAL_CALL TagWindowAsModified::disposing(const css::lang::EventObject& aEvent) + throw(css::uno::RuntimeException) +{ + // SAFE -> ---------------------------------- + WriteGuard aWriteLock(m_aLock); + + css::uno::Reference< css::frame::XFrame > xFrame(m_xFrame.get(), css::uno::UNO_QUERY); + if ( + (xFrame.is () ) && + (aEvent.Source == xFrame) + ) + { + m_xFrame = css::uno::Reference< css::frame::XFrame >(); + return; + } + + css::uno::Reference< css::frame::XModel > xModel(m_xModel.get(), css::uno::UNO_QUERY); + if ( + (xModel.is () ) && + (aEvent.Source == xModel) + ) + { + m_xModel = css::uno::Reference< css::frame::XModel >(); + return; + } + + aWriteLock.unlock(); + // <- SAFE ---------------------------------- +} + +//***************************************************************************************************************** +void TagWindowAsModified::impl_update (const css::uno::Reference< css::frame::XFrame >& xFrame) +{ + if ( ! xFrame.is ()) + return; + + css::uno::Reference< css::awt::XWindow > xWindow = xFrame->getContainerWindow (); + css::uno::Reference< css::frame::XController > xController = xFrame->getController (); + css::uno::Reference< css::frame::XModel > xModel ; + if (xController.is ()) + xModel = xController->getModel (); + + if ( + ( ! xWindow.is ()) || + ( ! xModel.is ()) + ) + return; + + // SAFE -> ---------------------------------- + WriteGuard aWriteLock(m_aLock); + // Note: frame was set as member outside ! we have to refresh connections + // regarding window and model only here. + m_xWindow = xWindow; + m_xModel = xModel ; + aWriteLock.unlock(); + // <- SAFE ---------------------------------- + + css::uno::Reference< css::util::XModifyBroadcaster > xModifiable(xModel, css::uno::UNO_QUERY); + if (xModifiable.is ()) + xModifiable->addModifyListener (this); +} + +} // namespace framework + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/framework/source/helper/titlebarupdate.cxx b/framework/source/helper/titlebarupdate.cxx new file mode 100644 index 000000000000..6cb4ed5adcc2 --- /dev/null +++ b/framework/source/helper/titlebarupdate.cxx @@ -0,0 +1,450 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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_framework.hxx" + +#include <helper/titlebarupdate.hxx> + +//_________________________________________________________________________________________________________________ +// my own includes +//_________________________________________________________________________________________________________________ + +#include <pattern/window.hxx> + +#include <threadhelp/writeguard.hxx> + +#include <threadhelp/readguard.hxx> + +#include <macros/generic.hxx> + +#include <services.h> + +#include <properties.h> + +//_________________________________________________________________________________________________________________ +// interface includes +//_________________________________________________________________________________________________________________ + +#include <com/sun/star/awt/XWindow.hpp> + +#include <com/sun/star/lang/XServiceInfo.hpp> + +#include <com/sun/star/lang/IllegalArgumentException.hpp> + +#include <com/sun/star/frame/XModuleManager.hpp> + +#include <com/sun/star/container/XNameAccess.hpp> + +#include <com/sun/star/beans/XPropertySet.hpp> + +#include <com/sun/star/beans/XMaterialHolder.hpp> + +#include <com/sun/star/frame/XTitleChangeBroadcaster.hpp> + +#include <com/sun/star/beans/NamedValue.hpp> + +//_________________________________________________________________________________________________________________ +// other includes +//_________________________________________________________________________________________________________________ + +#include <comphelper/sequenceashashmap.hxx> + +#include <unotools/configmgr.hxx> + +#include <unotools/bootstrap.hxx> + +#include <vcl/window.hxx> + +#include <vcl/syswin.hxx> + +#include <toolkit/unohlp.hxx> + +#include <vcl/svapp.hxx> + +#include <vcl/wrkwin.hxx> + +//_________________________________________________________________________________________________________________ +// namespace + +namespace framework{ + +//_________________________________________________________________________________________________________________ +// const + +static const ::sal_Int32 INVALID_ICON_ID = -1; +static const ::sal_Int32 DEFAULT_ICON_ID = 0; + +//_________________________________________________________________________________________________________________ +// definitions + +//***************************************************************************************************************** +// XInterface, XTypeProvider + +DEFINE_XINTERFACE_5(TitleBarUpdate , + OWeakObject , + DIRECT_INTERFACE (css::lang::XTypeProvider ), + DIRECT_INTERFACE (css::lang::XInitialization ), + DIRECT_INTERFACE (css::frame::XFrameActionListener ), + DIRECT_INTERFACE (css::frame::XTitleChangeListener ), + DERIVED_INTERFACE(css::lang::XEventListener,css::frame::XFrameActionListener)) + +DEFINE_XTYPEPROVIDER_5(TitleBarUpdate , + css::lang::XTypeProvider , + css::lang::XInitialization , + css::frame::XFrameActionListener, + css::frame::XTitleChangeListener, + css::lang::XEventListener ) + +//***************************************************************************************************************** +TitleBarUpdate::TitleBarUpdate(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR) + : ThreadHelpBase (&Application::GetSolarMutex()) + , m_xSMGR (xSMGR ) + , m_xFrame ( ) +{ +} + +//***************************************************************************************************************** +TitleBarUpdate::~TitleBarUpdate() +{ +} + +//***************************************************************************************************************** +void SAL_CALL TitleBarUpdate::initialize(const css::uno::Sequence< css::uno::Any >& lArguments) + throw(css::uno::Exception , + css::uno::RuntimeException) +{ + // check arguments + css::uno::Reference< css::frame::XFrame > xFrame; + if (lArguments.getLength() < 1) + throw css::lang::IllegalArgumentException( + DECLARE_ASCII("Empty argument list!"), + static_cast< ::cppu::OWeakObject* >(this), + 1); + + lArguments[0] >>= xFrame; + if (!xFrame.is()) + throw css::lang::IllegalArgumentException( + DECLARE_ASCII("No valid frame specified!"), + static_cast< ::cppu::OWeakObject* >(this), + 1); + + // SYNCHRONIZED -> + WriteGuard aWriteLock(m_aLock); + // hold the frame as weak reference(!) so it can die everytimes :-) + m_xFrame = xFrame; + aWriteLock.unlock(); + // <- SYNCHRONIZED + + // start listening + xFrame->addFrameActionListener(this); + + css::uno::Reference< css::frame::XTitleChangeBroadcaster > xBroadcaster(xFrame, css::uno::UNO_QUERY); + if (xBroadcaster.is ()) + xBroadcaster->addTitleChangeListener (this); +} + +//***************************************************************************************************************** +void SAL_CALL TitleBarUpdate::frameAction(const css::frame::FrameActionEvent& aEvent) + throw(css::uno::RuntimeException) +{ + // we are interested on events only, which must trigger a title bar update + // because component was changed. + if ( + (aEvent.Action == css::frame::FrameAction_COMPONENT_ATTACHED ) || + (aEvent.Action == css::frame::FrameAction_COMPONENT_REATTACHED) || + (aEvent.Action == css::frame::FrameAction_COMPONENT_DETACHING ) + ) + { + impl_forceUpdate (); + } +} + +//***************************************************************************************************************** +void SAL_CALL TitleBarUpdate::titleChanged(const css::frame::TitleChangedEvent& /* aEvent */) + throw (css::uno::RuntimeException) +{ + impl_forceUpdate (); +} + +//***************************************************************************************************************** +void SAL_CALL TitleBarUpdate::disposing(const css::lang::EventObject&) + throw(css::uno::RuntimeException) +{ + // nothing todo here - because we hold the frame as weak reference only +} + +//http://live.gnome.org/GnomeShell/ApplicationBased +//See http://msdn.microsoft.com/en-us/library/dd378459(v=VS.85).aspx for future +//Windows 7 equivalent support +void TitleBarUpdate::impl_updateApplicationID(const css::uno::Reference< css::frame::XFrame >& xFrame) +{ + css::uno::Reference< css::awt::XWindow > xWindow = xFrame->getContainerWindow (); + if ( ! xWindow.is() ) + return; + + ::rtl::OUString sApplicationID; + try + { + ::rtl::OUString aProductName; + ::utl::ConfigManager::GetDirectConfigProperty(::utl::ConfigManager::PRODUCTNAME) >>= aProductName; + + // SYNCHRONIZED -> + ReadGuard aReadLock(m_aLock); + css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR; + aReadLock.unlock(); + // <- SYNCHRONIZED + + css::uno::Reference< css::frame::XModuleManager > xModuleManager( + xSMGR->createInstance(SERVICENAME_MODULEMANAGER), + css::uno::UNO_QUERY_THROW); + + css::uno::Reference< css::container::XNameAccess > xConfig( + xModuleManager, + css::uno::UNO_QUERY_THROW); + + rtl::OUString aModuleId = xModuleManager->identify(xFrame); + rtl::OUString sDesktopName; + + if ( aModuleId.equalsAscii( "com.sun.star.text.TextDocument" ) || + aModuleId.equalsAscii( "com.sun.star.text.GlobalDocument" ) || + aModuleId.equalsAscii( "com.sun.star.text.WebDocument" ) || + aModuleId.equalsAscii( "com.sun.star.xforms.XMLFormDocument" ) ) + sDesktopName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("writer")); + else if ( aModuleId.equalsAscii( "com.sun.star.sheet.SpreadsheetDocument" ) ) + sDesktopName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("calc")); + else if ( aModuleId.equalsAscii( "com.sun.star.presentation.PresentationDocument" ) ) + sDesktopName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("impress")); + else if ( aModuleId.equalsAscii( "com.sun.star.drawing.DrawingDocument" ) ) + sDesktopName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("draw")); + else if ( aModuleId.equalsAscii( "com.sun.star.formula.FormulaProperties" ) ) + sDesktopName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("math")); + else if ( aModuleId.equalsAscii( "com.sun.star.sdb.DatabaseDocument" ) || + aModuleId.equalsAscii( "com.sun.star.sdb.OfficeDatabaseDocument" ) || + aModuleId.equalsAscii( "com.sun.star.sdb.RelationDesign" ) || + aModuleId.equalsAscii( "com.sun.star.sdb.QueryDesign" ) || + aModuleId.equalsAscii( "com.sun.star.sdb.TableDesign" ) || + aModuleId.equalsAscii( "com.sun.star.sdb.DataSourceBrowser" ) ) + sDesktopName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("base")); + else if ( aModuleId.equalsAscii( "com.sun.star.frame.StartModule" ) ) + sDesktopName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("startcenter")); + else + sDesktopName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("startcenter")); + sApplicationID = aProductName.toAsciiLowerCase(); + sApplicationID += ::rtl::OUString(sal_Unicode('-')); + sApplicationID += sDesktopName; + } + catch(const css::uno::Exception&) + { + } + + // VCL SYNCHRONIZED -> + SolarMutexGuard aSolarGuard; + + Window* pWindow = (VCLUnoHelper::GetWindow( xWindow )); + if ( + ( pWindow ) && + ( pWindow->GetType() == WINDOW_WORKWINDOW ) + ) + { + WorkWindow* pWorkWindow = (WorkWindow*)pWindow; +#ifdef COPY_TO_TITLE_FOR_DEBUG + pWorkWindow->SetText( sApplicationID ); +#endif + pWorkWindow->SetApplicationID( sApplicationID ); + } + // <- VCL SYNCHRONIZED +} + + +//***************************************************************************************************************** +::sal_Bool TitleBarUpdate::implst_getModuleInfo(const css::uno::Reference< css::frame::XFrame >& xFrame, + TModuleInfo& rInfo ) +{ + if ( ! xFrame.is ()) + return sal_False; + + // SYNCHRONIZED -> + ReadGuard aReadLock(m_aLock); + css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR; + aReadLock.unlock(); + // <- SYNCHRONIZED + + try + { + css::uno::Reference< css::frame::XModuleManager > xModuleManager( + xSMGR->createInstance(SERVICENAME_MODULEMANAGER), + css::uno::UNO_QUERY_THROW); + + css::uno::Reference< css::container::XNameAccess > xConfig( + xModuleManager, + css::uno::UNO_QUERY_THROW); + + rInfo.sID = xModuleManager->identify(xFrame); + ::comphelper::SequenceAsHashMap lProps = xConfig->getByName (rInfo.sID); + + rInfo.sUIName = lProps.getUnpackedValueOrDefault (OFFICEFACTORY_PROPNAME_UINAME, ::rtl::OUString()); + rInfo.nIcon = lProps.getUnpackedValueOrDefault (OFFICEFACTORY_PROPNAME_ICON , INVALID_ICON_ID ); + + // Note: If we could retrieve a module id ... everything is OK. + // UIName and Icon ID are optional values ! + ::sal_Bool bSuccess = (rInfo.sID.getLength () > 0); + return bSuccess; + } + catch(const css::uno::Exception&) + {} + + return sal_False; +} + +//***************************************************************************************************************** +void TitleBarUpdate::impl_forceUpdate() +{ + // SYNCHRONIZED -> + ReadGuard aReadLock(m_aLock); + css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR ; + css::uno::Reference< css::frame::XFrame > xFrame(m_xFrame.get(), css::uno::UNO_QUERY); + aReadLock.unlock(); + // <- SYNCHRONIZED + + // frame already gone ? We hold it weak only ... + if ( ! xFrame.is()) + return; + + // no window -> no chance to set/update title and icon + css::uno::Reference< css::awt::XWindow > xWindow = xFrame->getContainerWindow(); + if ( ! xWindow.is()) + return; + + impl_updateIcon (xFrame); + impl_updateTitle (xFrame); +#if defined(UNX) && !defined(MACOSX) + impl_updateApplicationID (xFrame); +#endif +} + +//***************************************************************************************************************** +void TitleBarUpdate::impl_updateIcon(const css::uno::Reference< css::frame::XFrame >& xFrame) +{ + css::uno::Reference< css::frame::XController > xController = xFrame->getController (); + css::uno::Reference< css::awt::XWindow > xWindow = xFrame->getContainerWindow (); + + if ( + ( ! xController.is() ) || + ( ! xWindow.is() ) + ) + return; + + // a) set default value to an invalid one. So we can start further searches for right icon id, if + // first steps failed! + sal_Int32 nIcon = INVALID_ICON_ID; + + // b) try to find information on controller property set directly + // Don't forget to catch possible exceptions - because these property is an optional one! + css::uno::Reference< css::beans::XPropertySet > xSet( xController, css::uno::UNO_QUERY ); + if ( xSet.is() ) + { + try + { + xSet->getPropertyValue( DECLARE_ASCII("IconId") ) >>= nIcon; + } + catch(const css::uno::Exception&) + {} + } + + // c) if b) failed ... identify the used module and retrieve set icon from module config. + // Tirck :-) Module was already specified outside and aInfo contains all needed informations. + if ( nIcon == INVALID_ICON_ID ) + { + TModuleInfo aInfo; + if (implst_getModuleInfo(xFrame, aInfo)) + nIcon = aInfo.nIcon; + } + + // d) if all steps failed - use fallback :-) + // ... means using the global staroffice icon + if( nIcon == INVALID_ICON_ID ) + nIcon = DEFAULT_ICON_ID; + + // e) set icon on container window now + // Don't forget SolarMutex! We use vcl directly :-( + // Check window pointer for right WorkWindow class too!!! + + // VCL SYNCHRONIZED -> + SolarMutexGuard aSolarGuard; + + Window* pWindow = (VCLUnoHelper::GetWindow( xWindow )); + if ( + ( pWindow ) && + ( pWindow->GetType() == WINDOW_WORKWINDOW ) + ) + { + WorkWindow* pWorkWindow = (WorkWindow*)pWindow; + pWorkWindow->SetIcon( (sal_uInt16)nIcon ); + + css::uno::Reference< css::frame::XModel > xModel = xController->getModel(); + rtl::OUString aURL; + if( xModel.is() ) + aURL = xModel->getURL(); + pWorkWindow->SetRepresentedURL( aURL ); + } + // <- VCL SYNCHRONIZED +} + +//***************************************************************************************************************** +void TitleBarUpdate::impl_updateTitle(const css::uno::Reference< css::frame::XFrame >& xFrame) +{ + // no window ... no chance to set any title -> return + css::uno::Reference< css::awt::XWindow > xWindow = xFrame->getContainerWindow (); + if ( ! xWindow.is() ) + return; + + css::uno::Reference< css::frame::XTitle > xTitle(xFrame, css::uno::UNO_QUERY); + if ( ! xTitle.is() ) + return; + + const ::rtl::OUString sTitle = xTitle->getTitle (); + + // VCL SYNCHRONIZED -> + SolarMutexGuard aSolarGuard; + + Window* pWindow = (VCLUnoHelper::GetWindow( xWindow )); + if ( + ( pWindow ) && + ( pWindow->GetType() == WINDOW_WORKWINDOW ) + ) + { + WorkWindow* pWorkWindow = (WorkWindow*)pWindow; + pWorkWindow->SetText( sTitle ); + } + // <- VCL SYNCHRONIZED +} + +} // namespace framework + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/framework/source/helper/titlehelper.cxx b/framework/source/helper/titlehelper.cxx new file mode 100644 index 000000000000..e85648383a8e --- /dev/null +++ b/framework/source/helper/titlehelper.cxx @@ -0,0 +1,730 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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_framework.hxx" + +//_______________________________________________ +// includes + +#include <helper/titlehelper.hxx> +#include <services.h> +#include <properties.h> + +#include <com/sun/star/frame/UntitledNumbersConst.hpp> +#include <com/sun/star/frame/XStorable.hpp> +#include <com/sun/star/frame/XModuleManager.hpp> +#include <com/sun/star/container/XNameAccess.hpp> +#include <com/sun/star/document/XEventBroadcaster.hpp> +#include <com/sun/star/beans/XMaterialHolder.hpp> + +#include <unotools/configmgr.hxx> +#include <unotools/bootstrap.hxx> +#include <comphelper/sequenceashashmap.hxx> +#include <rtl/ustrbuf.hxx> +#include <osl/mutex.hxx> +#include <tools/urlobj.hxx> + +//_______________________________________________ +// namespace + +namespace framework{ + +namespace css = ::com::sun::star; + +//----------------------------------------------- +TitleHelper::TitleHelper(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR) + : ::cppu::BaseMutex () + , m_xSMGR (xSMGR) + , m_xOwner () + , m_xUntitledNumbers() + , m_xSubTitle () + , m_bExternalTitle (sal_False) + , m_sTitle () + , m_nLeasedNumber (css::frame::UntitledNumbersConst::INVALID_NUMBER) + , m_aListener (m_aMutex) +{ +} + +//----------------------------------------------- +TitleHelper::~TitleHelper() +{ +} + +//----------------------------------------------- +void TitleHelper::setOwner(const css::uno::Reference< css::uno::XInterface >& xOwner) +{ + // SYNCHRONIZED -> + ::osl::ResettableMutexGuard aLock(m_aMutex); + + m_xOwner = xOwner; + + aLock.clear (); + // <- SYNCHRONIZED + + css::uno::Reference< css::frame::XModel > xModel(xOwner, css::uno::UNO_QUERY); + if (xModel.is ()) + { + impl_startListeningForModel (xModel); + return; + } + + css::uno::Reference< css::frame::XController > xController(xOwner, css::uno::UNO_QUERY); + if (xController.is ()) + { + impl_startListeningForController (xController); + return; + } + + css::uno::Reference< css::frame::XFrame > xFrame(xOwner, css::uno::UNO_QUERY); + if (xFrame.is ()) + { + impl_startListeningForFrame (xFrame); + return; + } +} + +//----------------------------------------------- +::rtl::OUString SAL_CALL TitleHelper::getTitle() + throw (css::uno::RuntimeException) +{ + // SYNCHRONIZED -> + ::osl::ResettableMutexGuard aLock(m_aMutex); + + // An external title will win always and disable all internal logic about + // creating/using a title value. + // Even an empty string will be accepted as valid title ! + if (m_bExternalTitle) + return m_sTitle; + + // Title seams to be up-to-date. Return it directly. + if (m_sTitle.getLength() > 0) + return m_sTitle; + + // Title seams to be unused till now ... do bootstraping + impl_updateTitle (); + + return m_sTitle; + + // <- SYNCHRONIZED +} + +//----------------------------------------------- +void TitleHelper::connectWithUntitledNumbers (const css::uno::Reference< css::frame::XUntitledNumbers >& xNumbers) +{ + // SYNCHRONIZED -> + ::osl::ResettableMutexGuard aLock(m_aMutex); + + m_xUntitledNumbers = xNumbers; + + // <- SYNCHRONIZED +} + +//----------------------------------------------- +void SAL_CALL TitleHelper::setTitle(const ::rtl::OUString& sTitle) + throw (css::uno::RuntimeException) +{ + // SYNCHRONIZED -> + ::osl::ResettableMutexGuard aLock(m_aMutex); + + m_bExternalTitle = sal_True; + m_sTitle = sTitle; + + aLock.clear (); + // <- SYNCHRONIZED + + impl_sendTitleChangedEvent (); +} + +//----------------------------------------------- +void SAL_CALL TitleHelper::addTitleChangeListener(const css::uno::Reference< css::frame::XTitleChangeListener >& xListener) + throw (css::uno::RuntimeException) +{ + // container is threadsafe by himself + m_aListener.addInterface( ::getCppuType( (const css::uno::Reference< css::frame::XTitleChangeListener >*)NULL ), xListener ); +} + +//----------------------------------------------- +void SAL_CALL TitleHelper::removeTitleChangeListener(const css::uno::Reference< css::frame::XTitleChangeListener >& xListener) + throw (css::uno::RuntimeException) +{ + // container is threadsafe by himself + m_aListener.removeInterface( ::getCppuType( (const css::uno::Reference< css::frame::XTitleChangeListener >*)NULL ), xListener ); +} + +//----------------------------------------------- +void SAL_CALL TitleHelper::titleChanged(const css::frame::TitleChangedEvent& aEvent) + throw (css::uno::RuntimeException) +{ + // SYNCHRONIZED -> + ::osl::ResettableMutexGuard aLock(m_aMutex); + + css::uno::Reference< css::frame::XTitle > xSubTitle(m_xSubTitle.get (), css::uno::UNO_QUERY); + + aLock.clear (); + // <- SYNCHRONIZED + + if (aEvent.Source != xSubTitle) + return; + + impl_updateTitle (); +} + +//----------------------------------------------- +void SAL_CALL TitleHelper::notifyEvent(const css::document::EventObject& aEvent) + throw (css::uno::RuntimeException) +{ + if ( ! aEvent.EventName.equalsIgnoreAsciiCaseAscii ("OnSaveAsDone") + && ! aEvent.EventName.equalsIgnoreAsciiCaseAscii ("OnTitleChanged")) + return; + + // SYNCHRONIZED -> + ::osl::ResettableMutexGuard aLock(m_aMutex); + + css::uno::Reference< css::frame::XModel > xOwner(m_xOwner.get (), css::uno::UNO_QUERY); + + aLock.clear (); + // <- SYNCHRONIZED + + if ( + aEvent.Source != xOwner || + (aEvent.EventName.equalsIgnoreAsciiCaseAscii ("OnTitleChanged") && !xOwner.is()) + ) + { + return; + } + + impl_updateTitle (); +} + +//----------------------------------------------- +void SAL_CALL TitleHelper::frameAction(const css::frame::FrameActionEvent& aEvent) + throw(css::uno::RuntimeException) +{ + // SYNCHRONIZED -> + ::osl::ResettableMutexGuard aLock(m_aMutex); + + css::uno::Reference< css::frame::XFrame > xOwner(m_xOwner.get (), css::uno::UNO_QUERY); + + aLock.clear (); + // <- SYNCHRONIZED + + if (aEvent.Source != xOwner) + return; + + // we are interested on events only, which must trigger a title bar update + // because component was changed. + if ( + (aEvent.Action == css::frame::FrameAction_COMPONENT_ATTACHED ) || + (aEvent.Action == css::frame::FrameAction_COMPONENT_REATTACHED) || + (aEvent.Action == css::frame::FrameAction_COMPONENT_DETACHING ) + ) + { + impl_updateListeningForFrame (xOwner); + impl_updateTitle (); + } +} + +//----------------------------------------------- +void SAL_CALL TitleHelper::disposing(const css::lang::EventObject& aEvent) + throw (css::uno::RuntimeException) +{ + // SYNCHRONIZED -> + ::osl::ResettableMutexGuard aLock(m_aMutex); + css::uno::Reference< css::uno::XInterface > xOwner (m_xOwner.get() , css::uno::UNO_QUERY); + css::uno::Reference< css::frame::XUntitledNumbers > xNumbers (m_xUntitledNumbers.get(), css::uno::UNO_QUERY); + ::sal_Int32 nLeasedNumber = m_nLeasedNumber; + aLock.clear (); + // <- SYNCHRONIZED + + if ( ! xOwner.is ()) + return; + + if (xOwner != aEvent.Source) + return; + + if ( + (xNumbers.is () ) && + (nLeasedNumber != css::frame::UntitledNumbersConst::INVALID_NUMBER) + ) + xNumbers->releaseNumber (nLeasedNumber); + + // SYNCHRONIZED -> + aLock.reset (); + + m_sTitle = ::rtl::OUString (); + m_nLeasedNumber = css::frame::UntitledNumbersConst::INVALID_NUMBER; + + aLock.clear (); + // <- SYNCHRONIZED + + impl_sendTitleChangedEvent (); +} + +//----------------------------------------------- +void TitleHelper::impl_sendTitleChangedEvent () +{ + // SYNCHRONIZED -> + ::osl::ResettableMutexGuard aLock(m_aMutex); + + css::frame::TitleChangedEvent aEvent(m_xOwner.get (), m_sTitle); + + aLock.clear (); + // <- SYNCHRONIZED + + ::cppu::OInterfaceContainerHelper* pContainer = m_aListener.getContainer( ::getCppuType( ( const css::uno::Reference< css::frame::XTitleChangeListener >*) NULL ) ); + if ( ! pContainer) + return; + + ::cppu::OInterfaceIteratorHelper pIt( *pContainer ); + while ( pIt.hasMoreElements() ) + { + try + { + ((css::frame::XTitleChangeListener*)pIt.next())->titleChanged( aEvent ); + } + catch(const css::uno::Exception&) + { + pIt.remove(); + } + } +} + +//----------------------------------------------- +void TitleHelper::impl_updateTitle () +{ + // SYNCHRONIZED -> + ::osl::ResettableMutexGuard aLock(m_aMutex); + + css::uno::Reference< css::frame::XModel > xModel (m_xOwner.get(), css::uno::UNO_QUERY); + css::uno::Reference< css::frame::XController > xController(m_xOwner.get(), css::uno::UNO_QUERY); + css::uno::Reference< css::frame::XFrame > xFrame (m_xOwner.get(), css::uno::UNO_QUERY); + + aLock.clear (); + // <- SYNCHRONIZED + + if (xModel.is ()) + { + impl_updateTitleForModel (xModel); + return; + } + + if (xController.is ()) + { + impl_updateTitleForController (xController); + return; + } + + if (xFrame.is ()) + { + impl_updateTitleForFrame (xFrame); + return; + } +} + +//----------------------------------------------- +void TitleHelper::impl_updateTitleForModel (const css::uno::Reference< css::frame::XModel >& xModel) +{ + // SYNCHRONIZED -> + ::osl::ResettableMutexGuard aLock(m_aMutex); + + // external title wont be updated internaly ! + // It has to be set from outside new. + if (m_bExternalTitle) + return; + + css::uno::Reference< css::uno::XInterface > xOwner (m_xOwner.get() , css::uno::UNO_QUERY); + css::uno::Reference< css::frame::XUntitledNumbers > xNumbers (m_xUntitledNumbers.get(), css::uno::UNO_QUERY); + ::sal_Int32 nLeasedNumber = m_nLeasedNumber; + + aLock.clear (); + // <- SYNCHRONIZED + + if ( + ( ! xOwner.is ()) || + ( ! xNumbers.is ()) || + ( ! xModel.is ()) + ) + return; + + ::rtl::OUString sTitle; + ::rtl::OUString sURL ; + + css::uno::Reference< css::frame::XStorable > xURLProvider(xModel , css::uno::UNO_QUERY); + if (xURLProvider.is()) + sURL = xURLProvider->getLocation (); + + if (sURL.getLength () > 0) + { + sTitle = impl_convertURL2Title(sURL); + if (nLeasedNumber != css::frame::UntitledNumbersConst::INVALID_NUMBER) + xNumbers->releaseNumber (nLeasedNumber); + nLeasedNumber = css::frame::UntitledNumbersConst::INVALID_NUMBER; + } + else + { + if (nLeasedNumber == css::frame::UntitledNumbersConst::INVALID_NUMBER) + nLeasedNumber = xNumbers->leaseNumber (xOwner); + + ::rtl::OUStringBuffer sNewTitle(256); + sNewTitle.append (xNumbers->getUntitledPrefix ()); + if (nLeasedNumber != css::frame::UntitledNumbersConst::INVALID_NUMBER) + sNewTitle.append ((::sal_Int32)nLeasedNumber); + else + sNewTitle.appendAscii ("?"); + + sTitle = sNewTitle.makeStringAndClear (); + } + + // SYNCHRONIZED -> + aLock.reset (); + + // WORKAROUND: the notification is currently sent always, + // can be changed after shared mode is supported per UNO API + sal_Bool bChanged = sal_True; // (! m_sTitle.equals(sTitle)); + + m_sTitle = sTitle; + m_nLeasedNumber = nLeasedNumber; + + aLock.clear (); + // <- SYNCHRONIZED + + if (bChanged) + impl_sendTitleChangedEvent (); +} + +//----------------------------------------------- +void TitleHelper::impl_updateTitleForController (const css::uno::Reference< css::frame::XController >& xController) +{ + // SYNCHRONIZED -> + ::osl::ResettableMutexGuard aLock(m_aMutex); + + // external title wont be updated internaly ! + // It has to be set from outside new. + if (m_bExternalTitle) + return; + + css::uno::Reference< css::uno::XInterface > xOwner (m_xOwner.get() , css::uno::UNO_QUERY); + css::uno::Reference< css::frame::XUntitledNumbers > xNumbers (m_xUntitledNumbers.get(), css::uno::UNO_QUERY); + ::sal_Int32 nLeasedNumber = m_nLeasedNumber; + + aLock.clear (); + // <- SYNCHRONIZED + + if ( + ( ! xOwner.is ()) || + ( ! xNumbers.is ()) || + ( ! xController.is ()) + ) + return; + + ::rtl::OUStringBuffer sTitle(256); + + if (nLeasedNumber == css::frame::UntitledNumbersConst::INVALID_NUMBER) + nLeasedNumber = xNumbers->leaseNumber (xOwner); + + css::uno::Reference< css::frame::XTitle > xModelTitle(xController->getModel (), css::uno::UNO_QUERY); + if (!xModelTitle.is ()) + xModelTitle.set(xController, css::uno::UNO_QUERY); + if (xModelTitle.is ()) + { + sTitle.append (xModelTitle->getTitle ()); + if ( nLeasedNumber > 1 ) + { + sTitle.appendAscii (" : "); + sTitle.append ((::sal_Int32)nLeasedNumber); + } + } + else + { + sTitle.append (xNumbers->getUntitledPrefix ()); + if ( nLeasedNumber > 1 ) + { + sTitle.append ((::sal_Int32)nLeasedNumber ); + } + } + + // SYNCHRONIZED -> + aLock.reset (); + + ::rtl::OUString sNewTitle = sTitle.makeStringAndClear (); + sal_Bool bChanged = (! m_sTitle.equals(sNewTitle)); + m_sTitle = sNewTitle; + m_nLeasedNumber = nLeasedNumber; + + aLock.clear (); + // <- SYNCHRONIZED + + if (bChanged) + impl_sendTitleChangedEvent (); +} + +//----------------------------------------------- +void TitleHelper::impl_updateTitleForFrame (const css::uno::Reference< css::frame::XFrame >& xFrame) +{ + if ( ! xFrame.is ()) + return; + + // SYNCHRONIZED -> + ::osl::ResettableMutexGuard aLock(m_aMutex); + + // external title wont be updated internaly ! + // It has to be set from outside new. + if (m_bExternalTitle) + return; + + aLock.clear (); + // <- SYNCHRONIZED + + css::uno::Reference< css::uno::XInterface > xComponent; + xComponent = xFrame->getController (); + if ( ! xComponent.is ()) + xComponent = xFrame->getComponentWindow (); + + ::rtl::OUStringBuffer sTitle (256); + + impl_appendComponentTitle (sTitle, xComponent); + impl_appendProductName (sTitle); + impl_appendModuleName (sTitle); + impl_appendProductExtension (sTitle); + impl_appendDebugVersion (sTitle); + + // SYNCHRONIZED -> + aLock.reset (); + + ::rtl::OUString sNewTitle = sTitle.makeStringAndClear (); + sal_Bool bChanged = (! m_sTitle.equals(sNewTitle)); + m_sTitle = sNewTitle; + + aLock.clear (); + // <- SYNCHRONIZED + + if (bChanged) + impl_sendTitleChangedEvent (); +} + +//***************************************************************************************************************** +void TitleHelper::impl_appendComponentTitle ( ::rtl::OUStringBuffer& sTitle , + const css::uno::Reference< css::uno::XInterface >& xComponent) +{ + css::uno::Reference< css::frame::XTitle > xTitle(xComponent, css::uno::UNO_QUERY); + + // Note: Title has to be used (even if it's empty) if the right interface is supported. + if (xTitle.is ()) + sTitle.append (xTitle->getTitle ()); +} + +//***************************************************************************************************************** +void TitleHelper::impl_appendProductName (::rtl::OUStringBuffer& sTitle) +{ + ::rtl::OUString sProductName; + ::utl::ConfigManager::GetDirectConfigProperty(::utl::ConfigManager::PRODUCTNAME) >>= sProductName; + + if (sProductName.getLength ()) + { + if (sTitle.getLength() > 0) + sTitle.appendAscii (" - "); + + sTitle.append (sProductName); + } +} + +//***************************************************************************************************************** +void TitleHelper::impl_appendProductExtension (::rtl::OUStringBuffer& sTitle) +{ + ::rtl::OUString sProductExtension; + ::utl::ConfigManager::GetDirectConfigProperty(::utl::ConfigManager::PRODUCTEXTENSION) >>= sProductExtension; + + if (sProductExtension.getLength ()) + { + sTitle.appendAscii (" "); + sTitle.append (sProductExtension); + } +} + +//***************************************************************************************************************** +void TitleHelper::impl_appendModuleName (::rtl::OUStringBuffer& sTitle) +{ + // SYNCHRONIZED -> + ::osl::ResettableMutexGuard aLock(m_aMutex); + + css::uno::Reference< css::uno::XInterface > xOwner = m_xOwner.get(); + css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR; + + aLock.clear (); + // <- SYNCHRONIZED + + try + { + css::uno::Reference< css::frame::XModuleManager > xModuleManager( + xSMGR->createInstance(SERVICENAME_MODULEMANAGER), + css::uno::UNO_QUERY_THROW); + + css::uno::Reference< css::container::XNameAccess > xConfig( + xModuleManager, + css::uno::UNO_QUERY_THROW); + + const ::rtl::OUString sID = xModuleManager->identify(xOwner); + ::comphelper::SequenceAsHashMap lProps = xConfig->getByName (sID); + const ::rtl::OUString sUIName = lProps.getUnpackedValueOrDefault (OFFICEFACTORY_PROPNAME_UINAME, ::rtl::OUString()); + + // An UIname property is an optional value ! + // So please add it to the title in case it does realy exists only. + if (sUIName.getLength() > 0) + { + sTitle.appendAscii (" " ); + sTitle.append (sUIName); + } + } + catch(const css::uno::Exception&) + {} +} + +//***************************************************************************************************************** +#ifdef DBG_UTIL +void TitleHelper::impl_appendDebugVersion (::rtl::OUStringBuffer& sTitle) +{ + ::rtl::OUString sDefault ; + ::rtl::OUString sVersion = ::utl::Bootstrap::getBuildIdData( sDefault ); + + sTitle.appendAscii (" [" ); + sTitle.append (sVersion); + sTitle.appendAscii ("]" ); +} +#else +void TitleHelper::impl_appendDebugVersion (::rtl::OUStringBuffer&) +{ +} +#endif + +//----------------------------------------------- +void TitleHelper::impl_startListeningForModel (const css::uno::Reference< css::frame::XModel >& xModel) +{ + css::uno::Reference< css::document::XEventBroadcaster > xBroadcaster(xModel, css::uno::UNO_QUERY); + if ( ! xBroadcaster.is ()) + return; + + xBroadcaster->addEventListener (static_cast< css::document::XEventListener* >(this)); +} + +//----------------------------------------------- +void TitleHelper::impl_startListeningForController (const css::uno::Reference< css::frame::XController >& xController) +{ + css::uno::Reference< css::frame::XTitle > xSubTitle(xController->getModel (), css::uno::UNO_QUERY); + impl_setSubTitle (xSubTitle); +} + +//----------------------------------------------- +void TitleHelper::impl_startListeningForFrame (const css::uno::Reference< css::frame::XFrame >& xFrame) +{ + xFrame->addFrameActionListener(this ); + impl_updateListeningForFrame (xFrame); +} + +//----------------------------------------------- +void TitleHelper::impl_updateListeningForFrame (const css::uno::Reference< css::frame::XFrame >& xFrame) +{ + css::uno::Reference< css::frame::XTitle > xSubTitle(xFrame->getController (), css::uno::UNO_QUERY); + impl_setSubTitle (xSubTitle); +} + +//----------------------------------------------- +void TitleHelper::impl_setSubTitle (const css::uno::Reference< css::frame::XTitle >& xSubTitle) +{ + // SYNCHRONIZED -> + ::osl::ResettableMutexGuard aLock(m_aMutex); + + // ignore duplicate calls. Makes outside using of this helper more easy :-) + css::uno::Reference< css::frame::XTitle > xOldSubTitle(m_xSubTitle.get(), css::uno::UNO_QUERY); + if (xOldSubTitle == xSubTitle) + return; + + m_xSubTitle = xSubTitle; + + aLock.clear (); + // <- SYNCHRONIZED + + css::uno::Reference< css::frame::XTitleChangeBroadcaster > xOldBroadcaster(xOldSubTitle , css::uno::UNO_QUERY ); + css::uno::Reference< css::frame::XTitleChangeBroadcaster > xNewBroadcaster(xSubTitle , css::uno::UNO_QUERY ); + css::uno::Reference< css::frame::XTitleChangeListener > xThis (static_cast< css::frame::XTitleChangeListener* >(this), css::uno::UNO_QUERY_THROW); + + if (xOldBroadcaster.is()) + xOldBroadcaster->removeTitleChangeListener (xThis); + + if (xNewBroadcaster.is()) + xNewBroadcaster->addTitleChangeListener (xThis); +} + +//----------------------------------------------- +::rtl::OUString TitleHelper::impl_getSubTitle () +{ + // SYNCHRONIZED -> + ::osl::ResettableMutexGuard aLock(m_aMutex); + + css::uno::Reference< css::frame::XTitle > xSubTitle(m_xSubTitle.get (), css::uno::UNO_QUERY); + + aLock.clear (); + // <- SYNCHRONIZED + + if (xSubTitle.is ()) + return xSubTitle->getTitle (); + + return ::rtl::OUString (); +} + +//----------------------------------------------- +::rtl::OUString TitleHelper::impl_convertURL2Title(const ::rtl::OUString& sURL) +{ + INetURLObject aURL (sURL); + ::rtl::OUString sTitle; + + if (aURL.GetProtocol() == INET_PROT_FILE) + { + if (aURL.HasMark()) + aURL = INetURLObject(aURL.GetURLNoMark()); + + sTitle = aURL.getName(INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::DECODE_WITH_CHARSET); + } + else + { + if (aURL.hasExtension(INetURLObject::LAST_SEGMENT)) + sTitle = aURL.getName(INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::DECODE_WITH_CHARSET); + + if ( ! sTitle.getLength() ) + sTitle = aURL.GetHostPort(INetURLObject::DECODE_WITH_CHARSET); + + if ( ! sTitle.getLength() ) + sTitle = aURL.GetURLNoPass(INetURLObject::DECODE_WITH_CHARSET); + } + + return sTitle; +} + +} // namespace framework + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/framework/source/helper/uiconfigelementwrapperbase.cxx b/framework/source/helper/uiconfigelementwrapperbase.cxx new file mode 100644 index 000000000000..b4be597c21c3 --- /dev/null +++ b/framework/source/helper/uiconfigelementwrapperbase.cxx @@ -0,0 +1,574 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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_framework.hxx" + +//_________________________________________________________________________________________________________________ +// my own includes +//_________________________________________________________________________________________________________________ +#include <helper/uiconfigelementwrapperbase.hxx> +#include <general.h> +#include <properties.h> +#include <threadhelp/resetableguard.hxx> +#include <uielement/constitemcontainer.hxx> +#include <uielement/rootitemcontainer.hxx> + +//_________________________________________________________________________________________________________________ +// interface includes +//_________________________________________________________________________________________________________________ +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/ui/XUIConfiguration.hpp> + +//_________________________________________________________________________________________________________________ +// includes of other projects +//_________________________________________________________________________________________________________________ +#include <vcl/svapp.hxx> +#include <rtl/logfile.hxx> + +const int UIELEMENT_PROPHANDLE_CONFIGSOURCE = 1; +const int UIELEMENT_PROPHANDLE_FRAME = 2; +const int UIELEMENT_PROPHANDLE_PERSISTENT = 3; +const int UIELEMENT_PROPHANDLE_RESOURCEURL = 4; +const int UIELEMENT_PROPHANDLE_TYPE = 5; +const int UIELEMENT_PROPHANDLE_XMENUBAR = 6; +const int UIELEMENT_PROPHANDLE_CONFIGLISTENER = 7; +const int UIELEMENT_PROPHANDLE_NOCLOSE = 8; +const int UIELEMENT_PROPCOUNT = 8; +const rtl::OUString UIELEMENT_PROPNAME_CONFIGLISTENER( RTL_CONSTASCII_USTRINGPARAM( "ConfigListener" )); +const rtl::OUString UIELEMENT_PROPNAME_CONFIGSOURCE( RTL_CONSTASCII_USTRINGPARAM( "ConfigurationSource" )); +const rtl::OUString UIELEMENT_PROPNAME_FRAME( RTL_CONSTASCII_USTRINGPARAM( "Frame" )); +const rtl::OUString UIELEMENT_PROPNAME_PERSISTENT( RTL_CONSTASCII_USTRINGPARAM( "Persistent" )); +const rtl::OUString UIELEMENT_PROPNAME_RESOURCEURL( RTL_CONSTASCII_USTRINGPARAM( "ResourceURL" )); +const rtl::OUString UIELEMENT_PROPNAME_TYPE( RTL_CONSTASCII_USTRINGPARAM( "Type" )); +const rtl::OUString UIELEMENT_PROPNAME_XMENUBAR( RTL_CONSTASCII_USTRINGPARAM( "XMenuBar" )); +const rtl::OUString UIELEMENT_PROPNAME_NOCLOSE( RTL_CONSTASCII_USTRINGPARAM( "NoClose" )); + +using namespace rtl; +using namespace com::sun::star::beans; +using namespace com::sun::star::uno; +using namespace com::sun::star::frame; +using namespace com::sun::star::lang; +using namespace com::sun::star::container; +using namespace ::com::sun::star::ui; + +namespace framework +{ + +//***************************************************************************************************************** +// XInterface, XTypeProvider +//***************************************************************************************************************** +DEFINE_XINTERFACE_10 ( UIConfigElementWrapperBase , + OWeakObject , + DIRECT_INTERFACE( ::com::sun::star::lang::XTypeProvider ), + DIRECT_INTERFACE( ::com::sun::star::ui::XUIElement ), + DIRECT_INTERFACE( ::com::sun::star::ui::XUIElementSettings ), + DIRECT_INTERFACE( ::com::sun::star::beans::XMultiPropertySet ), + DIRECT_INTERFACE( ::com::sun::star::beans::XFastPropertySet ), + DIRECT_INTERFACE( ::com::sun::star::beans::XPropertySet ), + DIRECT_INTERFACE( ::com::sun::star::lang::XInitialization ), + DIRECT_INTERFACE( ::com::sun::star::lang::XComponent ), + DIRECT_INTERFACE( ::com::sun::star::util::XUpdatable ), + DIRECT_INTERFACE( ::com::sun::star::ui::XUIConfigurationListener ) + ) + +DEFINE_XTYPEPROVIDER_10 ( UIConfigElementWrapperBase , + ::com::sun::star::lang::XTypeProvider , + ::com::sun::star::ui::XUIElement , + ::com::sun::star::ui::XUIElementSettings , + ::com::sun::star::beans::XMultiPropertySet , + ::com::sun::star::beans::XFastPropertySet , + ::com::sun::star::beans::XPropertySet , + ::com::sun::star::lang::XInitialization , + ::com::sun::star::lang::XComponent , + ::com::sun::star::util::XUpdatable , + ::com::sun::star::ui::XUIConfigurationListener + ) + +UIConfigElementWrapperBase::UIConfigElementWrapperBase( sal_Int16 nType,const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _xServiceFactory ) + : ThreadHelpBase ( &Application::GetSolarMutex() ) + , ::cppu::OBroadcastHelperVar< ::cppu::OMultiTypeInterfaceContainerHelper, ::cppu::OMultiTypeInterfaceContainerHelper::keyType >( m_aLock.getShareableOslMutex() ) + , ::cppu::OPropertySetHelper ( *(static_cast< ::cppu::OBroadcastHelper* >(this)) ) + , ::cppu::OWeakObject ( ) + , m_nType ( nType ) + , m_bPersistent ( sal_True ) + , m_bInitialized ( sal_False ) + , m_bConfigListener ( sal_False ) + , m_bConfigListening ( sal_False ) + , m_bDisposed ( sal_False ) + , m_bNoClose ( sal_False ) + , m_xServiceFactory ( _xServiceFactory ) + , m_aListenerContainer ( m_aLock.getShareableOslMutex() ) +{ +} + +UIConfigElementWrapperBase::~UIConfigElementWrapperBase() +{ +} + +// XComponent +void SAL_CALL UIConfigElementWrapperBase::dispose() throw (::com::sun::star::uno::RuntimeException) +{ + // must be implemented by derived class + ResetableGuard aLock( m_aLock ); + m_bDisposed = sal_True; +} + +void SAL_CALL UIConfigElementWrapperBase::addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException) +{ + m_aListenerContainer.addInterface( ::getCppuType( ( const css::uno::Reference< css::lang::XEventListener >* ) NULL ), xListener ); +} + +void SAL_CALL UIConfigElementWrapperBase::removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& aListener ) throw (::com::sun::star::uno::RuntimeException) +{ + m_aListenerContainer.removeInterface( ::getCppuType( ( const css::uno::Reference< css::lang::XEventListener >* ) NULL ), aListener ); +} + +// XEventListener +void SAL_CALL UIConfigElementWrapperBase::disposing( const EventObject& ) +throw( RuntimeException ) +{ + ResetableGuard aLock( m_aLock ); + m_xConfigSource.clear(); +} + +void SAL_CALL UIConfigElementWrapperBase::initialize( const Sequence< Any >& aArguments ) +throw ( Exception, RuntimeException ) +{ + ResetableGuard aLock( m_aLock ); + + if ( !m_bInitialized ) + { + for ( sal_Int32 n = 0; n < aArguments.getLength(); n++ ) + { + PropertyValue aPropValue; + if ( aArguments[n] >>= aPropValue ) + { + if ( aPropValue.Name.equals( UIELEMENT_PROPNAME_CONFIGSOURCE )) + setFastPropertyValue_NoBroadcast( UIELEMENT_PROPHANDLE_CONFIGSOURCE, aPropValue.Value ); + else if ( aPropValue.Name.equals( UIELEMENT_PROPNAME_FRAME )) + setFastPropertyValue_NoBroadcast( UIELEMENT_PROPHANDLE_FRAME, aPropValue.Value ); + else if ( aPropValue.Name.equals( UIELEMENT_PROPNAME_PERSISTENT )) + setFastPropertyValue_NoBroadcast( UIELEMENT_PROPHANDLE_PERSISTENT, aPropValue.Value ); + else if ( aPropValue.Name.equals( UIELEMENT_PROPNAME_RESOURCEURL )) + setFastPropertyValue_NoBroadcast( UIELEMENT_PROPHANDLE_RESOURCEURL, aPropValue.Value ); + else if ( aPropValue.Name.equals( UIELEMENT_PROPNAME_TYPE )) + setFastPropertyValue_NoBroadcast( UIELEMENT_PROPHANDLE_TYPE, aPropValue.Value ); + else if ( aPropValue.Name.equals( UIELEMENT_PROPNAME_CONFIGLISTENER )) + setFastPropertyValue_NoBroadcast( UIELEMENT_PROPHANDLE_CONFIGLISTENER, aPropValue.Value ); + else if ( aPropValue.Name.equals( UIELEMENT_PROPNAME_NOCLOSE )) + setFastPropertyValue_NoBroadcast( UIELEMENT_PROPHANDLE_NOCLOSE, aPropValue.Value ); + } + } + + m_bInitialized = sal_True; + } +} + +// XUpdatable +void SAL_CALL UIConfigElementWrapperBase::update() throw (::com::sun::star::uno::RuntimeException) +{ + // can be implemented by derived class +} + +void SAL_CALL UIConfigElementWrapperBase::elementInserted( const ::com::sun::star::ui::ConfigurationEvent& ) throw (::com::sun::star::uno::RuntimeException) +{ + // can be implemented by derived class +} + +void SAL_CALL UIConfigElementWrapperBase::elementRemoved( const ::com::sun::star::ui::ConfigurationEvent& ) throw (::com::sun::star::uno::RuntimeException) +{ + // can be implemented by derived class +} + +void SAL_CALL UIConfigElementWrapperBase::elementReplaced( const ::com::sun::star::ui::ConfigurationEvent& ) throw (::com::sun::star::uno::RuntimeException) +{ + // can be implemented by derived class +} + +// XPropertySet helper +sal_Bool SAL_CALL UIConfigElementWrapperBase::convertFastPropertyValue( Any& aConvertedValue , + Any& aOldValue , + sal_Int32 nHandle , + const Any& aValue ) throw( com::sun::star::lang::IllegalArgumentException ) +{ + // Initialize state with FALSE !!! + // (Handle can be invalid) + sal_Bool bReturn = sal_False; + + switch( nHandle ) + { + case UIELEMENT_PROPHANDLE_CONFIGLISTENER: + bReturn = PropHelper::willPropertyBeChanged( + com::sun::star::uno::makeAny(m_bConfigListener), + aValue, + aOldValue, + aConvertedValue); + break; + + case UIELEMENT_PROPHANDLE_CONFIGSOURCE: + bReturn = PropHelper::willPropertyBeChanged( + com::sun::star::uno::makeAny(m_xConfigSource), + aValue, + aOldValue, + aConvertedValue); + break; + + case UIELEMENT_PROPHANDLE_FRAME: + { + Reference< XFrame > xFrame( m_xWeakFrame ); + bReturn = PropHelper::willPropertyBeChanged( + com::sun::star::uno::makeAny(xFrame), + aValue, + aOldValue, + aConvertedValue); + } + break; + + case UIELEMENT_PROPHANDLE_PERSISTENT: + bReturn = PropHelper::willPropertyBeChanged( + com::sun::star::uno::makeAny(m_bPersistent), + aValue, + aOldValue, + aConvertedValue); + break; + + case UIELEMENT_PROPHANDLE_RESOURCEURL: + bReturn = PropHelper::willPropertyBeChanged( + com::sun::star::uno::makeAny(m_aResourceURL), + aValue, + aOldValue, + aConvertedValue); + break; + + case UIELEMENT_PROPHANDLE_TYPE : + bReturn = PropHelper::willPropertyBeChanged( + com::sun::star::uno::makeAny(m_nType), + aValue, + aOldValue, + aConvertedValue); + break; + + case UIELEMENT_PROPHANDLE_XMENUBAR : + bReturn = PropHelper::willPropertyBeChanged( + com::sun::star::uno::makeAny(m_xMenuBar), + aValue, + aOldValue, + aConvertedValue); + break; + + case UIELEMENT_PROPHANDLE_NOCLOSE: + bReturn = PropHelper::willPropertyBeChanged( + com::sun::star::uno::makeAny(m_bNoClose), + aValue, + aOldValue, + aConvertedValue); + break; + } + + // Return state of operation. + return bReturn ; +} + +void SAL_CALL UIConfigElementWrapperBase::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle , + const com::sun::star::uno::Any& aValue ) throw( com::sun::star::uno::Exception ) +{ + switch( nHandle ) + { + case UIELEMENT_PROPHANDLE_CONFIGLISTENER: + { + bool bBool( m_bConfigListener ); + aValue >>= bBool; + if ( m_bConfigListener != bBool ) + { + if ( m_bConfigListening ) + { + if ( m_xConfigSource.is() && !bBool ) + { + try + { + Reference< XUIConfiguration > xUIConfig( m_xConfigSource, UNO_QUERY ); + if ( xUIConfig.is() ) + { + xUIConfig->removeConfigurationListener( Reference< XUIConfigurationListener >( static_cast< OWeakObject* >( this ), UNO_QUERY )); + m_bConfigListening = sal_False; + } + } + catch ( Exception& ) + { + } + } + } + else + { + if ( m_xConfigSource.is() && bBool ) + { + try + { + Reference< XUIConfiguration > xUIConfig( m_xConfigSource, UNO_QUERY ); + if ( xUIConfig.is() ) + { + xUIConfig->addConfigurationListener( Reference< XUIConfigurationListener >( static_cast< OWeakObject* >( this ), UNO_QUERY )); + m_bConfigListening = sal_True; + } + } + catch ( Exception& ) + { + } + } + } + + m_bConfigListener = bBool; + } + } + break; + case UIELEMENT_PROPHANDLE_CONFIGSOURCE: + aValue >>= m_xConfigSource; + break; + case UIELEMENT_PROPHANDLE_FRAME: + { + Reference< XFrame > xFrame; + + aValue >>= xFrame; + m_xWeakFrame = xFrame; + break; + } + case UIELEMENT_PROPHANDLE_PERSISTENT: + { + sal_Bool bBool( m_bPersistent ); + aValue >>= bBool; + m_bPersistent = bBool; + break; + } + case UIELEMENT_PROPHANDLE_RESOURCEURL: + aValue >>= m_aResourceURL; + break; + case UIELEMENT_PROPHANDLE_TYPE: + aValue >>= m_nType; + break; + case UIELEMENT_PROPHANDLE_XMENUBAR: + aValue >>= m_xMenuBar; + break; + case UIELEMENT_PROPHANDLE_NOCLOSE: + { + sal_Bool bBool( m_bNoClose ); + aValue >>= bBool; + m_bNoClose = bBool; + break; + } + } +} + +void SAL_CALL UIConfigElementWrapperBase::getFastPropertyValue( com::sun::star::uno::Any& aValue , + sal_Int32 nHandle ) const +{ + switch( nHandle ) + { + case UIELEMENT_PROPHANDLE_CONFIGLISTENER: + aValue <<= m_bConfigListener; + break; + case UIELEMENT_PROPHANDLE_CONFIGSOURCE: + aValue <<= m_xConfigSource; + break; + case UIELEMENT_PROPHANDLE_FRAME: + { + Reference< XFrame > xFrame( m_xWeakFrame ); + aValue <<= xFrame; + break; + } + case UIELEMENT_PROPHANDLE_PERSISTENT: + aValue <<= m_bPersistent; + break; + case UIELEMENT_PROPHANDLE_RESOURCEURL: + aValue <<= m_aResourceURL; + break; + case UIELEMENT_PROPHANDLE_TYPE: + aValue <<= m_nType; + break; + case UIELEMENT_PROPHANDLE_XMENUBAR: + aValue <<= m_xMenuBar; + break; + case UIELEMENT_PROPHANDLE_NOCLOSE: + aValue <<= m_bNoClose; + break; + } +} + +::cppu::IPropertyArrayHelper& SAL_CALL UIConfigElementWrapperBase::getInfoHelper() +{ + // Optimize this method ! + // We initialize a static variable only one time. And we don't must use a mutex at every call! + // For the first call; pInfoHelper is NULL - for the second call pInfoHelper is different from NULL! + static ::cppu::OPropertyArrayHelper* pInfoHelper = NULL; + + if( pInfoHelper == NULL ) + { + // Ready for multithreading + osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ; + + // Control this pointer again, another instance can be faster then these! + if( pInfoHelper == NULL ) + { + // Define static member to give structure of properties to baseclass "OPropertySetHelper". + // "impl_getStaticPropertyDescriptor" is a non exported and static funtion, who will define a static propertytable. + // "sal_True" say: Table is sorted by name. + static ::cppu::OPropertyArrayHelper aInfoHelper( impl_getStaticPropertyDescriptor(), sal_True ); + pInfoHelper = &aInfoHelper; + } + } + + return(*pInfoHelper); +} + +com::sun::star::uno::Reference< com::sun::star::beans::XPropertySetInfo > SAL_CALL UIConfigElementWrapperBase::getPropertySetInfo() throw (::com::sun::star::uno::RuntimeException) +{ + // Optimize this method ! + // We initialize a static variable only one time. And we don't must use a mutex at every call! + // For the first call; pInfo is NULL - for the second call pInfo is different from NULL! + static com::sun::star::uno::Reference< com::sun::star::beans::XPropertySetInfo >* pInfo = NULL; + + if( pInfo == NULL ) + { + // Ready for multithreading + osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ; + // Control this pointer again, another instance can be faster then these! + if( pInfo == NULL ) + { + // Create structure of propertysetinfo for baseclass "OPropertySetHelper". + // (Use method "getInfoHelper()".) + static com::sun::star::uno::Reference< com::sun::star::beans::XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) ); + pInfo = &xInfo; + } + } + + return (*pInfo); +} + +const com::sun::star::uno::Sequence< com::sun::star::beans::Property > UIConfigElementWrapperBase::impl_getStaticPropertyDescriptor() +{ + // Create a new static property array to initialize sequence! + // Table of all predefined properties of this class. Its used from OPropertySetHelper-class! + // Don't forget to change the defines (see begin of this file), if you add, change or delete a property in this list!!! + // It's necessary for methods of OPropertySetHelper. + // ATTENTION: + // YOU MUST SORT FOLLOW TABLE BY NAME ALPHABETICAL !!! + + static const com::sun::star::beans::Property pProperties[] = + { + com::sun::star::beans::Property( UIELEMENT_PROPNAME_CONFIGLISTENER, UIELEMENT_PROPHANDLE_CONFIGLISTENER , ::getCppuType((const sal_Bool*)NULL), com::sun::star::beans::PropertyAttribute::TRANSIENT ), + com::sun::star::beans::Property( UIELEMENT_PROPNAME_CONFIGSOURCE , UIELEMENT_PROPHANDLE_CONFIGSOURCE , ::getCppuType((const Reference< ::com::sun::star::ui::XUIConfigurationManager >*)NULL), com::sun::star::beans::PropertyAttribute::TRANSIENT ), + com::sun::star::beans::Property( UIELEMENT_PROPNAME_FRAME , UIELEMENT_PROPHANDLE_FRAME , ::getCppuType((const Reference< com::sun::star::frame::XFrame >*)NULL), com::sun::star::beans::PropertyAttribute::TRANSIENT | com::sun::star::beans::PropertyAttribute::READONLY ), + com::sun::star::beans::Property( UIELEMENT_PROPNAME_NOCLOSE , UIELEMENT_PROPHANDLE_NOCLOSE , ::getCppuType((const sal_Bool*)NULL), com::sun::star::beans::PropertyAttribute::TRANSIENT ), + com::sun::star::beans::Property( UIELEMENT_PROPNAME_PERSISTENT , UIELEMENT_PROPHANDLE_PERSISTENT , ::getCppuType((const sal_Bool*)NULL), com::sun::star::beans::PropertyAttribute::TRANSIENT ), + com::sun::star::beans::Property( UIELEMENT_PROPNAME_RESOURCEURL , UIELEMENT_PROPHANDLE_RESOURCEURL , ::getCppuType((const ::rtl::OUString*)NULL), com::sun::star::beans::PropertyAttribute::TRANSIENT | com::sun::star::beans::PropertyAttribute::READONLY ), + com::sun::star::beans::Property( UIELEMENT_PROPNAME_TYPE , UIELEMENT_PROPHANDLE_TYPE , ::getCppuType((const ::rtl::OUString*)NULL), com::sun::star::beans::PropertyAttribute::TRANSIENT | com::sun::star::beans::PropertyAttribute::READONLY ), + com::sun::star::beans::Property( UIELEMENT_PROPNAME_XMENUBAR , UIELEMENT_PROPHANDLE_XMENUBAR , ::getCppuType((const Reference< com::sun::star::awt::XMenuBar >*)NULL), com::sun::star::beans::PropertyAttribute::TRANSIENT | com::sun::star::beans::PropertyAttribute::READONLY ) + }; + // Use it to initialize sequence! + static const com::sun::star::uno::Sequence< com::sun::star::beans::Property > lPropertyDescriptor( pProperties, UIELEMENT_PROPCOUNT ); + // Return static "PropertyDescriptor" + return lPropertyDescriptor; +} +void SAL_CALL UIConfigElementWrapperBase::setSettings( const Reference< XIndexAccess >& xSettings ) throw ( RuntimeException ) +{ + ResetableGuard aLock( m_aLock ); + + //if ( m_bDisposed ) + // throw DisposedException(); + + if ( xSettings.is() ) + { + // Create a copy of the data if the container is not const + Reference< XIndexReplace > xReplace( xSettings, UNO_QUERY ); + if ( xReplace.is() ) + m_xConfigData = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer( xSettings ) ), UNO_QUERY ); + else + m_xConfigData = xSettings; + + if ( m_xConfigSource.is() && m_bPersistent ) + { + ::rtl::OUString aResourceURL( m_aResourceURL ); + Reference< XUIConfigurationManager > xUICfgMgr( m_xConfigSource ); + + aLock.unlock(); + + try + { + xUICfgMgr->replaceSettings( aResourceURL, m_xConfigData ); + } + catch( NoSuchElementException& ) + { + } + } + else if ( !m_bPersistent ) + { + // Transient menubar => Fill menubar with new data + impl_fillNewData(); + } + } +} +void UIConfigElementWrapperBase::impl_fillNewData() +{ +} +Reference< XIndexAccess > SAL_CALL UIConfigElementWrapperBase::getSettings( sal_Bool bWriteable ) throw ( RuntimeException ) +{ + ResetableGuard aLock( m_aLock ); + + //if ( m_bDisposed ) + // throw DisposedException(); + + if ( bWriteable ) + return Reference< XIndexAccess >( static_cast< OWeakObject * >( new RootItemContainer( m_xConfigData ) ), UNO_QUERY ); + + return m_xConfigData; +} + +Reference< XFrame > SAL_CALL UIConfigElementWrapperBase::getFrame() throw (RuntimeException) +{ + ResetableGuard aLock( m_aLock ); + Reference< XFrame > xFrame( m_xWeakFrame ); + return xFrame; +} + +::rtl::OUString SAL_CALL UIConfigElementWrapperBase::getResourceURL() throw (RuntimeException) +{ + ResetableGuard aLock( m_aLock ); + return m_aResourceURL; +} + +::sal_Int16 SAL_CALL UIConfigElementWrapperBase::getType() throw (RuntimeException) +{ + ResetableGuard aLock( m_aLock ); + return m_nType; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/framework/source/helper/uielementwrapperbase.cxx b/framework/source/helper/uielementwrapperbase.cxx new file mode 100644 index 000000000000..d2a890104b73 --- /dev/null +++ b/framework/source/helper/uielementwrapperbase.cxx @@ -0,0 +1,285 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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_framework.hxx" + +//_________________________________________________________________________________________________________________ +// my own includes +//_________________________________________________________________________________________________________________ +#include <helper/uielementwrapperbase.hxx> +#include <general.h> +#include <properties.h> +#include <threadhelp/resetableguard.hxx> + +//_________________________________________________________________________________________________________________ +// interface includes +//_________________________________________________________________________________________________________________ +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> + +//_________________________________________________________________________________________________________________ +// includes of other projects +//_________________________________________________________________________________________________________________ +#include <vcl/svapp.hxx> +#include <rtl/logfile.hxx> + +const int UIELEMENT_PROPHANDLE_RESOURCEURL = 1; +const int UIELEMENT_PROPHANDLE_TYPE = 2; +const int UIELEMENT_PROPHANDLE_FRAME = 3; +const int UIELEMENT_PROPCOUNT = 3; +const rtl::OUString UIELEMENT_PROPNAME_RESOURCEURL( RTL_CONSTASCII_USTRINGPARAM( "ResourceURL" )); +const rtl::OUString UIELEMENT_PROPNAME_TYPE( RTL_CONSTASCII_USTRINGPARAM( "Type" )); +const rtl::OUString UIELEMENT_PROPNAME_FRAME( RTL_CONSTASCII_USTRINGPARAM( "Frame" )); + +using namespace rtl; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::frame; + +namespace framework +{ + +//***************************************************************************************************************** +// XInterface, XTypeProvider +//***************************************************************************************************************** +DEFINE_XINTERFACE_8 ( UIElementWrapperBase , + OWeakObject , + DIRECT_INTERFACE( ::com::sun::star::lang::XTypeProvider ), + DIRECT_INTERFACE( ::com::sun::star::ui::XUIElement ), + DIRECT_INTERFACE( ::com::sun::star::beans::XMultiPropertySet ), + DIRECT_INTERFACE( ::com::sun::star::beans::XFastPropertySet ), + DIRECT_INTERFACE( ::com::sun::star::beans::XPropertySet ), + DIRECT_INTERFACE( ::com::sun::star::lang::XInitialization ), + DIRECT_INTERFACE( ::com::sun::star::util::XUpdatable ), + DIRECT_INTERFACE( ::com::sun::star::lang::XComponent ) + ) + +DEFINE_XTYPEPROVIDER_8 ( UIElementWrapperBase , + ::com::sun::star::lang::XTypeProvider , + ::com::sun::star::ui::XUIElement , + ::com::sun::star::beans::XMultiPropertySet , + ::com::sun::star::beans::XFastPropertySet , + ::com::sun::star::beans::XPropertySet , + ::com::sun::star::lang::XInitialization , + ::com::sun::star::util::XUpdatable , + ::com::sun::star::lang::XComponent + ) + +UIElementWrapperBase::UIElementWrapperBase( sal_Int16 nType ) + : ThreadHelpBase ( &Application::GetSolarMutex() ) + , ::cppu::OBroadcastHelperVar< ::cppu::OMultiTypeInterfaceContainerHelper, ::cppu::OMultiTypeInterfaceContainerHelper::keyType >( m_aLock.getShareableOslMutex() ) + , ::cppu::OPropertySetHelper ( *(static_cast< ::cppu::OBroadcastHelper* >(this)) ) + , ::cppu::OWeakObject ( ) + , m_aListenerContainer ( m_aLock.getShareableOslMutex() ) + , m_nType ( nType ) + , m_bInitialized ( sal_False ) + , m_bDisposed ( sal_False ) +{ +} + +UIElementWrapperBase::~UIElementWrapperBase() +{ +} + +void SAL_CALL UIElementWrapperBase::dispose() throw (::com::sun::star::uno::RuntimeException) +{ + // must be implemented by derived class + ResetableGuard aLock( m_aLock ); + m_bDisposed = sal_True; +} + +void SAL_CALL UIElementWrapperBase::addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException) +{ + m_aListenerContainer.addInterface( ::getCppuType( ( const css::uno::Reference< css::lang::XEventListener >* ) NULL ), xListener ); +} + +void SAL_CALL UIElementWrapperBase::removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException) +{ + m_aListenerContainer.removeInterface( ::getCppuType( ( const css::uno::Reference< css::lang::XEventListener >* ) NULL ), xListener ); +} + +void SAL_CALL UIElementWrapperBase::initialize( const Sequence< Any >& aArguments ) +throw ( Exception, RuntimeException ) +{ + ResetableGuard aLock( m_aLock ); + + if ( !m_bInitialized ) + { + for ( sal_Int32 n = 0; n < aArguments.getLength(); n++ ) + { + PropertyValue aPropValue; + if ( aArguments[n] >>= aPropValue ) + { + if ( aPropValue.Name.equalsAscii( "ResourceURL" )) + aPropValue.Value >>= m_aResourceURL; + else if ( aPropValue.Name.equalsAscii( "Frame" )) + { + Reference< XFrame > xFrame; + aPropValue.Value >>= xFrame; + m_xWeakFrame = xFrame; + } + } + } + + m_bInitialized = sal_True; + } +} + +// XUIElement +::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > SAL_CALL UIElementWrapperBase::getFrame() throw (::com::sun::star::uno::RuntimeException) +{ + ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > xFrame( m_xWeakFrame ); + return xFrame; +} + +::rtl::OUString SAL_CALL UIElementWrapperBase::getResourceURL() throw (::com::sun::star::uno::RuntimeException) +{ + return m_aResourceURL; +} + +::sal_Int16 SAL_CALL UIElementWrapperBase::getType() throw (::com::sun::star::uno::RuntimeException) +{ + return m_nType; +} + +// XUpdatable +void SAL_CALL UIElementWrapperBase::update() throw (::com::sun::star::uno::RuntimeException) +{ + // can be implemented by derived class +} + +// XPropertySet helper +sal_Bool SAL_CALL UIElementWrapperBase::convertFastPropertyValue( Any& /*aConvertedValue*/ , + Any& /*aOldValue*/ , + sal_Int32 /*nHandle*/ , + const Any& /*aValue*/ ) throw( com::sun::star::lang::IllegalArgumentException ) +{ + // Initialize state with FALSE !!! + // (Handle can be invalid) + return sal_False ; +} + +void SAL_CALL UIElementWrapperBase::setFastPropertyValue_NoBroadcast( sal_Int32 /*nHandle*/ , + const com::sun::star::uno::Any& /*aValue*/ ) throw( com::sun::star::uno::Exception ) +{ +} + +void SAL_CALL UIElementWrapperBase::getFastPropertyValue( com::sun::star::uno::Any& aValue , + sal_Int32 nHandle ) const +{ + switch( nHandle ) + { + case UIELEMENT_PROPHANDLE_RESOURCEURL: + aValue <<= m_aResourceURL; + break; + case UIELEMENT_PROPHANDLE_TYPE: + aValue <<= m_nType; + break; + case UIELEMENT_PROPHANDLE_FRAME: + Reference< XFrame > xFrame( m_xWeakFrame ); + aValue <<= xFrame; + break; + } +} + +::cppu::IPropertyArrayHelper& SAL_CALL UIElementWrapperBase::getInfoHelper() +{ + // Optimize this method ! + // We initialize a static variable only one time. And we don't must use a mutex at every call! + // For the first call; pInfoHelper is NULL - for the second call pInfoHelper is different from NULL! + static ::cppu::OPropertyArrayHelper* pInfoHelper = NULL; + + if( pInfoHelper == NULL ) + { + // Ready for multithreading + osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ; + + // Control this pointer again, another instance can be faster then these! + if( pInfoHelper == NULL ) + { + // Define static member to give structure of properties to baseclass "OPropertySetHelper". + // "impl_getStaticPropertyDescriptor" is a non exported and static funtion, who will define a static propertytable. + // "sal_True" say: Table is sorted by name. + static ::cppu::OPropertyArrayHelper aInfoHelper( impl_getStaticPropertyDescriptor(), sal_True ); + pInfoHelper = &aInfoHelper; + } + } + + return(*pInfoHelper); +} + +com::sun::star::uno::Reference< com::sun::star::beans::XPropertySetInfo > SAL_CALL UIElementWrapperBase::getPropertySetInfo() throw (::com::sun::star::uno::RuntimeException) +{ + // Optimize this method ! + // We initialize a static variable only one time. And we don't must use a mutex at every call! + // For the first call; pInfo is NULL - for the second call pInfo is different from NULL! + static com::sun::star::uno::Reference< com::sun::star::beans::XPropertySetInfo >* pInfo = NULL; + + if( pInfo == NULL ) + { + // Ready for multithreading + osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ; + // Control this pointer again, another instance can be faster then these! + if( pInfo == NULL ) + { + // Create structure of propertysetinfo for baseclass "OPropertySetHelper". + // (Use method "getInfoHelper()".) + static com::sun::star::uno::Reference< com::sun::star::beans::XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) ); + pInfo = &xInfo; + } + } + + return (*pInfo); +} + +const com::sun::star::uno::Sequence< com::sun::star::beans::Property > UIElementWrapperBase::impl_getStaticPropertyDescriptor() +{ + // Create a new static property array to initialize sequence! + // Table of all predefined properties of this class. Its used from OPropertySetHelper-class! + // Don't forget to change the defines (see begin of this file), if you add, change or delete a property in this list!!! + // It's necessary for methods of OPropertySetHelper. + // ATTENTION: + // YOU MUST SORT FOLLOW TABLE BY NAME ALPHABETICAL !!! + + static const com::sun::star::beans::Property pProperties[] = + { + com::sun::star::beans::Property( UIELEMENT_PROPNAME_FRAME , UIELEMENT_PROPHANDLE_FRAME , ::getCppuType((Reference< XFrame >*)NULL), com::sun::star::beans::PropertyAttribute::TRANSIENT | com::sun::star::beans::PropertyAttribute::READONLY ), + com::sun::star::beans::Property( UIELEMENT_PROPNAME_RESOURCEURL , UIELEMENT_PROPHANDLE_RESOURCEURL , ::getCppuType((sal_Int16*)NULL), com::sun::star::beans::PropertyAttribute::TRANSIENT | com::sun::star::beans::PropertyAttribute::READONLY ), + com::sun::star::beans::Property( UIELEMENT_PROPNAME_TYPE , UIELEMENT_PROPHANDLE_TYPE , ::getCppuType((const ::rtl::OUString*)NULL), com::sun::star::beans::PropertyAttribute::TRANSIENT | com::sun::star::beans::PropertyAttribute::READONLY ) + }; + // Use it to initialize sequence! + static const com::sun::star::uno::Sequence< com::sun::star::beans::Property > lPropertyDescriptor( pProperties, UIELEMENT_PROPCOUNT ); + // Return static "PropertyDescriptor" + return lPropertyDescriptor; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/framework/source/helper/vclstatusindicator.cxx b/framework/source/helper/vclstatusindicator.cxx new file mode 100644 index 000000000000..26baf432f2fe --- /dev/null +++ b/framework/source/helper/vclstatusindicator.cxx @@ -0,0 +1,234 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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_framework.hxx" +#include <helper/vclstatusindicator.hxx> + +//----------------------------------------------- +// includes of own modules +#include <threadhelp/readguard.hxx> +#include <threadhelp/writeguard.hxx> + +//----------------------------------------------- +// includes of interfaces + +//----------------------------------------------- +// includes of external modules + +#include <toolkit/unohlp.hxx> +#include <vcl/svapp.hxx> + +//----------------------------------------------- +// namespace + +namespace framework { + +//----------------------------------------------- +// definitions + +//----------------------------------------------- +DEFINE_XINTERFACE_1(VCLStatusIndicator , + OWeakObject , + DIRECT_INTERFACE(css::task::XStatusIndicator)) + +//----------------------------------------------- +VCLStatusIndicator::VCLStatusIndicator(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR , + const css::uno::Reference< css::awt::XWindow >& xParentWindow) + : ThreadHelpBase (&Application::GetSolarMutex()) + , ::cppu::OWeakObject( ) + , m_xSMGR (xSMGR ) + , m_xParentWindow (xParentWindow ) + , m_pStatusBar (0 ) + , m_nRange (0 ) + , m_nValue (0 ) +{ + if (!m_xParentWindow.is()) + throw css::uno::RuntimeException( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Cant work without a parent window!")), + static_cast< css::task::XStatusIndicator* >(this)); +} + +//----------------------------------------------- +VCLStatusIndicator::~VCLStatusIndicator() +{ +} + +//----------------------------------------------- +void SAL_CALL VCLStatusIndicator::start(const ::rtl::OUString& sText , + sal_Int32 nRange) + throw(css::uno::RuntimeException) +{ + // SAFE -> ---------------------------------- + ReadGuard aReadLock(m_aLock); + css::uno::Reference< css::awt::XWindow > xParentWindow = m_xParentWindow; + aReadLock.unlock(); + // <- SAFE ---------------------------------- + + // SOLAR SAFE -> ---------------------------- + { + SolarMutexGuard aSolarGuard; + + Window* pParentWindow = VCLUnoHelper::GetWindow(xParentWindow); + if (!m_pStatusBar) + m_pStatusBar = new StatusBar(pParentWindow, WB_3DLOOK|WB_BORDER); + + VCLStatusIndicator::impl_recalcLayout(m_pStatusBar, pParentWindow); + + m_pStatusBar->Show(); + m_pStatusBar->StartProgressMode(sText); + m_pStatusBar->SetProgressValue(0); + + // force repaint! + pParentWindow->Show(); + pParentWindow->Invalidate(INVALIDATE_CHILDREN); + pParentWindow->Flush(); + } + // <- SOLAR SAFE ---------------------------- + + // SAFE -> ---------------------------------- + WriteGuard aWriteLock(m_aLock); + m_sText = sText; + m_nRange = nRange; + m_nValue = 0; + aWriteLock.unlock(); + // <- SAFE ---------------------------------- +} + +//----------------------------------------------- +void SAL_CALL VCLStatusIndicator::reset() + throw(css::uno::RuntimeException) +{ + // SOLAR SAFE -> ---------------------------- + SolarMutexGuard aSolarGuard; + if (m_pStatusBar) + { + m_pStatusBar->SetProgressValue(0); + m_pStatusBar->SetText(String()); + } + // <- SOLAR SAFE ---------------------------- +} + +//----------------------------------------------- +void SAL_CALL VCLStatusIndicator::end() + throw(css::uno::RuntimeException) +{ + // SAFE -> ---------------------------------- + WriteGuard aWriteLock(m_aLock); + m_sText = ::rtl::OUString(); + m_nRange = 0; + m_nValue = 0; + aWriteLock.unlock(); + // <- SAFE ---------------------------------- + + // SOLAR SAFE -> ---------------------------- + { + SolarMutexGuard aSolarGuard; + if (m_pStatusBar) + { + m_pStatusBar->EndProgressMode(); + m_pStatusBar->Show(sal_False); + + delete m_pStatusBar; + m_pStatusBar = 0; + } + } + // <- SOLAR SAFE ---------------------------- +} + +//----------------------------------------------- +void SAL_CALL VCLStatusIndicator::setText(const ::rtl::OUString& sText) + throw(css::uno::RuntimeException) +{ + // SAFE -> ---------------------------------- + WriteGuard aWriteLock(m_aLock); + m_sText = sText; + aWriteLock.unlock(); + // <- SAFE ---------------------------------- + + // SOLAR SAFE -> ---------------------------- + { + SolarMutexGuard aSolarGuard; + if (m_pStatusBar) + m_pStatusBar->SetText(sText); + } + // <- SOLAR SAFE ---------------------------- +} + +//----------------------------------------------- +void SAL_CALL VCLStatusIndicator::setValue(sal_Int32 nValue) + throw(css::uno::RuntimeException) +{ + // SAFE -> ---------------------------------- + WriteGuard aWriteLock(m_aLock); + + if (nValue <= m_nRange) + m_nValue = nValue; + else + m_nValue = m_nRange; + + sal_Int32 nRange = m_nRange; + nValue = m_nValue; + + aWriteLock.unlock(); + // <- SAFE ---------------------------------- + + // normalize value to fit the range of 0-100 % + USHORT nPercent = sal::static_int_cast< USHORT >( + ::std::min( + ((nValue*100) / ::std::max(nRange,(sal_Int32)1)), (sal_Int32)100)); + + // SOLAR SAFE -> ---------------------------- + { + SolarMutexGuard aSolarGuard; + if (m_pStatusBar) + m_pStatusBar->SetProgressValue(nPercent); + } + // <- SOLAR SAFE ---------------------------- +} + +//----------------------------------------------- +void VCLStatusIndicator::impl_recalcLayout(Window* pStatusBar , + Window* pParentWindow) +{ + if ( + (!pStatusBar ) || + (!pParentWindow) + ) + return; + + Size aParentSize = pParentWindow->GetSizePixel(); + pStatusBar->SetPosSizePixel(0, + 0, + aParentSize.Width(), + aParentSize.Height()); +} + +} // namespace framework + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/framework/source/helper/wakeupthread.cxx b/framework/source/helper/wakeupthread.cxx new file mode 100644 index 000000000000..11828da7aee1 --- /dev/null +++ b/framework/source/helper/wakeupthread.cxx @@ -0,0 +1,86 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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_framework.hxx" + +//_______________________________________________ +// include files of own module +#include <helper/wakeupthread.hxx> +#include <threadhelp/readguard.hxx> +#include <threadhelp/writeguard.hxx> + +//_______________________________________________ +// namespace + +namespace framework{ + +//_______________________________________________ +// declarations + +//*********************************************** +WakeUpThread::WakeUpThread(const css::uno::Reference< css::util::XUpdatable >& xListener) + : ThreadHelpBase( ) + , m_xListener (xListener) +{ +} + +//*********************************************** +void SAL_CALL WakeUpThread::run() +{ + ::osl::Condition aSleeper; + + TimeValue aTime; + aTime.Seconds = 0; + aTime.Nanosec = 25000000; // 25 msec + + while(schedule()) + { + aSleeper.reset(); + aSleeper.wait(&aTime); + + // SAFE -> + ReadGuard aReadLock(m_aLock); + css::uno::Reference< css::util::XUpdatable > xListener(m_xListener.get(), css::uno::UNO_QUERY); + aReadLock.unlock(); + // <- SAFE + + if (xListener.is()) + xListener->update(); + } +} + +//*********************************************** +void SAL_CALL WakeUpThread::onTerminated() +{ + delete this; +} + +} // namespace framework + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |