summaryrefslogtreecommitdiff
path: root/dbaccess/source/ext/macromigration
diff options
context:
space:
mode:
Diffstat (limited to 'dbaccess/source/ext/macromigration')
-rw-r--r--dbaccess/source/ext/macromigration/dbmm.map8
-rw-r--r--dbaccess/source/ext/macromigration/dbmm_global.hrc86
-rw-r--r--dbaccess/source/ext/macromigration/dbmm_module.cxx48
-rw-r--r--dbaccess/source/ext/macromigration/dbmm_module.hxx48
-rw-r--r--dbaccess/source/ext/macromigration/dbmm_services.cxx61
-rw-r--r--dbaccess/source/ext/macromigration/dbmm_types.cxx66
-rw-r--r--dbaccess/source/ext/macromigration/dbmm_types.hxx72
-rw-r--r--dbaccess/source/ext/macromigration/docinteraction.cxx145
-rw-r--r--dbaccess/source/ext/macromigration/docinteraction.hxx98
-rw-r--r--dbaccess/source/ext/macromigration/macromigration.hrc99
-rw-r--r--dbaccess/source/ext/macromigration/macromigration.src443
-rw-r--r--dbaccess/source/ext/macromigration/macromigrationdialog.cxx631
-rw-r--r--dbaccess/source/ext/macromigration/macromigrationdialog.hxx97
-rw-r--r--dbaccess/source/ext/macromigration/macromigrationpages.cxx364
-rw-r--r--dbaccess/source/ext/macromigration/macromigrationpages.hxx185
-rw-r--r--dbaccess/source/ext/macromigration/macromigrationwizard.cxx268
-rw-r--r--dbaccess/source/ext/macromigration/makefile.mk105
-rw-r--r--dbaccess/source/ext/macromigration/migrationengine.cxx1993
-rw-r--r--dbaccess/source/ext/macromigration/migrationengine.hxx103
-rw-r--r--dbaccess/source/ext/macromigration/migrationerror.hxx176
-rw-r--r--dbaccess/source/ext/macromigration/migrationlog.cxx515
-rw-r--r--dbaccess/source/ext/macromigration/migrationlog.hxx131
-rw-r--r--dbaccess/source/ext/macromigration/migrationprogress.hxx61
-rw-r--r--dbaccess/source/ext/macromigration/progresscapture.cxx138
-rw-r--r--dbaccess/source/ext/macromigration/progresscapture.hxx82
-rw-r--r--dbaccess/source/ext/macromigration/progressmixer.cxx219
-rw-r--r--dbaccess/source/ext/macromigration/progressmixer.hxx103
-rw-r--r--dbaccess/source/ext/macromigration/rangeprogressbar.hxx107
28 files changed, 6452 insertions, 0 deletions
diff --git a/dbaccess/source/ext/macromigration/dbmm.map b/dbaccess/source/ext/macromigration/dbmm.map
new file mode 100644
index 000000000000..397b86886982
--- /dev/null
+++ b/dbaccess/source/ext/macromigration/dbmm.map
@@ -0,0 +1,8 @@
+DBMM_1_0 {
+ global:
+ component_getImplementationEnvironment;
+ component_writeInfo;
+ component_getFactory;
+ local:
+ *;
+};
diff --git a/dbaccess/source/ext/macromigration/dbmm_global.hrc b/dbaccess/source/ext/macromigration/dbmm_global.hrc
new file mode 100644
index 000000000000..3ce7577426c7
--- /dev/null
+++ b/dbaccess/source/ext/macromigration/dbmm_global.hrc
@@ -0,0 +1,86 @@
+/*************************************************************************
+ *
+ * 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_global.hrc,v $
+ * $Revision: 1.3.2.5 $
+ *
+ * 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_DBMM_GLOBAL_HRC
+#define DBACCESS_DBMM_GLOBAL_HRC
+
+#include <svtools/solar.hrc>
+
+//=====================================================================
+//= bases
+//=====================================================================
+#define RID_DBMM_DIALOG_START RID_DBACCESS_START + 0
+#define RID_DBMM_TAPPAGE_START RID_DBACCESS_START + 0
+#define RID_DBMM_STRING_START RID_DBACCESS_START + 0
+
+//=====================================================================
+//= dialogs
+//=====================================================================
+
+#define DLG_MACRO_MIGRATION RID_DBMM_DIALOG_START + 0
+
+//=====================================================================
+//= error boxes
+//=====================================================================
+
+#define ERR_INVALID_BACKUP_LOCATION RID_DBMM_DIALOG_START + 0
+
+//=====================================================================
+//= tab pages
+//=====================================================================
+
+#define TP_PREPARE ( RID_DBMM_TAPPAGE_START + 0 )
+#define TP_SAVE_DBDOC_AS ( RID_DBMM_TAPPAGE_START + 1 )
+#define TP_MIGRATE ( RID_DBMM_TAPPAGE_START + 2 )
+#define TP_SUMMARY ( RID_DBMM_TAPPAGE_START + 3 )
+
+//=====================================================================
+//= 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_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_module.cxx b/dbaccess/source/ext/macromigration/dbmm_module.cxx
new file mode 100644
index 000000000000..a73dba3110f9
--- /dev/null
+++ b/dbaccess/source/ext/macromigration/dbmm_module.cxx
@@ -0,0 +1,48 @@
+/*************************************************************************
+ *
+ * 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_module.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 "dbmm_module.hxx"
+
+#include <rtl/instance.hxx>
+
+//........................................................................
+namespace dbmm
+{
+//........................................................................
+
+ IMPLEMENT_MODULE( MacroMigrationModule, "dbmm" );
+
+//........................................................................
+} // namespace dbmm
+//........................................................................
+
diff --git a/dbaccess/source/ext/macromigration/dbmm_module.hxx b/dbaccess/source/ext/macromigration/dbmm_module.hxx
new file mode 100644
index 000000000000..e3e09bc0632a
--- /dev/null
+++ b/dbaccess/source/ext/macromigration/dbmm_module.hxx
@@ -0,0 +1,48 @@
+/*************************************************************************
+ *
+ * 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_module.hxx,v $
+ * $Revision: 1.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.
+ *
+ ************************************************************************/
+
+#ifndef DBACCESS_MACROMIGRATION_MODULE_HXX
+#define DBACCESS_MACROMIGRATION_MODULE_HXX
+
+#include <unotools/componentresmodule.hxx>
+
+//........................................................................
+namespace dbmm
+{
+//........................................................................
+
+ DEFINE_MODULE( MacroMigrationModule, MacroMigrationModuleClient, MacroMigrationResId )
+
+//........................................................................
+} // namespace dbmm
+//........................................................................
+
+#endif // DBACCESS_MACROMIGRATION_MODULE_HXX
+
diff --git a/dbaccess/source/ext/macromigration/dbmm_services.cxx b/dbaccess/source/ext/macromigration/dbmm_services.cxx
new file mode 100644
index 000000000000..eb47fee5d085
--- /dev/null
+++ b/dbaccess/source/ext/macromigration/dbmm_services.cxx
@@ -0,0 +1,61 @@
+/*************************************************************************
+ *
+ * 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_services.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 "dbmm_module.hxx"
+
+//........................................................................
+namespace dbmm
+{
+//........................................................................
+
+ //--------------------------------------------------------------------
+ extern void createRegistryInfo_MacroMigrationDialogService();
+
+ static void initializeModule()
+ {
+ static bool bInitialized( false );
+ if ( !bInitialized )
+ {
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ if ( !bInitialized )
+ {
+ createRegistryInfo_MacroMigrationDialogService();
+ }
+ }
+ }
+
+//........................................................................
+} // namespace dbmm
+//........................................................................
+
+IMPLEMENT_COMPONENT_LIBRARY_API( ::dbmm::MacroMigrationModule, ::dbmm::initializeModule )
diff --git a/dbaccess/source/ext/macromigration/dbmm_types.cxx b/dbaccess/source/ext/macromigration/dbmm_types.cxx
new file mode 100644
index 000000000000..c63823367b74
--- /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
new file mode 100644
index 000000000000..df47e4d9aba2
--- /dev/null
+++ b/dbaccess/source/ext/macromigration/dbmm_types.hxx
@@ -0,0 +1,72 @@
+/*************************************************************************
+ *
+ * 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.hxx,v $
+ * $Revision: 1.3.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_DBMM_TYPES_HXX
+#define DBACCESS_DBMM_TYPES_HXX
+
+#include <tools/string.hxx>
+
+//........................................................................
+namespace dbmm
+{
+//........................................................................
+
+ //====================================================================
+ //= ScriptType
+ //====================================================================
+ enum ScriptType
+ {
+ eBasic,
+ eBeanShell,
+ eJavaScript,
+ ePython,
+ eJava,
+ eDialog
+ };
+
+ //====================================================================
+ //= SubDocumentType
+ //====================================================================
+ enum SubDocumentType
+ {
+ eForm,
+ eReport
+ };
+
+ //====================================================================
+ //= helper
+ //====================================================================
+ String getScriptTypeDisplayName( const ScriptType _eType );
+
+//........................................................................
+} // namespace dbmm
+//........................................................................
+
+#endif // DBACCESS_DBMM_TYPES_HXX
diff --git a/dbaccess/source/ext/macromigration/docinteraction.cxx b/dbaccess/source/ext/macromigration/docinteraction.cxx
new file mode 100644
index 000000000000..77fba3e97a04
--- /dev/null
+++ b/dbaccess/source/ext/macromigration/docinteraction.cxx
@@ -0,0 +1,145 @@
+/*************************************************************************
+ *
+ * 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, 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 000000000000..9e9dd73b4651
--- /dev/null
+++ b/dbaccess/source/ext/macromigration/docinteraction.hxx
@@ -0,0 +1,98 @@
+/*************************************************************************
+ *
+ * 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, 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
new file mode 100644
index 000000000000..49668f254234
--- /dev/null
+++ b/dbaccess/source/ext/macromigration/macromigration.hrc
@@ -0,0 +1,99 @@
+/*************************************************************************
+ *
+ * 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: macromigration.hrc,v $
+ * $Revision: 1.3.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_MACROMIGRATION_HRC
+#define DBACCESS_MACROMIGRATION_HRC
+
+// height and width of tab pages
+#define TAB_PAGE_WIDTH 280
+#define TAB_PAGE_HEIGHT 185
+
+// margin between the tab page and its content
+#define TAB_PAGE_CONTENT_MARGIN 12
+
+// dimensions of certain control types
+#define FIXED_TEXT_HEIGHT 8
+#define INPUT_HEIGHT 12
+#define PROGRESS_HEIGHT 12
+#define BUTTON_WIDTH 50
+#define BUTTON_HEIGHT 14
+
+// spacing after the header on each page
+#define SPACING_AFTER_HEADER 6
+// spacing between related controls
+#define SPACING_RELATED 3
+// spacing between unrelated controls
+#define SPACING_UNRELATED 6
+
+// the position of the first control after the header
+#define CONTENT_POS_X ( TAB_PAGE_CONTENT_MARGIN + FIXED_TEXT_HEIGHT + SPACING_AFTER_HEADER )
+
+//... fixed texts .......................................................
+
+#define FT_HEADER 1
+#define FT_INTRODUCTION 2
+#define FT_EXPLANATION 3
+#define FT_SAVE_AS_LABEL 4
+#define FT_START_MIGRATION 5
+#define FT_CURRENT_OBJECT_LABEL 6
+#define FT_CURRENT_OBJECT 7
+#define FT_CURRENT_PROGRESS_LABEL 8
+#define FT_CURRENT_PROGRESS 9
+#define FT_ALL_PROGRESS_LABEL 10
+#define FT_CHANGES_LABEL 11
+#define FT_OBJECT_COUNT 12
+#define FT_OBJECT_COUNT_PROGRESS 13
+#define FT_MIGRATION_DONE 14
+#define FT_CLOSE_DOC_ERROR 15
+
+//... windows ............................................................
+
+#define WND_CURRENT_PROGRESS 1
+#define WND_ALL_PROGRESS 2
+
+//... edits ..............................................................
+
+#define ED_SAVE_AS_LOCATION 1
+#define ED_CHANGES 2
+
+//... buttons ............................................................
+
+#define PB_BROWSE_SAVE_AS_LOCATION 1
+
+//... strings ............................................................
+
+#define STR_STATE_CLOSE_SUB_DOCS 1
+#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
new file mode 100644
index 000000000000..bb49ac7ad287
--- /dev/null
+++ b/dbaccess/source/ext/macromigration/macromigration.src
@@ -0,0 +1,443 @@
+/*************************************************************************
+ *
+ * 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: macromigration.src,v $
+ * $Revision: 1.3.2.8 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "dbmm_global.hrc"
+#include "macromigration.hrc"
+
+// -----------------------------------------------------------------------------
+ModalDialog DLG_MACRO_MIGRATION
+{
+ OutputSize = TRUE ;
+ Moveable = TRUE;
+ Closeable = TRUE ;
+ Hide = TRUE;
+
+ Text[ en-US ] = "Database Document Macro Migration" ;
+
+ String STR_STATE_CLOSE_SUB_DOCS
+ {
+ Text [ en-US ] = "Prepare";
+ };
+
+ String STR_STATE_BACKUP_DBDOC
+ {
+ Text [ en-US ] = "Backup Document";
+ };
+
+ String STR_STATE_MIGRATE
+ {
+ Text [ en-US ] = "Migrate";
+ };
+
+ String STR_STATE_SUMMARY
+ {
+ Text [ en-US ] = "Summary";
+ };
+};
+
+//========================================================================
+//= PreparationPage
+//========================================================================
+
+TabPage TP_PREPARE
+{
+ Pos = MAP_APPFONT( 40, 130 );
+ Size = MAP_APPFONT( TAB_PAGE_WIDTH, TAB_PAGE_HEIGHT );
+
+ Hide = TRUE;
+
+ FixedText FT_HEADER
+ {
+ Pos = MAP_APPFONT( TAB_PAGE_CONTENT_MARGIN, TAB_PAGE_CONTENT_MARGIN );
+ Size = MAP_APPFONT( TAB_PAGE_WIDTH - 2 * TAB_PAGE_CONTENT_MARGIN, FIXED_TEXT_HEIGHT );
+
+ Text [ en-US ] = "Welcome to the Database Macro Migration Wizard";
+ };
+
+ FixedText FT_INTRODUCTION
+ {
+ Pos = MAP_APPFONT( TAB_PAGE_CONTENT_MARGIN, CONTENT_POS_X );
+ Size = MAP_APPFONT( TAB_PAGE_WIDTH - 2 * TAB_PAGE_CONTENT_MARGIN,
+ 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.\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, they will be adjusted, where "
+ "possible.\n\n"
+
+ "Before the migration can start, all forms, reports, queries and tables belonging to the document must be closed. "
+ "Press 'Next' to do so.";
+ };
+
+ FixedText FT_CLOSE_DOC_ERROR
+ {
+ Pos = MAP_APPFONT ( TAB_PAGE_CONTENT_MARGIN,
+ TAB_PAGE_HEIGHT - TAB_PAGE_CONTENT_MARGIN - ( 2 * FIXED_TEXT_HEIGHT - SPACING_UNRELATED ) );
+ Size = MAP_APPFONT( TAB_PAGE_WIDTH - 2 * TAB_PAGE_CONTENT_MARGIN,
+ 2 * FIXED_TEXT_HEIGHT - SPACING_UNRELATED );
+ Text [ en-US ] = "Not all objects could be closed. Please close them manually, and re-start the wizard.";
+ hide = TRUE;
+ };
+};
+
+//========================================================================
+//= SaveDBDocPage
+//========================================================================
+
+TabPage TP_SAVE_DBDOC_AS
+{
+ Pos = MAP_APPFONT( 40, 130 );
+ Size = MAP_APPFONT( TAB_PAGE_WIDTH, TAB_PAGE_HEIGHT );
+
+ Hide = TRUE;
+
+ FixedText FT_HEADER
+ {
+ Pos = MAP_APPFONT( TAB_PAGE_CONTENT_MARGIN, TAB_PAGE_CONTENT_MARGIN );
+ Size = MAP_APPFONT( TAB_PAGE_WIDTH - 2 * TAB_PAGE_CONTENT_MARGIN, FIXED_TEXT_HEIGHT );
+
+ Text [ en-US ] = "Backup your Document";
+ };
+
+ FixedText FT_EXPLANATION
+ {
+ Pos = MAP_APPFONT( TAB_PAGE_CONTENT_MARGIN, CONTENT_POS_X );
+ Size = MAP_APPFONT( TAB_PAGE_WIDTH - 2 * TAB_PAGE_CONTENT_MARGIN, 5 * FIXED_TEXT_HEIGHT );
+
+ WordBreak = TRUE;
+
+ Text [ en-US ] = "To allow you to go back to the state before the migration, the database "
+ "document will be backed up to a location of your choice. Every change done by the wizard will "
+ "be made to the original document, the backup will stay untouched.";
+ };
+
+ FixedText FT_SAVE_AS_LABEL
+ {
+ Pos = MAP_APPFONT( TAB_PAGE_CONTENT_MARGIN, CONTENT_POS_X + 5 * FIXED_TEXT_HEIGHT + SPACING_UNRELATED );
+ Size = MAP_APPFONT( 60, INPUT_HEIGHT );
+
+ VCenter = TRUE;
+
+ Text [ en-US ] = "Save To:";
+ };
+
+ ComboBox ED_SAVE_AS_LOCATION
+ {
+ Pos = MAP_APPFONT( TAB_PAGE_CONTENT_MARGIN + 60 + SPACING_RELATED,
+ CONTENT_POS_X + 5 * FIXED_TEXT_HEIGHT + SPACING_UNRELATED );
+ Size = MAP_APPFONT( TAB_PAGE_WIDTH - ( TAB_PAGE_CONTENT_MARGIN + 60 + SPACING_RELATED ) - TAB_PAGE_CONTENT_MARGIN,
+ INPUT_HEIGHT );
+
+ Border = TRUE;
+ DropDown = TRUE ;
+ };
+
+ PushButton PB_BROWSE_SAVE_AS_LOCATION
+ {
+ Pos = MAP_APPFONT( TAB_PAGE_WIDTH - BUTTON_WIDTH - TAB_PAGE_CONTENT_MARGIN,
+ CONTENT_POS_X + 5 * FIXED_TEXT_HEIGHT + SPACING_UNRELATED + INPUT_HEIGHT + SPACING_RELATED );
+ Size = MAP_APPFONT( BUTTON_WIDTH, BUTTON_HEIGHT );
+
+ Text [ en-US ] = "Browse ...";
+ };
+
+ FixedText FT_START_MIGRATION
+ {
+ Pos = MAP_APPFONT( TAB_PAGE_CONTENT_MARGIN,
+ TAB_PAGE_HEIGHT - TAB_PAGE_CONTENT_MARGIN - 3 * FIXED_TEXT_HEIGHT );
+ Size = MAP_APPFONT( TAB_PAGE_WIDTH - 2 * TAB_PAGE_CONTENT_MARGIN,
+ 3 * FIXED_TEXT_HEIGHT );
+
+ WordBreak = TRUE;
+
+ Text [ en-US ] = "Press 'Next' to save a copy of your document, and to begin the migration.";
+ };
+};
+
+//========================================================================
+//= ProgressPage
+//========================================================================
+
+TabPage TP_MIGRATE
+{
+ Pos = MAP_APPFONT( 40, 130 );
+ Size = MAP_APPFONT( TAB_PAGE_WIDTH, TAB_PAGE_HEIGHT );
+
+ Hide = TRUE;
+
+ FixedText FT_HEADER
+ {
+ Pos = MAP_APPFONT( TAB_PAGE_CONTENT_MARGIN, TAB_PAGE_CONTENT_MARGIN );
+ Size = MAP_APPFONT( TAB_PAGE_WIDTH - 2 * TAB_PAGE_CONTENT_MARGIN, FIXED_TEXT_HEIGHT );
+
+ Text [ en-US ] = "Migration Progress";
+ };
+
+ FixedText FT_OBJECT_COUNT
+ {
+ Pos = MAP_APPFONT( TAB_PAGE_CONTENT_MARGIN, CONTENT_POS_X );
+ Size = MAP_APPFONT( TAB_PAGE_WIDTH - 2 * TAB_PAGE_CONTENT_MARGIN, 2 * FIXED_TEXT_HEIGHT );
+
+ Text [ en-US ] = "The database document contains $forms$ form(s) and $reports$ report(s), which are currently being processed:";
+
+ WordBreak = TRUE;
+ };
+
+ FixedText FT_CURRENT_OBJECT_LABEL
+ {
+ Pos = MAP_APPFONT( TAB_PAGE_CONTENT_MARGIN,
+ CONTENT_POS_X + 2 * FIXED_TEXT_HEIGHT + SPACING_UNRELATED );
+ Size = MAP_APPFONT( 60, FIXED_TEXT_HEIGHT );
+
+ Text [ en-US ] = "Current object:";
+ };
+
+ FixedText FT_CURRENT_OBJECT
+ {
+ 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 );
+ };
+
+ FixedText FT_CURRENT_PROGRESS_LABEL
+ {
+ Pos = MAP_APPFONT( TAB_PAGE_CONTENT_MARGIN,
+ CONTENT_POS_X + 2 * FIXED_TEXT_HEIGHT + SPACING_UNRELATED + FIXED_TEXT_HEIGHT + SPACING_UNRELATED );
+ Size = MAP_APPFONT( 60, FIXED_TEXT_HEIGHT );
+
+ Text [ en-US ] = "Current progress:";
+ };
+
+ FixedText FT_CURRENT_PROGRESS
+ {
+ 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 );
+ };
+
+ Window WND_CURRENT_PROGRESS
+ {
+ Pos = MAP_APPFONT( TAB_PAGE_CONTENT_MARGIN + 60,
+ CONTENT_POS_X + 2 * FIXED_TEXT_HEIGHT + SPACING_UNRELATED + FIXED_TEXT_HEIGHT + SPACING_UNRELATED + FIXED_TEXT_HEIGHT + SPACING_RELATED );
+ Size = MAP_APPFONT( TAB_PAGE_WIDTH - ( TAB_PAGE_CONTENT_MARGIN + 60 ) - TAB_PAGE_CONTENT_MARGIN, PROGRESS_HEIGHT );
+
+ Border = TRUE;
+ BorderStyle = WINDOW_BORDER_MONO;
+ };
+
+ FixedText FT_ALL_PROGRESS_LABEL
+ {
+ Pos = MAP_APPFONT( TAB_PAGE_CONTENT_MARGIN,
+ CONTENT_POS_X + 2 * FIXED_TEXT_HEIGHT + SPACING_UNRELATED + FIXED_TEXT_HEIGHT + SPACING_UNRELATED + FIXED_TEXT_HEIGHT + SPACING_RELATED + PROGRESS_HEIGHT + SPACING_UNRELATED );
+ Size = MAP_APPFONT( 60, FIXED_TEXT_HEIGHT );
+
+ VCenter = TRUE;
+
+ Text [ en-US ] = "Overall progress:";
+ };
+
+ FixedText FT_OBJECT_COUNT_PROGRESS
+ {
+ Pos = MAP_APPFONT( TAB_PAGE_CONTENT_MARGIN + 60,
+ CONTENT_POS_X + 2 * FIXED_TEXT_HEIGHT + SPACING_UNRELATED + FIXED_TEXT_HEIGHT + SPACING_UNRELATED + FIXED_TEXT_HEIGHT + SPACING_RELATED + PROGRESS_HEIGHT + SPACING_UNRELATED );
+ Size = MAP_APPFONT( TAB_PAGE_WIDTH - ( TAB_PAGE_CONTENT_MARGIN + 60 ) - TAB_PAGE_CONTENT_MARGIN, FIXED_TEXT_HEIGHT );
+
+ Text [ en-US ] = "document $current$ of $overall$";
+ };
+
+ Window WND_ALL_PROGRESS
+ {
+ Pos = MAP_APPFONT( TAB_PAGE_CONTENT_MARGIN + 60,
+ CONTENT_POS_X + 2 * FIXED_TEXT_HEIGHT + SPACING_UNRELATED + FIXED_TEXT_HEIGHT + SPACING_UNRELATED + FIXED_TEXT_HEIGHT + SPACING_RELATED + PROGRESS_HEIGHT + SPACING_UNRELATED + FIXED_TEXT_HEIGHT + SPACING_RELATED );
+ Size = MAP_APPFONT( TAB_PAGE_WIDTH - ( TAB_PAGE_CONTENT_MARGIN + 60 ) - TAB_PAGE_CONTENT_MARGIN, PROGRESS_HEIGHT );
+
+ Border = TRUE;
+ BorderStyle = WINDOW_BORDER_MONO;
+ };
+
+ FixedText FT_MIGRATION_DONE
+ {
+ Pos = MAP_APPFONT( TAB_PAGE_CONTENT_MARGIN, TAB_PAGE_HEIGHT - TAB_PAGE_CONTENT_MARGIN - 2 * FIXED_TEXT_HEIGHT );
+ Size = MAP_APPFONT( TAB_PAGE_WIDTH - 2 * TAB_PAGE_CONTENT_MARGIN, 2 * FIXED_TEXT_HEIGHT );
+
+ WordBreak = TRUE;
+ Hide = TRUE;
+
+ Text [ en-US ] = "All forms and reports have been successfully processed. Press 'Next' to show a detailed summary.";
+ };
+};
+
+//========================================================================
+//= ResultPage
+//========================================================================
+
+TabPage TP_SUMMARY
+{
+ Pos = MAP_APPFONT( 40, 130 );
+ Size = MAP_APPFONT( TAB_PAGE_WIDTH, TAB_PAGE_HEIGHT );
+
+ Hide = TRUE;
+
+ FixedText FT_HEADER
+ {
+ Pos = MAP_APPFONT( TAB_PAGE_CONTENT_MARGIN, TAB_PAGE_CONTENT_MARGIN );
+ Size = MAP_APPFONT( TAB_PAGE_WIDTH - 2 * TAB_PAGE_CONTENT_MARGIN, FIXED_TEXT_HEIGHT );
+
+ Text [ en-US ] = "Summary";
+ };
+
+ FixedText FT_CHANGES_LABEL
+ {
+ Pos = MAP_APPFONT( TAB_PAGE_CONTENT_MARGIN, CONTENT_POS_X );
+ Size = MAP_APPFONT( TAB_PAGE_WIDTH - 2 * TAB_PAGE_CONTENT_MARGIN, FIXED_TEXT_HEIGHT );
+
+ WordBreak = TRUE;
+ };
+
+ MultiLineEdit ED_CHANGES
+ {
+ Pos = MAP_APPFONT( TAB_PAGE_CONTENT_MARGIN, CONTENT_POS_X + FIXED_TEXT_HEIGHT + SPACING_RELATED );
+ Size = MAP_APPFONT( TAB_PAGE_WIDTH - 2 * TAB_PAGE_CONTENT_MARGIN,
+ TAB_PAGE_HEIGHT - ( CONTENT_POS_X + FIXED_TEXT_HEIGHT + SPACING_RELATED ) - TAB_PAGE_CONTENT_MARGIN );
+
+ ReadOnly = TRUE;
+ AutoVScroll = TRUE;
+ 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
+{
+ Text [ en-US ] = "Form '$name$'";
+ Text [ x-comment ] = "This refers to a form document inside a database document.";
+};
+
+String STR_REPORT
+{
+ Text [ en-US ] = "Report '$name$'";
+ Text [ x-comment ] = "This refers to a report document inside a database document.";
+};
+
+String STR_OVERALL_PROGRESS
+{
+ Text [ en-US ] = "document $current$ of $overall$";
+};
+
+String STR_DATABASE_DOCUMENT
+{
+ Text[ en-US ] = "Database Document";
+};
+
+String STR_SAVED_COPY_TO
+{
+ Text[ en-US ] = "saved copy to $location$";
+};
+
+String STR_MOVED_LIBRARY
+{
+ 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";
+};
+
+String STR_JAVA_SCRIPT
+{
+ Text[ en-US ] = "JavaScript";
+};
+
+String STR_BEAN_SHELL
+{
+ Text[ en-US ] = "BeanShell";
+};
+
+String STR_JAVA
+{
+ Text[ en-US ] = "Java";
+};
+
+String STR_PYTHON
+{
+ Text[ en-US ] = "Python";
+};
+
+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
new file mode 100644
index 000000000000..36ddf714f9bc
--- /dev/null
+++ b/dbaccess/source/ext/macromigration/macromigrationdialog.cxx
@@ -0,0 +1,631 @@
+/*************************************************************************
+ *
+ * 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: macromigrationdialog.cxx,v $
+ * $Revision: 1.3.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 "dbmm_global.hrc"
+#include "dbmm_module.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/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
+{
+//........................................................................
+
+#define STATE_CLOSE_SUB_DOCS 0
+#define STATE_BACKUP_DBDOC 1
+#define STATE_MIGRATE 2
+#define STATE_SUMMARY 3
+
+#define PATH_DEFAULT 1
+
+ /** === 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::application::XDatabaseDocumentUI;
+ 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::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
+ {
+ ::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,
+ const Reference< XOfficeDatabaseDocument >& _rxDocument )
+ :aContext( _rContext )
+ ,aLogger()
+ ,xDocument( _rxDocument )
+ ,xDocumentModel( _rxDocument, UNO_QUERY )
+ ,bMigrationIsRunning( false )
+ ,bMigrationFailure( false )
+ ,bMigrationSuccess( false )
+ {
+ }
+ };
+
+ //====================================================================
+ //= MacroMigrationDialog
+ //====================================================================
+ //--------------------------------------------------------------------
+ MacroMigrationDialog::MacroMigrationDialog( Window* _pParent, const ::comphelper::ComponentContext& _rContext,
+ const Reference< XOfficeDatabaseDocument >& _rxDocument )
+ :MacroMigrationDialog_Base( _pParent, MacroMigrationResId( DLG_MACRO_MIGRATION ) )
+ ,m_pData( new MacroMigrationDialog_Data( _rContext, _rxDocument ) )
+ {
+ String sTitlePrepare( MacroMigrationResId( STR_STATE_CLOSE_SUB_DOCS ) );
+ String sTitleStoreAs( MacroMigrationResId( STR_STATE_BACKUP_DBDOC ) );
+ String sTitleMigrate( MacroMigrationResId( STR_STATE_MIGRATE ) );
+ String sTitleSummary( MacroMigrationResId( STR_STATE_SUMMARY ) );
+ FreeResource();
+
+ describeState( STATE_CLOSE_SUB_DOCS, sTitlePrepare, &PreparationPage::Create );
+ describeState( STATE_BACKUP_DBDOC, sTitleStoreAs, &SaveDBDocPage::Create );
+ describeState( STATE_MIGRATE, sTitleMigrate, &ProgressPage::Create );
+ describeState( STATE_SUMMARY, sTitleSummary, &ResultPage::Create );
+
+ declarePath( PATH_DEFAULT, STATE_CLOSE_SUB_DOCS, STATE_BACKUP_DBDOC, STATE_MIGRATE, STATE_SUMMARY, WZS_INVALID_STATE );
+
+ SetPageSizePixel( LogicToPixel( ::Size( TAB_PAGE_WIDTH, TAB_PAGE_HEIGHT ), MAP_APPFONT ) );
+ ShowButtonFixedLine( true );
+ SetRoadmapInteractive( true );
+ enableAutomaticNextButtonState();
+ defaultButton( WZB_NEXT );
+ enableButtons( WZB_FINISH, true );
+ ActivatePage();
+
+ OSL_PRECOND( m_pData->xDocumentModel.is(), "MacroMigrationDialog::MacroMigrationDialog: illegal document!" );
+ }
+
+ //--------------------------------------------------------------------
+ MacroMigrationDialog::~MacroMigrationDialog()
+ {
+ }
+
+ //--------------------------------------------------------------------
+ const ::comphelper::ComponentContext& MacroMigrationDialog::getComponentContext() const
+ {
+ return m_pData->aContext;
+ }
+
+ //--------------------------------------------------------------------
+ const Reference< XOfficeDatabaseDocument >& MacroMigrationDialog::getDocument() const
+ {
+ return m_pData->xDocument;
+ }
+
+ //--------------------------------------------------------------------
+ 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 )
+ return FALSE;
+ return MacroMigrationDialog_Base::Close();
+ }
+
+ //--------------------------------------------------------------------
+ void MacroMigrationDialog::enterState( WizardState _nState )
+ {
+ MacroMigrationDialog_Base::enterState( _nState );
+
+ switch ( _nState )
+ {
+ case STATE_CLOSE_SUB_DOCS:
+ enableButtons( WZB_FINISH, false );
+ enableState( STATE_MIGRATE, false );
+ enableState( STATE_SUMMARY, false );
+ break;
+
+ case STATE_BACKUP_DBDOC:
+ enableState( STATE_MIGRATE, true );
+ // Note that the state is automatically disabled if the current page
+ // (SaveDBDocPage) returns false in its canAdvance, not caring that
+ // we enabled it here.
+ break;
+
+ case STATE_MIGRATE:
+ {
+ // disable everything. The process we will start here cannot be cancelled, the user
+ // needs to wait 'til it's finished.
+ enableState( STATE_CLOSE_SUB_DOCS, false );
+ enableState( STATE_BACKUP_DBDOC, false );
+ enableState( STATE_SUMMARY, false );
+
+ enableButtons( WZB_FINISH | WZB_CANCEL | WZB_PREVIOUS | WZB_NEXT, false );
+
+ // start the migration asynchronously
+ PostUserEvent( LINK( this, MacroMigrationDialog, OnStartMigration ) );
+ }
+ break;
+
+ case STATE_SUMMARY:
+ // disable the previous step - we can't return to the actual migration, it already happened (or failed)
+ enableState( STATE_MIGRATE, false );
+ updateTravelUI();
+
+ // 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:
+ OSL_ENSURE( false, "MacroMigrationDialog::enterState: unhandled state!" );
+ }
+ }
+
+ //--------------------------------------------------------------------
+ sal_Bool MacroMigrationDialog::prepareLeaveCurrentState( CommitPageReason _eReason )
+ {
+ if ( !MacroMigrationDialog_Base::prepareLeaveCurrentState( _eReason ) )
+ return sal_False;
+
+ switch ( getCurrentState() )
+ {
+ case STATE_CLOSE_SUB_DOCS:
+ if ( !impl_closeSubDocs_nothrow() )
+ return sal_False;
+ break;
+ case STATE_BACKUP_DBDOC:
+ if ( !impl_backupDocument_nothrow() )
+ return sal_False;
+ break;
+ case STATE_MIGRATE:
+ break;
+ case STATE_SUMMARY:
+ break;
+ default:
+ OSL_ENSURE( false, "MacroMigrationDialog::prepareLeaveCurrentState: unhandled state!" );
+ }
+
+ return sal_True;
+ }
+
+ //--------------------------------------------------------------------
+ sal_Bool MacroMigrationDialog::leaveState( WizardState _nState )
+ {
+ return MacroMigrationDialog_Base::leaveState( _nState );
+ }
+
+ //--------------------------------------------------------------------
+ MacroMigrationDialog::WizardState MacroMigrationDialog::determineNextState( WizardState _nCurrentState ) const
+ {
+ return MacroMigrationDialog_Base::determineNextState( _nCurrentState );
+ }
+
+ //--------------------------------------------------------------------
+ sal_Bool MacroMigrationDialog::onFinish( sal_Int32 _nResult )
+ {
+ return MacroMigrationDialog_Base::onFinish( _nResult );
+ }
+
+ //--------------------------------------------------------------------
+ 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
+ m_pData->bMigrationSuccess = aEngine.migrateAll();
+ m_pData->bMigrationFailure = !m_pData->bMigrationSuccess;
+
+ // re-enable the UI
+ 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;
+ }
+
+ //--------------------------------------------------------------------
+ void MacroMigrationDialog::impl_showCloseDocsError( bool _bShow )
+ {
+ PreparationPage* pPreparationPage = dynamic_cast< PreparationPage* >( GetPage( STATE_CLOSE_SUB_DOCS ) );
+ OSL_ENSURE( pPreparationPage, "MacroMigrationDialog::impl_showCloseDocsError: did not find the page!" );
+ if ( pPreparationPage )
+ pPreparationPage->showCloseDocsError( _bShow );
+ }
+
+ //--------------------------------------------------------------------
+ bool MacroMigrationDialog::impl_closeSubDocs_nothrow()
+ {
+ OSL_PRECOND( m_pData->xDocument.is(), "MacroMigrationDialog::impl_closeSubDocs_nothrow: no document!" );
+ if ( !m_pData->xDocument.is() )
+ return false;
+
+ impl_showCloseDocsError( false );
+
+ bool bSuccess = true;
+ try
+ {
+ // collect all controllers of our document
+ ::std::list< Reference< XController2 > > aControllers;
+ lcl_getControllers_throw( m_pData->xDocumentModel, aControllers );
+
+ // close all sub documents of all controllers
+ for ( ::std::list< Reference< XController2 > >::const_iterator pos = aControllers.begin();
+ pos != aControllers.end() && bSuccess;
+ ++pos
+ )
+ {
+ Reference< XDatabaseDocumentUI > xController( *pos, UNO_QUERY );
+ OSL_ENSURE( xController.is(), "MacroMigrationDialog::impl_closeSubDocs_nothrow: unexpected: controller is missing an important interface!" );
+ // at the moment, only one implementation for a DBDoc's controller exists, which should
+ // support this interface
+ if ( !xController.is() )
+ continue;
+
+ bSuccess = xController->closeSubComponents();
+ }
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ bSuccess = false;
+ }
+
+ impl_showCloseDocsError( !bSuccess );
+ return bSuccess;
+ }
+
+ //--------------------------------------------------------------------
+ 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
+ {
+ 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& )
+ {
+ aError = ::cppu::getCaughtException();
+ }
+ if ( !aError.hasValue() )
+ {
+ ::svt::OFileNotation aFileNotation( sBackupLocation );
+ m_pData->aLogger.backedUpDocument( aFileNotation.get( ::svt::OFileNotation::N_SYSTEM ) );
+ return true;
+ }
+
+ // display the error to the user
+ InteractionHandler aHandler( m_pData->aContext, m_pData->xDocumentModel.get() );
+ aHandler.reportError( aError );
+
+ 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
new file mode 100644
index 000000000000..727dd333e1ea
--- /dev/null
+++ b/dbaccess/source/ext/macromigration/macromigrationdialog.hxx
@@ -0,0 +1,97 @@
+/*************************************************************************
+ *
+ * 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: macromigrationdialog.hxx,v $
+ * $Revision: 1.3.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_MACROMIGRATIONDIALOG_HXX
+#define DBACCESS_MACROMIGRATIONDIALOG_HXX
+
+/** === begin UNO includes === **/
+#include <com/sun/star/sdb/XOfficeDatabaseDocument.hpp>
+/** === end UNO includes === **/
+
+#include <comphelper/componentcontext.hxx>
+#include <svtools/roadmapwizard.hxx>
+
+#include <memory>
+
+//........................................................................
+namespace dbmm
+{
+//........................................................................
+
+ //====================================================================
+ //= MacroMigrationDialog
+ //====================================================================
+ struct MacroMigrationDialog_Data;
+ typedef ::svt::RoadmapWizard MacroMigrationDialog_Base;
+ class MacroMigrationDialog : public MacroMigrationDialog_Base
+ {
+ public:
+ MacroMigrationDialog(
+ Window* _pParent,
+ const ::comphelper::ComponentContext& _rContext,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::sdb::XOfficeDatabaseDocument >& _rxDocument
+ );
+ virtual ~MacroMigrationDialog();
+
+ const ::comphelper::ComponentContext&
+ getComponentContext() const;
+ const ::com::sun::star::uno::Reference< ::com::sun::star::sdb::XOfficeDatabaseDocument >&
+ getDocument() const;
+
+ protected:
+ // OWizardMachine overridables
+ virtual void enterState( WizardState _nState );
+ virtual sal_Bool prepareLeaveCurrentState( CommitPageReason _eReason );
+ virtual sal_Bool leaveState( WizardState _nState );
+ virtual WizardState determineNextState( WizardState _nCurrentState ) const;
+ virtual sal_Bool onFinish( sal_Int32 _nResult );
+
+ // 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* );
+
+ private:
+ ::std::auto_ptr< MacroMigrationDialog_Data > m_pData;
+ };
+
+//........................................................................
+} // namespace dbmm
+//........................................................................
+
+#endif // DBACCESS_MACROMIGRATIONDIALOG_HXX
diff --git a/dbaccess/source/ext/macromigration/macromigrationpages.cxx b/dbaccess/source/ext/macromigration/macromigrationpages.cxx
new file mode 100644
index 000000000000..683f7ebaa09c
--- /dev/null
+++ b/dbaccess/source/ext/macromigration/macromigrationpages.cxx
@@ -0,0 +1,364 @@
+/*************************************************************************
+ *
+ * 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: macromigrationpages.cxx,v $
+ * $Revision: 1.3.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 "dbaccess_helpid.hrc"
+#include "dbmm_module.hxx"
+#include "dbmm_global.hrc"
+#include "macromigration.hrc"
+#include "macromigrationpages.hxx"
+#include "macromigrationdialog.hxx"
+
+/** === begin UNO includes === **/
+#include <com/sun/star/frame/XModel.hpp>
+/** === end UNO includes === **/
+
+#include <tools/urlobj.hxx>
+#include <tools/diagnose_ex.h>
+#include <vcl/metric.hxx>
+
+//........................................................................
+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::uno::Sequence;
+ using ::com::sun::star::frame::XModel;
+ /** === end UNO using === **/
+
+ //====================================================================
+ //= MacroMigrationPage
+ //====================================================================
+ //--------------------------------------------------------------------
+ MacroMigrationPage::MacroMigrationPage( MacroMigrationDialog& _rParentDialog, const ResId& _rRes )
+ :MacroMigrationPage_Base( &_rParentDialog, _rRes )
+ ,m_aHeader( this, MacroMigrationResId( FT_HEADER ) )
+ {
+ Font aFont( m_aHeader.GetFont() );
+ aFont.SetWeight( WEIGHT_BOLD );
+ m_aHeader.SetFont( aFont );
+ }
+
+ //--------------------------------------------------------------------
+ MacroMigrationPage::~MacroMigrationPage()
+ {
+ }
+
+ //--------------------------------------------------------------------
+ const MacroMigrationDialog& MacroMigrationPage::getDialog() const
+ {
+ return *dynamic_cast< const MacroMigrationDialog* >( GetParent() );
+ }
+
+ //--------------------------------------------------------------------
+ MacroMigrationDialog& MacroMigrationPage::getDialog()
+ {
+ return *dynamic_cast< MacroMigrationDialog* >( GetParent() );
+ }
+
+ //====================================================================
+ //= PreparationPage
+ //====================================================================
+ //--------------------------------------------------------------------
+ PreparationPage::PreparationPage( MacroMigrationDialog& _rParentDialog )
+ :MacroMigrationPage( _rParentDialog, MacroMigrationResId( TP_PREPARE ) )
+ ,m_aIntroduction ( this, MacroMigrationResId( FT_INTRODUCTION ) )
+ ,m_aCloseDocError( this, MacroMigrationResId( FT_CLOSE_DOC_ERROR ) )
+ {
+ FreeResource();
+ }
+
+ //--------------------------------------------------------------------
+ void PreparationPage::showCloseDocsError( bool _bShow )
+ {
+ m_aCloseDocError.Show( _bShow );
+ }
+
+ //--------------------------------------------------------------------
+ TabPage* PreparationPage::Create( ::svt::RoadmapWizard& _rParentDialog )
+ {
+ return new PreparationPage( dynamic_cast< MacroMigrationDialog& >( _rParentDialog ) );
+ }
+
+ //====================================================================
+ //= SaveDBDocPage
+ //====================================================================
+ //--------------------------------------------------------------------
+ SaveDBDocPage::SaveDBDocPage( MacroMigrationDialog& _rParentDialog )
+ :MacroMigrationPage( _rParentDialog, MacroMigrationResId( TP_SAVE_DBDOC_AS ) )
+ ,m_aExplanation ( this, MacroMigrationResId( FT_EXPLANATION ) )
+ ,m_aSaveAsLabel ( this, MacroMigrationResId( FT_SAVE_AS_LABEL ) )
+ ,m_aSaveAsLocation ( this, MacroMigrationResId( ED_SAVE_AS_LOCATION ) )
+ ,m_aBrowseSaveAsLocation( this, MacroMigrationResId( PB_BROWSE_SAVE_AS_LOCATION ) )
+ ,m_aStartMigration ( this, MacroMigrationResId( FT_START_MIGRATION ) )
+ ,m_aLocationController( _rParentDialog.getComponentContext(), m_aSaveAsLocation, m_aBrowseSaveAsLocation )
+ {
+ FreeResource();
+
+ m_aSaveAsLocation.SetModifyHdl( LINK( this, SaveDBDocPage, OnLocationModified ) );
+ m_aSaveAsLocation.SetDropDownLineCount( 20 );
+
+ m_aSaveAsLocation.SetHelpId( HID_MACRO_MIGRATION_BACKUP_LOCATION );
+
+ impl_updateLocationDependentItems();
+ }
+
+ //--------------------------------------------------------------------
+ void SaveDBDocPage::impl_updateLocationDependentItems()
+ {
+ updateDialogTravelUI();
+ m_aStartMigration.Show( m_aSaveAsLocation.GetText().Len() > 0 );
+ }
+
+ //--------------------------------------------------------------------
+ IMPL_LINK( SaveDBDocPage, OnLocationModified, Edit*, /**/ )
+ {
+ impl_updateLocationDependentItems();
+ return 0L;
+ }
+
+ //--------------------------------------------------------------------
+ void SaveDBDocPage::initializePage()
+ {
+ OWizardPage::initializePage();
+
+ try
+ {
+ // get the document's current URL
+ Reference< XModel > xDocument( getDialog().getDocument(), UNO_QUERY_THROW );
+ INetURLObject aURLParser( xDocument->getURL() );
+ OSL_ENSURE( aURLParser.GetProtocol() != INET_PROT_NOT_VALID, "SaveDBDocPage::initializePage: illegal document URL!" );
+
+ ::rtl::OUStringBuffer aBaseName( aURLParser.getBase() );
+ aBaseName.appendAscii( ".backup" );
+ aURLParser.setBase( aBaseName.makeStringAndClear() );
+
+ m_aLocationController.setURL( aURLParser.GetMainURL( INetURLObject::NO_DECODE ) );
+ impl_updateLocationDependentItems();
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+
+ //--------------------------------------------------------------------
+ bool SaveDBDocPage::canAdvance() const
+ {
+ if ( !MacroMigrationPage::canAdvance() )
+ return false;
+
+ return m_aSaveAsLocation.GetText().Len() > 0;
+ }
+
+ //--------------------------------------------------------------------
+ sal_Bool SaveDBDocPage::commitPage( CommitPageReason _eReason )
+ {
+ if ( !MacroMigrationPage::commitPage( _eReason ) )
+ return sal_False;
+
+ if ( eTravelBackward == _eReason )
+ return sal_True;
+
+ if ( !m_aLocationController.prepareCommit() )
+ return sal_False;
+
+ return sal_True;
+ }
+
+ //--------------------------------------------------------------------
+ TabPage* SaveDBDocPage::Create( ::svt::RoadmapWizard& _rParentDialog )
+ {
+ return new SaveDBDocPage( dynamic_cast< MacroMigrationDialog& >( _rParentDialog ) );
+ }
+
+ //====================================================================
+ //= ProgressPage
+ //====================================================================
+ //--------------------------------------------------------------------
+ ProgressPage::ProgressPage( MacroMigrationDialog& _rParentDialog )
+ :MacroMigrationPage( _rParentDialog, MacroMigrationResId( TP_MIGRATE ) )
+ ,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_aCurrentProgress ( this, MacroMigrationResId( WND_CURRENT_PROGRESS ) )
+ ,m_aAllProgressLabel ( this, MacroMigrationResId( FT_ALL_PROGRESS_LABEL ) )
+ ,m_aAllProgressText ( this, MacroMigrationResId( FT_OBJECT_COUNT_PROGRESS ) )
+ ,m_aAllProgress ( this, MacroMigrationResId( WND_ALL_PROGRESS ) )
+ ,m_aMigrationDone ( this, MacroMigrationResId( FT_MIGRATION_DONE ) )
+ {
+ FreeResource();
+ }
+
+ //--------------------------------------------------------------------
+ TabPage* ProgressPage::Create( ::svt::RoadmapWizard& _rParentDialog )
+ {
+ return new ProgressPage( dynamic_cast< MacroMigrationDialog& >( _rParentDialog ) );
+ }
+
+ //--------------------------------------------------------------------
+ void ProgressPage::setDocumentCounts( const sal_Int32 _nForms, const sal_Int32 _nReports )
+ {
+ String sText( m_aObjectCount.GetText() );
+ sText.SearchAndReplaceAscii( "$forms$", String::CreateFromInt32( _nForms ) );
+ sText.SearchAndReplaceAscii( "$reports$", String::CreateFromInt32( _nReports ) );
+ m_aObjectCount.SetText( sText );
+ }
+
+ //--------------------------------------------------------------------
+ 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 );
+ m_aCurrentAction.SetText( _rCurrentAction );
+ m_aCurrentProgress.SetRange( _nRange );
+ m_aCurrentProgress.SetValue( (sal_uInt32)0 );
+
+ // 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();
+ }
+
+ //--------------------------------------------------------------------
+ void ProgressPage::setObjectProgressText( const ::rtl::OUString& _rText )
+ {
+ m_aCurrentAction.SetText( _rText );
+ m_aCurrentAction.Update();
+ Update();
+ }
+
+ //--------------------------------------------------------------------
+ void ProgressPage::setObjectProgressValue( const sal_uInt32 _nValue )
+ {
+ m_aCurrentProgress.SetValue( _nValue );
+ Update();
+ }
+
+ //--------------------------------------------------------------------
+ void ProgressPage::endObject()
+ {
+ m_aCurrentAction.SetText( String() );
+ m_aCurrentProgress.SetValue( m_aCurrentProgress.GetRange() );
+ m_aCurrentAction.Update();
+ Update();
+ }
+
+ //--------------------------------------------------------------------
+ void ProgressPage::start( const sal_uInt32 _nOverallRange )
+ {
+ m_aAllProgress.SetRange( _nOverallRange );
+ Update();
+ }
+
+ //--------------------------------------------------------------------
+ void ProgressPage::setOverallProgressText( const ::rtl::OUString& _rText )
+ {
+ m_aAllProgressText.SetText( _rText );
+ Update();
+ }
+
+ //--------------------------------------------------------------------
+ void ProgressPage::setOverallProgressValue( const sal_uInt32 _nValue )
+ {
+ m_aAllProgress.SetValue( _nValue );
+ Update();
+ }
+
+ //====================================================================
+ //= ResultPage
+ //====================================================================
+ //--------------------------------------------------------------------
+ ResultPage::ResultPage( MacroMigrationDialog& _rParentDialog )
+ :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();
+ }
+
+ //--------------------------------------------------------------------
+ TabPage* ResultPage::Create( ::svt::RoadmapWizard& _rParentDialog )
+ {
+ return new ResultPage( dynamic_cast< MacroMigrationDialog& >( _rParentDialog ) );
+ }
+
+ //--------------------------------------------------------------------
+ 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 );
+ }
+
+//........................................................................
+} // namespace dbmm
+//........................................................................
diff --git a/dbaccess/source/ext/macromigration/macromigrationpages.hxx b/dbaccess/source/ext/macromigration/macromigrationpages.hxx
new file mode 100644
index 000000000000..f4aefc4599c6
--- /dev/null
+++ b/dbaccess/source/ext/macromigration/macromigrationpages.hxx
@@ -0,0 +1,185 @@
+/*************************************************************************
+ *
+ * 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: macromigrationpages.hxx,v $
+ * $Revision: 1.3.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_MACROMIGRATIONPAGES_HXX
+#define DBACCESS_MACROMIGRATIONPAGES_HXX
+
+#include "migrationprogress.hxx"
+#include "rangeprogressbar.hxx"
+
+#include <svtools/svmedit.hxx>
+#include <svtools/urlcontrol.hxx>
+#include <svtools/wizardmachine.hxx>
+#include <svx/databaselocationinput.hxx>
+#include <vcl/fixed.hxx>
+#include <vcl/edit.hxx>
+
+namespace svt
+{
+ class RoadmapWizard;
+}
+
+//........................................................................
+namespace dbmm
+{
+//........................................................................
+
+ class MacroMigrationDialog;
+
+ //====================================================================
+ //= MacroMigrationPage
+ //====================================================================
+ typedef ::svt::OWizardPage MacroMigrationPage_Base;
+ class MacroMigrationPage : public MacroMigrationPage_Base
+ {
+ public:
+ MacroMigrationPage( MacroMigrationDialog& _rParentDialog, const ResId& _rRes );
+ ~MacroMigrationPage();
+
+ protected:
+ const MacroMigrationDialog& getDialog() const;
+ MacroMigrationDialog& getDialog() ;
+
+ protected:
+ FixedText m_aHeader;
+ };
+
+ //====================================================================
+ //= PreparationPage
+ //====================================================================
+ class PreparationPage : public MacroMigrationPage
+ {
+ public:
+ PreparationPage( MacroMigrationDialog& _rParentDialog );
+
+ static TabPage* Create( ::svt::RoadmapWizard& _rParentDialog );
+
+ public:
+ void showCloseDocsError( bool _bShow );
+
+ protected:
+ FixedText m_aIntroduction;
+ FixedText m_aCloseDocError;
+ };
+
+ //====================================================================
+ //= SaveDBDocPage
+ //====================================================================
+ class SaveDBDocPage : public MacroMigrationPage
+ {
+ public:
+ SaveDBDocPage( MacroMigrationDialog& _rParentDialog );
+ static TabPage* Create( ::svt::RoadmapWizard& _rParentDialog );
+
+ public:
+ ::rtl::OUString getBackupLocation() const { return m_aLocationController.getURL(); }
+ void grabLocationFocus() { m_aSaveAsLocation.GrabFocus(); }
+
+ protected:
+ FixedText m_aExplanation;
+ FixedText m_aSaveAsLabel;
+ ::svt::OFileURLControl m_aSaveAsLocation;
+ PushButton m_aBrowseSaveAsLocation;
+ FixedText m_aStartMigration;
+ ::svx::DatabaseLocationInputController
+ m_aLocationController;
+
+ protected:
+ // OWizardPage overridables
+ virtual void initializePage();
+ virtual bool canAdvance() const;
+ // IWizardPage overridables
+ virtual sal_Bool commitPage( CommitPageReason _eReason );
+
+ private:
+ DECL_LINK( OnLocationModified, Edit* );
+ void impl_updateLocationDependentItems();
+ };
+
+ //====================================================================
+ //= ProgressPage
+ //====================================================================
+ class ProgressPage : public MacroMigrationPage, public IMigrationProgress
+ {
+ public:
+ ProgressPage( MacroMigrationDialog& _rParentDialog );
+
+ static TabPage* Create( ::svt::RoadmapWizard& _rParentDialog );
+
+ void setDocumentCounts( const sal_Int32 _nForms, const sal_Int32 _nReports );
+ void onFinishedSuccessfully();
+
+ protected:
+ // IMigrationProgress
+ virtual void startObject( const ::rtl::OUString& _rObjectName, const ::rtl::OUString& _rCurrentAction, const sal_uInt32 _bRange );
+ virtual void setObjectProgressText( const ::rtl::OUString& _rText );
+ virtual void setObjectProgressValue( const sal_uInt32 _nValue );
+ virtual void endObject();
+ virtual void start( const sal_uInt32 _nOverallRange );
+ virtual void setOverallProgressText( const ::rtl::OUString& _rText );
+ virtual void setOverallProgressValue( const sal_uInt32 _nValue );
+
+ private:
+ FixedText m_aObjectCount;
+ FixedText m_aCurrentObjectLabel;
+ FixedText m_aCurrentObject;
+ FixedText m_aCurrentActionLabel;
+ FixedText m_aCurrentAction;
+ RangeProgressBar m_aCurrentProgress;
+ FixedText m_aAllProgressLabel;
+ FixedText m_aAllProgressText;
+ RangeProgressBar m_aAllProgress;
+ FixedText m_aMigrationDone;
+ };
+
+ //====================================================================
+ //= ResultPage
+ //====================================================================
+ class ResultPage : public MacroMigrationPage
+ {
+ public:
+ ResultPage( MacroMigrationDialog& _rParentDialog );
+
+ static TabPage* Create( ::svt::RoadmapWizard& _rParentDialog );
+
+ void displayMigrationLog( const bool _bSuccessful, const String& _rLog );
+
+ private:
+ FixedText m_aChangesLabel;
+ MultiLineEdit m_aChanges;
+ String m_aSuccessful;
+ String m_aUnsuccessful;
+ };
+
+//........................................................................
+} // namespace dbmm
+//........................................................................
+
+#endif // DBACCESS_MACROMIGRATIONPAGES_HXX
diff --git a/dbaccess/source/ext/macromigration/macromigrationwizard.cxx b/dbaccess/source/ext/macromigration/macromigrationwizard.cxx
new file mode 100644
index 000000000000..732fa9906119
--- /dev/null
+++ b/dbaccess/source/ext/macromigration/macromigrationwizard.cxx
@@ -0,0 +1,268 @@
+/*************************************************************************
+ *
+ * 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: macromigrationwizard.cxx,v $
+ * $Revision: 1.3.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 "dbmm_module.hxx"
+#include "macromigrationdialog.hxx"
+
+/** === 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>
+#include <svtools/genericunodialog.hxx>
+
+//........................................................................
+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::uno::XComponentContext;
+ using ::com::sun::star::uno::Sequence;
+ using ::com::sun::star::beans::XPropertySetInfo;
+ using ::com::sun::star::beans::Property;
+ 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 === **/
+
+ //====================================================================
+ //= MacroMigrationDialogService
+ //====================================================================
+ class MacroMigrationDialogService;
+ typedef ::svt::OGenericUnoDialog MacroMigrationDialogService_Base;
+ typedef ::comphelper::OPropertyArrayUsageHelper< MacroMigrationDialogService > MacroMigrationDialogService_PBase;
+
+ class MacroMigrationDialogService
+ :public MacroMigrationDialogService_Base
+ ,public MacroMigrationDialogService_PBase
+ ,public MacroMigrationModuleClient
+ {
+ public:
+ MacroMigrationDialogService( const Reference< XComponentContext >& _rxContext );
+
+ // XTypeProvider
+ virtual Sequence< sal_Int8 > SAL_CALL getImplementationId() throw(RuntimeException);
+
+ // XServiceInfo
+ virtual ::rtl::OUString SAL_CALL getImplementationName() throw(RuntimeException);
+ virtual Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw(RuntimeException);
+
+ // XInitialization
+ virtual void SAL_CALL initialize( const com::sun::star::uno::Sequence< com::sun::star::uno::Any >& aArguments ) throw(com::sun::star::uno::Exception, com::sun::star::uno::RuntimeException);
+
+ // XPropertySet
+ virtual Reference< XPropertySetInfo > SAL_CALL getPropertySetInfo() throw(RuntimeException);
+ virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper();
+
+ // OPropertyArrayUsageHelper
+ virtual ::cppu::IPropertyArrayHelper* createArrayHelper( ) const;
+
+ // helper for factories
+ static Reference< XInterface > SAL_CALL Create( const Reference< XComponentContext >& _rxContext );
+ static ::rtl::OUString SAL_CALL getImplementationName_static() throw(RuntimeException);
+ static Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames_static() throw(RuntimeException);
+
+ protected:
+ ~MacroMigrationDialogService();
+
+ protected:
+ virtual Dialog* createDialog( Window* _pParent );
+ virtual void destroyDialog();
+
+ private:
+ ::comphelper::ComponentContext m_aContext;
+ Reference< XOfficeDatabaseDocument > m_xDocument;
+ };
+
+ //====================================================================
+ //= MacroMigrationDialogService
+ //====================================================================
+ //--------------------------------------------------------------------
+ MacroMigrationDialogService::MacroMigrationDialogService( const Reference< XComponentContext >& _rxContext )
+ :MacroMigrationDialogService_Base( _rxContext )
+ ,m_aContext( _rxContext )
+ {
+ m_bNeedInitialization = true;
+ }
+
+ //--------------------------------------------------------------------
+ MacroMigrationDialogService::~MacroMigrationDialogService()
+ {
+ // we do this here cause the base class' call to destroyDialog won't reach us anymore : we're within an dtor,
+ // so this virtual-method-call the base class does does not work, we're already dead then ...
+ if ( m_pDialog )
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if ( m_pDialog )
+ destroyDialog();
+ }
+ }
+
+ //--------------------------------------------------------------------
+ Reference< XInterface > SAL_CALL MacroMigrationDialogService::Create( const Reference< XComponentContext >& _rxContext )
+ {
+ return *(new MacroMigrationDialogService( _rxContext ) );
+ }
+
+ //--------------------------------------------------------------------
+ Dialog* MacroMigrationDialogService::createDialog( Window* _pParent )
+ {
+ return new MacroMigrationDialog( _pParent, m_aContext, m_xDocument );
+ }
+
+ //--------------------------------------------------------------------
+ void MacroMigrationDialogService::destroyDialog()
+ {
+ MacroMigrationDialogService_Base::destroyDialog();
+ }
+
+ //--------------------------------------------------------------------
+ Sequence< sal_Int8 > SAL_CALL MacroMigrationDialogService::getImplementationId() throw(RuntimeException)
+ {
+ static ::cppu::OImplementationId* pId = NULL;
+ if ( !pId )
+ {
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ if ( !pId )
+ {
+ static ::cppu::OImplementationId aId;
+ pId = &aId;
+ }
+ }
+ return pId->getImplementationId();
+ }
+
+ //--------------------------------------------------------------------
+ ::rtl::OUString SAL_CALL MacroMigrationDialogService::getImplementationName_static() throw(RuntimeException)
+ {
+ return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.dbaccess.macromigration.MacroMigrationDialogService" ) );
+ }
+
+ //--------------------------------------------------------------------
+ Sequence< ::rtl::OUString > SAL_CALL MacroMigrationDialogService::getSupportedServiceNames_static() throw(RuntimeException)
+ {
+ Sequence< ::rtl::OUString > aServices(1);
+ aServices[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdb.application.MacroMigrationWizard" ) );
+ return aServices;
+ }
+
+ //--------------------------------------------------------------------
+ ::rtl::OUString SAL_CALL MacroMigrationDialogService::getImplementationName() throw(RuntimeException)
+ {
+ return getImplementationName_static();
+ }
+
+ //--------------------------------------------------------------------
+ Sequence< ::rtl::OUString > SAL_CALL MacroMigrationDialogService::getSupportedServiceNames() throw(RuntimeException)
+ {
+ return getSupportedServiceNames_static();
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL MacroMigrationDialogService::initialize( const Sequence< Any >& _rArguments ) throw(Exception, RuntimeException)
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if ( m_bInitialized )
+ throw AlreadyInitializedException( ::rtl::OUString(), *this );
+
+ if ( _rArguments.getLength() != 1 )
+ throw IllegalArgumentException(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Invalid number of initialization arguments. Expected 1." ) ),
+ // TODO: resource
+ *this,
+ 1
+ );
+
+ m_xDocument.set( _rArguments[0], UNO_QUERY );
+ if ( !m_xDocument.is() )
+ throw IllegalArgumentException(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "No database document found in the initializatin arguments." ) ),
+ // TODO: resource
+ *this,
+ 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;
+ }
+
+ //--------------------------------------------------------------------
+ Reference< XPropertySetInfo > SAL_CALL MacroMigrationDialogService::getPropertySetInfo() throw(RuntimeException)
+ {
+ return createPropertySetInfo( getInfoHelper() );
+ }
+
+ //--------------------------------------------------------------------
+ ::cppu::IPropertyArrayHelper& SAL_CALL MacroMigrationDialogService::getInfoHelper()
+ {
+ return *const_cast< MacroMigrationDialogService* >( this )->getArrayHelper();
+ }
+
+ //--------------------------------------------------------------------
+ ::cppu::IPropertyArrayHelper* MacroMigrationDialogService::createArrayHelper( ) const
+ {
+ Sequence< Property > aProps;
+ describeProperties( aProps );
+ return new ::cppu::OPropertyArrayHelper( aProps );
+ }
+
+ //--------------------------------------------------------------------
+ void createRegistryInfo_MacroMigrationDialogService()
+ {
+ static OAutoRegistration< MacroMigrationDialogService > aAutoRegistration;
+ }
+
+//........................................................................
+} // namespace dbmm
+//........................................................................
diff --git a/dbaccess/source/ext/macromigration/makefile.mk b/dbaccess/source/ext/macromigration/makefile.mk
new file mode 100644
index 000000000000..b108cac667e4
--- /dev/null
+++ b/dbaccess/source/ext/macromigration/makefile.mk
@@ -0,0 +1,105 @@
+#*************************************************************************
+#
+# 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: makefile.mk,v $
+#
+# $Revision: 1.3.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.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+PRJINC=$(PRJ)$/source
+PRJNAME=dbaccess
+TARGET=dbmm
+USE_DEFFILE=TRUE
+
+ENABLE_EXCEPTIONS=TRUE
+VISIBILITY_HIDDEN=TRUE
+
+# --- Settings ----------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files -------------------------------------
+
+# ... resource files ............................
+
+SRS1NAME=$(TARGET)
+SRC1FILES = \
+ macromigration.src
+
+# ... object files ............................
+SLOFILES= $(SLO)$/macromigrationwizard.obj \
+ $(SLO)$/macromigrationdialog.obj \
+ $(SLO)$/macromigrationpages.obj \
+ $(SLO)$/dbmm_module.obj \
+ $(SLO)$/dbmm_services.obj \
+ $(SLO)$/migrationengine.obj \
+ $(SLO)$/docinteraction.obj \
+ $(SLO)$/progresscapture.obj \
+ $(SLO)$/progressmixer.obj \
+ $(SLO)$/migrationlog.obj \
+ $(SLO)$/dbmm_types.obj \
+
+# --- library -----------------------------------
+
+SHL1TARGET=$(TARGET)$(DLLPOSTFIX)
+SHL1VERSIONMAP=$(TARGET).map
+
+SHL1STDLIBS= \
+ $(CPPULIB) \
+ $(CPPUHELPERLIB) \
+ $(COMPHELPERLIB) \
+ $(UNOTOOLSLIB) \
+ $(TOOLSLIB) \
+ $(SALLIB) \
+ $(SVTOOLLIB) \
+ $(SVLLIB) \
+ $(VCLLIB) \
+ $(SVXCORELIB) \
+ $(SVXLIB) \
+ $(UCBHELPERLIB) \
+ $(XMLSCRIPTLIB)
+
+SHL1LIBS= $(SLB)$/$(TARGET).lib
+SHL1IMPLIB= i$(TARGET)
+SHL1DEPN= $(SHL1LIBS)
+SHL1DEF= $(MISC)$/$(SHL1TARGET).def
+
+DEF1NAME= $(SHL1TARGET)
+
+# --- .res files -------------------------------
+
+RES1FILELIST=\
+ $(SRS)$/$(TARGET).srs
+
+RESLIB1NAME=$(TARGET)
+RESLIB1IMAGES=$(PRJ)$/res
+RESLIB1SRSFILES=$(RES1FILELIST)
+
+# --- Targets ----------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/dbaccess/source/ext/macromigration/migrationengine.cxx b/dbaccess/source/ext/macromigration/migrationengine.cxx
new file mode 100644
index 000000000000..c1d1c41eca39
--- /dev/null
+++ b/dbaccess/source/ext/macromigration/migrationengine.cxx
@@ -0,0 +1,1993 @@
+/*************************************************************************
+ *
+ * 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: migrationengine.cxx,v $
+ * $Revision: 1.4.2.14 $
+ *
+ * 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_global.hrc"
+#include "dbmm_module.hxx"
+#include "dbmm_types.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>
+#include <com/sun/star/sdb/XReportDocumentsSupplier.hpp>
+#include <com/sun/star/util/XCloseable.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/frame/XComponentLoader.hpp>
+#include <com/sun/star/ucb/XCommandProcessor.hpp>
+#include <com/sun/star/ucb/XContent.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>
+#include <com/sun/star/io/WrongFormatException.hpp>
+#include <com/sun/star/script/XScriptEventsSupplier.hpp>
+#include <com/sun/star/io/XInputStreamProvider.hpp>
+/** === end UNO includes === **/
+
+#include <comphelper/documentinfo.hxx>
+#include <comphelper/interaction.hxx>
+#include <comphelper/namedvaluecollection.hxx>
+#include <comphelper/storagehelper.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 <xmlscript/xmldlg_imexp.hxx>
+
+#include <vector>
+#include <set>
+
+#define DEFAULT_DOC_PROGRESS_RANGE 100000
+
+//........................................................................
+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::sdb::XFormDocumentsSupplier;
+ using ::com::sun::star::sdb::XReportDocumentsSupplier;
+ using ::com::sun::star::container::XNameAccess;
+ using ::com::sun::star::uno::Sequence;
+ using ::com::sun::star::util::XCloseable;
+ using ::com::sun::star::util::CloseVetoException;
+ using ::com::sun::star::lang::XComponent;
+ using ::com::sun::star::frame::XModel;
+ using ::com::sun::star::frame::XComponentLoader;
+ using ::com::sun::star::ucb::XCommandProcessor;
+ using ::com::sun::star::ucb::XContent;
+ 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;
+ using ::com::sun::star::io::WrongFormatException;
+ using ::com::sun::star::script::XScriptEventsSupplier;
+ using ::com::sun::star::io::XInputStreamProvider;
+ using ::com::sun::star::io::XInputStream;
+ /** === 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;
+ Reference< XModel > xDocument; // valid only temporarily
+ ::rtl::OUString sHierarchicalName;
+ SubDocumentType eType;
+ size_t nNumber;
+
+ SubDocument( const Reference< XCommandProcessor >& _rxCommandProcessor, const ::rtl::OUString& _rName,
+ const SubDocumentType _eType, const size_t _nNumber )
+ :xCommandProcessor( _rxCommandProcessor )
+ ,xDocument()
+ ,sHierarchicalName( _rName )
+ ,eType( _eType )
+ ,nNumber( _nNumber )
+ {
+ }
+ };
+
+ 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 );
+ }
+
+ //----------------------------------------------------------------
+ ::rtl::OUString lcl_getMimeType_nothrow( const Reference< XCommandProcessor >& _rxContent )
+ {
+ ::rtl::OUString sMimeType;
+ try
+ {
+ Reference< XContent > xContent( _rxContent, UNO_QUERY_THROW );
+ sMimeType = xContent->getContentType();
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ return sMimeType;
+ }
+
+ //----------------------------------------------------------------
+ enum OpenDocResult
+ {
+ eOpenedDoc,
+ eIgnoreDoc,
+ eFailure
+ };
+
+ //----------------------------------------------------------------
+ static OpenDocResult 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& )
+ {
+ Any aError( ::cppu::getCaughtException() );
+
+ bool bCausedByNewStyleReport =
+ ( _rDocument.eType == eReport )
+ && ( aError.isExtractableTo( ::cppu::UnoType< WrongFormatException >::get() ) )
+ && ( lcl_getMimeType_nothrow( _rDocument.xCommandProcessor ).equalsAscii( "application/vnd.sun.xml.report" ) );
+
+ if ( bCausedByNewStyleReport )
+ {
+ _rLogger.logRecoverable( MigrationError(
+ ERR_NEW_STYLE_REPORT,
+ lcl_getSubDocumentDescription( _rDocument )
+ ) );
+ return eIgnoreDoc;
+ }
+ else
+ {
+ _rLogger.logFailure( MigrationError(
+ ERR_OPENING_SUB_DOCUMENT_FAILED,
+ lcl_getSubDocumentDescription( _rDocument ),
+ aError
+ ) );
+ }
+ }
+ return _rDocument.xDocument.is() ? eOpenedDoc : eFailure;
+ }
+
+ //----------------------------------------------------------------
+ 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
+ {
+ public:
+ MigrationEngine_Impl(
+ const ::comphelper::ComponentContext& _rContext,
+ const Reference< XOfficeDatabaseDocument >& _rxDocument,
+ IMigrationProgress& _rProgress,
+ MigrationLog& _rLogger
+ );
+ ~MigrationEngine_Impl();
+
+ inline size_t getFormCount() const { return m_nFormCount; }
+ inline size_t getReportCount()const { return m_nReportCount; }
+ bool migrateAll();
+
+ 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;
+
+ private:
+ /** collects a description of all sub documents of our database document
+
+ @return
+ <TRUE/> if and only if collecting the documents was successful
+ */
+ bool impl_collectSubDocuments_nothrow();
+
+ /** 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;
+
+ /** adjusts the events for the given dialog/element, taking into account the new names
+ of the moved libraries
+ */
+ void impl_adjustDialogElementEvents_throw(
+ const Reference< XInterface >& _rxElement
+ ) const;
+
+ /** adjusts the events in the given dialog, and its controls, taking into account the new names
+ of the moved libraries
+ */
+ bool impl_adjustDialogEvents_nothrow(
+ Any& _inout_rDialogLibraryElement,
+ const ::rtl::OUString& _rDocName,
+ const ::rtl::OUString& _rDialogLibName,
+ const ::rtl::OUString& _rDialogName
+ ) 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;
+ };
+
+ //====================================================================
+ //= MigrationEngine_Impl - implementation
+ //====================================================================
+ //--------------------------------------------------------------------
+ MigrationEngine_Impl::MigrationEngine_Impl( const ::comphelper::ComponentContext& _rContext,
+ 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 )
+ {
+ OSL_VERIFY( impl_collectSubDocuments_nothrow() );
+ }
+
+ //--------------------------------------------------------------------
+ MigrationEngine_Impl::~MigrationEngine_Impl()
+ {
+ }
+
+ //--------------------------------------------------------------------
+ bool MigrationEngine_Impl::migrateAll()
+ {
+ if ( m_aSubDocs.empty() )
+ {
+ OSL_ENSURE( false, "MigrationEngine_Impl::migrateAll: no forms/reports found!" );
+ // The whole migration wizard is not expected to be called when there are no forms/reports
+ // with macros, not to mention when there are no forms/reports at all.
+ return false;
+ }
+
+ // initialize global progress
+ sal_Int32 nOverallRange( m_aSubDocs.size() );
+ String sProgressSkeleton = String( MacroMigrationResId( STR_OVERALL_PROGRESS ) );
+ sProgressSkeleton.SearchAndReplaceAscii( "$overall$", String::CreateFromInt32( nOverallRange ) );
+
+ m_rProgress.start( nOverallRange );
+
+ for ( SubDocuments::const_iterator doc = m_aSubDocs.begin();
+ doc != m_aSubDocs.end();
+ ++doc
+ )
+ {
+ sal_Int32 nOverallProgressValue( doc - m_aSubDocs.begin() + 1 );
+ // update overall progress text
+ ::rtl::OUString sOverallProgress( sProgressSkeleton );
+ ::comphelper::string::searchAndReplaceAsciiI( sOverallProgress, "$current$", ::rtl::OUString::valueOf( nOverallProgressValue ) );
+ m_rProgress.setOverallProgressText( sOverallProgress );
+
+ // migrate document
+ if ( !impl_handleDocument_nothrow( *doc ) )
+ return false;
+
+ // update overall progress vallue
+ 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;
+ }
+
+ //--------------------------------------------------------------------
+ namespace
+ {
+ void lcl_collectHierarchicalElementNames_throw(
+ const Reference< XNameAccess >& _rxContainer, const ::rtl::OUString& _rContainerLoc,
+ SubDocuments& _out_rDocs, const SubDocumentType _eType, size_t& _io_counter )
+ {
+ const ::rtl::OUString sHierarhicalBase(
+ _rContainerLoc.getLength() ? ::rtl::OUStringBuffer( _rContainerLoc ).appendAscii( "/" ).makeStringAndClear()
+ : ::rtl::OUString() );
+
+ Sequence< ::rtl::OUString > aElementNames( _rxContainer->getElementNames() );
+ for ( const ::rtl::OUString* elementName = aElementNames.getConstArray();
+ elementName != aElementNames.getConstArray() + aElementNames.getLength();
+ ++elementName
+ )
+ {
+ Any aElement( _rxContainer->getByName( *elementName ) );
+ ::rtl::OUString sElementName( ::rtl::OUStringBuffer( sHierarhicalBase ).append( *elementName ) );
+
+ Reference< XNameAccess > xSubContainer( aElement, UNO_QUERY );
+ if ( xSubContainer.is() )
+ {
+ lcl_collectHierarchicalElementNames_throw( xSubContainer, sElementName, _out_rDocs, _eType, _io_counter );
+ }
+ else
+ {
+ Reference< XCommandProcessor > xCommandProcessor( aElement, UNO_QUERY );
+ OSL_ENSURE( xCommandProcessor.is(), "lcl_collectHierarchicalElementNames_throw: no container, and no comand processor? What *is* it, then?!" );
+ if ( xCommandProcessor.is() )
+ {
+ _out_rDocs.push_back( SubDocument( xCommandProcessor, sElementName, _eType, ++_io_counter ) );
+ }
+ }
+ }
+ }
+ }
+
+ //--------------------------------------------------------------------
+ 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
+ {
+ Reference< XNameAccess > xDocContainer( m_xDocument->getFormDocuments(), UNO_SET_THROW );
+ m_nFormCount = 0;
+ lcl_collectHierarchicalElementNames_throw( xDocContainer, ::rtl::OUString(), m_aSubDocs, eForm, m_nFormCount );
+
+ xDocContainer.set( m_xDocument->getReportDocuments(), UNO_SET_THROW );
+ m_nReportCount = 0;
+ lcl_collectHierarchicalElementNames_throw( xDocContainer, ::rtl::OUString(), m_aSubDocs, eReport, m_nReportCount );
+ }
+ catch( const 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 );
+ OpenDocResult eResult = lcl_loadSubDocument_nothrow( aSubDocument, pStatusIndicator.get(), m_rLogger );
+ if ( eResult != eOpenedDoc )
+ {
+ pStatusIndicator->dispose();
+ m_rProgress.endObject();
+ m_rLogger.finishedDocument( m_nCurrentDocumentID );
+ m_nCurrentDocumentID = -1;
+ return ( eResult == eIgnoreDoc );
+ }
+
+ // -----------------
+ // 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 );
+ // order matters: First Basic scripts, then dialogs. So we can adjust references from the latter
+ // to the former
+
+ // 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
+ if ( m_rLogger.movedAnyLibrary( m_nCurrentDocumentID ) )
+ {
+ 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 ::rtl::OUString lcl_createTargetLibName( const SubDocument& _rDocument,
+ const ::rtl::OUString& _rSourceLibName, const Reference< XNameAccess >& _rxTargetContainer )
+ {
+ // The new library name is composed from the prefix, the base name, and the old library name.
+ const ::rtl::OUString sPrefix( ::rtl::OUString::createFromAscii( _rDocument.eType == eForm ? "Form_" : "Report_" ) );
+
+ ::rtl::OUString sBaseName( _rDocument.sHierarchicalName.copy(
+ _rDocument.sHierarchicalName.lastIndexOf( '/' ) + 1 ) );
+ // Normalize this name. In our current storage implementation (and script containers in a document
+ // are finally mapped to sub storages of the document storage), not all characters are allowed.
+ // The bug requesting to change this is #i95409#.
+ // Unfortunately, the storage implementation does not complain if you use invalid characters/names, but instead
+ // it silently accepts them, and produces garbage in the file (#i95408).
+ // So, until especially the former is fixed, we need to strip the name from all invalid characters.
+ // #i95865# / 2008-11-06 / frank.schoenheit@sun.com
+
+ // The general idea is to replace invalid characters with '_'. However, since "valid" essentially means
+ // ASCII only, this implies that for a lot of languages, we would simply replace everything with '_',
+ // which of course is not desired.
+ // So, we use a heuristics: If the name contains at most 3 invalid characters, and as many valid as invalid
+ // characters, then we use the replacement. Otherwise, we just use a unambiguous number for the sub document.
+ sal_Int32 nValid=0, nInvalid=0;
+ const sal_Unicode* pBaseName = sBaseName.getStr();
+ const sal_Int32 nBaseNameLen = sBaseName.getLength();
+ for ( sal_Int32 i=0; i<nBaseNameLen; ++i )
+ {
+ if ( ::comphelper::OStorageHelper::IsValidZipEntryFileName( pBaseName + i, 1, sal_False ) )
+ ++nValid;
+ else
+ ++nInvalid;
+ }
+ if ( ( nInvalid <= 3 ) && ( nInvalid * 2 <= nValid ) )
+ { // not "too many" invalid => replace them
+ ::rtl::OUStringBuffer aReplacement;
+ aReplacement.ensureCapacity( nBaseNameLen );
+ aReplacement.append( sBaseName );
+ const sal_Unicode* pReplacement = aReplacement.getStr();
+ for ( sal_Int32 i=0; i<nBaseNameLen; ++i )
+ {
+ if ( !::comphelper::OStorageHelper::IsValidZipEntryFileName( pReplacement + i, 1, sal_False ) )
+ aReplacement.setCharAt( i, '_' );
+ }
+ sBaseName = aReplacement.makeStringAndClear();
+
+ ::rtl::OUStringBuffer aNewLibNameAttempt;
+ aNewLibNameAttempt.append( sPrefix );
+ aNewLibNameAttempt.append( sBaseName );
+ aNewLibNameAttempt.appendAscii( "_" );
+ aNewLibNameAttempt.append( _rSourceLibName );
+ ::rtl::OUString sTargetName( aNewLibNameAttempt.makeStringAndClear() );
+ if ( !_rxTargetContainer->hasByName( sTargetName ) )
+ return sTargetName;
+ }
+
+ // "too many" invalid characters, or the name composed with the base name was already used.
+ // (The latter is valid, since there can be multiple sub documents with the same base name,
+ // in different levels in the hierarchy.)
+ // In this case, just use the umambiguous sub document number.
+ ::rtl::OUStringBuffer aNewLibName;
+ aNewLibName.append( sPrefix );
+ aNewLibName.append( ::rtl::OUString::valueOf( sal_Int64( _rDocument.nNumber ) ) );
+ aNewLibName.appendAscii( "_" );
+ aNewLibName.append( _rSourceLibName );
+ return aNewLibName.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() )
+ {
+ m_rLogger.logFailure( MigrationError(
+ ERR_UNKNOWN_SCRIPT_FOLDER,
+ lcl_getSubDocumentDescription( _rDocument ),
+ *aElementNames.begin()
+ ) );
+ return false;
+ }
+ }
+ 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 )
+ )
+ {
+ // no scripts at all, or no scripts of the given type
+ _rProgress.startPhase( _nPhaseID, 1 );
+ _rProgress.endPhase();
+ return !m_rLogger.hadFailure();
+ }
+
+ 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
+ )
+ {
+ 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,
+ getScriptTypeDisplayName( _eScriptType ),
+ lcl_getSubDocumentDescription( _rDocument )
+ ) );
+ 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;
+ }
+
+ // log the error, if any
+ if ( !bSuccess )
+ {
+ m_rLogger.logFailure( MigrationError(
+ ERR_GENERAL_SCRIPT_MIGRATION_FAILURE,
+ getScriptTypeDisplayName( _eScriptType ),
+ lcl_getSubDocumentDescription( _rDocument ),
+ aException
+ ) );
+ }
+
+ 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() )
+ {
+ bSuccess = true;
+ break;
+ }
+
+ // 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!" );
+
+ // if this is a dialog, adjust the references to scripts
+ if ( _eScriptType == eDialog )
+ {
+ impl_adjustDialogEvents_nothrow( aElement, lcl_getSubDocumentDescription( _rDocument ),
+ *pSourceLibName, *pSourceElementName );
+ }
+
+ xTargetLib->insertByName( *pSourceElementName, aElement );
+ }
+
+ // transfer the read-only flag
+ xTargetLibraries->setLibraryReadOnly(
+ sNewLibName, xSourceLibraries->isLibraryReadOnly( *pSourceLibName ) );
+ }
+
+ // 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 );
+ }
+
+ // 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()
+ )
+ {
+ 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;
+ }
+
+ // 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_adjustScriptLibrary_nothrow( ScriptEventDescriptor& _inout_rScriptEvent ) const
+ {
+ if ( _inout_rScriptEvent.ScriptType.getLength() && _inout_rScriptEvent.ScriptCode.getLength() )
+ return impl_adjustScriptLibrary_nothrow( _inout_rScriptEvent.ScriptType, _inout_rScriptEvent.ScriptCode );
+ return false;
+ }
+
+ //--------------------------------------------------------------------
+ bool MigrationEngine_Impl::impl_adjustScriptLibrary_nothrow( Any& _inout_rScriptDescriptor ) const
+ {
+ ::comphelper::NamedValueCollection aScriptDesc( _inout_rScriptDescriptor );
+
+ ::rtl::OUString sScriptType;
+ ::rtl::OUString sScript;
+ try
+ {
+ 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;
+ }
+
+ //--------------------------------------------------------------------
+ void MigrationEngine_Impl::impl_adjustDialogElementEvents_throw( const Reference< XInterface >& _rxElement ) const
+ {
+ Reference< XScriptEventsSupplier > xEventsSupplier( _rxElement, UNO_QUERY_THROW );
+ Reference< XNameReplace > xEvents( xEventsSupplier->getEvents(), UNO_QUERY_THROW );
+ Sequence< ::rtl::OUString > aEventNames( xEvents->getElementNames() );
+
+ const ::rtl::OUString* eventName = aEventNames.getArray();
+ const ::rtl::OUString* eventNamesEnd = eventName + aEventNames.getLength();
+
+ ScriptEventDescriptor aScriptEvent;
+ for ( ; eventName != eventNamesEnd; ++eventName )
+ {
+ OSL_VERIFY( xEvents->getByName( *eventName ) >>= aScriptEvent );
+
+ if ( !impl_adjustScriptLibrary_nothrow( aScriptEvent ) )
+ continue;
+
+ xEvents->replaceByName( *eventName, makeAny( aScriptEvent ) );
+ }
+ }
+
+ //--------------------------------------------------------------------
+ bool MigrationEngine_Impl::impl_adjustDialogEvents_nothrow( Any& _inout_rDialogLibraryElement,
+ const ::rtl::OUString& _rDocName, const ::rtl::OUString& _rDialogLibName, const ::rtl::OUString& _rDialogName ) const
+ {
+ try
+ {
+ // load a dialog model from the stream describing it
+ Reference< XInputStreamProvider > xISP( _inout_rDialogLibraryElement, UNO_QUERY_THROW );
+ Reference< XInputStream > xInput( xISP->createInputStream(), UNO_QUERY_THROW );
+
+ Reference< XNameContainer > xDialogModel( m_aContext.createComponent( "com.sun.star.awt.UnoControlDialogModel" ), UNO_QUERY_THROW );
+ ::xmlscript::importDialogModel( xInput, xDialogModel, m_aContext.getUNOContext() );
+
+ // adjust the events of the dialog
+ impl_adjustDialogElementEvents_throw( xDialogModel );
+
+ // adjust the events of the controls
+ Sequence< ::rtl::OUString > aControlNames( xDialogModel->getElementNames() );
+ const ::rtl::OUString* controlName = aControlNames.getConstArray();
+ const ::rtl::OUString* controlNamesEnd = controlName + aControlNames.getLength();
+ for ( ; controlName != controlNamesEnd; ++controlName )
+ {
+ impl_adjustDialogElementEvents_throw( Reference< XInterface >( xDialogModel->getByName( *controlName ), UNO_QUERY ) );
+ }
+
+ // export dialog model
+ xISP = ::xmlscript::exportDialogModel( xDialogModel, m_aContext.getUNOContext() );
+ _inout_rDialogLibraryElement <<= xISP;
+ }
+ catch( const Exception& )
+ {
+ m_rLogger.logRecoverable( MigrationError(
+ ERR_ADJUSTING_DIALOG_EVENTS_FAILED,
+ _rDocName,
+ _rDialogLibName,
+ _rDialogName,
+ ::cppu::getCaughtException()
+ ) );
+ return false;
+ }
+ return true;
+ }
+
+ //--------------------------------------------------------------------
+ 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() );
+
+ bool bChangedComponentEvents = false;
+ for ( ScriptEventDescriptor* scriptEvent = aEvents.getArray();
+ scriptEvent != aEvents.getArray() + aEvents.getLength();
+ ++scriptEvent
+ )
+ {
+ if ( !impl_adjustScriptLibrary_nothrow( *scriptEvent ) )
+ continue;
+
+ bChangedComponentEvents = true;
+ }
+
+ if ( bChangedComponentEvents )
+ aComponent.setEvents( aEvents );
+
+ // 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;
+ }
+
+ //--------------------------------------------------------------------
+ bool MigrationEngine_Impl::impl_unprotectPasswordLibrary_throw( const Reference< XLibraryContainerPassword >& _rxPasswordManager,
+ const ScriptType _eScriptType, const ::rtl::OUString& _rLibraryName ) const
+ {
+ // 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;
+ }
+
+ }
+
+ //====================================================================
+ //= MigrationEngine
+ //====================================================================
+ //--------------------------------------------------------------------
+ MigrationEngine::MigrationEngine( const ::comphelper::ComponentContext& _rContext,
+ const Reference< XOfficeDatabaseDocument >& _rxDocument, IMigrationProgress& _rProgress,
+ MigrationLog& _rLogger )
+ :m_pImpl( new MigrationEngine_Impl( _rContext, _rxDocument, _rProgress, _rLogger ) )
+ {
+ }
+
+ //--------------------------------------------------------------------
+ MigrationEngine::~MigrationEngine()
+ {
+ }
+
+ //--------------------------------------------------------------------
+ sal_Int32 MigrationEngine::getFormCount() const
+ {
+ return m_pImpl->getFormCount();
+ }
+
+ //--------------------------------------------------------------------
+ sal_Int32 MigrationEngine::getReportCount() const
+ {
+ return m_pImpl->getReportCount();
+ }
+
+ //--------------------------------------------------------------------
+ bool MigrationEngine::migrateAll()
+ {
+ return m_pImpl->migrateAll();
+ }
+
+//........................................................................
+} // namespace dbmm
+//........................................................................
diff --git a/dbaccess/source/ext/macromigration/migrationengine.hxx b/dbaccess/source/ext/macromigration/migrationengine.hxx
new file mode 100644
index 000000000000..cce304e767ed
--- /dev/null
+++ b/dbaccess/source/ext/macromigration/migrationengine.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: migrationengine.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_MIGRATIONENGINE_HXX
+#define DBACCESS_MIGRATIONENGINE_HXX
+
+/** === begin UNO includes === **/
+#include <com/sun/star/sdb/XOfficeDatabaseDocument.hpp>
+/** === end UNO includes === **/
+
+#include <comphelper/componentcontext.hxx>
+
+#include <memory>
+
+namespace comphelper {
+ class ComponentContext;
+}
+
+//........................................................................
+namespace dbmm
+{
+//........................................................................
+
+ class IMigrationProgress;
+ class MigrationLog;
+
+ //====================================================================
+ //= MigrationEngine
+ //====================================================================
+ class MigrationEngine_Impl;
+ class MigrationEngine
+ {
+ public:
+ /** creates the migration engine
+ @param _rxDocument
+ the document whose macros/scripts should be migrated
+ @param _rProgress
+ a callback for notifying progress. Beware of lifetimes here: The progress callback,
+ passed herein as reference, must live as long as the engine instance lives.
+ */
+ MigrationEngine(
+ const ::comphelper::ComponentContext& _rContext,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::sdb::XOfficeDatabaseDocument >& _rxDocument,
+ IMigrationProgress& _rProgress,
+ MigrationLog& _rLogger
+ );
+
+ ~MigrationEngine();
+
+ sal_Int32 getFormCount() const;
+ sal_Int32 getReportCount() const;
+
+ /** starts migrating the scripts and macros in the forms/reports to the database
+ document.
+
+ This process cannot be cancelled, as it would leave the document in an inconsistent
+ state.
+
+ When the function returns, then the migration is finished.
+
+ @return
+ whether or not the migration was successful. If it wasn't, then an error has been reported
+ to the user, using the document's interaction handler. If no such interaction handler
+ was present, then the error has been silenced.
+ */
+ bool migrateAll();
+
+ private:
+ ::std::auto_ptr< MigrationEngine_Impl > m_pImpl;
+ };
+
+//........................................................................
+} // namespace dbmm
+//........................................................................
+
+#endif // DBACCESS_MIGRATIONENGINE_HXX
diff --git a/dbaccess/source/ext/macromigration/migrationerror.hxx b/dbaccess/source/ext/macromigration/migrationerror.hxx
new file mode 100644
index 000000000000..fa7e058a5622
--- /dev/null
+++ b/dbaccess/source/ext/macromigration/migrationerror.hxx
@@ -0,0 +1,176 @@
+/*************************************************************************
+* 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_DIALOG_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,
+ ERR_NEW_STYLE_REPORT
+ };
+
+ //====================================================================
+ //= 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,
+ const ::com::sun::star::uno::Any& _rCaughtException )
+ :eType( _eType )
+ ,aCaughtException( _rCaughtException )
+ {
+ impl_constructDetails( _rDetail1, _rDetail2, _rDetail3 );
+ }
+
+ 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
new file mode 100644
index 000000000000..0d3cb09427b8
--- /dev/null
+++ b/dbaccess/source/ext/macromigration/migrationlog.cxx
@@ -0,0 +1,515 @@
+/*************************************************************************
+ *
+ * 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: migrationlog.cxx,v $
+ * $Revision: 1.4.2.8 $
+ *
+ * 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_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
+{
+//........................................................................
+
+ /** === begin UNO using === **/
+ /** === end UNO using === **/
+
+ //====================================================================
+ //= LibraryEntry
+ //====================================================================
+ struct LibraryEntry
+ {
+ ScriptType eType;
+ ::rtl::OUString sOldName;
+ ::rtl::OUString sNewName;
+
+ LibraryEntry()
+ :eType( eBasic )
+ ,sOldName()
+ ,sNewName()
+ {
+ }
+
+ LibraryEntry( const ScriptType& _eType, const ::rtl::OUString& _rOldName, const ::rtl::OUString& _rNewName )
+ :eType( _eType )
+ ,sOldName( _rOldName )
+ ,sNewName( _rNewName )
+ {
+ }
+ };
+
+ //====================================================================
+ //= DocumentEntry
+ //====================================================================
+ struct DocumentEntry
+ {
+ SubDocumentType eType;
+ ::rtl::OUString sName;
+ ::std::vector< LibraryEntry > aMovedLibraries;
+
+ DocumentEntry()
+ :eType( eForm )
+ ,sName()
+ ,aMovedLibraries()
+ {
+ }
+
+ DocumentEntry( const SubDocumentType _eType, const ::rtl::OUString& _rName )
+ :eType( _eType )
+ ,sName( _rName )
+ {
+ }
+ };
+
+ //====================================================================
+ //= DocumentLogs
+ //====================================================================
+ 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;
+ };
+
+ //====================================================================
+ //= MigrationLog
+ //====================================================================
+ //--------------------------------------------------------------------
+ MigrationLog::MigrationLog()
+ :m_pData( new MigrationLog_Data )
+ {
+ }
+
+ //--------------------------------------------------------------------
+ MigrationLog::~MigrationLog()
+ {
+ }
+
+ //--------------------------------------------------------------------
+ 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;
+ }
+
+ //--------------------------------------------------------------------
+ DocumentID MigrationLog::startedDocument( const SubDocumentType _eType, const ::rtl::OUString& _rName )
+ {
+#if OSL_DEBUG_LEVEL > 0
+ bool bAlreadyKnown = false;
+ for ( DocumentLogs::const_iterator doc = m_pData->aDocumentLogs.begin();
+ doc != m_pData->aDocumentLogs.end() && !bAlreadyKnown;
+ ++doc
+ )
+ {
+ bAlreadyKnown = ( doc->second.eType == _eType ) && ( doc->second.sName == _rName );
+ }
+ OSL_ENSURE( !bAlreadyKnown, "MigrationLog::startedDocument: document is already known!" );
+#endif
+
+ DocumentID nID = (DocumentID)( m_pData->aDocumentLogs.size() + 1 );
+ while ( m_pData->aDocumentLogs.find( nID ) != m_pData->aDocumentLogs.end() )
+ ++nID;
+
+ m_pData->aDocumentLogs[ nID ] = DocumentEntry( _eType, _rName );
+
+ return nID;
+ }
+
+ //--------------------------------------------------------------------
+ void MigrationLog::movedLibrary( const DocumentID _nDocID, const ScriptType _eScriptType,
+ const ::rtl::OUString& _rOriginalLibName, const ::rtl::OUString& _rNewLibName )
+ {
+ OSL_ENSURE( m_pData->aDocumentLogs.find( _nDocID ) != m_pData->aDocumentLogs.end(),
+ "MigrationLog::movedLibrary: document is not known!" );
+
+ DocumentEntry& rDocEntry = m_pData->aDocumentLogs[ _nDocID ];
+ rDocEntry.aMovedLibraries.push_back( LibraryEntry( _eScriptType, _rOriginalLibName, _rNewLibName ) );
+ }
+
+ //--------------------------------------------------------------------
+ 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 ];
+ (void)rDocEntry;
+ // nothing to do here
+ }
+
+ //--------------------------------------------------------------------
+ const ::rtl::OUString& MigrationLog::getNewLibraryName( DocumentID _nDocID, ScriptType _eScriptType,
+ const ::rtl::OUString& _rOriginalLibName ) const
+ {
+ static ::rtl::OUString s_sEmptyString;
+
+ DocumentLogs::const_iterator docPos = m_pData->aDocumentLogs.find( _nDocID );
+ if ( docPos == m_pData->aDocumentLogs.end() )
+ {
+ OSL_ENSURE( false, "MigrationLog::getNewLibraryName: document is not known!" );
+ return s_sEmptyString;
+ }
+
+ const DocumentEntry& rDocEntry( docPos->second );
+ for ( ::std::vector< LibraryEntry >::const_iterator lib = rDocEntry.aMovedLibraries.begin();
+ lib != rDocEntry.aMovedLibraries.end();
+ ++lib
+ )
+ {
+ if ( ( _eScriptType == lib->eType )
+ && ( _rOriginalLibName == lib->sOldName )
+ )
+ return lib->sNewName;
+ }
+
+ OSL_ENSURE( false, "MigrationLog::getNewLibraryName: doc is known, but library isn't!" );
+ return s_sEmptyString;
+ }
+
+ //--------------------------------------------------------------------
+ namespace
+ {
+ //----------------------------------------------------------------
+ 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 '#doc#' failed";
+ aAsciiParameterNames.push_back( "#doc#" );
+ break;
+
+ case ERR_CLOSING_SUB_DOCUMENT_FAILED:
+ pAsciiErrorDescription = "closing '#doc#' failed";
+ aAsciiParameterNames.push_back( "#doc#" );
+ break;
+
+ case ERR_STORAGE_COMMIT_FAILED:
+ pAsciiErrorDescription = "committing the changes for document '#doc#' failed";
+ aAsciiParameterNames.push_back( "#doc#" );
+ 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 while migrating #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_DIALOG_EVENTS_FAILED:
+ pAsciiErrorDescription = "adjusting events for dialog #lib#.#dlg# in document '#doc#' failed";
+ aAsciiParameterNames.push_back( "#doc#" );
+ aAsciiParameterNames.push_back( "#lib#" );
+ aAsciiParameterNames.push_back( "#dlg#" );
+ 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;
+
+ case ERR_NEW_STYLE_REPORT:
+ pAsciiErrorDescription = "#doc# could not be processed, since you don't have the Sun Report Builder (TM) extension installed.";
+ aAsciiParameterNames.push_back( "#doc#" );
+ 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 )
+ {
+ _rBuffer.appendAscii( "=== " );
+ _rBuffer.append ( String( MacroMigrationResId( _nHeadingResId ) ) );
+ _rBuffer.appendAscii( " ===\n" );
+
+ String sException( MacroMigrationResId( STR_EXCEPTION ) );
+
+ for ( ErrorLog::const_iterator error = _rErrors.begin();
+ error != _rErrors.end();
+ ++error
+ )
+ {
+ _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' ) );
+ }
+ }
+ }
+
+ //--------------------------------------------------------------------
+ bool MigrationLog::movedAnyLibrary( const DocumentID _nDocID )
+ {
+ DocumentLogs::const_iterator docPos = m_pData->aDocumentLogs.find( _nDocID );
+ if ( docPos == m_pData->aDocumentLogs.end() )
+ {
+ OSL_ENSURE( false, "MigrationLog::movedAnyLibrary: document is not known!" );
+ return false;
+ }
+ return !docPos->second.aMovedLibraries.empty();
+ }
+
+ //--------------------------------------------------------------------
+ ::rtl::OUString MigrationLog::getCompleteLog() const
+ {
+ ::rtl::OUStringBuffer aBuffer;
+
+ if ( m_pData->sBackupLocation.getLength() )
+ {
+ 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" );
+ }
+
+ 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
+ )
+ {
+ 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 );
+
+ 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' ) );
+ }
+ }
+
+ if ( !m_pData->aWarnings.empty() )
+ {
+ lcl_describeErrors( aBuffer, m_pData->aWarnings, STR_WARNINGS );
+ }
+
+ return aBuffer.makeStringAndClear();
+ }
+
+//........................................................................
+} // namespace dbmm
+//........................................................................
diff --git a/dbaccess/source/ext/macromigration/migrationlog.hxx b/dbaccess/source/ext/macromigration/migrationlog.hxx
new file mode 100644
index 000000000000..ebc81435aef7
--- /dev/null
+++ b/dbaccess/source/ext/macromigration/migrationlog.hxx
@@ -0,0 +1,131 @@
+/*************************************************************************
+ *
+ * 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: migrationlog.hxx,v $
+ * $Revision: 1.3.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_MIGRATIONLOG_HXX
+#define DBACCESS_MIGRATIONLOG_HXX
+
+#include "dbmm_types.hxx"
+
+/** === begin UNO includes === **/
+/** === end UNO includes === **/
+
+#include <rtl/ustring.hxx>
+
+#include <memory>
+
+//........................................................................
+namespace dbmm
+{
+//........................................................................
+
+ typedef sal_Int16 DocumentID;
+ struct MigrationError;
+
+ //====================================================================
+ //= MigrationLog
+ //====================================================================
+ struct MigrationLog_Data;
+ class MigrationLog
+ {
+ public:
+ MigrationLog();
+ ~MigrationLog();
+
+ //----------------------------------------------------------------
+ //- 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 );
+
+ /** logs that the migration for a certain sub document has been started, returns
+ a unique ID for this sub document which is to be used in later calls
+ */
+ DocumentID startedDocument( const SubDocumentType _eType, const ::rtl::OUString& _rName );
+
+ /** logs the event that a macro or script library has been moved from within a
+ sub document to the database document
+ */
+ void movedLibrary(
+ const DocumentID _nDocID,
+ const ScriptType _eScriptType,
+ const ::rtl::OUString& _rOriginalLibName,
+ const ::rtl::OUString& _rNewLibName
+ );
+
+ /** logs that the migration for a certain document has been finished
+ */
+ void finishedDocument( const DocumentID _nDocID );
+
+ //----------------------------------------------------------------
+ //- information retrieval
+
+ /** retrieves the new name of a library
+
+ The new library name must previously have been logger by calling
+ <member>movedLibrary</member>. If not, an assertion will be raised in
+ the non-product builds, and an empty string will be returned.
+ */
+ const ::rtl::OUString&
+ getNewLibraryName(
+ DocumentID _nDocID,
+ ScriptType _eScriptType,
+ const ::rtl::OUString& _rOriginalLibName
+ ) const;
+
+ /** determines whether for the given document, any library needed to be (and was) moved
+ */
+ bool movedAnyLibrary( const DocumentID );
+
+ /** provides a human-readable version of the log, explaining a user what happened during
+ the migration.
+ */
+ ::rtl::OUString
+ getCompleteLog() const;
+
+ private:
+ ::std::auto_ptr< MigrationLog_Data > m_pData;
+ };
+
+//........................................................................
+} // namespace dbmm
+//........................................................................
+
+#endif // DBACCESS_MIGRATIONLOG_HXX
diff --git a/dbaccess/source/ext/macromigration/migrationprogress.hxx b/dbaccess/source/ext/macromigration/migrationprogress.hxx
new file mode 100644
index 000000000000..8818010d8ea2
--- /dev/null
+++ b/dbaccess/source/ext/macromigration/migrationprogress.hxx
@@ -0,0 +1,61 @@
+/*************************************************************************
+ *
+ * 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: migrationprogress.hxx,v $
+ * $Revision: 1.3.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_MIGRATIONPROGRESS_HXX
+#define DBACCESS_MIGRATIONPROGRESS_HXX
+
+/** === begin UNO includes === **/
+/** === end UNO includes === **/
+
+//........................................................................
+namespace dbmm
+{
+//........................................................................
+
+ //====================================================================
+ //= IMigrationProgress
+ //====================================================================
+ class SAL_NO_VTABLE IMigrationProgress
+ {
+ public:
+ virtual void startObject( const ::rtl::OUString& _rObjectName, const ::rtl::OUString& _rCurrentAction, const sal_uInt32 _nRange ) = 0;
+ virtual void setObjectProgressText( const ::rtl::OUString& _rText ) = 0;
+ virtual void setObjectProgressValue( const sal_uInt32 _nValue ) = 0;
+ virtual void endObject() = 0;
+ virtual void start( const sal_uInt32 _nOverallRange ) = 0;
+ virtual void setOverallProgressText( const ::rtl::OUString& _rText ) = 0;
+ virtual void setOverallProgressValue( const sal_uInt32 _nValue ) = 0;
+ };
+
+//........................................................................
+} // namespace dbmm
+//........................................................................
+
+#endif // DBACCESS_MIGRATIONPROGRESS_HXX
diff --git a/dbaccess/source/ext/macromigration/progresscapture.cxx b/dbaccess/source/ext/macromigration/progresscapture.cxx
new file mode 100644
index 000000000000..5cab2fced4b2
--- /dev/null
+++ b/dbaccess/source/ext/macromigration/progresscapture.cxx
@@ -0,0 +1,138 @@
+/*************************************************************************
+ *
+ * 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: progresscapture.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 "progresscapture.hxx"
+#include "migrationprogress.hxx"
+
+/** === begin UNO includes === **/
+/** === end UNO includes === **/
+
+#include <vcl/svapp.hxx>
+#include <vos/mutex.hxx>
+
+//........................................................................
+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;
+ /** === end UNO using === **/
+
+ //====================================================================
+ //= ProgressCapture_Data
+ //====================================================================
+ struct ProgressCapture_Data
+ {
+ ProgressCapture_Data( const ::rtl::OUString& _rObjectName, IMigrationProgress& _rMasterProgress )
+ :sObjectName( _rObjectName )
+ ,rMasterProgress( _rMasterProgress )
+ ,bDisposed( false )
+ {
+ }
+
+ ::rtl::OUString sObjectName;
+ IMigrationProgress& rMasterProgress;
+ bool bDisposed;
+ };
+
+ //====================================================================
+ //= ProgressCapture
+ //====================================================================
+ //--------------------------------------------------------------------
+ ProgressCapture::ProgressCapture( const ::rtl::OUString& _rObjectName, IMigrationProgress& _rMasterProgress )
+ :m_pData( new ProgressCapture_Data( _rObjectName, _rMasterProgress ) )
+ {
+ }
+
+ //--------------------------------------------------------------------
+ ProgressCapture::~ProgressCapture()
+ {
+ }
+
+ //--------------------------------------------------------------------
+ void ProgressCapture::dispose()
+ {
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+ m_pData->bDisposed = true;
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL ProgressCapture::start( const ::rtl::OUString& _rText, ::sal_Int32 _nRange ) throw (RuntimeException)
+ {
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+ if ( !m_pData->bDisposed )
+ m_pData->rMasterProgress.startObject( m_pData->sObjectName, _rText, _nRange );
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL ProgressCapture::end( ) throw (RuntimeException)
+ {
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+ if ( !m_pData->bDisposed )
+ m_pData->rMasterProgress.endObject();
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL ProgressCapture::setText( const ::rtl::OUString& _rText ) throw (RuntimeException)
+ {
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+ if ( !m_pData->bDisposed )
+ m_pData->rMasterProgress.setObjectProgressText( _rText );
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL ProgressCapture::setValue( ::sal_Int32 _nValue ) throw (RuntimeException)
+ {
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+ if ( !m_pData->bDisposed )
+ m_pData->rMasterProgress.setObjectProgressValue( _nValue );
+ }
+
+ //--------------------------------------------------------------------
+ void SAL_CALL ProgressCapture::reset( ) throw (RuntimeException)
+ {
+ OSL_ENSURE( false, "ProgressCapture::reset: not implemented!" );
+ }
+
+//........................................................................
+} // namespace dbmm
+//........................................................................
diff --git a/dbaccess/source/ext/macromigration/progresscapture.hxx b/dbaccess/source/ext/macromigration/progresscapture.hxx
new file mode 100644
index 000000000000..c62d8e75baf0
--- /dev/null
+++ b/dbaccess/source/ext/macromigration/progresscapture.hxx
@@ -0,0 +1,82 @@
+/*************************************************************************
+ *
+ * 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: progresscapture.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_PROGRESSCAPTURE_HXX
+#define DBACCESS_PROGRESSCAPTURE_HXX
+
+/** === begin UNO includes === **/
+#include <com/sun/star/task/XStatusIndicator.hpp>
+/** === end UNO includes === **/
+
+#include <cppuhelper/implbase1.hxx>
+
+#include <memory>
+
+//........................................................................
+namespace dbmm
+{
+//........................................................................
+
+ class IMigrationProgress;
+
+ //====================================================================
+ //= ProgressCapture
+ //====================================================================
+ typedef ::cppu::WeakImplHelper1 < ::com::sun::star::task::XStatusIndicator
+ > ProgressCapture_Base;
+
+ struct ProgressCapture_Data;
+
+ class ProgressCapture : public ProgressCapture_Base
+ {
+ public:
+ ProgressCapture( const ::rtl::OUString& _rObjectName, IMigrationProgress& _rMasterProgress );
+
+ void dispose();
+
+ // XStatusIndicator
+ virtual void SAL_CALL start( const ::rtl::OUString& Text, ::sal_Int32 Range ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL end( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setText( const ::rtl::OUString& Text ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setValue( ::sal_Int32 Value ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL reset( ) throw (::com::sun::star::uno::RuntimeException);
+
+ protected:
+ virtual ~ProgressCapture();
+
+ private:
+ ::std::auto_ptr< ProgressCapture_Data > m_pData;
+ };
+
+//........................................................................
+} // namespace dbmm
+//........................................................................
+
+#endif // DBACCESS_PROGRESSCAPTURE_HXX
diff --git a/dbaccess/source/ext/macromigration/progressmixer.cxx b/dbaccess/source/ext/macromigration/progressmixer.cxx
new file mode 100644
index 000000000000..b738376fb051
--- /dev/null
+++ b/dbaccess/source/ext/macromigration/progressmixer.cxx
@@ -0,0 +1,219 @@
+/*************************************************************************
+* 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
+ {
+#if OSL_DEBUG_LEVEL > 0
+ //----------------------------------------------------------------
+ bool lcl_isRunning( const ProgressMixer_Data& _rData )
+ {
+ return _rData.pCurrentPhase != _rData.aPhases.end();
+ }
+#endif
+ //----------------------------------------------------------------
+ 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 000000000000..291fdc331661
--- /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/ext/macromigration/rangeprogressbar.hxx b/dbaccess/source/ext/macromigration/rangeprogressbar.hxx
new file mode 100644
index 000000000000..509ed7de0483
--- /dev/null
+++ b/dbaccess/source/ext/macromigration/rangeprogressbar.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: rangeprogressbar.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_RANGEPROGRESSBAR_HXX
+#define DBACCESS_RANGEPROGRESSBAR_HXX
+
+/** === begin UNO includes === **/
+/** === end UNO includes === **/
+
+#include <svtools/prgsbar.hxx>
+
+//........................................................................
+namespace dbmm
+{
+//........................................................................
+
+ //====================================================================
+ //= RangeProgressBar
+ //====================================================================
+ /** a slight extension of the usual progress bar, which is able to remember a range
+ */
+ class RangeProgressBar : public ProgressBar
+ {
+ public:
+ RangeProgressBar( Window* _pParent, WinBits nWinBits = WB_STDPROGRESSBAR )
+ :ProgressBar( _pParent, nWinBits )
+ {
+ }
+
+ RangeProgressBar( Window* _pParent, const ResId& rResId )
+ :ProgressBar( _pParent, rResId )
+ {
+ }
+
+ inline void SetRange( sal_uInt32 _nRange );
+ inline sal_uInt32 GetRange() const;
+
+ inline void SetValue( sal_uInt32 _nValue );
+ inline sal_uInt32 GetValue() const;
+
+ private:
+ sal_uInt32 m_nRange;
+
+ private:
+ using ProgressBar::SetValue;
+ using ProgressBar::GetValue;
+ };
+
+ //--------------------------------------------------------------------
+ inline void RangeProgressBar::SetRange( sal_uInt32 _nRange )
+ {
+ m_nRange = _nRange;
+ if ( !m_nRange )
+ m_nRange = 100;
+ }
+
+ //--------------------------------------------------------------------
+ inline sal_uInt32 RangeProgressBar::GetRange() const
+ {
+ return m_nRange;
+ }
+
+ //--------------------------------------------------------------------
+ inline void RangeProgressBar::SetValue( sal_uInt32 _nValue )
+ {
+ ProgressBar::SetValue( (USHORT)( 100.0 * _nValue / m_nRange ) );
+ }
+
+ //--------------------------------------------------------------------
+ inline sal_uInt32 RangeProgressBar::GetValue() const
+ {
+ return (sal_uInt32)( ProgressBar::GetValue() / 100.0 * m_nRange );
+ }
+
+
+//........................................................................
+} // namespace dbmm
+//........................................................................
+
+#endif // DBACCESS_RANGEPROGRESSBAR_HXX