diff options
Diffstat (limited to 'dbaccess/source/ext/macromigration')
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 |