summaryrefslogtreecommitdiff
path: root/dbaccess/source
diff options
context:
space:
mode:
authorOliver Bolte <obo@openoffice.org>2008-10-16 06:57:26 +0000
committerOliver Bolte <obo@openoffice.org>2008-10-16 06:57:26 +0000
commit83da8a29dd96d46cc4e65f673b31d2fd999882ed (patch)
tree3cf61dfe51fec5bf012767979c232c59a3131069 /dbaccess/source
parentf56058657facb7e5e8f3fe13ffef5d9ea158b79e (diff)
CWS-TOOLING: integrate CWS odbmacros3
Diffstat (limited to 'dbaccess/source')
-rw-r--r--dbaccess/source/core/dataaccess/ModelImpl.cxx142
-rw-r--r--dbaccess/source/core/dataaccess/ModelImpl.hxx115
-rw-r--r--dbaccess/source/core/dataaccess/databasecontext.cxx60
-rw-r--r--dbaccess/source/core/dataaccess/databasecontext.hxx7
-rw-r--r--dbaccess/source/core/dataaccess/databasedocument.cxx898
-rw-r--r--dbaccess/source/core/dataaccess/databasedocument.hxx284
-rw-r--r--dbaccess/source/core/dataaccess/datasource.cxx12
-rw-r--r--dbaccess/source/core/dataaccess/documentdefinition.cxx12
-rw-r--r--dbaccess/source/core/dataaccess/documentdefinition.hxx2
-rw-r--r--dbaccess/source/core/dataaccess/documenteventexecutor.cxx234
-rw-r--r--dbaccess/source/core/dataaccess/documenteventexecutor.hxx81
-rw-r--r--dbaccess/source/core/dataaccess/documenteventnotifier.cxx315
-rw-r--r--dbaccess/source/core/dataaccess/documenteventnotifier.hxx147
-rw-r--r--dbaccess/source/core/dataaccess/documentevents.cxx266
-rw-r--r--dbaccess/source/core/dataaccess/documentevents.hxx91
-rw-r--r--dbaccess/source/core/dataaccess/makefile.mk7
-rw-r--r--dbaccess/source/ext/macromigration/dbmm_global.hrc37
-rw-r--r--dbaccess/source/ext/macromigration/dbmm_types.cxx66
-rw-r--r--dbaccess/source/ext/macromigration/dbmm_types.hxx10
-rw-r--r--dbaccess/source/ext/macromigration/docerrorhandling.cxx91
-rw-r--r--dbaccess/source/ext/macromigration/docerrorhandling.hxx69
-rw-r--r--dbaccess/source/ext/macromigration/docinteraction.cxx157
-rw-r--r--dbaccess/source/ext/macromigration/docinteraction.hxx107
-rw-r--r--dbaccess/source/ext/macromigration/macromigration.hrc4
-rw-r--r--dbaccess/source/ext/macromigration/macromigration.src69
-rw-r--r--dbaccess/source/ext/macromigration/macromigrationdialog.cxx308
-rw-r--r--dbaccess/source/ext/macromigration/macromigrationdialog.hxx4
-rw-r--r--dbaccess/source/ext/macromigration/macromigrationpages.cxx45
-rw-r--r--dbaccess/source/ext/macromigration/macromigrationpages.hxx8
-rw-r--r--dbaccess/source/ext/macromigration/macromigrationwizard.cxx15
-rw-r--r--dbaccess/source/ext/macromigration/makefile.mk9
-rw-r--r--dbaccess/source/ext/macromigration/migrationengine.cxx1553
-rw-r--r--dbaccess/source/ext/macromigration/migrationerror.hxx162
-rw-r--r--dbaccess/source/ext/macromigration/migrationlog.cxx305
-rw-r--r--dbaccess/source/ext/macromigration/migrationlog.hxx16
-rw-r--r--dbaccess/source/ext/macromigration/migrationprogress.hxx4
-rw-r--r--dbaccess/source/ext/macromigration/progressmixer.cxx218
-rw-r--r--dbaccess/source/ext/macromigration/progressmixer.hxx103
-rw-r--r--dbaccess/source/filter/migration/cfgimport.cxx9
-rw-r--r--dbaccess/source/filter/xml/dbloader2.cxx79
-rw-r--r--dbaccess/source/filter/xml/xmlEnums.hxx5
-rw-r--r--dbaccess/source/filter/xml/xmlExport.cxx3
-rw-r--r--dbaccess/source/filter/xml/xmlExport.hxx2
-rw-r--r--dbaccess/source/filter/xml/xmlfilter.cxx28
-rw-r--r--dbaccess/source/filter/xml/xmlfilter.hxx4
-rw-r--r--dbaccess/source/ui/app/AppController.cxx59
-rw-r--r--dbaccess/source/ui/app/AppControllerDnD.cxx2
-rw-r--r--dbaccess/source/ui/app/AppControllerGen.cxx2
-rw-r--r--dbaccess/source/ui/app/AppView.cxx2
-rw-r--r--dbaccess/source/ui/app/app.src9
-rw-r--r--dbaccess/source/ui/browser/brwctrlr.cxx2
-rw-r--r--dbaccess/source/ui/browser/dbloader.cxx11
-rw-r--r--dbaccess/source/ui/browser/dsbrowserDnD.cxx2
-rw-r--r--dbaccess/source/ui/browser/exsrcbrw.cxx2
-rw-r--r--dbaccess/source/ui/browser/sbagrid.cxx2
-rw-r--r--dbaccess/source/ui/browser/unodatbr.cxx5
-rw-r--r--dbaccess/source/ui/control/RelationControl.cxx2
-rw-r--r--dbaccess/source/ui/control/tabletree.cxx2
-rw-r--r--dbaccess/source/ui/control/toolboxcontroller.cxx2
-rw-r--r--dbaccess/source/ui/dlg/AdabasStat.cxx2
-rw-r--r--dbaccess/source/ui/dlg/ConnectionPage.src4
-rw-r--r--dbaccess/source/ui/dlg/ExtensionNotPresent.cxx2
-rw-r--r--dbaccess/source/ui/dlg/adminpages.cxx2
-rw-r--r--dbaccess/source/ui/dlg/dbwizsetup.cxx80
-rw-r--r--dbaccess/source/ui/dlg/directsql.cxx2
-rw-r--r--dbaccess/source/ui/dlg/queryorder.cxx2
-rw-r--r--dbaccess/source/ui/dlg/tablespage.cxx2
-rw-r--r--dbaccess/source/ui/inc/brwctrlr.hxx2
-rw-r--r--dbaccess/source/ui/misc/DExport.cxx2
-rw-r--r--dbaccess/source/ui/misc/TableCopyHelper.cxx2
-rw-r--r--dbaccess/source/ui/misc/TokenWriter.cxx2
-rw-r--r--dbaccess/source/ui/misc/controllerframe.cxx47
-rw-r--r--dbaccess/source/ui/misc/databaseobjectview.cxx2
-rw-r--r--dbaccess/source/ui/misc/documentcontroller.cxx13
-rw-r--r--dbaccess/source/ui/misc/dsmeta.cxx58
-rw-r--r--dbaccess/source/ui/misc/dsntypes.cxx0
-rw-r--r--dbaccess/source/ui/misc/indexcollection.cxx2
-rw-r--r--dbaccess/source/ui/misc/singledoccontroller.cxx10
-rw-r--r--dbaccess/source/ui/uno/composerdialogs.cxx2
-rw-r--r--dbaccess/source/ui/uno/dbinteraction.cxx2
-rw-r--r--dbaccess/source/ui/uno/unoDirectSql.cxx2
81 files changed, 5383 insertions, 1126 deletions
diff --git a/dbaccess/source/core/dataaccess/ModelImpl.cxx b/dbaccess/source/core/dataaccess/ModelImpl.cxx
index f4dd05b55..1c3892bc0 100644
--- a/dbaccess/source/core/dataaccess/ModelImpl.cxx
+++ b/dbaccess/source/core/dataaccess/ModelImpl.cxx
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: ModelImpl.cxx,v $
- * $Revision: 1.32.18.1 $
+ * $Revision: 1.25.6.12 $
*
* This file is part of OpenOffice.org.
*
@@ -43,6 +43,7 @@
#include "userinformation.hxx"
/** === begin UNO includes === **/
+#include <com/sun/star/container/XSet.hpp>
#include <com/sun/star/document/MacroExecMode.hpp>
#include <com/sun/star/embed/XTransactedObject.hpp>
#include <com/sun/star/embed/XTransactionBroadcaster.hpp>
@@ -50,6 +51,7 @@
#include <com/sun/star/script/DocumentScriptLibraryContainer.hpp>
#include <com/sun/star/script/DocumentDialogLibraryContainer.hpp>
#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
+#include <com/sun/star/form/XLoadable.hpp>
/** === end UNO includes === **/
#include <comphelper/interaction.hxx>
@@ -128,6 +130,33 @@ void SAL_CALL SharedMutex::release()
}
//============================================================
+//= VosMutexFacade
+//============================================================
+//------------------------------------------------------------------------
+VosMutexFacade::VosMutexFacade( ::osl::Mutex& _rMutex )
+ :m_rMutex( _rMutex )
+{
+}
+
+//------------------------------------------------------------------------
+void SAL_CALL VosMutexFacade::acquire()
+{
+ m_rMutex.acquire();
+}
+
+//------------------------------------------------------------------------
+sal_Bool SAL_CALL VosMutexFacade::tryToAcquire()
+{
+ return m_rMutex.tryToAcquire();
+}
+
+//------------------------------------------------------------------------
+void SAL_CALL VosMutexFacade::release()
+{
+ m_rMutex.release();
+}
+
+//============================================================
//= DocumentStorageAccess
//============================================================
DBG_NAME( DocumentStorageAccess )
@@ -189,9 +218,9 @@ void DocumentStorageAccess::dispose()
{
::osl::MutexGuard aGuard( m_aMutex );
- for ( NamedStorages::iterator loop = m_aExposedStorages.begin();
- loop != m_aExposedStorages.end();
- ++loop
+ for ( NamedStorages::iterator loop = m_aExposedStorages.begin();
+ loop != m_aExposedStorages.end();
+ ++loop
)
{
try
@@ -202,7 +231,7 @@ void DocumentStorageAccess::dispose()
}
catch( const Exception& )
{
- OSL_ENSURE( sal_False, "DocumentStorageAccess::dispose: caught an exception!" );
+ DBG_UNHANDLED_EXCEPTION();
}
}
@@ -313,15 +342,17 @@ ODatabaseModelImpl::ODatabaseModelImpl( const Reference< XMultiServiceFactory >&
:m_xModel()
,m_xDataSource()
,m_pStorageAccess( NULL )
- ,m_xMutex( new SharedMutex )
+ ,m_aMutexFacade( m_xMutex->getMutex() )
,m_aContainer(4)
,m_aStorages()
,m_aMacroMode( *this )
,m_nImposedMacroExecMode( MacroExecMode::NEVER_EXECUTE )
,m_pDBContext( &_rDBContext )
+ ,m_refCount(0)
,m_bHasAnyObjectWithMacros( false )
,m_bHasMacroStorages( false )
,m_bModificationLock( false )
+ ,m_bDocumentInitialized( false )
,m_aContext( _rxFactory )
,m_nLoginTimeout(0)
,m_bReadOnly(sal_False)
@@ -331,7 +362,6 @@ ODatabaseModelImpl::ODatabaseModelImpl( const Reference< XMultiServiceFactory >&
,m_bDocumentReadOnly(sal_False)
,m_bDisposingSubStorages( sal_False )
,m_pSharedConnectionManager(NULL)
- ,m_refCount(0)
,m_nControllerLockCount(0)
{
// some kind of default
@@ -351,15 +381,17 @@ ODatabaseModelImpl::ODatabaseModelImpl(
:m_xModel()
,m_xDataSource()
,m_pStorageAccess( NULL )
- ,m_xMutex( new SharedMutex )
+ ,m_aMutexFacade( m_xMutex->getMutex() )
,m_aContainer(4)
,m_aStorages()
,m_aMacroMode( *this )
,m_nImposedMacroExecMode( MacroExecMode::NEVER_EXECUTE )
,m_pDBContext( &_rDBContext )
+ ,m_refCount(0)
,m_bHasAnyObjectWithMacros( false )
,m_bHasMacroStorages( false )
,m_bModificationLock( false )
+ ,m_bDocumentInitialized( false )
,m_aContext( _rxFactory )
,m_sName(_rRegistrationName)
,m_nLoginTimeout(0)
@@ -370,7 +402,6 @@ ODatabaseModelImpl::ODatabaseModelImpl(
,m_bDocumentReadOnly(sal_False)
,m_bDisposingSubStorages( sal_False )
,m_pSharedConnectionManager(NULL)
- ,m_refCount(0)
,m_nControllerLockCount(0)
{
DBG_CTOR(ODatabaseModelImpl,NULL);
@@ -678,6 +709,37 @@ const Reference< XNumberFormatsSupplier > & ODatabaseModelImpl::getNumberFormats
return m_xNumberFormatsSupplier;
}
// -----------------------------------------------------------------------------
+void ODatabaseModelImpl::attachResource( const ::rtl::OUString& _rURL, const Sequence< PropertyValue >& _rArgs )
+{
+ ::comphelper::NamedValueCollection aMediaDescriptor( _rArgs );
+
+ ::rtl::OUString sDocumentLocation( aMediaDescriptor.getOrDefault( "SalvagedFile", _rURL ) );
+ if ( !sDocumentLocation.getLength() )
+ // this indicates "the document is being recovered, but _rURL already is the real document URL,
+ // not the temporary document location"
+ sDocumentLocation = _rURL;
+
+ if ( aMediaDescriptor.has( "SalvagedFile" ) )
+ aMediaDescriptor.remove( "SalvagedFile" );
+
+ m_aArgs = stripLoadArguments( aMediaDescriptor );
+
+ switchToURL( sDocumentLocation, _rURL );
+}
+
+// -----------------------------------------------------------------------------
+Sequence< PropertyValue > ODatabaseModelImpl::stripLoadArguments( const ::comphelper::NamedValueCollection& _rArguments )
+{
+ OSL_ENSURE( !_rArguments.has( "Model" ), "ODatabaseModelImpl::stripLoadArguments: this is suspicious (1)!" );
+ OSL_ENSURE( !_rArguments.has( "ViewName" ), "ODatabaseModelImpl::stripLoadArguments: this is suspicious (2)!" );
+
+ ::comphelper::NamedValueCollection aMutableArgs( _rArguments );
+ aMutableArgs.remove( "Model" );
+ aMutableArgs.remove( "ViewName" );
+ return aMutableArgs.getPropertyValues();
+}
+
+// -----------------------------------------------------------------------------
void ODatabaseModelImpl::disposeStorages() SAL_THROW(())
{
m_bDisposingSubStorages = sal_True;
@@ -694,7 +756,7 @@ void ODatabaseModelImpl::disposeStorages() SAL_THROW(())
}
catch( const Exception& )
{
- OSL_ENSURE( sal_False, "ODatabaseModelImpl::disposeStorages: caught an exception!" );
+ DBG_UNHANDLED_EXCEPTION();
}
}
m_aStorages.clear();
@@ -780,7 +842,7 @@ DocumentStorageAccess* ODatabaseModelImpl::getDocumentStorageAccess()
}
// -----------------------------------------------------------------------------
-void ODatabaseModelImpl::modelIsDisposing( ResetModelAccess )
+void ODatabaseModelImpl::modelIsDisposing( const bool _wasInitialized, ResetModelAccess )
{
m_xModel = Reference< XModel >();
@@ -789,6 +851,8 @@ void ODatabaseModelImpl::modelIsDisposing( ResetModelAccess )
// So, to not be tempted to do anything with them, again, we reset them.
m_xBasicLibraries.clear();
m_xDialogLibraries.clear();
+
+ m_bDocumentInitialized = _wasInitialized;
}
// -----------------------------------------------------------------------------
@@ -906,7 +970,7 @@ bool ODatabaseModelImpl::commitStorageIfWriteable_ignoreErrors( const Reference<
}
catch( const Exception& )
{
- OSL_ENSURE( sal_False, "ODatabaseModelImpl::commitStorageIfWriteable_ignoreErrors: caught an exception!" );
+ DBG_UNHANDLED_EXCEPTION();
}
return bSuccess;
}
@@ -918,24 +982,24 @@ void ODatabaseModelImpl::setModified( sal_Bool _bModified )
try
{
- Reference<XModifiable> xModi(m_xModel.get(),UNO_QUERY);
+ Reference< XModifiable > xModi( m_xModel.get(), UNO_QUERY );
if ( xModi.is() )
xModi->setModified( _bModified );
else
m_bModified = _bModified;
}
- catch(Exception)
+ catch( const Exception& )
{
- OSL_ENSURE(0,"ODatabaseModelImpl::setModified: Exception caught!");
+ DBG_UNHANDLED_EXCEPTION();
}
}
// -----------------------------------------------------------------------------
-Reference<XDataSource> ODatabaseModelImpl::getDataSource( bool _bCreateIfNecessary )
+Reference<XDataSource> ODatabaseModelImpl::getOrCreateDataSource()
{
Reference<XDataSource> xDs = m_xDataSource;
- if ( !xDs.is() && _bCreateIfNecessary )
- { // no data source, so we have to create one and register it later on
+ if ( !xDs.is() )
+ {
xDs = new ODatabaseSource(this);
m_xDataSource = xDs;
}
@@ -947,7 +1011,7 @@ Reference< XModel> ODatabaseModelImpl::getModel_noCreate() const
return m_xModel;
}
// -----------------------------------------------------------------------------
-Reference< XModel > ODatabaseModelImpl::createNewModel_deliverOwnership()
+Reference< XModel > ODatabaseModelImpl::createNewModel_deliverOwnership( bool _bInitialize )
{
Reference< XModel > xModel( m_xModel );
OSL_PRECOND( !xModel.is(), "ODatabaseModelImpl::createNewModel_deliverOwnership: not to be called if there already is a model!" );
@@ -955,6 +1019,31 @@ Reference< XModel > ODatabaseModelImpl::createNewModel_deliverOwnership()
{
xModel = ODatabaseDocument::createDatabaseDocument( this, ODatabaseDocument::FactoryAccess() );
m_xModel = xModel;
+
+ try
+ {
+ Reference< XSet > xModelCollection;
+ if ( m_aContext.createComponent( "com.sun.star.frame.GlobalEventBroadcaster", xModelCollection ) )
+ xModelCollection->insert( makeAny( xModel ) );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+
+ if ( _bInitialize )
+ {
+ try
+ {
+ Reference< XLoadable > xLoad( xModel, UNO_QUERY_THROW );
+ xLoad->initNew();
+ }
+ catch( RuntimeException& ) { throw; }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
}
return xModel;
}
@@ -1159,7 +1248,7 @@ namespace
{
void lcl_modifyListening( ::sfx2::IModifiableDocument& _rDocument,
const Reference< XStorage >& _rxStorage, ::rtl::Reference< ::sfx2::DocumentStorageModifyListener >& _inout_rListener,
- bool _bListen )
+ ::vos::IMutex& _rMutex, bool _bListen )
{
Reference< XModifiable > xModify( _rxStorage, UNO_QUERY );
OSL_ENSURE( xModify.is() || !_rxStorage.is(), "lcl_modifyListening: storage can't notify us!" );
@@ -1178,15 +1267,12 @@ namespace
if ( xModify.is() && _bListen )
{
// the listener from sfx2 uses SolarMutex internally
- _inout_rListener = new ::sfx2::DocumentStorageModifyListener( _rDocument );
+ _inout_rListener = new ::sfx2::DocumentStorageModifyListener( _rDocument, _rMutex );
xModify->addModifyListener( _inout_rListener.get() );
}
}
-}
-// -----------------------------------------------------------------------------
-namespace
-{
+ // -------------------------------------------------------------------------
static void lcl_rebaseScriptStorage_throw( const Reference< XStorageBasedLibraryContainer >& _rxContainer,
const Reference< XStorage >& _rxNewRootStorage )
{
@@ -1204,13 +1290,13 @@ namespace
Reference< XStorage > ODatabaseModelImpl::impl_switchToStorage_throw( const Reference< XStorage >& _rxNewRootStorage )
{
// stop listening for modifications at the old storage
- lcl_modifyListening( *this, m_xDocumentStorage.getTyped(), m_pStorageModifyListener, false );
+ lcl_modifyListening( *this, m_xDocumentStorage.getTyped(), m_pStorageModifyListener, m_aMutexFacade, false );
// set new storage
m_xDocumentStorage.reset( _rxNewRootStorage, SharedStorage::TakeOwnership );
// start listening for modifications
- lcl_modifyListening( *this, m_xDocumentStorage.getTyped(), m_pStorageModifyListener, true );
+ lcl_modifyListening( *this, m_xDocumentStorage.getTyped(), m_pStorageModifyListener, m_aMutexFacade, true );
// forward new storage to Basic and Dialog library containers
lcl_rebaseScriptStorage_throw( m_xBasicLibraries, m_xDocumentStorage.getTyped() );
@@ -1310,7 +1396,7 @@ sal_Bool ODatabaseModelImpl::setCurrentMacroExecMode( sal_uInt16 nMacroMode )
// don't return getURL() (or m_sDocumentURL, which is the same). In case we were recovered
// after a previous crash of OOo, m_sDocFileLocation points to the file which were loaded from,
// and this is the one we need for security checks.
- return getLocation();
+ return getDocFileLocation();
}
// -----------------------------------------------------------------------------
diff --git a/dbaccess/source/core/dataaccess/ModelImpl.hxx b/dbaccess/source/core/dataaccess/ModelImpl.hxx
index 186d649cc..85feb2728 100644
--- a/dbaccess/source/core/dataaccess/ModelImpl.hxx
+++ b/dbaccess/source/core/dataaccess/ModelImpl.hxx
@@ -49,6 +49,7 @@
#include <com/sun/star/embed/XTransactionListener.hpp>
#include <com/sun/star/frame/XModel.hpp>
#include <com/sun/star/frame/XStorable.hpp>
+#include <com/sun/star/lang/NotInitializedException.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/lang/XSingleServiceFactory.hpp>
@@ -67,6 +68,7 @@
#include <com/sun/star/util/XNumberFormatter.hpp>
#include <com/sun/star/util/XRefreshable.hpp>
#include <com/sun/star/sdb/XDocumentDataSource.hpp>
+#include <com/sun/star/frame/DoubleInitializationException.hpp>
/** === end UNO includes === **/
#include <comphelper/broadcasthelper.hxx>
@@ -78,10 +80,15 @@
#include <sfx2/docstoragemodifylistener.hxx>
#include <tools/string.hxx>
#include <unotools/sharedunocomponent.hxx>
-#include <vos/ref.hxx>
+#include <vos/mutex.hxx>
#include <memory>
+namespace comphelper
+{
+ class NamedValueCollection;
+}
+
//........................................................................
namespace dbaccess
{
@@ -111,6 +118,9 @@ class OSharedConnectionManager;
//============================================================
//= SharedMutex
//============================================================
+/** a shared mutex, which deletes itself as soon as the last reference
+ to it dies.
+*/
class SharedMutex
{
private:
@@ -130,6 +140,45 @@ private:
};
//============================================================
+//= SharedMutexHolder
+//============================================================
+/** a base class merely holding a SharedMutex instance. Useful if you
+ need to ensure the SharedMutex is to be initialized before other
+ of your members, in this case just derive from SharedMutexHolder.
+*/
+class SharedMutexHolder
+{
+protected:
+ SharedMutexHolder() : m_xMutex( new SharedMutex ) { }
+ ~SharedMutexHolder() { }
+
+protected:
+ ::rtl::Reference< SharedMutex > m_xMutex;
+};
+
+//============================================================
+//= VosMutexFacade
+//============================================================
+/** a class which provides an IMutex interface to an OSL-based mutex
+*/
+class VosMutexFacade : public ::vos::IMutex
+{
+public:
+ /** beware of life time: the mutex you pass here must live as least as long
+ as the VosMutexFacade instance lives.
+ */
+ VosMutexFacade( ::osl::Mutex& _rMutex );
+
+ // IMutex
+ virtual void SAL_CALL acquire();
+ virtual sal_Bool SAL_CALL tryToAcquire();
+ virtual void SAL_CALL release();
+
+private:
+ ::osl::Mutex& m_rMutex;
+};
+
+//============================================================
//= ODatabaseModelImpl
//============================================================
DECLARE_STL_USTRINGACCESS_MAP(::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >,TStorages);
@@ -139,7 +188,8 @@ typedef ::utl::SharedUNOComponent< ::com::sun::star::embed::XStorage > SharedSt
class ODatabaseContext;
class DocumentStorageAccess;
class OSharedConnectionManager;
-class ODatabaseModelImpl :public ::rtl::IReference
+class ODatabaseModelImpl :public SharedMutexHolder
+ ,public ::rtl::IReference
,public ::sfx2::IMacroDocumentAccess
,public ::sfx2::IModifiableDocument
{
@@ -158,7 +208,7 @@ private:
::com::sun::star::uno::WeakReference< ::com::sun::star::sdbc::XDataSource > m_xDataSource;
DocumentStorageAccess* m_pStorageAccess;
- ::rtl::Reference< SharedMutex > m_xMutex;
+ VosMutexFacade m_aMutexFacade;
::std::vector< TContentPtr > m_aContainer; // one for each ObjectType
TStorages m_aStorages;
::sfx2::DocumentMacroMode m_aMacroMode;
@@ -171,8 +221,11 @@ private:
::rtl::Reference< ::sfx2::DocumentStorageModifyListener > m_pStorageModifyListener;
ODatabaseContext* m_pDBContext;
+ ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > m_aArgs;
/// the URL the document was loaded from
- ::rtl::OUString m_sDocFileLocation;
+ ::rtl::OUString m_sDocFileLocation;
+
+ oslInterlockedCount m_refCount;
/// do we have any object (forms/reports) which contains macros?
bool m_bHasAnyObjectWithMacros;
@@ -182,6 +235,9 @@ private:
/// true if setting the Modified flag of the document is currently locked
bool m_bModificationLock;
+ /// true if and only if a database document existed previously (though meanwhile disposed), and was already initialized
+ bool m_bDocumentInitialized;
+
/** the URL which the document should report as it's URL
This might differ from ->m_sDocFileLocation in case the document was loaded
@@ -220,12 +276,9 @@ public:
m_xSettings;
::com::sun::star::uno::Sequence< ::rtl::OUString > m_aTableFilter;
::com::sun::star::uno::Sequence< ::rtl::OUString > m_aTableTypeFilter;
- ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >
- m_aArgs;
OSharedConnectionManager* m_pSharedConnectionManager;
::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >
m_xSharedConnectionManager;
- oslInterlockedCount m_refCount;
sal_uInt16 m_nControllerLockCount;
void reset();
@@ -269,14 +322,23 @@ public:
void dispose();
- inline ::rtl::OUString getURL() const { return m_sDocumentURL; }
- inline ::rtl::OUString getLocation() const { return m_sDocFileLocation; }
+ inline ::rtl::OUString getURL() const { return m_sDocumentURL; }
+ inline ::rtl::OUString getDocFileLocation() const { return m_sDocFileLocation; }
::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage> getStorage(const ::rtl::OUString& _sStorageName,sal_Int32 nMode = ::com::sun::star::embed::ElementModes::READWRITE);
// helper
const ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatsSupplier >&
getNumberFormatsSupplier();
+ const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >&
+ getResource() const { return m_aArgs; }
+
+ void attachResource(
+ const ::rtl::OUString& _rURL,
+ const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& _rArgs );
+
+ static ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >
+ stripLoadArguments( const ::comphelper::NamedValueCollection& _rArguments );
// other stuff
void flushTables();
@@ -315,7 +377,7 @@ public:
/** returns the data source. If it doesn't exist it will be created
*/
- ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDataSource> getDataSource( bool _bCreateIfNecessary = true );
+ ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDataSource> getOrCreateDataSource();
/** returns the model, if there already exists one
*/
@@ -323,12 +385,16 @@ public:
/** returns a new ->ODatabaseDocument
+ @param _bInitializeIfNecessary
+ calls XLoadable::initNew on the newly created model, if necessary
+
@precond
No ->ODatabaseDocument exists so far
+
@seealso
getModel_noCreate
*/
- ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > createNewModel_deliverOwnership();
+ ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > createNewModel_deliverOwnership( bool _bInitialize );
struct ResetModelAccess { friend class ODatabaseDocument; private: ResetModelAccess() { } };
@@ -336,7 +402,9 @@ public:
Only to be called when the model is being disposed
*/
- void modelIsDisposing( ResetModelAccess );
+ void modelIsDisposing( const bool _wasInitialized, ResetModelAccess );
+
+ bool hadInitializedDocument() const { return m_bDocumentInitialized; }
DocumentStorageAccess*
getDocumentStorageAccess();
@@ -459,7 +527,7 @@ public:
const ::rtl::OUString& _rDocumentURL
);
- /** returns the macro mode imposed by an external instance, by passing it to attachResource
+ /** returns the macro mode imposed by an external instance, which passed it to attachResource
*/
sal_Int16 getImposedMacroExecMode() const
{
@@ -517,7 +585,7 @@ protected:
}
public:
- struct GuardAccess { friend class ModelMethodGuard; friend class ModifyLock; private: GuardAccess() { } };
+ struct GuardAccess { friend class ModelMethodGuard; private: GuardAccess() { } };
/** returns the mutex used for thread safety
@@ -534,18 +602,19 @@ public:
return m_pImpl;
}
+ /// checks whether the component is already disposed, throws a DisposedException if so
inline void checkDisposed() const
{
if ( !m_pImpl.is() )
throw ::com::sun::star::lang::DisposedException( ::rtl::OUString::createFromAscii( "Component is already disposed." ), getThis() );
}
- inline void lockModify( GuardAccess )
+ inline void lockModify()
{
m_pImpl->lockModify();
}
- inline void unlockModify( GuardAccess )
+ inline void unlockModify()
{
m_pImpl->unlockModify();
}
@@ -557,12 +626,12 @@ public:
ModifyLock( ModelDependentComponent& _component )
:m_rComponent( _component )
{
- m_rComponent.lockModify( ModelDependentComponent::GuardAccess() );
+ m_rComponent.lockModify();
}
~ModifyLock()
{
- m_rComponent.unlockModify( ModelDependentComponent::GuardAccess() );
+ m_rComponent.unlockModify();
}
private:
@@ -574,7 +643,7 @@ private:
Just put this guard onto the stack at the beginning of your method. Don't bother yourself
with a MutexGuard, checks for being disposed, and the like.
*/
-class ModelMethodGuard :public ::osl::ResettableMutexGuard
+class ModelMethodGuard : public ::osl::ResettableMutexGuard
{
private:
typedef ::osl::ResettableMutexGuard BaseMutexGuard;
@@ -594,14 +663,8 @@ public:
_component.checkDisposed();
}
- inline void clear()
- {
- BaseMutexGuard::clear();
- }
-
- inline void reset()
+ ~ModelMethodGuard()
{
- BaseMutexGuard::reset();
}
};
diff --git a/dbaccess/source/core/dataaccess/databasecontext.cxx b/dbaccess/source/core/dataaccess/databasecontext.cxx
index 527f37a5b..55c09a5d4 100644
--- a/dbaccess/source/core/dataaccess/databasecontext.cxx
+++ b/dbaccess/source/core/dataaccess/databasecontext.cxx
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: databasecontext.cxx,v $
- * $Revision: 1.43 $
+ * $Revision: 1.43.4.3 $
*
* This file is part of OpenOffice.org.
*
@@ -190,33 +190,36 @@ Sequence< ::rtl::OUString > ODatabaseContext::getSupportedServiceNames( ) throw
}
//--------------------------------------------------------------------------
-Reference< XInterface > SAL_CALL ODatabaseContext::createInstance( ) throw (Exception, RuntimeException)
+Reference< XInterface > ODatabaseContext::impl_createNewDataSource()
{
::rtl::Reference<ODatabaseModelImpl> pImpl( new ODatabaseModelImpl( m_aContext.getLegacyServiceFactory(), *this ) );
- Reference< XDataSource > xDataSource( pImpl->getDataSource() );
+ Reference< XDataSource > xDataSource( pImpl->getOrCreateDataSource() );
+
return xDataSource.get();
}
//--------------------------------------------------------------------------
+Reference< XInterface > SAL_CALL ODatabaseContext::createInstance( ) throw (Exception, RuntimeException)
+{
+ // for convenience of the API user, we ensure the document is fully initialized (effectively: XLoadable::initNew
+ // has been called at the DatabaseDocument).
+ return impl_createNewDataSource();
+}
+
+//--------------------------------------------------------------------------
Reference< XInterface > SAL_CALL ODatabaseContext::createInstanceWithArguments( const Sequence< Any >& _rArguments ) throw (Exception, RuntimeException)
{
- const Any* pIter = _rArguments.getConstArray();
- const Any* pEnd = pIter + _rArguments.getLength();
- NamedValue aValue;
- Reference< XInterface > xExistent;
- ::rtl::OUString sURL;
- for (; pIter != pEnd; ++pIter)
- {
- if ( (*pIter >>= aValue) && aValue.Name == INFO_POOLURL && (aValue.Value >>= sURL) )
- {
- xExistent = getObject(sURL);
- break;
- }
- }
- if ( !xExistent.is() )
- xExistent = createInstance();
+ ::comphelper::NamedValueCollection aArgs( _rArguments );
+ ::rtl::OUString sURL = aArgs.getOrDefault( (::rtl::OUString)INFO_POOLURL, ::rtl::OUString() );
- return xExistent;
+ Reference< XInterface > xDataSource;
+ if ( sURL.getLength() )
+ xDataSource = getObject( sURL );
+
+ if ( !xDataSource.is() )
+ xDataSource = impl_createNewDataSource();
+
+ return xDataSource;
}
// DatabaseAccessContext_Base
//------------------------------------------------------------------------------
@@ -233,7 +236,6 @@ void ODatabaseContext::disposing()
++aIter
)
{
- OSL_ENSURE(aIter->second->m_refCount != 0,"Object is already disposed");
aIter->second->dispose();
}
m_aDatabaseObjects.clear();
@@ -333,22 +335,24 @@ Reference< XInterface > ODatabaseContext::loadObjectFromURL(const ::rtl::OUStrin
{
pExistent.set( new ODatabaseModelImpl( _rName, m_aContext.getLegacyServiceFactory(), *this ) );
+ Reference< XModel > xModel( pExistent->createNewModel_deliverOwnership( false ), UNO_SET_THROW );
+ Reference< XLoadable > xLoad( xModel, UNO_QUERY_THROW );
+
::comphelper::NamedValueCollection aArgs;
aArgs.put( "FileName", _sURL );
aArgs.put( "MacroExecutionMode", MacroExecMode::USE_CONFIG );
aArgs.put( "InteractionHandler", m_aContext.createComponent( "com.sun.star.sdb.InteractionHandler" ) );
- Reference< XModel > xModel = pExistent->createNewModel_deliverOwnership();
- DBG_ASSERT( xModel.is(), "ODatabaseContext::loadObjectFromURL: no model?" );
-
- xModel->attachResource( _sURL, aArgs.getPropertyValues() );
+ Sequence< PropertyValue > aResource( aArgs.getPropertyValues() );
+ xLoad->load( aResource );
+ xModel->attachResource( _sURL, aResource );
::utl::CloseableComponent aEnsureClose( xModel );
}
setTransientProperties( _sURL, *pExistent );
- return pExistent->getDataSource().get();
+ return pExistent->getOrCreateDataSource().get();
}
// -----------------------------------------------------------------------------
void ODatabaseContext::setTransientProperties(const ::rtl::OUString& _sURL, ODatabaseModelImpl& _rDataSourceModel )
@@ -358,7 +362,7 @@ void ODatabaseContext::setTransientProperties(const ::rtl::OUString& _sURL, ODat
try
{
::rtl::OUString sAuthFailedPassword;
- Reference< XPropertySet > xDSProps( _rDataSourceModel.getDataSource(), UNO_QUERY_THROW );
+ Reference< XPropertySet > xDSProps( _rDataSourceModel.getOrCreateDataSource(), UNO_QUERY_THROW );
const Sequence< PropertyValue >& rSessionPersistentProps = m_aDatasourceProperties[_sURL];
const PropertyValue* pProp = rSessionPersistentProps.getConstArray();
const PropertyValue* pPropsEnd = rSessionPersistentProps.getConstArray() + rSessionPersistentProps.getLength();
@@ -428,7 +432,7 @@ void ODatabaseContext::registerObject(const rtl::OUString& _rName, const Referen
//------------------------------------------------------------------------------
void ODatabaseContext::storeTransientProperties( ODatabaseModelImpl& _rModelImpl)
{
- Reference< XPropertySet > xSource(_rModelImpl.getDataSource(),UNO_QUERY);
+ Reference< XPropertySet > xSource( _rModelImpl.getOrCreateDataSource(), UNO_QUERY );
::comphelper::NamedValueCollection aRememberProps;
try
@@ -641,7 +645,7 @@ Reference< XInterface > ODatabaseContext::getObject(const ::rtl::OUString& _rNam
ObjectCacheIterator aFind = m_aDatabaseObjects.find(_rName);
Reference< XInterface > xExistent;
if ( aFind != m_aDatabaseObjects.end() )
- xExistent = aFind->second->getDataSource();
+ xExistent = aFind->second->getOrCreateDataSource();
return xExistent;
}
// -----------------------------------------------------------------------------
diff --git a/dbaccess/source/core/dataaccess/databasecontext.hxx b/dbaccess/source/core/dataaccess/databasecontext.hxx
index a915ab11d..3b5ea93f8 100644
--- a/dbaccess/source/core/dataaccess/databasecontext.hxx
+++ b/dbaccess/source/core/dataaccess/databasecontext.hxx
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: databasecontext.hxx,v $
- * $Revision: 1.17 $
+ * $Revision: 1.17.2.2 $
*
* This file is part of OpenOffice.org.
*
@@ -138,6 +138,11 @@ private:
*/
void setTransientProperties(const ::rtl::OUString& _sURL, ODatabaseModelImpl& _rDataSourceModel );
+ /** creates a new data source
+ */
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >
+ impl_createNewDataSource();
+
protected:
::osl::Mutex m_aMutex;
::comphelper::ComponentContext m_aContext;
diff --git a/dbaccess/source/core/dataaccess/databasedocument.cxx b/dbaccess/source/core/dataaccess/databasedocument.cxx
index 131dcbf84..012c60f82 100644
--- a/dbaccess/source/core/dataaccess/databasedocument.cxx
+++ b/dbaccess/source/core/dataaccess/databasedocument.cxx
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: databasedocument.cxx,v $
- * $Revision: 1.48 $
+ * $Revision: 1.40.6.21 $
*
* This file is part of OpenOffice.org.
*
@@ -35,93 +35,49 @@
#include "databasedocument.hxx"
#include "dbastrings.hrc"
#include "module_dba.hxx"
+#include "documentevents.hxx"
+#include "documenteventexecutor.hxx"
+#include "databasecontext.hxx"
+#include "documentcontainer.hxx"
-#include <comphelper/documentconstants.hxx>
-#include <comphelper/namedvaluecollection.hxx>
-#include <comphelper/enumhelper.hxx>
-#include <comphelper/numberedcollection.hxx>
#include <comphelper/genericpropertyset.hxx>
#include <comphelper/property.hxx>
#include <svtools/saveopt.hxx>
-#include <framework/titlehelper.hxx>
-#ifndef _COM_SUN_STAR_EMBED_XTRANSACTEDOBJECT_HPP_
+/** === begin UNO includes === **/
+#include <com/sun/star/document/XExporter.hpp>
+#include <com/sun/star/document/XFilter.hpp>
+#include <com/sun/star/document/XImporter.hpp>
+#include <com/sun/star/embed/EntryInitModes.hpp>
+#include <com/sun/star/embed/XEmbedPersist.hpp>
#include <com/sun/star/embed/XTransactedObject.hpp>
-#endif
-#ifndef _COM_SUN_STAR_IO_XACTIVEDATASOURCE_HPP_
+#include <com/sun/star/embed/XTransactionBroadcaster.hpp>
#include <com/sun/star/io/XActiveDataSource.hpp>
-#endif
-#ifndef _COM_SUN_STAR_IO_XSEEKABLE_HPP_
#include <com/sun/star/io/XSeekable.hpp>
-#endif
-#ifndef _COM_SUN_STAR_TASK_XSTATUSINDICATOR_HPP_
+#include <com/sun/star/script/provider/XScriptProviderFactory.hpp>
+#include <com/sun/star/task/ErrorCodeIOException.hpp>
#include <com/sun/star/task/XStatusIndicator.hpp>
-#endif
-#ifndef _COM_SUN_STAR_TASK_XSTATUSINDICATORFACTORY_HPP_
#include <com/sun/star/task/XStatusIndicatorFactory.hpp>
-#endif
-#ifndef _COM_SUN_STAR_DOCUMENT_XEXPORTER_HPP_
-#include <com/sun/star/document/XExporter.hpp>
-#endif
-#ifndef _COM_SUN_STAR_DOCUMENT_XFILTER_HPP_
-#include <com/sun/star/document/XFilter.hpp>
-#endif
-#ifndef _COM_SUN_STAR_TASK_ERRORCODEIOEXCEPTION_HPP_
-#include <com/sun/star/task/ErrorCodeIOException.hpp>
-#endif
-#ifndef _COM_SUN_STAR_XML_SAX_XDOCUMENTHANDLER_HPP_
-#include <com/sun/star/xml/sax/XDocumentHandler.hpp>
-#endif
-#ifndef _DBA_COREDATAACCESS_DOCUMENTCONTAINER_HXX_
-#include "documentcontainer.hxx"
-#endif
-#ifndef _DBA_COREDATAACCESS_DATABASECONTEXT_HXX_
-#include "databasecontext.hxx"
-#endif
-#ifndef _URLOBJ_HXX
-#include <tools/urlobj.hxx>
-#endif
-#ifndef TOOLS_DIAGNOSE_EX_H
-#include <tools/diagnose_ex.h>
-#endif
-#ifndef _ERRCODE_HXX
-#include <tools/errcode.hxx>
-#endif
-#ifndef _COMPHELPER_MEDIADESCRIPTOR_HXX_
-#include <comphelper/mediadescriptor.hxx>
-#endif
-#ifndef _COM_SUN_STAR_UI_XUICONFIGURATIONSTORAGE_HPP_
#include <com/sun/star/ui/XUIConfigurationStorage.hpp>
-#endif
-#ifndef _COM_SUN_STAR_EMBED_XTRANSACTIONBROADCASTER_HPP_
-#include <com/sun/star/embed/XTransactionBroadcaster.hpp>
-#endif
-#ifndef _COM_SUN_STAR_EMBED_XEMBEDPERSIST_HPP_
-#include <com/sun/star/embed/XEmbedPersist.hpp>
-#endif
-#ifndef _COM_SUN_STAR_EMBED_ENTRYINITMODES_HPP_
-#include <com/sun/star/embed/EntryInitModes.hpp>
-#endif
-#ifndef _COM_SUN_STAR_VIEW_XSELECTIONSUPPLIER_HPP_
#include <com/sun/star/view/XSelectionSupplier.hpp>
-#endif
-#ifndef _COM_SUN_STAR_DOCUMENT_XIMPORTER_HPP_
-#include <com/sun/star/document/XImporter.hpp>
-#endif
-#ifndef _COM_SUN_STAR_SCRIPT_PROVIDER_XSCRIPTPROVIDERFACTORY_HPP_
-#include <com/sun/star/script/provider/XScriptProviderFactory.hpp>
-#endif
-#ifndef _TOOLS_DEBUG_HXX
-#include <tools/debug.hxx>
-#endif
-#ifndef _CPPUHELPER_EXC_HLP_HXX_
+#include <com/sun/star/xml/sax/XDocumentHandler.hpp>
+/** === end UNO includes === **/
+
+#include <comphelper/documentconstants.hxx>
+#include <comphelper/enumhelper.hxx>
+#include <comphelper/mediadescriptor.hxx>
+#include <comphelper/namedvaluecollection.hxx>
+#include <comphelper/numberedcollection.hxx>
+#include <comphelper/storagehelper.hxx>
#include <cppuhelper/exc_hlp.hxx>
-#endif
+#include <framework/titlehelper.hxx>
+#include <tools/debug.hxx>
+#include <tools/diagnose_ex.h>
+#include <tools/errcode.hxx>
+#include <tools/urlobj.hxx>
-#ifndef BOOST_BIND_HPP_INCLUDED
#include <boost/bind.hpp>
-#endif
#include <algorithm>
#include <functional>
@@ -156,7 +112,35 @@ namespace dbaccess
//........................................................................
//============================================================
-//= ODatabaseContext
+//= ViewMonitor
+//============================================================
+//--------------------------------------------------------------------------
+bool ViewMonitor::onControllerConnected( const Reference< XController >& _rxController )
+{
+ bool bFirstControllerEver = ( m_bEverHadController == false );
+ m_bEverHadController = true;
+
+ m_xLastConnectedController = _rxController;
+ m_bLastIsFirstEverController = bFirstControllerEver;
+
+ return bFirstControllerEver;
+}
+
+//--------------------------------------------------------------------------
+void ViewMonitor::onSetCurrentController( const Reference< XController >& _rxController )
+{
+ // we interpret this as "loading the document (including UI) is finished",
+ // if and only if this is the controller which was last connected, and it was the
+ // first controller ever connected
+ bool bLoadFinished = ( _rxController == m_xLastConnectedController ) && m_bLastIsFirstEverController;
+
+ // notify the respective events
+ if ( bLoadFinished )
+ m_rEventNotifier.notifyDocumentEventAsync( m_bIsNewDocument ? "OnNew" : "OnLoad" );
+}
+
+//============================================================
+//= ODatabaseDocument
//============================================================
DBG_NAME(ODatabaseDocument)
//--------------------------------------------------------------------------
@@ -171,8 +155,13 @@ ODatabaseDocument::ODatabaseDocument(const ::rtl::Reference<ODatabaseModelImpl>&
,ODatabaseDocument_OfficeDocument( getMutex() )
,m_aModifyListeners( getMutex() )
,m_aCloseListener( getMutex() )
- ,m_aDocEventListeners( getMutex() )
,m_aStorageListeners( getMutex() )
+ ,m_pEventContainer( new DocumentEvents( *this, getMutex() ) )
+ ,m_pEventExecutor( NULL ) // initialized below, ref-count-protected
+ ,m_aEventNotifier( *this, getMutex() )
+ ,m_aViewMonitor( m_aEventNotifier )
+ ,m_eInitState( NotInitialized )
+ ,m_bClosing( false )
{
DBG_CTOR(ODatabaseDocument,NULL);
@@ -182,8 +171,16 @@ ODatabaseDocument::ODatabaseDocument(const ::rtl::Reference<ODatabaseModelImpl>&
impl_reparent_nothrow( m_xReports );
impl_reparent_nothrow( m_pImpl->m_xTableDefinitions );
impl_reparent_nothrow( m_pImpl->m_xCommandDefinitions );
+
+ m_pEventExecutor = new DocumentEventExecutor( m_pImpl->m_aContext, this );
}
osl_decrementInterlockedCount( &m_refCount );
+
+ // if there previously was a document instance for the same Impl which was already initialized,
+ // then consider ourself initialized, too.
+ // #i94840#
+ if ( m_pImpl->hadInitializedDocument() )
+ impl_setInitialized();
}
//--------------------------------------------------------------------------
@@ -195,6 +192,8 @@ ODatabaseDocument::~ODatabaseDocument()
acquire();
dispose();
}
+
+ delete m_pEventContainer, m_pEventContainer = NULL;
}
// -----------------------------------------------------------------------------
Any SAL_CALL ODatabaseDocument::queryInterface( const Type& _rType ) throw (RuntimeException)
@@ -286,12 +285,9 @@ Sequence< sal_Int8 > SAL_CALL ODatabaseDocument::getImplementationId( ) throw (
bool ODatabaseDocument::impl_shouldDisallowScripting_nolck_nothrow() const
{
::osl::MutexGuard aGuard( getMutex() );
- // TODO: revert to the disabled code. The current version is just to be able
- // to integrate an intermediate version of the CWS, which should behave as
- // if no macros in DB docs are allowed
-// if ( m_pImpl.is() && m_pImpl->hasAnyObjectWithMacros() )
+ if ( m_pImpl.is() && m_pImpl->hasAnyObjectWithMacros() )
return true;
-// return false;
+ return false;
}
// -----------------------------------------------------------------------------
@@ -299,15 +295,6 @@ bool ODatabaseDocument::impl_shouldDisallowScripting_nolck_nothrow() const
// -----------------------------------------------------------------------------
namespace
{
- static void lcl_stripLoadArguments( ::comphelper::NamedValueCollection& _rArguments, Sequence< PropertyValue >& _rArgs )
- {
- OSL_ENSURE( !_rArguments.has( "Model" ), "lcl_stripLoadArguments: this is suspicious (1)!" );
- OSL_ENSURE( !_rArguments.has( "ViewName" ), "lcl_stripLoadArguments: this is suspicious (2)!" );
- _rArguments.remove( "Model" );
- _rArguments.remove( "ViewName" );
- _rArguments >>= _rArgs;
- }
-
// -----------------------------------------------------------------------------
static void lcl_extractAndStartStatusIndicator( const ::comphelper::NamedValueCollection& _rArguments, Reference< XStatusIndicator >& _rxStatusIndicator,
Sequence< Any >& _rCallArgs )
@@ -343,6 +330,15 @@ namespace
}
// -----------------------------------------------------------------------------
+void ODatabaseDocument::impl_setInitialized()
+{
+ m_eInitState = Initialized;
+
+ // start event notifications
+ m_aEventNotifier.onDocumentInitialized();
+}
+
+// -----------------------------------------------------------------------------
void ODatabaseDocument::impl_reset_nothrow()
{
try
@@ -356,6 +352,8 @@ void ODatabaseDocument::impl_reset_nothrow()
clearObjectContainer( m_pImpl->m_xTableDefinitions );
clearObjectContainer( m_pImpl->m_xCommandDefinitions );
+ m_eInitState = NotInitialized;
+
m_pImpl->reset();
}
catch(const Exception&)
@@ -366,140 +364,186 @@ void ODatabaseDocument::impl_reset_nothrow()
}
// -----------------------------------------------------------------------------
-bool ODatabaseDocument::impl_import_throw( const ::comphelper::NamedValueCollection& _rResource )
+void ODatabaseDocument::impl_import_throw( const ::comphelper::NamedValueCollection& _rResource )
{
- try
- {
- Sequence< Any > aFilterArgs;
- Reference< XStatusIndicator > xStatusIndicator;
- lcl_extractAndStartStatusIndicator( _rResource, xStatusIndicator, aFilterArgs );
+ Sequence< Any > aFilterArgs;
+ Reference< XStatusIndicator > xStatusIndicator;
+ lcl_extractAndStartStatusIndicator( _rResource, xStatusIndicator, aFilterArgs );
- Reference< XImporter > xImporter(
- m_pImpl->m_aContext.createComponentWithArguments( "com.sun.star.comp.sdb.DBFilter", aFilterArgs ),
- UNO_QUERY_THROW );
+ Reference< XImporter > xImporter(
+ m_pImpl->m_aContext.createComponentWithArguments( "com.sun.star.comp.sdb.DBFilter", aFilterArgs ),
+ UNO_QUERY_THROW );
- Reference< XComponent > xComponent( *this, UNO_QUERY_THROW );
- xImporter->setTargetDocument( xComponent );
+ Reference< XComponent > xComponent( *this, UNO_QUERY_THROW );
+ xImporter->setTargetDocument( xComponent );
- Reference< XFilter > xFilter( xImporter, UNO_QUERY_THROW );
- xFilter->filter( m_pImpl->m_aArgs );
+ Reference< XFilter > xFilter( xImporter, UNO_QUERY_THROW );
+ xFilter->filter( ODatabaseModelImpl::stripLoadArguments( _rResource ) );
- if ( xStatusIndicator.is() )
- xStatusIndicator->end();
- }
- catch( const RuntimeException& e )
- {
- throw e;
- }
- catch( const Exception& )
- {
- return false;
- }
- return true;
+ if ( xStatusIndicator.is() )
+ xStatusIndicator->end();
}
// -----------------------------------------------------------------------------
-// XModel
-// ATTENTION: The Application controller attaches the same resource to force a reload.
-// TODO: this is a bug. By (API) definition, attachResource is only for notifying the document
-// of its resource, *not* for loading it. We should implement an XLoadable, and move all the
-// load logic therein.
-sal_Bool SAL_CALL ODatabaseDocument::attachResource( const ::rtl::OUString& _rURL, const Sequence< PropertyValue >& _aArguments ) throw (RuntimeException)
+void SAL_CALL ODatabaseDocument::initNew( ) throw (DoubleInitializationException, IOException, Exception, RuntimeException)
{
- ModelMethodGuard aGuard( *this );
- OSL_ENSURE(m_pImpl.is(),"Impl is NULL");
+ // SYNCHRONIZED ->
+ DocumentGuard aGuard( *this, DocumentGuard::InitMethod );
impl_reset_nothrow();
- ::comphelper::NamedValueCollection aResource( _aArguments );
- lcl_stripLoadArguments( aResource, m_pImpl->m_aArgs );
+ impl_setInitializing();
+
+ // create a temporary storage
+ Reference< XStorage > xTempStor( ::comphelper::OStorageHelper::GetTemporaryStorage(
+ m_pImpl->m_aContext.getLegacyServiceFactory() ) );
+
+ // store therein
+ impl_storeToStorage_throw( xTempStor, Sequence< PropertyValue >() );
+
+ // let the impl know we're now based on this storage
+ m_pImpl->switchToStorage( xTempStor );
+
+ impl_setInitialized();
+
+ m_aEventNotifier.notifyDocumentEventAsync( "OnTitleChanged" );
+
+ impl_setModified_nothrow( sal_False, aGuard );
+ // <- SYNCHRONIZED
+
+ m_aEventNotifier.notifyDocumentEvent( "OnCreate" );
+
+ impl_notifyStorageChange_nolck_nothrow( xTempStor );
+}
+
+// -----------------------------------------------------------------------------
+void SAL_CALL ODatabaseDocument::load( const Sequence< PropertyValue >& _Arguments ) throw (DoubleInitializationException, IOException, Exception, RuntimeException)
+{
+ // SYNCHRONIZED ->
+ DocumentGuard aGuard( *this, DocumentGuard::InitMethod );
+
+ impl_reset_nothrow();
+
+ ::comphelper::NamedValueCollection aResource( _Arguments );
// now that somebody (perhaps) told us an macro execution mode, remember it as
// ImposedMacroExecMode
m_pImpl->setImposedMacroExecMode(
aResource.getOrDefault( "MacroExecutionMode", m_pImpl->getImposedMacroExecMode() ) );
- ::rtl::OUString sDocumentLocation( aResource.getOrDefault( "SalvagedFile", _rURL ) );
- if ( !sDocumentLocation.getLength() )
- // this indicates "the document is being recovered, but _rURL already is the real document URL,
- // not the temporary document location"
- sDocumentLocation = _rURL;
- m_pImpl->switchToURL( sDocumentLocation, _rURL );
+ impl_setInitializing();
+ try
+ {
+ impl_import_throw( aResource );
+ }
+ catch( const Exception& )
+ {
+ impl_reset_nothrow();
+ throw;
+ }
+ // tell our view monitor that the document has been loaded - this way it will fire the proper
+ // even (OnLoad instead of OnCreate) later on
+ m_aViewMonitor.onLoadedDocument();
- bool bSuccess =
- ( m_pImpl->getOrCreateRootStorage().is()
- && impl_import_throw( aResource ) // TODO: this doesn't belong here, but into an (externally called) XLoadable::load implementation
- );
+ // note that we do *not* call impl_setInitialized() here: The initialization is only complete
+ // when the XModel::attachResource has been called, not sooner.
+
+ impl_setModified_nothrow( sal_False, aGuard );
+ // <- SYNCHRONIZED
+}
- if ( !bSuccess )
+// -----------------------------------------------------------------------------
+// XModel
+sal_Bool SAL_CALL ODatabaseDocument::attachResource( const ::rtl::OUString& _rURL, const Sequence< PropertyValue >& _rArguments ) throw (RuntimeException)
+{
+ DocumentGuard aGuard( *this, DocumentGuard::MethodUsedDuringInit );
+
+ if ( ( _rURL == getURL() )
+ && ( _rArguments.getLength() == 1 )
+ && ( _rArguments[0].Name.compareToAscii( "BreakMacroSignature" ) == 0 )
+ )
{
- m_pImpl->revokeDataSource();
+ // this is a BAD hack of the Basic importer code ... there should be a dedicated API for this,
+ // not this bad mis-using of existing interfaces
return sal_False;
+ // (we do not support macro signatures, so we can ignore this call)
+ }
+
+ m_pImpl->attachResource( _rURL, _rArguments );
+
+ if ( impl_isInitializing() )
+ { // this means we've just been loaded, and this is the attachResource call which follows
+ // the load call.
+ impl_setInitialized();
+ m_aEventNotifier.notifyDocumentEvent( "OnLoadFinished" );
}
- impl_setModified_throw( sal_False, aGuard );
return sal_True;
}
+
// -----------------------------------------------------------------------------
::rtl::OUString SAL_CALL ODatabaseDocument::getURL( ) throw (RuntimeException)
{
- ModelMethodGuard aGuard( *this );
+ DocumentGuard aGuard( *this, DocumentGuard::MethodWithoutInit );
return m_pImpl->getURL();
}
+
// -----------------------------------------------------------------------------
Sequence< PropertyValue > SAL_CALL ODatabaseDocument::getArgs( ) throw (RuntimeException)
{
- ModelMethodGuard aGuard( *this );
- return m_pImpl->m_aArgs;
+ DocumentGuard aGuard( *this, DocumentGuard::MethodWithoutInit );
+ return m_pImpl->getResource();
}
+
// -----------------------------------------------------------------------------
void SAL_CALL ODatabaseDocument::connectController( const Reference< XController >& _xController ) throw (RuntimeException)
{
- ModelMethodGuard aGuard( *this );
+ DocumentGuard aGuard( *this );
m_aControllers.push_back( _xController );
- if ( m_aControllers.size() != 1 )
+ m_aEventNotifier.notifyDocumentEventAsync( "OnViewCreated", Reference< XController2 >( _xController, UNO_QUERY ) );
+
+ bool bFirstControllerEver = m_aViewMonitor.onControllerConnected( _xController );
+ if ( !bFirstControllerEver )
return;
- // it's the first controller
-
- // check/adjust our macro mode. Note: This is only temporary. When we fully support the
- // XEmbeddedScripts interface, plus related functionality, then the controller is able
- // to do this itself, since we'll then have a UNO method for this.
- //
- // Also, the same has to happen in the loader then, since the checks must be made
- // *before* OnLoad events are triggered - finally, the user can bind events to OnLoad ...
- // (This, at the latest, implies we need a UNO equivalent for checkMacrosOnLoading, else
- // the loader can't call it.)
- //
- // For now, as long as we do not have own macros, but only those in the embedded
- // forms/reports, it's sufficient to do the check here.
- //
+ // check/adjust our macro mode.
m_pImpl->checkMacrosOnLoading();
}
// -----------------------------------------------------------------------------
void SAL_CALL ODatabaseDocument::disconnectController( const Reference< XController >& _xController ) throw (RuntimeException)
{
- ModelMethodGuard aGuard( *this );
- OSL_ENSURE(m_pImpl.is(),"Impl is NULL");
+ bool bNotifyViewClosed = false;
+ bool bLastControllerGone = false;
+ bool bIsClosing = false;
+
+ // SYNCHRONIZED ->
+ {
+ DocumentGuard aGuard( *this );
+
+ Controllers::iterator pos = ::std::find( m_aControllers.begin(), m_aControllers.end(), _xController );
+ OSL_ENSURE( pos != m_aControllers.end(), "ODatabaseDocument::disconnectController: don't know this controller!" );
+ if ( pos != m_aControllers.end() )
+ {
+ m_aControllers.erase( pos );
+ bNotifyViewClosed = true;
+ }
- Controllers::iterator pos = ::std::find( m_aControllers.begin(), m_aControllers.end(), _xController );
- OSL_ENSURE( pos != m_aControllers.end(), "ODatabaseDocument::disconnectController: don't know this controller!" );
- if ( pos != m_aControllers.end() )
- m_aControllers.erase( pos );
+ if ( m_xCurrentController == _xController )
+ m_xCurrentController = NULL;
- if ( m_xCurrentController == _xController )
- m_xCurrentController = NULL;
+ bLastControllerGone = m_aControllers.empty();
+ bIsClosing = m_bClosing;
+ }
+ // <- SYNCHRONIZED
- if ( m_aControllers.empty() )
- {
- // reset the macro mode: in case the our impl struct stays alive (e.g. because our DataSource
- // object still exists), and somebody subsequently re-opens the document, we want to have
- // the security warning, again.
- m_pImpl->resetMacroExecutionMode();
+ if ( bNotifyViewClosed )
+ m_aEventNotifier.notifyDocumentEvent( "OnViewClosed", Reference< XController2 >( _xController, UNO_QUERY ) );
+ if ( bLastControllerGone && !bIsClosing )
+ {
// if this was the last view, close the document as a whole
// #i51157# / 2006-03-16 / frank.schoenheit@sun.com
try
@@ -512,51 +556,52 @@ void SAL_CALL ODatabaseDocument::disconnectController( const Reference< XControl
}
}
}
+
// -----------------------------------------------------------------------------
void SAL_CALL ODatabaseDocument::lockControllers( ) throw (RuntimeException)
{
- ModelMethodGuard aGuard( *this );
- OSL_ENSURE(m_pImpl.is(),"Impl is NULL");
+ DocumentGuard aGuard( *this );
++m_pImpl->m_nControllerLockCount;
}
+
// -----------------------------------------------------------------------------
void SAL_CALL ODatabaseDocument::unlockControllers( ) throw (RuntimeException)
{
- ModelMethodGuard aGuard( *this );
- OSL_ENSURE(m_pImpl.is(),"Impl is NULL");
+ DocumentGuard aGuard( *this );
--m_pImpl->m_nControllerLockCount;
}
+
// -----------------------------------------------------------------------------
sal_Bool SAL_CALL ODatabaseDocument::hasControllersLocked( ) throw (RuntimeException)
{
- ModelMethodGuard aGuard( *this );
- OSL_ENSURE(m_pImpl.is(),"Impl is NULL");
+ DocumentGuard aGuard( *this );
return m_pImpl->m_nControllerLockCount != 0;
}
+
// -----------------------------------------------------------------------------
Reference< XController > SAL_CALL ODatabaseDocument::getCurrentController() throw (RuntimeException)
{
- ModelMethodGuard aGuard( *this );
- OSL_ENSURE(m_pImpl.is(),"Impl is NULL");
+ DocumentGuard aGuard( *this );
return m_xCurrentController.is() ? m_xCurrentController : ( m_aControllers.empty() ? Reference< XController >() : *m_aControllers.begin() );
}
+
// -----------------------------------------------------------------------------
void SAL_CALL ODatabaseDocument::setCurrentController( const Reference< XController >& _xController ) throw (NoSuchElementException, RuntimeException)
{
- ModelMethodGuard aGuard( *this );
- OSL_ENSURE(m_pImpl.is(),"Impl is NULL");
+ DocumentGuard aGuard( *this );
m_xCurrentController = _xController;
+
+ m_aViewMonitor.onSetCurrentController( _xController );
}
// -----------------------------------------------------------------------------
Reference< XInterface > SAL_CALL ODatabaseDocument::getCurrentSelection( ) throw (RuntimeException)
{
- ModelMethodGuard aGuard( *this );
- OSL_ENSURE(m_pImpl.is(),"Impl is NULL");
+ DocumentGuard aGuard( *this );
Reference< XInterface > xRet;
Reference< XSelectionSupplier > xDocView( getCurrentController(), UNO_QUERY );
@@ -570,91 +615,115 @@ Reference< XInterface > SAL_CALL ODatabaseDocument::getCurrentSelection( ) thro
// XStorable
sal_Bool SAL_CALL ODatabaseDocument::hasLocation( ) throw (RuntimeException)
{
- ModelMethodGuard aGuard( *this );
- return m_pImpl->getLocation().getLength() > 0;
+ return getLocation().getLength() > 0;
}
// -----------------------------------------------------------------------------
::rtl::OUString SAL_CALL ODatabaseDocument::getLocation( ) throw (RuntimeException)
{
- ModelMethodGuard aGuard( *this );
- return m_pImpl->getLocation();
+ DocumentGuard aGuard( *this, DocumentGuard::MethodWithoutInit );
+ return m_pImpl->getURL();
}
// -----------------------------------------------------------------------------
sal_Bool SAL_CALL ODatabaseDocument::isReadonly( ) throw (RuntimeException)
{
- ModelMethodGuard aGuard( *this );
- OSL_ENSURE(m_pImpl.is(),"Impl is NULL");
-
+ DocumentGuard aGuard( *this, DocumentGuard::MethodWithoutInit );
return m_pImpl->m_bDocumentReadOnly;
}
// -----------------------------------------------------------------------------
void SAL_CALL ODatabaseDocument::store( ) throw (IOException, RuntimeException)
{
- ModelMethodGuard aGuard( *this );
- //ModifyLock aLock( *this );
+ DocumentGuard aGuard( *this );
- if ( m_pImpl->getLocation() == m_pImpl->getURL() )
+ if ( m_pImpl->getDocFileLocation() == m_pImpl->getURL() )
if ( m_pImpl->m_bDocumentReadOnly )
throw IOException();
- impl_storeAs_throw( m_pImpl->getURL(), m_pImpl->m_aArgs, "OnSaveDone", aGuard );
+ impl_storeAs_throw( m_pImpl->getURL(), m_pImpl->getResource(), SAVE, aGuard );
}
// -----------------------------------------------------------------------------
void ODatabaseDocument::impl_storeAs_throw( const ::rtl::OUString& _rURL, const Sequence< PropertyValue>& _rArguments,
- const sal_Char* _pAsciiDocumentEventName, ModelMethodGuard& _rGuard )
+ const StoreType _eType, DocumentGuard& _rGuard )
{
+ OSL_PRECOND( ( _eType == SAVE ) || ( _eType == SAVE_AS ),
+ "ODatabaseDocument::impl_storeAs_throw: you introduced a new type which cannot be handled here!" );
+
+ // if we're in the process of initializing the document (which effectively means it is an implicit
+ // initialization triggered in storeAsURL), the we do not notify events, since to an observer, the SaveAs
+ // should not be noticable
+ bool bIsInitializationProcess = impl_isInitializing();
+
+ if ( !bIsInitializationProcess )
+ {
+ _rGuard.clear();
+ m_aEventNotifier.notifyDocumentEvent( _eType == SAVE ? "OnSave" : "OnSaveAs", NULL, makeAny( _rURL ) );
+ _rGuard.reset();
+ }
+
Reference< XStorage > xNewRootStorage;
// will be non-NULL if our storage changed
- sal_Bool bLocationChanged = ( _rURL != m_pImpl->getLocation() );
- if ( bLocationChanged )
+ try
{
- // create storage for target URL
- Reference< XStorage > xTargetStorage( impl_createStorageFor_throw( _rURL ) );
+ ModifyLock aLock( *this );
+ // ignore all changes of our "modified" state during storing
- if ( m_pImpl->isEmbeddedDatabase() )
- m_pImpl->clearConnections();
-
- // commit everything
- m_pImpl->commitEmbeddedStorage();
- m_pImpl->commitStorages();
+ sal_Bool bLocationChanged = ( _rURL != m_pImpl->getDocFileLocation() );
+ if ( bLocationChanged )
+ {
+ // create storage for target URL
+ Reference< XStorage > xTargetStorage( impl_createStorageFor_throw( _rURL ) );
- // copy own storage to target storage
- Reference< XStorage > xCurrentStorage( m_pImpl->getRootStorage() );
- if ( xCurrentStorage.is() )
- xCurrentStorage->copyToStorage( xTargetStorage );
+ if ( m_pImpl->isEmbeddedDatabase() )
+ m_pImpl->clearConnections();
- m_pImpl->disposeStorages();
+ // commit everything
+ m_pImpl->commitEmbeddedStorage();
+ m_pImpl->commitStorages();
- xNewRootStorage = m_pImpl->switchToStorage( xTargetStorage );
+ // copy own storage to target storage
+ Reference< XStorage > xCurrentStorage( m_pImpl->getRootStorage() );
+ if ( xCurrentStorage.is() )
+ xCurrentStorage->copyToStorage( xTargetStorage );
- m_pImpl->m_bDocumentReadOnly = sal_False;
- }
+ m_pImpl->disposeStorages();
- // adjust arguments
- ::comphelper::NamedValueCollection aResource( _rArguments );
- lcl_stripLoadArguments( aResource, m_pImpl->m_aArgs );
- Sequence< PropertyValue > aMediaDescriptor( lcl_appendFileNameToDescriptor( m_pImpl->m_aArgs, _rURL ) );
+ xNewRootStorage = m_pImpl->switchToStorage( xTargetStorage );
- // store to current storage
- Reference< XStorage > xCurrentStorage( m_pImpl->getOrCreateRootStorage(), UNO_QUERY_THROW );
- impl_storeToStorage_throw( xCurrentStorage, aMediaDescriptor );
+ m_pImpl->m_bDocumentReadOnly = sal_False;
+ }
- // success - tell our impl the new URL
- m_pImpl->switchToURL( _rURL, _rURL );
+ // store to current storage
+ Reference< XStorage > xCurrentStorage( m_pImpl->getOrCreateRootStorage(), UNO_QUERY_THROW );
+ Sequence< PropertyValue > aMediaDescriptor( lcl_appendFileNameToDescriptor( _rArguments, _rURL ) );
+ impl_storeToStorage_throw( xCurrentStorage, aMediaDescriptor );
- // create a document event (mutex still locked)
- document::EventObject aEvent( *this, ::rtl::OUString::createFromAscii( _pAsciiDocumentEventName ) );
+ // success - tell our impl
+ m_pImpl->attachResource( _rURL, aMediaDescriptor );
- // reset our "modified" flag, and clear the guard
- impl_setModified_throw( sal_False, _rGuard );
+ // if we are in an initialization process, then this is finished, now that we stored the document
+ if ( bIsInitializationProcess )
+ impl_setInitialized();
+ }
+ catch( const Exception& )
+ {
+ // notify the failure
+ if ( !bIsInitializationProcess )
+ m_aEventNotifier.notifyDocumentEventAsync( _eType == SAVE ? "OnSaveFailed" : "OnSaveAsFailed", NULL, makeAny( _rURL ) );
+ throw;
+ }
// notify the document event
- impl_notifyEvent_nolck_nothrow( aEvent );
+ if ( !bIsInitializationProcess )
+ m_aEventNotifier.notifyDocumentEventAsync( _eType == SAVE ? "OnSaveDone" : "OnSaveAsDone", NULL, makeAny( _rURL ) );
+
+ // reset our "modified" flag, and clear the guard
+ impl_setModified_nothrow( sal_False, _rGuard );
+ // <- SYNCHRONIZED
// notify storage listeners
- impl_notifyStorageChange_nolck_nothrow( xNewRootStorage );
+ if ( xNewRootStorage.is() )
+ impl_notifyStorageChange_nolck_nothrow( xNewRootStorage );
}
// -----------------------------------------------------------------------------
@@ -671,10 +740,46 @@ Reference< XStorage > ODatabaseDocument::impl_createStorageFor_throw( const ::rt
// -----------------------------------------------------------------------------
void SAL_CALL ODatabaseDocument::storeAsURL( const ::rtl::OUString& _rURL, const Sequence< PropertyValue >& _rArguments ) throw (IOException, RuntimeException)
{
- ModelMethodGuard aGuard( *this );
- //ModifyLock aLock( *this );
+ // SYNCHRONIZED ->
+ DocumentGuard aGuard( *this, DocumentGuard::MethodWithoutInit );
+
+ // Normally, a document initialization is done via XLoadable::load or XLoadable::initNew. For convenience
+ // reasons, and to not break existing API clients, it's allowed to call storeAsURL without having initialized
+ // the document, in which case the initialization will be done implicitly.
+ bool bImplicitInitialization = !impl_isInitialized();
+ // implicit initialization while another initialization is just running is not possible
+ if ( bImplicitInitialization && impl_isInitializing() )
+ throw DoubleInitializationException();
- impl_storeAs_throw( _rURL, _rArguments, "OnSaveAsDone", aGuard );
+ if ( bImplicitInitialization )
+ impl_setInitializing();
+
+ try
+ {
+ impl_storeAs_throw( _rURL, _rArguments, SAVE_AS, aGuard );
+ // <- SYNCHRONIZED
+
+ // impl_storeAs_throw cleared the lock on our mutex, but the below lines need this lock
+ // SYNCHRONIZED ->
+ aGuard.reset();
+
+ // our title might have changed, potentially at least
+ // Sadly, we cannot check this: Calling getTitle here and now would not deliver
+ // an up-to-date result, as the call is delegated to our TitleHelper instance, which itself
+ // updates its title only if it gets the OnSaveAsDone event (which was sent asynchronously
+ // by impl_storeAs_throw). So, we simply notify always, and also asynchronously
+ m_aEventNotifier.notifyDocumentEventAsync( "OnTitleChanged" );
+ }
+ catch( const Exception& )
+ {
+ impl_reset_nothrow();
+ throw;
+ }
+ aGuard.clear();
+ // <- SYNCHRONIZED
+
+ if ( bImplicitInitialization )
+ m_aEventNotifier.notifyDocumentEvent( "OnCreate" );
}
// -----------------------------------------------------------------------------
@@ -693,9 +798,12 @@ void ODatabaseDocument::impl_storeToStorage_throw( const Reference< XStorage >&
m_pImpl->commitStorages();
// copy own storage to target storage
- Reference< XStorage > xCurrentStorage( m_pImpl->getOrCreateRootStorage(), UNO_QUERY_THROW );
- if ( xCurrentStorage != _rxTargetStorage )
- xCurrentStorage->copyToStorage( _rxTargetStorage );
+ if ( impl_isInitialized() )
+ {
+ Reference< XStorage > xCurrentStorage( m_pImpl->getOrCreateRootStorage(), UNO_QUERY_THROW );
+ if ( xCurrentStorage != _rxTargetStorage )
+ xCurrentStorage->copyToStorage( _rxTargetStorage );
+ }
// write into target storage
::comphelper::NamedValueCollection aWriteArgs( _rMediaDescriptor );
@@ -715,31 +823,47 @@ void ODatabaseDocument::impl_storeToStorage_throw( const Reference< XStorage >&
// -----------------------------------------------------------------------------
void SAL_CALL ODatabaseDocument::storeToURL( const ::rtl::OUString& _rURL, const Sequence< PropertyValue >& _rArguments ) throw (IOException, RuntimeException)
{
- ModelMethodGuard aGuard( *this );
+ DocumentGuard aGuard( *this );
ModifyLock aLock( *this );
- // create storage for target URL
- Reference< XStorage > xTargetStorage( impl_createStorageFor_throw( _rURL ) );
+ {
+ aGuard.clear();
+ m_aEventNotifier.notifyDocumentEvent( "OnSaveTo", NULL, makeAny( _rURL ) );
+ aGuard.reset();
+ }
- // extend media descriptor with URL
- Sequence< PropertyValue > aMediaDescriptor( lcl_appendFileNameToDescriptor( _rArguments, _rURL ) );
+ try
+ {
+ // create storage for target URL
+ Reference< XStorage > xTargetStorage( impl_createStorageFor_throw( _rURL ) );
+
+ // extend media descriptor with URL
+ Sequence< PropertyValue > aMediaDescriptor( lcl_appendFileNameToDescriptor( _rArguments, _rURL ) );
+
+ // store to this storage
+ impl_storeToStorage_throw( xTargetStorage, aMediaDescriptor );
+ }
+ catch( const Exception& )
+ {
+ m_aEventNotifier.notifyDocumentEventAsync( "OnSaveToFailed", NULL, makeAny( _rURL ) );
+ throw;
+ }
- // store to this storage
- impl_storeToStorage_throw( xTargetStorage, aMediaDescriptor );
+ m_aEventNotifier.notifyDocumentEventAsync( "OnSaveToDone", NULL, makeAny( _rURL ) );
}
// -----------------------------------------------------------------------------
// XModifyBroadcaster
void SAL_CALL ODatabaseDocument::addModifyListener( const Reference< XModifyListener >& _xListener ) throw (RuntimeException)
{
- ::connectivity::checkDisposed(ODatabaseDocument_OfficeDocument::rBHelper.bDisposed);
+ DocumentGuard aGuard( *this );
m_aModifyListeners.addInterface(_xListener);
}
// -----------------------------------------------------------------------------
void SAL_CALL ODatabaseDocument::removeModifyListener( const Reference< XModifyListener >& _xListener ) throw (RuntimeException)
{
- ::connectivity::checkDisposed(ODatabaseDocument_OfficeDocument::rBHelper.bDisposed);
+ DocumentGuard aGuard( *this );
m_aModifyListeners.removeInterface(_xListener);
}
@@ -747,8 +871,7 @@ void SAL_CALL ODatabaseDocument::removeModifyListener( const Reference< XModifyL
// XModifiable
sal_Bool SAL_CALL ODatabaseDocument::isModified( ) throw (RuntimeException)
{
- ModelMethodGuard aGuard( *this );
- OSL_ENSURE(m_pImpl.is(),"Impl is NULL");
+ DocumentGuard aGuard( *this );
return m_pImpl->m_bModified;
}
@@ -756,52 +879,82 @@ sal_Bool SAL_CALL ODatabaseDocument::isModified( ) throw (RuntimeException)
// -----------------------------------------------------------------------------
void SAL_CALL ODatabaseDocument::setModified( sal_Bool _bModified ) throw (PropertyVetoException, RuntimeException)
{
- ModelMethodGuard aGuard( *this );
- impl_setModified_throw( _bModified, aGuard );
+ DocumentGuard aGuard( *this, DocumentGuard::MethodWithoutInit );
+ if ( impl_isInitialized() )
+ impl_setModified_nothrow( _bModified, aGuard );
+ // it's allowed to call setModified without the document being initialized already. In this case,
+ // we simply ignore the call - when the initialization is finished, the respective code will set
+ // a proper "modified" flag
}
// -----------------------------------------------------------------------------
-void ODatabaseDocument::impl_setModified_throw( sal_Bool _bModified, ModelMethodGuard& _rGuard )
+void ODatabaseDocument::impl_setModified_nothrow( sal_Bool _bModified, DocumentGuard& _rGuard )
{
- if ( m_pImpl->m_bModified == _bModified )
- return;
-
- if ( m_pImpl->isModifyLocked() )
- return;
-
- m_pImpl->m_bModified = _bModified;
+ // SYNCHRONIZED ->
+ bool bModifiedChanged = ( m_pImpl->m_bModified != _bModified ) && ( !m_pImpl->isModifyLocked() );
- document::EventObject aEvent( *this, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OnModifyChanged" ) ) );
+ if ( bModifiedChanged )
+ {
+ m_pImpl->m_bModified = _bModified;
+ m_aEventNotifier.notifyDocumentEventAsync( "OnModifyChanged" );
+ }
_rGuard.clear();
+ // <- SYNCHRONIZED
- m_aModifyListeners.notifyEach( &XModifyListener::modified, (const lang::EventObject&)aEvent );
- impl_notifyEvent_nolck_nothrow( aEvent );
+ if ( bModifiedChanged )
+ {
+ lang::EventObject aEvent( *this );
+ m_aModifyListeners.notifyEach( &XModifyListener::modified, aEvent );
+ }
}
// -----------------------------------------------------------------------------
// ::com::sun::star::document::XEventBroadcaster
-void SAL_CALL ODatabaseDocument::addEventListener(const uno::Reference< document::XEventListener >& _xListener ) throw (uno::RuntimeException)
+void SAL_CALL ODatabaseDocument::addEventListener(const uno::Reference< document::XEventListener >& _Listener ) throw (uno::RuntimeException)
{
- ::connectivity::checkDisposed(ODatabaseDocument_OfficeDocument::rBHelper.bDisposed);
- m_aDocEventListeners.addInterface(_xListener);
+ DocumentGuard aGuard( *this, DocumentGuard::MethodWithoutInit );
+ m_aEventNotifier.addLegacyEventListener( _Listener );
}
// -----------------------------------------------------------------------------
-void SAL_CALL ODatabaseDocument::removeEventListener( const uno::Reference< document::XEventListener >& _xListener ) throw (uno::RuntimeException)
+void SAL_CALL ODatabaseDocument::removeEventListener( const uno::Reference< document::XEventListener >& _Listener ) throw (uno::RuntimeException)
{
- ::connectivity::checkDisposed(ODatabaseDocument_OfficeDocument::rBHelper.bDisposed);
- m_aDocEventListeners.removeInterface(_xListener);
+ DocumentGuard aGuard( *this, DocumentGuard::MethodWithoutInit );
+ m_aEventNotifier.removeLegacyEventListener( _Listener );
}
// -----------------------------------------------------------------------------
-void SAL_CALL ODatabaseDocument::notifyEvent( const document::EventObject& _rEvent ) throw (RuntimeException)
+void SAL_CALL ODatabaseDocument::addDocumentEventListener( const Reference< XDocumentEventListener >& _Listener ) throw (RuntimeException)
{
- ModelMethodGuard aGuard( *this );
- // used only to forward external events (e.g. for doc creation) from the frame loader
- // to the global event broadcaster and all other interested doc event listener.
- document::EventObject aEvent( *this, _rEvent.EventName );
+ DocumentGuard aGuard( *this, DocumentGuard::MethodWithoutInit );
+ m_aEventNotifier.addDocumentEventListener( _Listener );
+}
+
+// -----------------------------------------------------------------------------
+void SAL_CALL ODatabaseDocument::removeDocumentEventListener( const Reference< XDocumentEventListener >& _Listener ) throw (RuntimeException)
+{
+ DocumentGuard aGuard( *this, DocumentGuard::MethodWithoutInit );
+ m_aEventNotifier.removeDocumentEventListener( _Listener );
+}
+
+// -----------------------------------------------------------------------------
+void SAL_CALL ODatabaseDocument::notifyDocumentEvent( const ::rtl::OUString& _EventName, const Reference< XController2 >& _ViewController, const Any& _Supplement ) throw (IllegalArgumentException, NoSupportException, RuntimeException)
+{
+ if ( !_EventName.getLength() )
+ throw IllegalArgumentException( ::rtl::OUString(), *this, 1 );
+
+ // SYNCHRONIZED ->
+ DocumentGuard aGuard( *this );
+
+ if ( !DocumentEvents::needsSynchronousNotification( _EventName ) )
+ {
+ m_aEventNotifier.notifyDocumentEventAsync( _EventName, _ViewController, _Supplement );
+ return;
+ }
aGuard.clear();
- impl_notifyEvent_nolck_nothrow( aEvent );
+ // <- SYNCHRONIZED
+
+ m_aEventNotifier.notifyDocumentEvent( _EventName, _ViewController, _Supplement );
}
// -----------------------------------------------------------------------------
@@ -844,9 +997,6 @@ void ODatabaseDocument::clearObjectContainer( WeakReference< XNameAccess >& _rxC
// -----------------------------------------------------------------------------
Reference< XNameAccess > ODatabaseDocument::impl_getDocumentContainer_throw( ODatabaseModelImpl::ObjectType _eType )
{
- ModelMethodGuard aGuard( *this );
- OSL_POSTCOND( m_pImpl.is(), "ODatabaseDocument::impl_getDocumentContainer_throw: Impl is NULL" );
-
if ( ( _eType != ODatabaseModelImpl::E_FORM ) && ( _eType != ODatabaseModelImpl::E_REPORT ) )
throw IllegalArgumentException();
@@ -916,42 +1066,67 @@ void ODatabaseDocument::impl_disposeControllerFrames_nothrow()
}
// -----------------------------------------------------------------------------
-void SAL_CALL ODatabaseDocument::close( sal_Bool _bDeliverOwnership ) throw (::com::sun::star::util::CloseVetoException, RuntimeException)
+void SAL_CALL ODatabaseDocument::close( sal_Bool _bDeliverOwnership ) throw (CloseVetoException, RuntimeException)
{
- document::EventObject aEvent( *this, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OnUnload" ) ) );
+ // nearly everything below can/must be done without our mutex locked, the below is just for
+ // the checks for being disposed and the like
+ // SYNCHRONIZED ->
+ {
+ DocumentGuard aGuard( *this );
+ m_bClosing = true;
+ }
+ // <- SYNCHRONIZED
+
+ try
+ {
+ // allow listeners to veto
+ lang::EventObject aEvent( *this );
+ m_aCloseListener.forEach< XCloseListener >(
+ boost::bind( &XCloseListener::queryClosing, _1, boost::cref( aEvent ), boost::cref( _bDeliverOwnership ) ) );
- m_aCloseListener.forEach< XCloseListener >(
- boost::bind( &XCloseListener::queryClosing, _1, boost::cref( aEvent ), boost::cref( _bDeliverOwnership ) ) );
+ // notify that we're going to unload
+ m_aEventNotifier.notifyDocumentEvent( "OnPrepareUnload" );
- impl_closeControllerFrames_nolck_throw( _bDeliverOwnership );
+ impl_closeControllerFrames_nolck_throw( _bDeliverOwnership );
- m_aCloseListener.notifyEach( &XCloseListener::notifyClosing, (const lang::EventObject&)aEvent );
+ m_aCloseListener.notifyEach( &XCloseListener::notifyClosing, (const lang::EventObject&)aEvent );
- // notify the OnUnload at the earliest possibility - which is here and now
- impl_notifyEvent_nolck_nothrow( aEvent );
+ dispose();
+ }
+ catch ( const Exception& )
+ {
+ ::osl::MutexGuard aGuard( m_xMutex->getMutex() );
+ m_bClosing = false;
+ throw;
+ }
- dispose();
+ // SYNCHRONIZED ->
+ ::osl::MutexGuard aGuard( m_xMutex->getMutex() );
+ m_bClosing = false;
+ // <- SYNCHRONIZED
}
// -----------------------------------------------------------------------------
void SAL_CALL ODatabaseDocument::addCloseListener( const Reference< ::com::sun::star::util::XCloseListener >& Listener ) throw (RuntimeException)
{
- ::connectivity::checkDisposed(ODatabaseDocument_OfficeDocument::rBHelper.bDisposed);
+ DocumentGuard aGuard( *this );
m_aCloseListener.addInterface(Listener);
}
// -----------------------------------------------------------------------------
void SAL_CALL ODatabaseDocument::removeCloseListener( const Reference< ::com::sun::star::util::XCloseListener >& Listener ) throw (RuntimeException)
{
- ::connectivity::checkDisposed(ODatabaseDocument_OfficeDocument::rBHelper.bDisposed);
+ DocumentGuard aGuard( *this );
m_aCloseListener.removeInterface(Listener);
}
// -----------------------------------------------------------------------------
Reference< XNameAccess > SAL_CALL ODatabaseDocument::getFormDocuments( ) throw (RuntimeException)
{
+ DocumentGuard aGuard( *this, DocumentGuard::MethodUsedDuringInit );
return impl_getDocumentContainer_throw( ODatabaseModelImpl::E_FORM );
}
// -----------------------------------------------------------------------------
Reference< XNameAccess > SAL_CALL ODatabaseDocument::getReportDocuments( ) throw (RuntimeException)
{
+ DocumentGuard aGuard( *this, DocumentGuard::MethodUsedDuringInit );
return impl_getDocumentContainer_throw( ODatabaseModelImpl::E_REPORT );
}
@@ -1072,8 +1247,7 @@ void ODatabaseDocument::writeStorage( const Reference< XStorage >& _rxTargetStor
// -----------------------------------------------------------------------------
Reference< XUIConfigurationManager > SAL_CALL ODatabaseDocument::getUIConfigurationManager( ) throw (RuntimeException)
{
- ModelMethodGuard aGuard( *this );
- OSL_ENSURE(m_pImpl.is(),"Impl is NULL");
+ DocumentGuard aGuard( *this );
if ( !m_xUIConfigurationManager.is() )
{
@@ -1111,7 +1285,7 @@ Reference< XUIConfigurationManager > SAL_CALL ODatabaseDocument::getUIConfigurat
// -----------------------------------------------------------------------------
Reference< XStorage > SAL_CALL ODatabaseDocument::getDocumentSubStorage( const ::rtl::OUString& aStorageName, sal_Int32 nMode ) throw (RuntimeException)
{
- ModelMethodGuard aGuard( *this );
+ DocumentGuard aGuard( *this );
Reference< XDocumentSubStorageSupplier > xStorageAccess( m_pImpl->getDocumentSubStorageSupplier() );
return xStorageAccess->getDocumentSubStorage( aStorageName, nMode );
@@ -1123,19 +1297,6 @@ Sequence< ::rtl::OUString > SAL_CALL ODatabaseDocument::getDocumentSubStoragesNa
return xStorageAccess->getDocumentSubStoragesNames();
}
-// -----------------------------------------------------------------------------
-void ODatabaseDocument::impl_notifyEvent_nolck_nothrow( const document::EventObject& _rEvent )
-{
- try
- {
- m_aDocEventListeners.notifyEach( &XEventListener::notifyEvent, _rEvent );
- }
- catch(const Exception&)
- {
- DBG_UNHANDLED_EXCEPTION();
- }
-}
-
//------------------------------------------------------------------------------
void ODatabaseDocument::impl_notifyStorageChange_nolck_nothrow( const Reference< XStorage >& _rxNewRootStorage )
{
@@ -1155,39 +1316,51 @@ void ODatabaseDocument::disposing()
return;
}
+ if ( impl_isInitialized() )
+ m_aEventNotifier.notifyDocumentEvent( "OnUnload" );
+
+ Reference< XModel > xHoldAlive( this );
+
+ m_aEventNotifier.disposing();
+
+ lang::EventObject aDisposeEvent(static_cast<XWeak*>(this));
+ m_aModifyListeners.disposeAndClear( aDisposeEvent );
+ m_aCloseListener.disposeAndClear( aDisposeEvent );
+ m_aStorageListeners.disposeAndClear( aDisposeEvent );
+
+ // SYNCHRONIZED ->
+ ::osl::MutexGuard aGuard( m_xMutex->getMutex() );
+
DBG_ASSERT( m_aControllers.empty(), "ODatabaseDocument::disposing: there still are controllers!" );
// normally, nobody should explicitly dispose, but only XCloseable::close the document. And upon
// closing, our controllers are closed, too
- Reference< XModel > xHoldAlive( this );
- {
- {
- document::EventObject aEvent( *this, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OnLoad" ) ) );
- impl_notifyEvent_nolck_nothrow( aEvent );
- }
+ m_xUIConfigurationManager = NULL;
- lang::EventObject aDisposeEvent(static_cast<XWeak*>(this));
- m_aModifyListeners.disposeAndClear( aDisposeEvent );
- m_aCloseListener.disposeAndClear( aDisposeEvent );
- m_aDocEventListeners.disposeAndClear( aDisposeEvent );
- m_aStorageListeners.disposeAndClear( aDisposeEvent );
+ clearObjectContainer( m_xForms );
+ clearObjectContainer( m_xReports );
- m_xUIConfigurationManager = NULL;
+ // reset the macro mode: in case the our impl struct stays alive (e.g. because our DataSource
+ // object still exists), and somebody subsequently re-opens the document, we want to have
+ // the security warning, again.
+ m_pImpl->resetMacroExecutionMode();
- clearObjectContainer( m_xForms );
- clearObjectContainer( m_xReports );
+ // similar argueing for our ViewMonitor
+ m_aViewMonitor.reset();
- m_pImpl->modelIsDisposing( ODatabaseModelImpl::ResetModelAccess() );
+ // tell our Impl to forget us
+ m_pImpl->modelIsDisposing( impl_isInitialized(), ODatabaseModelImpl::ResetModelAccess() );
- // now, at the latest, the controller array should be empty. Controllers are
- // expected to listen for our disposal, and disconnect then
- DBG_ASSERT( m_aControllers.empty(), "ODatabaseDocument::disposing: there still are controllers!" );
- impl_disposeControllerFrames_nothrow();
- m_xModuleManager.clear();
- m_xTitleHelper.clear();
- }
+ // now, at the latest, the controller array should be empty. Controllers are
+ // expected to listen for our disposal, and disconnect then
+ DBG_ASSERT( m_aControllers.empty(), "ODatabaseDocument::disposing: there still are controllers!" );
+ impl_disposeControllerFrames_nothrow();
+
+ m_xModuleManager.clear();
+ m_xTitleHelper.clear();
m_pImpl.clear();
+ // <- SYNCHRONIZED
}
// -----------------------------------------------------------------------------
// XComponent
@@ -1232,7 +1405,7 @@ Reference< XInterface > ODatabaseDocument::Create( const Reference< XComponentCo
ODatabaseContext* pContext = reinterpret_cast< ODatabaseContext* >( xDBContextTunnel->getSomething( ODatabaseContext::getUnoTunnelImplementationId() ) );
::rtl::Reference<ODatabaseModelImpl> pImpl( new ODatabaseModelImpl( aContext.getLegacyServiceFactory(), *pContext ) );
- Reference< XModel > xModel( pImpl->createNewModel_deliverOwnership() );
+ Reference< XModel > xModel( pImpl->createNewModel_deliverOwnership( false ) );
return xModel.get();
}
@@ -1253,15 +1426,14 @@ sal_Bool ODatabaseDocument::supportsService( const ::rtl::OUString& _rServiceNam
// -----------------------------------------------------------------------------
Reference< XDataSource > SAL_CALL ODatabaseDocument::getDataSource() throw (RuntimeException)
{
- ModelMethodGuard aGuard( *this );
- OSL_ENSURE(m_pImpl.is(),"Impl is NULL");
- return m_pImpl->getDataSource();
+ DocumentGuard aGuard( *this, DocumentGuard::MethodWithoutInit );
+ return m_pImpl->getOrCreateDataSource();
}
// -----------------------------------------------------------------------------
void SAL_CALL ODatabaseDocument::loadFromStorage( const Reference< XStorage >& /*xStorage*/, const Sequence< PropertyValue >& /*aMediaDescriptor*/ ) throw (IllegalArgumentException, DoubleInitializationException, IOException, Exception, RuntimeException)
{
- ModelMethodGuard aGuard( *this );
+ DocumentGuard aGuard( *this );
throw Exception(
::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Embedding of database documents is not supported." ) ),
@@ -1273,8 +1445,7 @@ void SAL_CALL ODatabaseDocument::loadFromStorage( const Reference< XStorage >& /
// -----------------------------------------------------------------------------
void SAL_CALL ODatabaseDocument::storeToStorage( const Reference< XStorage >& _rxStorage, const Sequence< PropertyValue >& _rMediaDescriptor ) throw (IllegalArgumentException, IOException, Exception, RuntimeException)
{
- ModelMethodGuard aGuard( *this );
- //ModifyLock aLock( *this );
+ DocumentGuard aGuard( *this );
impl_storeToStorage_throw( _rxStorage, _rMediaDescriptor );
}
@@ -1282,7 +1453,7 @@ void SAL_CALL ODatabaseDocument::storeToStorage( const Reference< XStorage >& _r
// -----------------------------------------------------------------------------
void SAL_CALL ODatabaseDocument::switchToStorage( const Reference< XStorage >& _rxNewRootStorage ) throw (IllegalArgumentException, IOException, Exception, RuntimeException)
{
- ModelMethodGuard aGuard( *this );
+ DocumentGuard aGuard( *this );
Reference< XStorage > xNewRootStorage( m_pImpl->switchToStorage( _rxNewRootStorage ) );
@@ -1293,56 +1464,56 @@ void SAL_CALL ODatabaseDocument::switchToStorage( const Reference< XStorage >& _
// -----------------------------------------------------------------------------
Reference< XStorage > SAL_CALL ODatabaseDocument::getDocumentStorage( ) throw (IOException, Exception, RuntimeException)
{
- ModelMethodGuard aGuard( *this );
- return m_pImpl->getRootStorage();
+ DocumentGuard aGuard( *this );
+ return m_pImpl->getOrCreateRootStorage();
}
// -----------------------------------------------------------------------------
void SAL_CALL ODatabaseDocument::addStorageChangeListener( const Reference< XStorageChangeListener >& _Listener ) throw (RuntimeException)
{
- ModelMethodGuard aGuard( *this );
+ DocumentGuard aGuard( *this );
m_aStorageListeners.addInterface( _Listener );
}
// -----------------------------------------------------------------------------
void SAL_CALL ODatabaseDocument::removeStorageChangeListener( const Reference< XStorageChangeListener >& _Listener ) throw (RuntimeException)
{
- ModelMethodGuard aGuard( *this );
+ DocumentGuard aGuard( *this );
m_aStorageListeners.addInterface( _Listener );
}
// -----------------------------------------------------------------------------
Reference< XStorageBasedLibraryContainer > SAL_CALL ODatabaseDocument::getBasicLibraries() throw (RuntimeException)
{
- ModelMethodGuard aGuard( *this );
+ DocumentGuard aGuard( *this, DocumentGuard::MethodUsedDuringInit );
return m_pImpl->getLibraryContainer( true );
}
// -----------------------------------------------------------------------------
Reference< XStorageBasedLibraryContainer > SAL_CALL ODatabaseDocument::getDialogLibraries() throw (RuntimeException)
{
- ModelMethodGuard aGuard( *this );
+ DocumentGuard aGuard( *this );
return m_pImpl->getLibraryContainer( false );
}
// -----------------------------------------------------------------------------
::sal_Bool SAL_CALL ODatabaseDocument::getAllowMacroExecution() throw (RuntimeException)
{
- ModelMethodGuard aGuard( *this );
+ DocumentGuard aGuard( *this );
return m_pImpl->adjustMacroMode_AutoReject();
}
// -----------------------------------------------------------------------------
Reference< XEmbeddedScripts > SAL_CALL ODatabaseDocument::getScriptContainer() throw (RuntimeException)
{
- ModelMethodGuard aGuard( *this );
+ DocumentGuard aGuard( *this );
return this;
}
// -----------------------------------------------------------------------------
Reference< provider::XScriptProvider > SAL_CALL ODatabaseDocument::getScriptProvider( ) throw (RuntimeException)
{
- ModelMethodGuard aGuard( *this );
+ DocumentGuard aGuard( *this );
Reference< XScriptProvider > xScriptProvider( m_xScriptProvider );
if ( !xScriptProvider.is() )
@@ -1361,6 +1532,12 @@ Reference< provider::XScriptProvider > SAL_CALL ODatabaseDocument::getScriptProv
return xScriptProvider;
}
+// -----------------------------------------------------------------------------
+Reference< XNameReplace > SAL_CALL ODatabaseDocument::getEvents( ) throw (RuntimeException)
+{
+ DocumentGuard aGuard( *this, DocumentGuard::MethodUsedDuringInit );
+ return m_pEventContainer;
+}
// -----------------------------------------------------------------------------
void SAL_CALL ODatabaseDocument::disposing( const ::com::sun::star::lang::EventObject& Source ) throw(RuntimeException)
@@ -1386,7 +1563,7 @@ struct CreateAny : public ::std::unary_function< Reference<XController>, Any>
// XModel2
Reference< XEnumeration > SAL_CALL ODatabaseDocument::getControllers( ) throw (RuntimeException)
{
- ModelMethodGuard aGuard( *this );
+ DocumentGuard aGuard( *this );
uno::Sequence< Any> aController( m_aControllers.size() );
::std::transform( m_aControllers.begin(), m_aControllers.end(), aController.getArray(), CreateAny() );
return new ::comphelper::OAnyEnumeration(aController);
@@ -1416,7 +1593,7 @@ Reference< XController2 > SAL_CALL ODatabaseDocument::createViewController( cons
if ( !_Frame.is() )
throw IllegalArgumentException( ::rtl::OUString(), *this, 3 );
- ModelMethodGuard aGuard( *this );
+ DocumentGuard aGuard( *this );
::comphelper::ComponentContext aContext( m_pImpl->m_aContext );
aGuard.clear();
@@ -1437,8 +1614,6 @@ Reference< XController2 > SAL_CALL ODatabaseDocument::createViewController( cons
//=============================================================================
Reference< XTitle > ODatabaseDocument::impl_getTitleHelper_throw()
{
- ModelMethodGuard aGuard( *this );
-
if ( ! m_xTitleHelper.is ())
{
Reference< XUntitledNumbers > xDesktop(
@@ -1458,8 +1633,6 @@ Reference< XTitle > ODatabaseDocument::impl_getTitleHelper_throw()
//=============================================================================
uno::Reference< frame::XUntitledNumbers > ODatabaseDocument::impl_getUntitledHelper_throw(const uno::Reference< uno::XInterface >& _xComponent)
{
- ModelMethodGuard aGuard( *this );
-
if ( !m_xModuleManager.is() )
m_xModuleManager.set( m_pImpl->m_aContext.createComponent( "com.sun.star.frame.ModuleManager" ), UNO_QUERY_THROW );
@@ -1498,9 +1671,8 @@ uno::Reference< frame::XUntitledNumbers > ODatabaseDocument::impl_getUntitledHel
throw (uno::RuntimeException)
{
// SYNCHRONIZED ->
- ModelMethodGuard aGuard( *this );
-
- return impl_getTitleHelper_throw()->getTitle ();
+ DocumentGuard aGuard( *this, DocumentGuard::MethodUsedDuringInit );
+ return impl_getTitleHelper_throw()->getTitle();
}
//=============================================================================
@@ -1509,9 +1681,10 @@ void SAL_CALL ODatabaseDocument::setTitle( const ::rtl::OUString& sTitle )
throw (uno::RuntimeException)
{
// SYNCHRONIZED ->
- ModelMethodGuard aGuard( *this );
-
- impl_getTitleHelper_throw()->setTitle (sTitle);
+ DocumentGuard aGuard( *this );
+ impl_getTitleHelper_throw()->setTitle( sTitle );
+ m_aEventNotifier.notifyDocumentEventAsync( "OnTitleChanged" );
+ // <- SYNCHRONIZED
}
//=============================================================================
@@ -1520,11 +1693,10 @@ void SAL_CALL ODatabaseDocument::addTitleChangeListener( const uno::Reference< f
throw (uno::RuntimeException)
{
// SYNCHRONIZED ->
- ModelMethodGuard aGuard( *this );
-
- uno::Reference< frame::XTitleChangeBroadcaster > xBroadcaster(impl_getTitleHelper_throw(), uno::UNO_QUERY);
- if (xBroadcaster.is ())
- xBroadcaster->addTitleChangeListener (xListener);
+ DocumentGuard aGuard( *this );
+
+ uno::Reference< frame::XTitleChangeBroadcaster > xBroadcaster( impl_getTitleHelper_throw(), uno::UNO_QUERY_THROW );
+ xBroadcaster->addTitleChangeListener( xListener );
}
//=============================================================================
@@ -1533,11 +1705,10 @@ void SAL_CALL ODatabaseDocument::removeTitleChangeListener( const uno::Reference
throw (uno::RuntimeException)
{
// SYNCHRONIZED ->
- ModelMethodGuard aGuard( *this );
+ DocumentGuard aGuard( *this );
- uno::Reference< frame::XTitleChangeBroadcaster > xBroadcaster(impl_getTitleHelper_throw(), uno::UNO_QUERY);
- if (xBroadcaster.is ())
- xBroadcaster->removeTitleChangeListener (xListener);
+ uno::Reference< frame::XTitleChangeBroadcaster > xBroadcaster( impl_getTitleHelper_throw(), uno::UNO_QUERY_THROW );
+ xBroadcaster->removeTitleChangeListener( xListener );
}
//=============================================================================
@@ -1546,9 +1717,7 @@ void SAL_CALL ODatabaseDocument::removeTitleChangeListener( const uno::Reference
throw (lang::IllegalArgumentException,
uno::RuntimeException )
{
- // object already disposed?
- ModelMethodGuard aGuard( *this );
-
+ DocumentGuard aGuard( *this );
return impl_getUntitledHelper_throw(xComponent)->leaseNumber (xComponent);
}
@@ -1558,9 +1727,7 @@ void SAL_CALL ODatabaseDocument::releaseNumber( ::sal_Int32 nNumber )
throw (lang::IllegalArgumentException,
uno::RuntimeException )
{
- // object already disposed?
- ModelMethodGuard aGuard( *this );
-
+ DocumentGuard aGuard( *this );
impl_getUntitledHelper_throw()->releaseNumber (nNumber);
}
@@ -1570,8 +1737,7 @@ void SAL_CALL ODatabaseDocument::releaseNumberForComponent( const uno::Reference
throw (lang::IllegalArgumentException,
uno::RuntimeException )
{
- // object already disposed?
- ModelMethodGuard aGuard( *this );
+ DocumentGuard aGuard( *this );
impl_getUntitledHelper_throw(xComponent)->releaseNumberForComponent (xComponent);
}
diff --git a/dbaccess/source/core/dataaccess/databasedocument.hxx b/dbaccess/source/core/dataaccess/databasedocument.hxx
index e354c00d5..2ab142124 100644
--- a/dbaccess/source/core/dataaccess/databasedocument.hxx
+++ b/dbaccess/source/core/dataaccess/databasedocument.hxx
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: databasedocument.hxx,v $
- * $Revision: 1.22 $
+ * $Revision: 1.20.2.13 $
*
* This file is part of OpenOffice.org.
*
@@ -31,6 +31,7 @@
#define _DBA_COREDATAACCESS_DATABASEDOCUMENT_HXX_
#include "ModelImpl.hxx"
+#include "documenteventnotifier.hxx"
/** === begin UNO includes === **/
#include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
@@ -46,28 +47,33 @@
#include <com/sun/star/util/XCloseable.hpp>
#include <com/sun/star/view/XPrintable.hpp>
#include <com/sun/star/frame/XModuleManager.hpp>
-#include <cppuhelper/compbase10.hxx>
-#include <cppuhelper/implbase3.hxx>
-
-#include <com/sun/star/document/XEventListener.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/sdb/XOfficeDatabaseDocument.hpp>
#include <com/sun/star/embed/XTransactionListener.hpp>
#include <com/sun/star/document/XStorageBasedDocument.hpp>
#include <com/sun/star/document/XEmbeddedScripts.hpp>
+#include <com/sun/star/document/XEventsSupplier.hpp>
#include <com/sun/star/document/XScriptInvocationContext.hpp>
#include <com/sun/star/script/XStorageBasedLibraryContainer.hpp>
#include <com/sun/star/script/provider/XScriptProviderSupplier.hpp>
+#include <com/sun/star/frame/XLoadable.hpp>
+#include <com/sun/star/document/XEventBroadcaster.hpp>
+#include <com/sun/star/document/XDocumentEventBroadcaster.hpp>
/** === end UNO includes === **/
-#if ! defined(INCLUDED_COMPHELPER_IMPLBASE_VAR_HXX_14)
-#define INCLUDED_COMPHELPER_IMPLBASE_VAR_HXX_14
-#define COMPHELPER_IMPLBASE_INTERFACE_NUMBER 14
+#if ! defined(INCLUDED_COMPHELPER_IMPLBASE_VAR_HXX_16)
+#define INCLUDED_COMPHELPER_IMPLBASE_VAR_HXX_16
+#define COMPHELPER_IMPLBASE_INTERFACE_NUMBER 16
#include <comphelper/implbase_var.hxx>
#endif
+#include <cppuhelper/compbase10.hxx>
+#include <cppuhelper/implbase3.hxx>
+#include <rtl/ref.hxx>
+
#include <boost/shared_ptr.hpp>
+#include <boost/noncopyable.hpp>
namespace comphelper {
class NamedValueCollection;
@@ -78,18 +84,70 @@ namespace dbaccess
{
//........................................................................
-class ODatabaseContext;
+class DocumentEvents;
+class DocumentEventExecutor;
+class DocumentGuard;
typedef ::std::vector< ::com::sun::star::uno::Reference< ::com::sun::star::frame::XController > > Controllers;
//============================================================
+//= ViewMonitor
+//============================================================
+/** helper class monitoring the views of a document, and firing appropriate events
+ when views are attached / detached
+*/
+class ViewMonitor : public boost::noncopyable
+{
+public:
+ ViewMonitor( DocumentEventNotifier& _rEventNotifier )
+ :m_rEventNotifier( _rEventNotifier )
+ ,m_bIsNewDocument( true )
+ ,m_bEverHadController( false )
+ ,m_bLastIsFirstEverController( false )
+ ,m_xLastConnectedController()
+ {
+ }
+
+ void reset()
+ {
+ m_bEverHadController = false;
+ m_bLastIsFirstEverController = false;
+ m_xLastConnectedController.clear();
+ }
+
+ /** to be called when a view (aka controller) has been connected to the document
+ @return
+ <TRUE/> if and only if this was the first-ever controller connected to the document
+ */
+ bool onControllerConnected(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XController >& _rxController
+ );
+
+ /** to be called when a controller is set as current controller
+ */
+ void onSetCurrentController(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XController >& _rxController
+ );
+
+ void onLoadedDocument() { m_bIsNewDocument = false; }
+
+private:
+ DocumentEventNotifier& m_rEventNotifier;
+ bool m_bIsNewDocument;
+ bool m_bEverHadController;
+ bool m_bLastIsFirstEverController;
+ ::com::sun::star::uno::Reference< ::com::sun::star::frame::XController >
+ m_xLastConnectedController;
+};
+
+//============================================================
//= ODatabaseDocument
//============================================================
-typedef ::comphelper::WeakComponentImplHelper14 < ::com::sun::star::frame::XModel2
+typedef ::comphelper::WeakComponentImplHelper16 < ::com::sun::star::frame::XModel2
, ::com::sun::star::util::XModifiable
, ::com::sun::star::frame::XStorable
, ::com::sun::star::document::XEventBroadcaster
- , ::com::sun::star::document::XEventListener
+ , ::com::sun::star::document::XDocumentEventBroadcaster
, ::com::sun::star::view::XPrintable
, ::com::sun::star::util::XCloseable
, ::com::sun::star::lang::XServiceInfo
@@ -99,6 +157,8 @@ typedef ::comphelper::WeakComponentImplHelper14 < ::com::sun::star::frame::XMo
, ::com::sun::star::document::XEmbeddedScripts
, ::com::sun::star::document::XScriptInvocationContext
, ::com::sun::star::script::provider::XScriptProviderSupplier
+ , ::com::sun::star::document::XEventsSupplier
+ , ::com::sun::star::frame::XLoadable
> ODatabaseDocument_OfficeDocument;
typedef ::cppu::ImplHelper3< ::com::sun::star::frame::XTitle
@@ -110,41 +170,64 @@ class ODatabaseDocument :public ModelDependentComponent // ModelDepe
,public ODatabaseDocument_OfficeDocument
,public ODatabaseDocument_Title
{
+ enum InitState
+ {
+ NotInitialized,
+ Initializing,
+ Initialized
+ };
+
DECLARE_STL_USTRINGACCESS_MAP(::com::sun::star::uno::Reference< ::com::sun::star::frame::XUntitledNumbers >,TNumberedController);
::com::sun::star::uno::Reference< ::com::sun::star::ui::XUIConfigurationManager> m_xUIConfigurationManager;
::cppu::OInterfaceContainerHelper m_aModifyListeners;
::cppu::OInterfaceContainerHelper m_aCloseListener;
- ::cppu::OInterfaceContainerHelper m_aDocEventListeners;
::cppu::OInterfaceContainerHelper m_aStorageListeners;
+ DocumentEvents* m_pEventContainer;
+ ::rtl::Reference< DocumentEventExecutor > m_pEventExecutor;
+ DocumentEventNotifier m_aEventNotifier;
+
::com::sun::star::uno::Reference< ::com::sun::star::frame::XController > m_xCurrentController;
Controllers m_aControllers;
+ ViewMonitor m_aViewMonitor;
::com::sun::star::uno::WeakReference< ::com::sun::star::container::XNameAccess > m_xForms;
::com::sun::star::uno::WeakReference< ::com::sun::star::container::XNameAccess > m_xReports;
::com::sun::star::uno::WeakReference< ::com::sun::star::script::provider::XScriptProvider > m_xScriptProvider;
+ /** @short such module manager is used to classify new opened documents. */
+ ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModuleManager > m_xModuleManager;
+ ::com::sun::star::uno::Reference< ::com::sun::star::frame::XTitle > m_xTitleHelper;
+ TNumberedController m_aNumberedControllers;
+
+ /** true if and only if the DatabaseDocument's "initNew" or "load" have been called (or, well,
+ the document has be initialized implicitly - see storeAsURL
+ */
+ InitState m_eInitState;
+ bool m_bClosing;
+
+ enum StoreType { SAVE, SAVE_AS };
/** stores the document to the given URL, rebases it to the respective new storage, if necessary, resets
the modified flag, and notifies any listeners as required
+
+ @param _rURL
+ the URL to store the document to
+ @param _rArguments
+ arguments for storing the document (MediaDescriptor)
+ @param _eType
+ the type of the store process (Save or SaveAs). The method will automatically
+ notify the proper events for this type.
+ @param _rGuard
+ the instance lock to be released before doing synchronous notifications
*/
void impl_storeAs_throw(
const ::rtl::OUString& _rURL,
const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue>& _rArguments,
- const sal_Char* _pAsciiDocumentEventName,
- ModelMethodGuard& _rGuard
+ const StoreType _eType,
+ DocumentGuard& _rGuard
);
- /** @short such module manager is used to classify new opened documents. */
- ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModuleManager > m_xModuleManager;
- ::com::sun::star::uno::Reference< ::com::sun::star::frame::XTitle > m_xTitleHelper;
- TNumberedController m_aNumberedControllers;
-
- /** notifies the global event broadcaster
- The method must be called without our mutex locked
- */
- void impl_notifyEvent_nolck_nothrow( const ::com::sun::star::document::EventObject& _rEvent );
-
/** notifies our storage change listeners that our underlying storage changed
@param _rxNewRootStorage
@@ -256,13 +339,13 @@ public:
virtual void SAL_CALL setCurrentController( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XController >& Controller ) throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::uno::RuntimeException) ;
virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL getCurrentSelection( ) throw (::com::sun::star::uno::RuntimeException) ;
-// ::com::sun::star::frame::XModel2
+ // XModel2
virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XEnumeration > SAL_CALL getControllers( ) throw (::com::sun::star::uno::RuntimeException) ;
virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getAvailableViewControllerNames( ) throw (::com::sun::star::uno::RuntimeException) ;
virtual ::com::sun::star::uno::Reference< ::com::sun::star::frame::XController2 > SAL_CALL createDefaultViewController( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& Frame ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) ;
virtual ::com::sun::star::uno::Reference< ::com::sun::star::frame::XController2 > SAL_CALL createViewController( const ::rtl::OUString& ViewName, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& Arguments, const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& Frame ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) ;
-// ::com::sun::star::frame::XStorable
+ // XStorable
virtual sal_Bool SAL_CALL hasLocation( ) throw (::com::sun::star::uno::RuntimeException) ;
virtual ::rtl::OUString SAL_CALL getLocation( ) throw (::com::sun::star::uno::RuntimeException) ;
virtual sal_Bool SAL_CALL isReadonly( ) throw (::com::sun::star::uno::RuntimeException) ;
@@ -270,41 +353,43 @@ public:
virtual void SAL_CALL storeAsURL( const ::rtl::OUString& sURL, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& lArguments ) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException) ;
virtual void SAL_CALL storeToURL( const ::rtl::OUString& sURL, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& lArguments ) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException) ;
-// ::com::sun::star::util::XModifyBroadcaster
+ // XModifyBroadcaster
virtual void SAL_CALL addModifyListener( const ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener >& aListener ) throw (::com::sun::star::uno::RuntimeException);
virtual void SAL_CALL removeModifyListener( const ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener >& aListener ) throw (::com::sun::star::uno::RuntimeException);
-// ::com::sun::star::util::XModifiable
+ // ::com::sun::star::util::XModifiable
virtual sal_Bool SAL_CALL isModified( ) throw (::com::sun::star::uno::RuntimeException) ;
virtual void SAL_CALL setModified( sal_Bool bModified ) throw (::com::sun::star::beans::PropertyVetoException, ::com::sun::star::uno::RuntimeException) ;
-// ::com::sun::star::document::XEventBroadcaster
+
+ // XEventBroadcaster
virtual void SAL_CALL addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::document::XEventListener >& aListener ) throw (::com::sun::star::uno::RuntimeException);
virtual void SAL_CALL removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::document::XEventListener >& aListener ) throw (::com::sun::star::uno::RuntimeException);
-// ::com::sun::star::document::XEventListener
- virtual void SAL_CALL notifyEvent( const ::com::sun::star::document::EventObject& aEvent ) throw (::com::sun::star::uno::RuntimeException);
+ // XDocumentEventBroadcaster
+ virtual void SAL_CALL addDocumentEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::document::XDocumentEventListener >& _Listener ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeDocumentEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::document::XDocumentEventListener >& _Listener ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL notifyDocumentEvent( const ::rtl::OUString& _EventName, const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XController2 >& _ViewController, const ::com::sun::star::uno::Any& _Supplement ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::NoSupportException, ::com::sun::star::uno::RuntimeException);
-
-// ::com::sun::star::view::XPrintable
+ // XPrintable
virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > SAL_CALL getPrinter( ) throw (::com::sun::star::uno::RuntimeException) ;
virtual void SAL_CALL setPrinter( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aPrinter ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) ;
virtual void SAL_CALL print( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& xOptions ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) ;
-// XFormDocumentsSupplier
+ // XFormDocumentsSupplier
virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > SAL_CALL getFormDocuments( ) throw (::com::sun::star::uno::RuntimeException);
-// XReportDocumentsSupplier
+ // XReportDocumentsSupplier
virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > SAL_CALL getReportDocuments( ) throw (::com::sun::star::uno::RuntimeException);
-// XCloseable
+ // XCloseable
virtual void SAL_CALL close( sal_Bool DeliverOwnership ) throw (::com::sun::star::util::CloseVetoException, ::com::sun::star::uno::RuntimeException);
virtual void SAL_CALL addCloseListener( const ::com::sun::star::uno::Reference< ::com::sun::star::util::XCloseListener >& Listener ) throw (::com::sun::star::uno::RuntimeException);
virtual void SAL_CALL removeCloseListener( const ::com::sun::star::uno::Reference< ::com::sun::star::util::XCloseListener >& Listener ) throw (::com::sun::star::uno::RuntimeException);
-// XUIConfigurationManagerSupplier
+ // XUIConfigurationManagerSupplier
virtual ::com::sun::star::uno::Reference< ::com::sun::star::ui::XUIConfigurationManager > SAL_CALL getUIConfigurationManager( ) throw (::com::sun::star::uno::RuntimeException);
-// XDocumentSubStorageSupplier
+ // XDocumentSubStorageSupplier
virtual ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage > SAL_CALL getDocumentSubStorage( const ::rtl::OUString& aStorageName, sal_Int32 nMode ) throw (::com::sun::star::uno::RuntimeException);
virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getDocumentSubStoragesNames( ) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
@@ -330,6 +415,13 @@ public:
// XScriptProviderSupplier
virtual ::com::sun::star::uno::Reference< ::com::sun::star::script::provider::XScriptProvider > SAL_CALL getScriptProvider( ) throw (::com::sun::star::uno::RuntimeException);
+ // XEventsSupplier
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameReplace > SAL_CALL getEvents( ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XLoadable
+ virtual void SAL_CALL initNew( ) throw (::com::sun::star::frame::DoubleInitializationException, ::com::sun::star::io::IOException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL load( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& lArguments ) throw (::com::sun::star::frame::DoubleInitializationException, ::com::sun::star::io::IOException, ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
+
// XTitle
virtual ::rtl::OUString SAL_CALL getTitle( ) throw (::com::sun::star::uno::RuntimeException);
virtual void SAL_CALL setTitle( const ::rtl::OUString& sTitle ) throw (::com::sun::star::uno::RuntimeException);
@@ -356,7 +448,50 @@ public:
static void clearObjectContainer(
::com::sun::star::uno::WeakReference< ::com::sun::star::container::XNameAccess >& _rxContainer);
+ /** checks whether the component is already initialized, throws a NotInitializedException if not
+ */
+ inline void checkInitialized() const
+ {
+ if ( !impl_isInitialized() )
+ throw ::com::sun::star::lang::NotInitializedException( ::rtl::OUString(), getThis() );
+ }
+
+ /** checks the document is currently in the initialization phase, or already initialized.
+ Throws NotInitializedException if not so.
+ */
+ inline void checkNotUninitilized() const
+ {
+ if ( impl_isInitialized() || impl_isInitializing() )
+ // fine
+ return;
+
+ throw ::com::sun::star::lang::NotInitializedException( ::rtl::OUString(), getThis() );
+ }
+
+ /** checks whether the document is currently being initialized, or already initialized,
+ throws a DoubleInitializationException if so
+ */
+ inline void checkNotInitialized() const
+ {
+ if ( impl_isInitializing() || impl_isInitialized() )
+ throw ::com::sun::star::frame::DoubleInitializationException( ::rtl::OUString(), getThis() );
+ }
+
private:
+ /** returns whether the model is currently being initialized
+ */
+ bool impl_isInitializing() const { return m_eInitState == Initializing; }
+
+ /** returns whether the model is already initialized, i.e. the XModel's "initNew" or "load" methods have been called
+ */
+ bool impl_isInitialized() const { return m_eInitState == Initialized; }
+
+ /// tells the model it is being initialized now
+ void impl_setInitializing() { m_eInitState = Initializing; }
+
+ /// tells the model its initialization is done
+ void impl_setInitialized();
+
/** closes the frames of all connected controllers
@param _bDeliverOwnership
@@ -399,7 +534,7 @@ private:
/** imports the document from the given resource.
*/
- bool impl_import_throw( const ::comphelper::NamedValueCollection& _rResource );
+ void impl_import_throw( const ::comphelper::NamedValueCollection& _rResource );
/** creates a storage for the given URL, truncating it if a file with this name already exists
@@ -414,9 +549,21 @@ private:
const ::rtl::OUString& _rURL
) const;
- /** clears the guard before notifying.
+ /** sets our "modified" flag
+
+ will notify all our respective listeners, if the "modified" state actually changed
+
+ @param _bModified
+ the (new) flag indicating whether the document is currently modified or not
+ @param _rGuard
+ the guard for our instance. At method entry, the guard must hold the lock. At the moment
+ of method leave, the lock will be released.
+ @precond
+ our mutex is locked
+ @postcond
+ our mutex is not locked
*/
- void impl_setModified_throw( sal_Bool _bModified, ModelMethodGuard& _rGuard );
+ void impl_setModified_nothrow( sal_Bool _bModified, DocumentGuard& _rGuard );
/** stores the document to the given storage
@@ -440,6 +587,61 @@ private:
/// determines whether we should disable the scripting related interfaces
bool impl_shouldDisallowScripting_nolck_nothrow() const;
+
+ /** checks whether we need to implicitly initialize the document
+
+ */
+};
+
+/** an extended version of the ModelMethodGuard, which also cares for the initialization state
+ of the document
+*/
+class DocumentGuard : public ModelMethodGuard
+{
+public:
+ enum MethodType
+ {
+ // a method which is to initialize the document
+ InitMethod,
+ // a default method
+ DefaultMethod,
+ // a method which is used (externally) during the initialization phase
+ MethodUsedDuringInit,
+ // a method which does not need initialization - use with care!
+ MethodWithoutInit
+ };
+
+ /** constructs the guard
+
+ @param _document
+ the ODatabaseDocument instance
+
+ @throws ::com::sun::star::lang::DisposedException
+ If the given component is already disposed
+
+ @throws ::com::sun::star::frame::DoubleInitializationException
+ if _eType is InitMethod, and the given component is already initialized, or currently being initialized.
+
+ @throws ::com::sun::star::lang::NotInitializedException
+ if _eType is DefaultMethod, and the given component is not yet initialized; or if _eType
+ is MethodUsedDuringInit, and the component is still uninitialized, and not in the initialization
+ phase currently.
+ */
+ DocumentGuard( const ODatabaseDocument& _document, MethodType _eType = DefaultMethod )
+ :ModelMethodGuard( _document )
+ {
+ switch ( _eType )
+ {
+ case InitMethod: _document.checkNotInitialized(); break;
+ case DefaultMethod: _document.checkInitialized(); break;
+ case MethodUsedDuringInit: _document.checkNotUninitilized(); break;
+ case MethodWithoutInit: break;
+ }
+ }
+
+ ~DocumentGuard()
+ {
+ }
};
//........................................................................
diff --git a/dbaccess/source/core/dataaccess/datasource.cxx b/dbaccess/source/core/dataaccess/datasource.cxx
index a944d5725..7c112a9c5 100644
--- a/dbaccess/source/core/dataaccess/datasource.cxx
+++ b/dbaccess/source/core/dataaccess/datasource.cxx
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: datasource.cxx,v $
- * $Revision: 1.80 $
+ * $Revision: 1.79.4.5 $
*
* This file is part of OpenOffice.org.
*
@@ -1349,6 +1349,7 @@ void SAL_CALL ODatabaseSource::flush( ) throw (RuntimeException)
{
try
{
+ // SYNCHRONIZED ->
{
ModelMethodGuard aGuard( *this );
@@ -1356,11 +1357,12 @@ void SAL_CALL ODatabaseSource::flush( ) throw (RuntimeException)
SharedModel xModel( m_pImpl->getModel_noCreate(), SharedModel::NoTakeOwnership );
if ( !xModel.is() )
- xModel.reset( m_pImpl->createNewModel_deliverOwnership(), SharedModel::TakeOwnership );
+ xModel.reset( m_pImpl->createNewModel_deliverOwnership( false ), SharedModel::TakeOwnership );
Reference< css::frame::XStorable> xStorable( xModel, UNO_QUERY_THROW );
xStorable->store();
}
+ // <- SYNCHRONIZED
css::lang::EventObject aFlushedEvent(*this);
m_aFlushListeners.notifyEach( &XFlushListener::flushed, aFlushedEvent );
@@ -1381,7 +1383,7 @@ void SAL_CALL ODatabaseSource::flushed( const EventObject& /*rEvent*/ ) throw (R
// In general, we have the problem that embedded databases write into their underlying storage, which
// logically is one of our sub storage, and practically is a temporary file maintained by the
// package implementation. As long as we did not commit this storage and our main storage,
- // the changes made by the embedded database engine is not really reflected in the database document
+ // the changes made by the embedded database engine are not really reflected in the database document
// file. This is Bad (TM) for a "real" database application - imagine somebody entering some
// data, and then crashing: For a database application, you would expect that the data still is present
// when you connect to the database next time.
@@ -1443,9 +1445,9 @@ Reference< XOfficeDatabaseDocument > SAL_CALL ODatabaseSource::getDatabaseDocume
Reference< XModel > xModel( m_pImpl->getModel_noCreate() );
if ( !xModel.is() )
- xModel = m_pImpl->createNewModel_deliverOwnership();
+ xModel = m_pImpl->createNewModel_deliverOwnership( false );
- return Reference< XOfficeDatabaseDocument >( xModel, UNO_QUERY );
+ return Reference< XOfficeDatabaseDocument >( xModel, UNO_QUERY_THROW );
}
// -----------------------------------------------------------------------------
Reference< XInterface > ODatabaseSource::getThis() const
diff --git a/dbaccess/source/core/dataaccess/documentdefinition.cxx b/dbaccess/source/core/dataaccess/documentdefinition.cxx
index da386a904..64392b023 100644
--- a/dbaccess/source/core/dataaccess/documentdefinition.cxx
+++ b/dbaccess/source/core/dataaccess/documentdefinition.cxx
@@ -867,7 +867,7 @@ void ODocumentDefinition::onCommandOpenSomething( const Any& _rOpenArgument, con
// for the document, default to the interaction handler as used for loading the DB doc
// This might be overwritten below, when examining _rOpenArgument.
- ::comphelper::NamedValueCollection aDBDocArgs( m_pImpl->m_pDataSource->m_aArgs );
+ ::comphelper::NamedValueCollection aDBDocArgs( m_pImpl->m_pDataSource->getResource() );
aDocumentArgs.put( "InteractionHandler", aDBDocArgs.getOrDefault( "InteractionHandler", Reference< XInteractionHandler >() ) );
::boost::optional< sal_Int16 > aDocumentMacroMode;
@@ -1529,15 +1529,7 @@ namespace
// -----------------------------------------------------------------------------
sal_Bool ODocumentDefinition::objectSupportsEmbeddedScripts() const
{
-// bool bAllowDocumentMacros = !m_pImpl->m_pDataSource || m_pImpl->m_pDataSource->hasAnyObjectWithMacros();
- // TODO: revert to the disabled code. The current version is just to be able
- // to integrate an intermediate version of the CWS, which should behave as
- // if no macros in DB docs are allowed
- bool bAllowDocumentMacros = !m_pImpl->m_pDataSource->hasMacroStorages();
- // even if the current version is not able to create documents which contain macros,
- // later versions will be. Such documents contain macro/script storages in the
- // document root storage, in which case we need to disable the per-form/report
- // scripting.
+ bool bAllowDocumentMacros = !m_pImpl->m_pDataSource || m_pImpl->m_pDataSource->hasAnyObjectWithMacros();
// if *any* of the objects of the database document already has macros, we continue to allow it
// to have them, until the user did a migration.
diff --git a/dbaccess/source/core/dataaccess/documentdefinition.hxx b/dbaccess/source/core/dataaccess/documentdefinition.hxx
index 3a2f68764..e8b28a0c2 100644
--- a/dbaccess/source/core/dataaccess/documentdefinition.hxx
+++ b/dbaccess/source/core/dataaccess/documentdefinition.hxx
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: documentdefinition.hxx,v $
- * $Revision: 1.32 $
+ * $Revision: 1.28.6.4 $
*
* This file is part of OpenOffice.org.
*
diff --git a/dbaccess/source/core/dataaccess/documenteventexecutor.cxx b/dbaccess/source/core/dataaccess/documenteventexecutor.cxx
new file mode 100644
index 000000000..319209cef
--- /dev/null
+++ b/dbaccess/source/core/dataaccess/documenteventexecutor.cxx
@@ -0,0 +1,234 @@
+/*************************************************************************
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* Copyright 2008 by Sun Microsystems, Inc.
+*
+* OpenOffice.org - a multi-platform office productivity suite
+*
+* $RCSfile: documenteventexecutor.cxx,v $
+*
+* $Revision: 1.1.2.7 $
+*
+* 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_dbaccess.hxx"
+
+#include "documenteventexecutor.hxx"
+
+/** === begin UNO includes === **/
+#include <com/sun/star/document/XDocumentEventBroadcaster.hpp>
+#include <com/sun/star/util/XURLTransformer.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+/** === end UNO includes === **/
+
+#include <comphelper/componentcontext.hxx>
+#include <comphelper/namedvaluecollection.hxx>
+#include <cppuhelper/weakref.hxx>
+#include <tools/diagnose_ex.h>
+#include <vcl/svapp.hxx>
+#include <vos/mutex.hxx>
+
+//........................................................................
+namespace dbaccess
+{
+//........................................................................
+
+ /** === begin UNO using === **/
+ using ::com::sun::star::uno::Reference;
+ using ::com::sun::star::uno::XInterface;
+ using ::com::sun::star::uno::UNO_QUERY;
+ using ::com::sun::star::uno::UNO_QUERY_THROW;
+ using ::com::sun::star::uno::UNO_SET_THROW;
+ using ::com::sun::star::uno::Exception;
+ using ::com::sun::star::uno::RuntimeException;
+ using ::com::sun::star::uno::Any;
+ using ::com::sun::star::uno::makeAny;
+ using ::com::sun::star::uno::Sequence;
+ using ::com::sun::star::uno::Type;
+ using ::com::sun::star::uno::WeakReference;
+ using ::com::sun::star::document::XDocumentEventBroadcaster;
+ using ::com::sun::star::document::XEventsSupplier;
+ using ::com::sun::star::container::XNameAccess;
+ using ::com::sun::star::frame::XModel;
+ using ::com::sun::star::util::XURLTransformer;
+ using ::com::sun::star::frame::XDispatchProvider;
+ using ::com::sun::star::frame::XDispatch;
+ using ::com::sun::star::util::URL;
+ using ::com::sun::star::beans::PropertyValue;
+ using ::com::sun::star::frame::XController;
+ using ::com::sun::star::document::DocumentEvent;
+ /** === end UNO using === **/
+ using namespace ::com::sun::star;
+
+ //====================================================================
+ //= DocumentEventExecutor_Data
+ //====================================================================
+ struct DocumentEventExecutor_Data
+ {
+ WeakReference< XEventsSupplier > xDocument;
+ Reference< XURLTransformer > xURLTransformer;
+
+ DocumentEventExecutor_Data( const Reference< XEventsSupplier >& _rxDocument )
+ :xDocument( _rxDocument )
+ {
+ }
+ };
+
+ //--------------------------------------------------------------------
+ namespace
+ {
+ static void lcl_dispatchScriptURL_throw( DocumentEventExecutor_Data& _rDocExecData,
+ const ::rtl::OUString& _rScriptURL, const DocumentEvent& _rTrigger )
+ {
+ Reference< XModel > xDocument( _rDocExecData.xDocument.get(), UNO_QUERY_THROW );
+
+ Reference< XController > xController( xDocument->getCurrentController() );
+ Reference< XDispatchProvider > xDispProv;
+ if ( xController.is() )
+ xDispProv.set( xController->getFrame(), UNO_QUERY );
+ if ( !xDispProv.is() )
+ {
+ OSL_ENSURE( false, "lcl_dispatchScriptURL_throw: no controller/frame? How should I dispatch?" );
+ return;
+ }
+
+ URL aScriptURL;
+ aScriptURL.Complete = _rScriptURL;
+ if ( _rDocExecData.xURLTransformer.is() )
+ _rDocExecData.xURLTransformer->parseStrict( aScriptURL );
+
+ // unfortunately, executing a script can trigger all kind of complex stuff, and unfortunately, not
+ // every component involved into this properly cares for thread safety. To be on the safe side,
+ // we lock the solar mutex here.
+ ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+
+ Reference< XDispatch > xDispatch( xDispProv->queryDispatch( aScriptURL, ::rtl::OUString(), 0 ) );
+ if ( !xDispatch.is() )
+ {
+ OSL_ENSURE( false, "lcl_dispatchScriptURL_throw: no dispatcher for the script URL!" );
+ return;
+ }
+
+ PropertyValue aEventParam;
+ aEventParam.Value <<= _rTrigger;
+ Sequence< PropertyValue > aDispatchArgs( &aEventParam, 1 );
+ xDispatch->dispatch( aScriptURL, aDispatchArgs );
+ }
+ }
+
+ //====================================================================
+ //= DocumentEventExecutor
+ //====================================================================
+ //--------------------------------------------------------------------
+ DocumentEventExecutor::DocumentEventExecutor( const ::comphelper::ComponentContext& _rContext,
+ const Reference< XEventsSupplier >& _rxDocument )
+ :m_pData( new DocumentEventExecutor_Data( _rxDocument ) )
+ {
+ Reference< XDocumentEventBroadcaster > xBroadcaster( _rxDocument, UNO_QUERY_THROW );
+
+ osl_incrementInterlockedCount( &m_refCount );
+ {
+ xBroadcaster->addDocumentEventListener( this );
+ }
+ osl_decrementInterlockedCount( &m_refCount );
+
+ try
+ {
+ _rContext.createComponent( "com.sun.star.util.URLTransformer", m_pData->xURLTransformer );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+
+ //--------------------------------------------------------------------
+ DocumentEventExecutor::~DocumentEventExecutor()
+ {
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL DocumentEventExecutor::documentEventOccured( const DocumentEvent& _Event ) throw (RuntimeException)
+ {
+ Reference< XEventsSupplier > xEventsSupplier( m_pData->xDocument.get(), UNO_QUERY );
+ if ( !xEventsSupplier.is() )
+ {
+ OSL_ENSURE( false, "DocumentEventExecutor::documentEventOccured: no document anymore, but still being notified?" );
+ return;
+ }
+
+ Reference< XModel > xDocument( xEventsSupplier, UNO_QUERY_THROW );
+
+ try
+ {
+ Reference< XNameAccess > xDocEvents( xEventsSupplier->getEvents().get(), UNO_SET_THROW );
+ if ( !xDocEvents->hasByName( _Event.EventName ) )
+ {
+ // this is worth an assertion: We are listener at the very same document which we just asked
+ // for its events. So when EventName is fired, why isn't it supported by xDocEvents?
+ OSL_ENSURE( false, "DocumentEventExecutor::documentEventOccured: an unsupported event is notified!" );
+ return;
+ }
+
+ const ::comphelper::NamedValueCollection aScriptDescriptor( xDocEvents->getByName( _Event.EventName ) );
+
+
+ ::rtl::OUString sEventType;
+ bool bScriptAssigned = aScriptDescriptor.get_ensureType( "EventType", sEventType );
+
+ ::rtl::OUString sScript;
+ bScriptAssigned = bScriptAssigned && aScriptDescriptor.get_ensureType( "Script", sScript );
+
+ if ( !bScriptAssigned )
+ // no script is assigned to this event
+ return;
+
+ bool bDispatchScriptURL =
+ ( sEventType.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Script" ) )
+ || sEventType.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Service" ) )
+ );
+ bool bNonEmptyScript = sScript.getLength() != 0;
+
+ OSL_ENSURE( bDispatchScriptURL && bNonEmptyScript,
+ "DocumentEventExecutor::documentEventOccured: invalid/unsupported script descriptor" );
+
+ if ( bDispatchScriptURL && bNonEmptyScript )
+ {
+ lcl_dispatchScriptURL_throw( *m_pData, sScript, _Event );
+ }
+ }
+ catch( const RuntimeException& ) { throw; }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL DocumentEventExecutor::disposing( const lang::EventObject& /*_Source*/ ) throw (RuntimeException)
+ {
+ // not interested in
+ }
+
+
+//........................................................................
+} // namespace dbaccess
+//........................................................................
diff --git a/dbaccess/source/core/dataaccess/documenteventexecutor.hxx b/dbaccess/source/core/dataaccess/documenteventexecutor.hxx
new file mode 100644
index 000000000..03d0ddc09
--- /dev/null
+++ b/dbaccess/source/core/dataaccess/documenteventexecutor.hxx
@@ -0,0 +1,81 @@
+/*************************************************************************
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* Copyright 2008 by Sun Microsystems, Inc.
+*
+* OpenOffice.org - a multi-platform office productivity suite
+*
+* $RCSfile: documenteventexecutor.hxx,v $
+*
+* $Revision: 1.1.2.2 $
+*
+* 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.
+************************************************************************/
+
+#ifndef DBACCESS_DOCUMENTEVENTEXECUTOR_HXX
+#define DBACCESS_DOCUMENTEVENTEXECUTOR_HXX
+
+/** === begin UNO includes === **/
+#include <com/sun/star/document/XDocumentEventListener.hpp>
+#include <com/sun/star/document/XEventsSupplier.hpp>
+/** === end UNO includes === **/
+
+#include <cppuhelper/implbase1.hxx>
+
+#include <memory>
+
+namespace comphelper
+{
+ class ComponentContext;
+}
+
+//........................................................................
+namespace dbaccess
+{
+//........................................................................
+
+ struct DocumentEventExecutor_Data;
+ //====================================================================
+ //= DocumentEventExecutor
+ //====================================================================
+ typedef ::cppu::WeakImplHelper1 < ::com::sun::star::document::XDocumentEventListener
+ > DocumentEventExecutor_Base;
+ class DocumentEventExecutor : public DocumentEventExecutor_Base
+ {
+ public:
+ DocumentEventExecutor(
+ const ::comphelper::ComponentContext& _rContext,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::document::XEventsSupplier >& _rxDocument );
+
+ protected:
+ virtual ~DocumentEventExecutor();
+
+ // css.document.XDocumentEventListener
+ virtual void SAL_CALL documentEventOccured( const ::com::sun::star::document::DocumentEvent& Event ) throw (::com::sun::star::uno::RuntimeException);
+ // css.lang.XEventListener
+ virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException);
+
+ private:
+ ::std::auto_ptr< DocumentEventExecutor_Data > m_pData;
+ };
+
+//........................................................................
+} // namespace dbaccess
+//........................................................................
+
+#endif // DBACCESS_DOCUMENTEVENTEXECUTOR_HXX
diff --git a/dbaccess/source/core/dataaccess/documenteventnotifier.cxx b/dbaccess/source/core/dataaccess/documenteventnotifier.cxx
new file mode 100644
index 000000000..c35ddb945
--- /dev/null
+++ b/dbaccess/source/core/dataaccess/documenteventnotifier.cxx
@@ -0,0 +1,315 @@
+/*************************************************************************
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* Copyright 2008 by Sun Microsystems, Inc.
+*
+* OpenOffice.org - a multi-platform office productivity suite
+*
+* $RCSfile: documenteventnotifier.cxx,v $
+*
+* $Revision: 1.1.2.4 $
+*
+* 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_dbaccess.hxx"
+
+#include "documenteventnotifier.hxx"
+
+/** === begin UNO includes === **/
+#include <com/sun/star/frame/DoubleInitializationException.hpp>
+/** === end UNO includes === **/
+
+#include <comphelper/asyncnotification.hxx>
+#include <cppuhelper/interfacecontainer.hxx>
+#include <cppuhelper/weak.hxx>
+#include <tools/diagnose_ex.h>
+
+//........................................................................
+namespace dbaccess
+{
+//........................................................................
+
+ /** === begin UNO using === **/
+ using ::com::sun::star::uno::Reference;
+ using ::com::sun::star::uno::XInterface;
+ using ::com::sun::star::uno::UNO_QUERY;
+ using ::com::sun::star::uno::UNO_QUERY_THROW;
+ using ::com::sun::star::uno::UNO_SET_THROW;
+ using ::com::sun::star::uno::Exception;
+ using ::com::sun::star::uno::RuntimeException;
+ using ::com::sun::star::uno::Any;
+ using ::com::sun::star::uno::makeAny;
+ using ::com::sun::star::uno::Sequence;
+ using ::com::sun::star::uno::Type;
+ using ::com::sun::star::frame::DoubleInitializationException;
+ using ::com::sun::star::document::XDocumentEventListener;
+ using ::com::sun::star::document::DocumentEvent;
+ using ::com::sun::star::frame::XController2;
+ /** === end UNO using === **/
+ using namespace ::com::sun::star;
+
+ //==================================================================
+ //= DocumentEventHolder
+ //==================================================================
+ typedef ::comphelper::EventHolder< DocumentEvent > DocumentEventHolder;
+
+ //====================================================================
+ //= DocumentEventNotifier_Impl
+ //====================================================================
+ class DocumentEventNotifier_Impl : public ::comphelper::IEventProcessor
+ {
+ oslInterlockedCount m_refCount;
+ ::cppu::OWeakObject& m_rDocument;
+ ::osl::Mutex& m_rMutex;
+ bool m_bInitialized;
+ bool m_bDisposed;
+ ::rtl::Reference< ::comphelper::AsyncEventNotifier > m_pEventBroadcaster;
+ ::cppu::OInterfaceContainerHelper m_aLegacyEventListeners;
+ ::cppu::OInterfaceContainerHelper m_aDocumentEventListeners;
+
+ public:
+ DocumentEventNotifier_Impl( ::cppu::OWeakObject& _rBroadcasterDocument, ::osl::Mutex& _rMutex )
+ :m_refCount( 0 )
+ ,m_rDocument( _rBroadcasterDocument )
+ ,m_rMutex( _rMutex )
+ ,m_bInitialized( false )
+ ,m_bDisposed( false )
+ ,m_aLegacyEventListeners( _rMutex )
+ ,m_aDocumentEventListeners( _rMutex )
+ {
+ }
+
+ // IReference
+ virtual void SAL_CALL acquire();
+ virtual void SAL_CALL release();
+
+ void addLegacyEventListener( const Reference< document::XEventListener >& _Listener )
+ {
+ m_aLegacyEventListeners.addInterface( _Listener );
+ }
+
+ void removeLegacyEventListener( const Reference< document::XEventListener >& _Listener )
+ {
+ m_aLegacyEventListeners.removeInterface( _Listener );
+ }
+
+ void addDocumentEventListener( const Reference< XDocumentEventListener >& _Listener )
+ {
+ m_aDocumentEventListeners.addInterface( _Listener );
+ }
+
+ void removeDocumentEventListener( const Reference< XDocumentEventListener >& _Listener )
+ {
+ m_aDocumentEventListeners.removeInterface( _Listener );
+ }
+
+ void disposing();
+
+ void onDocumentInitialized();
+
+ void notifyDocumentEvent( const ::rtl::OUString& _EventName, const Reference< XController2 >& _ViewController,
+ const Any& _Supplement )
+ {
+ impl_notifyEvent_nothrow( DocumentEvent(
+ m_rDocument, _EventName, _ViewController, _Supplement ) );
+ }
+
+ void notifyDocumentEventAsync( const ::rtl::OUString& _EventName, const Reference< XController2 >& _ViewController,
+ const Any& _Supplement )
+ {
+ impl_notifyEventAsync_nothrow( DocumentEvent(
+ m_rDocument, _EventName, _ViewController, _Supplement ) );
+ }
+
+ protected:
+ virtual ~DocumentEventNotifier_Impl()
+ {
+ }
+
+ // IEventProcessor
+ virtual void processEvent( const ::comphelper::AnyEvent& _rEvent );
+
+ private:
+ void impl_notifyEvent_nothrow( const DocumentEvent& _rEvent );
+ void impl_notifyEventAsync_nothrow( const DocumentEvent& _rEvent );
+ };
+
+ //--------------------------------------------------------------------
+ void SAL_CALL DocumentEventNotifier_Impl::acquire()
+ {
+ osl_incrementInterlockedCount( &m_refCount );
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL DocumentEventNotifier_Impl::release()
+ {
+ if ( 0 == osl_decrementInterlockedCount( &m_refCount ) )
+ delete this;
+ }
+
+ //--------------------------------------------------------------------
+ void DocumentEventNotifier_Impl::disposing()
+ {
+ // cancel any pending asynchronous events
+ ::osl::MutexGuard aGuard( m_rMutex );
+ if ( m_pEventBroadcaster.is() )
+ {
+ m_pEventBroadcaster->removeEventsForProcessor( this );
+ m_pEventBroadcaster->terminate();
+ m_pEventBroadcaster = NULL;
+ }
+
+ lang::EventObject aEvent( m_rDocument );
+ m_aLegacyEventListeners.disposeAndClear( aEvent );
+ m_aDocumentEventListeners.disposeAndClear( aEvent );
+
+ m_bDisposed = true;
+ }
+
+ //--------------------------------------------------------------------
+ void DocumentEventNotifier_Impl::onDocumentInitialized()
+ {
+ if ( m_bInitialized )
+ throw DoubleInitializationException();
+
+ m_bInitialized = true;
+ if ( m_pEventBroadcaster.is() )
+ // there are already pending asynchronous events
+ m_pEventBroadcaster->create();
+ }
+
+ //--------------------------------------------------------------------
+ void DocumentEventNotifier_Impl::impl_notifyEvent_nothrow( const DocumentEvent& _rEvent )
+ {
+ OSL_PRECOND( m_bInitialized,
+ "DocumentEventNotifier_Impl::impl_notifyEvent_nothrow: only to be called when the document is already initialized!" );
+ try
+ {
+ document::EventObject aLegacyEvent( _rEvent.Source, _rEvent.EventName );
+ m_aLegacyEventListeners.notifyEach( &document::XEventListener::notifyEvent, aLegacyEvent );
+ }
+ catch(const Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ try
+ {
+ m_aDocumentEventListeners.notifyEach( &XDocumentEventListener::documentEventOccured, _rEvent );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+
+ //--------------------------------------------------------------------
+ void DocumentEventNotifier_Impl::impl_notifyEventAsync_nothrow( const DocumentEvent& _rEvent )
+ {
+ if ( !m_pEventBroadcaster.is() )
+ {
+ m_pEventBroadcaster.set( new ::comphelper::AsyncEventNotifier );
+ if ( m_bInitialized )
+ // start processing the events if and only if we (our document, respectively) are
+ // already initialized
+ m_pEventBroadcaster->create();
+ }
+ m_pEventBroadcaster->addEvent( new DocumentEventHolder( _rEvent ), this );
+ }
+
+ // -----------------------------------------------------------------------------
+ void DocumentEventNotifier_Impl::processEvent( const ::comphelper::AnyEvent& _rEvent )
+ {
+ // beware, this is called from the notification thread
+ {
+ ::osl::MutexGuard aGuard( m_rMutex );
+ if ( m_bDisposed )
+ return;
+ }
+ const DocumentEventHolder& rEventHolder = dynamic_cast< const DocumentEventHolder& >( _rEvent );
+ impl_notifyEvent_nothrow( rEventHolder.getEventObject() );
+ }
+
+ //====================================================================
+ //= DocumentEventNotifier
+ //====================================================================
+ //--------------------------------------------------------------------
+ DocumentEventNotifier::DocumentEventNotifier( ::cppu::OWeakObject& _rBroadcasterDocument, ::osl::Mutex& _rMutex )
+ :m_pImpl( new DocumentEventNotifier_Impl( _rBroadcasterDocument, _rMutex ) )
+ {
+ }
+
+ //--------------------------------------------------------------------
+ DocumentEventNotifier::~DocumentEventNotifier()
+ {
+ }
+
+ //--------------------------------------------------------------------
+ void DocumentEventNotifier::disposing()
+ {
+ m_pImpl->disposing();
+ }
+
+ //--------------------------------------------------------------------
+ void DocumentEventNotifier::onDocumentInitialized()
+ {
+ m_pImpl->onDocumentInitialized();
+ }
+
+ //--------------------------------------------------------------------
+ void DocumentEventNotifier::addLegacyEventListener( const Reference< document::XEventListener >& _Listener )
+ {
+ m_pImpl->addLegacyEventListener( _Listener );
+ }
+
+ //--------------------------------------------------------------------
+ void DocumentEventNotifier::removeLegacyEventListener( const Reference< document::XEventListener >& _Listener )
+ {
+ m_pImpl->removeLegacyEventListener( _Listener );
+ }
+
+ //--------------------------------------------------------------------
+ void DocumentEventNotifier::addDocumentEventListener( const Reference< XDocumentEventListener >& _Listener )
+ {
+ m_pImpl->addDocumentEventListener( _Listener );
+ }
+
+ //--------------------------------------------------------------------
+ void DocumentEventNotifier::removeDocumentEventListener( const Reference< XDocumentEventListener >& _Listener )
+ {
+ m_pImpl->removeDocumentEventListener( _Listener );
+ }
+
+ //--------------------------------------------------------------------
+ void DocumentEventNotifier::notifyDocumentEvent( const ::rtl::OUString& _EventName,
+ const Reference< XController2 >& _ViewController, const Any& _Supplement )
+ {
+ m_pImpl->notifyDocumentEvent( _EventName, _ViewController, _Supplement );
+ }
+
+ //--------------------------------------------------------------------
+ void DocumentEventNotifier::notifyDocumentEventAsync( const ::rtl::OUString& _EventName,
+ const Reference< XController2 >& _ViewController, const Any& _Supplement )
+ {
+ m_pImpl->notifyDocumentEventAsync( _EventName, _ViewController, _Supplement );
+ }
+
+//........................................................................
+} // namespace dbaccess
+//........................................................................
diff --git a/dbaccess/source/core/dataaccess/documenteventnotifier.hxx b/dbaccess/source/core/dataaccess/documenteventnotifier.hxx
new file mode 100644
index 000000000..0c85a0b52
--- /dev/null
+++ b/dbaccess/source/core/dataaccess/documenteventnotifier.hxx
@@ -0,0 +1,147 @@
+
+/*************************************************************************
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* Copyright 2008 by Sun Microsystems, Inc.
+*
+* OpenOffice.org - a multi-platform office productivity suite
+*
+* $RCSfile: documenteventnotifier.hxx,v $
+*
+* $Revision: 1.1.2.3 $
+*
+* 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.
+************************************************************************/
+
+#ifndef DBACCESS_DOCUMENTEVENTNOTIFIER_HXX
+#define DBACCESS_DOCUMENTEVENTNOTIFIER_HXX
+
+/** === begin UNO includes === **/
+#include <com/sun/star/document/XEventListener.hpp>
+#include <com/sun/star/document/XDocumentEventListener.hpp>
+/** === end UNO includes === **/
+
+#include <rtl/ref.hxx>
+
+namespace cppu
+{
+ class OWeakObject;
+}
+
+//........................................................................
+namespace dbaccess
+{
+//........................................................................
+
+ class DocumentEventNotifier_Impl;
+ //====================================================================
+ //= DocumentEventNotifier
+ //====================================================================
+ class DocumentEventNotifier
+ {
+ public:
+ DocumentEventNotifier( ::cppu::OWeakObject& _rBroadcasterDocument, ::osl::Mutex& _rMutex );
+ ~DocumentEventNotifier();
+
+ void addLegacyEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::document::XEventListener >& _Listener );
+ void removeLegacyEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::document::XEventListener >& _Listener );
+ void addDocumentEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::document::XDocumentEventListener >& _Listener );
+ void removeDocumentEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::document::XDocumentEventListener >& _Listener );
+
+ /** disposes the instance
+ @precond
+ the mutex is not locked
+ */
+ void disposing();
+
+ /** tells the instance that its document is completely initialized now.
+
+ Before you call this method, no notification will actually happen
+
+ @precond
+ the mutex is locked
+ */
+ void onDocumentInitialized();
+
+ /** notifies a document event described by the given parameters
+
+ @precond
+ the mutex is not locked
+ @precond
+ ->onDocumentInitialized has been called
+ */
+ void notifyDocumentEvent(
+ const ::rtl::OUString& _EventName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XController2 >& _rxViewController = NULL,
+ const ::com::sun::star::uno::Any& _Supplement = ::com::sun::star::uno::Any()
+ );
+
+ /** notifies a document event, described by the given parameters, asynchronously
+
+ Note that no event is actually notified before you called ->onDocumentInitialized.
+
+ @precond
+ the mutex is locked
+ */
+ void notifyDocumentEventAsync(
+ const ::rtl::OUString& _EventName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XController2 >& _ViewController = NULL,
+ const ::com::sun::star::uno::Any& _Supplement = ::com::sun::star::uno::Any()
+ );
+
+ /** notifies a document event to all registered listeners
+
+ @precond
+ the mutex is not locked
+ @precond
+ ->onDocumentInitialized has been called
+ */
+ void notifyDocumentEvent(
+ const sal_Char* _pAsciiEventName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XController2 >& _rxViewController = NULL,
+ const ::com::sun::star::uno::Any& _rSupplement = ::com::sun::star::uno::Any()
+ )
+ {
+ notifyDocumentEvent( ::rtl::OUString::createFromAscii( _pAsciiEventName ), _rxViewController, _rSupplement );
+ }
+
+ /** notifies a document event to all registered listeners, asynchronously
+
+ Note that no event is actually notified before you called ->onDocumentInitialized.
+
+ @precond
+ the mutex is locked
+ */
+ void notifyDocumentEventAsync(
+ const sal_Char* _pAsciiEventName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XController2 >& _rxViewController = NULL,
+ const ::com::sun::star::uno::Any& _rSupplement = ::com::sun::star::uno::Any()
+ )
+ {
+ notifyDocumentEventAsync( ::rtl::OUString::createFromAscii( _pAsciiEventName ), _rxViewController, _rSupplement );
+ }
+
+ private:
+ ::rtl::Reference< DocumentEventNotifier_Impl > m_pImpl;
+ };
+
+//........................................................................
+} // namespace dbaccess
+//........................................................................
+
+#endif // DBACCESS_DOCUMENTEVENTNOTIFIER_HXX
diff --git a/dbaccess/source/core/dataaccess/documentevents.cxx b/dbaccess/source/core/dataaccess/documentevents.cxx
new file mode 100644
index 000000000..c56fbed15
--- /dev/null
+++ b/dbaccess/source/core/dataaccess/documentevents.cxx
@@ -0,0 +1,266 @@
+/*************************************************************************
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* Copyright 2008 by Sun Microsystems, Inc.
+*
+* OpenOffice.org - a multi-platform office productivity suite
+*
+* $RCSfile: documentevents.cxx,v $
+*
+* $Revision: 1.1.2.9 $
+*
+* 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_dbaccess.hxx"
+
+#include "documentevents.hxx"
+
+/** === begin UNO includes === **/
+#include <com/sun/star/beans/PropertyValue.hpp>
+/** === end UNO includes === **/
+
+#include <comphelper/namedvaluecollection.hxx>
+
+#include <map>
+#include <algorithm>
+#include <functional>
+
+//........................................................................
+namespace dbaccess
+{
+//........................................................................
+
+ /** === begin UNO using === **/
+ using ::com::sun::star::uno::Reference;
+ using ::com::sun::star::uno::XInterface;
+ using ::com::sun::star::uno::UNO_QUERY;
+ using ::com::sun::star::uno::UNO_QUERY_THROW;
+ using ::com::sun::star::uno::UNO_SET_THROW;
+ using ::com::sun::star::uno::Exception;
+ using ::com::sun::star::uno::RuntimeException;
+ using ::com::sun::star::uno::Any;
+ using ::com::sun::star::uno::makeAny;
+ using ::com::sun::star::beans::PropertyValue;
+ using ::com::sun::star::container::NoSuchElementException;
+ using ::com::sun::star::lang::WrappedTargetException;
+ using ::com::sun::star::lang::IllegalArgumentException;
+ using ::com::sun::star::uno::Sequence;
+ using ::com::sun::star::uno::Type;
+ /** === end UNO using === **/
+
+ //====================================================================
+ //= DocumentEvents_Data
+ //====================================================================
+ typedef ::std::map< ::rtl::OUString, Sequence< PropertyValue > > NamedEventDescriptors;
+
+ struct DocumentEvents_Data : public ::boost::noncopyable
+ {
+ ::cppu::OWeakObject& rParent;
+ ::osl::Mutex& rMutex;
+ NamedEventDescriptors aEventDescs;
+
+ DocumentEvents_Data( ::cppu::OWeakObject& _rParent, ::osl::Mutex& _rMutex )
+ :rParent( _rParent )
+ ,rMutex( _rMutex )
+ {
+ }
+ };
+
+ //====================================================================
+ //= helper
+ //====================================================================
+ struct DocumentEventData
+ {
+ const sal_Char* pAsciiEventName;
+ bool bNeedsSyncNotify;
+ };
+
+ //--------------------------------------------------------------------
+ namespace
+ {
+ static const DocumentEventData* lcl_getDocumentEventData()
+ {
+ static const DocumentEventData s_aData[] = {
+ { "OnCreate", true },
+ { "OnLoadFinished", true },
+ { "OnNew", false }, // compatibility, see http://www.openoffice.org/issues/show_bug.cgi?id=46484
+ { "OnLoad", false }, // compatibility, see http://www.openoffice.org/issues/show_bug.cgi?id=46484
+ { "OnSaveAs", true },
+ { "OnSaveAsDone", false },
+ { "OnSaveAsFailed", false },
+ { "OnSave", true },
+ { "OnSaveDone", false },
+ { "OnSaveFailed", false },
+ { "OnSaveTo", true },
+ { "OnSaveToDone", false },
+ { "OnSaveToFailed", false },
+ { "OnPrepareUnload", true },
+ { "OnUnload", true },
+ { "OnFocus", false },
+ { "OnUnfocus", false },
+ { "OnModifyChanged", false },
+ { "OnViewCreated", false },
+ { "OnPrepareViewClosing", true },
+ { "OnViewClosed", false },
+ { "OnTitleChanged", false },
+ { NULL, false }
+ };
+ return s_aData;
+ }
+ }
+
+ //====================================================================
+ //= DocumentEvents
+ //====================================================================
+ //--------------------------------------------------------------------
+ DocumentEvents::DocumentEvents( ::cppu::OWeakObject& _rParent, ::osl::Mutex& _rMutex )
+ :m_pData( new DocumentEvents_Data( _rParent, _rMutex ) )
+ {
+ const DocumentEventData* pEventData = lcl_getDocumentEventData();
+ while ( pEventData->pAsciiEventName )
+ {
+ m_pData->aEventDescs[ ::rtl::OUString::createFromAscii( pEventData->pAsciiEventName ) ] =
+ Sequence< PropertyValue >();
+ ++pEventData;
+ }
+ }
+
+ //--------------------------------------------------------------------
+ DocumentEvents::~DocumentEvents()
+ {
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL DocumentEvents::acquire() throw()
+ {
+ m_pData->rParent.acquire();
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL DocumentEvents::release() throw()
+ {
+ m_pData->rParent.release();
+ }
+
+ //--------------------------------------------------------------------
+ bool DocumentEvents::needsSynchronousNotification( const ::rtl::OUString& _rEventName )
+ {
+ const DocumentEventData* pEventData = lcl_getDocumentEventData();
+ while ( pEventData->pAsciiEventName )
+ {
+ if ( _rEventName.compareToAscii( pEventData->pAsciiEventName ) == 0 )
+ return pEventData->bNeedsSyncNotify;
+ ++pEventData;
+ }
+
+ // this is an unknown event ... assume async notification
+ return false;
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL DocumentEvents::replaceByName( const ::rtl::OUString& _Name, const Any& _Element ) throw (IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_pData->rMutex );
+
+ NamedEventDescriptors::iterator elementPos = m_pData->aEventDescs.find( _Name );
+ if ( elementPos == m_pData->aEventDescs.end() )
+ throw NoSuchElementException( _Name, *this );
+
+ Sequence< PropertyValue > aEventDescriptor;
+ if ( _Element.hasValue() && !( _Element >>= aEventDescriptor ) )
+ throw IllegalArgumentException( _Element.getValueTypeName(), *this, 2 );
+
+ // Weird enough, the event assignment UI has (well: had) the idea of using an empty "EventType"/"Script"
+ // to indicate the event descriptor should be reset, instead of just passing an empty event descriptor.
+ ::comphelper::NamedValueCollection aCheck( aEventDescriptor );
+ if ( aCheck.has( "EventType" ) )
+ {
+ ::rtl::OUString sEventType = aCheck.getOrDefault( "EventType", ::rtl::OUString() );
+ OSL_ENSURE( sEventType.getLength(), "DocumentEvents::replaceByName: doing a reset via an empty EventType is weird!" );
+ if ( !sEventType.getLength() )
+ aEventDescriptor.realloc( 0 );
+ }
+ if ( aCheck.has( "Script" ) )
+ {
+ ::rtl::OUString sScript = aCheck.getOrDefault( "Script", ::rtl::OUString() );
+ OSL_ENSURE( sScript.getLength(), "DocumentEvents::replaceByName: doing a reset via an empty Script is weird!" );
+ if ( !sScript.getLength() )
+ aEventDescriptor.realloc( 0 );
+ }
+
+ elementPos->second = aEventDescriptor;
+ }
+
+ //--------------------------------------------------------------------
+ Any SAL_CALL DocumentEvents::getByName( const ::rtl::OUString& _Name ) throw (NoSuchElementException, WrappedTargetException, RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_pData->rMutex );
+
+ NamedEventDescriptors::const_iterator elementPos = m_pData->aEventDescs.find( _Name );
+ if ( elementPos == m_pData->aEventDescs.end() )
+ throw NoSuchElementException( _Name, *this );
+
+ Any aReturn;
+ const Sequence< PropertyValue >& rEventDesc( elementPos->second );
+ if ( rEventDesc.getLength() > 0 )
+ aReturn <<= rEventDesc;
+ return aReturn;
+ }
+
+ //--------------------------------------------------------------------
+ Sequence< ::rtl::OUString > SAL_CALL DocumentEvents::getElementNames( ) throw (RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_pData->rMutex );
+
+ Sequence< ::rtl::OUString > aNames( m_pData->aEventDescs.size() );
+ ::std::transform(
+ m_pData->aEventDescs.begin(),
+ m_pData->aEventDescs.end(),
+ aNames.getArray(),
+ ::std::select1st< NamedEventDescriptors::value_type >()
+ );
+ return aNames;
+ }
+
+ //--------------------------------------------------------------------
+ ::sal_Bool SAL_CALL DocumentEvents::hasByName( const ::rtl::OUString& _Name ) throw (RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_pData->rMutex );
+
+ return m_pData->aEventDescs.find( _Name ) != m_pData->aEventDescs.end();
+ }
+
+ //--------------------------------------------------------------------
+ Type SAL_CALL DocumentEvents::getElementType( ) throw (RuntimeException)
+ {
+ return ::cppu::UnoType< Sequence< PropertyValue > >::get();
+ }
+
+ //--------------------------------------------------------------------
+ ::sal_Bool SAL_CALL DocumentEvents::hasElements( ) throw (RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_pData->rMutex );
+ return !m_pData->aEventDescs.empty();
+ }
+
+
+//........................................................................
+} // namespace dbaccess
+//........................................................................
diff --git a/dbaccess/source/core/dataaccess/documentevents.hxx b/dbaccess/source/core/dataaccess/documentevents.hxx
new file mode 100644
index 000000000..3a471e3ab
--- /dev/null
+++ b/dbaccess/source/core/dataaccess/documentevents.hxx
@@ -0,0 +1,91 @@
+/*************************************************************************
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* Copyright 2008 by Sun Microsystems, Inc.
+*
+* OpenOffice.org - a multi-platform office productivity suite
+*
+* $RCSfile: documentevents.hxx,v $
+*
+* $Revision: 1.1.2.2 $
+*
+* 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.
+************************************************************************/
+
+#ifndef DBACCESS_DOCUMENTEVENTS_HXX
+#define DBACCESS_DOCUMENTEVENTS_HXX
+
+#include "dbaccessdllapi.h"
+
+/** === begin UNO includes === **/
+#include <com/sun/star/container/XNameReplace.hpp>
+/** === end UNO includes === **/
+
+#include <cppuhelper/implbase1.hxx>
+
+#include <memory>
+#include <boost/noncopyable.hpp>
+
+//........................................................................
+namespace dbaccess
+{
+//........................................................................
+
+ //====================================================================
+ //= DocumentEvents
+ //====================================================================
+ struct DocumentEvents_Data;
+
+ typedef ::cppu::WeakImplHelper1 < ::com::sun::star::container::XNameReplace
+ > DocumentEvents_Base;
+
+ class DBACCESS_DLLPRIVATE DocumentEvents
+ :public DocumentEvents_Base
+ ,public ::boost::noncopyable
+ {
+ public:
+ DocumentEvents( ::cppu::OWeakObject& _rParent, ::osl::Mutex& _rMutex );
+ ~DocumentEvents();
+
+ static bool needsSynchronousNotification( const ::rtl::OUString& _rEventName );
+
+ // XInterface
+ virtual void SAL_CALL acquire() throw();
+ virtual void SAL_CALL release() throw();
+
+ // XNameReplace
+ virtual void SAL_CALL replaceByName( const ::rtl::OUString& aName, const ::com::sun::star::uno::Any& aElement ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+
+ // XNameAccess
+ virtual ::com::sun::star::uno::Any SAL_CALL getByName( const ::rtl::OUString& aName ) throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getElementNames( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XElementAccess
+ virtual ::com::sun::star::uno::Type SAL_CALL getElementType( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::sal_Bool SAL_CALL hasElements( ) throw (::com::sun::star::uno::RuntimeException);
+
+ private:
+ ::std::auto_ptr< DocumentEvents_Data > m_pData;
+ };
+
+//........................................................................
+} // namespace dbaccess
+//........................................................................
+
+#endif // DBACCESS_DOCUMENTEVENTS_HXX
diff --git a/dbaccess/source/core/dataaccess/makefile.mk b/dbaccess/source/core/dataaccess/makefile.mk
index 77aa24c91..f49e011bd 100644
--- a/dbaccess/source/core/dataaccess/makefile.mk
+++ b/dbaccess/source/core/dataaccess/makefile.mk
@@ -8,7 +8,7 @@
#
# $RCSfile: makefile.mk,v $
#
-# $Revision: 1.10 $
+# $Revision: 1.10.2.3 $
#
# This file is part of OpenOffice.org.
#
@@ -60,7 +60,10 @@ SLOFILES= \
$(SLO)$/myucp_resultset.obj \
$(SLO)$/databasedocument.obj \
$(SLO)$/dataaccessdescriptor.obj\
- $(SLO)$/ModelImpl.obj
+ $(SLO)$/ModelImpl.obj \
+ $(SLO)$/documentevents.obj \
+ $(SLO)$/documenteventexecutor.obj \
+ $(SLO)$/documenteventnotifier.obj
# --- Targets ----------------------------------
diff --git a/dbaccess/source/ext/macromigration/dbmm_global.hrc b/dbaccess/source/ext/macromigration/dbmm_global.hrc
index 5084a025e..7bc71199c 100644
--- a/dbaccess/source/ext/macromigration/dbmm_global.hrc
+++ b/dbaccess/source/ext/macromigration/dbmm_global.hrc
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: dbmm_global.hrc,v $
- * $Revision: 1.3 $
+ * $Revision: 1.3.2.5 $
*
* This file is part of OpenOffice.org.
*
@@ -47,6 +47,12 @@
#define DLG_MACRO_MIGRATION RID_DBMM_DIALOG_START + 0
//=====================================================================
+//= error boxes
+//=====================================================================
+
+#define ERR_INVALID_BACKUP_LOCATION RID_DBMM_DIALOG_START + 0
+
+//=====================================================================
//= tab pages
//=====================================================================
@@ -59,17 +65,22 @@
//= strings
//=====================================================================
-#define STR_FORM ( RID_DBMM_STRING_START + 0 )
-#define STR_REPORT ( RID_DBMM_STRING_START + 1 )
-#define STR_OVERALL_PROGRESS ( RID_DBMM_STRING_START + 2 )
-#define STR_DATABASE_DOCUMENT ( RID_DBMM_STRING_START + 3 )
-#define STR_SAVED_COPY_TO ( RID_DBMM_STRING_START + 4 )
-#define STR_MOVED_LIBRARY ( RID_DBMM_STRING_START + 5 )
-#define STR_OOO_BASIC ( RID_DBMM_STRING_START + 6 )
-#define STR_JAVA_SCRIPT ( RID_DBMM_STRING_START + 7 )
-#define STR_BEAN_SHELL ( RID_DBMM_STRING_START + 8 )
-#define STR_JAVA ( RID_DBMM_STRING_START + 9 )
-#define STR_PYTHON ( RID_DBMM_STRING_START + 10 )
-#define STR_DIALOG ( RID_DBMM_STRING_START + 11 )
+#define STR_FORM ( RID_DBMM_STRING_START + 0 )
+#define STR_REPORT ( RID_DBMM_STRING_START + 1 )
+#define STR_OVERALL_PROGRESS ( RID_DBMM_STRING_START + 2 )
+#define STR_DATABASE_DOCUMENT ( RID_DBMM_STRING_START + 3 )
+#define STR_SAVED_COPY_TO ( RID_DBMM_STRING_START + 4 )
+#define STR_MOVED_LIBRARY ( RID_DBMM_STRING_START + 5 )
+#define STR_OOO_BASIC ( RID_DBMM_STRING_START + 6 )
+#define STR_JAVA_SCRIPT ( RID_DBMM_STRING_START + 7 )
+#define STR_BEAN_SHELL ( RID_DBMM_STRING_START + 8 )
+#define STR_JAVA ( RID_DBMM_STRING_START + 9 )
+#define STR_PYTHON ( RID_DBMM_STRING_START + 10 )
+#define STR_DIALOG ( RID_DBMM_STRING_START + 11 )
+#define STR_MIGRATING_LIBS ( RID_DBMM_STRING_START + 12 )
+#define STR_ERRORS ( RID_DBMM_STRING_START + 13 )
+#define STR_WARNINGS ( RID_DBMM_STRING_START + 14 )
+#define STR_EXCEPTION ( RID_DBMM_STRING_START + 15 )
+#define STR_LIBRARY_TYPE_AND_NAME ( RID_DBMM_STRING_START + 16 )
#endif // DBACCESS_DBMM_GLOBAL_HRC
diff --git a/dbaccess/source/ext/macromigration/dbmm_types.cxx b/dbaccess/source/ext/macromigration/dbmm_types.cxx
new file mode 100644
index 000000000..68916437d
--- /dev/null
+++ b/dbaccess/source/ext/macromigration/dbmm_types.cxx
@@ -0,0 +1,66 @@
+/*************************************************************************
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* Copyright 2008 by Sun Microsystems, Inc.
+*
+* OpenOffice.org - a multi-platform office productivity suite
+*
+* $RCSfile: dbmm_types.cxx,v $
+*
+* $Revision: 1.1.2.1 $
+*
+* 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_dbaccess.hxx"
+
+#include "dbmm_types.hxx"
+
+#include "dbmm_global.hrc"
+#include "dbmm_module.hxx"
+
+//........................................................................
+namespace dbmm
+{
+//........................................................................
+
+ //====================================================================
+ //= helper
+ //====================================================================
+ //--------------------------------------------------------------------
+ String getScriptTypeDisplayName( const ScriptType _eType )
+ {
+ USHORT nResId( 0 );
+
+ switch ( _eType )
+ {
+ case eBasic: nResId = STR_OOO_BASIC; break;
+ case eBeanShell: nResId = STR_BEAN_SHELL; break;
+ case eJavaScript: nResId = STR_JAVA_SCRIPT; break;
+ case ePython: nResId = STR_PYTHON; break;
+ case eJava: nResId = STR_JAVA; break;
+ case eDialog: nResId = STR_DIALOG; break;
+ }
+ OSL_ENSURE( nResId != 0, "getScriptTypeDisplayName: illegal script type!" );
+ return nResId ? String( MacroMigrationResId( nResId ) ) : String();
+ }
+
+//........................................................................
+} // namespace dbmm
+//........................................................................
diff --git a/dbaccess/source/ext/macromigration/dbmm_types.hxx b/dbaccess/source/ext/macromigration/dbmm_types.hxx
index f42c47cea..ec53f6f02 100644
--- a/dbaccess/source/ext/macromigration/dbmm_types.hxx
+++ b/dbaccess/source/ext/macromigration/dbmm_types.hxx
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: dbmm_types.hxx,v $
- * $Revision: 1.3 $
+ * $Revision: 1.3.2.1 $
*
* This file is part of OpenOffice.org.
*
@@ -31,8 +31,7 @@
#ifndef DBACCESS_DBMM_TYPES_HXX
#define DBACCESS_DBMM_TYPES_HXX
-/** === begin UNO includes === **/
-/** === end UNO includes === **/
+#include <tools/string.hxx>
//........................................................................
namespace dbmm
@@ -61,6 +60,11 @@ namespace dbmm
eReport
};
+ //====================================================================
+ //= helper
+ //====================================================================
+ String getScriptTypeDisplayName( const ScriptType _eType );
+
//........................................................................
} // namespace dbmm
//........................................................................
diff --git a/dbaccess/source/ext/macromigration/docerrorhandling.cxx b/dbaccess/source/ext/macromigration/docerrorhandling.cxx
deleted file mode 100644
index c98404a76..000000000
--- a/dbaccess/source/ext/macromigration/docerrorhandling.cxx
+++ /dev/null
@@ -1,91 +0,0 @@
-/*************************************************************************
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * Copyright 2008 by Sun Microsystems, Inc.
- *
- * OpenOffice.org - a multi-platform office productivity suite
- *
- * $RCSfile: docerrorhandling.cxx,v $
- * $Revision: 1.3 $
- *
- * 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_dbaccess.hxx"
-
-#include "docerrorhandling.hxx"
-
-/** === begin UNO includes === **/
-#include <com/sun/star/task/XInteractionHandler.hpp>
-#include <com/sun/star/frame/XModel.hpp>
-/** === end UNO includes === **/
-
-#include <comphelper/componentcontext.hxx>
-#include <comphelper/namedvaluecollection.hxx>
-#include <comphelper/interaction.hxx>
-#include <tools/diagnose_ex.h>
-
-//........................................................................
-namespace dbmm
-{
-//........................................................................
-
- /** === begin UNO using === **/
- using ::com::sun::star::uno::Reference;
- using ::com::sun::star::uno::XInterface;
- using ::com::sun::star::uno::UNO_QUERY;
- using ::com::sun::star::uno::UNO_QUERY_THROW;
- using ::com::sun::star::uno::UNO_SET_THROW;
- using ::com::sun::star::uno::Exception;
- using ::com::sun::star::uno::RuntimeException;
- using ::com::sun::star::uno::Any;
- using ::com::sun::star::uno::makeAny;
- using ::com::sun::star::sdb::XOfficeDatabaseDocument;
- using ::com::sun::star::task::XInteractionHandler;
- using ::com::sun::star::frame::XModel;
- /** === end UNO using === **/
-
- //====================================================================
- //= DocumentErrorHandling
- //====================================================================
- //--------------------------------------------------------------------
- void DocumentErrorHandling::reportError( const ::comphelper::ComponentContext& _rContext, const Reference< XOfficeDatabaseDocument >& _rxDocument, const Any& _rError )
- {
- try
- {
- Reference< XInteractionHandler > xHandler( _rContext.createComponent( "com.sun.star.task.InteractionHandler" ), UNO_QUERY_THROW );
- // check whether the DB doc has an own interaction handler set
- Reference< XModel > xDocModel( _rxDocument, UNO_QUERY_THROW );
- ::comphelper::NamedValueCollection aDocArgs( xDocModel->getArgs() );
- xHandler = aDocArgs.getOrDefault( "InteractionHandler", xHandler );
- xHandler->handle(
- new ::comphelper::OInteractionRequest( _rError )
- );
- }
- catch( const Exception& )
- {
- DBG_UNHANDLED_EXCEPTION();
- }
- }
-
-//........................................................................
-} // namespace dbmm
-//........................................................................
diff --git a/dbaccess/source/ext/macromigration/docerrorhandling.hxx b/dbaccess/source/ext/macromigration/docerrorhandling.hxx
deleted file mode 100644
index 5e3f18fc7..000000000
--- a/dbaccess/source/ext/macromigration/docerrorhandling.hxx
+++ /dev/null
@@ -1,69 +0,0 @@
-/*************************************************************************
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * Copyright 2008 by Sun Microsystems, Inc.
- *
- * OpenOffice.org - a multi-platform office productivity suite
- *
- * $RCSfile: docerrorhandling.hxx,v $
- * $Revision: 1.3 $
- *
- * 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.
- *
- ************************************************************************/
-
-#ifndef DBACCESS_DOCERRORHANDLING_HXX
-#define DBACCESS_DOCERRORHANDLING_HXX
-
-/** === begin UNO includes === **/
-#include <com/sun/star/sdb/XOfficeDatabaseDocument.hpp>
-/** === end UNO includes === **/
-
-namespace comphelper {
- class ComponentContext;
-}
-
-//........................................................................
-namespace dbmm
-{
-//........................................................................
-
- //====================================================================
- //= DocumentErrorHandling
- //====================================================================
- class DocumentErrorHandling
- {
- public:
- /** reports the given error (usually an exception caught on the caller's side)
- to the user, using the document's interaction handler, if present. If the document
- does not have an own interaction handler, the given component context is used
- to create a new one.
- */
- static void reportError(
- const ::comphelper::ComponentContext& _rContext,
- const ::com::sun::star::uno::Reference< ::com::sun::star::sdb::XOfficeDatabaseDocument >& _rxDocument,
- const ::com::sun::star::uno::Any& _rError
- );
- };
-
-//........................................................................
-} // namespace dbmm
-//........................................................................
-
-#endif // DBACCESS_DOCERRORHANDLING_HXX
diff --git a/dbaccess/source/ext/macromigration/docinteraction.cxx b/dbaccess/source/ext/macromigration/docinteraction.cxx
new file mode 100644
index 000000000..19d1f682f
--- /dev/null
+++ b/dbaccess/source/ext/macromigration/docinteraction.cxx
@@ -0,0 +1,157 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: docinteraction.cxx,v $
+ * $Revision: 1.1.2.2 $
+ *
+ * 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_dbaccess.hxx"
+
+#include "docinteraction.hxx"
+
+/** === begin UNO includes === **/
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/task/DocumentPasswordRequest.hpp>
+/** === end UNO includes === **/
+
+#include <comphelper/componentcontext.hxx>
+#include <comphelper/namedvaluecollection.hxx>
+#include <comphelper/interaction.hxx>
+#include <rtl/ref.hxx>
+#include <tools/diagnose_ex.h>
+
+//........................................................................
+namespace dbmm
+{
+//........................................................................
+
+ /** === begin UNO using === **/
+ using ::com::sun::star::uno::Reference;
+ using ::com::sun::star::uno::XInterface;
+ using ::com::sun::star::uno::UNO_QUERY;
+ using ::com::sun::star::uno::UNO_QUERY_THROW;
+ using ::com::sun::star::uno::UNO_SET_THROW;
+ using ::com::sun::star::uno::Exception;
+ using ::com::sun::star::uno::RuntimeException;
+ using ::com::sun::star::uno::Any;
+ using ::com::sun::star::uno::makeAny;
+ using ::com::sun::star::task::XInteractionHandler;
+ using ::com::sun::star::frame::XModel;
+ using ::com::sun::star::task::DocumentPasswordRequest;
+ using ::com::sun::star::task::InteractionClassification_QUERY;
+ using ::com::sun::star::task::PasswordRequestMode_PASSWORD_ENTER;
+ using ::com::sun::star::task::PasswordRequestMode_PASSWORD_REENTER;
+ /** === end UNO using === **/
+
+ //====================================================================
+ //= InteractionHandler_Data
+ //====================================================================
+ struct InteractionHandler_Data
+ {
+ Reference< XInteractionHandler > xHandler;
+
+ InteractionHandler_Data( const Reference< XInteractionHandler >& _rxHandler )
+ :xHandler( _rxHandler )
+ {
+ }
+
+ InteractionHandler_Data( const ::comphelper::ComponentContext& _rContext )
+ :xHandler( _rContext.createComponent( "com.sun.star.task.InteractionHandler" ), UNO_QUERY_THROW )
+ {
+ }
+ };
+
+ //====================================================================
+ //= InteractionHandler
+ //====================================================================
+ //--------------------------------------------------------------------
+ InteractionHandler::InteractionHandler( const ::comphelper::ComponentContext& _rContext )
+ :m_pData( new InteractionHandler_Data( _rContext ) )
+ {
+ }
+
+ //--------------------------------------------------------------------
+ InteractionHandler::InteractionHandler( const Reference< XInteractionHandler >& _rxHandler )
+ :m_pData( new InteractionHandler_Data( _rxHandler ) )
+ {
+ }
+
+ //--------------------------------------------------------------------
+ InteractionHandler::InteractionHandler( const ::comphelper::ComponentContext& _rContext, const Reference< XModel >& _rxDocument )
+ :m_pData( new InteractionHandler_Data( _rContext ) )
+ {
+ // check whether the doumentc has an own interaction handler set
+ ::comphelper::NamedValueCollection aDocArgs( _rxDocument->getArgs() );
+ m_pData->xHandler = aDocArgs.getOrDefault( "InteractionHandler", m_pData->xHandler );
+ }
+
+ //--------------------------------------------------------------------
+ InteractionHandler::~InteractionHandler()
+ {
+ }
+
+ //--------------------------------------------------------------------
+ bool InteractionHandler::requestDocumentPassword( const ::rtl::OUString& _rDocumentName, ::rtl::OUString& _io_rPassword )
+ {
+ // create request
+ DocumentPasswordRequest aRequest(
+ ::rtl::OUString(), NULL,
+ InteractionClassification_QUERY,
+ _io_rPassword.getLength() ? PasswordRequestMode_PASSWORD_REENTER : PasswordRequestMode_PASSWORD_ENTER,
+ _rDocumentName
+ );
+
+ ::rtl::Reference< ::comphelper::OInteractionRequest > pRequest( new ::comphelper::OInteractionRequest( makeAny( aRequest ) ) );
+ ::rtl::Reference< ::comphelper::OInteractionPassword > pPassword( new ::comphelper::OInteractionPassword( _io_rPassword ) );
+ ::rtl::Reference< ::comphelper::OInteractionAbort > pAbort( new ::comphelper::OInteractionAbort );
+ pRequest->addContinuation( pPassword.get() );
+ pRequest->addContinuation( pAbort.get() );
+
+ // handle
+ m_pData->xHandler->handle( pRequest.get() );
+
+ // finish up
+ if ( pAbort->wasSelected() )
+ return false;
+
+ _io_rPassword = pPassword->getPassword();
+ return true;
+ }
+
+ //--------------------------------------------------------------------
+ void InteractionHandler::reportError( const Any& _rError )
+ {
+ ::rtl::Reference< ::comphelper::OInteractionRequest > pRequest( new ::comphelper::OInteractionRequest( _rError ) );
+ ::rtl::Reference< ::comphelper::OInteractionApprove > pApprove( new ::comphelper::OInteractionApprove );
+ pRequest->addContinuation( pApprove.get() );
+
+ m_pData->xHandler->handle( pRequest.get() );
+ }
+
+//........................................................................
+} // namespace dbmm
+//........................................................................
diff --git a/dbaccess/source/ext/macromigration/docinteraction.hxx b/dbaccess/source/ext/macromigration/docinteraction.hxx
new file mode 100644
index 000000000..298e06c71
--- /dev/null
+++ b/dbaccess/source/ext/macromigration/docinteraction.hxx
@@ -0,0 +1,107 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: docinteraction.hxx,v $
+ * $Revision: 1.1.2.1 $
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef DBACCESS_DOCERRORHANDLING_HXX
+#define DBACCESS_DOCERRORHANDLING_HXX
+
+/** === begin UNO includes === **/
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/task/XInteractionHandler.hpp>
+/** === end UNO includes === **/
+
+namespace comphelper {
+ class ComponentContext;
+}
+
+#include <memory>
+
+//........................................................................
+namespace dbmm
+{
+//........................................................................
+
+ //====================================================================
+ //= DocumentErrorHandling
+ //====================================================================
+ struct InteractionHandler_Data;
+ /** wraps common operations with an interaction handler.
+ */
+ class InteractionHandler
+ {
+ public:
+ /** creates an interaction handler by instantiating a css.task.InteractionHandler
+ component at the given component context.
+ */
+ InteractionHandler( const ::comphelper::ComponentContext& _rContext );
+
+ /** creates an InteractionHandler instance, using the given existing UNO handler.
+ */
+ InteractionHandler( const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& _rxHandler );
+
+ /** creates an interaction handler by instantiating a css.task.InteractionHandler
+ component at the given component context, or using the given document's interaction handler,
+ if one is specified in the document's media descriptor.
+ */
+ InteractionHandler( const ::comphelper::ComponentContext& _rContext, const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& _rxDocument );
+
+ /** destructor
+ */
+ ~InteractionHandler();
+
+ /** requests a document password
+ @param _rDocumentName
+ the document name
+ @param _io_rPassword
+ the initial password on method entry, the password as entered by the user on method leave
+ @return
+ <TRUE/> if and only if the user entered a password, and confirmed with OK, <FALSE/>
+ if the user aborted the request.
+ */
+ bool requestDocumentPassword(
+ const ::rtl::OUString& _rDocumentName,
+ ::rtl::OUString& _io_rPassword
+ );
+
+ /** reports the given error (usually an exception caught on the caller's side)
+ to the user
+ */
+ void reportError(
+ const ::com::sun::star::uno::Any& _rError
+ );
+
+ private:
+ ::std::auto_ptr< InteractionHandler_Data > m_pData;
+ };
+
+//........................................................................
+} // namespace dbmm
+//........................................................................
+
+#endif // DBACCESS_DOCERRORHANDLING_HXX
diff --git a/dbaccess/source/ext/macromigration/macromigration.hrc b/dbaccess/source/ext/macromigration/macromigration.hrc
index 18a9ba8aa..673174f21 100644
--- a/dbaccess/source/ext/macromigration/macromigration.hrc
+++ b/dbaccess/source/ext/macromigration/macromigration.hrc
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: macromigration.hrc,v $
- * $Revision: 1.3 $
+ * $Revision: 1.3.2.1 $
*
* This file is part of OpenOffice.org.
*
@@ -93,5 +93,7 @@
#define STR_STATE_BACKUP_DBDOC 2
#define STR_STATE_MIGRATE 3
#define STR_STATE_SUMMARY 4
+#define STR_SUCCESSFUL 5
+#define STR_UNSUCCESSFUL 6
#endif // DBACCESS_MACROMIGRATION_HRC
diff --git a/dbaccess/source/ext/macromigration/macromigration.src b/dbaccess/source/ext/macromigration/macromigration.src
index aa572c0fe..aca9d8975 100644
--- a/dbaccess/source/ext/macromigration/macromigration.src
+++ b/dbaccess/source/ext/macromigration/macromigration.src
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: macromigration.src,v $
- * $Revision: 1.3 $
+ * $Revision: 1.3.2.8 $
*
* This file is part of OpenOffice.org.
*
@@ -88,16 +88,16 @@ TabPage TP_PREPARE
TAB_PAGE_HEIGHT - CONTENT_POS_X - TAB_PAGE_CONTENT_MARGIN - ( 2 * FIXED_TEXT_HEIGHT - SPACING_UNRELATED ) );
WordBreak = TRUE;
- Text [ en-US ] = "This wizard will guide you through the task of migrating your macros and scripts.\n\n"
+ Text [ en-US ] = "This wizard will guide you through the task of migrating your macros.\n\n"
- "After you finished it, all macros and scripts which were formerly embedded into your "
- "forms and reports will have been moved to the database document. In this course, libraries "
- "will be renamed as needed.\n\n"
+ "After you finished it, all macros which were formerly embedded into the forms and reports of "
+ "the current database document will have been moved to the document itself. In this course, "
+ "libraries will be renamed as needed.\n\n"
- "If your forms and reports contain references to those macros and scripts, they "
- "will be adjusted, where possible.\n\n"
+ "If your forms and reports contain references to those macros, they will be adjusted, where "
+ "possible.\n\n"
- "Before the migration can start, all forms, reports, queries and tables must be closed. "
+ "Before the migration can start, all forms, reports, queries and tables belonging to the document must be closed. "
"Press 'Next' to do so.";
};
@@ -231,8 +231,6 @@ TabPage TP_MIGRATE
Pos = MAP_APPFONT( TAB_PAGE_CONTENT_MARGIN + 60,
CONTENT_POS_X + 2 * FIXED_TEXT_HEIGHT + SPACING_UNRELATED );
Size = MAP_APPFONT( TAB_PAGE_WIDTH - ( TAB_PAGE_CONTENT_MARGIN + 60 ), FIXED_TEXT_HEIGHT );
-
- Text [ en-US ] = "Form 1";
};
FixedText FT_CURRENT_PROGRESS_LABEL
@@ -249,8 +247,6 @@ TabPage TP_MIGRATE
Pos = MAP_APPFONT( TAB_PAGE_CONTENT_MARGIN + 60,
CONTENT_POS_X + 2 * FIXED_TEXT_HEIGHT + SPACING_UNRELATED + FIXED_TEXT_HEIGHT + SPACING_UNRELATED );
Size = MAP_APPFONT( TAB_PAGE_WIDTH - ( TAB_PAGE_CONTENT_MARGIN + 60 ), FIXED_TEXT_HEIGHT );
-
- Text [ en-US ] = "loading ...";
};
Window WND_CURRENT_PROGRESS
@@ -299,8 +295,9 @@ TabPage TP_MIGRATE
Size = MAP_APPFONT( TAB_PAGE_WIDTH - 2 * TAB_PAGE_CONTENT_MARGIN, 2 * FIXED_TEXT_HEIGHT );
WordBreak = TRUE;
+ Hide = TRUE;
- Text [ en-US ] = "All documents have been successfully processed. Press 'Next' to show a detailed summary.";
+ Text [ en-US ] = "All forms and reports have been successfully processed. Press 'Next' to show a detailed summary.";
};
};
@@ -328,7 +325,7 @@ TabPage TP_SUMMARY
Pos = MAP_APPFONT( TAB_PAGE_CONTENT_MARGIN, CONTENT_POS_X );
Size = MAP_APPFONT( TAB_PAGE_WIDTH - 2 * TAB_PAGE_CONTENT_MARGIN, FIXED_TEXT_HEIGHT );
- Text [ en-US ] = "The following actions have been taken:";
+ WordBreak = TRUE;
};
MultiLineEdit ED_CHANGES
@@ -342,6 +339,15 @@ TabPage TP_SUMMARY
Border = TRUE;
BorderStyle = WINDOW_BORDER_MONO;
};
+
+ String STR_SUCCESSFUL
+ {
+ Text [ en-US ] = "The migration was successful. Below is a log of the actions which have been taken to your document.";
+ };
+ String STR_UNSUCCESSFUL
+ {
+ Text [ en-US ] = "The migration was not successful. Examine the migration log below for details.";
+ };
};
String STR_FORM
@@ -373,12 +379,22 @@ String STR_SAVED_COPY_TO
String STR_MOVED_LIBRARY
{
- Text[ en-US ] = "moved $type$ library $old$ to $new$";
+ Text[ en-US ] = "migrated $type$ library '$old$' to '$new$'";
+};
+
+String STR_LIBRARY_TYPE_AND_NAME
+{
+ Text [ en-US ] = "$type$ library '$library$'";
+};
+
+String STR_MIGRATING_LIBS
+{
+ Text [ en-US ] = "migrating libraries ...";
};
String STR_OOO_BASIC
{
- Text[ en-US ] = "%PRODUCTNAME% Basic";
+ Text[ en-US ] = "%PRODUCTNAME Basic";
};
String STR_JAVA_SCRIPT
@@ -406,3 +422,24 @@ String STR_DIALOG
Text[ en-US ] = "dialog";
};
+String STR_ERRORS
+{
+ Text [ en-US ] = "Error(s)";
+};
+
+String STR_WARNINGS
+{
+ Text [ en-US ] = "Warnings";
+};
+
+String STR_EXCEPTION
+{
+ Text [ en-US ] = "caught exception: ";
+};
+
+
+ErrorBox ERR_INVALID_BACKUP_LOCATION
+{
+ Buttons = WB_OK;
+ Message [ en-US ] = "You need to choose a backup location other than the document location itself.";
+};
diff --git a/dbaccess/source/ext/macromigration/macromigrationdialog.cxx b/dbaccess/source/ext/macromigration/macromigrationdialog.cxx
index 7f18ad760..a7432cb71 100644
--- a/dbaccess/source/ext/macromigration/macromigrationdialog.cxx
+++ b/dbaccess/source/ext/macromigration/macromigrationdialog.cxx
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: macromigrationdialog.cxx,v $
- * $Revision: 1.3 $
+ * $Revision: 1.3.2.9 $
*
* This file is part of OpenOffice.org.
*
@@ -33,23 +33,36 @@
#include "dbmm_global.hrc"
#include "dbmm_module.hxx"
-#include "docerrorhandling.hxx"
+#include "docinteraction.hxx"
#include "macromigration.hrc"
#include "macromigrationdialog.hxx"
#include "macromigrationpages.hxx"
#include "migrationengine.hxx"
+#include "migrationerror.hxx"
#include "migrationlog.hxx"
/** === begin UNO includes === **/
#include <com/sun/star/sdb/application/XDatabaseDocumentUI.hpp>
#include <com/sun/star/frame/XModel2.hpp>
#include <com/sun/star/frame/XStorable.hpp>
-#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/util/XCloseable.hpp>
+#include <com/sun/star/frame/XComponentLoader.hpp>
+#include <com/sun/star/util/XModifiable.hpp>
+#include <com/sun/star/ucb/XContent.hpp>
+#include <com/sun/star/ucb/XContentProvider.hpp>
/** === end UNO includes === **/
+#include <comphelper/namedvaluecollection.hxx>
#include <cppuhelper/exc_hlp.hxx>
+#include <cppuhelper/implbase1.hxx>
+#include <rtl/ref.hxx>
#include <svtools/filenotation.hxx>
#include <tools/diagnose_ex.h>
+#include <ucbhelper/content.hxx>
+#include <ucbhelper/contentbroker.hxx>
+#include <vcl/msgbox.hxx>
+
+#include <list>
//........................................................................
namespace dbmm
@@ -61,7 +74,7 @@ namespace dbmm
#define STATE_MIGRATE 2
#define STATE_SUMMARY 3
-#define PATH_DEFAULT 1
+#define PATH_DEFAULT 1
/** === begin UNO using === **/
using ::com::sun::star::uno::Reference;
@@ -77,14 +90,39 @@ namespace dbmm
using ::com::sun::star::sdb::XOfficeDatabaseDocument;
using ::com::sun::star::frame::XModel2;
using ::com::sun::star::frame::XController;
+ using ::com::sun::star::frame::XController2;
using ::com::sun::star::container::XEnumeration;
using ::com::sun::star::frame::XStorable;
using ::com::sun::star::uno::Sequence;
using ::com::sun::star::beans::PropertyValue;
- using ::com::sun::star::frame::XModel;
+ using ::com::sun::star::frame::XFrame;
+ using ::com::sun::star::awt::XWindow;
+ using ::com::sun::star::util::XCloseable;
+ using ::com::sun::star::util::XCloseListener;
+ using ::com::sun::star::util::CloseVetoException;
+ using ::com::sun::star::lang::EventObject;
+ using ::com::sun::star::frame::XComponentLoader;
+ using ::com::sun::star::util::XModifiable;
+ using ::com::sun::star::ucb::XCommandEnvironment;
+ using ::com::sun::star::ucb::XContent;
+ using ::com::sun::star::ucb::XContentIdentifier;
+ using ::com::sun::star::ucb::XContentProvider;
/** === end UNO using === **/
//====================================================================
+ //= helper
+ //====================================================================
+ //--------------------------------------------------------------------
+ static void lcl_getControllers_throw( const Reference< XModel2 >& _rxDocument,
+ ::std::list< Reference< XController2 > >& _out_rControllers )
+ {
+ _out_rControllers.clear();
+ Reference< XEnumeration > xControllerEnum( _rxDocument->getControllers(), UNO_SET_THROW );
+ while ( xControllerEnum->hasMoreElements() )
+ _out_rControllers.push_back( Reference< XController2 >( xControllerEnum->nextElement(), UNO_QUERY_THROW ) );
+ }
+
+ //====================================================================
//= MacroMigrationDialog_Data
//====================================================================
struct MacroMigrationDialog_Data
@@ -92,7 +130,11 @@ namespace dbmm
::comphelper::ComponentContext aContext;
MigrationLog aLogger;
Reference< XOfficeDatabaseDocument > xDocument;
+ Reference< XModel2 > xDocumentModel;
+ ::rtl::OUString sSuccessfulBackupLocation;
bool bMigrationIsRunning;
+ bool bMigrationFailure;
+ bool bMigrationSuccess;
MacroMigrationDialog_Data(
const ::comphelper::ComponentContext& _rContext,
@@ -100,12 +142,14 @@ namespace dbmm
:aContext( _rContext )
,aLogger()
,xDocument( _rxDocument )
+ ,xDocumentModel( _rxDocument, UNO_QUERY )
,bMigrationIsRunning( false )
+ ,bMigrationFailure( false )
+ ,bMigrationSuccess( false )
{
}
};
-
//====================================================================
//= MacroMigrationDialog
//====================================================================
@@ -136,7 +180,7 @@ namespace dbmm
enableButtons( WZB_FINISH, true );
ActivatePage();
- OSL_PRECOND( m_pData->xDocument.is(), "MacroMigrationDialog::MacroMigrationDialog: illegal document!" );
+ OSL_PRECOND( m_pData->xDocumentModel.is(), "MacroMigrationDialog::MacroMigrationDialog: illegal document!" );
}
//--------------------------------------------------------------------
@@ -157,6 +201,21 @@ namespace dbmm
}
//--------------------------------------------------------------------
+ short MacroMigrationDialog::Execute()
+ {
+ short nResult = MacroMigrationDialog_Base::Execute();
+ if ( !m_pData->bMigrationFailure && !m_pData->bMigrationSuccess )
+ // migration did not even start
+ return nResult;
+
+ OSL_ENSURE( !m_pData->bMigrationFailure || !m_pData->bMigrationSuccess,
+ "MacroMigrationDialog::Execute: success *and* failure at the same time?!" );
+ impl_reloadDocument_nothrow( m_pData->bMigrationSuccess );
+
+ return nResult;
+ }
+
+ //--------------------------------------------------------------------
BOOL MacroMigrationDialog::Close()
{
if ( m_pData->bMigrationIsRunning )
@@ -194,18 +253,23 @@ namespace dbmm
enableButtons( WZB_FINISH | WZB_CANCEL | WZB_PREVIOUS | WZB_NEXT, false );
- // prevent closing
- m_pData->bMigrationIsRunning = true;
// start the migration asynchronously
PostUserEvent( LINK( this, MacroMigrationDialog, OnStartMigration ) );
}
break;
case STATE_SUMMARY:
- // enable the previous step - we can't return to the actual migration, it already happened (or failed)
+ // disable the previous step - we can't return to the actual migration, it already happened (or failed)
enableState( STATE_MIGRATE, false );
updateTravelUI();
- dynamic_cast< ResultPage& >( *GetPage( STATE_SUMMARY ) ).displaySummary( m_pData->aLogger.getCompleteLog() );
+
+ // display the results
+ dynamic_cast< ResultPage& >( *GetPage( STATE_SUMMARY ) ).displayMigrationLog(
+ m_pData->bMigrationSuccess, m_pData->aLogger.getCompleteLog() );
+
+ enableButtons( WZB_FINISH, m_pData->bMigrationSuccess );
+ enableButtons( WZB_CANCEL, m_pData->bMigrationFailure );
+ defaultButton( m_pData->bMigrationSuccess ? WZB_FINISH : WZB_CANCEL );
break;
default:
@@ -261,21 +325,34 @@ namespace dbmm
//--------------------------------------------------------------------
IMPL_LINK( MacroMigrationDialog, OnStartMigration, void*, /*_pNotInterestedIn*/ )
{
+ // prevent closing
+ m_pData->bMigrationIsRunning = true;
+
// initialize migration engine and progress
ProgressPage& rProgressPage( dynamic_cast< ProgressPage& >( *GetPage( STATE_MIGRATE ) ) );
MigrationEngine aEngine( m_pData->aContext, m_pData->xDocument, rProgressPage, m_pData->aLogger );
rProgressPage.setDocumentCounts( aEngine.getFormCount(), aEngine.getReportCount() );
// do the migration
- bool bSuccess = aEngine.migrateAll();
+ m_pData->bMigrationSuccess = aEngine.migrateAll();
+ m_pData->bMigrationFailure = !m_pData->bMigrationSuccess;
// re-enable the UI
- enableButtons( ( bSuccess ? WZB_FINISH | WZB_NEXT : 0 ), true );
- enableState( STATE_SUMMARY, bSuccess );
+ enableButtons( WZB_FINISH | WZB_NEXT, true );
+ enableState( STATE_SUMMARY, true );
updateTravelUI();
m_pData->bMigrationIsRunning = false;
+ if ( m_pData->bMigrationSuccess )
+ {
+ rProgressPage.onFinishedSuccessfully();
+ }
+ else
+ { // if there was an error, show the summary automatically
+ travelNext();
+ }
+
// outta here
return 0L;
}
@@ -301,16 +378,12 @@ namespace dbmm
bool bSuccess = true;
try
{
- ::std::vector< Reference< XController > > aControllers;
-
// collect all controllers of our document
- Reference< XModel2 > xDocument( m_pData->xDocument, UNO_QUERY_THROW );
- Reference< XEnumeration > xControllerEnum( xDocument->getControllers(), UNO_SET_THROW );
- while ( xControllerEnum->hasMoreElements() )
- aControllers.push_back( Reference< XController >( xControllerEnum->nextElement(), UNO_QUERY_THROW ) );
+ ::std::list< Reference< XController2 > > aControllers;
+ lcl_getControllers_throw( m_pData->xDocumentModel, aControllers );
// close all sub documents of all controllers
- for ( ::std::vector< Reference< XController > >::const_iterator pos = aControllers.begin();
+ for ( ::std::list< Reference< XController2 > >::const_iterator pos = aControllers.begin();
pos != aControllers.end() && bSuccess;
++pos
)
@@ -336,16 +409,64 @@ namespace dbmm
}
//--------------------------------------------------------------------
+ namespace
+ {
+ bool lcl_equalURLs_nothrow( const ::rtl::OUString& _lhs, const ::rtl::OUString _rhs )
+ {
+ // the cheap situation: the URLs are equal
+ if ( _lhs == _rhs )
+ return true;
+
+ bool bEqual = true;
+ try
+ {
+ ::ucbhelper::Content aContentLHS = ::ucbhelper::Content( _lhs, Reference< XCommandEnvironment >() );
+ ::ucbhelper::Content aContentRHS = ::ucbhelper::Content( _rhs, Reference< XCommandEnvironment >() );
+ Reference< XContent > xContentLHS( aContentLHS.get(), UNO_SET_THROW );
+ Reference< XContent > xContentRHS( aContentRHS.get(), UNO_SET_THROW );
+ Reference< XContentIdentifier > xID1( xContentLHS->getIdentifier(), UNO_SET_THROW );
+ Reference< XContentIdentifier > xID2( xContentRHS->getIdentifier(), UNO_SET_THROW );
+
+ ::ucbhelper::ContentBroker* pBroker = ::ucbhelper::ContentBroker::get();
+ Reference< XContentProvider > xProvider(
+ pBroker ? pBroker->getContentProviderInterface() : Reference< XContentProvider >(), UNO_SET_THROW );
+
+ bEqual = ( 0 == xProvider->compareContentIds( xID1, xID2 ) );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ return bEqual;
+ }
+ }
+
+ //--------------------------------------------------------------------
bool MacroMigrationDialog::impl_backupDocument_nothrow() const
{
- const SaveDBDocPage& rBackupPage = dynamic_cast< const SaveDBDocPage& >( *GetPage( STATE_BACKUP_DBDOC ) );
+ if ( !m_pData->xDocumentModel.is() )
+ // should never happen, but has been reported as assertion before
+ return false;
+
+ SaveDBDocPage& rBackupPage = dynamic_cast< SaveDBDocPage& >( *GetPage( STATE_BACKUP_DBDOC ) );
::rtl::OUString sBackupLocation( rBackupPage.getBackupLocation() );
Any aError;
try
{
+ // check that the backup location isn't the same as the document itself
+ if ( lcl_equalURLs_nothrow( sBackupLocation, m_pData->xDocumentModel->getURL() ) )
+ {
+ ErrorBox aErrorBox( const_cast< MacroMigrationDialog* >( this ), MacroMigrationResId( ERR_INVALID_BACKUP_LOCATION ) );
+ aErrorBox.Execute();
+ rBackupPage.grabLocationFocus();
+ return false;
+ }
+
+ // store to the backup location
const Reference< XStorable > xDocument( getDocument(), UNO_QUERY_THROW );
xDocument->storeToURL( sBackupLocation, Sequence< PropertyValue >() );
+ m_pData->sSuccessfulBackupLocation = sBackupLocation;
}
catch( const Exception& )
{
@@ -359,13 +480,152 @@ namespace dbmm
}
// display the error to the user
- DocumentErrorHandling::reportError( m_pData->aContext, m_pData->xDocument, aError );
+ InteractionHandler aHandler( m_pData->aContext, m_pData->xDocumentModel.get() );
+ aHandler.reportError( aError );
- // TODO: log the error
+ m_pData->aLogger.logFailure( MigrationError(
+ ERR_DOCUMENT_BACKUP_FAILED,
+ sBackupLocation,
+ aError
+ ) );
return false;
}
+ //--------------------------------------------------------------------
+ void MacroMigrationDialog::impl_reloadDocument_nothrow( bool _bMigrationSuccess )
+ {
+ typedef ::std::pair< Reference< XFrame >, ::rtl::OUString > ViewDescriptor;
+ ::std::list< ViewDescriptor > aViews;
+
+ try
+ {
+ // the information which is necessary to reload the document
+ ::rtl::OUString sDocumentURL ( m_pData->xDocumentModel->getURL() );
+ ::comphelper::NamedValueCollection aDocumentArgs( m_pData->xDocumentModel->getArgs() );
+ if ( !_bMigrationSuccess )
+ {
+ // if the migration was not successful, then reload from the backup
+ aDocumentArgs.put( "SalvagedFile", m_pData->sSuccessfulBackupLocation );
+ // reset the modified flag of the document, so the controller can be suspended later
+ Reference< XModifiable > xModify( m_pData->xDocument, UNO_QUERY_THROW );
+ xModify->setModified( sal_False );
+ // after this reload, don't show the migration warning, again
+ aDocumentArgs.put( "SuppressMigrationWarning", sal_Bool(sal_True) );
+ }
+
+ // remove anything from the args which might refer to the old document
+ aDocumentArgs.remove( "Model" );
+ aDocumentArgs.remove( "Stream" );
+ aDocumentArgs.remove( "InputStream" );
+ aDocumentArgs.remove( "FileName" );
+ aDocumentArgs.remove( "URL" );
+
+ // collect all controllers of our document
+ ::std::list< Reference< XController2 > > aControllers;
+ lcl_getControllers_throw( m_pData->xDocumentModel, aControllers );
+
+ // close all those controllers
+ while ( !aControllers.empty() )
+ {
+ Reference< XController2 > xController( aControllers.front(), UNO_SET_THROW );
+ aControllers.pop_front();
+
+ Reference< XFrame > xFrame( xController->getFrame(), UNO_SET_THROW );
+ ::rtl::OUString sViewName( xController->getViewControllerName() );
+
+ if ( !xController->suspend( sal_True ) )
+ { // ouch. There shouldn't be any modal dialogs and such, so there
+ // really is no reason why suspending shouldn't work.
+ OSL_ENSURE( false, "MacroMigrationDialog::impl_reloadDocument_nothrow: could not suspend a controller!" );
+ // ignoring this would be at the cost of a crash (potentially)
+ // so, we cannot continue here.
+ throw CloseVetoException();
+ }
+
+ aViews.push_back( ViewDescriptor( xFrame, sViewName ) );
+ xFrame->setComponent( NULL, NULL );
+ xController->dispose();
+ }
+
+ // Note the document is closed now - disconnecting the last controller
+ // closes it automatically.
+
+ Reference< XOfficeDatabaseDocument > xNewDocument;
+
+ // re-create the views
+ while ( !aViews.empty() )
+ {
+ ViewDescriptor aView( aViews.front() );
+ aViews.pop_front();
+
+ // load the document into this frame
+ Reference< XComponentLoader > xLoader( aView.first, UNO_QUERY_THROW );
+ aDocumentArgs.put( "ViewName", aView.second );
+ Reference< XInterface > xReloaded( xLoader->loadComponentFromURL(
+ sDocumentURL,
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_self" ) ),
+ 0,
+ aDocumentArgs.getPropertyValues()
+ ) );
+
+ OSL_ENSURE( xReloaded != m_pData->xDocumentModel,
+ "MacroMigrationDialog::impl_reloadDocument_nothrow: this should have been a new instance!" );
+ // this would be unexpected, but recoverable: The loader should at least have done
+ // this: really *load* the document, even if it loaded it into the old document instance
+ if ( !xNewDocument.is() )
+ {
+ xNewDocument.set( xReloaded, UNO_QUERY_THROW );
+ // for subsequent loads, into different frames, put the document into the load args
+ aDocumentArgs.put( "Model", xNewDocument );
+ }
+ #if OSL_DEBUG_LEVEL > 0
+ else
+ {
+ OSL_ENSURE( xNewDocument == xReloaded,
+ "MacroMigrationDialog::impl_reloadDocument_nothrow: unexpected: subsequent load attempt returned a wrong document!" );
+ }
+ #endif
+ }
+
+ m_pData->xDocument = xNewDocument;
+ m_pData->xDocumentModel.set( xNewDocument, UNO_QUERY );
+
+ // finally, now that the document has been reloaded - if the migration was not successful,
+ // then it was reloaded from the backup, but the real document still is broken. So, save
+ // the document once, which will write the content loaded from the backup to the real docfile.
+ if ( !_bMigrationSuccess )
+ {
+ Reference< XModifiable > xModify( m_pData->xDocument, UNO_QUERY_THROW );
+ xModify->setModified( sal_True );
+ // this is just parnoia - in case saving the doc fails, perhaps the user is tempted to do so
+ Reference< XStorable > xStor( m_pData->xDocument, UNO_QUERY_THROW );
+ xStor->store();
+ }
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+
+ // close all frames from aViews - the respective controllers have been closed, but
+ // reloading didn't work, so the frames are zombies now.
+ while ( !aViews.empty() )
+ {
+ ViewDescriptor aView( aViews.front() );
+ aViews.pop_front();
+ try
+ {
+ Reference< XCloseable > xFrameClose( aView.first, UNO_QUERY_THROW );
+ xFrameClose->close( sal_True );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+ }
+
//........................................................................
} // namespace dbmm
//........................................................................
diff --git a/dbaccess/source/ext/macromigration/macromigrationdialog.hxx b/dbaccess/source/ext/macromigration/macromigrationdialog.hxx
index 2fb747bcf..e3f3d100d 100644
--- a/dbaccess/source/ext/macromigration/macromigrationdialog.hxx
+++ b/dbaccess/source/ext/macromigration/macromigrationdialog.hxx
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: macromigrationdialog.hxx,v $
- * $Revision: 1.3 $
+ * $Revision: 1.3.2.1 $
*
* This file is part of OpenOffice.org.
*
@@ -75,11 +75,13 @@ namespace dbmm
// Dialog overridables
virtual BOOL Close();
+ virtual short Execute();
private:
void impl_showCloseDocsError( bool _bShow );
bool impl_closeSubDocs_nothrow();
bool impl_backupDocument_nothrow() const;
+ void impl_reloadDocument_nothrow( bool _bMigrationSuccess );
private:
DECL_LINK( OnStartMigration, void* );
diff --git a/dbaccess/source/ext/macromigration/macromigrationpages.cxx b/dbaccess/source/ext/macromigration/macromigrationpages.cxx
index 137414beb..79273fd59 100644
--- a/dbaccess/source/ext/macromigration/macromigrationpages.cxx
+++ b/dbaccess/source/ext/macromigration/macromigrationpages.cxx
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: macromigrationpages.cxx,v $
- * $Revision: 1.3 $
+ * $Revision: 1.3.2.4 $
*
* This file is part of OpenOffice.org.
*
@@ -43,6 +43,7 @@
#include <tools/urlobj.hxx>
#include <tools/diagnose_ex.h>
+#include <vcl/metric.hxx>
//........................................................................
namespace dbmm
@@ -216,8 +217,8 @@ namespace dbmm
,m_aObjectCount ( this, MacroMigrationResId( FT_OBJECT_COUNT ) )
,m_aCurrentObjectLabel ( this, MacroMigrationResId( FT_CURRENT_OBJECT_LABEL ) )
,m_aCurrentObject ( this, MacroMigrationResId( FT_CURRENT_OBJECT ) )
- ,m_aCurrentActionLabel ( this, MacroMigrationResId( FT_CURRENT_PROGRESS_LABEL ) )
- ,m_aCurrentAction ( this, MacroMigrationResId( FT_CURRENT_PROGRESS ) )
+ ,m_aCurrentActionLabel ( this, MacroMigrationResId( FT_CURRENT_PROGRESS_LABEL ) )
+ ,m_aCurrentAction ( this, MacroMigrationResId( FT_CURRENT_PROGRESS ) )
,m_aCurrentProgress ( this, MacroMigrationResId( WND_CURRENT_PROGRESS ) )
,m_aAllProgressLabel ( this, MacroMigrationResId( FT_ALL_PROGRESS_LABEL ) )
,m_aAllProgressText ( this, MacroMigrationResId( FT_OBJECT_COUNT_PROGRESS ) )
@@ -243,6 +244,12 @@ namespace dbmm
}
//--------------------------------------------------------------------
+ void ProgressPage::onFinishedSuccessfully()
+ {
+ m_aMigrationDone.Show();
+ }
+
+ //--------------------------------------------------------------------
void ProgressPage::startObject( const ::rtl::OUString& _rObjectName, const ::rtl::OUString& _rCurrentAction, const sal_uInt32 _nRange )
{
m_aCurrentObject.SetText( _rObjectName );
@@ -252,6 +259,8 @@ namespace dbmm
// since this is currently called from the main thread, which does not have the chance
// to re-schedule, we need to explicitly update the display
+ m_aCurrentObject.Update();
+ m_aCurrentAction.Update();
Update();
}
@@ -259,6 +268,7 @@ namespace dbmm
void ProgressPage::setObjectProgressText( const ::rtl::OUString& _rText )
{
m_aCurrentAction.SetText( _rText );
+ m_aCurrentAction.Update();
Update();
}
@@ -272,9 +282,9 @@ namespace dbmm
//--------------------------------------------------------------------
void ProgressPage::endObject()
{
- m_aCurrentObject.SetText( String() );
m_aCurrentAction.SetText( String() );
- m_aCurrentProgress.SetValue( (sal_uInt32)0 );
+ m_aCurrentProgress.SetValue( m_aCurrentProgress.GetRange() );
+ m_aCurrentAction.Update();
Update();
}
@@ -307,6 +317,8 @@ namespace dbmm
:MacroMigrationPage( _rParentDialog, MacroMigrationResId( TP_SUMMARY ) )
,m_aChangesLabel( this, MacroMigrationResId( FT_CHANGES_LABEL ) )
,m_aChanges ( this, MacroMigrationResId( ED_CHANGES ) )
+ ,m_aSuccessful ( MacroMigrationResId( STR_SUCCESSFUL ) )
+ ,m_aUnsuccessful( MacroMigrationResId( STR_UNSUCCESSFUL ) )
{
FreeResource();
}
@@ -318,9 +330,30 @@ namespace dbmm
}
//--------------------------------------------------------------------
- void ResultPage::displaySummary( const String& _rSummary )
+ void ResultPage::displayMigrationLog( const bool _bSuccessful, const String& _rSummary )
{
+ m_aChangesLabel.SetText( _bSuccessful ? m_aSuccessful : m_aUnsuccessful );
m_aChanges.SetText( _rSummary );
+
+ // resize m_aChangesLabel and m_aChances as needed for the label text to fit
+ Rectangle aOriginalLabelSize( m_aChangesLabel.GetPosPixel(), m_aChangesLabel.GetSizePixel() );
+ // assume 3 lines, at most
+ Rectangle aNewLabelSize( aOriginalLabelSize );
+ aNewLabelSize.Bottom() = aNewLabelSize.Top() + m_aChangesLabel.LogicToPixel( Size( 0, 3*8 ), MAP_APPFONT ).Height();
+ TextRectInfo aInfo;
+ aNewLabelSize = m_aChangesLabel.GetTextRect( aNewLabelSize, m_aChangesLabel.GetText(), TEXT_DRAW_MULTILINE | TEXT_DRAW_WORDBREAK, &aInfo );
+ aNewLabelSize.Bottom() = aNewLabelSize.Top() + m_aChangesLabel.LogicToPixel( Size( 0, aInfo.GetLineCount() * 8 ), MAP_APPFONT ).Height();
+
+ m_aChangesLabel.SetSizePixel( aNewLabelSize.GetSize() );
+
+ long nChangesDiff = aNewLabelSize.GetHeight() - aOriginalLabelSize.GetHeight();
+ Size aChangesSize( m_aChanges.GetSizePixel() );
+ aChangesSize.Height() -= nChangesDiff;
+ m_aChanges.SetSizePixel( aChangesSize );
+
+ Point aChangesPos( m_aChanges.GetPosPixel() );
+ aChangesPos.Y() += nChangesDiff;
+ m_aChanges.SetPosPixel( aChangesPos );
}
//........................................................................
diff --git a/dbaccess/source/ext/macromigration/macromigrationpages.hxx b/dbaccess/source/ext/macromigration/macromigrationpages.hxx
index d6b7ce28c..0a7063727 100644
--- a/dbaccess/source/ext/macromigration/macromigrationpages.hxx
+++ b/dbaccess/source/ext/macromigration/macromigrationpages.hxx
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: macromigrationpages.hxx,v $
- * $Revision: 1.3 $
+ * $Revision: 1.3.2.3 $
*
* This file is part of OpenOffice.org.
*
@@ -100,6 +100,7 @@ namespace dbmm
public:
::rtl::OUString getBackupLocation() const { return m_aLocationController.getURL(); }
+ void grabLocationFocus() { m_aSaveAsLocation.GrabFocus(); }
protected:
FixedText m_aExplanation;
@@ -133,6 +134,7 @@ namespace dbmm
static TabPage* Create( ::svt::RoadmapWizard& _rParentDialog );
void setDocumentCounts( const sal_Int32 _nForms, const sal_Int32 _nReports );
+ void onFinishedSuccessfully();
protected:
// IMigrationProgress
@@ -167,11 +169,13 @@ namespace dbmm
static TabPage* Create( ::svt::RoadmapWizard& _rParentDialog );
- void displaySummary( const String& _rSummary );
+ void displayMigrationLog( const bool _bSuccessful, const String& _rLog );
private:
FixedText m_aChangesLabel;
MultiLineEdit m_aChanges;
+ String m_aSuccessful;
+ String m_aUnsuccessful;
};
//........................................................................
diff --git a/dbaccess/source/ext/macromigration/macromigrationwizard.cxx b/dbaccess/source/ext/macromigration/macromigrationwizard.cxx
index 1419f8899..77643b8c1 100644
--- a/dbaccess/source/ext/macromigration/macromigrationwizard.cxx
+++ b/dbaccess/source/ext/macromigration/macromigrationwizard.cxx
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: macromigrationwizard.cxx,v $
- * $Revision: 1.3 $
+ * $Revision: 1.3.2.2 $
*
* This file is part of OpenOffice.org.
*
@@ -37,6 +37,7 @@
/** === begin UNO includes === **/
#include <com/sun/star/ucb/AlreadyInitializedException.hpp>
#include <com/sun/star/sdb/XOfficeDatabaseDocument.hpp>
+#include <com/sun/star/frame/XStorable.hpp>
/** === end UNO includes === **/
#include <comphelper/componentcontext.hxx>
@@ -64,6 +65,7 @@ namespace dbmm
using ::com::sun::star::ucb::AlreadyInitializedException;
using ::com::sun::star::sdb::XOfficeDatabaseDocument;
using ::com::sun::star::lang::IllegalArgumentException;
+ using ::com::sun::star::frame::XStorable;
/** === end UNO using === **/
//====================================================================
@@ -209,7 +211,7 @@ namespace dbmm
if ( _rArguments.getLength() != 1 )
throw IllegalArgumentException(
::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Invalid number of initialization arguments. Expected 1." ) ),
- // TODO: resoource
+ // TODO: resource
*this,
1
);
@@ -223,6 +225,15 @@ namespace dbmm
1
);
+ Reference< XStorable > xDocStor( m_xDocument, UNO_QUERY_THROW );
+ if ( xDocStor->isReadonly() )
+ throw IllegalArgumentException(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Not applicable to read-only documents." ) ),
+ // TODO: resource
+ *this,
+ 1
+ );
+
m_bInitialized = true;
}
diff --git a/dbaccess/source/ext/macromigration/makefile.mk b/dbaccess/source/ext/macromigration/makefile.mk
index dba5395c3..3c833332f 100644
--- a/dbaccess/source/ext/macromigration/makefile.mk
+++ b/dbaccess/source/ext/macromigration/makefile.mk
@@ -8,7 +8,7 @@
#
# $RCSfile: makefile.mk,v $
#
-# $Revision: 1.3 $
+# $Revision: 1.3.2.4 $
#
# This file is part of OpenOffice.org.
#
@@ -56,9 +56,11 @@ SLOFILES= $(SLO)$/macromigrationwizard.obj \
$(SLO)$/dbmm_module.obj \
$(SLO)$/dbmm_services.obj \
$(SLO)$/migrationengine.obj \
- $(SLO)$/docerrorhandling.obj \
+ $(SLO)$/docinteraction.obj \
$(SLO)$/progresscapture.obj \
+ $(SLO)$/progressmixer.obj \
$(SLO)$/migrationlog.obj \
+ $(SLO)$/dbmm_types.obj \
# --- library -----------------------------------
@@ -75,7 +77,8 @@ SHL1STDLIBS= \
$(SVTOOLLIB) \
$(SVLLIB) \
$(VCLLIB) \
- $(SVXLIB)
+ $(SVXLIB) \
+ $(UCBHELPERLIB)
SHL1LIBS= $(SLB)$/$(TARGET).lib
SHL1IMPLIB= i$(TARGET)
diff --git a/dbaccess/source/ext/macromigration/migrationengine.cxx b/dbaccess/source/ext/macromigration/migrationengine.cxx
index 1e3bd0e65..eb3f3c976 100644
--- a/dbaccess/source/ext/macromigration/migrationengine.cxx
+++ b/dbaccess/source/ext/macromigration/migrationengine.cxx
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: migrationengine.cxx,v $
- * $Revision: 1.4 $
+ * $Revision: 1.4.2.14 $
*
* This file is part of OpenOffice.org.
*
@@ -34,11 +34,13 @@
#include "dbmm_global.hrc"
#include "dbmm_module.hxx"
#include "dbmm_types.hxx"
-#include "docerrorhandling.hxx"
+#include "docinteraction.hxx"
#include "migrationengine.hxx"
+#include "migrationerror.hxx"
#include "migrationprogress.hxx"
#include "migrationlog.hxx"
#include "progresscapture.hxx"
+#include "progressmixer.hxx"
/** === begin UNO includes === **/
#include <com/sun/star/sdb/XFormDocumentsSupplier.hpp>
@@ -48,16 +50,38 @@
#include <com/sun/star/frame/XComponentLoader.hpp>
#include <com/sun/star/ucb/XCommandProcessor.hpp>
#include <com/sun/star/embed/XComponentSupplier.hpp>
+#include <com/sun/star/embed/ElementModes.hpp>
+#include <com/sun/star/document/XStorageBasedDocument.hpp>
+#include <com/sun/star/embed/XTransactedObject.hpp>
+#include <com/sun/star/frame/XStorable.hpp>
+#include <com/sun/star/embed/XEmbedPersist.hpp>
+#include <com/sun/star/script/DocumentScriptLibraryContainer.hpp>
+#include <com/sun/star/script/DocumentDialogLibraryContainer.hpp>
+#include <com/sun/star/document/XEmbeddedScripts.hpp>
+#include <com/sun/star/document/XEventsSupplier.hpp>
+#include <com/sun/star/uri/UriReferenceFactory.hpp>
+#include <com/sun/star/uri/XVndSunStarScriptUrlReference.hpp>
+#include <com/sun/star/form/XFormsSupplier.hpp>
+#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
+#include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
+#include <com/sun/star/script/XEventAttacherManager.hpp>
+#include <com/sun/star/script/XLibraryContainerPassword.hpp>
/** === end UNO includes === **/
-#include <comphelper/string.hxx>
+#include <comphelper/documentinfo.hxx>
+#include <comphelper/interaction.hxx>
#include <comphelper/namedvaluecollection.hxx>
+#include <comphelper/string.hxx>
+#include <comphelper/types.hxx>
+#include <cppuhelper/exc_hlp.hxx>
#include <tools/string.hxx>
#include <tools/diagnose_ex.h>
#include <rtl/ustrbuf.hxx>
#include <rtl/ref.hxx>
+#include <unotools/sharedunocomponent.hxx>
#include <vector>
+#include <set>
#define DEFAULT_DOC_PROGRESS_RANGE 100000
@@ -90,19 +114,54 @@ namespace dbmm
using ::com::sun::star::ucb::Command;
using ::com::sun::star::embed::XComponentSupplier;
using ::com::sun::star::task::XStatusIndicator;
+ using ::com::sun::star::embed::XStorage;
+ using ::com::sun::star::document::XStorageBasedDocument;
+ using ::com::sun::star::embed::XTransactedObject;
+ using ::com::sun::star::frame::XStorable;
+ using ::com::sun::star::embed::XEmbedPersist;
+ using ::com::sun::star::script::DocumentDialogLibraryContainer;
+ using ::com::sun::star::script::DocumentScriptLibraryContainer;
+ using ::com::sun::star::script::XStorageBasedLibraryContainer;
+ using ::com::sun::star::document::XEmbeddedScripts;
+ using ::com::sun::star::container::XNameContainer;
+ using ::com::sun::star::document::XEventsSupplier;
+ using ::com::sun::star::container::XNameReplace;
+ using com::sun::star::uri::UriReferenceFactory;
+ using com::sun::star::uri::XUriReferenceFactory;
+ using com::sun::star::uri::XVndSunStarScriptUrlReference;
+ using ::com::sun::star::form::XFormsSupplier;
+ using ::com::sun::star::drawing::XDrawPageSupplier;
+ using ::com::sun::star::drawing::XDrawPagesSupplier;
+ using ::com::sun::star::drawing::XDrawPage;
+ using ::com::sun::star::drawing::XDrawPages;
+ using ::com::sun::star::container::XIndexAccess;
+ using ::com::sun::star::script::XEventAttacherManager;
+ using ::com::sun::star::script::ScriptEventDescriptor;
+ using ::com::sun::star::script::XLibraryContainerPassword;
/** === end UNO using === **/
+ namespace ElementModes = ::com::sun::star::embed::ElementModes;
+
+// migration phases whose progresses are to be mixed into one progress
+#define PHASE_JAVASCRIPT 1
+#define PHASE_BEANSHELL 2
+#define PHASE_PYTHON 3
+#define PHASE_JAVA 4
+#define PHASE_BASIC 5
+#define PHASE_DIALOGS 6
//====================================================================
//= SubDocument
//====================================================================
struct SubDocument
{
- Reference< XCommandProcessor > xCommandProcessor;
- ::rtl::OUString sHierarchicalName;
- SubDocumentType eType;
+ Reference< XCommandProcessor > xCommandProcessor;
+ Reference< XModel > xDocument; // valid only temporarily
+ ::rtl::OUString sHierarchicalName;
+ SubDocumentType eType;
SubDocument( const Reference< XCommandProcessor >& _rxCommandProcessor, const ::rtl::OUString& _rName, const SubDocumentType _eType )
:xCommandProcessor( _rxCommandProcessor )
+ ,xDocument()
,sHierarchicalName( _rName )
,eType( _eType )
{
@@ -112,6 +171,644 @@ namespace dbmm
typedef ::std::vector< SubDocument > SubDocuments;
//====================================================================
+ //= helper
+ //====================================================================
+ //--------------------------------------------------------------------
+ typedef ::utl::SharedUNOComponent< XStorage > SharedStorage;
+
+ namespace
+ {
+ //----------------------------------------------------------------
+ static const ::rtl::OUString& lcl_getScriptsStorageName()
+ {
+ static const ::rtl::OUString s_sScriptsStorageName( RTL_CONSTASCII_USTRINGPARAM( "Scripts" ) );
+ return s_sScriptsStorageName;
+ }
+
+ //----------------------------------------------------------------
+ static const ::rtl::OUString& lcl_getScriptsSubStorageName( const ScriptType _eType )
+ {
+ static const ::rtl::OUString s_sBeanShell ( RTL_CONSTASCII_USTRINGPARAM( "beanshell" ) );
+ static const ::rtl::OUString s_sJavaScript( RTL_CONSTASCII_USTRINGPARAM( "javascript" ) );
+ static const ::rtl::OUString s_sPython ( RTL_CONSTASCII_USTRINGPARAM( "python" ) ); // TODO: is this correct?
+ static const ::rtl::OUString s_sJava ( RTL_CONSTASCII_USTRINGPARAM( "java" ) );
+
+ switch ( _eType )
+ {
+ case eBeanShell: return s_sBeanShell;
+ case eJavaScript: return s_sJavaScript;
+ case ePython: return s_sPython;
+ case eJava: return s_sJava;
+ default:
+ break;
+ }
+
+ OSL_ENSURE( false, "lcl_getScriptsSubStorageName: illegal type!" );
+ static ::rtl::OUString s_sEmpty;
+ return s_sEmpty;
+ }
+
+ //----------------------------------------------------------------
+ static bool lcl_getScriptTypeFromLanguage( const ::rtl::OUString& _rLanguage, ScriptType& _out_rScriptType )
+ {
+ struct LanguageMapping
+ {
+ const sal_Char* pAsciiLanguage;
+ const ScriptType eScriptType;
+
+ LanguageMapping( const sal_Char* _pAsciiLanguage, const ScriptType _eScriptType )
+ :pAsciiLanguage( _pAsciiLanguage )
+ ,eScriptType( _eScriptType )
+ {
+ }
+ }
+ aLanguageMapping[] =
+ {
+ LanguageMapping( "JavaScript", eJavaScript ),
+ LanguageMapping( "BeanShell", eBeanShell ),
+ LanguageMapping( "Java", eJava ),
+ LanguageMapping( "Python", ePython ), // TODO: is this correct?
+ LanguageMapping( "Basic", eBasic )
+ };
+ for ( size_t i=0; i < sizeof( aLanguageMapping ) / sizeof( aLanguageMapping[0] ); ++i )
+ {
+ if ( _rLanguage.equalsAscii( aLanguageMapping[i].pAsciiLanguage ) )
+ {
+ _out_rScriptType = aLanguageMapping[i].eScriptType;
+ return true;
+ }
+ }
+ OSL_ENSURE( false, "lcl_getScriptTypeFromLanguage: unknown language!" );
+ return false;
+ }
+
+ //----------------------------------------------------------------
+ ::rtl::OUString lcl_getSubDocumentDescription( const SubDocument& _rDocument )
+ {
+ ::rtl::OUString sObjectName = String( MacroMigrationResId( _rDocument.eType == eForm ? STR_FORM : STR_REPORT ) );
+ ::comphelper::string::searchAndReplaceAsciiI( sObjectName, "$name$", _rDocument.sHierarchicalName );
+ return sObjectName;
+ }
+
+ //----------------------------------------------------------------
+ static Any lcl_executeCommand_throw( const Reference< XCommandProcessor >& _rxCommandProc,
+ const sal_Char* _pAsciiCommand )
+ {
+ OSL_PRECOND( _rxCommandProc.is(), "lcl_executeCommand_throw: illegal object!" );
+ if ( !_rxCommandProc.is() )
+ return Any();
+
+ Command aCommand;
+ aCommand.Name = ::rtl::OUString::createFromAscii( _pAsciiCommand );
+ return _rxCommandProc->execute(
+ aCommand, _rxCommandProc->createCommandIdentifier(), NULL );
+ }
+
+ //----------------------------------------------------------------
+ static bool lcl_loadSubDocument_nothrow( SubDocument& _rDocument,
+ const Reference< XStatusIndicator >& _rxProgress, MigrationLog& _rLogger )
+ {
+ OSL_PRECOND( !_rDocument.xDocument.is(), "lcl_loadSubDocument_nothrow: already loaded!" );
+
+ try
+ {
+ ::comphelper::NamedValueCollection aLoadArgs;
+ aLoadArgs.put( "Hidden", (sal_Bool)sal_True );
+ aLoadArgs.put( "StatusIndicator", _rxProgress );
+
+ Reference< XCommandProcessor > xCommandProcessor( _rDocument.xCommandProcessor, UNO_SET_THROW );
+ Command aCommand;
+ aCommand.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "openDesign" ) );
+ aCommand.Argument <<= aLoadArgs.getPropertyValues();
+ Reference< XComponent > xDocComponent(
+ xCommandProcessor->execute(
+ aCommand, xCommandProcessor->createCommandIdentifier(), NULL
+ ),
+ UNO_QUERY
+ );
+ OSL_ENSURE( xDocComponent.is(), "lcl_loadSubDocument_nothrow: no component loaded!" );
+
+ _rDocument.xDocument.set( xDocComponent, UNO_QUERY_THROW );
+ }
+ catch( const Exception& )
+ {
+ _rLogger.logFailure( MigrationError(
+ ERR_OPENING_SUB_DOCUMENT_FAILED,
+ lcl_getSubDocumentDescription( _rDocument ),
+ ::cppu::getCaughtException()
+ ) );
+ }
+ return _rDocument.xDocument.is();
+ }
+
+ //----------------------------------------------------------------
+ static bool lcl_unloadSubDocument_nothrow( SubDocument& _rDocument, MigrationLog& _rLogger )
+ {
+ bool bSuccess = false;
+ Any aException;
+ try
+ {
+ OSL_VERIFY( lcl_executeCommand_throw( _rDocument.xCommandProcessor, "close" ) >>= bSuccess );
+ }
+ catch( const Exception& )
+ {
+ aException = ::cppu::getCaughtException();
+ }
+
+ // log the failure, if any
+ if ( !bSuccess )
+ {
+ _rLogger.logFailure( MigrationError(
+ ERR_CLOSING_SUB_DOCUMENT_FAILED,
+ lcl_getSubDocumentDescription( _rDocument ),
+ aException
+ ) );
+ }
+
+ _rDocument.xDocument.clear();
+ return bSuccess;
+ }
+
+ //----------------------------------------------------------------
+ bool lcl_commitStorage_nothrow( const Reference< XStorage >& _rxStorage )
+ {
+ try
+ {
+ Reference< XTransactedObject > xTrans( _rxStorage, UNO_QUERY_THROW );
+ xTrans->commit();
+ }
+ catch( const Exception& )
+ {
+ return false;
+ }
+ return true;
+ }
+
+ //----------------------------------------------------------------
+ bool lcl_commitDocumentStorage_nothrow( const Reference< XModel >& _rxDocument, MigrationLog& _rLogger )
+ {
+ bool bSuccess = false;
+ Any aException;
+ try
+ {
+ Reference< XStorageBasedDocument > xStorageDoc( _rxDocument, UNO_QUERY_THROW );
+ Reference< XStorage > xDocStorage( xStorageDoc->getDocumentStorage(), UNO_QUERY_THROW );
+ bSuccess = lcl_commitStorage_nothrow( xDocStorage );
+ }
+ catch( const Exception& )
+ {
+ aException = ::cppu::getCaughtException();
+ }
+
+ // log the failure, if any
+ if ( !bSuccess )
+ {
+ _rLogger.logFailure( MigrationError(
+ ERR_STORAGE_COMMIT_FAILED,
+ ::comphelper::DocumentInfo::getDocumentTitle( _rxDocument ),
+ aException
+ ) );
+ }
+ return bSuccess;
+ }
+
+ //----------------------------------------------------------------
+ bool lcl_storeDocument_nothrow( const Reference< XModel >& _rxDocument, MigrationLog& _rLogger )
+ {
+ bool bSuccess = false;
+ Any aException;
+ try
+ {
+ Reference< XStorable > xStorable( _rxDocument, UNO_QUERY_THROW );
+ xStorable->store();
+ bSuccess = true;
+ }
+ catch( const Exception& )
+ {
+ aException = ::cppu::getCaughtException();
+ }
+
+ // log the failure, if any
+ if ( !bSuccess )
+ {
+ _rLogger.logFailure( MigrationError(
+ ERR_STORING_DATABASEDOC_FAILED,
+ aException
+ ) );
+ }
+ return bSuccess;
+ }
+
+ //----------------------------------------------------------------
+ bool lcl_storeEmbeddedDocument_nothrow( const SubDocument& _rDocument )
+ {
+ try
+ {
+ lcl_executeCommand_throw( _rDocument.xCommandProcessor, "store" );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ return false;
+ }
+ return true;
+ }
+ }
+
+ //====================================================================
+ //= DrawPageIterator
+ //====================================================================
+ class DrawPageIterator
+ {
+ public:
+ DrawPageIterator( const Reference< XModel >& _rxDocument )
+ :m_xDocument( _rxDocument )
+ ,m_nPageCount( 0 )
+ ,m_nCurrentPage( 0 )
+ {
+ Reference< XDrawPageSupplier > xSingle( _rxDocument, UNO_QUERY );
+ Reference< XDrawPagesSupplier > xMulti( _rxDocument, UNO_QUERY );
+ if ( xSingle.is() )
+ {
+ m_xSinglePage.set( xSingle->getDrawPage(), UNO_SET_THROW );
+ m_nPageCount = 1;
+ }
+ else if ( xMulti.is() )
+ {
+ m_xMultiPages.set( xMulti->getDrawPages(), UNO_SET_THROW );
+ m_nPageCount = m_xMultiPages->getCount();
+ }
+ }
+
+ bool hasMore() const
+ {
+ return m_nCurrentPage < m_nPageCount;
+ }
+
+ Reference< XDrawPage > next()
+ {
+ Reference< XDrawPage > xNextPage;
+
+ if ( m_xSinglePage.is() )
+ {
+ xNextPage = m_xSinglePage;
+ }
+ else if ( m_xMultiPages.is() )
+ {
+ xNextPage.set( m_xMultiPages->getByIndex( m_nCurrentPage ), UNO_QUERY_THROW );
+ }
+ ++m_nCurrentPage;
+ return xNextPage;
+ }
+
+ private:
+ const Reference< XModel > m_xDocument;
+ Reference< XDrawPage > m_xSinglePage;
+ Reference< XDrawPages > m_xMultiPages;
+ sal_Int32 m_nPageCount;
+ sal_Int32 m_nCurrentPage;
+ };
+
+ //====================================================================
+ //= FormComponentScripts
+ //====================================================================
+ class FormComponentScripts
+ {
+ public:
+ FormComponentScripts(
+ const Reference< XInterface >& _rxComponent,
+ const Reference< XEventAttacherManager >& _rxManager,
+ const sal_Int32 _nIndex
+ )
+ :m_xComponent( _rxComponent, UNO_SET_THROW )
+ ,m_xManager( _rxManager, UNO_SET_THROW )
+ ,m_nIndex( _nIndex )
+ {
+ }
+
+ Sequence< ScriptEventDescriptor > getEvents() const
+ {
+ return m_xManager->getScriptEvents( m_nIndex );
+ }
+
+ void setEvents( const Sequence< ScriptEventDescriptor >& _rEvents ) const
+ {
+ m_xManager->registerScriptEvents( m_nIndex, _rEvents );
+ }
+
+ const Reference< XInterface >& getComponent() const
+ {
+ return m_xComponent;
+ }
+
+ private:
+ const Reference< XInterface > m_xComponent;
+ const Reference< XEventAttacherManager > m_xManager;
+ const sal_Int32 m_nIndex;
+ };
+
+ //====================================================================
+ //= FormComponentIterator
+ //====================================================================
+ class FormComponentIterator
+ {
+ public:
+ FormComponentIterator( const Reference< XIndexAccess >& _rxContainer )
+ :m_xContainer( _rxContainer, UNO_SET_THROW )
+ ,m_xEventManager( _rxContainer, UNO_QUERY_THROW )
+ ,m_nElementCount( _rxContainer->getCount() )
+ ,m_nCurrentElement( 0 )
+ {
+ }
+
+ bool hasMore() const
+ {
+ return m_nCurrentElement < m_nElementCount;
+ }
+
+ FormComponentScripts next()
+ {
+ FormComponentScripts aComponent(
+ Reference< XInterface >( m_xContainer->getByIndex( m_nCurrentElement ), UNO_QUERY_THROW ),
+ m_xEventManager,
+ m_nCurrentElement
+ );
+ ++m_nCurrentElement;
+ return aComponent;
+ }
+
+ private:
+ const Reference< XIndexAccess > m_xContainer;
+ const Reference< XEventAttacherManager > m_xEventManager;
+ const sal_Int32 m_nElementCount;
+ sal_Int32 m_nCurrentElement;
+
+ };
+
+ //====================================================================
+ //= ScriptsStorage - declaration
+ //====================================================================
+ /** a helper class which encapsulates access to the storages for Java/Script, BeanShell, and Python scripts,
+ i.e. all script types which can be manipulated on storage level.
+ */
+ class ScriptsStorage
+ {
+ public:
+ ScriptsStorage( MigrationLog& _rLogger );
+ ScriptsStorage( const Reference< XModel >& _rxDocument, MigrationLog& _rLogger );
+ ~ScriptsStorage();
+
+ /** determines whether the instance is valid, i.e. refers to a valid root storage
+ for reading/storing scripts
+ */
+ inline bool isValid() const { return m_xScriptsStorage.is(); }
+
+ /** binds the instance to a new document. Only to be called when the instance is not yet
+ bound (i.e. isValid returns <FALSE/>).
+ */
+ void bind( const Reference< XModel >& _rxDocument );
+
+ /// determines whether scripts of the given type are present
+ bool hasScripts( const ScriptType _eType ) const;
+
+ /// returns the root storage for the scripts of the given type
+ SharedStorage
+ getScriptsRoot( const ScriptType _eType ) const;
+
+ /** returns the names of the elements in the "Scripts" storage
+ */
+ ::std::set< ::rtl::OUString >
+ getElementNames() const;
+
+ /** removes the sub storage for a given script type
+ @precond
+ the respective storage is empty
+ @precond
+ the ScriptsStorage instance was opened for writing
+ */
+ void removeScriptTypeStorage( const ScriptType _eType ) const;
+
+ /** commits the changes at our XStorage object
+ */
+ bool commit();
+
+ /** removes the "Scripts" sub storage from the given document's root storage
+ @precond
+ the "Scripts" storage is empty
+ */
+ static bool
+ removeFromDocument( const Reference< XModel >& _rxDocument, MigrationLog& _rLogger );
+
+ private:
+ MigrationLog& m_rLogger;
+ SharedStorage m_xScriptsStorage;
+ };
+
+ //====================================================================
+ //= ScriptsStorage - implementation
+ //====================================================================
+ //--------------------------------------------------------------------
+ ScriptsStorage::ScriptsStorage( MigrationLog& _rLogger )
+ :m_rLogger( _rLogger )
+ ,m_xScriptsStorage()
+ {
+ }
+
+ //--------------------------------------------------------------------
+ ScriptsStorage::ScriptsStorage( const Reference< XModel >& _rxDocument, MigrationLog& _rLogger )
+ :m_rLogger( _rLogger )
+ ,m_xScriptsStorage()
+ {
+ bind( _rxDocument );
+ }
+
+ //--------------------------------------------------------------------
+ ScriptsStorage::~ScriptsStorage()
+ {
+ }
+
+ //--------------------------------------------------------------------
+ bool ScriptsStorage::commit()
+ {
+ return lcl_commitStorage_nothrow( m_xScriptsStorage );
+ }
+
+ //--------------------------------------------------------------------
+ void ScriptsStorage::bind( const Reference< XModel >& _rxDocument )
+ {
+ OSL_PRECOND( !isValid(), "ScriptsStorage:bind: did not bother, yet, to check whether this is allowed!" );
+ try
+ {
+ Reference< XStorageBasedDocument > xStorageDoc( _rxDocument, UNO_QUERY_THROW );
+ Reference< XStorage > xDocStorage( xStorageDoc->getDocumentStorage(), UNO_QUERY_THROW );
+
+ // the the "Scripts" storage exist, or if it does not (yet) exist and we are in write mode
+ // => open the storage
+ if ( ( xDocStorage->hasByName( lcl_getScriptsStorageName() )
+ && xDocStorage->isStorageElement( lcl_getScriptsStorageName() )
+ )
+ || !xDocStorage->hasByName( lcl_getScriptsStorageName() )
+ )
+ {
+ m_xScriptsStorage.set(
+ xDocStorage->openStorageElement(
+ lcl_getScriptsStorageName(), ElementModes::READWRITE
+ ),
+ UNO_QUERY_THROW
+ );
+ }
+ }
+ catch( const Exception& )
+ {
+ m_rLogger.logFailure( MigrationError(
+ ERR_BIND_SCRIPT_STORAGE_FAILED,
+ ::comphelper::DocumentInfo::getDocumentTitle( _rxDocument ),
+ ::cppu::getCaughtException()
+ ) );
+ }
+ }
+
+ //--------------------------------------------------------------------
+ bool ScriptsStorage::hasScripts( const ScriptType _eType ) const
+ {
+ OSL_PRECOND( isValid(), "ScriptsStorage::hasScripts: illegal call!" );
+ if ( !isValid() )
+ return false;
+
+ const ::rtl::OUString& rSubStorageName( lcl_getScriptsSubStorageName( _eType ) );
+ return m_xScriptsStorage->hasByName( rSubStorageName )
+ && m_xScriptsStorage->isStorageElement( rSubStorageName );
+ }
+
+ //--------------------------------------------------------------------
+ SharedStorage ScriptsStorage::getScriptsRoot( const ScriptType _eType ) const
+ {
+ SharedStorage xStorage;
+ if ( isValid() )
+ {
+ xStorage.reset( m_xScriptsStorage->openStorageElement(
+ lcl_getScriptsSubStorageName( _eType ), ElementModes::READWRITE
+ ) );
+ }
+ return xStorage;
+ }
+
+ //--------------------------------------------------------------------
+ ::std::set< ::rtl::OUString > ScriptsStorage::getElementNames() const
+ {
+ Sequence< ::rtl::OUString > aElementNames;
+ if ( isValid() )
+ aElementNames = m_xScriptsStorage->getElementNames();
+
+ ::std::set< ::rtl::OUString > aNames;
+ ::std::copy(
+ aElementNames.getConstArray(),
+ aElementNames.getConstArray() + aElementNames.getLength(),
+ ::std::insert_iterator< ::std::set< ::rtl::OUString > >( aNames, aNames.end() )
+ );
+ return aNames;
+ }
+
+ //--------------------------------------------------------------------
+ void ScriptsStorage::removeScriptTypeStorage( const ScriptType _eType ) const
+ {
+ ::rtl::OUString sSubStorageName( lcl_getScriptsSubStorageName( _eType ) );
+ if ( m_xScriptsStorage->hasByName( sSubStorageName ) )
+ m_xScriptsStorage->removeElement( sSubStorageName );
+ }
+
+ //--------------------------------------------------------------------
+ bool ScriptsStorage::removeFromDocument( const Reference< XModel >& _rxDocument, MigrationLog& _rLogger )
+ {
+ try
+ {
+ Reference< XStorageBasedDocument > xStorageDoc( _rxDocument, UNO_QUERY_THROW );
+ Reference< XStorage > xDocStorage( xStorageDoc->getDocumentStorage(), UNO_QUERY_THROW );
+ xDocStorage->removeElement( lcl_getScriptsStorageName() );
+ }
+ catch( const Exception& )
+ {
+ _rLogger.logFailure( MigrationError(
+ ERR_REMOVE_SCRIPTS_STORAGE_FAILED,
+ ::comphelper::DocumentInfo::getDocumentTitle( _rxDocument ),
+ ::cppu::getCaughtException()
+ ) ) ;
+ return false;
+ }
+ return true;
+ }
+
+ //====================================================================
+ //= ProgressDelegator
+ //====================================================================
+ class ProgressDelegator : public IProgressConsumer
+ {
+ public:
+ ProgressDelegator( IMigrationProgress& _rDelegator,
+ const ::rtl::OUString& _rObjectName,
+ const ::rtl::OUString& _rAction
+ )
+ :m_rDelegator( _rDelegator )
+ ,m_sObjectName( _rObjectName )
+ ,m_sAction( _rAction )
+ {
+ }
+ virtual ~ProgressDelegator()
+ {
+ }
+
+ // IProgressConsumer
+ virtual void start( sal_uInt32 _nRange )
+ {
+ m_rDelegator.startObject( m_sObjectName, m_sAction, _nRange );
+ }
+ virtual void advance( sal_uInt32 _nValue )
+ {
+ m_rDelegator.setObjectProgressValue( _nValue );
+ }
+ virtual void end()
+ {
+ m_rDelegator.endObject();
+ }
+
+ private:
+ IMigrationProgress& m_rDelegator;
+ ::rtl::OUString m_sObjectName;
+ ::rtl::OUString m_sAction;
+ };
+
+ //====================================================================
+ //= PhaseGuard
+ //====================================================================
+ class PhaseGuard
+ {
+ public:
+ PhaseGuard( ProgressMixer& _rMixer )
+ :m_rMixer( _rMixer )
+ {
+ }
+
+ PhaseGuard( ProgressMixer& _rMixer, const PhaseID _nID, const sal_uInt32 _nPhaseRange )
+ :m_rMixer( _rMixer )
+ {
+ start( _nID, _nPhaseRange );
+ }
+
+ ~PhaseGuard()
+ {
+ m_rMixer.endPhase();
+ }
+
+ void start( const PhaseID _nID, const sal_uInt32 _nPhaseRange )
+ {
+ m_rMixer.startPhase( _nID, _nPhaseRange );
+ }
+
+ private:
+ ProgressMixer& m_rMixer;
+ };
+
+ //====================================================================
//= MigrationEngine_Impl - declaration
//====================================================================
class MigrationEngine_Impl
@@ -132,8 +829,10 @@ namespace dbmm
private:
::comphelper::ComponentContext m_aContext;
const Reference< XOfficeDatabaseDocument > m_xDocument;
+ const Reference< XModel > m_xDocumentModel;
IMigrationProgress& m_rProgress;
MigrationLog& m_rLogger;
+ mutable DocumentID m_nCurrentDocumentID;
SubDocuments m_aSubDocs;
size_t m_nFormCount;
size_t m_nReportCount;
@@ -146,14 +845,79 @@ namespace dbmm
*/
bool impl_collectSubDocuments_nothrow();
- /** reports the given error (usually an exception caught on the caller's side)
- to the user, using the document's interaction handler, if any.
- */
- void impl_reportError_nothrow( const Any& _rError ) const;
-
/** migrates the macros/scripts of the given sub document
*/
bool impl_handleDocument_nothrow( const SubDocument& _rDocument ) const;
+
+ /** checks the structure of the 'Scripts' folder of a sub document
+ for unknown elements
+
+ @return
+ <TRUE/> if and only if the 'Scripts' folder contains known elements only.
+ */
+ bool impl_checkScriptStorageStructure_nothrow( const SubDocument& _rDocument ) const;
+
+ /** migrates the scripts of the given "storage-based" script type
+ */
+ bool impl_migrateScriptStorage_nothrow(
+ const SubDocument& _rDocument,
+ const ScriptType _eScriptType,
+ ProgressMixer& _rProgress,
+ const PhaseID _nPhaseID
+ ) const;
+
+ /** migrates the content of the given "container based" libraries (Basic/Dialogs)
+ */
+ bool impl_migrateContainerLibraries_nothrow(
+ const SubDocument& _rDocument,
+ const ScriptType _eScriptType,
+ ProgressMixer& _rProgress,
+ const PhaseID _nPhaseID
+ ) const;
+
+ /** adjust the document-events which refer to macros/scripts in the document, taking into
+ account the new names of the moved libraries
+ */
+ bool impl_adjustDocumentEvents_nothrow(
+ const SubDocument& _rDocument
+ ) const;
+
+ /** adjusts the script references bound to form component events
+ */
+ bool impl_adjustFormComponentEvents_nothrow(
+ const SubDocument& _rDocument
+ ) const;
+
+ /** adjusts the script references for the elements of the given form component container
+ */
+ void impl_adjustFormComponentEvents_throw(
+ const Reference< XIndexAccess >& _rxComponentContainer
+ ) const;
+
+ /** adjusts the library name in the given script URL, so that it reflects
+ the new name of the library
+
+ @return <TRUE/>
+ if and only if adjustments to the script code have been made
+ */
+ bool impl_adjustScriptLibrary_nothrow(
+ const ::rtl::OUString& _rScriptType,
+ ::rtl::OUString& _inout_rScriptCode
+ ) const;
+
+ bool impl_adjustScriptLibrary_nothrow( Any& _inout_rScriptDescriptor ) const;
+ bool impl_adjustScriptLibrary_nothrow( ScriptEventDescriptor& _inout_rScriptEvent ) const;
+
+ /** asks the user for a password for the given library, and unprotects the library
+
+ @return <TRUE/>
+ if and only if the library could be successfully unprotected
+ */
+ bool impl_unprotectPasswordLibrary_throw(
+ const Reference< XLibraryContainerPassword >& _rxPasswordManager,
+ const ScriptType _eScriptType,
+ const ::rtl::OUString& _rLibraryName
+ ) const;
};
//====================================================================
@@ -164,8 +928,10 @@ namespace dbmm
const Reference< XOfficeDatabaseDocument >& _rxDocument, IMigrationProgress& _rProgress, MigrationLog& _rLogger )
:m_aContext( _rContext )
,m_xDocument( _rxDocument )
+ ,m_xDocumentModel( _rxDocument, UNO_QUERY_THROW )
,m_rProgress( _rProgress )
,m_rLogger( _rLogger )
+ ,m_nCurrentDocumentID( - 1 )
,m_aSubDocs()
,m_nFormCount( 0 )
,m_nReportCount( 0 )
@@ -215,6 +981,14 @@ namespace dbmm
m_rProgress.setOverallProgressValue( nOverallProgressValue );
}
+ // commit the root storage of the database document, for all changes made so far to take effect
+ if ( !lcl_commitDocumentStorage_nothrow( m_xDocumentModel, m_rLogger ) )
+ return false;
+
+ // save the document
+ if ( !lcl_storeDocument_nothrow( m_xDocumentModel, m_rLogger ) )
+ return false;
+
return true;
}
@@ -263,141 +1037,744 @@ namespace dbmm
//--------------------------------------------------------------------
bool MigrationEngine_Impl::impl_collectSubDocuments_nothrow()
{
+ OSL_PRECOND( m_xDocument.is(), "MigrationEngine_Impl::impl_collectSubDocuments_nothrow: invalid document!" );
+ if ( !m_xDocument.is() )
+ return false;
+
try
{
- ::rtl::OUString sRootLocation;
-
- Reference< XFormDocumentsSupplier > xSuppForms( m_xDocument, UNO_QUERY_THROW );
- Reference< XNameAccess > xDocContainer( xSuppForms->getFormDocuments(), UNO_SET_THROW );
- m_nFormCount = lcl_collectHierarchicalElementNames_throw( xDocContainer, sRootLocation, m_aSubDocs, eForm );
+ Reference< XNameAccess > xDocContainer( m_xDocument->getFormDocuments(), UNO_SET_THROW );
+ m_nFormCount = lcl_collectHierarchicalElementNames_throw( xDocContainer, ::rtl::OUString(), m_aSubDocs, eForm );
- Reference< XReportDocumentsSupplier > xSuppReports( m_xDocument, UNO_QUERY_THROW );
- xDocContainer.set( xSuppReports->getReportDocuments(), UNO_SET_THROW );
- m_nReportCount = lcl_collectHierarchicalElementNames_throw( xDocContainer, sRootLocation, m_aSubDocs, eReport );
+ xDocContainer.set( m_xDocument->getReportDocuments(), UNO_SET_THROW );
+ m_nReportCount = lcl_collectHierarchicalElementNames_throw( xDocContainer, ::rtl::OUString(), m_aSubDocs, eReport );
}
catch( const Exception& )
{
- // TODO: check whether we can handle this error
- DBG_UNHANDLED_EXCEPTION();
+ m_rLogger.logFailure( MigrationError(
+ ERR_COLLECTING_DOCUMENTS_FAILED,
+ ::cppu::getCaughtException()
+ ) );
return false;
}
-
return true;
}
//--------------------------------------------------------------------
+ bool MigrationEngine_Impl::impl_handleDocument_nothrow( const SubDocument& _rDocument ) const
+ {
+ OSL_ENSURE( m_nCurrentDocumentID == -1,
+ "MigrationEngine_Impl::impl_handleDocument_nothrow: there already is a current document!");
+ m_nCurrentDocumentID = m_rLogger.startedDocument( _rDocument.eType, _rDocument.sHierarchicalName );
+
+ // start the progress
+ ::rtl::OUString sObjectName( lcl_getSubDocumentDescription( _rDocument ) );
+ m_rProgress.startObject( sObjectName, ::rtl::OUString(), DEFAULT_DOC_PROGRESS_RANGE );
+
+ // -----------------
+ // load the document
+ ::rtl::Reference< ProgressCapture > pStatusIndicator( new ProgressCapture( sObjectName, m_rProgress ) );
+ SubDocument aSubDocument( _rDocument );
+ if ( !lcl_loadSubDocument_nothrow( aSubDocument, pStatusIndicator.get(), m_rLogger ) )
+ {
+ pStatusIndicator->dispose();
+ m_rProgress.endObject();
+ m_rLogger.finishedDocument( m_nCurrentDocumentID );
+ m_nCurrentDocumentID = -1;
+ return false;
+ }
+
+ // -----------------
+ // migrate the libraries
+ ProgressDelegator aDelegator( m_rProgress, sObjectName, String( MacroMigrationResId( STR_MIGRATING_LIBS ) ) );
+ ProgressMixer aProgressMixer( aDelegator );
+ aProgressMixer.registerPhase( PHASE_JAVASCRIPT, 1 );
+ aProgressMixer.registerPhase( PHASE_BEANSHELL, 1 );
+ aProgressMixer.registerPhase( PHASE_PYTHON, 1 );
+ aProgressMixer.registerPhase( PHASE_JAVA, 1 );
+ aProgressMixer.registerPhase( PHASE_BASIC, 5 );
+ // more weight than then others, assuming that usually, there are much more Basic macros than any other scripts
+ aProgressMixer.registerPhase( PHASE_DIALOGS, 1 );
+
+ bool bSuccess = impl_checkScriptStorageStructure_nothrow( aSubDocument );
+
+ // migrate storage-based script libraries (which can be handled by mere storage operations)
+ bSuccess = bSuccess
+ && impl_migrateScriptStorage_nothrow( aSubDocument, eJavaScript, aProgressMixer, PHASE_JAVASCRIPT )
+ && impl_migrateScriptStorage_nothrow( aSubDocument, eBeanShell, aProgressMixer, PHASE_BEANSHELL )
+ && impl_migrateScriptStorage_nothrow( aSubDocument, ePython, aProgressMixer, PHASE_PYTHON )
+ && impl_migrateScriptStorage_nothrow( aSubDocument, eJava, aProgressMixer, PHASE_JAVA );
+
+ // migrate Basic and dialog libraries
+ bSuccess = bSuccess
+ && impl_migrateContainerLibraries_nothrow( aSubDocument, eBasic, aProgressMixer, PHASE_BASIC )
+ && impl_migrateContainerLibraries_nothrow( aSubDocument, eDialog, aProgressMixer, PHASE_DIALOGS );
+
+ // adjust the events in the document
+ // (note that errors are ignored here - failure to convert a script reference
+ // is not considered a critical error)
+ if ( bSuccess )
+ {
+ impl_adjustDocumentEvents_nothrow( aSubDocument );
+ impl_adjustFormComponentEvents_nothrow( aSubDocument );
+ }
+
+ // -----------------
+ // clean up
+ // store the sub document, including removal of the (now obsolete) "Scripts" sub folder
+ bSuccess = bSuccess
+ && ScriptsStorage::removeFromDocument( aSubDocument.xDocument, m_rLogger )
+ && lcl_commitDocumentStorage_nothrow( aSubDocument.xDocument, m_rLogger )
+ && lcl_storeEmbeddedDocument_nothrow( aSubDocument );
+
+ // unload in any case, even if we were not successful
+ bSuccess = lcl_unloadSubDocument_nothrow( aSubDocument, m_rLogger )
+ && bSuccess;
+
+ pStatusIndicator->dispose();
+
+ // end the progress, just in case the ProgressCapture didn't receive the XStatusIndicator::end event
+ m_rProgress.endObject();
+
+ m_rLogger.finishedDocument( m_nCurrentDocumentID );
+ m_nCurrentDocumentID = -1;
+ return bSuccess;
+ }
+
+ //--------------------------------------------------------------------
namespace
{
- //................................................................
- static void lcl_disposeComponent_nothrow( const Reference< XCommandProcessor >& _rxCommandProc )
+ static ::rtl::OUString lcl_createTargetLibName( const SubDocument& _rDocument,
+ const ::rtl::OUString& _rSourceLibName, const Reference< XNameAccess >& _rxTargetStorage )
{
- OSL_PRECOND( _rxCommandProc.is(), "lcl_disposeComponent_nothrow: illegal object!" );
- if ( !_rxCommandProc.is() )
- return;
+ // a prefix denoting the type
+ const ::rtl::OUString sPrefix( ::rtl::OUString::createFromAscii( _rDocument.eType == eForm ? "Form_" : "Report_" ) );
- bool bCouldClose = false;
- try
+ ::rtl::OUStringBuffer aBuffer;
+ aBuffer.append( sPrefix );
+
+ // first try with the base name of the sub document
+ aBuffer.append( _rDocument.sHierarchicalName.copy(
+ _rDocument.sHierarchicalName.lastIndexOf( '/' ) + 1 ) );
+ aBuffer.appendAscii( "_" );
+ aBuffer.append( _rSourceLibName );
+ ::rtl::OUString sTargetName( aBuffer.makeStringAndClear() );
+ if ( !_rxTargetStorage->hasByName( sTargetName ) )
+ return sTargetName;
+
+ // if this name is already used (which is valid, since documents with the same base
+ // name can exist in different logical folders), then use the complete name
+ aBuffer.append( sPrefix );
+ aBuffer.append( ::comphelper::string::searchAndReplaceAllAsciiWithAscii(
+ _rDocument.sHierarchicalName, "/", "_" ) );
+ aBuffer.appendAscii( "_" );
+ aBuffer.append( _rSourceLibName );
+ return aBuffer.makeStringAndClear();
+
+ }
+ }
+
+ //--------------------------------------------------------------------
+ bool MigrationEngine_Impl::impl_checkScriptStorageStructure_nothrow( const SubDocument& _rDocument ) const
+ {
+ OSL_PRECOND( _rDocument.xDocument.is(), "MigrationEngine_Impl::impl_checkScriptStorageStructure_nothrow: invalid document!" );
+ if ( !_rDocument.xDocument.is() )
+ return false;
+
+ try
+ {
+ // the root storage of the document whose scripts are to be migrated
+ ScriptsStorage aDocStorage( _rDocument.xDocument, m_rLogger );
+ if ( !aDocStorage.isValid() )
+ { // no scripts at all, or no scripts of the given type
+ return !m_rLogger.hadFailure();
+ }
+ ::std::set< ::rtl::OUString > aElementNames( aDocStorage.getElementNames() );
+
+ ScriptType aKnownStorageBasedTypes[] = {
+ eBeanShell, eJavaScript, ePython, eJava
+ };
+ for ( size_t i=0; i<sizeof( aKnownStorageBasedTypes ) / sizeof( aKnownStorageBasedTypes[0] ); ++i )
+ aElementNames.erase( lcl_getScriptsSubStorageName( aKnownStorageBasedTypes[i] ) );
+
+ if ( !aElementNames.empty() )
{
- Command aCommand;
- aCommand.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "shutdown" ) );
- OSL_VERIFY( _rxCommandProc->execute(
- aCommand, _rxCommandProc->createCommandIdentifier(), NULL ) >>= bCouldClose );
+ m_rLogger.logFailure( MigrationError(
+ ERR_UNKNOWN_SCRIPT_FOLDER,
+ lcl_getSubDocumentDescription( _rDocument ),
+ *aElementNames.begin()
+ ) );
+ return false;
}
- catch( const Exception& )
+ }
+ catch( const Exception& )
+ {
+ m_rLogger.logFailure( MigrationError(
+ ERR_EXAMINING_SCRIPTS_FOLDER_FAILED,
+ lcl_getSubDocumentDescription( _rDocument ),
+ ::cppu::getCaughtException()
+ ) );
+ return false;
+ }
+ return true;
+ }
+
+ //--------------------------------------------------------------------
+ bool MigrationEngine_Impl::impl_migrateScriptStorage_nothrow( const SubDocument& _rDocument,
+ const ScriptType _eScriptType, ProgressMixer& _rProgress, const PhaseID _nPhaseID ) const
+ {
+ OSL_PRECOND( _rDocument.xDocument.is(), "MigrationEngine_Impl::impl_migrateScriptStorage_nothrow: invalid document!" );
+ if ( !_rDocument.xDocument.is() )
+ return false;
+
+ ScriptsStorage aDatabaseScripts( m_rLogger );
+ // the scripts of our complete database document - created on demand only
+ SharedStorage xTargetStorage;
+ // the target for moving the scripts storages - created on demand only
+
+ PhaseGuard aPhase( _rProgress );
+ bool bSuccess = false;
+ Any aException;
+ try
+ {
+ // the root storage of the document whose scripts are to be migrated
+ ScriptsStorage aDocStorage( _rDocument.xDocument, m_rLogger );
+ if ( !aDocStorage.isValid()
+ || !aDocStorage.hasScripts( _eScriptType )
+ )
{
- DBG_UNHANDLED_EXCEPTION();
+ // no scripts at all, or no scripts of the given type
+ _rProgress.startPhase( _nPhaseID, 1 );
+ _rProgress.endPhase();
+ return !m_rLogger.hadFailure();
}
- if ( !bCouldClose )
+
+ SharedStorage xScriptsRoot( aDocStorage.getScriptsRoot( _eScriptType ) );
+ if ( !xScriptsRoot.is() )
+ throw RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "internal error" ) ), NULL );
+
+ // loop through the script libraries
+ Sequence< ::rtl::OUString > aStorageElements( xScriptsRoot->getElementNames() );
+ aPhase.start( _nPhaseID, aStorageElements.getLength() );
+
+ for ( const ::rtl::OUString* element = aStorageElements.getConstArray();
+ element != aStorageElements.getConstArray() + aStorageElements.getLength();
+ ++element
+ )
{
- ;
- // TODO: can we handle this somehow?
+ bool bIsScriptLibrary = xScriptsRoot->isStorageElement( *element );
+ OSL_ENSURE( bIsScriptLibrary,
+ "MigrationEngine_Impl::impl_migrateScriptStorage_nothrow: warning: unknown scripts storage structure!" );
+ // we cannot handle this. We would need to copy this stream to the respective scripts storage
+ // of the database document, but we cannot guarantee that the name is not used, yet, and we cannot
+ // simply rename the thing.
+ if ( !bIsScriptLibrary )
+ {
+ m_rLogger.logFailure( MigrationError(
+ ERR_UNEXPECTED_LIBSTORAGE_ELEMENT,
+ lcl_getSubDocumentDescription( _rDocument ),
+ getScriptTypeDisplayName( _eScriptType ),
+ *element
+ ) );
+ return false;
+ }
+
+ // ensure we have access to the DBDoc's scripts storage
+ if ( !aDatabaseScripts.isValid() )
+ { // not needed 'til now
+ aDatabaseScripts.bind( m_xDocumentModel );
+ if ( aDatabaseScripts.isValid() )
+ xTargetStorage = aDatabaseScripts.getScriptsRoot( _eScriptType );
+
+ if ( !xTargetStorage.is() )
+ {
+ m_rLogger.logFailure( MigrationError(
+ ERR_CREATING_DBDOC_SCRIPT_STORAGE_FAILED,
+ getScriptTypeDisplayName( _eScriptType )
+ ) );
+ return false;
+ }
+ }
+
+ // move the library to the DBDoc's scripts library, under the new name
+ ::rtl::OUString sNewLibName( lcl_createTargetLibName( _rDocument, *element, xTargetStorage.getTyped().get() ) );
+ xScriptsRoot->moveElementTo( *element, xTargetStorage, sNewLibName );
+
+ // log the fact that we moved the library
+ m_rLogger.movedLibrary( m_nCurrentDocumentID, _eScriptType, *element, sNewLibName );
+
+ // progress
+ _rProgress.advancePhase( element - aStorageElements.getConstArray() );
}
+
+ // commit the storages, so the changes we made persist
+ if ( !lcl_commitStorage_nothrow( xScriptsRoot )
+ || ( xTargetStorage.is() && !lcl_commitStorage_nothrow( xTargetStorage ) )
+ )
+ {
+ m_rLogger.logFailure( MigrationError(
+ ERR_COMMITTING_SCRIPT_STORAGES_FAILED,
+ lcl_getSubDocumentDescription( _rDocument ),
+ getScriptTypeDisplayName( _eScriptType )
+ ) );
+ return false;
+ }
+
+ // now that the concrete scripts storage does not have any elements anymore,
+ // remove it
+ xScriptsRoot.reset( NULL ); // need to reset the storage to be allowed to remove it
+ aDocStorage.removeScriptTypeStorage( _eScriptType );
+
+ // done so far
+ bSuccess = aDocStorage.commit()
+ && aDatabaseScripts.commit();
+ }
+ catch( const Exception& )
+ {
+ aException = ::cppu::getCaughtException();
+ bSuccess = false;
}
- //................................................................
- static Reference< XModel > lcl_loadSubDocument_nothrow( const SubDocument& _rDocument,
- const Reference< XStatusIndicator >& _rxProgress )
+ // log the error, if any
+ if ( !bSuccess )
{
- Reference< XModel > xDocument;
+ m_rLogger.logFailure( MigrationError(
+ ERR_GENERAL_SCRIPT_MIGRATION_FAILURE,
+ lcl_getSubDocumentDescription( _rDocument ),
+ getScriptTypeDisplayName( _eScriptType ),
+ aException
+ ) );
+ }
- try
+ return bSuccess;
+ }
+
+ //--------------------------------------------------------------------
+ bool MigrationEngine_Impl::impl_migrateContainerLibraries_nothrow( const SubDocument& _rDocument,
+ const ScriptType _eScriptType, ProgressMixer& _rProgress, const PhaseID _nPhaseID ) const
+ {
+ OSL_PRECOND( ( _eScriptType == eBasic ) || ( _eScriptType == eDialog ),
+ "MigrationEngine_Impl::impl_migrateContainerLibraries_nothrow: illegal script type!" );
+
+ bool bSuccess = false;
+ PhaseGuard aPhase( _rProgress );
+ Any aException;
+ do // artificial loop for flow control only
+ {
+ try
+ {
+ // access library container of the sub document
+ Reference< XEmbeddedScripts > xSubDocScripts( _rDocument.xDocument, UNO_QUERY );
+ if ( !xSubDocScripts.is() )
+ { // no script support in the sub document -> nothing to migrate
+ // (though ... this is suspicious, at least ...)
+ bSuccess = true;
+ break;
+ }
+
+ Reference< XStorageBasedLibraryContainer > xSourceLibraries(
+ _eScriptType == eBasic ? xSubDocScripts->getBasicLibraries() : xSubDocScripts->getDialogLibraries(),
+ UNO_QUERY_THROW
+ );
+ Reference< XLibraryContainerPassword > xSourcePasswords( xSourceLibraries, UNO_QUERY );
+ OSL_ENSURE( xSourcePasswords.is(),
+ "MigrationEngine_Impl::impl_migrateContainerLibraries_nothrow: suspicious: no password management for the source libraries!" );
+
+ Sequence< ::rtl::OUString > aSourceLibNames( xSourceLibraries->getElementNames() );
+ aPhase.start( _nPhaseID, aSourceLibNames.getLength() );
+
+ if ( !xSourceLibraries->hasElements() )
{
- ::comphelper::NamedValueCollection aLoadArgs;
- aLoadArgs.put( "Hidden", (sal_Bool)sal_True );
- aLoadArgs.put( "StatusIndicator", _rxProgress );
+ bSuccess = true;
+ break;
+ }
- Reference< XCommandProcessor > xCommandProcessor( _rDocument.xCommandProcessor, UNO_SET_THROW );
- Command aCommand;
- aCommand.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "openDesign" ) );
- aCommand.Argument <<= aLoadArgs.getPropertyValues();
- Reference< XComponent > xDocComponent(
- xCommandProcessor->execute(
- aCommand, xCommandProcessor->createCommandIdentifier(), NULL
- ),
- UNO_QUERY
- );
- OSL_ENSURE( xDocComponent.is(), "lcl_loadSubDocument_nothrow: no component loaded!" );
+ // create library containers for the document - those will be the target for the migration
+ Reference< XStorageBasedDocument > xStorageDoc( m_xDocument, UNO_QUERY_THROW );
+ Reference< XStorageBasedLibraryContainer > xTargetLibraries;
+ if ( _eScriptType == eBasic )
+ {
+ xTargetLibraries.set( DocumentScriptLibraryContainer::create(
+ m_aContext.getUNOContext(), xStorageDoc ), UNO_QUERY_THROW );
+ }
+ else
+ {
+ xTargetLibraries.set( DocumentDialogLibraryContainer::create(
+ m_aContext.getUNOContext(), xStorageDoc ), UNO_QUERY_THROW );
+ }
+
+ // copy all libs to the target, with potentially renaming them
+ const ::rtl::OUString* pSourceLibBegin = aSourceLibNames.getConstArray();
+ const ::rtl::OUString* pSourceLibEnd = pSourceLibBegin + aSourceLibNames.getLength();
+ for ( const ::rtl::OUString* pSourceLibName = pSourceLibBegin;
+ pSourceLibName != pSourceLibEnd;
+ ++pSourceLibName
+ )
+ {
+ // if the library is password-protected, ask the user to unprotect it
+ if ( xSourcePasswords.is()
+ && xSourcePasswords->isLibraryPasswordProtected( *pSourceLibName )
+ && !xSourcePasswords->isLibraryPasswordVerified( *pSourceLibName )
+ )
+ {
+ if ( !impl_unprotectPasswordLibrary_throw( xSourcePasswords, _eScriptType, *pSourceLibName ) )
+ {
+ m_rLogger.logFailure( MigrationError(
+ ERR_PASSWORD_VERIFICATION_FAILED,
+ _rDocument.sHierarchicalName,
+ getScriptTypeDisplayName( _eScriptType ),
+ *pSourceLibName
+ ) );
+ return false;
+ }
+ }
+
+ ::rtl::OUString sNewLibName( lcl_createTargetLibName( _rDocument, *pSourceLibName, xTargetLibraries.get() ) );
+
+ if ( xSourceLibraries->isLibraryLink( *pSourceLibName ) )
+ {
+ // just re-create the link in the target library
+ xTargetLibraries->createLibraryLink(
+ sNewLibName,
+ xSourceLibraries->getLibraryLinkURL( *pSourceLibName ),
+ xSourceLibraries->isLibraryReadOnly( *pSourceLibName )
+ );
+ }
+ else
+ {
+ if ( !xSourceLibraries->isLibraryLoaded( *pSourceLibName ) )
+ xSourceLibraries->loadLibrary( *pSourceLibName );
+
+ // copy the content of this particular libary
+ Reference< XNameAccess > xSourceLib( xSourceLibraries->getByName( *pSourceLibName ), UNO_QUERY_THROW );
+ Reference< XNameContainer > xTargetLib( xTargetLibraries->createLibrary( sNewLibName ), UNO_QUERY_THROW );
+
+ Sequence< ::rtl::OUString > aLibElementNames( xSourceLib->getElementNames() );
+ for ( const ::rtl::OUString* pSourceElementName = aLibElementNames.getConstArray();
+ pSourceElementName != aLibElementNames.getConstArray() + aLibElementNames.getLength();
+ ++pSourceElementName
+ )
+ {
+ Any aElement = xSourceLib->getByName( *pSourceElementName );
+ OSL_ENSURE( aElement.hasValue(),
+ "MigrationEngine_Impl::impl_migrateContainerLibraries_nothrow: invalid (empty) lib element!" );
+ xTargetLib->insertByName( *pSourceElementName, aElement );
+ }
+
+ // transfer the read-only flag
+ xTargetLibraries->setLibraryReadOnly(
+ sNewLibName, xSourceLibraries->isLibraryReadOnly( *pSourceLibName ) );
+ }
- xDocument.set( xDocComponent, UNO_QUERY_THROW );
+ // remove the source lib
+ xSourceLibraries->removeLibrary( *pSourceLibName );
+
+ // tell the logger
+ m_rLogger.movedLibrary( m_nCurrentDocumentID, _eScriptType, *pSourceLibName, sNewLibName );
+
+ // tell the progress
+ _rProgress.advancePhase( pSourceLibName - pSourceLibBegin );
}
- catch( const Exception& )
+
+ // clean up
+ xSourceLibraries->storeLibraries();
+
+ xTargetLibraries->storeLibraries();
+ Reference< XStorage > xTargetRoot( xTargetLibraries->getRootLocation(), UNO_QUERY_THROW );
+ bSuccess = lcl_commitStorage_nothrow( xTargetRoot );
+ }
+ catch( const Exception& )
+ {
+ aException = ::cppu::getCaughtException();
+ bSuccess = false;
+ }
+ } while ( false );
+
+ // log the error, if any
+ if ( !bSuccess )
+ {
+ m_rLogger.logFailure( MigrationError(
+ ERR_GENERAL_MACRO_MIGRATION_FAILURE,
+ lcl_getSubDocumentDescription( _rDocument ),
+ aException
+ ) );
+ }
+
+ return bSuccess;
+ }
+
+ //--------------------------------------------------------------------
+ bool MigrationEngine_Impl::impl_adjustScriptLibrary_nothrow( const ::rtl::OUString& _rScriptType,
+ ::rtl::OUString& _inout_rScriptCode ) const
+ {
+ OSL_PRECOND( _inout_rScriptCode.getLength(), "MigrationEngine_Impl::impl_adjustScriptLibrary_nothrow: invalid script!" );
+ if ( !_inout_rScriptCode.getLength() )
+ return false;
+
+ bool bSuccess = false;
+ Any aException;
+ try
+ {
+ if ( !_rScriptType.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Script" ) )
+ || !_rScriptType.getLength()
+ )
{
- // TODO: how to proceed?
- DBG_UNHANDLED_EXCEPTION();
+ OSL_ENSURE( false,
+ "MigrationEngine_Impl::impl_adjustScriptLibrary_nothrow: no or unknown script type!" );
+ m_rLogger.logRecoverable( MigrationError(
+ ERR_UNKNOWN_SCRIPT_TYPE,
+ _rScriptType
+ ) );
+ return false;
+ }
+
+ // analyze the script URI
+ Reference< XUriReferenceFactory > xUriRefFac = UriReferenceFactory::create( m_aContext.getUNOContext() );
+ Reference< XVndSunStarScriptUrlReference > xUri( xUriRefFac->parse( _inout_rScriptCode ), UNO_QUERY_THROW );
+
+ ::rtl::OUString sScriptLanguage = xUri->getParameter(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "language" ) ) );
+ ScriptType eScriptType = eBasic;
+ if ( !lcl_getScriptTypeFromLanguage( sScriptLanguage, eScriptType ) )
+ {
+ OSL_ENSURE( false,
+ "MigrationEngine_Impl::impl_adjustScriptLibrary_nothrow: unknown script language!" );
+ m_rLogger.logRecoverable( MigrationError(
+ ERR_UNKNOWN_SCRIPT_LANGUAGE,
+ sScriptLanguage
+ ) );
+ return false;
+ }
+
+ ::rtl::OUString sLocation = xUri->getParameter(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "location" ) ) );
+ if ( !sLocation.equalsAscii( "document" ) )
+ {
+ // only document libraries must be migrated, of course
+ return false;
+ }
+
+ ::rtl::OUString sScriptName = xUri->getName();
+ sal_Int32 nLibModuleSeparator = sScriptName.indexOf( '.' );
+ if ( nLibModuleSeparator < 0 )
+ {
+ OSL_ENSURE( false,
+ "MigrationEngine_Impl::impl_adjustScriptLibrary_nothrow: invalid/unknown location format!" );
+ m_rLogger.logRecoverable( MigrationError(
+ ERR_UNKNOWN_SCRIPT_NAME_FORMAT,
+ sScriptName
+ ) );
+ return false;
}
- return xDocument;
+ // replace the library name
+ ::rtl::OUString sLibrary = sScriptName.copy( 0, nLibModuleSeparator );
+ ::rtl::OUString sNewLibName = m_rLogger.getNewLibraryName(
+ m_nCurrentDocumentID, eScriptType, sLibrary );
+ OSL_ENSURE( sLibrary != sNewLibName,
+ "MigrationEngine_Impl::impl_adjustScriptLibrary_nothrow: a library which has not been migrated?" );
+
+ ::rtl::OUStringBuffer aNewLocation;
+ aNewLocation.append( sNewLibName );
+ aNewLocation.append( sScriptName.copy( nLibModuleSeparator ) );
+ xUri->setName( aNewLocation.makeStringAndClear() );
+
+ // update the new script URL
+ _inout_rScriptCode = xUri->getUriReference();
+ bSuccess = true;
+ }
+ catch( const Exception& )
+ {
+ aException = ::cppu::getCaughtException();
+ bSuccess = false;
}
+
+ // log the failure, if any
+ if ( !bSuccess )
+ {
+ m_rLogger.logRecoverable( MigrationError(
+ ERR_SCRIPT_TRANSLATION_FAILURE,
+ _rScriptType,
+ _inout_rScriptCode,
+ aException
+ ) );
+ }
+
+ return bSuccess;
}
//--------------------------------------------------------------------
- bool MigrationEngine_Impl::impl_handleDocument_nothrow( const SubDocument& _rDocument ) const
+ bool MigrationEngine_Impl::impl_adjustScriptLibrary_nothrow( ScriptEventDescriptor& _inout_rScriptEvent ) const
{
- DocumentID nDocID = m_rLogger.startedDocument( _rDocument.eType, _rDocument.sHierarchicalName );
+ if ( _inout_rScriptEvent.ScriptType.getLength() && _inout_rScriptEvent.ScriptCode.getLength() )
+ return impl_adjustScriptLibrary_nothrow( _inout_rScriptEvent.ScriptType, _inout_rScriptEvent.ScriptCode );
+ return false;
+ }
- // start the progress
- ::rtl::OUString aProgress;
- aProgress = String( MacroMigrationResId( _rDocument.eType == eForm ? STR_FORM : STR_REPORT ) );
- ::comphelper::string::searchAndReplaceAsciiI( aProgress, "$name$", _rDocument.sHierarchicalName );
- m_rProgress.startObject( aProgress, ::rtl::OUString(), DEFAULT_DOC_PROGRESS_RANGE );
+ //--------------------------------------------------------------------
+ bool MigrationEngine_Impl::impl_adjustScriptLibrary_nothrow( Any& _inout_rScriptDescriptor ) const
+ {
+ ::comphelper::NamedValueCollection aScriptDesc( _inout_rScriptDescriptor );
- // load the document
- ::rtl::Reference< ProgressCapture > pStatusIndicator( new ProgressCapture( aProgress, m_rProgress ) );
- Reference< XModel > xDocument( lcl_loadSubDocument_nothrow( _rDocument, pStatusIndicator.get() ) );
- if ( !xDocument.is() )
+ ::rtl::OUString sScriptType;
+ ::rtl::OUString sScript;
+ try
{
- pStatusIndicator->dispose();
- m_rProgress.endObject();
- m_rLogger.finishedDocument( nDocID, false );
- // TODO: log the *reason* for the failure
+ OSL_VERIFY( aScriptDesc.get_ensureType( "EventType", sScriptType ) );
+ OSL_VERIFY( aScriptDesc.get_ensureType( "Script", sScript ) );
+ }
+ catch( const Exception& )
+ {
+ m_rLogger.logRecoverable( MigrationError(
+ ERR_INVALID_SCRIPT_DESCRIPTOR_FORMAT,
+ ::cppu::getCaughtException()
+ ) );
+ }
+
+ if ( sScriptType.getLength() && sScript.getLength() )
+ if ( !impl_adjustScriptLibrary_nothrow( sScriptType, sScript ) )
+ return false;
+
+ aScriptDesc.put( "Script", sScript );
+ _inout_rScriptDescriptor <<= aScriptDesc.getPropertyValues();
+ return true;
+ }
+
+ //--------------------------------------------------------------------
+ bool MigrationEngine_Impl::impl_adjustDocumentEvents_nothrow( const SubDocument& _rDocument ) const
+ {
+ try
+ {
+ Reference< XEventsSupplier > xSuppEvents( _rDocument.xDocument, UNO_QUERY );
+ if ( !xSuppEvents.is() )
+ // this is allowed. E.g. new-style reports currently do not support this
+ return true;
+
+ Reference< XNameReplace > xEvents( xSuppEvents->getEvents(), UNO_SET_THROW );
+ Sequence< ::rtl::OUString > aEventNames = xEvents->getElementNames();
+
+ Any aEvent;
+ for ( const ::rtl::OUString* eventName = aEventNames.getConstArray();
+ eventName != aEventNames.getConstArray() + aEventNames.getLength();
+ ++eventName
+ )
+ {
+ aEvent = xEvents->getByName( *eventName );
+ if ( !aEvent.hasValue() )
+ continue;
+
+ // translate
+ if ( !impl_adjustScriptLibrary_nothrow( aEvent ) )
+ continue;
+
+ // put back
+ xEvents->replaceByName( *eventName, aEvent );
+ }
+ }
+ catch( const Exception& )
+ {
+ m_rLogger.logRecoverable( MigrationError(
+ ERR_ADJUSTING_DOCUMENT_EVENTS_FAILED,
+ lcl_getSubDocumentDescription( _rDocument ),
+ ::cppu::getCaughtException()
+ ) );
return false;
}
+ return true;
+ }
- // TODO
+ //--------------------------------------------------------------------
+ void MigrationEngine_Impl::impl_adjustFormComponentEvents_throw( const Reference< XIndexAccess >& _rxComponentContainer ) const
+ {
+ FormComponentIterator aCompIter( _rxComponentContainer );
+ while ( aCompIter.hasMore() )
+ {
+ // 1. adjust the component's scripts of the current component
+ FormComponentScripts aComponent( aCompIter.next() );
+ Sequence< ScriptEventDescriptor > aEvents( aComponent.getEvents() );
- // clean up
- lcl_disposeComponent_nothrow( _rDocument.xCommandProcessor );
- pStatusIndicator->dispose();
+ bool bChangedComponentEvents = false;
+ for ( ScriptEventDescriptor* scriptEvent = aEvents.getArray();
+ scriptEvent != aEvents.getArray() + aEvents.getLength();
+ ++scriptEvent
+ )
+ {
+ if ( !impl_adjustScriptLibrary_nothrow( *scriptEvent ) )
+ continue;
- // end the progress, just in case the ProgressCapture didn't receive the XStatusIndicator::end event
- m_rProgress.endObject();
+ bChangedComponentEvents = true;
+ }
+
+ if ( bChangedComponentEvents )
+ aComponent.setEvents( aEvents );
- m_rLogger.finishedDocument( nDocID, true );
+ // 2. step down if the component is a container itself
+ Reference< XIndexAccess > xContainer( aComponent.getComponent(), UNO_QUERY );
+ if ( xContainer.is() )
+ impl_adjustFormComponentEvents_throw( xContainer );
+ }
+ }
+
+ //--------------------------------------------------------------------
+ bool MigrationEngine_Impl::impl_adjustFormComponentEvents_nothrow( const SubDocument& _rDocument ) const
+ {
+ try
+ {
+ DrawPageIterator aPageIter( _rDocument.xDocument );
+ while ( aPageIter.hasMore() )
+ {
+ Reference< XFormsSupplier > xSuppForms( aPageIter.next(), UNO_QUERY_THROW );
+ Reference< XIndexAccess > xForms( xSuppForms->getForms(), UNO_QUERY_THROW );
+ impl_adjustFormComponentEvents_throw( xForms );
+ }
+ }
+ catch( const Exception& )
+ {
+ m_rLogger.logRecoverable( MigrationError(
+ ERR_ADJUSTING_FORMCOMP_EVENTS_FAILED,
+ lcl_getSubDocumentDescription( _rDocument ),
+ ::cppu::getCaughtException()
+ ) );
+ return false;
+ }
return true;
}
//--------------------------------------------------------------------
- void MigrationEngine_Impl::impl_reportError_nothrow( const Any& _rError ) const
+ bool MigrationEngine_Impl::impl_unprotectPasswordLibrary_throw( const Reference< XLibraryContainerPassword >& _rxPasswordManager,
+ const ScriptType _eScriptType, const ::rtl::OUString& _rLibraryName ) const
{
- DocumentErrorHandling::reportError( m_aContext, m_xDocument, _rError );
+ // a human-readable description of the affected library
+ ::rtl::OUString sLibraryDescription( String(
+ MacroMigrationResId( STR_LIBRARY_TYPE_AND_NAME ) ) );
+ ::comphelper::string::searchAndReplaceAsciiI( sLibraryDescription, "$type$",
+ getScriptTypeDisplayName( _eScriptType ) );
+ ::comphelper::string::searchAndReplaceAsciiI( sLibraryDescription, "$library$",
+ _rLibraryName );
+
+ InteractionHandler aHandler( m_aContext, m_xDocumentModel );
+ ::rtl::OUString sPassword;
+ while ( true )
+ {
+ if ( !aHandler.requestDocumentPassword( sLibraryDescription, sPassword ) )
+ // aborted by the user
+ return false;
+
+ bool bSuccessVerification = _rxPasswordManager->verifyLibraryPassword( _rLibraryName, sPassword );
+ if ( bSuccessVerification )
+ return true;
+ }
+
+ return false;
}
//====================================================================
//= MigrationEngine
//====================================================================
//--------------------------------------------------------------------
- MigrationEngine::MigrationEngine( const ::comphelper::ComponentContext& _rContext, const Reference< XOfficeDatabaseDocument >& _rxDocument,
- IMigrationProgress& _rProgress, MigrationLog& _rLogger )
+ MigrationEngine::MigrationEngine( const ::comphelper::ComponentContext& _rContext,
+ const Reference< XOfficeDatabaseDocument >& _rxDocument, IMigrationProgress& _rProgress,
+ MigrationLog& _rLogger )
:m_pImpl( new MigrationEngine_Impl( _rContext, _rxDocument, _rProgress, _rLogger ) )
{
}
diff --git a/dbaccess/source/ext/macromigration/migrationerror.hxx b/dbaccess/source/ext/macromigration/migrationerror.hxx
new file mode 100644
index 000000000..a4e7e5334
--- /dev/null
+++ b/dbaccess/source/ext/macromigration/migrationerror.hxx
@@ -0,0 +1,162 @@
+/*************************************************************************
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* Copyright 2008 by Sun Microsystems, Inc.
+*
+* OpenOffice.org - a multi-platform office productivity suite
+*
+* $RCSfile: migrationerror.hxx,v $
+*
+* $Revision: 1.1.2.3 $
+*
+* 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.
+************************************************************************/
+
+#ifndef DBACCESS_MIGRATIONERROR_HXX
+#define DBACCESS_MIGRATIONERROR_HXX
+
+/** === begin UNO includes === **/
+#include <com/sun/star/uno/Any.hxx>
+/** === end UNO includes === **/
+
+#include <vector>
+
+//........................................................................
+namespace dbmm
+{
+//........................................................................
+
+ enum MigrationErrorType
+ {
+ ERR_OPENING_SUB_DOCUMENT_FAILED = 1,
+ ERR_CLOSING_SUB_DOCUMENT_FAILED,
+ ERR_STORAGE_COMMIT_FAILED,
+ ERR_STORING_DATABASEDOC_FAILED,
+ ERR_COLLECTING_DOCUMENTS_FAILED,
+ ERR_UNEXPECTED_LIBSTORAGE_ELEMENT,
+ ERR_CREATING_DBDOC_SCRIPT_STORAGE_FAILED,
+ ERR_COMMITTING_SCRIPT_STORAGES_FAILED,
+ ERR_GENERAL_SCRIPT_MIGRATION_FAILURE,
+ ERR_GENERAL_MACRO_MIGRATION_FAILURE,
+ ERR_UNKNOWN_SCRIPT_TYPE,
+ ERR_UNKNOWN_SCRIPT_LANGUAGE,
+ ERR_UNKNOWN_SCRIPT_NAME_FORMAT,
+ ERR_SCRIPT_TRANSLATION_FAILURE,
+ ERR_INVALID_SCRIPT_DESCRIPTOR_FORMAT,
+ ERR_ADJUSTING_DOCUMENT_EVENTS_FAILED,
+ ERR_ADJUSTING_FORMCOMP_EVENTS_FAILED,
+ ERR_BIND_SCRIPT_STORAGE_FAILED,
+ ERR_REMOVE_SCRIPTS_STORAGE_FAILED,
+ ERR_DOCUMENT_BACKUP_FAILED,
+ ERR_UNKNOWN_SCRIPT_FOLDER,
+ ERR_EXAMINING_SCRIPTS_FOLDER_FAILED,
+ ERR_PASSWORD_VERIFICATION_FAILED
+ };
+
+ //====================================================================
+ //= MigrationError
+ //====================================================================
+ /** encapsulates information about an error which happened during the migration
+ */
+ struct MigrationError
+ {
+ const MigrationErrorType eType;
+ ::std::vector< ::rtl::OUString > aErrorDetails;
+ const ::com::sun::star::uno::Any aCaughtException;
+
+ MigrationError(
+ const MigrationErrorType _eType )
+ :eType( _eType )
+ {
+ }
+
+ MigrationError(
+ const MigrationErrorType _eType,
+ const ::com::sun::star::uno::Any& _rCaughtException )
+ :eType( _eType )
+ ,aCaughtException( _rCaughtException )
+ {
+ }
+
+ MigrationError(
+ const MigrationErrorType _eType,
+ const ::rtl::OUString& _rDetail )
+ :eType( _eType )
+ {
+ impl_constructDetails( _rDetail );
+ }
+
+ MigrationError(
+ const MigrationErrorType _eType,
+ const ::rtl::OUString& _rDetail,
+ const ::com::sun::star::uno::Any& _rCaughtException )
+ :eType( _eType )
+ ,aCaughtException( _rCaughtException )
+ {
+ impl_constructDetails( _rDetail );
+ }
+
+ MigrationError(
+ const MigrationErrorType _eType,
+ const ::rtl::OUString& _rDetail1,
+ const ::rtl::OUString& _rDetail2 )
+ :eType( _eType )
+ {
+ impl_constructDetails( _rDetail1, _rDetail2 );
+ }
+
+ MigrationError(
+ const MigrationErrorType _eType,
+ const ::rtl::OUString& _rDetail1,
+ const ::rtl::OUString& _rDetail2,
+ const ::com::sun::star::uno::Any& _rCaughtException )
+ :eType( _eType )
+ ,aCaughtException( _rCaughtException )
+ {
+ impl_constructDetails( _rDetail1, _rDetail2 );
+ }
+
+ MigrationError(
+ const MigrationErrorType _eType,
+ const ::rtl::OUString& _rDetail1,
+ const ::rtl::OUString& _rDetail2,
+ const ::rtl::OUString& _rDetail3 )
+ :eType( _eType )
+ {
+ impl_constructDetails( _rDetail1, _rDetail2, _rDetail3 );
+ }
+
+ private:
+ void impl_constructDetails(
+ const ::rtl::OUString& _rDetail1,
+ const ::rtl::OUString& _rDetail2 = ::rtl::OUString(),
+ const ::rtl::OUString& _rDetail3 = ::rtl::OUString()
+ )
+ {
+ if ( _rDetail1.getLength() ) aErrorDetails.push_back( _rDetail1 );
+ if ( _rDetail2.getLength() ) aErrorDetails.push_back( _rDetail2 );
+ if ( _rDetail3.getLength() ) aErrorDetails.push_back( _rDetail3 );
+ }
+ };
+
+//........................................................................
+} // namespace dbmm
+//........................................................................
+
+#endif // DBACCESS_MIGRATIONERROR_HXX
+
diff --git a/dbaccess/source/ext/macromigration/migrationlog.cxx b/dbaccess/source/ext/macromigration/migrationlog.cxx
index 659383499..b15a6b5f9 100644
--- a/dbaccess/source/ext/macromigration/migrationlog.cxx
+++ b/dbaccess/source/ext/macromigration/migrationlog.cxx
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: migrationlog.cxx,v $
- * $Revision: 1.4 $
+ * $Revision: 1.4.2.8 $
*
* This file is part of OpenOffice.org.
*
@@ -33,16 +33,20 @@
#include "dbmm_module.hxx"
#include "dbmm_global.hrc"
+#include "migrationerror.hxx"
#include "migrationlog.hxx"
/** === begin UNO includes === **/
/** === end UNO includes === **/
+#include <comphelper/anytostring.hxx>
+#include <comphelper/string.hxx>
#include <tools/string.hxx>
#include <rtl/ustrbuf.hxx>
#include <vector>
#include <map>
+#include <list>
//........................................................................
namespace dbmm
@@ -84,20 +88,17 @@ namespace dbmm
SubDocumentType eType;
::rtl::OUString sName;
::std::vector< LibraryEntry > aMovedLibraries;
- bool bSuccess;
DocumentEntry()
:eType( eForm )
,sName()
,aMovedLibraries()
- ,bSuccess( false )
{
}
DocumentEntry( const SubDocumentType _eType, const ::rtl::OUString& _rName )
:eType( _eType )
,sName( _rName )
- ,bSuccess( false )
{
}
};
@@ -108,12 +109,19 @@ namespace dbmm
typedef ::std::map< DocumentID, DocumentEntry > DocumentLogs;
//====================================================================
+ //= ErrorLog
+ //====================================================================
+ typedef ::std::list< MigrationError > ErrorLog;
+
+ //====================================================================
//= MigrationLog_Data
//====================================================================
struct MigrationLog_Data
{
::rtl::OUString sBackupLocation;
DocumentLogs aDocumentLogs;
+ ErrorLog aFailures;
+ ErrorLog aWarnings;
};
//====================================================================
@@ -131,6 +139,24 @@ namespace dbmm
}
//--------------------------------------------------------------------
+ void MigrationLog::logFailure( const MigrationError& _rError )
+ {
+ m_pData->aFailures.push_back( _rError );
+ }
+
+ //--------------------------------------------------------------------
+ void MigrationLog::logRecoverable( const MigrationError& _rError )
+ {
+ m_pData->aWarnings.push_back( _rError );
+ }
+
+ //--------------------------------------------------------------------
+ bool MigrationLog::hadFailure() const
+ {
+ return !m_pData->aFailures.empty();
+ }
+
+ //--------------------------------------------------------------------
void MigrationLog::backedUpDocument( const ::rtl::OUString& _rNewDocumentLocation )
{
m_pData->sBackupLocation = _rNewDocumentLocation;
@@ -172,13 +198,14 @@ namespace dbmm
}
//--------------------------------------------------------------------
- void MigrationLog::finishedDocument( const DocumentID _nDocID, const bool _bSuccessful )
+ void MigrationLog::finishedDocument( const DocumentID _nDocID )
{
OSL_ENSURE( m_pData->aDocumentLogs.find( _nDocID ) != m_pData->aDocumentLogs.end(),
"MigrationLog::finishedDocument: document is not known!" );
DocumentEntry& rDocEntry = m_pData->aDocumentLogs[ _nDocID ];
- rDocEntry.bSuccess = _bSuccessful;
+ (void)rDocEntry;
+ // nothing to do here
}
//--------------------------------------------------------------------
@@ -213,21 +240,180 @@ namespace dbmm
//--------------------------------------------------------------------
namespace
{
- String lcl_getScriptTypeDisplayName( const ScriptType _eType )
+ //----------------------------------------------------------------
+ static void lcl_appendErrorDescription( ::rtl::OUStringBuffer& _inout_rBuffer, const MigrationError& _rError )
+ {
+ const sal_Char* pAsciiErrorDescription( NULL );
+ ::std::vector< const sal_Char* > aAsciiParameterNames;
+ switch ( _rError.eType )
+ {
+ case ERR_OPENING_SUB_DOCUMENT_FAILED:
+ pAsciiErrorDescription = "opening '#name#' failed";
+ aAsciiParameterNames.push_back( "#name#" );
+ break;
+
+ case ERR_CLOSING_SUB_DOCUMENT_FAILED:
+ pAsciiErrorDescription = "closing '#name#' failed";
+ aAsciiParameterNames.push_back( "#name#" );
+ break;
+
+ case ERR_STORAGE_COMMIT_FAILED:
+ pAsciiErrorDescription = "committing the changes for document '#name#' failed";
+ aAsciiParameterNames.push_back( "#name#" );
+ break;
+
+ case ERR_STORING_DATABASEDOC_FAILED:
+ pAsciiErrorDescription = "storing the database document failed";
+ break;
+
+ case ERR_COLLECTING_DOCUMENTS_FAILED:
+ pAsciiErrorDescription = "collecting the forms/reports of the database document failed";
+ break;
+
+ case ERR_UNEXPECTED_LIBSTORAGE_ELEMENT:
+ pAsciiErrorDescription = "unexpected #lib# storage element in document '#doc#', named '#element#'";
+ aAsciiParameterNames.push_back( "#doc#" );
+ aAsciiParameterNames.push_back( "#libstore#" );
+ aAsciiParameterNames.push_back( "#element#" );
+ break;
+
+ case ERR_CREATING_DBDOC_SCRIPT_STORAGE_FAILED:
+ pAsciiErrorDescription = "creating the database document's storage for #scripttype# scripts failed";
+ aAsciiParameterNames.push_back( "#scripttype#" );
+ break;
+
+ case ERR_COMMITTING_SCRIPT_STORAGES_FAILED:
+ pAsciiErrorDescription = "saving the #scripttype# scripts for document '#doc#' failed";
+ aAsciiParameterNames.push_back( "#scripttype#" );
+ aAsciiParameterNames.push_back( "#doc#" );
+ break;
+
+ case ERR_GENERAL_SCRIPT_MIGRATION_FAILURE:
+ pAsciiErrorDescription = "general error during migrationg #scripttype# scripts of document '#doc#'";
+ aAsciiParameterNames.push_back( "#scripttype#" );
+ aAsciiParameterNames.push_back( "#doc#" );
+ break;
+
+ case ERR_GENERAL_MACRO_MIGRATION_FAILURE:
+ pAsciiErrorDescription = "general error during macro migration of document '#doc#'";
+ aAsciiParameterNames.push_back( "#doc#" );
+ break;
+
+ case ERR_UNKNOWN_SCRIPT_TYPE:
+ pAsciiErrorDescription = "unknown script type: #type#";
+ aAsciiParameterNames.push_back( "#type#" );
+ break;
+
+ case ERR_UNKNOWN_SCRIPT_LANGUAGE:
+ pAsciiErrorDescription = "unknown script language: #lang#";
+ aAsciiParameterNames.push_back( "#lang#" );
+ break;
+
+ case ERR_UNKNOWN_SCRIPT_NAME_FORMAT:
+ pAsciiErrorDescription = "unknown script name format: #script#";
+ aAsciiParameterNames.push_back( "#script#" );
+ break;
+
+ case ERR_SCRIPT_TRANSLATION_FAILURE:
+ pAsciiErrorDescription = "analyzing/translating the script URL failed; script type: #type#; script: #code#";
+ aAsciiParameterNames.push_back( "#type#" );
+ aAsciiParameterNames.push_back( "#code#" );
+ break;
+
+ case ERR_INVALID_SCRIPT_DESCRIPTOR_FORMAT:
+ pAsciiErrorDescription = "invalid script descriptor format";
+ break;
+
+ case ERR_ADJUSTING_DOCUMENT_EVENTS_FAILED:
+ pAsciiErrorDescription = "adjusting events for document #doc# failed";
+ aAsciiParameterNames.push_back( "#doc#" );
+ break;
+
+ case ERR_ADJUSTING_FORMCOMP_EVENTS_FAILED:
+ pAsciiErrorDescription = "adjusting form component events for '#doc#' failed";
+ aAsciiParameterNames.push_back( "#doc#" );
+ break;
+
+ case ERR_BIND_SCRIPT_STORAGE_FAILED:
+ pAsciiErrorDescription = "binding to the script storage failed for document '#doc#'";
+ aAsciiParameterNames.push_back( "#doc#" );
+ break;
+
+ case ERR_REMOVE_SCRIPTS_STORAGE_FAILED:
+ pAsciiErrorDescription = "removing a scripts storage failed for document '#doc#'";
+ aAsciiParameterNames.push_back( "#doc#" );
+ break;
+
+ case ERR_DOCUMENT_BACKUP_FAILED:
+ pAsciiErrorDescription = "backing up the document to #location# failed";
+ aAsciiParameterNames.push_back( "#location#" );
+ break;
+
+ case ERR_UNKNOWN_SCRIPT_FOLDER:
+ pAsciiErrorDescription = "unknown script folder '#name#' in document '#doc#'";
+ aAsciiParameterNames.push_back( "#doc#" );
+ aAsciiParameterNames.push_back( "#name#" );
+ break;
+
+ case ERR_EXAMINING_SCRIPTS_FOLDER_FAILED:
+ pAsciiErrorDescription = "examining the 'Scripts' folder failed for document '#doc#'";
+ aAsciiParameterNames.push_back( "#doc#" );
+ break;
+
+ case ERR_PASSWORD_VERIFICATION_FAILED:
+ pAsciiErrorDescription = "password verification failed for document '#doc#', #libtype# library '#name#'";
+ aAsciiParameterNames.push_back( "#doc#" );
+ aAsciiParameterNames.push_back( "#libtype#" );
+ aAsciiParameterNames.push_back( "#name#" );
+ break;
+
+ // do *not* add a default case here: Without a default, some compilers will warn you when
+ // you miss a newly-introduced enum value here
+ }
+ OSL_ENSURE( pAsciiErrorDescription, "lcl_appendErrorDescription: no error message!" );
+ if ( pAsciiErrorDescription )
+ {
+ ::rtl::OUString sSubstituted( ::rtl::OUString::createFromAscii( pAsciiErrorDescription ) );
+ OSL_ENSURE( aAsciiParameterNames.size() == _rError.aErrorDetails.size(),
+ "lcl_appendErrorDescription: unexpected number of error message parameters!" );
+
+ for ( size_t i=0; i < ::std::min( aAsciiParameterNames.size(), _rError.aErrorDetails.size() ); ++i )
+ {
+ ::comphelper::string::searchAndReplaceAsciiI( sSubstituted, aAsciiParameterNames[i],
+ _rError.aErrorDetails[i] );
+ }
+
+ _inout_rBuffer.append( sSubstituted );
+ }
+ }
+
+ //----------------------------------------------------------------
+ void lcl_describeErrors( ::rtl::OUStringBuffer& _rBuffer, const ErrorLog& _rErrors, const USHORT _nHeadingResId )
{
- USHORT nResId( 0 );
+ _rBuffer.appendAscii( "=== " );
+ _rBuffer.append ( String( MacroMigrationResId( _nHeadingResId ) ) );
+ _rBuffer.appendAscii( " ===\n" );
- switch ( _eType )
+ String sException( MacroMigrationResId( STR_EXCEPTION ) );
+
+ for ( ErrorLog::const_iterator error = _rErrors.begin();
+ error != _rErrors.end();
+ ++error
+ )
{
- case eBasic: nResId = STR_OOO_BASIC; break;
- case eBeanShell: nResId = STR_BEAN_SHELL; break;
- case eJavaScript: nResId = STR_JAVA_SCRIPT; break;
- case ePython: nResId = STR_PYTHON; break;
- case eJava: nResId = STR_JAVA; break;
- case eDialog: nResId = STR_DIALOG; break;
+ _rBuffer.append( sal_Unicode( '-' ) );
+ _rBuffer.append( sal_Unicode( ' ' ) );
+ lcl_appendErrorDescription( _rBuffer, *error );
+ _rBuffer.append( sal_Unicode( '\n' ) );
+
+ if ( !error->aCaughtException.hasValue() )
+ continue;
+
+ _rBuffer.append( sException );
+ _rBuffer.append( ::comphelper::anyToString( error->aCaughtException ) );
+ _rBuffer.append( sal_Unicode( '\n' ) );
+ _rBuffer.append( sal_Unicode( '\n' ) );
}
- OSL_ENSURE( nResId != 0, "lcl_getScriptTypeDisplayName: illegal script type!" );
- return nResId ? String( MacroMigrationResId( nResId ) ) : String();
}
}
@@ -236,54 +422,65 @@ namespace dbmm
{
::rtl::OUStringBuffer aBuffer;
- String sBackedUp( MacroMigrationResId( STR_SAVED_COPY_TO ) );
- sBackedUp.SearchAndReplaceAllAscii( "$location$", m_pData->sBackupLocation );
-
- aBuffer.appendAscii( "=== " );
- aBuffer.append ( String( MacroMigrationResId( STR_DATABASE_DOCUMENT ) ) );
- aBuffer.appendAscii( " ===\n" );
- aBuffer.append ( sBackedUp );
- aBuffer.appendAscii( "\n\n" );
-
- String sMovedLibTemplate( MacroMigrationResId( STR_MOVED_LIBRARY ) );
-
- for ( DocumentLogs::const_iterator doc = m_pData->aDocumentLogs.begin();
- doc != m_pData->aDocumentLogs.end();
- ++doc
- )
+ if ( m_pData->sBackupLocation.getLength() )
{
- const DocumentEntry& rDoc( doc->second );
-
- if ( rDoc.aMovedLibraries.empty() )
- continue;
-
- String sDocTitle( MacroMigrationResId( rDoc.eType == eForm ? STR_FORM : STR_REPORT ) );
- sDocTitle.SearchAndReplaceAllAscii( "$name$", rDoc.sName );
+ String sBackedUp( MacroMigrationResId( STR_SAVED_COPY_TO ) );
+ sBackedUp.SearchAndReplaceAllAscii( "$location$", m_pData->sBackupLocation );
aBuffer.appendAscii( "=== " );
- aBuffer.append ( sDocTitle );
+ aBuffer.append ( String( MacroMigrationResId( STR_DATABASE_DOCUMENT ) ) );
aBuffer.appendAscii( " ===\n" );
+ aBuffer.append ( sBackedUp );
+ aBuffer.appendAscii( "\n\n" );
+ }
- for ( ::std::vector< LibraryEntry >::const_iterator lib = rDoc.aMovedLibraries.begin();
- lib != rDoc.aMovedLibraries.end();
- ++lib
+ if ( !m_pData->aFailures.empty() )
+ {
+ lcl_describeErrors( aBuffer, m_pData->aFailures
+ , STR_ERRORS );
+ }
+ else
+ {
+ String sMovedLibTemplate( MacroMigrationResId( STR_MOVED_LIBRARY ) );
+
+ for ( DocumentLogs::const_iterator doc = m_pData->aDocumentLogs.begin();
+ doc != m_pData->aDocumentLogs.end();
+ ++doc
)
{
- String sMovedLib( sMovedLibTemplate );
- sMovedLib.SearchAndReplaceAllAscii( "$type$", lcl_getScriptTypeDisplayName( lib->eType ) );
- sMovedLib.SearchAndReplaceAllAscii( "$old$", lib->sOldName );
- sMovedLib.SearchAndReplaceAllAscii( "$new$", lib->sNewName );
+ const DocumentEntry& rDoc( doc->second );
- aBuffer.append ( sMovedLib );
- aBuffer.appendAscii( "\n" );
- }
+ if ( rDoc.aMovedLibraries.empty() )
+ continue;
- if ( !rDoc.bSuccess )
- {
- // TODO
+ String sDocTitle( MacroMigrationResId( rDoc.eType == eForm ? STR_FORM : STR_REPORT ) );
+ sDocTitle.SearchAndReplaceAllAscii( "$name$", rDoc.sName );
+
+ aBuffer.appendAscii( "=== " );
+ aBuffer.append ( sDocTitle );
+ aBuffer.appendAscii( " ===\n" );
+
+ for ( ::std::vector< LibraryEntry >::const_iterator lib = rDoc.aMovedLibraries.begin();
+ lib != rDoc.aMovedLibraries.end();
+ ++lib
+ )
+ {
+ String sMovedLib( sMovedLibTemplate );
+ sMovedLib.SearchAndReplaceAllAscii( "$type$", getScriptTypeDisplayName( lib->eType ) );
+ sMovedLib.SearchAndReplaceAllAscii( "$old$", lib->sOldName );
+ sMovedLib.SearchAndReplaceAllAscii( "$new$", lib->sNewName );
+
+ aBuffer.append( sMovedLib );
+ aBuffer.append( sal_Unicode( '\n' ) );
+ }
+
+ aBuffer.append( sal_Unicode( '\n' ) );
}
+ }
- aBuffer.appendAscii( "\n" );
+ if ( !m_pData->aWarnings.empty() )
+ {
+ lcl_describeErrors( aBuffer, m_pData->aWarnings, STR_WARNINGS );
}
return aBuffer.makeStringAndClear();
diff --git a/dbaccess/source/ext/macromigration/migrationlog.hxx b/dbaccess/source/ext/macromigration/migrationlog.hxx
index 67c9a7d60..4a23dd2b8 100644
--- a/dbaccess/source/ext/macromigration/migrationlog.hxx
+++ b/dbaccess/source/ext/macromigration/migrationlog.hxx
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: migrationlog.hxx,v $
- * $Revision: 1.3 $
+ * $Revision: 1.3.2.2 $
*
* This file is part of OpenOffice.org.
*
@@ -46,6 +46,7 @@ namespace dbmm
//........................................................................
typedef sal_Int16 DocumentID;
+ struct MigrationError;
//====================================================================
//= MigrationLog
@@ -60,6 +61,17 @@ namespace dbmm
//----------------------------------------------------------------
//- event logging
+ /** logs an unrecoverable error during the migration process
+ */
+ void logFailure( const MigrationError& _rError );
+
+ /** logs a recoverable (or at least ignorable) error during the migration process
+ */
+ void logRecoverable( const MigrationError& _rError );
+
+ /// checks whether logFailure has been called
+ bool hadFailure() const;
+
/// logs the fact that the database document has been backed up
void backedUpDocument( const ::rtl::OUString& _rNewDocumentLocation );
@@ -80,7 +92,7 @@ namespace dbmm
/** logs that the migration for a certain document has been finished
*/
- void finishedDocument( const DocumentID _nDocID, const bool _bSuccessful );
+ void finishedDocument( const DocumentID _nDocID );
//----------------------------------------------------------------
//- information retrieval
diff --git a/dbaccess/source/ext/macromigration/migrationprogress.hxx b/dbaccess/source/ext/macromigration/migrationprogress.hxx
index 0db16fba9..84ff58722 100644
--- a/dbaccess/source/ext/macromigration/migrationprogress.hxx
+++ b/dbaccess/source/ext/macromigration/migrationprogress.hxx
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: migrationprogress.hxx,v $
- * $Revision: 1.3 $
+ * $Revision: 1.3.2.1 $
*
* This file is part of OpenOffice.org.
*
@@ -40,7 +40,7 @@ namespace dbmm
//........................................................................
//====================================================================
- //= MigrationProgress
+ //= IMigrationProgress
//====================================================================
class SAL_NO_VTABLE IMigrationProgress
{
diff --git a/dbaccess/source/ext/macromigration/progressmixer.cxx b/dbaccess/source/ext/macromigration/progressmixer.cxx
new file mode 100644
index 000000000..0dfdee019
--- /dev/null
+++ b/dbaccess/source/ext/macromigration/progressmixer.cxx
@@ -0,0 +1,218 @@
+/*************************************************************************
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* Copyright 2008 by Sun Microsystems, Inc.
+*
+* OpenOffice.org - a multi-platform office productivity suite
+*
+* $RCSfile: progressmixer.cxx,v $
+*
+* $Revision: 1.1.2.1 $
+*
+* 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_dbaccess.hxx"
+
+#include "progressmixer.hxx"
+
+/** === begin UNO includes === **/
+/** === end UNO includes === **/
+
+#include <osl/diagnose.h>
+
+#include <map>
+
+//........................................................................
+namespace dbmm
+{
+//........................................................................
+
+ /** === begin UNO using === **/
+ /** === end UNO using === **/
+
+#define OVERALL_RANGE 100000
+
+ //====================================================================
+ //= misc types
+ //====================================================================
+ struct PhaseData
+ {
+ // the weight of the phase, relative to all other phases
+ PhaseWeight nWeight;
+ // the "local" range of the phase
+ sal_uInt32 nRange;
+ // this is the point in the "overall range" at which this phase starts
+ sal_uInt32 nGlobalStart;
+ /** the "global" range of the phase, i.e. its range after weighting with all other
+ phases
+ */
+ sal_uInt32 nGlobalRange;
+
+ PhaseData()
+ :nWeight(1)
+ ,nRange(100)
+ ,nGlobalStart(0)
+ ,nGlobalRange(100)
+ {
+ }
+
+ PhaseData( const PhaseWeight _nWeight )
+ :nWeight( _nWeight )
+ ,nRange(100)
+ ,nGlobalStart(0)
+ ,nGlobalRange(100)
+ {
+ }
+ };
+
+ typedef ::std::map< PhaseID, PhaseData > Phases;
+
+ //====================================================================
+ //= ProgressMixer_Data
+ //====================================================================
+ struct ProgressMixer_Data
+ {
+ Phases aPhases;
+ Phases::iterator pCurrentPhase;
+ sal_uInt32 nWeightSum; /// the cached sum of the weights
+ double nOverallStretch;
+ IProgressConsumer& rConsumer;
+
+ ProgressMixer_Data( IProgressConsumer& _rConsumer )
+ :aPhases()
+ ,pCurrentPhase( aPhases.end() )
+ ,nWeightSum( 0 )
+ ,nOverallStretch( 0 )
+ ,rConsumer( _rConsumer )
+ {
+ }
+ };
+
+ //--------------------------------------------------------------------
+ namespace
+ {
+ //----------------------------------------------------------------
+ bool lcl_isRunning( const ProgressMixer_Data& _rData )
+ {
+ return _rData.pCurrentPhase != _rData.aPhases.end();
+ }
+
+ //----------------------------------------------------------------
+ void lcl_ensureInitialized( ProgressMixer_Data& _rData )
+ {
+ OSL_PRECOND( _rData.nWeightSum, "lcl_ensureInitialized: we have no phases, this will crash!" );
+
+ if ( _rData.nOverallStretch )
+ return;
+
+ _rData.nOverallStretch = 1.0 * OVERALL_RANGE / _rData.nWeightSum;
+
+ // tell the single phases their "overall starting point"
+ PhaseWeight nRunningWeight( 0 );
+ for ( Phases::iterator phase = _rData.aPhases.begin();
+ phase != _rData.aPhases.end();
+ ++phase
+ )
+ {
+ phase->second.nGlobalStart = (sal_uInt32)( nRunningWeight * _rData.nOverallStretch );
+ nRunningWeight += phase->second.nWeight;
+
+ sal_uInt32 nNextPhaseStart = (sal_uInt32)( nRunningWeight * _rData.nOverallStretch );
+ phase->second.nGlobalRange = nNextPhaseStart - phase->second.nGlobalStart;
+ }
+
+ _rData.rConsumer.start( OVERALL_RANGE );
+ }
+ }
+
+ //====================================================================
+ //= ProgressMixer
+ //====================================================================
+ //--------------------------------------------------------------------
+ ProgressMixer::ProgressMixer( IProgressConsumer& _rConsumer )
+ :m_pData( new ProgressMixer_Data( _rConsumer ) )
+ {
+ }
+
+ //--------------------------------------------------------------------
+ ProgressMixer::~ProgressMixer()
+ {
+ }
+
+ //--------------------------------------------------------------------
+ void ProgressMixer::registerPhase( const PhaseID _nID, const PhaseWeight _nWeight )
+ {
+ OSL_PRECOND( !lcl_isRunning( *m_pData ), "ProgressMixer::registerPhase: already running!" );
+ OSL_ENSURE( m_pData->aPhases.find( _nID ) == m_pData->aPhases.end(),
+ "ProgressMixer::registerPhase: ID already used!" );
+ m_pData->aPhases[ _nID ] = PhaseData( _nWeight );
+ m_pData->nWeightSum += _nWeight;
+ }
+
+ //--------------------------------------------------------------------
+ void ProgressMixer::startPhase( const PhaseID _nID, const sal_uInt32 _nPhaseRange )
+ {
+ OSL_ENSURE( m_pData->aPhases.find( _nID ) != m_pData->aPhases.end(),
+ "ProgresMixer::startPhase: unknown phase!" );
+
+ m_pData->aPhases[ _nID ].nRange = _nPhaseRange;
+ m_pData->pCurrentPhase = m_pData->aPhases.find( _nID );
+ }
+
+ //--------------------------------------------------------------------
+ void ProgressMixer::advancePhase( const sal_uInt32 _nPhaseProgress )
+ {
+ OSL_PRECOND( lcl_isRunning( *m_pData ), "ProgresMixer::advancePhase: not running!" );
+
+ // in case this is the first call, ensure all the ranges/weights are calculated
+ // correctly
+ lcl_ensureInitialized( *m_pData );
+
+ const PhaseData& rPhase( m_pData->pCurrentPhase->second );
+
+ double nLocalProgress = 1.0 * _nPhaseProgress / rPhase.nRange;
+ sal_uInt32 nOverallProgress = (sal_uInt32)
+ ( rPhase.nGlobalStart + nLocalProgress * rPhase.nGlobalRange );
+
+ m_pData->rConsumer.advance( nOverallProgress );
+ }
+
+ //--------------------------------------------------------------------
+ void ProgressMixer::endPhase()
+ {
+ OSL_PRECOND( lcl_isRunning( *m_pData ), "ProgresMixer::endPhase: not running!" );
+
+ // in case this is the first call, ensure all the ranges/weights are calculated
+ // correctly
+ lcl_ensureInitialized( *m_pData );
+
+ // simply assume the phase's complete range is over
+ advancePhase( m_pData->pCurrentPhase->second.nRange );
+
+ // if that's the last phase, this is the "global end", too
+ Phases::const_iterator pNextPhase( m_pData->pCurrentPhase );
+ ++pNextPhase;
+ if ( pNextPhase == m_pData->aPhases.end() )
+ m_pData->rConsumer.end();
+ }
+
+//........................................................................
+} // namespace dbmm
+//........................................................................
diff --git a/dbaccess/source/ext/macromigration/progressmixer.hxx b/dbaccess/source/ext/macromigration/progressmixer.hxx
new file mode 100644
index 000000000..8290eca7e
--- /dev/null
+++ b/dbaccess/source/ext/macromigration/progressmixer.hxx
@@ -0,0 +1,103 @@
+/*************************************************************************
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* Copyright 2008 by Sun Microsystems, Inc.
+*
+* OpenOffice.org - a multi-platform office productivity suite
+*
+* $RCSfile: progressmixer.hxx,v $
+*
+* $Revision: 1.1.2.1 $
+*
+* 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.
+************************************************************************/
+
+#ifndef DBACCESS_PROGRESSMIXER_HXX
+#define DBACCESS_PROGRESSMIXER_HXX
+
+/** === begin UNO includes === **/
+/** === end UNO includes === **/
+
+#include <sal/types.h>
+
+#include <memory>
+
+//........................................................................
+namespace dbmm
+{
+//........................................................................
+
+ typedef sal_uInt32 PhaseID;
+ typedef sal_uInt32 PhaseWeight;
+
+ //====================================================================
+ //= IProgressConsumer
+ //====================================================================
+ class SAL_NO_VTABLE IProgressConsumer
+ {
+ public:
+ virtual void start( sal_uInt32 _nRange ) = 0;
+ virtual void advance( sal_uInt32 _nValue ) = 0;
+ virtual void end() = 0;
+ };
+
+ //====================================================================
+ //= ProgressMixer
+ //====================================================================
+ struct ProgressMixer_Data;
+ /** a class which mixes (i.e. concatenates) progress values from different
+ sources/phases, with different weight
+ */
+ class ProgressMixer
+ {
+ public:
+ ProgressMixer( IProgressConsumer& _rConsumer );
+ ~ProgressMixer();
+
+ /** registers a phase of the process, which has the given weight
+ in the overall process
+ @precond
+ the progress is not runnig, yet
+ */
+ void registerPhase( const PhaseID _nID, const PhaseWeight _nWeight );
+
+ /** enters the phase with the given ID, with the phase having
+ the given overall range
+ */
+ void startPhase( const PhaseID _nID, const sal_uInt32 _nPhaseRange );
+
+ /** announces a new progress in the current phase.
+
+ The given phase progress must be between 0 and the overall phase range
+ as specified in ->startPhase.
+ */
+ void advancePhase( const sal_uInt32 _nPhaseProgress );
+
+ /** leaves the current phase, which has been started with ->startPhase previously
+ */
+ void endPhase();
+
+ private:
+ ::std::auto_ptr< ProgressMixer_Data > m_pData;
+ };
+
+//........................................................................
+} // namespace dbmm
+//........................................................................
+
+#endif // DBACCESS_PROGRESSMIXER_HXX
diff --git a/dbaccess/source/filter/migration/cfgimport.cxx b/dbaccess/source/filter/migration/cfgimport.cxx
index 60c861912..213a2af29 100644
--- a/dbaccess/source/filter/migration/cfgimport.cxx
+++ b/dbaccess/source/filter/migration/cfgimport.cxx
@@ -620,7 +620,14 @@ void OCfgImport::createDataSource(const ::rtl::OUString& _sName)
aURL.setExtension(sExtension);
sFileName = aURL.GetMainURL(INetURLObject::NO_DECODE);
}
- m_xModel->attachResource(sFileName,Sequence<PropertyValue>());
+
+ Sequence< PropertyValue > aArgs(1);
+ aArgs[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FileName" ) );
+ aArgs[0].Value <<= sFileName;
+
+ Reference< XLoadable > xLoad( m_xModel, UNO_QUERY_THROW );
+ xLoad->load( aArgs );
+ m_xModel->attachResource( sFileName, Sequence< PropertyValue >() );
}
catch(Exception&)
{
diff --git a/dbaccess/source/filter/xml/dbloader2.cxx b/dbaccess/source/filter/xml/dbloader2.cxx
index c3ef8df30..ccb6433ec 100644
--- a/dbaccess/source/filter/xml/dbloader2.cxx
+++ b/dbaccess/source/filter/xml/dbloader2.cxx
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: dbloader2.cxx,v $
- * $Revision: 1.39 $
+ * $Revision: 1.32.28.13 $
*
* This file is part of OpenOffice.org.
*
@@ -37,7 +37,6 @@
/** === begin UNO includes === **/
#include <com/sun/star/beans/NamedValue.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
-#include <com/sun/star/container/XSet.hpp>
#include <com/sun/star/document/XEventListener.hpp>
#include <com/sun/star/document/XExtendedFilterDetection.hpp>
#include <com/sun/star/document/XFilter.hpp>
@@ -62,6 +61,7 @@
#include <com/sun/star/view/XSelectionSupplier.hpp>
#include <com/sun/star/sdb/application/DatabaseObjectContainer.hpp>
#include <com/sun/star/sdb/application/NamedDatabaseObject.hpp>
+#include <com/sun/star/frame/XLoadable.hpp>
/** === end UNO includes === **/
#include <comphelper/componentcontext.hxx>
@@ -473,16 +473,32 @@ void SAL_CALL DBContentLoader::load(const Reference< XFrame > & rFrame, const ::
}
else
{
- Sequence< Any > aCreationArgs( 1 );
- aCreationArgs[0] <<= NamedValue( INFO_POOLURL, makeAny( sSalvagedURL ) );
- xDocumentDataSource.set( xDatabaseContext->createInstanceWithArguments( aCreationArgs ), UNO_QUERY_THROW );
+ ::comphelper::NamedValueCollection aCreationArgs;
+ aCreationArgs.put( (::rtl::OUString)INFO_POOLURL, sSalvagedURL );
+ xDocumentDataSource.set( xDatabaseContext->createInstanceWithArguments( aCreationArgs.getWrappedNamedValues() ), UNO_QUERY_THROW );
}
xModel.set( xDocumentDataSource->getDatabaseDocument(), UNO_QUERY );
- if ( xModel.is() && bNewAndInteractive )
- {
- const ::rtl::OUString sURL = xModel->getURL();
- bSuccess = impl_executeNewDatabaseWizard( xModel, bStartTableWizard );
+
+ if ( bCreateNew && xModel.is() )
+ {
+ if ( bNewAndInteractive )
+ {
+ bSuccess = impl_executeNewDatabaseWizard( xModel, bStartTableWizard );
+ }
+ else
+ {
+ try
+ {
+ Reference< XLoadable > xLoad( xModel, UNO_QUERY_THROW );
+ xLoad->initNew();
+ bSuccess = true;
+ }
+ catch( const Exception& )
+ {
+ bSuccess = false;
+ }
+ }
// initially select the "Tables" category (will be done below)
nInitialSelection = ::com::sun::star::sdb::application::DatabaseObjectContainer::TABLES;
@@ -501,7 +517,11 @@ void SAL_CALL DBContentLoader::load(const Reference< XFrame > & rFrame, const ::
try
{
aMediaDesc.put( "FileName", _rURL );
- xModel->attachResource( _rURL, aMediaDesc.getPropertyValues() );
+ Reference< XLoadable > xLoad( xModel, UNO_QUERY_THROW );
+
+ Sequence< PropertyValue > aResource( aMediaDesc.getPropertyValues() );
+ xLoad->load( aResource );
+ xModel->attachResource( _rURL, aResource );
}
catch(const Exception&)
{
@@ -523,8 +543,8 @@ void SAL_CALL DBContentLoader::load(const Reference< XFrame > & rFrame, const ::
{
xController->attachModel( xModel );
rFrame->setComponent( xController->getComponentWindow(), xController.get() );
- xModel->setCurrentController( xController.get() );
xController->attachFrame( rFrame );
+ xModel->setCurrentController( xController.get() );
}
}
catch( const Exception& )
@@ -536,43 +556,6 @@ void SAL_CALL DBContentLoader::load(const Reference< XFrame > & rFrame, const ::
if (bSuccess)
{
- try
- {
- Reference< css::container::XSet > xModelCollection;
- if ( m_aContext.createComponent( "com.sun.star.frame.GlobalEventBroadcaster", xModelCollection ) )
- xModelCollection->insert(css::uno::makeAny(xModel));
-
- Reference< css::document::XEventListener > xDocEventBroadcaster(xModel,UNO_QUERY_THROW);
- css::document::EventObject aEvent;
- aEvent.Source = xModel;
- ::std::vector< ::rtl::OUString > aEvents;
- if ( bCreateNew )
- {
- aEvents.push_back(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("OnCreate")));
- aEvents.push_back(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("OnNew"))); // UI event
- }
- else
- {
- aEvents.push_back(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("OnLoadFinished")));
- aEvents.push_back(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("OnLoad"))); // UI event
- }
-
- std::vector< rtl::OUString >::iterator aIter = aEvents.begin();
- const std::vector< rtl::OUString >::iterator aEnd = aEvents.end();
- for (; aIter != aEnd; ++aIter)
- {
- aEvent.EventName = *aIter;
- xDocEventBroadcaster->notifyEvent(aEvent);
- }
-
- aEvent.EventName = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("OnViewCreated"));
- Reference< css::document::XEventListener > xGlobalDocEventBroadcaster(xModelCollection,UNO_QUERY_THROW);
- xGlobalDocEventBroadcaster->notifyEvent(aEvent);
- }
- catch(Exception)
- {
- OSL_ENSURE(0,"Could not add database model to global model collection and broadcast the events OnNew/OnLoad!");
- }
if ( rListener.is() )
rListener->loadFinished(this);
diff --git a/dbaccess/source/filter/xml/xmlEnums.hxx b/dbaccess/source/filter/xml/xmlEnums.hxx
index 60cf4568a..bbcbc2b2e 100644
--- a/dbaccess/source/filter/xml/xmlEnums.hxx
+++ b/dbaccess/source/filter/xml/xmlEnums.hxx
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: xmlEnums.hxx,v $
- * $Revision: 1.7 $
+ * $Revision: 1.7.2.1 $
*
* This file is part of OpenOffice.org.
*
@@ -39,7 +39,8 @@ namespace dbaxml
XML_TOK_DOC_AUTOSTYLES,
XML_TOK_DOC_SETTINGS,
XML_TOK_DOC_DATABASE,
- XML_TOK_DOC_STYLES
+ XML_TOK_DOC_STYLES,
+ XML_TOK_DOC_SCRIPT
};
enum XMLDatabaseToken
{
diff --git a/dbaccess/source/filter/xml/xmlExport.cxx b/dbaccess/source/filter/xml/xmlExport.cxx
index 37de5e0b2..205b02417 100644
--- a/dbaccess/source/filter/xml/xmlExport.cxx
+++ b/dbaccess/source/filter/xml/xmlExport.cxx
@@ -244,10 +244,9 @@ namespace dbaxml
};
// -----------------------------------------------------------------------------
ODBExport::ODBExport(const Reference< XMultiServiceFactory >& _rxMSF,sal_uInt16 nExportFlag)
-: SvXMLExport( _rxMSF,MAP_10TH_MM,XML_DATABASE, EXPORT_OASIS)
+: SvXMLExport( _rxMSF,MAP_10TH_MM,XML_DATABASE, EXPORT_OASIS | nExportFlag)
,m_bAllreadyFilled(sal_False)
{
- setExportFlags( EXPORT_OASIS | nExportFlag);
GetMM100UnitConverter().setCoreMeasureUnit(MAP_10TH_MM);
GetMM100UnitConverter().setXMLMeasureUnit(MAP_CM);
diff --git a/dbaccess/source/filter/xml/xmlExport.hxx b/dbaccess/source/filter/xml/xmlExport.hxx
index bf2773545..9d9101bad 100644
--- a/dbaccess/source/filter/xml/xmlExport.hxx
+++ b/dbaccess/source/filter/xml/xmlExport.hxx
@@ -212,7 +212,7 @@ protected:
virtual ~ODBExport(){};
public:
- ODBExport(const Reference< XMultiServiceFactory >& _rxMSF, sal_uInt16 nExportFlag = EXPORT_CONTENT | EXPORT_AUTOSTYLES | EXPORT_PRETTY|EXPORT_FONTDECLS);
+ ODBExport(const Reference< XMultiServiceFactory >& _rxMSF, sal_uInt16 nExportFlag = EXPORT_CONTENT | EXPORT_AUTOSTYLES | EXPORT_PRETTY | EXPORT_FONTDECLS | EXPORT_SCRIPTS );
// XServiceInfo
DECLARE_SERVICE_INFO_STATIC( );
diff --git a/dbaccess/source/filter/xml/xmlfilter.cxx b/dbaccess/source/filter/xml/xmlfilter.cxx
index c5d0c6312..ac1703de3 100644
--- a/dbaccess/source/filter/xml/xmlfilter.cxx
+++ b/dbaccess/source/filter/xml/xmlfilter.cxx
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: xmlfilter.cxx,v $
- * $Revision: 1.20 $
+ * $Revision: 1.20.2.2 $
*
* This file is part of OpenOffice.org.
*
@@ -55,6 +55,9 @@
#ifndef _XMLOFF_XMLNMSPE_HXX
#include <xmloff/xmlnmspe.hxx>
#endif
+#ifndef _XMLOFF_XMLSCRIPTI_HXX
+#include <xmloff/xmlscripti.hxx>
+#endif
#ifndef _XMLOFF_XMLTOKEN_HXX
#include <xmloff/xmltoken.hxx>
#endif
@@ -216,13 +219,9 @@ sal_Int32 ReadThroughComponent(
{
return ERRCODE_IO_BROKENPACKAGE;
}
- catch( IOException& )
- {
- return 1;
- }
catch( Exception& )
{
- return 1;
+ DBG_UNHANDLED_EXCEPTION();
}
// success!
@@ -474,6 +473,9 @@ SvXMLImportContext* ODBFilter::CreateContext( sal_uInt16 nPrefix,
GetProgressBarHelper()->Increment( PROGRESS_BAR_STEP );
pContext = CreateStylesContext(nPrefix, rLocalName, xAttrList, sal_True);
break;
+ case XML_TOK_DOC_SCRIPT:
+ pContext = CreateScriptContext( rLocalName );
+ break;
}
if ( !pContext )
@@ -538,13 +540,14 @@ const SvXMLTokenMap& ODBFilter::GetDocElemTokenMap() const
static __FAR_DATA SvXMLTokenMapEntry aElemTokenMap[]=
{
{ XML_NAMESPACE_OFFICE, XML_SETTINGS, XML_TOK_DOC_SETTINGS },
- { XML_NAMESPACE_OOO, XML_SETTINGS, XML_TOK_DOC_SETTINGS },
+ { XML_NAMESPACE_OOO, XML_SETTINGS, XML_TOK_DOC_SETTINGS },
{ XML_NAMESPACE_OFFICE, XML_STYLES, XML_TOK_DOC_STYLES },
- { XML_NAMESPACE_OOO, XML_STYLES, XML_TOK_DOC_STYLES },
+ { XML_NAMESPACE_OOO, XML_STYLES, XML_TOK_DOC_STYLES },
{ XML_NAMESPACE_OFFICE, XML_AUTOMATIC_STYLES, XML_TOK_DOC_AUTOSTYLES },
- { XML_NAMESPACE_OOO, XML_AUTOMATIC_STYLES, XML_TOK_DOC_AUTOSTYLES },
+ { XML_NAMESPACE_OOO, XML_AUTOMATIC_STYLES, XML_TOK_DOC_AUTOSTYLES },
{ XML_NAMESPACE_OFFICE, XML_DATABASE, XML_TOK_DOC_DATABASE },
- { XML_NAMESPACE_OOO, XML_DATABASE, XML_TOK_DOC_DATABASE },
+ { XML_NAMESPACE_OOO, XML_DATABASE, XML_TOK_DOC_DATABASE },
+ { XML_NAMESPACE_OFFICE, XML_SCRIPTS, XML_TOK_DOC_SCRIPT },
XML_TOKEN_MAP_END
};
m_pDocElemTokenMap.reset(new SvXMLTokenMap( aElemTokenMap ));
@@ -781,6 +784,11 @@ SvXMLImportContext* ODBFilter::CreateStylesContext(sal_uInt16 _nPrefix,const ::r
return pContext;
}
// -----------------------------------------------------------------------------
+SvXMLImportContext* ODBFilter::CreateScriptContext( const ::rtl::OUString& _rLocalName )
+{
+ return new XMLScriptContext( *this, XML_NAMESPACE_OFFICE, _rLocalName, GetModel() );
+}
+// -----------------------------------------------------------------------------
UniReference < XMLPropertySetMapper > ODBFilter::GetTableStylesPropertySetMapper() const
{
if ( !m_xTableStylesPropertySetMapper.is() )
diff --git a/dbaccess/source/filter/xml/xmlfilter.hxx b/dbaccess/source/filter/xml/xmlfilter.hxx
index 16977718d..762cb8a49 100644
--- a/dbaccess/source/filter/xml/xmlfilter.hxx
+++ b/dbaccess/source/filter/xml/xmlfilter.hxx
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: xmlfilter.hxx,v $
- * $Revision: 1.8 $
+ * $Revision: 1.8.2.1 $
*
* This file is part of OpenOffice.org.
*
@@ -146,6 +146,8 @@ private:
SvXMLImportContext* CreateStylesContext(sal_uInt16 nPrefix,const ::rtl::OUString& rLocalName,
const Reference< XAttributeList>& xAttrList, sal_Bool bIsAutoStyle );
+ SvXMLImportContext* CreateScriptContext( const ::rtl::OUString& rLocalName );
+
protected:
// SvXMLImport
virtual SvXMLImportContext *CreateContext( sal_uInt16 nPrefix,
diff --git a/dbaccess/source/ui/app/AppController.cxx b/dbaccess/source/ui/app/AppController.cxx
index 712b6ed72..867000b0d 100644
--- a/dbaccess/source/ui/app/AppController.cxx
+++ b/dbaccess/source/ui/app/AppController.cxx
@@ -76,6 +76,7 @@
#include <com/sun/star/task/XInteractionHandler.hpp>
#include <com/sun/star/sdb/application/DatabaseObject.hpp>
#include <com/sun/star/sdb/application/DatabaseObjectContainer.hpp>
+#include <com/sun/star/document/XDocumentEventBroadcaster.hpp>
/** === end UNO includes === **/
#ifndef _TOOLS_DEBUG_HXX
@@ -263,6 +264,8 @@ using namespace ::com::sun::star::datatransfer;
using namespace ::com::sun::star::ui::dialogs;
using namespace ::com::sun::star::task;
using ::com::sun::star::document::XEmbeddedScripts;
+using ::com::sun::star::document::XDocumentEventBroadcaster;
+using ::com::sun::star::document::DocumentEvent;
using ::com::sun::star::sdb::application::NamedDatabaseObject;
namespace DatabaseObject = ::com::sun::star::sdb::application::DatabaseObject;
@@ -513,18 +516,22 @@ void SAL_CALL OApplicationController::disposing()
::rtl::OUString sUrl = m_xModel->getURL();
if ( sUrl.getLength() )
{
- ::rtl::OUString aFilter;
- INetURLObject aURL( m_xModel->getURL() );
- const SfxFilter* pFilter = getStandardDatabaseFilter();
- if ( pFilter )
- aFilter = pFilter->GetFilterName();
-
- // add to svtool history options
- SvtHistoryOptions().AppendItem( ePICKLIST,
- aURL.GetURLNoPass( INetURLObject::NO_DECODE ),
- aFilter,
- getStrippedDatabaseName(),
- ::rtl::OUString() );
+ ::comphelper::NamedValueCollection aArgs( m_xModel->getArgs() );
+ if ( true == aArgs.getOrDefault( "PickListEntry", true ) )
+ {
+ ::rtl::OUString aFilter;
+ INetURLObject aURL( m_xModel->getURL() );
+ const SfxFilter* pFilter = getStandardDatabaseFilter();
+ if ( pFilter )
+ aFilter = pFilter->GetFilterName();
+
+ // add to svtool history options
+ SvtHistoryOptions().AppendItem( ePICKLIST,
+ aURL.GetURLNoPass( INetURLObject::NO_DECODE ),
+ aFilter,
+ getStrippedDatabaseName(),
+ ::rtl::OUString() );
+ }
}
m_aModelConnector.clear();
@@ -533,6 +540,7 @@ void SAL_CALL OApplicationController::disposing()
}
catch(Exception)
{
+ DBG_UNHANDLED_EXCEPTION();
}
m_pView = NULL;
@@ -642,6 +650,17 @@ void SAL_CALL OApplicationController::disposing(const EventObject& _rSource) thr
//--------------------------------------------------------------------
sal_Bool SAL_CALL OApplicationController::suspend(sal_Bool bSuspend) throw( RuntimeException )
{
+ // notify the OnPrepareViewClosing event (before locking any mutex)
+ Reference< XDocumentEventBroadcaster > xBroadcaster( m_xModel, UNO_QUERY );
+ if ( xBroadcaster.is() )
+ {
+ xBroadcaster->notifyDocumentEvent(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OnPrepareViewClosing" ) ),
+ this,
+ Any()
+ );
+ }
+
::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
::osl::MutexGuard aGuard(m_aMutex);
@@ -819,11 +838,9 @@ FeatureState OApplicationController::GetState(sal_uInt16 _nId) const
// Our document supports embedding scripts into it, if and only if there are no
// forms/reports with macros/scripts into them. So, we need to enable migration
// if and only if the database document does *not* support embedding scripts.
-// bool bAvailable = !Reference< XEmbeddedScripts >( m_xModel, UNO_QUERY ).is();
- // TODO: revert to the disabled code. The current version is just to be able
- // to integrate an intermediate version of the CWS, which should behave as
- // if no macros in DB docs are allowed
- bool bAvailable = false;
+ bool bAvailable =
+ !Reference< XEmbeddedScripts >( m_xModel, UNO_QUERY ).is()
+ && !Reference< XStorable >( m_xModel, UNO_QUERY_THROW )->isReadonly();
aReturn.bEnabled = bAvailable;
if ( !bAvailable )
aReturn.bInvisible = true;
@@ -2732,11 +2749,6 @@ IMPL_LINK( OApplicationController, OnFirstControllerConnected, void*, /**/ )
// if we have forms or reports which contain macros/scripts, then show a warning
// which suggests the user to migrate them to the database document
- // TODO: remove the following line. The current version is just to be able
- // to integrate an intermediate version of the CWS, which should behave as
- // if no macros in DB docs are allowed
- return 0L;
-/*
Reference< XEmbeddedScripts > xDocumentScripts( m_xModel, UNO_QUERY );
if ( xDocumentScripts.is() )
{
@@ -2779,7 +2791,6 @@ IMPL_LINK( OApplicationController, OnFirstControllerConnected, void*, /**/ )
}
return 1L;
-*/
}
// -----------------------------------------------------------------------------
@@ -2801,7 +2812,7 @@ sal_Bool SAL_CALL OApplicationController::attachModel(const Reference< XModel >
if ( _rxModel.is() )
{
m_xDocumentModify.set( m_xModel, UNO_QUERY_THROW );
- m_aModelConnector = ModelControllerConnector( _rxModel, this );
+ m_aModelConnector.connect( _rxModel, this );
onConnectedModel();
}
else
diff --git a/dbaccess/source/ui/app/AppControllerDnD.cxx b/dbaccess/source/ui/app/AppControllerDnD.cxx
index 6a8306195..eff26fc07 100644
--- a/dbaccess/source/ui/app/AppControllerDnD.cxx
+++ b/dbaccess/source/ui/app/AppControllerDnD.cxx
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: AppControllerDnD.cxx,v $
- * $Revision: 1.29 $
+ * $Revision: 1.26.6.4 $
*
* This file is part of OpenOffice.org.
*
diff --git a/dbaccess/source/ui/app/AppControllerGen.cxx b/dbaccess/source/ui/app/AppControllerGen.cxx
index 7e1c03a8c..392b48428 100644
--- a/dbaccess/source/ui/app/AppControllerGen.cxx
+++ b/dbaccess/source/ui/app/AppControllerGen.cxx
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: AppControllerGen.cxx,v $
- * $Revision: 1.37 $
+ * $Revision: 1.32.6.5 $
*
* This file is part of OpenOffice.org.
*
diff --git a/dbaccess/source/ui/app/AppView.cxx b/dbaccess/source/ui/app/AppView.cxx
index 8888c62d5..01fa100b4 100644
--- a/dbaccess/source/ui/app/AppView.cxx
+++ b/dbaccess/source/ui/app/AppView.cxx
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: AppView.cxx,v $
- * $Revision: 1.25 $
+ * $Revision: 1.22.6.3 $
*
* This file is part of OpenOffice.org.
*
diff --git a/dbaccess/source/ui/app/app.src b/dbaccess/source/ui/app/app.src
index 76ef3465a..3f9ff4e74 100644
--- a/dbaccess/source/ui/app/app.src
+++ b/dbaccess/source/ui/app/app.src
@@ -451,18 +451,17 @@ String STR_FOLDER_LABEL
String STR_SUB_DOCS_WITH_SCRIPTS
{
- Text [ en-US ] = "The document contains forms and/or reports with macros and/or scripts embedded.";
+ Text [ en-US ] = "The document contains forms or reports with embedded macros.";
};
String STR_SUB_DOCS_WITH_SCRIPTS_DETAIL
{
- Text [ en-US ] = "Scripts and macros should nowadays be embedded into the database document itself.\n\n"
+ Text [ en-US ] = "Macros should be embedded into the database document itself.\n\n"
"You can continue to use your document as before, however, you are encouraged to migrate "
- "your scripts and macros. The menu item 'Tools / Migrate Scripts and Macros ...' will "
- "assist you with this.\n\n"
+ "your macros. The menu item 'Tools / Migrate Macros ...' will assist you with this.\n\n"
- "Note that you won't be able to embed macros or scripts into the database document until "
+ "Note that you won't be able to embed macros into the database document itself until "
"this migration is done. ";
};
diff --git a/dbaccess/source/ui/browser/brwctrlr.cxx b/dbaccess/source/ui/browser/brwctrlr.cxx
index ce3730fce..3fd77bc23 100644
--- a/dbaccess/source/ui/browser/brwctrlr.cxx
+++ b/dbaccess/source/ui/browser/brwctrlr.cxx
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: brwctrlr.cxx,v $
- * $Revision: 1.108 $
+ * $Revision: 1.105.6.3 $
*
* This file is part of OpenOffice.org.
*
diff --git a/dbaccess/source/ui/browser/dbloader.cxx b/dbaccess/source/ui/browser/dbloader.cxx
index fbf01d77b..c7c3116a6 100644
--- a/dbaccess/source/ui/browser/dbloader.cxx
+++ b/dbaccess/source/ui/browser/dbloader.cxx
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: dbloader.cxx,v $
- * $Revision: 1.37 $
+ * $Revision: 1.36.2.3 $
*
* This file is part of OpenOffice.org.
*
@@ -335,15 +335,6 @@ void SAL_CALL DBContentLoader::load(const Reference< XFrame > & rFrame, const ::
xController->attachFrame(rFrame);
}
- if ( xDatabaseDocument.is() )
- {
- Reference< document::XEventListener > xGlobalDocEventBroadcaster(m_xServiceFactory->createInstance(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.GlobalEventBroadcaster"))),UNO_QUERY_THROW);
- document::EventObject aEvent( xDatabaseDocument, ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("OnViewCreated")) );
- xGlobalDocEventBroadcaster->notifyEvent(aEvent);
- // TODO: is this correct? The newly created view is not a view for the database document, at least not in
- // the sense that its XController::getModel would return the database document
- }
-
if ( rListener.is() )
rListener->loadFinished( this );
}
diff --git a/dbaccess/source/ui/browser/dsbrowserDnD.cxx b/dbaccess/source/ui/browser/dsbrowserDnD.cxx
index 186e7d065..1a3647ed3 100644
--- a/dbaccess/source/ui/browser/dsbrowserDnD.cxx
+++ b/dbaccess/source/ui/browser/dsbrowserDnD.cxx
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: dsbrowserDnD.cxx,v $
- * $Revision: 1.81 $
+ * $Revision: 1.78.140.3 $
*
* This file is part of OpenOffice.org.
*
diff --git a/dbaccess/source/ui/browser/exsrcbrw.cxx b/dbaccess/source/ui/browser/exsrcbrw.cxx
index b38ab3889..44747c699 100644
--- a/dbaccess/source/ui/browser/exsrcbrw.cxx
+++ b/dbaccess/source/ui/browser/exsrcbrw.cxx
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: exsrcbrw.cxx,v $
- * $Revision: 1.34 $
+ * $Revision: 1.32.6.2 $
*
* This file is part of OpenOffice.org.
*
diff --git a/dbaccess/source/ui/browser/sbagrid.cxx b/dbaccess/source/ui/browser/sbagrid.cxx
index b7d93c96a..1708d1c0d 100644
--- a/dbaccess/source/ui/browser/sbagrid.cxx
+++ b/dbaccess/source/ui/browser/sbagrid.cxx
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: sbagrid.cxx,v $
- * $Revision: 1.86 $
+ * $Revision: 1.83.6.3 $
*
* This file is part of OpenOffice.org.
*
diff --git a/dbaccess/source/ui/browser/unodatbr.cxx b/dbaccess/source/ui/browser/unodatbr.cxx
index 424587a26..7a31f55f4 100644
--- a/dbaccess/source/ui/browser/unodatbr.cxx
+++ b/dbaccess/source/ui/browser/unodatbr.cxx
@@ -3094,11 +3094,6 @@ void SbaTableQueryBrowser::impl_initialize()
m_aDocScriptSupport = ::boost::optional< bool >( Reference< XEmbeddedScripts >( xDocument, UNO_QUERY ).is() );
}
- // TODO: remove the following line. The current version is just to be able
- // to integrate an intermediate version of the CWS, which should behave as
- // if no macros in DB docs are allowed
- m_aDocScriptSupport = ::boost::optional< bool> ( false );
-
if ( implSelect( sInitialDataSourceName, sInitialCommand, nInitialDisplayCommandType, bEsacpeProcessing, xConnection, sal_True ) )
{
try
diff --git a/dbaccess/source/ui/control/RelationControl.cxx b/dbaccess/source/ui/control/RelationControl.cxx
index 4fd12aa7b..aecebb252 100644
--- a/dbaccess/source/ui/control/RelationControl.cxx
+++ b/dbaccess/source/ui/control/RelationControl.cxx
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: RelationControl.cxx,v $
- * $Revision: 1.25 $
+ * $Revision: 1.23.6.2 $
*
* This file is part of OpenOffice.org.
*
diff --git a/dbaccess/source/ui/control/tabletree.cxx b/dbaccess/source/ui/control/tabletree.cxx
index 9f9f29b2d..50e3b4b8c 100644
--- a/dbaccess/source/ui/control/tabletree.cxx
+++ b/dbaccess/source/ui/control/tabletree.cxx
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: tabletree.cxx,v $
- * $Revision: 1.38 $
+ * $Revision: 1.35.78.3 $
*
* This file is part of OpenOffice.org.
*
diff --git a/dbaccess/source/ui/control/toolboxcontroller.cxx b/dbaccess/source/ui/control/toolboxcontroller.cxx
index 34a776071..d87511346 100644
--- a/dbaccess/source/ui/control/toolboxcontroller.cxx
+++ b/dbaccess/source/ui/control/toolboxcontroller.cxx
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: toolboxcontroller.cxx,v $
- * $Revision: 1.15 $
+ * $Revision: 1.13.98.2 $
*
* This file is part of OpenOffice.org.
*
diff --git a/dbaccess/source/ui/dlg/AdabasStat.cxx b/dbaccess/source/ui/dlg/AdabasStat.cxx
index 8b48b88bb..deb8ea845 100644
--- a/dbaccess/source/ui/dlg/AdabasStat.cxx
+++ b/dbaccess/source/ui/dlg/AdabasStat.cxx
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: AdabasStat.cxx,v $
- * $Revision: 1.19 $
+ * $Revision: 1.17.158.2 $
*
* This file is part of OpenOffice.org.
*
diff --git a/dbaccess/source/ui/dlg/ConnectionPage.src b/dbaccess/source/ui/dlg/ConnectionPage.src
index 5ee309d87..f8ba12cda 100644
--- a/dbaccess/source/ui/dlg/ConnectionPage.src
+++ b/dbaccess/source/ui/dlg/ConnectionPage.src
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: ConnectionPage.src,v $
- * $Revision: 1.8 $
+ * $Revision: 1.8.2.1 $
*
* This file is part of OpenOffice.org.
*
@@ -165,7 +165,7 @@ String STR_CONNECTION_SUCCESS
String STR_CONNECTION_NO_SUCCESS
{
- Text [ en-US ] = "The connection could not be established successfully.";
+ Text [ en-US ] = "The connection could not be established.";
};
String STR_JDBCDRIVER_SUCCESS
diff --git a/dbaccess/source/ui/dlg/ExtensionNotPresent.cxx b/dbaccess/source/ui/dlg/ExtensionNotPresent.cxx
index 1c8777747..645793979 100644
--- a/dbaccess/source/ui/dlg/ExtensionNotPresent.cxx
+++ b/dbaccess/source/ui/dlg/ExtensionNotPresent.cxx
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: ExtensionNotPresent.cxx,v $
- * $Revision: 1.4 $
+ * $Revision: 1.2.158.2 $
*
* This file is part of OpenOffice.org.
*
diff --git a/dbaccess/source/ui/dlg/adminpages.cxx b/dbaccess/source/ui/dlg/adminpages.cxx
index 9f540e360..650d54d9d 100644
--- a/dbaccess/source/ui/dlg/adminpages.cxx
+++ b/dbaccess/source/ui/dlg/adminpages.cxx
@@ -320,7 +320,7 @@ namespace dbaui
eImage = OSQLMessageBox::Error;
aMessage = String(ModuleRes(STR_CONNECTION_NO_SUCCESS));
}
- OSQLMessageBox aMsg(this,sTitle,aMessage,eImage);
+ OSQLMessageBox aMsg( this, sTitle, aMessage, WB_OK, eImage );
aMsg.Execute();
}
if ( !bSuccess )
diff --git a/dbaccess/source/ui/dlg/dbwizsetup.cxx b/dbaccess/source/ui/dlg/dbwizsetup.cxx
index 36993b528..1f0ef64d0 100644
--- a/dbaccess/source/ui/dlg/dbwizsetup.cxx
+++ b/dbaccess/source/ui/dlg/dbwizsetup.cxx
@@ -915,74 +915,30 @@ void ODbTypeWizDialogSetup::enableConfirmSettings( bool _bEnable )
//-------------------------------------------------------------------------
sal_Bool ODbTypeWizDialogSetup::SaveDatabaseDocument()
{
- Reference< XInteractionHandler > xHandler(getORB()->createInstance(SERVICE_TASK_INTERACTION_HANDLER), UNO_QUERY);
+ Reference< XInteractionHandler > xHandler( getORB()->createInstance( SERVICE_TASK_INTERACTION_HANDLER ), UNO_QUERY );
try
{
if (callSaveAsDialog() == sal_True)
{
m_pImpl->saveChanges(*m_pOutSet);
Reference< XPropertySet > xDatasource = m_pImpl->getCurrentDataSource();
-#if OSL_DEBUG_LEVEL > 0
- SFX_ITEMSET_GET(*m_pOutSet, pDocUrl, SfxStringItem, DSID_DOCUMENT_URL, sal_True);
- (void)pDocUrl;
-#endif
- Reference<XStorable> xStore(getDataSourceOrModel(xDatasource),UNO_QUERY);
- Reference<XComponent> xComponent(xStore,UNO_QUERY);
- ::rtl::OUString sPath = m_pImpl->getDocumentUrl(*m_pOutSet);
- if ( xStore.is() )
- {
- if ( m_pGeneralPage->GetDatabaseCreationMode() == OGeneralPage::eCreateNew )
- CreateDatabase();
- Reference< XModel > xModel(xStore, UNO_QUERY);
-
- Sequence<PropertyValue> aArgs = xModel->getArgs();
-
- sal_Bool bOverwrite = sal_True;
- sal_Bool bAddOverwrite = sal_True;
- sal_Bool bAddInteractionHandler = sal_True;
- PropertyValue* pIter = aArgs.getArray();
- PropertyValue* pEnd = pIter + aArgs.getLength();
- for(;pIter != pEnd;++pIter)
- {
- if ( pIter->Name.equalsAscii("Overwrite") )
- {
- pIter->Value <<= bOverwrite;
- bAddOverwrite = sal_False;
- }
- if ( pIter->Name.equalsAscii("InteractionHandler") )
- {
- pIter->Value <<= xHandler;
- bAddInteractionHandler = sal_False;
- }
+ Reference< XModel > xModel( getDataSourceOrModel( xDatasource ), UNO_QUERY_THROW );
+ Reference< XStorable > xStore( xModel, UNO_QUERY_THROW );
- }
- if ( bAddOverwrite )
- {
- sal_Int32 nLen = aArgs.getLength();
- aArgs.realloc(nLen+1);
- aArgs[nLen].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Overwrite"));
- aArgs[nLen].Value <<= bOverwrite;
- }
- if ( bAddInteractionHandler )
- {
- sal_Int32 nLen = aArgs.getLength();
- aArgs.realloc(nLen+1);
- aArgs[nLen].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("InteractionHandler"));
- aArgs[nLen].Value <<= xHandler;
- }
- xStore->storeAsURL(sPath,aArgs);
+ if ( m_pGeneralPage->GetDatabaseCreationMode() == OGeneralPage::eCreateNew )
+ CreateDatabase();
- if (pFinalPage != NULL)
- {
- if (pFinalPage->IsDatabaseDocumentToBeRegistered())
- RegisterDataSourceByLocation(sPath);
- }
- else
- {
- RegisterDataSourceByLocation(sPath);
- }
- return sal_True;
- }
+ ::comphelper::NamedValueCollection aArgs( xModel->getArgs() );
+ aArgs.put( "Overwrite", sal_Bool( sal_True ) );
+ aArgs.put( "InteractionHandler", xHandler );
+
+ ::rtl::OUString sPath = m_pImpl->getDocumentUrl( *m_pOutSet );
+ xStore->storeAsURL( sPath, aArgs.getPropertyValues() );
+
+ if ( !pFinalPage || pFinalPage->IsDatabaseDocumentToBeRegistered() )
+ RegisterDataSourceByLocation( sPath );
+
+ return sal_True;
}
}
catch (Exception& e)
@@ -1318,10 +1274,10 @@ sal_Bool ODbTypeWizDialogSetup::SaveDatabaseDocument()
skipUntil(PAGE_DBSETUPWIZARD_FINAL);
}
if (getCurrentState() == PAGE_DBSETUPWIZARD_FINAL)
- return SaveDatabaseDocument() ? OWizardMachine::onFinish(_nResult) : sal_False;
+ return SaveDatabaseDocument() ? OWizardMachine::onFinish( _nResult ) : sal_False;
else
{
- enableButtons( WZB_FINISH, sal_False);
+ enableButtons( WZB_FINISH, sal_False );
return sal_False;
}
}
diff --git a/dbaccess/source/ui/dlg/directsql.cxx b/dbaccess/source/ui/dlg/directsql.cxx
index a0c4e37e9..0e18cfc23 100644
--- a/dbaccess/source/ui/dlg/directsql.cxx
+++ b/dbaccess/source/ui/dlg/directsql.cxx
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: directsql.cxx,v $
- * $Revision: 1.12 $
+ * $Revision: 1.10.158.2 $
*
* This file is part of OpenOffice.org.
*
diff --git a/dbaccess/source/ui/dlg/queryorder.cxx b/dbaccess/source/ui/dlg/queryorder.cxx
index 03b71ccfa..8c086cbb4 100644
--- a/dbaccess/source/ui/dlg/queryorder.cxx
+++ b/dbaccess/source/ui/dlg/queryorder.cxx
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: queryorder.cxx,v $
- * $Revision: 1.22 $
+ * $Revision: 1.20.172.2 $
*
* This file is part of OpenOffice.org.
*
diff --git a/dbaccess/source/ui/dlg/tablespage.cxx b/dbaccess/source/ui/dlg/tablespage.cxx
index c763d12e1..ad9969c2e 100644
--- a/dbaccess/source/ui/dlg/tablespage.cxx
+++ b/dbaccess/source/ui/dlg/tablespage.cxx
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: tablespage.cxx,v $
- * $Revision: 1.35 $
+ * $Revision: 1.33.6.2 $
*
* This file is part of OpenOffice.org.
*
diff --git a/dbaccess/source/ui/inc/brwctrlr.hxx b/dbaccess/source/ui/inc/brwctrlr.hxx
index 2e8b993b4..b817d6b05 100644
--- a/dbaccess/source/ui/inc/brwctrlr.hxx
+++ b/dbaccess/source/ui/inc/brwctrlr.hxx
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: brwctrlr.hxx,v $
- * $Revision: 1.43 $
+ * $Revision: 1.40.6.3 $
*
* This file is part of OpenOffice.org.
*
diff --git a/dbaccess/source/ui/misc/DExport.cxx b/dbaccess/source/ui/misc/DExport.cxx
index 5096223a6..2b8d48a45 100644
--- a/dbaccess/source/ui/misc/DExport.cxx
+++ b/dbaccess/source/ui/misc/DExport.cxx
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: DExport.cxx,v $
- * $Revision: 1.42 $
+ * $Revision: 1.40.32.2 $
*
* This file is part of OpenOffice.org.
*
diff --git a/dbaccess/source/ui/misc/TableCopyHelper.cxx b/dbaccess/source/ui/misc/TableCopyHelper.cxx
index 947e659b4..b2a344dd4 100644
--- a/dbaccess/source/ui/misc/TableCopyHelper.cxx
+++ b/dbaccess/source/ui/misc/TableCopyHelper.cxx
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: TableCopyHelper.cxx,v $
- * $Revision: 1.13 $
+ * $Revision: 1.11.32.2 $
*
* This file is part of OpenOffice.org.
*
diff --git a/dbaccess/source/ui/misc/TokenWriter.cxx b/dbaccess/source/ui/misc/TokenWriter.cxx
index 0ed988bd3..dee480dfc 100644
--- a/dbaccess/source/ui/misc/TokenWriter.cxx
+++ b/dbaccess/source/ui/misc/TokenWriter.cxx
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: TokenWriter.cxx,v $
- * $Revision: 1.39 $
+ * $Revision: 1.36.14.3 $
*
* This file is part of OpenOffice.org.
*
diff --git a/dbaccess/source/ui/misc/controllerframe.cxx b/dbaccess/source/ui/misc/controllerframe.cxx
index 9476a2b6e..7f975eff3 100644
--- a/dbaccess/source/ui/misc/controllerframe.cxx
+++ b/dbaccess/source/ui/misc/controllerframe.cxx
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: controllerframe.cxx,v $
- * $Revision: 1.3 $
+ * $Revision: 1.3.2.2 $
*
* This file is part of OpenOffice.org.
*
@@ -36,6 +36,8 @@
#include <com/sun/star/awt/XTopWindow.hpp>
#include <com/sun/star/awt/XWindow2.hpp>
#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/document/XDocumentEventBroadcaster.hpp>
+#include <com/sun/star/frame/XController2.hpp>
/** === end UNO includes === **/
#include <cppuhelper/implbase1.hxx>
@@ -66,6 +68,7 @@ namespace dbaui
using ::com::sun::star::frame::FrameAction_FRAME_UI_DEACTIVATING;
using ::com::sun::star::frame::XModel;
using ::com::sun::star::frame::XController;
+ using ::com::sun::star::frame::XController2;
using ::com::sun::star::frame::XFramesSupplier;
using ::com::sun::star::sdb::XOfficeDatabaseDocument;
using ::com::sun::star::awt::XTopWindow;
@@ -73,6 +76,7 @@ namespace dbaui
using ::com::sun::star::awt::XWindow2;
using ::com::sun::star::lang::DisposedException;
using ::com::sun::star::lang::EventObject;
+ using ::com::sun::star::document::XDocumentEventBroadcaster;
/** === end UNO using === **/
//====================================================================
@@ -118,6 +122,7 @@ namespace dbaui
ControllerFrame_Data( IController& _rController )
:m_rController( _rController )
,m_xFrame()
+ ,m_xDocEventBroadcaster()
,m_pListener()
,m_bActive( false )
{
@@ -125,6 +130,7 @@ namespace dbaui
IController& m_rController;
Reference< XFrame > m_xFrame;
+ Reference< XDocumentEventBroadcaster > m_xDocEventBroadcaster;
::rtl::Reference< FrameWindowActivationListener > m_pListener;
bool m_bActive;
};
@@ -141,11 +147,26 @@ namespace dbaui
_rData.m_pListener->dispose();
_rData.m_pListener = NULL;
}
+
// remember new frame
_rData.m_xFrame = _rxFrame;
+
// create new listener
if ( _rData.m_xFrame.is() )
_rData.m_pListener = new FrameWindowActivationListener( _rData );
+
+ // at this point in time, we can assume the controller also has a model set, if it supports models
+ try
+ {
+ Reference< XController > xController( _rData.m_rController.getXController(), UNO_SET_THROW );
+ Reference< XModel > xModel( xController->getModel() );
+ if ( xModel.is() )
+ _rData.m_xDocEventBroadcaster.set( xModel, UNO_QUERY );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
}
//--------------------------------------------------------------------
@@ -204,6 +225,26 @@ namespace dbaui
}
//--------------------------------------------------------------------
+ /** broadcasts the OnFocus resp. OnUnfocus event
+ */
+ static void lcl_notifyFocusChange_nothrow( ControllerFrame_Data& _rData, bool _bActive )
+ {
+ try
+ {
+ if ( _rData.m_xDocEventBroadcaster.is() )
+ {
+ ::rtl::OUString sEventName( ::rtl::OUString::createFromAscii( _bActive ? "OnFocus" : "OnUnfocus" ) );
+ Reference< XController2 > xController( _rData.m_rController.getXController(), UNO_QUERY_THROW );
+ _rData.m_xDocEventBroadcaster->notifyDocumentEvent( sEventName, xController, Any() );
+ }
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+
+ //--------------------------------------------------------------------
static void lcl_updateActive_nothrow( ControllerFrame_Data& _rData, bool _bActive )
{
if ( _rData.m_bActive == _bActive )
@@ -211,6 +252,7 @@ namespace dbaui
_rData.m_bActive = _bActive;
lcl_updateActiveComponents_nothrow( _rData );
+ lcl_notifyFocusChange_nothrow( _rData, _bActive );
}
//--------------------------------------------------------------------
@@ -335,7 +377,10 @@ namespace dbaui
// update active component
if ( m_pData->m_bActive )
+ {
lcl_updateActiveComponents_nothrow( *m_pData );
+ lcl_notifyFocusChange_nothrow( *m_pData, true );
+ }
return m_pData->m_xFrame;
}
diff --git a/dbaccess/source/ui/misc/databaseobjectview.cxx b/dbaccess/source/ui/misc/databaseobjectview.cxx
index 9ee23e612..a38cad920 100644
--- a/dbaccess/source/ui/misc/databaseobjectview.cxx
+++ b/dbaccess/source/ui/misc/databaseobjectview.cxx
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: databaseobjectview.cxx,v $
- * $Revision: 1.11 $
+ * $Revision: 1.8.6.3 $
*
* This file is part of OpenOffice.org.
*
diff --git a/dbaccess/source/ui/misc/documentcontroller.cxx b/dbaccess/source/ui/misc/documentcontroller.cxx
index 007c79ddc..34132b99c 100644
--- a/dbaccess/source/ui/misc/documentcontroller.cxx
+++ b/dbaccess/source/ui/misc/documentcontroller.cxx
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: documentcontroller.cxx,v $
- * $Revision: 1.7 $
+ * $Revision: 1.5.178.4 $
*
* This file is part of OpenOffice.org.
*
@@ -83,11 +83,14 @@ namespace dbaui
}
//--------------------------------------------------------------------
- void ModelControllerConnector::swap( ModelControllerConnector& _rSource )
+ void ModelControllerConnector::connect( const Reference< XModel >& _rxModel, const Reference< XController >& _rxController )
{
- ModelControllerConnector aTemp( _rSource );
- _rSource.impl_copyFrom( *this );
- impl_copyFrom( aTemp );
+ impl_disconnect();
+
+ m_xModel = _rxModel;
+ m_xController = _rxController;
+
+ impl_connect();
}
//--------------------------------------------------------------------
diff --git a/dbaccess/source/ui/misc/dsmeta.cxx b/dbaccess/source/ui/misc/dsmeta.cxx
index 2a6f7374e..c53d8ca85 100644
--- a/dbaccess/source/ui/misc/dsmeta.cxx
+++ b/dbaccess/source/ui/misc/dsmeta.cxx
@@ -68,26 +68,26 @@ namespace dbaui
bAutoIncrementIsPrimaryKey = ( _AutoPKey != 0 );
}
- enum Special { All, None };
+ enum Special { All, AllButIgnoreCurrency, None };
InitAdvanced( Special _eType )
:AdvancedSettingsSupport()
{
- bGeneratedValues = ( _eType == All );
- bUseSQL92NamingConstraints = ( _eType == All );
- bAppendTableAliasInSelect = ( _eType == All );
- bUseKeywordAsBeforeAlias = ( _eType == All );
- bUseBracketedOuterJoinSyntax = ( _eType == All );
- bIgnoreDriverPrivileges = ( _eType == All );
- bParameterNameSubstitution = ( _eType == All );
- bDisplayVersionColumns = ( _eType == All );
- bUseCatalogInSelect = ( _eType == All );
- bUseSchemaInSelect = ( _eType == All );
- bUseIndexDirectionKeyword = ( _eType == All );
- bUseDOSLineEnds = ( _eType == All );
- bBooleanComparisonMode = ( _eType == All );
- bFormsCheckRequiredFields = ( _eType == All );
- bIgnoreCurrency = false; // Oracle special
+ bGeneratedValues = ( _eType == All ) || ( _eType == AllButIgnoreCurrency );
+ bUseSQL92NamingConstraints = ( _eType == All ) || ( _eType == AllButIgnoreCurrency );
+ bAppendTableAliasInSelect = ( _eType == All ) || ( _eType == AllButIgnoreCurrency );
+ bUseKeywordAsBeforeAlias = ( _eType == All ) || ( _eType == AllButIgnoreCurrency );
+ bUseBracketedOuterJoinSyntax = ( _eType == All ) || ( _eType == AllButIgnoreCurrency );
+ bIgnoreDriverPrivileges = ( _eType == All ) || ( _eType == AllButIgnoreCurrency );
+ bParameterNameSubstitution = ( _eType == All ) || ( _eType == AllButIgnoreCurrency );
+ bDisplayVersionColumns = ( _eType == All ) || ( _eType == AllButIgnoreCurrency );
+ bUseCatalogInSelect = ( _eType == All ) || ( _eType == AllButIgnoreCurrency );
+ bUseSchemaInSelect = ( _eType == All ) || ( _eType == AllButIgnoreCurrency );
+ bUseIndexDirectionKeyword = ( _eType == All ) || ( _eType == AllButIgnoreCurrency );
+ bUseDOSLineEnds = ( _eType == All ) || ( _eType == AllButIgnoreCurrency );
+ bBooleanComparisonMode = ( _eType == All ) || ( _eType == AllButIgnoreCurrency );
+ bFormsCheckRequiredFields = ( _eType == All ) || ( _eType == AllButIgnoreCurrency );
+ bIgnoreCurrency = ( _eType == All );
bAutoIncrementIsPrimaryKey = false; // hsqldb special
}
};
@@ -128,8 +128,8 @@ namespace dbaui
s_aSupport[ ::dbaccess::DST_CALC ] = InitAdvanced( InitAdvanced::None );
s_aSupport[ ::dbaccess::DST_DBASE ] = InitAdvanced( 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 );
s_aSupport[ ::dbaccess::DST_FLAT ] = InitAdvanced( 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 );
- s_aSupport[ ::dbaccess::DST_JDBC ] = InitAdvanced( InitAdvanced::All );
- s_aSupport[ ::dbaccess::DST_ODBC ] = InitAdvanced( InitAdvanced::All );
+ s_aSupport[ ::dbaccess::DST_JDBC ] = InitAdvanced( InitAdvanced::AllButIgnoreCurrency );
+ s_aSupport[ ::dbaccess::DST_ODBC ] = InitAdvanced( InitAdvanced::AllButIgnoreCurrency );
s_aSupport[ ::dbaccess::DST_ADO ] = InitAdvanced( 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0 );
s_aSupport[ ::dbaccess::DST_MOZILLA ] = InitAdvanced( InitAdvanced::None );
s_aSupport[ ::dbaccess::DST_THUNDERBIRD ] = InitAdvanced( InitAdvanced::None );
@@ -143,18 +143,16 @@ namespace dbaui
s_aSupport[ ::dbaccess::DST_MACAB ] = InitAdvanced( InitAdvanced::None );
s_aSupport[ ::dbaccess::DST_MSACCESS_2007 ] = InitAdvanced( 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0 );
s_aSupport[ ::dbaccess::DST_EMBEDDED_HSQLDB ] = InitAdvanced( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1 );
- s_aSupport[ ::dbaccess::DST_USERDEFINE1 ] = InitAdvanced( InitAdvanced::All );
- s_aSupport[ ::dbaccess::DST_USERDEFINE2 ] = InitAdvanced( InitAdvanced::All );
- s_aSupport[ ::dbaccess::DST_USERDEFINE3 ] = InitAdvanced( InitAdvanced::All );
- s_aSupport[ ::dbaccess::DST_USERDEFINE4 ] = InitAdvanced( InitAdvanced::All );
- s_aSupport[ ::dbaccess::DST_USERDEFINE5 ] = InitAdvanced( InitAdvanced::All );
- s_aSupport[ ::dbaccess::DST_USERDEFINE6 ] = InitAdvanced( InitAdvanced::All );
- s_aSupport[ ::dbaccess::DST_USERDEFINE7 ] = InitAdvanced( InitAdvanced::All );
- s_aSupport[ ::dbaccess::DST_USERDEFINE8 ] = InitAdvanced( InitAdvanced::All );
- s_aSupport[ ::dbaccess::DST_USERDEFINE9 ] = InitAdvanced( InitAdvanced::All );
- s_aSupport[ ::dbaccess::DST_USERDEFINE10 ] = InitAdvanced( InitAdvanced::All );
-
- s_aSupport[ ::dbaccess::DST_ORACLE_JDBC ].bIgnoreCurrency = true;
+ s_aSupport[ ::dbaccess::DST_USERDEFINE1 ] = InitAdvanced( InitAdvanced::AllButIgnoreCurrency );
+ s_aSupport[ ::dbaccess::DST_USERDEFINE2 ] = InitAdvanced( InitAdvanced::AllButIgnoreCurrency );
+ s_aSupport[ ::dbaccess::DST_USERDEFINE3 ] = InitAdvanced( InitAdvanced::AllButIgnoreCurrency );
+ s_aSupport[ ::dbaccess::DST_USERDEFINE4 ] = InitAdvanced( InitAdvanced::AllButIgnoreCurrency );
+ s_aSupport[ ::dbaccess::DST_USERDEFINE5 ] = InitAdvanced( InitAdvanced::AllButIgnoreCurrency );
+ s_aSupport[ ::dbaccess::DST_USERDEFINE6 ] = InitAdvanced( InitAdvanced::AllButIgnoreCurrency );
+ s_aSupport[ ::dbaccess::DST_USERDEFINE7 ] = InitAdvanced( InitAdvanced::AllButIgnoreCurrency );
+ s_aSupport[ ::dbaccess::DST_USERDEFINE8 ] = InitAdvanced( InitAdvanced::AllButIgnoreCurrency );
+ s_aSupport[ ::dbaccess::DST_USERDEFINE9 ] = InitAdvanced( InitAdvanced::AllButIgnoreCurrency );
+ s_aSupport[ ::dbaccess::DST_USERDEFINE10 ] = InitAdvanced( InitAdvanced::AllButIgnoreCurrency );
}
return s_aSupport[ _eType ];
}
diff --git a/dbaccess/source/ui/misc/dsntypes.cxx b/dbaccess/source/ui/misc/dsntypes.cxx
deleted file mode 100644
index e69de29bb..000000000
--- a/dbaccess/source/ui/misc/dsntypes.cxx
+++ /dev/null
diff --git a/dbaccess/source/ui/misc/indexcollection.cxx b/dbaccess/source/ui/misc/indexcollection.cxx
index 8e8bb0d9a..befe0216d 100644
--- a/dbaccess/source/ui/misc/indexcollection.cxx
+++ b/dbaccess/source/ui/misc/indexcollection.cxx
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: indexcollection.cxx,v $
- * $Revision: 1.10 $
+ * $Revision: 1.8.254.2 $
*
* This file is part of OpenOffice.org.
*
diff --git a/dbaccess/source/ui/misc/singledoccontroller.cxx b/dbaccess/source/ui/misc/singledoccontroller.cxx
index c9864725a..ead1c347d 100644
--- a/dbaccess/source/ui/misc/singledoccontroller.cxx
+++ b/dbaccess/source/ui/misc/singledoccontroller.cxx
@@ -169,13 +169,9 @@ namespace dbaui
bool documentHasScriptSupport() const
{
- // TODO: revert to the disabled code. The current version is just to be able
- // to integrate an intermediate version of the CWS, which should behave as
- // if no macros in DB docs are allowed
- return false;
-// OSL_PRECOND( !!m_aDocScriptSupport,
-// "OSingleDocumentControllerImpl::documentHasScriptSupport: not completely initialized, yet - don't know!?" );
-// return !!m_aDocScriptSupport && *m_aDocScriptSupport;
+ OSL_PRECOND( !!m_aDocScriptSupport,
+ "OSingleDocumentControllerImpl::documentHasScriptSupport: not completely initialized, yet - don't know!?" );
+ return !!m_aDocScriptSupport && *m_aDocScriptSupport;
}
void setDocumentScriptSupport( const bool _bSupport )
diff --git a/dbaccess/source/ui/uno/composerdialogs.cxx b/dbaccess/source/ui/uno/composerdialogs.cxx
index 33b349d69..6d43e61cc 100644
--- a/dbaccess/source/ui/uno/composerdialogs.cxx
+++ b/dbaccess/source/ui/uno/composerdialogs.cxx
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: composerdialogs.cxx,v $
- * $Revision: 1.12 $
+ * $Revision: 1.9.32.3 $
*
* This file is part of OpenOffice.org.
*
diff --git a/dbaccess/source/ui/uno/dbinteraction.cxx b/dbaccess/source/ui/uno/dbinteraction.cxx
index 4549b1ffd..e0ca05ce6 100644
--- a/dbaccess/source/ui/uno/dbinteraction.cxx
+++ b/dbaccess/source/ui/uno/dbinteraction.cxx
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: dbinteraction.cxx,v $
- * $Revision: 1.19 $
+ * $Revision: 1.17.6.2 $
*
* This file is part of OpenOffice.org.
*
diff --git a/dbaccess/source/ui/uno/unoDirectSql.cxx b/dbaccess/source/ui/uno/unoDirectSql.cxx
index 9ac0d8a1b..a9fe3278d 100644
--- a/dbaccess/source/ui/uno/unoDirectSql.cxx
+++ b/dbaccess/source/ui/uno/unoDirectSql.cxx
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: unoDirectSql.cxx,v $
- * $Revision: 1.10 $
+ * $Revision: 1.7.142.3 $
*
* This file is part of OpenOffice.org.
*