summaryrefslogtreecommitdiff
path: root/sfx2
diff options
context:
space:
mode:
Diffstat (limited to 'sfx2')
-rw-r--r--sfx2/Library_sfx.mk3
-rw-r--r--sfx2/inc/backingcomp.hxx138
-rw-r--r--sfx2/source/appl/appuno.cxx2
-rw-r--r--sfx2/source/control/droptargetlistener.cxx222
-rw-r--r--sfx2/source/dialog/backingcomp.cxx831
-rw-r--r--sfx2/source/dialog/backingwindow.cxx690
-rw-r--r--sfx2/source/dialog/backingwindow.hxx130
-rw-r--r--sfx2/util/sfx.component3
8 files changed, 2019 insertions, 0 deletions
diff --git a/sfx2/Library_sfx.mk b/sfx2/Library_sfx.mk
index 52660b77b158..1c5f507300b8 100644
--- a/sfx2/Library_sfx.mk
+++ b/sfx2/Library_sfx.mk
@@ -129,6 +129,7 @@ $(eval $(call gb_Library_add_exception_objects,sfx,\
sfx2/source/config/evntconf \
sfx2/source/control/bindings \
sfx2/source/control/ctrlitem \
+ sfx2/source/control/droptargetlistener \
sfx2/source/control/minfitem \
sfx2/source/control/msg \
sfx2/source/control/msgpool \
@@ -150,6 +151,8 @@ $(eval $(call gb_Library_add_exception_objects,sfx,\
sfx2/source/control/thumbnailview \
sfx2/source/control/unoctitm \
sfx2/source/dialog/alienwarn \
+ sfx2/source/dialog/backingcomp \
+ sfx2/source/dialog/backingwindow \
sfx2/source/dialog/basedlgs \
sfx2/source/dialog/checkin \
sfx2/source/dialog/dialoghelper \
diff --git a/sfx2/inc/backingcomp.hxx b/sfx2/inc/backingcomp.hxx
new file mode 100644
index 000000000000..16a2ae7b6346
--- /dev/null
+++ b/sfx2/inc/backingcomp.hxx
@@ -0,0 +1,138 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef __SFX2_DIALOG_BACKINGCOMP_HXX_
+#define __SFX2_DIALOG_BACKINGCOMP_HXX_
+
+#include <com/sun/star/lang/XTypeProvider.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <com/sun/star/awt/XWindow.hpp>
+#include <com/sun/star/awt/XKeyListener.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+
+#include <com/sun/star/frame/XFrame.hpp>
+
+#include <com/sun/star/datatransfer/dnd/XDropTargetListener.hpp>
+#include <com/sun/star/lang/XEventListener.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+
+#include <cppuhelper/weak.hxx>
+
+//__________________________________________
+// definition
+
+//__________________________________________
+/**
+ implements the backing component.
+
+ This component is a special one, which doesn't provide a controller
+ nor a model. It supports the following features:
+ - Drag & Drop
+ - Key Accelerators
+ - Simple Menu
+ - Progress Bar
+ - Background
+ */
+class BackingComp : public css::lang::XTypeProvider
+ , public css::lang::XServiceInfo
+ , public css::lang::XInitialization
+ , public css::frame::XController // => XComponent
+ , public css::awt::XKeyListener // => XEventListener
+ , public ::cppu::OWeakObject
+{
+ //______________________________________
+ // member
+
+ private:
+ /** the global uno service manager.
+ Must be used to create own needed services. */
+ css::uno::Reference< css::uno::XComponentContext > m_xContext;
+
+ /** reference to the component window. */
+ css::uno::Reference< css::awt::XWindow > m_xWindow;
+
+ /** the owner frame of this component. */
+ css::uno::Reference< css::frame::XFrame > m_xFrame;
+
+ /** helper for drag&drop. */
+ css::uno::Reference< css::datatransfer::dnd::XDropTargetListener > m_xDropTargetListener;
+
+ //______________________________________
+ // interface
+
+ public:
+
+ BackingComp( const css::uno::Reference< css::uno::XComponentContext >& xContext );
+ virtual ~BackingComp( );
+
+ // XInterface
+ virtual css::uno::Any SAL_CALL queryInterface( const css::uno::Type& aType ) throw(css::uno::RuntimeException);
+ virtual void SAL_CALL acquire ( ) throw( );
+ virtual void SAL_CALL release ( ) throw( );
+
+ // XTypeProvide
+ virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes () throw(css::uno::RuntimeException);
+ virtual css::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() throw(css::uno::RuntimeException);
+
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName ( ) throw(css::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService ( const OUString& sServiceName ) throw(css::uno::RuntimeException);
+ virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames( ) throw(css::uno::RuntimeException);
+
+ // XInitialization
+ virtual void SAL_CALL initialize( const css::uno::Sequence< css::uno::Any >& lArgs ) throw(css::uno::Exception, css::uno::RuntimeException);
+
+ // XController
+ virtual void SAL_CALL attachFrame ( const css::uno::Reference< css::frame::XFrame >& xFrame ) throw(css::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL attachModel ( const css::uno::Reference< css::frame::XModel >& xModel ) throw(css::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL suspend ( sal_Bool bSuspend ) throw(css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL getViewData ( ) throw(css::uno::RuntimeException);
+ virtual void SAL_CALL restoreViewData( const css::uno::Any& aData ) throw(css::uno::RuntimeException);
+ virtual css::uno::Reference< css::frame::XModel > SAL_CALL getModel ( ) throw(css::uno::RuntimeException);
+ virtual css::uno::Reference< css::frame::XFrame > SAL_CALL getFrame ( ) throw(css::uno::RuntimeException);
+
+ // XKeyListener
+ virtual void SAL_CALL keyPressed ( const css::awt::KeyEvent& aEvent ) throw(css::uno::RuntimeException);
+ virtual void SAL_CALL keyReleased( const css::awt::KeyEvent& aEvent ) throw(css::uno::RuntimeException);
+
+ // XEventListener
+ virtual void SAL_CALL disposing( const css::lang::EventObject& aEvent ) throw(css::uno::RuntimeException);
+
+ // XComponent
+ virtual void SAL_CALL dispose ( ) throw(css::uno::RuntimeException);
+ virtual void SAL_CALL addEventListener ( const css::uno::Reference< css::lang::XEventListener >& xListener ) throw(css::uno::RuntimeException);
+ virtual void SAL_CALL removeEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener ) throw(css::uno::RuntimeException);
+
+ //______________________________________
+ // helper
+
+ public:
+
+ static css::uno::Sequence< OUString > SAL_CALL impl_getStaticSupportedServiceNames( );
+ static OUString SAL_CALL impl_getStaticImplementationName ( );
+ static css::uno::Reference< css::uno::XInterface > SAL_CALL impl_createInstance ( const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR ) throw( css::uno::Exception );
+ static css::uno::Reference< css::lang::XSingleServiceFactory > SAL_CALL impl_createFactory ( const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR );
+};
+
+#endif // __SFX2_DIALOG_BACKINGCOMP_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sfx2/source/appl/appuno.cxx b/sfx2/source/appl/appuno.cxx
index 4d1fcc16bafd..089946aeddfb 100644
--- a/sfx2/source/appl/appuno.cxx
+++ b/sfx2/source/appl/appuno.cxx
@@ -23,6 +23,7 @@
#include "sfx2/appuno.hxx"
+#include "backingcomp.hxx"
#include "SfxDocumentMetaData.hxx"
#include "appbaslib.hxx"
#include "doctemplates.hxx"
@@ -2275,6 +2276,7 @@ SFX2_DLLPUBLIC void* SAL_CALL sfx_component_getFactory(
// !!! ATTENTION !!!
// Write no ";" at end of line and dont forget "else" ! (see macro)
//=============================================================================
+ IF_NAME_CREATECOMPONENTFACTORY( BackingComp )
IF_NAME_CREATECOMPONENTFACTORY( SfxGlobalEvents_Impl )
IF_NAME_CREATECOMPONENTFACTORY( SfxFrameLoader_Impl )
IF_NAME_CREATECOMPONENTFACTORY( SfxMacroLoader )
diff --git a/sfx2/source/control/droptargetlistener.cxx b/sfx2/source/control/droptargetlistener.cxx
new file mode 100644
index 000000000000..cb40283250b7
--- /dev/null
+++ b/sfx2/source/control/droptargetlistener.cxx
@@ -0,0 +1,222 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sfx2/droptargetlistener.hxx>
+
+#include <com/sun/star/datatransfer/dnd/DNDConstants.hpp>
+#include <com/sun/star/frame/XDispatch.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/util/URLTransformer.hpp>
+#include <com/sun/star/util/XURLTransformer.hpp>
+
+#include <svtools/transfer.hxx>
+#include <unotools/localfilehelper.hxx>
+#include <sot/filelist.hxx>
+#include <comphelper/processfactory.hxx>
+
+#include <osl/file.hxx>
+#include <vcl/svapp.hxx>
+
+const OUString SPECIALTARGET_DEFAULT("_default");
+
+DropTargetListener::DropTargetListener( const css::uno::Reference< css::uno::XComponentContext >& xContext,
+ const css::uno::Reference< css::frame::XFrame >& xFrame )
+ : m_xContext ( xContext )
+ , m_xTargetFrame ( xFrame )
+ , m_pFormats ( new DataFlavorExVector )
+{
+}
+
+// -----------------------------------------------------------------------------
+
+DropTargetListener::~DropTargetListener()
+{
+ m_xTargetFrame.clear();
+ m_xContext.clear();
+ delete m_pFormats;
+ m_pFormats = NULL;
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL DropTargetListener::disposing( const css::lang::EventObject& ) throw( css::uno::RuntimeException )
+{
+ m_xTargetFrame.clear();
+ m_xContext.clear();
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL DropTargetListener::drop( const css::datatransfer::dnd::DropTargetDropEvent& dtde ) throw( css::uno::RuntimeException )
+{
+ const sal_Int8 nAction = dtde.DropAction;
+
+ try
+ {
+ if ( css::datatransfer::dnd::DNDConstants::ACTION_NONE != nAction )
+ {
+ TransferableDataHelper aHelper( dtde.Transferable );
+ sal_Bool bFormatFound = sal_False;
+ FileList aFileList;
+
+ // at first check filelist format
+ if ( aHelper.GetFileList( SOT_FORMAT_FILE_LIST, aFileList ) )
+ {
+ sal_uLong i, nCount = aFileList.Count();
+ for ( i = 0; i < nCount; ++i )
+ implts_OpenFile( aFileList.GetFile(i) );
+ bFormatFound = sal_True;
+ }
+
+ // then, if necessary, the file format
+ String aFilePath;
+ if ( !bFormatFound && aHelper.GetString( SOT_FORMAT_FILE, aFilePath ) )
+ implts_OpenFile( aFilePath );
+ }
+ dtde.Context->dropComplete( css::datatransfer::dnd::DNDConstants::ACTION_NONE != nAction );
+ }
+ catch( const ::com::sun::star::uno::Exception& )
+ {
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL DropTargetListener::dragEnter( const css::datatransfer::dnd::DropTargetDragEnterEvent& dtdee ) throw( css::uno::RuntimeException )
+{
+ try
+ {
+ implts_BeginDrag( dtdee.SupportedDataFlavors );
+ }
+ catch( const ::com::sun::star::uno::Exception& )
+ {
+ }
+
+ dragOver( dtdee );
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL DropTargetListener::dragExit( const css::datatransfer::dnd::DropTargetEvent& ) throw( css::uno::RuntimeException )
+{
+ try
+ {
+ implts_EndDrag();
+ }
+ catch( const ::com::sun::star::uno::Exception& )
+ {
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL DropTargetListener::dragOver( const css::datatransfer::dnd::DropTargetDragEvent& dtde ) throw( css::uno::RuntimeException )
+{
+ try
+ {
+ sal_Bool bAccept = ( implts_IsDropFormatSupported( SOT_FORMAT_FILE ) ||
+ implts_IsDropFormatSupported( SOT_FORMAT_FILE_LIST ) );
+
+ if ( !bAccept )
+ dtde.Context->rejectDrag();
+ else
+ dtde.Context->acceptDrag( css::datatransfer::dnd::DNDConstants::ACTION_COPY );
+ }
+ catch( const ::com::sun::star::uno::Exception& )
+ {
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void SAL_CALL DropTargetListener::dropActionChanged( const css::datatransfer::dnd::DropTargetDragEvent& ) throw( css::uno::RuntimeException )
+{
+}
+
+void DropTargetListener::implts_BeginDrag( const css::uno::Sequence< css::datatransfer::DataFlavor >& rSupportedDataFlavors )
+{
+ /* SAFE { */
+ SolarMutexGuard aGuard;
+ m_pFormats->clear();
+ TransferableDataHelper::FillDataFlavorExVector(rSupportedDataFlavors,*m_pFormats);
+ /* } SAFE */
+}
+
+void DropTargetListener::implts_EndDrag()
+{
+ /* SAFE { */
+ SolarMutexGuard aGuard;
+ m_pFormats->clear();
+ /* } SAFE */
+}
+
+sal_Bool DropTargetListener::implts_IsDropFormatSupported( SotFormatStringId nFormat )
+{
+ /* SAFE { */
+ SolarMutexGuard aGuard;
+ DataFlavorExVector::iterator aIter( m_pFormats->begin() ), aEnd( m_pFormats->end() );
+ sal_Bool bRet = sal_False;
+
+ while ( aIter != aEnd )
+ {
+ if ( nFormat == (*aIter++).mnSotId )
+ {
+ bRet = sal_True;
+ aIter = aEnd;
+ }
+ }
+
+ return bRet;
+ /* } SAFE */
+}
+
+void DropTargetListener::implts_OpenFile( const String& rFilePath )
+{
+ OUString aFileURL;
+ if ( !::utl::LocalFileHelper::ConvertPhysicalNameToURL( rFilePath, aFileURL ) )
+ aFileURL = rFilePath;
+
+ ::osl::FileStatus aStatus( osl_FileStatus_Mask_FileURL );
+ ::osl::DirectoryItem aItem;
+ if( ::osl::FileBase::E_None == ::osl::DirectoryItem::get( aFileURL, aItem ) &&
+ ::osl::FileBase::E_None == aItem.getFileStatus( aStatus ) )
+ aFileURL = aStatus.getFileURL();
+
+ // open file
+ /* SAFE { */
+ SolarMutexGuard aGuard;
+ css::uno::Reference< css::frame::XFrame > xTargetFrame( m_xTargetFrame.get(), css::uno::UNO_QUERY );
+ css::uno::Reference< css::util::XURLTransformer > xParser ( css::util::URLTransformer::create(m_xContext) );
+
+ if (xTargetFrame.is() && xParser.is())
+ {
+ css::util::URL aURL;
+ aURL.Complete = aFileURL;
+ xParser->parseStrict(aURL);
+
+ css::uno::Reference < css::frame::XDispatchProvider > xProvider( xTargetFrame, css::uno::UNO_QUERY );
+ css::uno::Reference< css::frame::XDispatch > xDispatcher = xProvider->queryDispatch( aURL, SPECIALTARGET_DEFAULT, 0 );
+ if ( xDispatcher.is() )
+ xDispatcher->dispatch( aURL, css::uno::Sequence < css::beans::PropertyValue >() );
+ }
+ /* } SAFE */
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sfx2/source/dialog/backingcomp.cxx b/sfx2/source/dialog/backingcomp.cxx
new file mode 100644
index 000000000000..6b7cd16d249b
--- /dev/null
+++ b/sfx2/source/dialog/backingcomp.cxx
@@ -0,0 +1,831 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "backingcomp.hxx"
+
+#include "backingwindow.hxx"
+
+#include <sfx2/droptargetlistener.hxx>
+
+#include <helpid.hrc>
+
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/util/XURLTransformer.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/awt/Toolkit.hpp>
+#include <com/sun/star/awt/XDataTransferProviderAccess.hpp>
+#include <com/sun/star/datatransfer/dnd/XDropTarget.hpp>
+#include <com/sun/star/awt/KeyEvent.hpp>
+#include <com/sun/star/awt/KeyModifier.hpp>
+#include <com/sun/star/frame/XLayoutManager.hpp>
+#include <com/sun/star/util/URLTransformer.hpp>
+
+#include <comphelper/processfactory.hxx>
+#include <cppuhelper/typeprovider.hxx>
+#include <cppuhelper/factory.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+#include <vcl/keycod.hxx>
+#include <vcl/wrkwin.hxx>
+#include <vcl/svapp.hxx>
+#include <rtl/ustrbuf.hxx>
+
+#include <svl/solar.hrc>
+#include <svl/urihelper.hxx>
+#include <osl/file.hxx>
+#include <unotools/configmgr.hxx>
+
+#include <unotools/bootstrap.hxx>
+
+const char SERVICENAME_FRAMECONTROLLER[] = "com.sun.star.frame.Controller";
+const char IMPLEMENTATIONNAME_STARTMODULE[] = "com.sun.star.comp.sfx2.BackingComp";
+const char FRAME_PROPNAME_LAYOUTMANAGER[] = "LayoutManager";
+const char HID_BACKINGWINDOW[] = "FWK_HID_BACKINGWINDOW";
+const char SPECIALTARGET_MENUBAR[] = "_menubar";
+
+//_______________________________________________
+
+//_______________________________________________
+
+BackingComp::BackingComp( const css::uno::Reference< css::uno::XComponentContext >& xContext )
+ : m_xContext(xContext)
+{
+}
+
+//_______________________________________________
+
+BackingComp::~BackingComp()
+{
+}
+
+//_______________________________________________
+
+/** return information about supported interfaces.
+
+ Some interfaces are supported by his class directly, but some other ones are
+ used by aggregation. An instance of this class must provide some window interfaces.
+ But it must represent a VCL window behind such interfaces too! So we use an internal
+ saved window member to ask it for it's interfaces and return it. But we must be aware then,
+ that it can be destroyed from outside too ...
+
+ @param aType
+ describe the required interface type
+
+ @return An Any holding the instance, which provides the queried interface.
+ Note: There exist two possible results ... this instance itself and her window member!
+ */
+
+css::uno::Any SAL_CALL BackingComp::queryInterface( /*IN*/ const css::uno::Type& aType )
+ throw(css::uno::RuntimeException)
+{
+ css::uno::Any aResult;
+
+ // first look for own supported interfaces
+ aResult = ::cppu::queryInterface(
+ aType,
+ static_cast< css::lang::XTypeProvider* >(this),
+ static_cast< css::lang::XServiceInfo* >(this),
+ static_cast< css::lang::XInitialization* >(this),
+ static_cast< css::frame::XController* >(this),
+ static_cast< css::lang::XComponent* >(this),
+ static_cast< css::lang::XEventListener* >(this),
+ static_cast< css::awt::XKeyListener* >(static_cast< css::lang::XEventListener* >(this)));
+
+ // then look for supported window interfaces
+ // Note: They exist only, if this instance was initialized
+ // with a valid window reference. It's aggregation on demand ...
+ if (!aResult.hasValue())
+ {
+ /* SAFE { */
+ SolarMutexGuard aGuard;
+ if (m_xWindow.is())
+ aResult = m_xWindow->queryInterface(aType);
+ /* } SAFE */
+ }
+
+ // look for XWeak and XInterface
+ if (!aResult.hasValue())
+ aResult = OWeakObject::queryInterface(aType);
+
+ return aResult;
+}
+
+//_______________________________________________
+
+/** increase ref count of this instance.
+ */
+
+void SAL_CALL BackingComp::acquire()
+ throw()
+{
+ OWeakObject::acquire();
+}
+
+//_______________________________________________
+
+/** decrease ref count of this instance.
+ */
+
+void SAL_CALL BackingComp::release()
+ throw()
+{
+ OWeakObject::release();
+}
+
+//_______________________________________________
+
+/** return collection about all supported interfaces.
+
+ 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; pTypeCollection is NULL -
+ for the second call pTypeCollection is different from NULL!
+
+ @return A list of all supported interface types.
+*/
+
+css::uno::Sequence< css::uno::Type > SAL_CALL BackingComp::getTypes()
+ throw(css::uno::RuntimeException)
+{
+ static ::cppu::OTypeCollection* pTypeCollection = NULL;
+ if (!pTypeCollection)
+ {
+ /* GLOBAL SAFE { */
+ ::osl::MutexGuard aGlobalLock(::osl::Mutex::getGlobalMutex());
+ // Control these pointer again ... it can be, that another instance will be faster then this one!
+ if (!pTypeCollection)
+ {
+ /* LOCAL SAFE { */
+ SolarMutexGuard aGuard;
+ css::uno::Reference< css::lang::XTypeProvider > xProvider(m_xWindow, css::uno::UNO_QUERY);
+
+ css::uno::Sequence< css::uno::Type > lWindowTypes;
+ if (xProvider.is())
+ lWindowTypes = xProvider->getTypes();
+
+ static ::cppu::OTypeCollection aTypeCollection(
+ ::getCppuType((const ::com::sun::star::uno::Reference< css::lang::XInitialization >*)NULL ),
+ ::getCppuType((const ::com::sun::star::uno::Reference< css::lang::XTypeProvider >*)NULL ),
+ ::getCppuType((const ::com::sun::star::uno::Reference< css::lang::XServiceInfo >*)NULL ),
+ ::getCppuType((const ::com::sun::star::uno::Reference< css::frame::XController >*)NULL ),
+ ::getCppuType((const ::com::sun::star::uno::Reference< css::lang::XComponent >*)NULL ),
+ lWindowTypes);
+
+ pTypeCollection = &aTypeCollection;
+ /* } LOCAL SAFE */
+ }
+ /* } GLOBAL SAFE */
+ }
+ return pTypeCollection->getTypes();
+}
+
+//_______________________________________________
+
+/** create one unique Id for all instances of this class.
+
+ 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; pID is NULL - for the second call pID is different from NULL!
+
+ @return A byte array, which represent the unique id.
+*/
+
+css::uno::Sequence< sal_Int8 > SAL_CALL BackingComp::getImplementationId()
+ throw(css::uno::RuntimeException)
+{
+ static ::cppu::OImplementationId* pID = NULL;
+ if (!pID)
+ {
+ /* GLOBAL SAFE { */
+ ::osl::MutexGuard aLock(::osl::Mutex::getGlobalMutex());
+ // Control these pointer again ... it can be, that another instance will be faster then this one!
+ if (!pID)
+ {
+ static ::cppu::OImplementationId aID(sal_False);
+ pID = &aID;
+ }
+ /* } GLOBAL SAFE */
+ }
+ return pID->getImplementationId();
+}
+
+//_______________________________________________
+
+/** returns a static implementation name for this UNO service.
+
+ Because this value is needed at different places and our class is used
+ by some generic macros too, we have to use a static impl method for that!
+
+ @see impl_getStaticImplementationName()
+ @see IMPLEMENTATIONNAME
+
+ @return The implementation name of this class.
+*/
+
+OUString SAL_CALL BackingComp::getImplementationName()
+ throw(css::uno::RuntimeException)
+{
+ return impl_getStaticImplementationName();
+}
+
+//_______________________________________________
+
+/** returns information about supported services.
+
+ Because this value is needed at different places and our class is used
+ by some generic macros too, we have to use a static impl method for that!
+
+ @see impl_getStaticSupportedServiceNames()
+ @see SERVICENAME
+
+ @return <TRUE/> if the queried service is supported;
+ <br><FALSE/> otherwise.
+*/
+
+sal_Bool SAL_CALL BackingComp::supportsService( /*IN*/ const OUString& sServiceName )
+ throw(css::uno::RuntimeException)
+{
+ return (
+ sServiceName.equals("com.sun.star.frame.StartModule") ||
+ sServiceName.equals(SERVICENAME_FRAMECONTROLLER)
+ );
+}
+
+//_______________________________________________
+
+/** returns collection of supported services.
+
+ Because this value is needed at different places and our class is used
+ by some generic macros too, we have to use a static impl method for that!
+
+ @see impl_getStaticSupportedServiceNames()
+ @see SERVICENAME
+
+ @return A list of all supported uno service names.
+*/
+
+css::uno::Sequence< OUString > SAL_CALL BackingComp::getSupportedServiceNames()
+ throw(css::uno::RuntimeException)
+{
+ return impl_getStaticSupportedServiceNames();
+}
+
+//_______________________________________________
+
+/** returns static implementation name.
+
+ Because this value is needed at different places and our class is used
+ by some generic macros too, we have to use a static impl method for that!
+
+ @see impl_getStaticSupportedServiceNames()
+ @see SERVICENAME
+
+ @return The implementation name of this class.
+*/
+
+OUString BackingComp::impl_getStaticImplementationName()
+{
+ return OUString( IMPLEMENTATIONNAME_STARTMODULE );
+}
+
+//_______________________________________________
+
+/** returns static list of supported service names.
+
+ Because this value is needed at different places and our class is used
+ by some generic macros too, we have to use a static impl method for that!
+
+ @see impl_getStaticSupportedServiceNames()
+ @see SERVICENAME
+
+ @return A list of all supported uno service names.
+*/
+
+css::uno::Sequence< OUString > BackingComp::impl_getStaticSupportedServiceNames()
+{
+ css::uno::Sequence< OUString > lNames(1);
+ lNames[0] = "com.sun.star.frame.StartModule";
+ return lNames;
+}
+
+//_______________________________________________
+
+/** returns a new instance of this class.
+
+ This factory method is registered inside the UNO runtime
+ and will be called for every createInstance() request from outside,
+ which wish to use this service.
+
+ @param xSMGR
+ reference to the uno service manager, which call us
+ We use it too, to set it at the new created instance.
+
+ @return A new instance as uno reference.
+*/
+
+css::uno::Reference< css::uno::XInterface > SAL_CALL BackingComp::impl_createInstance( /*IN*/ const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR )
+ throw(css::uno::Exception)
+{
+ BackingComp* pObject = new BackingComp(comphelper::getComponentContext(xSMGR));
+ return css::uno::Reference< css::uno::XInterface >(static_cast< ::cppu::OWeakObject* >(pObject), css::uno::UNO_QUERY);
+}
+
+//_______________________________________________
+
+/** returns a new factory instance for instances of this class.
+
+ It uses a helper class of the cppuhelper project as factory.
+ It will be initialized with all neccessary information and
+ will be able afterwards to create instance of this class.
+ This factory call us back inside our method impl_createInstance().
+ So we can create and initialize ourself. Only filtering of creation
+ requests will be done by this factory.
+
+ @param xSMGR
+ reference to the uno service manager, which call us
+
+ @return A new instance of our factory.
+*/
+
+css::uno::Reference< css::lang::XSingleServiceFactory > BackingComp::impl_createFactory( /*IN*/ const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR )
+{
+ css::uno::Reference< css::lang::XSingleServiceFactory > xReturn(
+ cppu::createSingleFactory(
+ xSMGR,
+ BackingComp::impl_getStaticImplementationName(),
+ BackingComp::impl_createInstance,
+ BackingComp::impl_getStaticSupportedServiceNames()));
+ return xReturn;
+}
+
+//_______________________________________________
+
+/**
+ attach this component to a target frame.
+
+ We has to use the container window of this frame as parent window of our own component window.
+ But it's not allowed to work with it realy. May another component used it too.
+ Currently we need it only to create our child component window and support it's
+ interfaces inside our queryInterface() method. The user of us must have e.g. the
+ XWindow interface of it to be able to call setComponent(xWindow,xController) at the
+ frame!
+
+ May he will do the following things:
+
+ <listing>
+ XController xBackingComp = (XController)UnoRuntime.queryInterface(
+ XController.class,
+ xSMGR.createInstance(SERVICENAME_STARTMODULE));
+
+ // at this time XWindow isn't present at this instance!
+ XWindow xBackingComp = (XWindow)UnoRuntime.queryInterface(
+ XWindow.class,
+ xBackingComp);
+
+ // attach controller to the frame
+ // We will use it's container window, to create
+ // the component window. From now we offer the window interfaces!
+ xBackingComp.attachFrame(xFrame);
+
+ XWindow xBackingComp = (XWindow)UnoRuntime.queryInterface(
+ XWindow.class,
+ xBackingComp);
+
+ // Our user can set us at the frame as new component
+ xFrame.setComponent(xBackingWin, xBackingComp);
+
+ // But that had no effect to our view state.
+ // We must be started to create our UI elements like e.g. menu, title, background ...
+ XInitialization xBackingInit = (XInitialization)UnoRuntime.queryInterface(
+ XInitialization.class,
+ xBackingComp);
+
+ xBackingInit.initialize(lArgs);
+ </listing>
+
+ @param xFrame
+ reference to our new target frame
+
+ @throw com::sun::star::uno::RuntimeException
+ if the given frame reference is wrong or component window couldn't be created
+ successfully.
+ We throw it too, if we already attached to a frame. Because we don't support
+ reparenting of our component window on demand!
+*/
+
+void SAL_CALL BackingComp::attachFrame( /*IN*/ const css::uno::Reference< css::frame::XFrame >& xFrame )
+ throw (css::uno::RuntimeException)
+{
+ /* SAFE */
+ SolarMutexGuard aGuard;
+
+ // check some required states
+ if (m_xFrame.is())
+ throw css::uno::RuntimeException(
+ OUString("already attached"),
+ static_cast< ::cppu::OWeakObject* >(this));
+
+ if (!xFrame.is())
+ throw css::uno::RuntimeException(
+ OUString("invalid frame reference"),
+ static_cast< ::cppu::OWeakObject* >(this));
+
+ if (!m_xWindow.is())
+ return; // disposed
+
+ // safe the frame reference
+ m_xFrame = xFrame;
+
+ // establish drag&drop mode
+ DropTargetListener* pDropListener = new DropTargetListener( m_xContext, m_xFrame);
+ m_xDropTargetListener = css::uno::Reference< css::datatransfer::dnd::XDropTargetListener >(static_cast< ::cppu::OWeakObject* >(pDropListener), css::uno::UNO_QUERY);
+
+ css::uno::Reference< css::awt::XToolkit2 > xToolkit = css::awt::Toolkit::create( m_xContext );
+ css::uno::Reference< css::datatransfer::dnd::XDropTarget > xDropTarget = xToolkit->getDropTarget(m_xWindow);
+ if (xDropTarget.is())
+ {
+ xDropTarget->addDropTargetListener(m_xDropTargetListener);
+ xDropTarget->setActive(sal_True);
+ }
+
+ // initialize the component and it's parent window
+ css::uno::Reference< css::awt::XWindow > xParentWindow = xFrame->getContainerWindow();
+ WorkWindow* pParent = (WorkWindow*)VCLUnoHelper::GetWindow(xParentWindow);
+ Window* pWindow = VCLUnoHelper::GetWindow(m_xWindow);
+
+ // disable full screen mode of the frame!
+ if (pParent && pParent->IsFullScreenMode())
+ {
+ pParent->ShowFullScreenMode(sal_False);
+ pParent->SetMenuBarMode(MENUBAR_MODE_NORMAL);
+ }
+
+ // create the menu bar for the backing component
+ css::uno::Reference< css::beans::XPropertySet > xPropSet(m_xFrame, css::uno::UNO_QUERY_THROW);
+ css::uno::Reference< css::frame::XLayoutManager > xLayoutManager;
+ xPropSet->getPropertyValue(FRAME_PROPNAME_LAYOUTMANAGER) >>= xLayoutManager;
+ if (xLayoutManager.is())
+ {
+ xLayoutManager->lock();
+ xLayoutManager->createElement("private:resource/menubar/menubar");
+ xLayoutManager->unlock();
+ }
+
+ if (pWindow)
+ {
+ // set help ID for our canvas
+ pWindow->SetHelpId(HID_BACKINGWINDOW);
+ }
+
+ // inform BackingWindow about frame
+ BackingWindow* pBack = dynamic_cast<BackingWindow*>(pWindow );
+ if( pBack )
+ pBack->setOwningFrame( m_xFrame );
+
+ /* } SAFE */
+}
+
+//_______________________________________________
+
+/** not supported.
+
+ This component does not know any model. It will be represented by a window and
+ it's controller only.
+
+ return <FALSE/> everytime.
+ */
+
+sal_Bool SAL_CALL BackingComp::attachModel( /*IN*/ const css::uno::Reference< css::frame::XModel >& )
+ throw (css::uno::RuntimeException)
+{
+ return sal_False;
+}
+
+//_______________________________________________
+
+/** not supported.
+
+ This component does not know any model. It will be represented by a window and
+ it's controller only.
+
+ return An empty reference every time.
+ */
+
+css::uno::Reference< css::frame::XModel > SAL_CALL BackingComp::getModel()
+ throw (css::uno::RuntimeException)
+{
+ return css::uno::Reference< css::frame::XModel >();
+}
+
+//_______________________________________________
+
+/** not supported.
+
+ return An empty value.
+ */
+
+css::uno::Any SAL_CALL BackingComp::getViewData()
+ throw (css::uno::RuntimeException)
+{
+ return css::uno::Any();
+}
+
+//_______________________________________________
+
+/** not supported.
+
+ @param aData
+ not used.
+ */
+
+void SAL_CALL BackingComp::restoreViewData( /*IN*/ const css::uno::Any& )
+ throw (css::uno::RuntimeException)
+{
+}
+
+//_______________________________________________
+
+/** returns the attached frame for this component.
+
+ @see attachFrame()
+
+ @return The internaly saved frame reference.
+ Can be null, if attachFrame() was not called before.
+ */
+
+css::uno::Reference< css::frame::XFrame > SAL_CALL BackingComp::getFrame()
+ throw (css::uno::RuntimeException)
+{
+ /* SAFE { */
+ SolarMutexGuard aGuard;
+ return m_xFrame;
+ /* } SAFE */
+}
+
+//_______________________________________________
+
+/** ask controller for it's current working state.
+
+ If somehwere whish to close this component, it must suspend the controller before.
+ That will be a chance for it to disagree with that AND show any UI for a possible
+ UI user.
+
+ @param bSuspend
+ If its set to sal_True this controller should be suspended.
+ sal_False will resuspend it.
+
+ @return sal_True if the request could be finished successfully; sal_False otherwise.
+ */
+
+sal_Bool SAL_CALL BackingComp::suspend( /*IN*/ sal_Bool )
+ throw (css::uno::RuntimeException)
+{
+ /* FIXME ... implemented by using default :-( */
+ return sal_True;
+}
+
+//_______________________________________________
+
+/** callback from our window member.
+
+ Our internal saved window wish to die. It will be disposed from outside (may be the frame)
+ and inform us. We must release its reference only here. Of course we check the given reference
+ here and reject callback from unknown sources.
+
+ Note: deregistration as listener isnt neccessary here. The broadcaster do it automaticly.
+
+ @param aEvent
+ describe the broadcaster of this callback
+
+ @throw ::com::sun::star::uno::RuntimeException
+ if the broadcaster doesn't represent the expected window reference.
+*/
+
+void SAL_CALL BackingComp::disposing( /*IN*/ const css::lang::EventObject& aEvent )
+ throw(css::uno::RuntimeException)
+{
+ // Attention: dont free m_pAccExec here! see comments inside dtor and
+ // keyPressed() for further details.
+
+ /* SAFE { */
+ SolarMutexGuard aGuard;
+
+ if (!aEvent.Source.is() || aEvent.Source!=m_xWindow || !m_xWindow.is())
+ throw css::uno::RuntimeException(
+ OUString("unexpected source or called twice"),
+ static_cast< ::cppu::OWeakObject* >(this));
+
+ m_xWindow = css::uno::Reference< css::awt::XWindow >();
+
+ /* } SAFE */
+}
+
+//_______________________________________________
+
+/** kill this instance.
+
+ It can be called from our owner frame only. But there is no possibility to check the calli.
+ We have to release all our internal used resources and die. From this point we can throw
+ DisposedExceptions for every further interface request ... but current implementation doesn`t do so ...
+
+*/
+
+void SAL_CALL BackingComp::dispose()
+ throw(css::uno::RuntimeException)
+{
+ /* SAFE { */
+ SolarMutexGuard aGuard;
+
+ // kill the menu
+ css::util::URL aURL;
+ aURL.Complete = OUString(".uno:close");
+ css::uno::Reference< css::util::XURLTransformer > xParser = css::util::URLTransformer::create(m_xContext);
+ if (xParser.is())
+ xParser->parseStrict(aURL);
+
+ css::uno::Reference< css::frame::XDispatchProvider > xProvider(m_xFrame, css::uno::UNO_QUERY);
+ if (xProvider.is())
+ {
+ css::uno::Reference< css::frame::XDispatch > xDispatch = xProvider->queryDispatch(aURL, SPECIALTARGET_MENUBAR, 0);
+ if (xDispatch.is())
+ xDispatch->dispatch(aURL, css::uno::Sequence< css::beans::PropertyValue>());
+ }
+
+ // deregister drag&drop helper
+ if (m_xDropTargetListener.is())
+ {
+ css::uno::Reference< css::awt::XToolkit2 > xToolkit = css::awt::Toolkit::create( m_xContext );
+ css::uno::Reference< css::datatransfer::dnd::XDropTarget > xDropTarget = xToolkit->getDropTarget(m_xWindow);
+ if (xDropTarget.is())
+ {
+ xDropTarget->removeDropTargetListener(m_xDropTargetListener);
+ xDropTarget->setActive(sal_False);
+ }
+ m_xDropTargetListener = css::uno::Reference< css::datatransfer::dnd::XDropTargetListener >();
+ }
+
+ // stop listening at the window
+ if (m_xWindow.is())
+ {
+ css::uno::Reference< css::lang::XComponent > xBroadcaster(m_xWindow, css::uno::UNO_QUERY);
+ if (xBroadcaster.is())
+ {
+ css::uno::Reference< css::lang::XEventListener > xEventThis(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY);
+ xBroadcaster->removeEventListener(xEventThis);
+ }
+ css::uno::Reference< css::awt::XKeyListener > xKeyThis(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY);
+ m_xWindow->removeKeyListener(xKeyThis);
+ m_xWindow = css::uno::Reference< css::awt::XWindow >();
+ }
+
+ // forget all other used references
+ m_xFrame.clear();
+ m_xContext.clear();
+
+ /* } SAFE */
+}
+
+//_______________________________________________
+
+/** not supported.
+
+ @param xListener
+ not used.
+
+ @throw ::com::sun::star::uno::RuntimeException
+ because the listener expect to be holded alive by this container.
+ We must inform it about this unsupported feature.
+ */
+
+void SAL_CALL BackingComp::addEventListener( /*IN*/ const css::uno::Reference< css::lang::XEventListener >& )
+ throw(css::uno::RuntimeException)
+{
+ throw css::uno::RuntimeException(
+ OUString("not supported"),
+ static_cast< ::cppu::OWeakObject* >(this));
+}
+
+//_______________________________________________
+
+/** not supported.
+
+ Because registration is not supported too, we must do nothing here. Nobody can call this method realy.
+
+ @param xListener
+ not used.
+ */
+
+void SAL_CALL BackingComp::removeEventListener( /*IN*/ const css::uno::Reference< css::lang::XEventListener >& )
+ throw(css::uno::RuntimeException)
+{
+}
+
+//_______________________________________________
+
+/**
+ force initialiation for this component.
+
+ Inside attachFrame() we created our component window. But it was not allowed there, to
+ initialitze it. E.g. the menu must be set at the container window of the frame, which
+ is our parent window. But may at that time another component used it.
+ That's why our creator has to inform us, when it's time to initialize us realy.
+ Currently only calling of this method must be done. But further implementatoins
+ can use special in parameter to configure this initialization ...
+
+ @param lArgs
+ currently not used
+
+ @throw com::sun::star::uno::RuntimeException
+ if some resources are missing
+ Means if may be attachedFrame() wasn't called before.
+ */
+
+void SAL_CALL BackingComp::initialize( /*IN*/ const css::uno::Sequence< css::uno::Any >& lArgs )
+ throw(css::uno::Exception, css::uno::RuntimeException)
+{
+ /* SAFE { */
+ SolarMutexGuard aGuard;
+
+ if (m_xWindow.is())
+ throw css::uno::Exception(
+ OUString("already initialized"),
+ static_cast< ::cppu::OWeakObject* >(this));
+
+ css::uno::Reference< css::awt::XWindow > xParentWindow;
+ if (
+ (lArgs.getLength()!=1 ) ||
+ (!(lArgs[0] >>= xParentWindow)) ||
+ (!xParentWindow.is() )
+ )
+ {
+ throw css::uno::Exception(
+ OUString("wrong or corrupt argument list"),
+ static_cast< ::cppu::OWeakObject* >(this));
+ }
+
+ // create the component window
+ Window* pParent = VCLUnoHelper::GetWindow(xParentWindow);
+ Window* pWindow = new BackingWindow(pParent);
+ m_xWindow = VCLUnoHelper::GetInterface(pWindow);
+
+ if (!m_xWindow.is())
+ throw css::uno::RuntimeException(
+ OUString("couldn't create component window"),
+ static_cast< ::cppu::OWeakObject* >(this));
+
+ // start listening for window disposing
+ // It's set at our owner frame as component window later too. So it will may be disposed there ...
+ css::uno::Reference< css::lang::XComponent > xBroadcaster(m_xWindow, css::uno::UNO_QUERY);
+ if (xBroadcaster.is())
+ xBroadcaster->addEventListener(static_cast< css::lang::XEventListener* >(this));
+
+ m_xWindow->setVisible(sal_True);
+
+ /* } SAFE */
+}
+
+//_______________________________________________
+
+/**
+ */
+
+void SAL_CALL BackingComp::keyPressed( /*IN*/ const css::awt::KeyEvent& )
+ throw(css::uno::RuntimeException)
+{
+}
+
+//_______________________________________________
+
+/**
+ */
+
+void SAL_CALL BackingComp::keyReleased( /*IN*/ const css::awt::KeyEvent& )
+ throw(css::uno::RuntimeException)
+{
+ /* Attention
+ Please use keyPressed() instead of this method. Otherwhise it would be possible, that
+ - a key input may be first switch to the backing mode
+ - and this component register itself as key listener too
+ - and it's first event will be a keyRealeased() for the already well known event, which switched to the backing mode!
+ So it will be handled twice! document => backing mode => exit app ...
+ */
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sfx2/source/dialog/backingwindow.cxx b/sfx2/source/dialog/backingwindow.cxx
new file mode 100644
index 000000000000..be49bd2cf463
--- /dev/null
+++ b/sfx2/source/dialog/backingwindow.cxx
@@ -0,0 +1,690 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "backingwindow.hxx"
+
+#include <vcl/svapp.hxx>
+#include <vcl/virdev.hxx>
+
+#include <unotools/dynamicmenuoptions.hxx>
+#include <svtools/langhelp.hxx>
+#include <svtools/colorcfg.hxx>
+
+#include <comphelper/processfactory.hxx>
+#include <comphelper/sequenceashashmap.hxx>
+
+#include <toolkit/awt/vclxmenu.hxx>
+
+#include <com/sun/star/frame/Desktop.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/configuration/theDefaultProvider.hpp>
+#include <com/sun/star/system/SystemShellExecute.hpp>
+#include <com/sun/star/system/SystemShellExecuteFlags.hpp>
+#include <com/sun/star/util/URLTransformer.hpp>
+#include <com/sun/star/frame/PopupMenuControllerFactory.hpp>
+
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star;
+
+const char RECENT_FILE_LIST[] = ".uno:RecentFileList";
+
+const char WRITER_URL[] = "private:factory/swriter";
+const char CALC_URL[] = "private:factory/scalc";
+const char IMPRESS_WIZARD_URL[] = "private:factory/simpress?slot=6686";
+const char DRAW_URL[] = "private:factory/sdraw";
+const char BASE_URL[] = "private:factory/sdatabase?Interactive";
+const char MATH_URL[] = "private:factory/smath";
+const char TEMPLATE_URL[] = "slot:5500";
+const char OPEN_URL[] = ".uno:Open";
+const char SERVICENAME_CFGREADACCESS[] = "com.sun.star.configuration.ConfigurationAccess";
+
+const int nItemId_Extensions = 1;
+const int nItemId_Info = 3;
+const int nItemId_TplRep = 4;
+
+const int nShadowTop = 30;
+const int nShadowLeft = 30;
+const int nShadowRight = 30;
+const int nShadowBottom = 30;
+
+const int nPaddingTop = 30;
+const int nPaddingLeft = 50;
+const int nPaddingRight = 50;
+const int nPaddingBottom = 30;
+
+const int nLogoHeight = 150;
+
+BackingWindow::BackingWindow( Window* i_pParent ) :
+ Window( i_pParent ),
+ mbInitControls( false ),
+ mnHideExternalLinks( 0 ),
+ mpAccExec( NULL )
+{
+ m_pUIBuilder = new VclBuilder(this, getUIRootDir(),
+ "modules/StartModule/ui/startcenter.ui",
+ "StartCenter" );
+ get(mpWriterButton, "writer");
+ get(mpCalcButton, "calc");
+ get(mpImpressButton, "impress");
+ get(mpOpenButton, "open");
+ get(mpDrawButton, "draw");
+ get(mpDBButton, "database");
+ get(mpMathButton, "math");
+ get(mpTemplateButton, "templates");
+
+ get(mpExtensionsButton, "extension");
+ get(mpInfoButton, "info");
+ get(mpTplRepButton, "add_temp");
+
+ get(mpStartCenterContainer, "sccontainer");
+
+ try
+ {
+ mxContext.set( ::comphelper::getProcessComponentContext(), uno::UNO_SET_THROW );
+ Reference<lang::XMultiServiceFactory> xConfig = configuration::theDefaultProvider::get( mxContext );
+ Sequence<Any> args(1);
+ PropertyValue val(
+ "nodepath",
+ 0,
+ Any(OUString("/org.openoffice.Office.Common/Help/StartCenter")),
+ PropertyState_DIRECT_VALUE);
+ args.getArray()[0] <<= val;
+ Reference<container::XNameAccess> xNameAccess(xConfig->createInstanceWithArguments(SERVICENAME_CFGREADACCESS,args), UNO_QUERY);
+ if( xNameAccess.is() )
+ {
+ //throws css::container::NoSuchElementException, css::lang::WrappedTargetException
+ Any value( xNameAccess->getByName("StartCenterHideExternalLinks") );
+ mnHideExternalLinks = value.get<sal_Int32>();
+ }
+
+ mxPopupMenuFactory.set(
+ frame::PopupMenuControllerFactory::create( mxContext ) );
+ // TODO If there is no PopupMenuController, the button should be a nomral one not a MenuButton
+ if ( mxPopupMenuFactory->hasController(
+ OUString( RECENT_FILE_LIST ) , OUString("com.sun.star.frame.StartModule") ) )
+ {
+ mxPopupMenu.set( mxContext->getServiceManager()->createInstanceWithContext(
+ OUString( "com.sun.star.awt.PopupMenu" ), mxContext ), uno::UNO_QUERY_THROW );
+ }
+ }
+ catch (const Exception& e)
+ {
+ SAL_WARN( "fwk", "BackingWindow - caught an exception! " << e.Message );
+ }
+
+ // clean up resource stack
+ //FreeResource();
+
+ // fdo#34392: we do the layout dynamically, the layout depends on the font,
+ // so we should handle data changed events (font changing) of the last child
+ // control, at this point all the controls have updated settings (i.e. font).
+
+ EnableChildTransparentMode();
+
+ SetStyle( GetStyle() | WB_DIALOGCONTROL );
+
+ // get dispatch provider
+ Reference<XDesktop2> xDesktop = Desktop::create( comphelper::getProcessComponentContext() );
+ mxDesktopDispatchProvider = xDesktop;
+
+ mpWriterButton->SetHelpId( ".HelpId:StartCenter:WriterButton" );
+ mpCalcButton->SetHelpId( ".HelpId:StartCenter:CalcButton" );
+ mpImpressButton->SetHelpId( ".HelpId:StartCenter:ImpressButton" );
+ mpDrawButton->SetHelpId( ".HelpId:StartCenter:DrawButton" );
+ mpDBButton->SetHelpId( ".HelpId:StartCenter:DBButton" );
+ mpMathButton->SetHelpId( ".HelpId:StartCenter:MathButton" );
+ mpTemplateButton->SetHelpId( ".HelpId:StartCenter:TemplateButton" );
+ mpOpenButton->SetHelpId( ".HelpId:StartCenter:OpenButton" );
+ mpExtensionsButton->SetHelpId( ".HelpId:StartCenter:Extensions" );
+ mpInfoButton->SetHelpId( ".HelpId:StartCenter:Info" );
+ mpTplRepButton->SetHelpId( ".HelpId:StartCenter:TemplateRepository" );
+
+ // init background
+ initBackground();
+}
+
+
+BackingWindow::~BackingWindow()
+{
+ if( mxPopupMenuController.is() )
+ {
+ Reference< lang::XComponent > xComponent( mxPopupMenuController, UNO_QUERY );
+ if( xComponent.is() )
+ {
+ try
+ {
+ xComponent->dispose();
+ }
+ catch (...)
+ {}
+ }
+ mxPopupMenuController.clear();
+ }
+ mxPopupMenuFactory.clear();
+ mxPopupMenu.clear();
+}
+
+IMPL_LINK( BackingWindow, WindowEventListener, VclSimpleEvent*, pEvent )
+{
+ VclWindowEvent* pWinEvent = dynamic_cast<VclWindowEvent*>( pEvent );
+ if ( pWinEvent && pWinEvent->GetId() == VCLEVENT_WINDOW_DATACHANGED )
+ {
+ DataChangedEvent* pDCEvt =
+ static_cast<DataChangedEvent*>( pWinEvent->GetData() );
+ if ( pDCEvt->GetFlags() & SETTINGS_STYLE )
+ {
+ initBackground();
+ Invalidate();
+ // fdo#34392: Resize buttons to match the new text size.
+ Resize();
+ }
+ }
+ return 0;
+}
+
+void BackingWindow::prepareRecentFileMenu()
+{
+ if( ! mxPopupMenu.is() )
+ return;
+
+ if ( !mxPopupMenuController.is() )
+ {
+ uno::Sequence< uno::Any > aArgs( 2 );
+ beans::PropertyValue aProp;
+
+ aProp.Name = OUString( "Frame" );
+ aProp.Value <<= mxFrame;
+ aArgs[0] <<= aProp;
+
+ aProp.Name = OUString( "ModuleIdentifier" );
+ aProp.Value <<= OUString("com.sun.star.frame.StartModule");
+ aArgs[1] <<= aProp;
+ try
+ {
+ mxPopupMenuController.set(
+ mxPopupMenuFactory->createInstanceWithArgumentsAndContext(
+ OUString( RECENT_FILE_LIST ), aArgs, mxContext),
+ uno::UNO_QUERY_THROW );
+ mxPopupMenuController->setPopupMenu( mxPopupMenu );
+ }
+ catch ( const Exception &e )
+ {
+ SAL_WARN( "fwk", "BackingWindow - caught an exception! " << e.Message );
+ }
+
+ PopupMenu *pRecentMenu = NULL;
+ VCLXMenu* pTKMenu = VCLXMenu::GetImplementation( mxPopupMenu );
+ if ( pTKMenu )
+ pRecentMenu = dynamic_cast< PopupMenu * >( pTKMenu->GetMenu() );
+ mpOpenButton->SetPopupMenu( pRecentMenu );
+ }
+}
+
+void BackingWindow::initBackground()
+{
+ SetBackground();
+
+ // scale middle segment
+ Size aMiddleSize;
+ if( !! maBackgroundMiddle )
+ aMiddleSize = maBackgroundMiddle.GetSizePixel();
+
+ // load middle segment
+ Application::LoadBrandBitmap ("shell/backing_space", maBackgroundMiddle);
+
+ // and scale it to previous size
+ if( aMiddleSize.Width() && aMiddleSize.Height() )
+ maBackgroundMiddle.Scale( aMiddleSize );
+
+ if( GetSettings().GetLayoutRTL() )
+ {
+ // replace images by RTL versions
+ Application::LoadBrandBitmap ("shell/backing_rtl_right", maBackgroundLeft);
+ Application::LoadBrandBitmap ("shell/backing_rtl_left", maBackgroundRight);
+ }
+ else
+ {
+ Application::LoadBrandBitmap ("shell/backing_left", maBackgroundLeft);
+ Application::LoadBrandBitmap ("shell/backing_right", maBackgroundRight);
+ }
+
+ mpOpenButton->SetMenuMode( MENUBUTTON_MENUMODE_TIMED );
+ mpOpenButton->SetActivateHdl( LINK( this, BackingWindow, ActivateHdl ) );
+
+ // this will be moved to somewhere saner later
+ mnSCWidth = 780;
+ mnSCHeight = maBackgroundLeft.GetSizePixel().Height();
+}
+
+void BackingWindow::initControls()
+{
+ if( mbInitControls )
+ return;
+
+ mbInitControls = true;
+
+ // collect the URLs of the entries in the File/New menu
+ SvtModuleOptions aModuleOptions;
+ std::set< OUString > aFileNewAppsAvailable;
+ SvtDynamicMenuOptions aOpt;
+ Sequence < Sequence < PropertyValue > > aNewMenu = aOpt.GetMenu( E_NEWMENU );
+ const OUString sURLKey( "URL" );
+
+ const Sequence< PropertyValue >* pNewMenu = aNewMenu.getConstArray();
+ const Sequence< PropertyValue >* pNewMenuEnd = aNewMenu.getConstArray() + aNewMenu.getLength();
+ for ( ; pNewMenu != pNewMenuEnd; ++pNewMenu )
+ {
+ comphelper::SequenceAsHashMap aEntryItems( *pNewMenu );
+ OUString sURL( aEntryItems.getUnpackedValueOrDefault( sURLKey, OUString() ) );
+ if ( !sURL.isEmpty() )
+ aFileNewAppsAvailable.insert( sURL );
+ }
+
+ setupButton( mpWriterButton, WRITER_URL, aFileNewAppsAvailable,
+ aModuleOptions, SvtModuleOptions::E_SWRITER );
+ setupButton( mpDrawButton, DRAW_URL, aFileNewAppsAvailable,
+ aModuleOptions, SvtModuleOptions::E_SDRAW );
+ setupButton( mpCalcButton, CALC_URL, aFileNewAppsAvailable,
+ aModuleOptions, SvtModuleOptions::E_SCALC );
+ setupButton( mpDBButton, BASE_URL, aFileNewAppsAvailable,
+ aModuleOptions, SvtModuleOptions::E_SDATABASE );
+ setupButton( mpImpressButton, IMPRESS_WIZARD_URL, aFileNewAppsAvailable,
+ aModuleOptions, SvtModuleOptions::E_SIMPRESS );
+ setupButton( mpMathButton, MATH_URL, aFileNewAppsAvailable,
+ aModuleOptions, SvtModuleOptions::E_SMATH );
+
+ setupButton( mpOpenButton, "", aFileNewAppsAvailable,
+ aModuleOptions, SvtModuleOptions::E_SWRITER );
+ setupButton( mpTemplateButton, "", aFileNewAppsAvailable,
+ aModuleOptions, SvtModuleOptions::E_SWRITER );
+
+ setupExternalLink( mpExtensionsButton );
+ setupExternalLink( mpInfoButton );
+ setupExternalLink( mpTplRepButton );
+
+ Resize();
+
+ mpWriterButton->GrabFocus();
+}
+
+void BackingWindow::setupButton( PushButton* pButton, const OUString &rURL,
+ const std::set<OUString>& rURLS,
+ SvtModuleOptions& rOpt, SvtModuleOptions::EModule eMod )
+{
+ pButton->SetClickHdl( LINK( this, BackingWindow, ClickHdl ) );
+
+ // disable the parts that are not installed
+ if( !rURL.isEmpty() && (!rOpt.IsModuleInstalled( eMod ) || rURLS.find( rURL ) == rURLS.end()) )
+ {
+ pButton->Enable( sal_False );
+ }
+
+ // setup text - slighly larger font than normal labels on the texts
+ Font aFont;
+ aFont.SetSize( Size( 0, 11 ) );
+ aFont.SetWeight( WEIGHT_NORMAL );
+
+ pButton->SetFont( aFont );
+ pButton->SetControlFont( aFont );
+}
+
+void BackingWindow::setupExternalLink( PushButton* pButton )
+{
+ if( mnHideExternalLinks == 0 )
+ pButton->Show();
+ else
+ pButton->Hide();
+
+ pButton->SetClickHdl( LINK( this, BackingWindow, ExtLinkClickHdl ) );
+}
+
+void BackingWindow::Paint( const Rectangle& )
+{
+ Resize();
+
+ Wallpaper aBack( svtools::ColorConfig().GetColorValue(::svtools::APPBACKGROUND).nColor );
+ Region aClip( Rectangle( Point( 0, 0 ), GetOutputSizePixel() ) );
+
+ Rectangle aBmpRect(Point((GetOutputSizePixel().Width()-mnSCWidth)/2,
+ (GetOutputSizePixel().Height()-mnSCHeight)/2),
+ Size(mnSCWidth,mnSCHeight));
+ aClip.Exclude( aBmpRect );
+
+ Push( PUSH_CLIPREGION );
+ IntersectClipRegion( aClip );
+ DrawWallpaper( Rectangle( Point( 0, 0 ), GetOutputSizePixel() ), aBack );
+ Pop();
+
+ VirtualDevice aDev( *this );
+ aDev.EnableRTL( IsRTLEnabled() );
+ aDev.SetOutputSizePixel( aBmpRect.GetSize() );
+ Point aOffset( Point( 0, 0 ) - aBmpRect.TopLeft());
+ aDev.DrawWallpaper( Rectangle( aOffset, GetOutputSizePixel() ), aBack );
+
+ maBackgroundMiddle.Scale(
+ Size(mnSCWidth - maBackgroundLeft.GetSizePixel().Width() - maBackgroundRight.GetSizePixel().Width(),
+ maBackgroundMiddle.GetSizePixel().Height()),
+ BMP_SCALE_FAST);
+
+ // draw bitmap
+ Point aTL( 0, 0 );
+ aDev.DrawBitmapEx( aTL, maBackgroundLeft );
+ aTL.X() += maBackgroundLeft.GetSizePixel().Width();
+ if( !!maBackgroundMiddle )
+ {
+ aDev.DrawBitmapEx( aTL, maBackgroundMiddle );
+ aTL.X() += maBackgroundMiddle.GetSizePixel().Width();
+ }
+ aDev.DrawBitmapEx( aTL, maBackgroundRight );
+
+ DrawOutDev( aBmpRect.TopLeft(), aBmpRect.GetSize(),
+ Point( 0, 0 ), aBmpRect.GetSize(),
+ aDev );
+}
+
+long BackingWindow::Notify( NotifyEvent& rNEvt )
+{
+ if( rNEvt.GetType() == EVENT_KEYINPUT )
+ {
+ // try the 'normal' accelerators (so that eg. Ctrl+Q works)
+ if( !mpAccExec )
+ {
+ mpAccExec = svt::AcceleratorExecute::createAcceleratorHelper();
+ mpAccExec->init( comphelper::getProcessComponentContext(), mxFrame);
+ }
+
+ const KeyEvent* pEvt = rNEvt.GetKeyEvent();
+ const KeyCode& rKeyCode(pEvt->GetKeyCode());
+ if( pEvt && mpAccExec->execute(rKeyCode) )
+ return 1;
+
+ // #i110344# extrawurst: specialized arrow key control
+ if( rKeyCode.GetModifier() == 0 )
+ {
+ if( rKeyCode.GetCode() == KEY_RIGHT )
+ {
+ if( mpWriterButton->HasFocus() )
+ mpDrawButton->GrabFocus();
+ else if( mpCalcButton->HasFocus() )
+ mpDBButton->GrabFocus();
+ else if( mpImpressButton->HasFocus() )
+ mpMathButton->GrabFocus();
+ else if( mpOpenButton->HasFocus() )
+ mpTemplateButton->GrabFocus();
+ return 1;
+ }
+ else if( rKeyCode.GetCode() == KEY_LEFT )
+ {
+ if( mpDrawButton->HasFocus() )
+ mpWriterButton->GrabFocus();
+ else if( mpDBButton->HasFocus() )
+ mpCalcButton->GrabFocus();
+ else if( mpMathButton->HasFocus() )
+ mpImpressButton->GrabFocus();
+ else if( mpTemplateButton->HasFocus() )
+ mpOpenButton->GrabFocus();
+ return 1;
+ }
+ else if( rKeyCode.GetCode() == KEY_UP )
+ {
+ // first column
+ if( mpOpenButton->HasFocus() )
+ mpImpressButton->GrabFocus();
+ else if( mpImpressButton->HasFocus() )
+ mpCalcButton->GrabFocus();
+ else if( mpCalcButton->HasFocus() )
+ mpWriterButton->GrabFocus();
+ // second column
+ else if( mpTemplateButton->HasFocus() )
+ mpMathButton->GrabFocus();
+ else if( mpMathButton->HasFocus() )
+ mpDBButton->GrabFocus();
+ else if( mpDBButton->HasFocus() )
+ mpDrawButton->GrabFocus();
+ return 1;
+ }
+ else if( rKeyCode.GetCode() == KEY_DOWN )
+ {
+ // first column
+ if( mpWriterButton->HasFocus() )
+ mpCalcButton->GrabFocus();
+ else if( mpCalcButton->HasFocus() )
+ mpImpressButton->GrabFocus();
+ else if( mpImpressButton->HasFocus() )
+ mpOpenButton->GrabFocus();
+ // second column
+ else if( mpDrawButton->HasFocus() )
+ mpDBButton->GrabFocus();
+ else if( mpDBButton->HasFocus() )
+ mpMathButton->GrabFocus();
+ else if( mpMathButton->HasFocus() )
+ mpTemplateButton->GrabFocus();
+ return 1;
+ }
+ }
+ }
+
+ return Window::Notify( rNEvt );
+}
+
+void BackingWindow::setOwningFrame( const com::sun::star::uno::Reference< com::sun::star::frame::XFrame >& xFrame )
+{
+ mxFrame = xFrame;
+ if( ! mbInitControls )
+ initControls();
+}
+
+void BackingWindow::Resize()
+{
+ maStartCentButtons = Rectangle(
+ Point((GetOutputSizePixel().Width()-mnSCWidth)/2 + nShadowTop + nPaddingTop,
+ (GetOutputSizePixel().Height()-mnSCHeight)/2 + nShadowLeft + nPaddingLeft + nLogoHeight),
+ Size(mnSCWidth - nShadowLeft - nShadowRight - nPaddingLeft - nPaddingRight,
+ mnSCHeight - nShadowTop - nShadowBottom - nPaddingTop - nPaddingBottom - nLogoHeight));
+ if (isLayoutEnabled(this))
+ VclContainer::setLayoutAllocation(*GetWindow(WINDOW_FIRSTCHILD),
+ maStartCentButtons.TopLeft(), maStartCentButtons.GetSize());
+
+ if( !IsInPaint())
+ Invalidate();
+}
+
+IMPL_LINK( BackingWindow, ExtLinkClickHdl, Button*, pButton )
+{
+ const char* pNode = NULL;
+
+ if( pButton == mpExtensionsButton )
+ pNode = "AddFeatureURL";
+ else if( pButton == mpInfoButton )
+ pNode = "InfoURL";
+ else if( pButton == mpTplRepButton )
+ pNode = "TemplateRepositoryURL";
+
+ if( pNode )
+ {
+ const char* pNodePath = "/org.openoffice.Office.Common/Help/StartCenter";
+ try
+ {
+ Reference<lang::XMultiServiceFactory> xConfig = configuration::theDefaultProvider::get( comphelper::getProcessComponentContext() );
+ Sequence<Any> args(1);
+ PropertyValue val(
+ "nodepath",
+ 0,
+ Any(OUString::createFromAscii(pNodePath)),
+ PropertyState_DIRECT_VALUE);
+ args.getArray()[0] <<= val;
+ Reference<container::XNameAccess> xNameAccess(xConfig->createInstanceWithArguments(SERVICENAME_CFGREADACCESS,args), UNO_QUERY);
+ if( xNameAccess.is() )
+ {
+ OUString sURL;
+ //throws css::container::NoSuchElementException, css::lang::WrappedTargetException
+ Any value( xNameAccess->getByName(OUString::createFromAscii(pNode)) );
+ sURL = value.get<OUString> ();
+ localizeWebserviceURI(sURL);
+
+ Reference< com::sun::star::system::XSystemShellExecute > xSystemShellExecute(
+ com::sun::star::system::SystemShellExecute::create(comphelper::getProcessComponentContext()));
+ //throws css::lang::IllegalArgumentException, css::system::SystemShellExecuteException
+ xSystemShellExecute->execute( sURL, OUString(), com::sun::star::system::SystemShellExecuteFlags::URIS_ONLY);
+ }
+ }
+ catch (const Exception&)
+ {
+ }
+ }
+ return 0;
+}
+
+IMPL_LINK( BackingWindow, ClickHdl, Button*, pButton )
+{
+ // dispatch the appropriate URL and end the dialog
+ if( pButton == mpWriterButton )
+ dispatchURL( WRITER_URL );
+ else if( pButton == mpCalcButton )
+ dispatchURL( CALC_URL );
+ else if( pButton == mpImpressButton )
+ dispatchURL( IMPRESS_WIZARD_URL );
+ else if( pButton == mpDrawButton )
+ dispatchURL( DRAW_URL );
+ else if( pButton == mpDBButton )
+ dispatchURL( BASE_URL );
+ else if( pButton == mpMathButton )
+ dispatchURL( MATH_URL );
+ else if( pButton == mpOpenButton )
+ {
+ Reference< XDispatchProvider > xFrame( mxFrame, UNO_QUERY );
+
+ Sequence< com::sun::star::beans::PropertyValue > aArgs(1);
+ PropertyValue* pArg = aArgs.getArray();
+ pArg[0].Name = "Referer";
+ pArg[0].Value <<= OUString("private:user");
+
+ dispatchURL( OPEN_URL, OUString(), xFrame, aArgs );
+ }
+ else if( pButton == mpTemplateButton )
+ {
+ Reference< XDispatchProvider > xFrame( mxFrame, UNO_QUERY );
+
+ Sequence< com::sun::star::beans::PropertyValue > aArgs(1);
+ PropertyValue* pArg = aArgs.getArray();
+ pArg[0].Name = OUString("Referer");
+ pArg[0].Value <<= OUString("private:user");
+
+ dispatchURL( TEMPLATE_URL, OUString(), xFrame, aArgs );
+ }
+ return 0;
+}
+
+IMPL_LINK( BackingWindow, ActivateHdl, Button*, pButton )
+{
+ if( pButton == mpOpenButton )
+ prepareRecentFileMenu();
+ return 0;
+}
+
+struct ImplDelayedDispatch
+{
+ Reference< XDispatch > xDispatch;
+ com::sun::star::util::URL aDispatchURL;
+ Sequence< PropertyValue > aArgs;
+
+ ImplDelayedDispatch( const Reference< XDispatch >& i_xDispatch,
+ const com::sun::star::util::URL& i_rURL,
+ const Sequence< PropertyValue >& i_rArgs )
+ : xDispatch( i_xDispatch ),
+ aDispatchURL( i_rURL ),
+ aArgs( i_rArgs )
+ {
+ }
+ ~ImplDelayedDispatch() {}
+};
+
+static long implDispatchDelayed( void*, void* pArg )
+{
+ struct ImplDelayedDispatch* pDispatch = reinterpret_cast<ImplDelayedDispatch*>(pArg);
+ try
+ {
+ pDispatch->xDispatch->dispatch( pDispatch->aDispatchURL, pDispatch->aArgs );
+ }
+ catch (const Exception&)
+ {
+ }
+
+ // clean up
+ delete pDispatch;
+
+ return 0;
+}
+
+void BackingWindow::dispatchURL( const OUString& i_rURL,
+ const OUString& rTarget,
+ const Reference< XDispatchProvider >& i_xProv,
+ const Sequence< PropertyValue >& i_rArgs )
+{
+ // if no special dispatch provider is given, get the desktop
+ Reference< XDispatchProvider > xProvider( i_xProv.is() ? i_xProv : mxDesktopDispatchProvider );
+
+ // check for dispatch provider
+ if( !xProvider.is())
+ return;
+
+ // get an URL transformer to clean up the URL
+ com::sun::star::util::URL aDispatchURL;
+ aDispatchURL.Complete = i_rURL;
+
+ Reference < com::sun::star::util::XURLTransformer > xURLTransformer(
+ com::sun::star::util::URLTransformer::create( comphelper::getProcessComponentContext() ) );
+ try
+ {
+ // clean up the URL
+ xURLTransformer->parseStrict( aDispatchURL );
+ // get a Dispatch for the URL and target
+ Reference< XDispatch > xDispatch(
+ xProvider->queryDispatch( aDispatchURL, rTarget, 0 )
+ );
+ // dispatch the URL
+ if ( xDispatch.is() )
+ {
+ ImplDelayedDispatch* pDisp = new ImplDelayedDispatch( xDispatch, aDispatchURL, i_rArgs );
+ sal_uLong nEventId = 0;
+ if( ! Application::PostUserEvent( nEventId, Link( NULL, implDispatchDelayed ), pDisp ) )
+ delete pDisp; // event could not be posted for unknown reason, at least don't leak
+ }
+ }
+ catch (const com::sun::star::uno::RuntimeException&)
+ {
+ throw;
+ }
+ catch (const com::sun::star::uno::Exception&)
+ {
+ }
+}
+
+Size BackingWindow::GetOptimalSize() const
+{
+ if (isLayoutEnabled(this))
+ return VclContainer::getLayoutRequisition(*GetWindow(WINDOW_FIRSTCHILD));
+
+ return Window::GetOptimalSize();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab:*/
diff --git a/sfx2/source/dialog/backingwindow.hxx b/sfx2/source/dialog/backingwindow.hxx
new file mode 100644
index 000000000000..287a77778bad
--- /dev/null
+++ b/sfx2/source/dialog/backingwindow.hxx
@@ -0,0 +1,130 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef SFX2_BACKINGWINDOW_HXX
+#define SFX2_BACKINGWINDOW_HXX
+
+#include <rtl/ustring.hxx>
+
+#include <vcl/builder.hxx>
+#include <vcl/button.hxx>
+#include <vcl/menubtn.hxx>
+#include <vcl/bitmapex.hxx>
+#include <vcl/toolbox.hxx>
+#include <vcl/layout.hxx>
+
+#include <svtools/acceleratorexecute.hxx>
+#include <unotools/moduleoptions.hxx>
+
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/frame/XUIControllerFactory.hpp>
+#include <com/sun/star/frame/XPopupMenuController.hpp>
+#include <com/sun/star/awt/XPopupMenu.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/frame/XDesktop.hpp>
+#include <com/sun/star/frame/XFrame.hpp>
+#include <com/sun/star/frame/XTerminateListener.hpp>
+#include <com/sun/star/document/XEventListener.hpp>
+#include <com/sun/star/document/XEventBroadcaster.hpp>
+#include <com/sun/star/util/XURLTransformer.hpp>
+#include <com/sun/star/ui/dialogs/XFilePicker.hpp>
+#include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp>
+#include <com/sun/star/ui/dialogs/XFilterManager.hpp>
+#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
+#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
+
+#include <set>
+
+class MnemonicGenerator;
+
+class BackingWindow
+ : public Window
+ , public VclBuilderContainer
+{
+ com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > mxContext;
+ com::sun::star::uno::Reference<com::sun::star::frame::XDispatchProvider > mxDesktopDispatchProvider;
+ com::sun::star::uno::Reference<com::sun::star::frame::XFrame> mxFrame;
+ com::sun::star::uno::Reference< com::sun::star::frame::XUIControllerFactory > mxPopupMenuFactory;
+ com::sun::star::uno::Reference< com::sun::star::frame::XPopupMenuController > mxPopupMenuController;
+ com::sun::star::uno::Reference< com::sun::star::awt::XPopupMenu > mxPopupMenu;
+
+ PushButton* mpWriterButton;
+ PushButton* mpCalcButton;
+ PushButton* mpImpressButton;
+ MenuButton* mpOpenButton;
+ PushButton* mpDrawButton;
+ PushButton* mpDBButton;
+ PushButton* mpMathButton;
+ PushButton* mpTemplateButton;
+
+ PushButton* mpExtensionsButton;
+ PushButton* mpInfoButton;
+ PushButton* mpTplRepButton;
+
+ VclGrid* mpStartCenterContainer;
+
+ BitmapEx maBackgroundLeft;
+ BitmapEx maBackgroundMiddle;
+ BitmapEx maBackgroundRight;
+
+ Rectangle maStartCentButtons;
+
+ bool mbInitControls;
+ sal_Int32 mnHideExternalLinks;
+ svt::AcceleratorExecute* mpAccExec;
+
+ int mnSCWidth;
+ int mnSCHeight;
+
+ void setupButton( PushButton* pButton, const OUString& rURL, const std::set<OUString>& rURLS,
+ SvtModuleOptions& rOpt, SvtModuleOptions::EModule eMod );
+
+ void setupExternalLink( PushButton* pButton );
+
+ void dispatchURL( const OUString& i_rURL,
+ const OUString& i_rTarget = OUString( "_default" ),
+ const com::sun::star::uno::Reference< com::sun::star::frame::XDispatchProvider >& i_xProv = com::sun::star::uno::Reference< com::sun::star::frame::XDispatchProvider >(),
+ const com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >& = com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >()
+ );
+
+ DECL_LINK( ClickHdl, Button* );
+ DECL_LINK( ExtLinkClickHdl, Button* );
+ DECL_LINK( ActivateHdl, Button* );
+ DECL_LINK( WindowEventListener, VclSimpleEvent* );
+
+ void initControls();
+ void initBackground();
+ void prepareRecentFileMenu();
+
+public:
+ BackingWindow( Window* pParent );
+ ~BackingWindow();
+
+ virtual void Paint( const Rectangle& rRect );
+ virtual void Resize();
+ virtual long Notify( NotifyEvent& rNEvt );
+
+ virtual Size GetOptimalSize() const;
+
+ void setOwningFrame( const com::sun::star::uno::Reference< com::sun::star::frame::XFrame >& xFrame );
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sfx2/util/sfx.component b/sfx2/util/sfx.component
index 0de2629eb110..dc3150988622 100644
--- a/sfx2/util/sfx.component
+++ b/sfx2/util/sfx.component
@@ -19,6 +19,9 @@
<component loader="com.sun.star.loader.SharedLibrary" prefix="sfx"
xmlns="http://openoffice.org/2010/uno-components">
+ <implementation name="com.sun.star.comp.sfx2.BackingComp">
+ <service name="com.sun.star.frame.StartModule"/>
+ </implementation>
<implementation name="SfxDocumentMetaData">
<service name="com.sun.star.document.DocumentProperties"/>
</implementation>