summaryrefslogtreecommitdiff
path: root/desktop/source/deployment
diff options
context:
space:
mode:
Diffstat (limited to 'desktop/source/deployment')
-rw-r--r--desktop/source/deployment/deployment.map8
-rw-r--r--desktop/source/deployment/dp_log.cxx214
-rw-r--r--desktop/source/deployment/dp_persmap.cxx269
-rw-r--r--desktop/source/deployment/dp_services.cxx140
-rw-r--r--desktop/source/deployment/dp_xml.cxx262
-rw-r--r--desktop/source/deployment/gui/descedit.cxx103
-rw-r--r--desktop/source/deployment/gui/descedit.hxx60
-rw-r--r--desktop/source/deployment/gui/dp_gui.h105
-rw-r--r--desktop/source/deployment/gui/dp_gui.hrc177
-rw-r--r--desktop/source/deployment/gui/dp_gui_autoscrolledit.cxx77
-rw-r--r--desktop/source/deployment/gui/dp_gui_autoscrolledit.hxx54
-rw-r--r--desktop/source/deployment/gui/dp_gui_backend.src134
-rw-r--r--desktop/source/deployment/gui/dp_gui_dependencydialog.cxx89
-rw-r--r--desktop/source/deployment/gui/dp_gui_dependencydialog.hxx71
-rw-r--r--desktop/source/deployment/gui/dp_gui_dependencydialog.src73
-rw-r--r--desktop/source/deployment/gui/dp_gui_dialog.src346
-rw-r--r--desktop/source/deployment/gui/dp_gui_dialog2.cxx1789
-rw-r--r--desktop/source/deployment/gui/dp_gui_dialog2.hxx277
-rw-r--r--desktop/source/deployment/gui/dp_gui_dialog2.src246
-rw-r--r--desktop/source/deployment/gui/dp_gui_extensioncmdqueue.cxx1188
-rw-r--r--desktop/source/deployment/gui/dp_gui_extensioncmdqueue.hxx122
-rw-r--r--desktop/source/deployment/gui/dp_gui_extlistbox.cxx1175
-rw-r--r--desktop/source/deployment/gui/dp_gui_extlistbox.hxx271
-rw-r--r--desktop/source/deployment/gui/dp_gui_service.cxx369
-rw-r--r--desktop/source/deployment/gui/dp_gui_shared.hxx65
-rw-r--r--desktop/source/deployment/gui/dp_gui_system.cxx62
-rw-r--r--desktop/source/deployment/gui/dp_gui_system.hxx40
-rw-r--r--desktop/source/deployment/gui/dp_gui_theextmgr.cxx538
-rw-r--r--desktop/source/deployment/gui/dp_gui_theextmgr.hxx143
-rw-r--r--desktop/source/deployment/gui/dp_gui_thread.cxx85
-rw-r--r--desktop/source/deployment/gui/dp_gui_thread.hxx87
-rw-r--r--desktop/source/deployment/gui/dp_gui_updatability.cxx280
-rw-r--r--desktop/source/deployment/gui/dp_gui_updatability.hxx104
-rw-r--r--desktop/source/deployment/gui/dp_gui_updatedata.hxx79
-rw-r--r--desktop/source/deployment/gui/dp_gui_updatedialog.cxx1274
-rw-r--r--desktop/source/deployment/gui/dp_gui_updatedialog.hxx226
-rw-r--r--desktop/source/deployment/gui/dp_gui_updatedialog.src277
-rw-r--r--desktop/source/deployment/gui/dp_gui_updateinstalldialog.cxx731
-rw-r--r--desktop/source/deployment/gui/dp_gui_updateinstalldialog.hxx141
-rw-r--r--desktop/source/deployment/gui/dp_gui_updateinstalldialog.src206
-rw-r--r--desktop/source/deployment/gui/dp_gui_versionboxes.src79
-rw-r--r--desktop/source/deployment/gui/license_dialog.cxx328
-rw-r--r--desktop/source/deployment/gui/license_dialog.hxx73
-rw-r--r--desktop/source/deployment/gui/makefile.mk113
-rw-r--r--desktop/source/deployment/inc/db.hxx176
-rw-r--r--desktop/source/deployment/inc/dp_dependencies.hxx99
-rw-r--r--desktop/source/deployment/inc/dp_descriptioninfoset.hxx281
-rw-r--r--desktop/source/deployment/inc/dp_identifier.hxx95
-rw-r--r--desktop/source/deployment/inc/dp_interact.h153
-rw-r--r--desktop/source/deployment/inc/dp_misc.h159
-rw-r--r--desktop/source/deployment/inc/dp_misc.mk46
-rw-r--r--desktop/source/deployment/inc/dp_misc_api.hxx43
-rw-r--r--desktop/source/deployment/inc/dp_persmap.h70
-rw-r--r--desktop/source/deployment/inc/dp_platform.hxx60
-rw-r--r--desktop/source/deployment/inc/dp_resource.h70
-rw-r--r--desktop/source/deployment/inc/dp_ucb.h87
-rw-r--r--desktop/source/deployment/inc/dp_version.hxx58
-rw-r--r--desktop/source/deployment/inc/dp_xml.h164
-rw-r--r--desktop/source/deployment/makefile.mk116
-rw-r--r--desktop/source/deployment/manager/dp_activepackages.cxx187
-rw-r--r--desktop/source/deployment/manager/dp_activepackages.hxx83
-rw-r--r--desktop/source/deployment/manager/dp_informationprovider.cxx507
-rw-r--r--desktop/source/deployment/manager/dp_manager.cxx1283
-rw-r--r--desktop/source/deployment/manager/dp_manager.h270
-rw-r--r--desktop/source/deployment/manager/dp_manager.hrc42
-rw-r--r--desktop/source/deployment/manager/dp_manager.src58
-rw-r--r--desktop/source/deployment/manager/dp_managerfac.cxx199
-rw-r--r--desktop/source/deployment/manager/makefile.mk56
-rw-r--r--desktop/source/deployment/migration/dp_migration.cxx254
-rw-r--r--desktop/source/deployment/migration/makefile.mk45
-rw-r--r--desktop/source/deployment/misc/db.cxx275
-rw-r--r--desktop/source/deployment/misc/dp_dependencies.cxx181
-rw-r--r--desktop/source/deployment/misc/dp_descriptioninfoset.cxx581
-rw-r--r--desktop/source/deployment/misc/dp_identifier.cxx76
-rw-r--r--desktop/source/deployment/misc/dp_interact.cxx188
-rw-r--r--desktop/source/deployment/misc/dp_misc.cxx473
-rw-r--r--desktop/source/deployment/misc/dp_misc.hrc36
-rw-r--r--desktop/source/deployment/misc/dp_misc.src40
-rw-r--r--desktop/source/deployment/misc/dp_platform.cxx221
-rw-r--r--desktop/source/deployment/misc/dp_resource.cxx236
-rw-r--r--desktop/source/deployment/misc/dp_ucb.cxx282
-rw-r--r--desktop/source/deployment/misc/dp_version.cxx83
-rw-r--r--desktop/source/deployment/misc/makefile.mk97
-rw-r--r--desktop/source/deployment/registry/component/dp_component.cxx1389
-rw-r--r--desktop/source/deployment/registry/component/dp_component.hrc42
-rw-r--r--desktop/source/deployment/registry/component/dp_component.src57
-rw-r--r--desktop/source/deployment/registry/component/makefile.mk51
-rw-r--r--desktop/source/deployment/registry/configuration/dp_configuration.cxx648
-rw-r--r--desktop/source/deployment/registry/configuration/dp_configuration.hrc39
-rw-r--r--desktop/source/deployment/registry/configuration/dp_configuration.src42
-rw-r--r--desktop/source/deployment/registry/configuration/makefile.mk55
-rw-r--r--desktop/source/deployment/registry/dp_backend.cxx594
-rw-r--r--desktop/source/deployment/registry/dp_registry.cxx531
-rw-r--r--desktop/source/deployment/registry/dp_registry.src62
-rw-r--r--desktop/source/deployment/registry/executable/dp_executable.cxx292
-rw-r--r--desktop/source/deployment/registry/executable/makefile.mk47
-rw-r--r--desktop/source/deployment/registry/help/dp_help.cxx592
-rw-r--r--desktop/source/deployment/registry/help/dp_help.hrc42
-rw-r--r--desktop/source/deployment/registry/help/dp_help.src47
-rw-r--r--desktop/source/deployment/registry/help/makefile.mk55
-rw-r--r--desktop/source/deployment/registry/inc/dp_backend.h319
-rw-r--r--desktop/source/deployment/registry/inc/dp_registry.hrc43
-rw-r--r--desktop/source/deployment/registry/makefile.mk52
-rw-r--r--desktop/source/deployment/registry/package/dp_description.cxx208
-rw-r--r--desktop/source/deployment/registry/package/dp_description.hxx128
-rw-r--r--desktop/source/deployment/registry/package/dp_package.cxx1547
-rw-r--r--desktop/source/deployment/registry/package/dp_package.hrc38
-rw-r--r--desktop/source/deployment/registry/package/dp_package.src37
-rw-r--r--desktop/source/deployment/registry/package/makefile.mk52
-rw-r--r--desktop/source/deployment/registry/script/dp_lib_container.cxx76
-rw-r--r--desktop/source/deployment/registry/script/dp_lib_container.h60
-rw-r--r--desktop/source/deployment/registry/script/dp_script.cxx476
-rw-r--r--desktop/source/deployment/registry/script/dp_script.hrc42
-rw-r--r--desktop/source/deployment/registry/script/dp_script.src52
-rw-r--r--desktop/source/deployment/registry/script/makefile.mk52
-rw-r--r--desktop/source/deployment/registry/sfwk/dp_parceldesc.cxx133
-rw-r--r--desktop/source/deployment/registry/sfwk/dp_parceldesc.hxx92
-rw-r--r--desktop/source/deployment/registry/sfwk/dp_sfwk.cxx401
-rw-r--r--desktop/source/deployment/registry/sfwk/dp_sfwk.hrc38
-rw-r--r--desktop/source/deployment/registry/sfwk/dp_sfwk.src38
-rw-r--r--desktop/source/deployment/registry/sfwk/makefile.mk52
-rw-r--r--desktop/source/deployment/target.pmk40
-rw-r--r--desktop/source/deployment/unopkg/makefile.mk52
-rw-r--r--desktop/source/deployment/unopkg/unopkg.src92
124 files changed, 28685 insertions, 0 deletions
diff --git a/desktop/source/deployment/deployment.map b/desktop/source/deployment/deployment.map
new file mode 100644
index 000000000000..563b3d86a5d0
--- /dev/null
+++ b/desktop/source/deployment/deployment.map
@@ -0,0 +1,8 @@
+UDK_3_1_0 {
+ global:
+ component_getImplementationEnvironment;
+ component_writeInfo;
+ component_getFactory;
+ local:
+ *;
+};
diff --git a/desktop/source/deployment/dp_log.cxx b/desktop/source/deployment/dp_log.cxx
new file mode 100644
index 000000000000..d83ee8602204
--- /dev/null
+++ b/desktop/source/deployment/dp_log.cxx
@@ -0,0 +1,214 @@
+/*************************************************************************
+ *
+ * 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: dp_log.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_desktop.hxx"
+
+#include "dp_misc.h"
+#include "rtl/strbuf.hxx"
+#include "osl/time.h"
+#include "osl/thread.h"
+#include "cppuhelper/compbase1.hxx"
+#include "comphelper/anytostring.hxx"
+#include "comphelper/servicedecl.hxx"
+#include "comphelper/unwrapargs.hxx"
+#include "com/sun/star/deployment/DeploymentException.hpp"
+#include "com/sun/star/ucb/XProgressHandler.hpp"
+#include "com/sun/star/ucb/XSimpleFileAccess.hpp"
+#include "com/sun/star/io/XSeekable.hpp"
+#include <stdio.h>
+
+
+using namespace ::rtl;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+
+namespace dp_log {
+
+typedef ::cppu::WeakComponentImplHelper1<ucb::XProgressHandler> t_log_helper;
+
+//==============================================================================
+class ProgressLogImpl : public ::dp_misc::MutexHolder, public t_log_helper
+{
+ Reference<io::XOutputStream> m_xLogFile;
+ sal_Int32 m_log_level;
+ void log_write( OString const & text );
+
+protected:
+ virtual void SAL_CALL disposing();
+ virtual ~ProgressLogImpl();
+
+public:
+ ProgressLogImpl( Sequence<Any> const & args,
+ Reference<XComponentContext> const & xContext );
+
+ // XProgressHandler
+ virtual void SAL_CALL push( Any const & Status ) throw (RuntimeException);
+ virtual void SAL_CALL update( Any const & Status ) throw (RuntimeException);
+ virtual void SAL_CALL pop() throw (RuntimeException);
+};
+
+//______________________________________________________________________________
+ProgressLogImpl::~ProgressLogImpl()
+{
+}
+
+//______________________________________________________________________________
+void ProgressLogImpl::disposing()
+{
+ try {
+ if (m_xLogFile.is()) {
+ m_xLogFile->closeOutput();
+ m_xLogFile.clear();
+ }
+ }
+ catch (Exception & exc) {
+ (void) exc;
+ OSL_ENSURE( 0, OUStringToOString(
+ exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
+ }
+}
+
+//______________________________________________________________________________
+ProgressLogImpl::ProgressLogImpl(
+ Sequence<Any> const & args,
+ Reference<XComponentContext> const & xContext )
+ : t_log_helper( getMutex() ),
+ m_log_level( 0 )
+{
+ OUString log_file;
+ boost::optional< Reference<task::XInteractionHandler> > interactionHandler;
+ comphelper::unwrapArgs( args, log_file, interactionHandler );
+
+ Reference<ucb::XSimpleFileAccess> xSimpleFileAccess(
+ xContext->getServiceManager()->createInstanceWithContext(
+ OUSTR("com.sun.star.ucb.SimpleFileAccess"),
+ xContext ), UNO_QUERY_THROW );
+ // optional ia handler:
+ if (interactionHandler)
+ xSimpleFileAccess->setInteractionHandler( *interactionHandler );
+
+ m_xLogFile.set(
+ xSimpleFileAccess->openFileWrite( log_file ), UNO_QUERY_THROW );
+ Reference<io::XSeekable> xSeekable( m_xLogFile, UNO_QUERY_THROW );
+ xSeekable->seek( xSeekable->getLength() );
+
+ // write log stamp
+ OStringBuffer buf;
+ buf.append(
+ RTL_CONSTASCII_STRINGPARAM("###### Progress log entry ") );
+ TimeValue m_start_time, tLocal;
+ oslDateTime date_time;
+ if (osl_getSystemTime( &m_start_time ) &&
+ osl_getLocalTimeFromSystemTime( &m_start_time, &tLocal ) &&
+ osl_getDateTimeFromTimeValue( &tLocal, &date_time ))
+ {
+ char ar[ 128 ];
+ snprintf(
+ ar, sizeof (ar),
+ "%04d-%02d-%02d %02d:%02d:%02d ",
+ date_time.Year, date_time.Month, date_time.Day,
+ date_time.Hours, date_time.Minutes, date_time.Seconds );
+ buf.append( ar );
+ }
+ buf.append( RTL_CONSTASCII_STRINGPARAM("######\n") );
+ log_write( buf.makeStringAndClear() );
+}
+
+//______________________________________________________________________________
+void ProgressLogImpl::log_write( OString const & text )
+{
+ try {
+ if (m_xLogFile.is()) {
+ m_xLogFile->writeBytes(
+ Sequence< sal_Int8 >(
+ reinterpret_cast< sal_Int8 const * >(text.getStr()),
+ text.getLength() ) );
+ }
+ }
+ catch (io::IOException & exc) {
+ (void) exc;
+ OSL_ENSURE( 0, OUStringToOString(
+ exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
+ }
+}
+
+// XProgressHandler
+//______________________________________________________________________________
+void ProgressLogImpl::push( Any const & Status )
+ throw (RuntimeException)
+{
+ update( Status );
+ OSL_ASSERT( m_log_level >= 0 );
+ ++m_log_level;
+}
+
+//______________________________________________________________________________
+void ProgressLogImpl::update( Any const & Status )
+ throw (RuntimeException)
+{
+ if (! Status.hasValue())
+ return;
+
+ OUStringBuffer buf;
+ OSL_ASSERT( m_log_level >= 0 );
+ for ( sal_Int32 n = 0; n < m_log_level; ++n )
+ buf.append( static_cast<sal_Unicode>(' ') );
+
+ OUString msg;
+ if (Status >>= msg) {
+ buf.append( msg );
+ }
+ else {
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("ERROR: ") );
+ buf.append( ::comphelper::anyToString(Status) );
+ }
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\n") );
+ log_write( OUStringToOString(
+ buf.makeStringAndClear(), osl_getThreadTextEncoding() ) );
+}
+
+//______________________________________________________________________________
+void ProgressLogImpl::pop() throw (RuntimeException)
+{
+ OSL_ASSERT( m_log_level > 0 );
+ --m_log_level;
+}
+
+namespace sdecl = comphelper::service_decl;
+sdecl::class_<ProgressLogImpl, sdecl::with_args<true> > servicePLI;
+extern sdecl::ServiceDecl const serviceDecl(
+ servicePLI,
+ // a private one:
+ "com.sun.star.comp.deployment.ProgressLog",
+ "com.sun.star.comp.deployment.ProgressLog" );
+
+} // namespace dp_log
+
diff --git a/desktop/source/deployment/dp_persmap.cxx b/desktop/source/deployment/dp_persmap.cxx
new file mode 100644
index 000000000000..39ea6f016dbf
--- /dev/null
+++ b/desktop/source/deployment/dp_persmap.cxx
@@ -0,0 +1,269 @@
+/*************************************************************************
+ *
+ * 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: dp_persmap.cxx,v $
+ * $Revision: 1.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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "dp_misc.h"
+#include "dp_ucb.h"
+#include "dp_persmap.h"
+#include "rtl/strbuf.hxx"
+#include "rtl/ustrbuf.hxx"
+#include "osl/file.hxx"
+#include "osl/thread.h"
+
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::rtl;
+using ::osl::File;
+
+namespace dp_misc
+{
+
+//______________________________________________________________________________
+void PersistentMap::throw_rtexc( int err, char const * pmsg ) const
+{
+ OUStringBuffer buf;
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[") );
+ buf.append( m_sysPath );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] Berkeley Db error (") );
+ buf.append( static_cast<sal_Int32>(err) );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("): ") );
+ if (pmsg == 0)
+ pmsg = DbEnv::strerror(err);
+ const OString msg(pmsg);
+ buf.append( OUString( msg.getStr(), msg.getLength(),
+ osl_getThreadTextEncoding() ) );
+ const OUString msg_(buf.makeStringAndClear());
+ OSL_ENSURE( 0, rtl::OUStringToOString(
+ msg_, RTL_TEXTENCODING_UTF8 ).getStr() );
+ throw RuntimeException( msg_, Reference<XInterface>() );
+}
+
+//______________________________________________________________________________
+PersistentMap::~PersistentMap()
+{
+ try {
+ m_db.close(0);
+ }
+ catch (DbException & exc) {
+ (void) exc; // avoid warnings
+ OSL_ENSURE( 0, DbEnv::strerror( exc.get_errno() ) );
+ }
+}
+
+//______________________________________________________________________________
+void PersistentMap::flush() const
+{
+ try {
+ int err = m_db.sync(0);
+ if (err != 0)
+ throw_rtexc(err);
+ }
+ catch (DbException & exc) {
+ throw_rtexc( exc.get_errno(), exc.what() );
+ }
+}
+
+//______________________________________________________________________________
+PersistentMap::PersistentMap( OUString const & url_, bool readOnly )
+ : m_db( 0, 0 )
+{
+ try {
+ OUString url( expandUnoRcUrl(url_) );
+ if ( File::getSystemPathFromFileURL( url, m_sysPath ) != File::E_None )
+ {
+ OSL_ASSERT( false );
+ }
+ OString cstr_sysPath(
+ OUStringToOString( m_sysPath, osl_getThreadTextEncoding() ) );
+ char const * pcstr_sysPath = cstr_sysPath.getStr();
+
+ u_int32_t flags = DB_CREATE;
+ if (readOnly) {
+ flags = DB_RDONLY;
+ if (! create_ucb_content(
+ 0, url,
+ Reference<com::sun::star::ucb::XCommandEnvironment>(),
+ false /* no throw */ )) {
+ // ignore non-existent file in read-only mode: simulate empty db
+ pcstr_sysPath = 0;
+ flags = DB_CREATE;
+ }
+ }
+
+ int err = m_db.open(
+ // xxx todo: DB_THREAD, DB_DBT_MALLOC currently not used
+ 0, pcstr_sysPath, 0, DB_HASH, flags/* | DB_THREAD*/, 0664 /* fs mode */ );
+ if (err != 0)
+ throw_rtexc(err);
+ }
+ catch (DbException & exc) {
+ throw_rtexc( exc.get_errno(), exc.what() );
+ }
+}
+
+//______________________________________________________________________________
+PersistentMap::PersistentMap()
+ : m_db( 0, 0 )
+{
+ try {
+ // xxx todo: DB_THREAD, DB_DBT_MALLOC currently not used
+ int err = m_db.open( 0, 0, 0, DB_HASH, DB_CREATE/* | DB_THREAD*/, 0 );
+ if (err != 0)
+ throw_rtexc(err);
+ }
+ catch (DbException & exc) {
+ throw_rtexc( exc.get_errno(), exc.what() );
+ }
+}
+
+//______________________________________________________________________________
+bool PersistentMap::has( OString const & key ) const
+{
+ return get( 0, key );
+}
+
+//______________________________________________________________________________
+bool PersistentMap::get( OString * value, OString const & key ) const
+{
+ try {
+ Dbt dbKey( const_cast< sal_Char * >(key.getStr()), key.getLength() );
+ Dbt dbData;
+ int err = m_db.get( 0, &dbKey, &dbData, 0 );
+ if (err == DB_NOTFOUND)
+ return false;
+ if (err == 0) {
+ if (value != 0) {
+ *value = OString(
+ static_cast< sal_Char const * >(dbData.get_data()),
+ dbData.get_size() );
+ }
+ return true;
+ }
+ throw_rtexc(err);
+ }
+ catch (DbException & exc) {
+ throw_rtexc( exc.get_errno(), exc.what() );
+ }
+ return false; // avoiding warning
+}
+
+//______________________________________________________________________________
+void PersistentMap::put( OString const & key, OString const & value )
+{
+ try {
+ Dbt dbKey( const_cast< sal_Char * >(key.getStr()), key.getLength() );
+ Dbt dbData( const_cast< sal_Char * >(
+ value.getStr()), value.getLength() );
+ int err = m_db.put( 0, &dbKey, &dbData, 0 );
+ if (err == 0) {
+#if OSL_DEBUG_LEVEL > 0
+ OString v;
+ OSL_ASSERT( get( &v, key ) );
+ OSL_ASSERT( v.equals( value ) );
+#endif
+ err = m_db.sync(0);
+ }
+ if (err != 0)
+ throw_rtexc(err);
+ }
+ catch (DbException & exc) {
+ throw_rtexc( exc.get_errno(), exc.what() );
+ }
+}
+
+//______________________________________________________________________________
+bool PersistentMap::erase( OString const & key, bool flush_immediately )
+{
+ try {
+ Dbt dbKey( const_cast< sal_Char * >(key.getStr()), key.getLength() );
+ int err = m_db.del( &dbKey, 0 );
+ if (err == 0) {
+ if (flush_immediately) {
+ err = m_db.sync(0);
+ if (err != 0)
+ throw_rtexc(err);
+ }
+ return true;
+ }
+ if (err == DB_NOTFOUND)
+ return false;
+ throw_rtexc(err);
+ }
+ catch (DbException & exc) {
+ throw_rtexc( exc.get_errno(), exc.what() );
+ }
+ return false; // avoiding warning
+}
+
+//______________________________________________________________________________
+t_string2string_map PersistentMap::getEntries() const
+{
+ try {
+ Dbc * pcurs = 0;
+ int err = m_db.cursor( 0, &pcurs, 0 );
+ if (err != 0)
+ throw_rtexc(err);
+
+ t_string2string_map ret;
+ for (;;) {
+ Dbt dbKey, dbData;
+ err = pcurs->get( &dbKey, &dbData, DB_NEXT );
+ if (err == DB_NOTFOUND)
+ break;
+ if (err != 0)
+ throw_rtexc(err);
+
+ ::std::pair<t_string2string_map::iterator, bool > insertion(
+ ret.insert( t_string2string_map::value_type(
+ t_string2string_map::value_type(
+ OString( static_cast< sal_Char const * >(
+ dbKey.get_data()),
+ dbKey.get_size() ),
+ OString( static_cast< sal_Char const * >(
+ dbData.get_data()),
+ dbData.get_size() ) ) ) ) );
+ OSL_ASSERT( insertion.second );
+ }
+ err = pcurs->close();
+ if (err != 0)
+ throw_rtexc(err);
+ return ret;
+ }
+ catch (DbException & exc) {
+ throw_rtexc( exc.get_errno(), exc.what() );
+ }
+ return t_string2string_map(); // avoiding warning
+}
+
+}
+
diff --git a/desktop/source/deployment/dp_services.cxx b/desktop/source/deployment/dp_services.cxx
new file mode 100644
index 000000000000..c98522a168df
--- /dev/null
+++ b/desktop/source/deployment/dp_services.cxx
@@ -0,0 +1,140 @@
+/*************************************************************************
+ *
+ * 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: dp_services.cxx,v $
+ * $Revision: 1.6 $
+ *
+ * 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_desktop.hxx"
+
+#define COMPHELPER_SERVICEDECL_COMPONENT_HELPER_MAX_ARGS 11
+#include "comphelper/servicedecl.hxx"
+
+using namespace com::sun::star;
+namespace sdecl = comphelper::service_decl;
+
+namespace dp_registry {
+namespace backend {
+
+namespace configuration {
+extern sdecl::ServiceDecl const serviceDecl;
+}
+
+namespace component {
+extern sdecl::ServiceDecl const serviceDecl;
+}
+
+namespace script {
+extern sdecl::ServiceDecl const serviceDecl;
+}
+
+namespace sfwk {
+extern sdecl::ServiceDecl const serviceDecl;
+}
+
+namespace help {
+extern sdecl::ServiceDecl const serviceDecl;
+}
+
+namespace executable {
+extern sdecl::ServiceDecl const serviceDecl;
+}
+
+} // namespace backend
+} // namespace dp_registry
+
+namespace dp_manager {
+namespace factory {
+extern sdecl::ServiceDecl const serviceDecl;
+bool singleton_entries( uno::Reference<registry::XRegistryKey> const& );
+}
+}
+
+namespace dp_log {
+extern sdecl::ServiceDecl const serviceDecl;
+}
+
+namespace dp_migration {
+extern sdecl::ServiceDecl const serviceDecl;
+}
+
+namespace dp_info {
+extern sdecl::ServiceDecl const serviceDecl;
+bool singleton_entries( uno::Reference<registry::XRegistryKey> const& );
+}
+
+extern "C" {
+
+struct uno_Environment;
+
+void SAL_CALL component_getImplementationEnvironment(
+ const sal_Char ** ppEnvTypeName, uno_Environment ** )
+{
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
+
+sal_Bool SAL_CALL component_writeInfo(
+ lang::XMultiServiceFactory * pServiceManager,
+ registry::XRegistryKey * pRegistryKey )
+{
+ return component_writeInfoHelper(
+ pServiceManager, pRegistryKey,
+ dp_registry::backend::configuration::serviceDecl,
+ dp_registry::backend::component::serviceDecl,
+ dp_registry::backend::help::serviceDecl,
+ dp_registry::backend::script::serviceDecl,
+ dp_registry::backend::sfwk::serviceDecl,
+ dp_registry::backend::executable::serviceDecl,
+ dp_manager::factory::serviceDecl,
+ dp_log::serviceDecl,
+ dp_migration::serviceDecl,
+ dp_info::serviceDecl ) &&
+ dp_manager::factory::singleton_entries( pRegistryKey ) &&
+ dp_info::singleton_entries( pRegistryKey );
+}
+
+void * SAL_CALL component_getFactory(
+ sal_Char const * pImplName,
+ lang::XMultiServiceFactory * pServiceManager,
+ registry::XRegistryKey * pRegistryKey )
+{
+ return component_getFactoryHelper(
+ pImplName, pServiceManager, pRegistryKey,
+ dp_registry::backend::configuration::serviceDecl,
+ dp_registry::backend::component::serviceDecl,
+ dp_registry::backend::help::serviceDecl,
+ dp_registry::backend::script::serviceDecl,
+ dp_registry::backend::sfwk::serviceDecl,
+ dp_registry::backend::executable::serviceDecl,
+ dp_manager::factory::serviceDecl,
+ dp_log::serviceDecl,
+ dp_migration::serviceDecl,
+ dp_info::serviceDecl );
+}
+
+} // extern "C"
+
diff --git a/desktop/source/deployment/dp_xml.cxx b/desktop/source/deployment/dp_xml.cxx
new file mode 100644
index 000000000000..8ed30ccc9066
--- /dev/null
+++ b/desktop/source/deployment/dp_xml.cxx
@@ -0,0 +1,262 @@
+/*************************************************************************
+ *
+ * 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: dp_xml.cxx,v $
+ * $Revision: 1.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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "dp_misc.h"
+#include "dp_xml.h"
+#include "rtl/ustrbuf.hxx"
+#include "ucbhelper/content.hxx"
+#include "com/sun/star/xml/sax/XParser.hpp"
+
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using ::rtl::OUString;
+
+namespace dp_misc
+{
+
+//==============================================================================
+void xml_parse(
+ Reference<xml::sax::XDocumentHandler> const & xDocHandler,
+ ::ucbhelper::Content & ucb_content,
+ Reference<XComponentContext> const & xContext )
+{
+ // raise sax parser:
+ Reference<xml::sax::XParser> xParser(
+ xContext->getServiceManager()->createInstanceWithContext(
+ OUSTR("com.sun.star.xml.sax.Parser"), xContext ), UNO_QUERY_THROW );
+
+ // error handler, entity resolver omitted
+ xParser->setDocumentHandler( xDocHandler );
+ xml::sax::InputSource source;
+ source.aInputStream = ucb_content.openStream();
+ source.sSystemId = ucb_content.getURL();
+ xParser->parseStream( source );
+}
+
+//==============================================================================
+void xml_parse(
+ Reference<xml::input::XRoot> const & xRoot,
+ ::ucbhelper::Content & ucb_content,
+ Reference<XComponentContext> const & xContext )
+{
+ const Any arg(xRoot);
+ const Reference<xml::sax::XDocumentHandler> xDocHandler(
+ xContext->getServiceManager()->createInstanceWithArgumentsAndContext(
+ OUSTR("com.sun.star.xml.input.SaxDocumentHandler"),
+ Sequence<Any>( &arg, 1 ), xContext ), UNO_QUERY_THROW );
+ xml_parse( xDocHandler, ucb_content, xContext );
+}
+
+//##############################################################################
+
+//______________________________________________________________________________
+XmlRootElement::XmlRootElement(
+ OUString const & uri, OUString const & localname )
+ : m_uri( uri )
+{
+ m_localname = localname;
+}
+
+//______________________________________________________________________________
+XmlRootElement::~XmlRootElement()
+{
+}
+
+// XRoot
+//______________________________________________________________________________
+void XmlRootElement::startDocument(
+ Reference<xml::input::XNamespaceMapping> const & xMapping )
+ throw (xml::sax::SAXException, RuntimeException)
+{
+ m_xNamespaceMapping = xMapping;
+
+ try {
+ m_uid = m_xNamespaceMapping->getUidByUri( m_uri );
+ }
+ catch (container::NoSuchElementException & exc) {
+ throw xml::sax::SAXException(
+ exc.Message, static_cast<OWeakObject *>(this), Any(exc) );
+ }
+}
+
+//______________________________________________________________________________
+void XmlRootElement::endDocument()
+ throw (xml::sax::SAXException, RuntimeException)
+{
+}
+
+//______________________________________________________________________________
+void XmlRootElement::processingInstruction(
+ OUString const &, OUString const & )
+ throw (xml::sax::SAXException, RuntimeException)
+{
+}
+
+//______________________________________________________________________________
+void XmlRootElement::setDocumentLocator(
+ Reference<xml::sax::XLocator> const & )
+ throw (xml::sax::SAXException, RuntimeException)
+{
+}
+
+//______________________________________________________________________________
+Reference<xml::input::XElement> XmlRootElement::startRootElement(
+ sal_Int32 uid, OUString const & localname,
+ Reference<xml::input::XAttributes> const & xAttributes )
+ throw (xml::sax::SAXException, RuntimeException)
+{
+ check_xmlns( uid );
+ if (! localname.equals( m_localname )) {
+ throw xml::sax::SAXException(
+ OUSTR("unexpected root element ") + localname,
+ static_cast<OWeakObject *>(this), Any() );
+ }
+ m_xAttributes = xAttributes;
+
+ return this;
+}
+
+//##############################################################################
+
+//______________________________________________________________________________
+XmlElement::~XmlElement()
+{
+}
+
+//______________________________________________________________________________
+void XmlElement::check_xmlns( sal_Int32 uid ) const
+ throw (xml::sax::SAXException)
+{
+ if (uid != m_uid)
+ {
+ ::rtl::OUStringBuffer buf;
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM("illegal xml namespace uri=\"") );
+ try {
+ buf.append( m_xNamespaceMapping->getUriByUid( uid ) );
+ }
+ catch (container::NoSuchElementException & exc) {
+ throw xml::sax::SAXException(
+ exc.Message, static_cast<OWeakObject *>(
+ const_cast<XmlElement *>(this) ), Any(exc) );
+ }
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\"!") );
+ throw xml::sax::SAXException(
+ buf.makeStringAndClear(),
+ static_cast<OWeakObject *>( const_cast<XmlElement *>(this) ),
+ Any() );
+ }
+}
+
+// XElement
+//______________________________________________________________________________
+Reference<xml::input::XElement> XmlElement::getParent()
+ throw (RuntimeException)
+{
+ return m_xParent;
+}
+
+//______________________________________________________________________________
+OUString XmlElement::getLocalName()
+ throw (RuntimeException)
+{
+ return m_localname;
+}
+
+//______________________________________________________________________________
+sal_Int32 XmlElement::getUid()
+ throw (RuntimeException)
+{
+ return m_uid;
+}
+
+//______________________________________________________________________________
+Reference<xml::input::XAttributes> XmlElement::getAttributes()
+ throw (RuntimeException)
+{
+ return m_xAttributes;
+}
+
+//______________________________________________________________________________
+void XmlElement::ignorableWhitespace(
+ OUString const & )
+ throw (xml::sax::SAXException, RuntimeException)
+{
+}
+
+//______________________________________________________________________________
+void XmlElement::characters( OUString const & chars )
+ throw (xml::sax::SAXException, RuntimeException)
+{
+ m_characters += chars;
+}
+
+//______________________________________________________________________________
+void XmlElement::processingInstruction(
+ OUString const &, OUString const & )
+ throw (xml::sax::SAXException, RuntimeException)
+{
+}
+
+//______________________________________________________________________________
+void XmlElement::endElement()
+ throw (xml::sax::SAXException, RuntimeException)
+{
+ m_got_endElement = true;
+}
+
+//______________________________________________________________________________
+Reference<xml::input::XElement> XmlElement::startChildElement(
+ sal_Int32 uid, OUString const & localName,
+ Reference<xml::input::XAttributes> const & )
+ throw (xml::sax::SAXException, RuntimeException)
+{
+ ::rtl::OUStringBuffer buf;
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("unexpected element "
+ "{ tag=\"") );
+ buf.append( localName );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\", uri=\"") );
+ try {
+ buf.append( m_xNamespaceMapping->getUriByUid( uid ) );
+ }
+ catch (container::NoSuchElementException & exc) {
+ throw xml::sax::SAXException(
+ exc.Message, static_cast<OWeakObject *>(this), Any(exc) );
+ }
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\" }!") );
+ throw xml::sax::SAXException(
+ buf.makeStringAndClear(), static_cast<OWeakObject *>(this), Any() );
+}
+
+}
diff --git a/desktop/source/deployment/gui/descedit.cxx b/desktop/source/deployment/gui/descedit.cxx
new file mode 100644
index 000000000000..f38f80f27620
--- /dev/null
+++ b/desktop/source/deployment/gui/descedit.cxx
@@ -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: descedit.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_desktop.hxx"
+
+#include <vcl/scrbar.hxx>
+#include <svtools/txtattr.hxx>
+#include <svtools/xtextedt.hxx>
+
+#include "descedit.hxx"
+
+#include "dp_gui.hrc"
+
+using dp_gui::DescriptionEdit;
+
+// DescriptionEdit -------------------------------------------------------
+
+DescriptionEdit::DescriptionEdit( Window* pParent, const ResId& rResId ) :
+
+ ExtMultiLineEdit( pParent, rResId ),
+
+ m_bIsVerticalScrollBarHidden( true )
+
+{
+ Init();
+}
+
+// -----------------------------------------------------------------------
+
+void DescriptionEdit::Init()
+{
+ Clear();
+ // no tabstop
+ SetStyle( ( GetStyle() & ~WB_TABSTOP ) | WB_NOTABSTOP );
+ // read-only
+ SetReadOnly();
+ // no cursor
+ EnableCursor( FALSE );
+}
+
+// -----------------------------------------------------------------------
+
+void DescriptionEdit::UpdateScrollBar()
+{
+ if ( m_bIsVerticalScrollBarHidden )
+ {
+ ScrollBar* pVScrBar = GetVScrollBar();
+ if ( pVScrBar && pVScrBar->GetVisibleSize() < pVScrBar->GetRangeMax() )
+ {
+ pVScrBar->Show();
+ m_bIsVerticalScrollBarHidden = false;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void DescriptionEdit::Clear()
+{
+ SetText( String() );
+
+ m_bIsVerticalScrollBarHidden = true;
+ ScrollBar* pVScrBar = GetVScrollBar();
+ if ( pVScrBar )
+ pVScrBar->Hide();
+}
+
+// -----------------------------------------------------------------------
+
+void DescriptionEdit::SetDescription( const String& rDescription )
+{
+ SetText( rDescription );
+ UpdateScrollBar();
+}
+
diff --git a/desktop/source/deployment/gui/descedit.hxx b/desktop/source/deployment/gui/descedit.hxx
new file mode 100644
index 000000000000..8afd5a561bd6
--- /dev/null
+++ b/desktop/source/deployment/gui/descedit.hxx
@@ -0,0 +1,60 @@
+/*************************************************************************
+ *
+ * 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: descedit.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 INCLUDED_DESKTOP_SOURCE_DEPLOYMENT_GUI_DP_GUI_DESCEDIT_HXX
+#define INCLUDED_DESKTOP_SOURCE_DEPLOYMENT_GUI_DP_GUI_DESCEDIT_HXX
+
+#include "svtools/svmedit2.hxx"
+
+/// @HTML
+
+namespace dp_gui
+{
+
+ class DescriptionEdit : public ExtMultiLineEdit
+ {
+ private:
+ bool m_bIsVerticalScrollBarHidden;
+
+ void Init();
+ void UpdateScrollBar();
+
+ public:
+ DescriptionEdit( Window* pParent, const ResId& rResId );
+ inline ~DescriptionEdit() {}
+
+ void Clear();
+ void SetDescription( const String& rDescription );
+ };
+
+} // namespace dp_gui
+
+#endif // INCLUDED_DESKTOP_SOURCE_DEPLOYMENT_GUI_DP_GUI_DESCEDIT_HXX
+
diff --git a/desktop/source/deployment/gui/dp_gui.h b/desktop/source/deployment/gui/dp_gui.h
new file mode 100644
index 000000000000..7f2cb7a9626a
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui.h
@@ -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: dp_gui.h,v $
+ * $Revision: 1.24.86.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.
+ *
+ ************************************************************************/
+
+#if ! defined INCLUDED_DP_GUI_H
+#define INCLUDED_DP_GUI_H
+
+#include "dp_gui_updatedata.hxx"
+#include "dp_misc.h"
+#include "dp_gui_updatability.hxx"
+#include "dp_gui.hrc"
+#include "rtl/ref.hxx"
+#include "rtl/instance.hxx"
+#include "osl/thread.hxx"
+#include "cppuhelper/implbase2.hxx"
+#include "vcl/svapp.hxx"
+#include "vcl/dialog.hxx"
+#include "vcl/button.hxx"
+#include "vcl/fixed.hxx"
+#include "salhelper/simplereferenceobject.hxx"
+#include "svtools/svtabbx.hxx"
+#include "svtools/headbar.hxx"
+#include "com/sun/star/ucb/XContentEventListener.hpp"
+#include "osl/mutex.hxx"
+#include <list>
+#include <memory>
+#include <queue>
+
+namespace com { namespace sun { namespace star {
+ namespace container {
+ class XNameAccess;
+ }
+ namespace frame {
+ class XDesktop;
+ }
+ namespace awt {
+ class XWindow;
+ }
+ namespace uno {
+ class XComponentContext;
+ }
+ namespace deployment {
+ class XPackageManagerFactory;
+ }
+} } }
+
+namespace svt {
+ class FixedHyperlink;
+}
+
+namespace dp_gui {
+
+enum PackageState { REGISTERED, NOT_REGISTERED, AMBIGUOUS, NOT_AVAILABLE };
+
+//==============================================================================
+
+class SelectedPackage: public salhelper::SimpleReferenceObject {
+public:
+ SelectedPackage() {}
+ SelectedPackage( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage> &xPackage,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackageManager> &xPackageManager )
+ : m_xPackage( xPackage ),
+ m_xPackageManager( xPackageManager )
+ {}
+
+ virtual ~SelectedPackage();
+ ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage> getPackage() const { return m_xPackage; }
+ ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackageManager> getPackageManager() const { return m_xPackageManager; }
+private:
+ SelectedPackage(SelectedPackage &); // not defined
+ void operator =(SelectedPackage &); // not defined
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage> m_xPackage;
+ ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackageManager> m_xPackageManager;
+};
+
+} // namespace dp_gui
+
+#endif
diff --git a/desktop/source/deployment/gui/dp_gui.hrc b/desktop/source/deployment/gui/dp_gui.hrc
new file mode 100644
index 000000000000..387072c98618
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui.hrc
@@ -0,0 +1,177 @@
+/*************************************************************************
+ *
+ * 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
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#if ! defined INCLUDED_DP_GUI_HRC
+#define INCLUDED_DP_GUI_HRC
+
+#include "deployment.hrc"
+#include "helpid.hrc"
+
+// Package Manager Dialog:
+#define RID_DLG_EXTENSION_MANAGER RID_DEPLOYMENT_GUI_START
+#define RID_DLG_UPDATE_REQUIRED (RID_DEPLOYMENT_GUI_START + 11)
+
+#define RID_EM_BTN_CLOSE 10
+#define RID_EM_BTN_HELP 11
+#define RID_EM_BTN_ADD 12
+#define RID_EM_BTN_CHECK_UPDATES 13
+#define RID_EM_BTN_OPTIONS 14
+#define RID_EM_BTN_CANCEL 15
+#define RID_EM_FT_GET_EXTENSIONS 20
+#define RID_EM_FT_PROGRESS 21
+#define RID_EM_FT_MSG 22
+
+// local RIDs:
+#define PB_LICENSE_DOWN 50
+#define ML_LICENSE 51
+#define BTN_LICENSE_DECLINE 53
+#define FT_LICENSE_HEADER 54
+#define FT_LICENSE_BODY_1 55
+#define FT_LICENSE_BODY_1_TXT 56
+#define FT_LICENSE_BODY_2 57
+#define FT_LICENSE_BODY_2_TXT 58
+#define FL_LICENSE 69
+#define FI_LICENSE_ARROW1 60
+#define FI_LICENSE_ARROW2 61
+#define IMG_LICENCE_ARROW_HC 62
+#define BTN_LICENSE_ACCEPT 63
+
+// local RIDs for "Download and Install" dialog
+
+#define RID_DLG_UPDATE_INSTALL_ABORT 2
+#define RID_DLG_UPDATE_INSTALL_OK 3
+#define RID_DLG_UPDATE_INSTALL_DOWNLOADING 4
+#define RID_DLG_UPDATE_INSTALL_INSTALLING 5
+#define RID_DLG_UPDATE_INSTALL_FINISHED 6
+#define RID_DLG_UPDATE_INSTALL_LINE 7
+#define RID_DLG_UPDATE_INSTALL_HELP 8
+#define RID_DLG_UPDATE_INSTALL_STATUSBAR 9
+#define RID_DLG_UPDATE_INSTALL_EXTENSION_NAME 10
+#define RID_DLG_UPDATE_INSTALL_RESULTS 11
+#define RID_DLG_UPDATE_INSTALL_INFO 12
+#define RID_DLG_UPDATE_INSTALL_NO_ERRORS 13
+#define RID_DLG_UPDATE_INSTALL_THIS_ERROR_OCCURRED 14
+#define RID_DLG_UPDATE_INSTALL_ERROR_DOWNLOAD 15
+#define RID_DLG_UPDATE_INSTALL_ERROR_INSTALLATION 16
+#define RID_DLG_UPDATE_INSTALL_ERROR_LIC_DECLINED 17
+#define RID_DLG_UPDATE_INSTALL_EXTENSION_NOINSTALL 18
+
+#define RID_DLG_DEPENDENCIES (RID_DEPLOYMENT_GUI_START + 1)
+#define RID_DLG_DEPENDENCIES_TEXT 1
+#define RID_DLG_DEPENDENCIES_LIST 2
+#define RID_DLG_DEPENDENCIES_OK 3
+
+#define RID_QUERYBOX_INSTALL_FOR_ALL (RID_DEPLOYMENT_GUI_START + 2)
+#define RID_WARNINGBOX_VERSION_LESS (RID_DEPLOYMENT_GUI_START + 3)
+#define RID_STR_WARNINGBOX_VERSION_LESS_DIFFERENT_NAMES (RID_DEPLOYMENT_GUI_START + 4)
+#define RID_WARNINGBOX_VERSION_EQUAL (RID_DEPLOYMENT_GUI_START + 5)
+#define RID_STR_WARNINGBOX_VERSION_EQUAL_DIFFERENT_NAMES (RID_DEPLOYMENT_GUI_START + 6)
+#define RID_WARNINGBOX_VERSION_GREATER (RID_DEPLOYMENT_GUI_START + 7)
+#define RID_STR_WARNINGBOX_VERSION_GREATER_DIFFERENT_NAMES (RID_DEPLOYMENT_GUI_START + 8)
+#define RID_WARNINGBOX_INSTALL_EXTENSION (RID_DEPLOYMENT_GUI_START + 9)
+
+#define RID_DLG_UPDATE (RID_DEPLOYMENT_GUI_START + 10)
+
+#define RID_DLG_UPDATE_CHECKING 1
+#define RID_DLG_UPDATE_THROBBER 2
+#define RID_DLG_UPDATE_UPDATE 3
+#define RID_DLG_UPDATE_UPDATES 4
+#define RID_DLG_UPDATE_ALL 5
+#define RID_DLG_UPDATE_DESCRIPTION 6
+#define RID_DLG_UPDATE_DESCRIPTIONS 7
+#define RID_DLG_UPDATE_LINE 8
+#define RID_DLG_UPDATE_HELP 9
+#define RID_DLG_UPDATE_OK 10
+#define RID_DLG_UPDATE_CANCEL 11
+#define RID_DLG_UPDATE_NORMALALERT 12
+#define RID_DLG_UPDATE_HIGHCONTRASTALERT 13
+#define RID_DLG_UPDATE_ERROR 14
+#define RID_DLG_UPDATE_NONE 15
+#define RID_DLG_UPDATE_NOINSTALLABLE 16
+#define RID_DLG_UPDATE_FAILURE 17
+#define RID_DLG_UPDATE_UNKNOWNERROR 18
+#define RID_DLG_UPDATE_NODESCRIPTION 19
+#define RID_DLG_UPDATE_NOINSTALL 20
+#define RID_DLG_UPDATE_NODEPENDENCY 21
+#define RID_DLG_UPDATE_NODEPENDENCY_CUR_VER 22
+#define RID_DLG_UPDATE_NOPERMISSION 23
+#define RID_DLG_UPDATE_NOPERMISSION_VISTA 24
+#define RID_DLG_UPDATE_BROWSERBASED 25
+#define RID_DLG_UPDATE_PUBLISHER_LABEL 26
+#define RID_DLG_UPDATE_PUBLISHER_LINK 27
+#define RID_DLG_UPDATE_RELEASENOTES_LABEL 28
+#define RID_DLG_UPDATE_RELEASENOTES_LINK 29
+#define RID_DLG_UPDATE_NOUPDATE 30
+#define RID_DLG_UPDATE_VERSION 31
+
+
+#define RID_DLG_UPDATEINSTALL (RID_DEPLOYMENT_GUI_START + 20)
+#define RID_INFOBOX_UPDATE_SHARED_EXTENSION (RID_DEPLOYMENT_GUI_START + 21)
+
+#define RID_IMG_WARNING (RID_DEPLOYMENT_GUI_START+56)
+#define RID_IMG_WARNING_HC (RID_DEPLOYMENT_GUI_START+57)
+#define RID_IMG_LOCKED (RID_DEPLOYMENT_GUI_START+58)
+#define RID_IMG_LOCKED_HC (RID_DEPLOYMENT_GUI_START+59)
+#define RID_IMG_EXTENSION (RID_DEPLOYMENT_GUI_START+60)
+#define RID_IMG_EXTENSION_HC (RID_DEPLOYMENT_GUI_START+61)
+
+#define RID_STR_ADD_PACKAGES (RID_DEPLOYMENT_GUI_START+70)
+
+#define RID_CTX_ITEM_REMOVE (RID_DEPLOYMENT_GUI_START+80)
+#define RID_CTX_ITEM_ENABLE (RID_DEPLOYMENT_GUI_START+81)
+#define RID_CTX_ITEM_DISABLE (RID_DEPLOYMENT_GUI_START+82)
+#define RID_CTX_ITEM_CHECK_UPDATE (RID_DEPLOYMENT_GUI_START+83)
+#define RID_CTX_ITEM_OPTIONS (RID_DEPLOYMENT_GUI_START+84)
+
+#define RID_STR_ADDING_PACKAGES (RID_DEPLOYMENT_GUI_START+85)
+#define RID_STR_REMOVING_PACKAGES (RID_DEPLOYMENT_GUI_START+86)
+#define RID_STR_ENABLING_PACKAGES (RID_DEPLOYMENT_GUI_START+87)
+#define RID_STR_DISABLING_PACKAGES (RID_DEPLOYMENT_GUI_START+88)
+
+#define RID_STR_INSTALL_FOR_ALL (RID_DEPLOYMENT_GUI_START+90)
+#define RID_STR_INSTALL_FOR_ME (RID_DEPLOYMENT_GUI_START+91)
+#define RID_STR_ERROR_UNKNOWN_STATUS (RID_DEPLOYMENT_GUI_START+92)
+#define RID_STR_CLOSE_BTN (RID_DEPLOYMENT_GUI_START+93)
+#define RID_STR_EXIT_BTN (RID_DEPLOYMENT_GUI_START+94)
+#define RID_STR_NO_ADMIN_PRIVILEGE (RID_DEPLOYMENT_GUI_START+95)
+#define RID_STR_ERROR_MISSING_DEPENDENCIES (RID_DEPLOYMENT_GUI_START+96)
+
+#define WARNINGBOX_CONCURRENTINSTANCE (RID_DEPLOYMENT_GUI_START+100)
+
+#define RID_STR_UNSUPPORTED_PLATFORM (RID_DEPLOYMENT_GUI_START+101)
+#define RID_WARNINGBOX_UPDATE_SHARED_EXTENSION (RID_DEPLOYMENT_GUI_START+102)
+#define RID_WARNINGBOX_REMOVE_EXTENSION (RID_DEPLOYMENT_GUI_START+103)
+#define RID_WARNINGBOX_REMOVE_SHARED_EXTENSION (RID_DEPLOYMENT_GUI_START+104)
+#define RID_WARNINGBOX_ENABLE_SHARED_EXTENSION (RID_DEPLOYMENT_GUI_START+105)
+#define RID_WARNINGBOX_DISABLE_SHARED_EXTENSION (RID_DEPLOYMENT_GUI_START+106)
+
+#define RID_DLG_LICENSE RID_DEPLOYMENT_LICENSE_START
+#define WARNINGBOX_NOSHAREDALLOWED (RID_DEPLOYMENT_LICENSE_START+1)
+
+
+
+#endif
diff --git a/desktop/source/deployment/gui/dp_gui_autoscrolledit.cxx b/desktop/source/deployment/gui/dp_gui_autoscrolledit.cxx
new file mode 100644
index 000000000000..7338a377de5d
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_autoscrolledit.cxx
@@ -0,0 +1,77 @@
+/*************************************************************************
+ *
+ * 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: dp_gui_autoscrolledit.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_desktop.hxx"
+
+
+#include "svtools/svmedit2.hxx"
+#include "svtools/lstner.hxx"
+#include "svtools/xtextedt.hxx"
+#include "vcl/scrbar.hxx"
+
+#include "dp_gui_autoscrolledit.hxx"
+
+
+namespace dp_gui {
+
+
+AutoScrollEdit::AutoScrollEdit( Window* pParent, const ResId& rResId )
+ : ExtMultiLineEdit( pParent, rResId )
+{
+ ScrollBar* pScroll = GetVScrollBar();
+ if (pScroll)
+ pScroll->Hide();
+// SetLeftMargin( 0 );
+ StartListening( *GetTextEngine() );
+}
+
+AutoScrollEdit::~AutoScrollEdit()
+{
+ EndListeningAll();
+}
+
+void AutoScrollEdit::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ if ( rHint.IsA( TYPE(TextHint) ) )
+ {
+ ULONG nId = ((const TextHint&)rHint).GetId();
+ if ( nId == TEXT_HINT_VIEWSCROLLED )
+ {
+ ScrollBar* pScroll = GetVScrollBar();
+ if ( pScroll )
+ pScroll->Show();
+ }
+ }
+}
+
+
+} // namespace dp_gui
+
diff --git a/desktop/source/deployment/gui/dp_gui_autoscrolledit.hxx b/desktop/source/deployment/gui/dp_gui_autoscrolledit.hxx
new file mode 100644
index 000000000000..98fa0050584a
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_autoscrolledit.hxx
@@ -0,0 +1,54 @@
+/*************************************************************************
+ *
+ * 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: dp_gui_autoscrolledit.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 INCLUDED_DESKTOP_SOURCE_DEPLOYMENT_GUI_DP_GUI_AUTOSCROLLEDIT_HXX
+#define INCLUDED_DESKTOP_SOURCE_DEPLOYMENT_GUI_DP_GUI_AUTOSCROLLEDIT_HXX
+
+#include "svtools/svmedit2.hxx"
+#include "svtools/lstner.hxx"
+
+namespace dp_gui {
+
+/** This control shows automatically the vertical scroll bar if text is inserted,
+ that does not fit into the text area. In the resource one uses MultiLineEdit
+ and needs to set VScroll = TRUE
+*/
+class AutoScrollEdit : public ExtMultiLineEdit, public SfxListener
+{
+public:
+ AutoScrollEdit( Window* pParent, const ResId& rResId );
+ ~AutoScrollEdit();
+
+ using ExtMultiLineEdit::Notify;
+ virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
+};
+
+} // namespace dp_gui
+
+#endif
diff --git a/desktop/source/deployment/gui/dp_gui_backend.src b/desktop/source/deployment/gui/dp_gui_backend.src
new file mode 100644
index 000000000000..18c44fdf6e46
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_backend.src
@@ -0,0 +1,134 @@
+/*************************************************************************
+ *
+ * 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: dp_gui_backend.src,v $
+ * $Revision: 1.6 $
+ *
+ * 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 "dp_gui.hrc"
+
+// package bundle:
+Image RID_IMG_DEF_PACKAGE_BUNDLE
+{
+ ImageBitmap = Bitmap { File = "sx03256.bmp"; };
+ MASKCOLOR
+};
+Image RID_IMG_DEF_PACKAGE_BUNDLE_HC
+{
+ ImageBitmap = Bitmap { File = "sxh03256.bmp"; };
+ MASKCOLOR
+};
+
+// script, dialog:
+Image RID_IMG_SCRIPTLIB
+{
+ ImageBitmap = Bitmap { File = "im30820.bmp"; };
+ MASKCOLOR
+};
+Image RID_IMG_SCRIPTLIB_HC
+{
+ ImageBitmap = Bitmap { File = "imh30820.bmp"; };
+ MASKCOLOR
+};
+
+Image RID_IMG_DIALOGLIB
+{
+ ImageBitmap = Bitmap { File = "dialogfolder_16.bmp"; };
+ MASKCOLOR
+};
+Image RID_IMG_DIALOGLIB_HC
+{
+ ImageBitmap = Bitmap { File = "dialogfolder_16_h.bmp"; };
+ MASKCOLOR
+};
+
+// configuration:
+Image RID_IMG_CONF_XML
+{
+ ImageBitmap = Bitmap { File = "xml_16.bmp"; };
+ MASKCOLOR
+};
+Image RID_IMG_CONF_XML_HC
+{
+ ImageBitmap = Bitmap { File = "xml_16_h.bmp"; };
+ MASKCOLOR
+};
+
+// component, typelib:
+Image RID_IMG_COMPONENT
+{
+ ImageBitmap = Bitmap { File = "component_16.bmp"; };
+ MASKCOLOR
+};
+Image RID_IMG_COMPONENT_HC
+{
+ ImageBitmap = Bitmap { File = "component_16_h.bmp"; };
+ MASKCOLOR
+};
+
+Image RID_IMG_JAVA_COMPONENT
+{
+ ImageBitmap = Bitmap { File = "javacomponent_16.bmp"; };
+ MASKCOLOR
+};
+Image RID_IMG_JAVA_COMPONENT_HC
+{
+ ImageBitmap = Bitmap { File = "javacomponent_16_h.bmp"; };
+ MASKCOLOR
+};
+
+Image RID_IMG_TYPELIB
+{
+ ImageBitmap = Bitmap { File = "library_16.bmp"; };
+ MASKCOLOR
+};
+Image RID_IMG_TYPELIB_HC
+{
+ ImageBitmap = Bitmap { File = "library_16_h.bmp"; };
+ MASKCOLOR
+};
+
+Image RID_IMG_JAVA_TYPELIB
+{
+ ImageBitmap = Bitmap { File = "javalibrary_16.bmp"; };
+ MASKCOLOR
+};
+Image RID_IMG_JAVA_TYPELIB_HC
+{
+ ImageBitmap = Bitmap { File = "javalibrary_16_h.bmp"; };
+ MASKCOLOR
+};
+
+Image RID_IMG_HELP
+{
+ ImageBitmap = Bitmap { File = "commandimagelist/sc_helperdialog.bmp"; };
+ MASKCOLOR
+};
+Image RID_IMG_HELP_HC
+{
+ ImageBitmap = Bitmap { File = "commandimagelist/sch_helperdialog.bmp"; };
+ MASKCOLOR
+};
diff --git a/desktop/source/deployment/gui/dp_gui_dependencydialog.cxx b/desktop/source/deployment/gui/dp_gui_dependencydialog.cxx
new file mode 100644
index 000000000000..2e8b64dd237d
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_dependencydialog.cxx
@@ -0,0 +1,89 @@
+/*************************************************************************
+ *
+ * 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: dp_gui_dependencydialog.cxx,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "sal/config.h"
+
+#include <algorithm>
+#include <vector>
+
+#include "rtl/ustring.hxx"
+#include "tools/gen.hxx"
+#include "tools/resid.hxx"
+#include "tools/resmgr.hxx"
+#include "tools/solar.h"
+#include "tools/string.hxx"
+#include "vcl/dialog.hxx"
+
+#include "dp_gui.hrc"
+#include "dp_gui_dependencydialog.hxx"
+#include "dp_gui_shared.hxx"
+
+class Window;
+
+using dp_gui::DependencyDialog;
+
+DependencyDialog::DependencyDialog(
+ Window * parent, std::vector< rtl::OUString > const & dependencies):
+ ModalDialog(parent, DpGuiResId(RID_DLG_DEPENDENCIES) ),
+ m_text(this, DpGuiResId(RID_DLG_DEPENDENCIES_TEXT)),
+ m_list(this, DpGuiResId(RID_DLG_DEPENDENCIES_LIST)),
+ m_ok(this, DpGuiResId(RID_DLG_DEPENDENCIES_OK)),
+ m_listDelta(
+ GetOutputSizePixel().Width() - m_list.GetSizePixel().Width(),
+ GetOutputSizePixel().Height() - m_list.GetSizePixel().Height())
+{
+ FreeResource();
+ SetMinOutputSizePixel(GetOutputSizePixel());
+ m_list.SetReadOnly();
+ for (std::vector< rtl::OUString >::const_iterator i(dependencies.begin());
+ i != dependencies.end(); ++i)
+ {
+ m_list.InsertEntry(*i);
+ }
+}
+
+DependencyDialog::~DependencyDialog() {}
+
+void DependencyDialog::Resize() {
+ long n = m_ok.GetPosPixel().Y() -
+ (m_list.GetPosPixel().Y() + m_list.GetSizePixel().Height());
+ m_list.SetSizePixel(
+ Size(
+ GetOutputSizePixel().Width() - m_listDelta.Width(),
+ GetOutputSizePixel().Height() - m_listDelta.Height()));
+ m_ok.SetPosPixel(
+ Point(
+ (m_list.GetPosPixel().X() +
+ (m_list.GetSizePixel().Width() - m_ok.GetSizePixel().Width()) / 2),
+ m_list.GetPosPixel().Y() + m_list.GetSizePixel().Height() + n));
+}
diff --git a/desktop/source/deployment/gui/dp_gui_dependencydialog.hxx b/desktop/source/deployment/gui/dp_gui_dependencydialog.hxx
new file mode 100644
index 000000000000..7030ea68ffd5
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_dependencydialog.hxx
@@ -0,0 +1,71 @@
+/*************************************************************************
+ *
+ * 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: dp_gui_dependencydialog.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 INCLUDED_DESKTOP_SOURCE_DEPLOYMENT_GUI_DP_GUI_DEPENDENCYDIALOG_HXX
+#define INCLUDED_DESKTOP_SOURCE_DEPLOYMENT_GUI_DP_GUI_DEPENDENCYDIALOG_HXX
+
+#include "sal/config.h"
+
+#include <vector>
+#include "tools/gen.hxx"
+#ifndef _SV_BUTTON_HXX
+#include "vcl/button.hxx"
+#endif
+#include "vcl/dialog.hxx"
+#include "vcl/fixed.hxx"
+#include "vcl/lstbox.hxx"
+
+class Window;
+namespace rtl { class OUString; }
+
+namespace dp_gui {
+
+class DependencyDialog: public ModalDialog {
+public:
+ DependencyDialog(
+ Window * parent, std::vector< rtl::OUString > const & dependencies);
+
+ ~DependencyDialog();
+
+private:
+ DependencyDialog(DependencyDialog &); // not defined
+ void operator =(DependencyDialog &); // not defined
+
+ virtual void Resize();
+
+ FixedText m_text;
+ ListBox m_list;
+ OKButton m_ok;
+ Size m_listDelta;
+};
+
+}
+
+#endif
diff --git a/desktop/source/deployment/gui/dp_gui_dependencydialog.src b/desktop/source/deployment/gui/dp_gui_dependencydialog.src
new file mode 100644
index 000000000000..dc03e75f4291
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_dependencydialog.src
@@ -0,0 +1,73 @@
+/*************************************************************************
+ *
+ * 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: dp_gui_dependencydialog.src,v $
+ * $Revision: 1.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.
+ *
+ ************************************************************************/
+
+#include "svtools/controldims.hrc"
+
+#include "dp_gui.hrc"
+
+#define LOCAL_WIDTH (50 * RSC_BS_CHARWIDTH)
+#define LOCAL_TEXT_HEIGHT (2 * RSC_CD_FIXEDTEXT_HEIGHT)
+#define LOCAL_LIST_HEIGHT (6 * RSC_BS_CHARHEIGHT)
+
+ModalDialog RID_DLG_DEPENDENCIES {
+ Size = MAP_APPFONT(
+ (RSC_SP_DLG_INNERBORDER_LEFT + LOCAL_WIDTH +
+ RSC_SP_DLG_INNERBORDER_RIGHT),
+ (RSC_SP_DLG_INNERBORDER_TOP + LOCAL_TEXT_HEIGHT + RSC_SP_CTRL_DESC_Y +
+ LOCAL_LIST_HEIGHT + RSC_SP_CTRL_Y + RSC_CD_PUSHBUTTON_HEIGHT +
+ RSC_SP_DLG_INNERBORDER_BOTTOM));
+ Text[en-US] = "System dependencies check";
+ Sizeable = TRUE;
+ Moveable = TRUE;
+ Closeable = TRUE;
+ FixedText RID_DLG_DEPENDENCIES_TEXT {
+ Pos = MAP_APPFONT(
+ RSC_SP_DLG_INNERBORDER_LEFT, RSC_SP_DLG_INNERBORDER_TOP);
+ Size = MAP_APPFONT(LOCAL_WIDTH, LOCAL_TEXT_HEIGHT);
+ Text[en-US] = "The extension cannot be installed as the following\nsystem dependencies are not fulfilled:";
+ NoLabel = TRUE;
+ };
+ ListBox RID_DLG_DEPENDENCIES_LIST {
+ Pos = MAP_APPFONT(
+ RSC_SP_DLG_INNERBORDER_LEFT,
+ (RSC_SP_DLG_INNERBORDER_TOP + LOCAL_TEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y));
+ Size = MAP_APPFONT(LOCAL_WIDTH, LOCAL_LIST_HEIGHT);
+ };
+ OKButton RID_DLG_DEPENDENCIES_OK {
+ Pos = MAP_APPFONT(
+ (RSC_SP_DLG_INNERBORDER_LEFT +
+ (LOCAL_WIDTH - RSC_CD_PUSHBUTTON_WIDTH) / 2),
+ (RSC_SP_DLG_INNERBORDER_TOP + LOCAL_TEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + LOCAL_LIST_HEIGHT + RSC_SP_CTRL_Y));
+ Size = MAP_APPFONT(RSC_CD_PUSHBUTTON_WIDTH, RSC_CD_PUSHBUTTON_HEIGHT);
+ DefButton = TRUE;
+ };
+};
diff --git a/desktop/source/deployment/gui/dp_gui_dialog.src b/desktop/source/deployment/gui/dp_gui_dialog.src
new file mode 100644
index 000000000000..e7c785c86973
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_dialog.src
@@ -0,0 +1,346 @@
+/*************************************************************************
+ *
+ * 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: dp_gui_dialog.src,v $
+ * $Revision: 1.19 $
+ *
+ * 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 "svtools/controldims.hrc"
+#include "dp_gui.hrc"
+
+String RID_STR_ADD_PACKAGES
+{
+ Text [ en-US ] = "Add Extension(s)";
+};
+String RID_CTX_ITEM_REMOVE
+{
+ Text [ en-US ] = "~Remove";
+};
+String RID_CTX_ITEM_ENABLE
+{
+ Text [ en-US ] = "~Enable";
+};
+String RID_CTX_ITEM_DISABLE
+{
+ Text [ en-US ] = "~Disable";
+};
+String RID_CTX_ITEM_CHECK_UPDATE
+{
+ Text [ en-US ] = "~Update...";
+};
+String RID_CTX_ITEM_OPTIONS
+{
+ Text [ en-US ] = "~Options...";
+};
+
+String RID_STR_ADDING_PACKAGES
+{
+ Text [ en-US ] = "Adding %EXTENSION_NAME";
+};
+
+String RID_STR_REMOVING_PACKAGES
+{
+ Text [ en-US ] = "Removing %EXTENSION_NAME";
+};
+
+String RID_STR_ENABLING_PACKAGES
+{
+ Text [ en-US ] = "Enabling %EXTENSION_NAME";
+};
+
+String RID_STR_DISABLING_PACKAGES
+{
+ Text [ en-US ] = "Disabling %EXTENSION_NAME";
+};
+
+String RID_STR_INSTALL_FOR_ALL
+{
+ Text [ en-US ] = "~For all users";
+};
+
+String RID_STR_INSTALL_FOR_ME
+{
+ Text [ en-US ] = "~Only for me";
+};
+
+String RID_STR_ERROR_UNKNOWN_STATUS
+{
+ Text [ en-US ] = "Error: The status of this extension is unknown";
+};
+
+String RID_STR_CLOSE_BTN
+{
+ Text [ en-US ] = "Close";
+};
+
+String RID_STR_EXIT_BTN
+{
+ Text [ en-US ] = "Quit";
+};
+
+String RID_STR_NO_ADMIN_PRIVILEGE
+{
+ Text [ en-US ] = "%PRODUCTNAME has been updated to a new version. "
+ "Some shared %PRODUCTNAME extensions are not compatible with this version and need to be updated before %PRODUCTNAME can be started.\n\n"
+ "Updating of shared extension requires administrator privileges. Contact your system administrator to update the following shared extensions:";
+};
+
+String RID_STR_ERROR_MISSING_DEPENDENCIES
+{
+ Text [ en-US ] = "The extension cannot be enabled as the following system dependencies are not fulfilled:";
+};
+
+// Dialog layout
+// ---------------------------------------------------
+// row 1 | multi line edit
+// ---------------------------------------------------
+// row 2 | fixed text
+// ---------------------------------------------------
+// row 3 | img | fixed text | fixed text | button
+// ----------------------------------------------------
+// row 4 | img | fixed text | fixed text
+// ---------------------------------------------------
+// row 5 |fixed line
+// ---------------------------------------------------
+// row 6 | | |button | button
+// ---------------------------------------------------
+// | col 1 | col 2 | col3 | col4 | col5
+
+//To change the overall size of the multi line edit change
+//ROW1_HEIGHT and COL3_WIDTH
+
+#define ROW1_Y RSC_SP_DLG_INNERBORDER_TOP
+#define ROW1_HEIGHT 16*RSC_CD_FIXEDTEXT_HEIGHT
+#define ROW2_Y ROW1_Y+ROW1_HEIGHT+RSC_SP_CTRL_GROUP_Y
+#define ROW2_HEIGHT 2*RSC_CD_FIXEDTEXT_HEIGHT
+#define ROW3_Y ROW2_Y+ROW2_HEIGHT+RSC_SP_CTRL_GROUP_Y
+#define ROW3_HEIGHT 3*RSC_CD_FIXEDTEXT_HEIGHT
+#define ROW4_Y ROW3_Y+ROW3_HEIGHT+RSC_SP_CTRL_GROUP_Y
+#define ROW4_HEIGHT 3*RSC_CD_FIXEDTEXT_HEIGHT
+#define ROW5_Y ROW4_Y+ROW4_HEIGHT+RSC_SP_CTRL_GROUP_Y
+#define ROW5_HEIGHT RSC_CD_FIXEDTEXT_HEIGHT
+#define ROW6_Y ROW5_Y+ROW5_HEIGHT+RSC_SP_CTRL_GROUP_Y
+#define ROW6_HEIGHT RSC_CD_PUSHBUTTON_HEIGHT
+
+#define LIC_DLG_HEIGHT ROW6_Y+ROW6_HEIGHT+RSC_SP_DLG_INNERBORDER_BOTTOM
+
+#define COL1_X RSC_SP_DLG_INNERBORDER_LEFT
+#define IMG_ARROW_WIDTH 16
+#define COL1_WIDTH IMG_ARROW_WIDTH
+#define COL2_X COL1_X+COL1_WIDTH
+#define COL2_WIDTH 10
+#define COL3_X COL2_X+COL2_WIDTH+RSC_SP_CTRL_GROUP_X
+#define COL3_WIDTH 150
+#define COL4_X COL3_X+COL3_WIDTH
+#define COL4_WIDTH RSC_CD_PUSHBUTTON_WIDTH+RSC_SP_CTRL_GROUP_X
+#define COL5_X COL4_X+COL4_WIDTH
+
+#define LIC_DLG_WIDTH COL5_X+RSC_CD_PUSHBUTTON_WIDTH+RSC_SP_DLG_INNERBORDER_RIGHT
+#define BODYWIDTH LIC_DLG_WIDTH-RSC_SP_DLG_INNERBORDER_LEFT-RSC_SP_DLG_INNERBORDER_RIGHT
+
+ModalDialog RID_DLG_LICENSE
+{
+ Text [ en-US ] = "Extension Software License Agreement";
+
+ Size = MAP_APPFONT(LIC_DLG_WIDTH, LIC_DLG_HEIGHT);
+ OutputSize = TRUE;
+ SVLook = TRUE;
+ Moveable = TRUE;
+ Closeable = TRUE;
+ Sizeable = FALSE;
+// Hide = TRUE;
+
+ MultiLineEdit ML_LICENSE
+ {
+ Pos = MAP_APPFONT(COL1_X, ROW1_Y);
+ Size = MAP_APPFONT(BODYWIDTH, ROW1_HEIGHT);
+ Border = TRUE;
+ VScroll = TRUE;
+ ReadOnly = TRUE;
+ };
+
+ FixedText FT_LICENSE_HEADER
+ {
+ Pos = MAP_APPFONT(COL1_X, ROW2_Y);
+ Size = MAP_APPFONT(COL1_WIDTH+COL2_WIDTH+COL3_WIDTH+COL4_WIDTH, ROW2_HEIGHT);
+ WordBreak = TRUE;
+ NoLabel = TRUE;
+ Text [ en-US ] = "Please follow these steps to proceed with the installation of the extension:";
+ };
+ FixedText FT_LICENSE_BODY_1
+ {
+ Pos = MAP_APPFONT(COL2_X, ROW3_Y);
+ Size = MAP_APPFONT( COL2_WIDTH, ROW3_HEIGHT );
+ NoLabel = TRUE;
+ Text [ en-US ] = "1.";
+ };
+ //spans col3 + col4
+ FixedText FT_LICENSE_BODY_1_TXT
+ {
+ Pos = MAP_APPFONT(COL3_X, ROW3_Y);
+ Size = MAP_APPFONT(COL3_WIDTH+COL4_WIDTH, ROW3_HEIGHT);
+ WordBreak = TRUE;
+ NoLabel = TRUE;
+ Text [ en-US ] = "Read the complete License Agreement. Use the scroll bar or the \'Scroll Down\' button in this dialog to view the entire license text.";
+ };
+ FixedText FT_LICENSE_BODY_2
+ {
+ Pos = MAP_APPFONT(COL2_X, ROW4_Y);
+ Size = MAP_APPFONT(COL2_WIDTH, ROW4_HEIGHT);
+ NoLabel = TRUE;
+ Text [ en-US ] = "2.";
+ };
+ FixedText FT_LICENSE_BODY_2_TXT
+ {
+ Pos = MAP_APPFONT(COL3_X, ROW4_Y);
+ Size = MAP_APPFONT(COL3_WIDTH+COL4_WIDTH, ROW4_HEIGHT);
+ WordBreak = TRUE;
+ NoLabel = TRUE;
+ Text [ en-US ] = "Accept the License Agreement for the extension by pressing the \'Accept\' button.";
+
+ };
+ PushButton PB_LICENSE_DOWN
+ {
+ TabStop = TRUE ;
+ Pos = MAP_APPFONT(COL5_X , ROW3_Y) ;
+ Size = MAP_APPFONT(RSC_CD_PUSHBUTTON_WIDTH, RSC_CD_PUSHBUTTON_HEIGHT) ;
+ Text [ en-US ] = "~Scroll Down";
+
+ };
+ FixedLine FL_LICENSE
+ {
+ Pos = MAP_APPFONT ( 0, ROW5_Y) ;
+ Size = MAP_APPFONT ( LIC_DLG_WIDTH, ROW5_HEIGHT ) ;
+ };
+
+ FixedImage FI_LICENSE_ARROW1
+ {
+ Pos = MAP_APPFONT (COL1_X, ROW3_Y) ;
+ Size = (16, 16);
+ Fixed = Image
+ {
+ ImageBitmap = Bitmap { File = "sc06300.png"; };
+ MASKCOLOR
+ };
+ };
+
+ FixedImage FI_LICENSE_ARROW2
+ {
+ Pos = MAP_APPFONT (COL1_X, ROW4_Y) ;
+ Size = (16,16);
+ Fixed = Image
+ {
+ ImageBitmap = Bitmap { File = "sc06300.png"; };
+ MASKCOLOR
+ };
+ };
+
+ Image IMG_LICENCE_ARROW_HC
+ {
+ ImageBitmap = Bitmap { File = "sch06300.png"; };
+ MASKCOLOR
+ };
+
+ OKButton BTN_LICENSE_ACCEPT
+ {
+ Pos = MAP_APPFONT(COL4_X, ROW6_Y);
+ Size = MAP_APPFONT(RSC_CD_PUSHBUTTON_WIDTH, RSC_CD_PUSHBUTTON_HEIGHT );
+
+ TabStop = TRUE;
+ DefButton = TRUE;
+ Text [ en-US ] = "Accept";
+ };
+
+ CancelButton BTN_LICENSE_DECLINE
+ {
+ Pos = MAP_APPFONT(COL5_X, ROW6_Y);
+ Size = MAP_APPFONT( RSC_CD_PUSHBUTTON_WIDTH, RSC_CD_PUSHBUTTON_HEIGHT );
+ Text [ en-US ] = "Decline" ;
+ TabStop = TRUE;
+ };
+
+};
+
+
+
+WarningBox WARNINGBOX_NOSHAREDALLOWED
+{
+ Buttons = WB_OK ;
+ DefButton = WB_DEF_OK;
+ Message[ en-US ] ="The extension \'%NAME\' cannot be installed under \"%PRODUCTNAME Extensions\", because "
+ "every user has to agree to the license agreement of the extension. The extension will not be installed.";
+};
+
+WarningBox RID_WARNINGBOX_INSTALL_EXTENSION {
+ Buttons = WB_OK_CANCEL;
+ DefButton = WB_DEF_OK;
+ Message[en-US] = "You are about to install the extension \'%NAME\'.\n"
+ "Click \'OK\' to proceed with the installation.\n"
+ "Click \'Cancel\' to stop the installation.";
+};
+
+WarningBox RID_WARNINGBOX_REMOVE_EXTENSION {
+ Buttons = WB_OK_CANCEL;
+ DefButton = WB_DEF_CANCEL;
+ Message[en-US] = "You are about to remove the extension \'%NAME\'.\n"
+ "Click \'OK\' to remove the extension.\n"
+ "Click \'Cancel\' to stop removing the extension.";
+};
+
+WARNINGBOX RID_WARNINGBOX_REMOVE_SHARED_EXTENSION
+{
+ Buttons = WB_OK_CANCEL;
+ DefButton = WB_DEF_CANCEL;
+ Message[en-US] = "Make sure that no further users are working with the same "
+ "%PRODUCTNAME, when changing shared extensions in a multi user environment.\n"
+ "Click \'OK\' to remove the extension.\n"
+ "Click \'Cancel\' to stop removing the extension.";
+};
+
+WARNINGBOX RID_WARNINGBOX_ENABLE_SHARED_EXTENSION
+{
+ Buttons = WB_OK_CANCEL;
+ DefButton = WB_DEF_CANCEL;
+ Message[en-US] = "Make sure that no further users are working with the same "
+ "%PRODUCTNAME, when changing shared extensions in a multi user environment.\n"
+ "Click \'OK\' to enable the extension.\n"
+ "Click \'Cancel\' to stop enabling the extension.";
+};
+
+WARNINGBOX RID_WARNINGBOX_DISABLE_SHARED_EXTENSION
+{
+ Buttons = WB_OK_CANCEL;
+ DefButton = WB_DEF_CANCEL;
+ Message[en-US] = "Make sure that no further users are working with the same "
+ "%PRODUCTNAME, when changing shared extensions in a multi user environment.\n"
+ "Click \'OK\' to disable the extension.\n"
+ "Click \'Cancel\' to stop disabling the extension.";
+};
+
+
+String RID_STR_UNSUPPORTED_PLATFORM
+{
+ Text [ en-US ] = "The extension \'%Name\' does not work on this computer.";
+};
diff --git a/desktop/source/deployment/gui/dp_gui_dialog2.cxx b/desktop/source/deployment/gui/dp_gui_dialog2.cxx
new file mode 100644
index 000000000000..f09d906a840e
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_dialog2.cxx
@@ -0,0 +1,1789 @@
+/*************************************************************************
+ *
+ * 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: dp_gui_dialog2.cxx,v $
+ *
+ * $Revision: 1.8.4.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_desktop.hxx"
+
+#include "dp_gui.hrc"
+#include "svtools/controldims.hrc"
+#include "svtools/svtools.hrc"
+
+#include "dp_gui.h"
+#include "dp_gui_dialog2.hxx"
+#include "dp_gui_extlistbox.hxx"
+#include "dp_gui_shared.hxx"
+#include "dp_gui_theextmgr.hxx"
+#include "dp_misc.h"
+
+#include "vcl/ctrl.hxx"
+#include "vcl/menu.hxx"
+#include "vcl/msgbox.hxx"
+#include "vcl/scrbar.hxx"
+#include "vcl/svapp.hxx"
+
+#include "vos/mutex.hxx"
+
+#include "svtools/extensionlistbox.hxx"
+
+#include "sfx2/sfxdlg.hxx"
+
+#include "comphelper/anytostring.hxx"
+#include "cppuhelper/exc_hlp.hxx"
+#include "cppuhelper/bootstrap.hxx"
+
+#include "comphelper/processfactory.hxx"
+#include "ucbhelper/content.hxx"
+#include "unotools/collatorwrapper.hxx"
+
+#include "com/sun/star/beans/StringPair.hpp"
+
+#include "com/sun/star/i18n/CollatorOptions.hpp"
+
+#include "com/sun/star/system/SystemShellExecuteFlags.hpp"
+#include "com/sun/star/system/XSystemShellExecute.hpp"
+
+#include "com/sun/star/ui/dialogs/ExecutableDialogResults.hpp"
+#include "com/sun/star/ui/dialogs/TemplateDescription.hpp"
+#include "com/sun/star/ui/dialogs/XFilePicker.hpp"
+#include "com/sun/star/ui/dialogs/XFilterManager.hpp"
+
+#include "com/sun/star/uno/Any.hxx"
+#include "com/sun/star/uno/XComponentContext.hpp"
+
+#include "com/sun/star/deployment/thePackageManagerFactory.hpp"
+
+#include <map>
+#include <vector>
+#include <boost/shared_ptr.hpp>
+
+#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::system;
+
+using ::rtl::OUString;
+
+
+namespace dp_gui {
+
+#define ICON_OFFSET 50
+#define TOP_OFFSET 3
+#define LINE_SIZE 4
+#define PROGRESS_WIDTH 60
+#define PROGRESS_HEIGHT 14
+
+//------------------------------------------------------------------------------
+struct StrAllFiles : public rtl::StaticWithInit< const OUString, StrAllFiles >
+{
+ const OUString operator () () {
+ const ::vos::OGuard guard( Application::GetSolarMutex() );
+ ::std::auto_ptr< ResMgr > const resmgr( ResMgr::CreateResMgr( "fps_office" ) );
+ OSL_ASSERT( resmgr.get() != 0 );
+ String ret( ResId( STR_FILTERNAME_ALL, *resmgr.get() ) );
+ return ret;
+ }
+};
+
+//------------------------------------------------------------------------------
+UpdateListEntry::UpdateListEntry( const uno::Reference< deployment::XPackage > &xPackage,
+ const uno::Reference< deployment::XPackageManager > &xPackageManager ) :
+ m_xPackage( xPackage ),
+ m_xPackageManager( xPackageManager )
+{}
+
+//------------------------------------------------------------------------------
+UpdateListEntry::~UpdateListEntry()
+{}
+
+//------------------------------------------------------------------------------
+// ExtBoxWithBtns_Impl
+//------------------------------------------------------------------------------
+
+enum MENU_COMMAND
+{
+ CMD_NONE = 0,
+ CMD_REMOVE = 1,
+ CMD_ENABLE,
+ CMD_DISABLE,
+ CMD_UPDATE
+};
+
+class ExtBoxWithBtns_Impl : public ExtensionBox_Impl
+{
+ Size m_aOutputSize;
+ bool m_bInterfaceLocked;
+
+ PushButton *m_pOptionsBtn;
+ PushButton *m_pEnableBtn;
+ PushButton *m_pRemoveBtn;
+
+ ExtMgrDialog *m_pParent;
+
+ void SetButtonPos( const Rectangle& rRect );
+ void SetButtonStatus( const TEntry_Impl pEntry );
+ bool HandleTabKey( bool bReverse );
+ MENU_COMMAND ShowPopupMenu( const Point &rPos, const long nPos );
+
+ //-----------------
+ DECL_DLLPRIVATE_LINK( ScrollHdl, ScrollBar * );
+
+ DECL_DLLPRIVATE_LINK( HandleOptionsBtn, void * );
+ DECL_DLLPRIVATE_LINK( HandleEnableBtn, void * );
+ DECL_DLLPRIVATE_LINK( HandleRemoveBtn, void * );
+ DECL_DLLPRIVATE_LINK( HandleHyperlink, svt::FixedHyperlink * );
+
+public:
+ ExtBoxWithBtns_Impl( ExtMgrDialog* pParent, TheExtensionManager *pManager );
+ ~ExtBoxWithBtns_Impl();
+
+ virtual void MouseButtonDown( const MouseEvent& rMEvt );
+ virtual long Notify( NotifyEvent& rNEvt );
+
+ const Size GetMinOutputSizePixel() const;
+
+ virtual void RecalcAll();
+ virtual void selectEntry( const long nPos );
+ //-----------------
+ void enableButtons( bool bEnable );
+};
+
+//------------------------------------------------------------------------------
+ExtBoxWithBtns_Impl::ExtBoxWithBtns_Impl( ExtMgrDialog* pParent, TheExtensionManager *pManager ) :
+ ExtensionBox_Impl( pParent, pManager ),
+ m_bInterfaceLocked( false ),
+ m_pOptionsBtn( NULL ),
+ m_pEnableBtn( NULL ),
+ m_pRemoveBtn( NULL ),
+ m_pParent( pParent )
+{
+ m_pOptionsBtn = new PushButton( this, WB_TABSTOP );
+ m_pEnableBtn = new PushButton( this, WB_TABSTOP );
+ m_pRemoveBtn = new PushButton( this, WB_TABSTOP );
+
+ SetHelpId( HID_EXTENSION_MANAGER_LISTBOX );
+ m_pOptionsBtn->SetHelpId( HID_EXTENSION_MANAGER_LISTBOX_OPTIONS );
+ m_pEnableBtn->SetHelpId( HID_EXTENSION_MANAGER_LISTBOX_DISABLE );
+ m_pRemoveBtn->SetHelpId( HID_EXTENSION_MANAGER_LISTBOX_REMOVE );
+
+ m_pOptionsBtn->SetClickHdl( LINK( this, ExtBoxWithBtns_Impl, HandleOptionsBtn ) );
+ m_pEnableBtn->SetClickHdl( LINK( this, ExtBoxWithBtns_Impl, HandleEnableBtn ) );
+ m_pRemoveBtn->SetClickHdl( LINK( this, ExtBoxWithBtns_Impl, HandleRemoveBtn ) );
+
+ m_pOptionsBtn->SetText( DialogHelper::getResourceString( RID_CTX_ITEM_OPTIONS ) );
+ m_pEnableBtn->SetText( DialogHelper::getResourceString( RID_CTX_ITEM_DISABLE ) );
+ m_pRemoveBtn->SetText( DialogHelper::getResourceString( RID_CTX_ITEM_REMOVE ) );
+
+ Size aSize = LogicToPixel( Size( RSC_CD_PUSHBUTTON_WIDTH, RSC_CD_PUSHBUTTON_HEIGHT ),
+ MapMode( MAP_APPFONT ) );
+ m_pOptionsBtn->SetSizePixel( aSize );
+ m_pEnableBtn->SetSizePixel( aSize );
+ m_pRemoveBtn->SetSizePixel( aSize );
+
+ SetExtraSize( aSize.Height() + 2 * TOP_OFFSET );
+
+ SetScrollHdl( LINK( this, ExtBoxWithBtns_Impl, ScrollHdl ) );
+}
+
+//------------------------------------------------------------------------------
+ExtBoxWithBtns_Impl::~ExtBoxWithBtns_Impl()
+{
+ delete m_pOptionsBtn;
+ delete m_pEnableBtn;
+ delete m_pRemoveBtn;
+}
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+const Size ExtBoxWithBtns_Impl::GetMinOutputSizePixel() const
+{
+ Size aMinSize( ExtensionBox_Impl::GetMinOutputSizePixel() );
+ long nHeight = aMinSize.Height();
+ nHeight += m_pOptionsBtn->GetSizePixel().Height();
+ nHeight += 2 * TOP_OFFSET;
+ long nWidth = m_pOptionsBtn->GetSizePixel().Width();
+ nWidth *= 3;
+ nWidth += 5*TOP_OFFSET + 20;
+
+ return Size( nWidth, nHeight );
+}
+
+// -----------------------------------------------------------------------
+void ExtBoxWithBtns_Impl::RecalcAll()
+{
+ ExtensionBox_Impl::RecalcAll();
+
+ const sal_Int32 nActive = getSelIndex();
+
+ if ( nActive != EXTENSION_LISTBOX_ENTRY_NOTFOUND )
+ SetButtonPos( GetEntryRect( nActive ) );
+ else
+ {
+ m_pOptionsBtn->Hide();
+ m_pEnableBtn->Hide();
+ m_pRemoveBtn->Hide();
+ }
+}
+
+
+//------------------------------------------------------------------------------
+//This function may be called with nPos < 0
+void ExtBoxWithBtns_Impl::selectEntry( const long nPos )
+{
+ if ( HasActive() && ( nPos == getSelIndex() ) )
+ return;
+
+ ExtensionBox_Impl::selectEntry( nPos );
+
+ if ( ( nPos >= 0 ) && ( nPos < GetEntryCount() ) )
+ {
+ if ( IsReallyVisible() )
+ {
+ SetButtonPos( GetEntryRect( nPos ) );
+ }
+ SetButtonStatus( GetEntryData( nPos) );
+ }
+ else
+ {
+ m_pOptionsBtn->Hide();
+ m_pEnableBtn->Hide();
+ m_pRemoveBtn->Hide();
+ }
+}
+
+// -----------------------------------------------------------------------
+void ExtBoxWithBtns_Impl::SetButtonPos( const Rectangle& rRect )
+{
+ Size aBtnSize( m_pOptionsBtn->GetSizePixel() );
+ Point aBtnPos( rRect.Left() + ICON_OFFSET,
+ rRect.Bottom() - TOP_OFFSET - aBtnSize.Height() );
+
+ m_pOptionsBtn->SetPosPixel( aBtnPos );
+ aBtnPos.X() = rRect.Right() - TOP_OFFSET - aBtnSize.Width();
+ m_pRemoveBtn->SetPosPixel( aBtnPos );
+ aBtnPos.X() -= ( TOP_OFFSET + aBtnSize.Width() );
+ m_pEnableBtn->SetPosPixel( aBtnPos );
+}
+
+// -----------------------------------------------------------------------
+void ExtBoxWithBtns_Impl::SetButtonStatus( const TEntry_Impl pEntry )
+{
+ if ( ( pEntry->m_eState == REGISTERED ) || ( pEntry->m_eState == NOT_AVAILABLE ) )
+ {
+ m_pEnableBtn->SetText( DialogHelper::getResourceString( RID_CTX_ITEM_DISABLE ) );
+ m_pEnableBtn->SetHelpId( HID_EXTENSION_MANAGER_LISTBOX_DISABLE );
+ }
+ else
+ {
+ m_pEnableBtn->SetText( DialogHelper::getResourceString( RID_CTX_ITEM_ENABLE ) );
+ m_pEnableBtn->SetHelpId( HID_EXTENSION_MANAGER_LISTBOX_ENABLE );
+ }
+
+ if ( ( pEntry->m_eState == NOT_AVAILABLE ) || pEntry->m_bMissingDeps )
+ m_pEnableBtn->Hide();
+ else
+ {
+ m_pEnableBtn->Enable( !pEntry->m_bLocked );
+ m_pEnableBtn->Show();
+ }
+
+ if ( pEntry->m_bHasOptions )
+ {
+ m_pOptionsBtn->Enable( pEntry->m_bHasOptions );
+ m_pOptionsBtn->Show();
+ }
+ else
+ m_pOptionsBtn->Hide();
+
+ m_pRemoveBtn->Show();
+ m_pRemoveBtn->Enable( !pEntry->m_bLocked );
+}
+
+// -----------------------------------------------------------------------
+bool ExtBoxWithBtns_Impl::HandleTabKey( bool bReverse )
+{
+ sal_Int32 nIndex = getSelIndex();
+
+ if ( nIndex == EXTENSION_LISTBOX_ENTRY_NOTFOUND )
+ return false;
+
+ PushButton *pNext = NULL;
+
+ if ( m_pOptionsBtn->HasFocus() ) {
+ if ( !bReverse && !GetEntryData( nIndex )->m_bLocked )
+ pNext = m_pEnableBtn;
+ }
+ else if ( m_pEnableBtn->HasFocus() ) {
+ if ( !bReverse )
+ pNext = m_pRemoveBtn;
+ else if ( GetEntryData( nIndex )->m_bHasOptions )
+ pNext = m_pOptionsBtn;
+ }
+ else if ( m_pRemoveBtn->HasFocus() ) {
+ if ( bReverse )
+ pNext = m_pEnableBtn;
+ }
+ else {
+ if ( !bReverse ) {
+ if ( GetEntryData( nIndex )->m_bHasOptions )
+ pNext = m_pOptionsBtn;
+ else if ( ! GetEntryData( nIndex )->m_bLocked )
+ pNext = m_pEnableBtn;
+ } else {
+ if ( ! GetEntryData( nIndex )->m_bLocked )
+ pNext = m_pRemoveBtn;
+ else if ( GetEntryData( nIndex )->m_bHasOptions )
+ pNext = m_pOptionsBtn;
+ }
+ }
+
+ if ( pNext )
+ {
+ pNext->GrabFocus();
+ return true;
+ }
+ else
+ return false;
+}
+
+// -----------------------------------------------------------------------
+MENU_COMMAND ExtBoxWithBtns_Impl::ShowPopupMenu( const Point & rPos, const long nPos )
+{
+ if ( nPos >= (long) getItemCount() )
+ return CMD_NONE;
+
+ PopupMenu aPopup;
+
+ aPopup.InsertItem( CMD_UPDATE, DialogHelper::getResourceString( RID_CTX_ITEM_CHECK_UPDATE ) );
+
+ if ( ! GetEntryData( nPos )->m_bLocked )
+ {
+ if ( GetEntryData( nPos )->m_eState == REGISTERED )
+ aPopup.InsertItem( CMD_DISABLE, DialogHelper::getResourceString( RID_CTX_ITEM_DISABLE ) );
+ else if ( GetEntryData( nPos )->m_eState != NOT_AVAILABLE )
+ aPopup.InsertItem( CMD_ENABLE, DialogHelper::getResourceString( RID_CTX_ITEM_ENABLE ) );
+
+ aPopup.InsertItem( CMD_REMOVE, DialogHelper::getResourceString( RID_CTX_ITEM_REMOVE ) );
+ }
+
+ return (MENU_COMMAND) aPopup.Execute( this, rPos );
+}
+
+//------------------------------------------------------------------------------
+void ExtBoxWithBtns_Impl::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ if ( m_bInterfaceLocked )
+ return;
+
+ const Point aMousePos( rMEvt.GetPosPixel() );
+ const long nPos = PointToPos( aMousePos );
+
+ if ( rMEvt.IsRight() )
+ {
+ switch( ShowPopupMenu( aMousePos, nPos ) )
+ {
+ case CMD_NONE: break;
+ case CMD_ENABLE: m_pParent->enablePackage( GetEntryData( nPos )->m_xPackageManager,
+ GetEntryData( nPos )->m_xPackage, true );
+ break;
+ case CMD_DISABLE: m_pParent->enablePackage( GetEntryData( nPos )->m_xPackageManager,
+ GetEntryData( nPos )->m_xPackage, false );
+ break;
+ case CMD_UPDATE: m_pParent->updatePackage( GetEntryData( nPos )->m_xPackageManager,
+ GetEntryData( nPos )->m_xPackage );
+ break;
+ case CMD_REMOVE: m_pParent->removePackage( GetEntryData( nPos )->m_xPackageManager,
+ GetEntryData( nPos )->m_xPackage );
+ break;
+ }
+ }
+ else if ( rMEvt.IsLeft() )
+ {
+ if ( rMEvt.IsMod1() && HasActive() )
+ selectEntry( EXTENSION_LISTBOX_ENTRY_NOTFOUND ); // Selecting an not existing entry will deselect the current one
+ else
+ selectEntry( nPos );
+ }
+}
+
+//------------------------------------------------------------------------------
+long ExtBoxWithBtns_Impl::Notify( NotifyEvent& rNEvt )
+{
+ bool bHandled = false;
+
+ if ( rNEvt.GetType() == EVENT_KEYINPUT )
+ {
+ const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
+ KeyCode aKeyCode = pKEvt->GetKeyCode();
+ USHORT nKeyCode = aKeyCode.GetCode();
+
+ if ( nKeyCode == KEY_TAB )
+ bHandled = HandleTabKey( aKeyCode.IsShift() );
+ }
+
+ if ( !bHandled )
+ return ExtensionBox_Impl::Notify( rNEvt );
+ else
+ return true;
+}
+
+//------------------------------------------------------------------------------
+void ExtBoxWithBtns_Impl::enableButtons( bool bEnable )
+{
+ m_bInterfaceLocked = ! bEnable;
+
+ if ( bEnable )
+ {
+ sal_Int32 nIndex = getSelIndex();
+ if ( nIndex != EXTENSION_LISTBOX_ENTRY_NOTFOUND )
+ SetButtonStatus( GetEntryData( nIndex ) );
+ }
+ else
+ {
+ m_pOptionsBtn->Enable( false );
+ m_pRemoveBtn->Enable( false );
+ m_pEnableBtn->Enable( false );
+ }
+}
+
+// -----------------------------------------------------------------------
+IMPL_LINK( ExtBoxWithBtns_Impl, ScrollHdl, ScrollBar*, pScrBar )
+{
+ long nDelta = pScrBar->GetDelta();
+
+ Point aNewOptPt( m_pOptionsBtn->GetPosPixel() - Point( 0, nDelta ) );
+ Point aNewRemPt( m_pRemoveBtn->GetPosPixel() - Point( 0, nDelta ) );
+ Point aNewEnPt( m_pEnableBtn->GetPosPixel() - Point( 0, nDelta ) );
+
+ DoScroll( nDelta );
+
+ m_pOptionsBtn->SetPosPixel( aNewOptPt );
+ m_pRemoveBtn->SetPosPixel( aNewRemPt );
+ m_pEnableBtn->SetPosPixel( aNewEnPt );
+
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+IMPL_LINK( ExtBoxWithBtns_Impl, HandleOptionsBtn, void*, EMPTYARG )
+{
+ const sal_Int32 nActive = getSelIndex();
+
+ if ( nActive != EXTENSION_LISTBOX_ENTRY_NOTFOUND )
+ {
+ SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
+
+ if ( pFact )
+ {
+ OUString sExtensionId = GetEntryData( nActive )->m_xPackage->getIdentifier().Value;
+ VclAbstractDialog* pDlg = pFact->CreateOptionsDialog( this, sExtensionId, rtl::OUString() );
+
+ pDlg->Execute();
+
+ delete pDlg;
+ }
+ }
+
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+IMPL_LINK( ExtBoxWithBtns_Impl, HandleEnableBtn, void*, EMPTYARG )
+{
+ const sal_Int32 nActive = getSelIndex();
+
+ if ( nActive != EXTENSION_LISTBOX_ENTRY_NOTFOUND )
+ {
+ TEntry_Impl pEntry = GetEntryData( nActive );
+ const bool bEnable( pEntry->m_eState != REGISTERED );
+
+ m_pParent->enablePackage( pEntry->m_xPackageManager,
+ pEntry->m_xPackage,
+ bEnable );
+ }
+
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+IMPL_LINK( ExtBoxWithBtns_Impl, HandleRemoveBtn, void*, EMPTYARG )
+{
+ const sal_Int32 nActive = getSelIndex();
+
+ if ( nActive != EXTENSION_LISTBOX_ENTRY_NOTFOUND )
+ {
+ TEntry_Impl pEntry = GetEntryData( nActive );
+ m_pParent->removePackage( pEntry->m_xPackageManager,
+ pEntry->m_xPackage );
+ }
+
+ return 1;
+}
+
+//------------------------------------------------------------------------------
+// DialogHelper
+//------------------------------------------------------------------------------
+DialogHelper::DialogHelper( const uno::Reference< uno::XComponentContext > &xContext,
+ Dialog *pWindow ) :
+ m_pVCLWindow( pWindow ),
+ m_nEventID( 0 ),
+ m_bIsBusy( false )
+{
+ m_xContext = xContext;
+}
+
+//------------------------------------------------------------------------------
+DialogHelper::~DialogHelper()
+{
+ if ( m_nEventID )
+ Application::RemoveUserEvent( m_nEventID );
+}
+
+//------------------------------------------------------------------------------
+ResId DialogHelper::getResId( USHORT nId )
+{
+ const ::vos::OGuard guard( Application::GetSolarMutex() );
+ return ResId( nId, *DeploymentGuiResMgr::get() );
+}
+
+//------------------------------------------------------------------------------
+String DialogHelper::getResourceString( USHORT id )
+{
+ // init with non-acquired solar mutex:
+ BrandName::get();
+ const ::vos::OGuard guard( Application::GetSolarMutex() );
+ String ret( ResId( id, *DeploymentGuiResMgr::get() ) );
+ if (ret.SearchAscii( "%PRODUCTNAME" ) != STRING_NOTFOUND) {
+ ret.SearchAndReplaceAllAscii( "%PRODUCTNAME", BrandName::get() );
+ }
+ return ret;
+}
+
+//------------------------------------------------------------------------------
+bool DialogHelper::IsSharedPkgMgr( const uno::Reference< deployment::XPackageManager > &xPackageManager )
+{
+ if ( xPackageManager->getContext().equals( OUSTR("shared") ) )
+ return true;
+ else
+ return false;
+}
+
+//------------------------------------------------------------------------------
+bool DialogHelper::continueOnSharedExtension( const uno::Reference< deployment::XPackageManager > &xPackageManager,
+ Window *pParent,
+ const USHORT nResID,
+ bool &bHadWarning )
+{
+ if ( !bHadWarning && IsSharedPkgMgr( xPackageManager ) )
+ {
+ const ::vos::OGuard guard( Application::GetSolarMutex() );
+ WarningBox aInfoBox( pParent, getResId( nResID ) );
+ String aMsgText = aInfoBox.GetMessText();
+ aMsgText.SearchAndReplaceAllAscii( "%PRODUCTNAME", BrandName::get() );
+ aInfoBox.SetMessText( aMsgText );
+
+ bHadWarning = true;
+
+ if ( RET_OK == aInfoBox.Execute() )
+ return true;
+ else
+ return false;
+ }
+ else
+ return true;
+}
+
+//------------------------------------------------------------------------------
+void DialogHelper::openWebBrowser( const OUString & sURL, const OUString &sTitle ) const
+{
+ if ( ! sURL.getLength() ) // Nothing to do, when the URL is empty
+ return;
+
+ try
+ {
+ uno::Reference< XSystemShellExecute > xSystemShellExecute(
+ m_xContext->getServiceManager()->createInstanceWithContext( OUSTR( "com.sun.star.system.SystemShellExecute" ), m_xContext), uno::UNO_QUERY_THROW);
+ //throws css::lang::IllegalArgumentException, css::system::SystemShellExecuteException
+ xSystemShellExecute->execute( sURL, OUString(), SystemShellExecuteFlags::DEFAULTS );
+ }
+ catch ( uno::Exception& )
+ {
+ uno::Any exc( ::cppu::getCaughtException() );
+ OUString msg( ::comphelper::anyToString( exc ) );
+ const ::vos::OGuard guard( Application::GetSolarMutex() );
+ ErrorBox aErrorBox( NULL, WB_OK, msg );
+ aErrorBox.SetText( sTitle );
+ aErrorBox.Execute();
+ }
+}
+
+//------------------------------------------------------------------------------
+bool DialogHelper::installExtensionWarn( const OUString &rExtensionName ) const
+{
+ const ::vos::OGuard guard( Application::GetSolarMutex() );
+ WarningBox aInfo( m_pVCLWindow, getResId( RID_WARNINGBOX_INSTALL_EXTENSION ) );
+
+ String sText( aInfo.GetMessText() );
+ sText.SearchAndReplaceAllAscii( "%NAME", rExtensionName );
+ aInfo.SetMessText( sText );
+
+ return ( RET_OK == aInfo.Execute() );
+}
+
+//------------------------------------------------------------------------------
+bool DialogHelper::installForAllUsers( bool &bInstallForAll ) const
+{
+ const ::vos::OGuard guard( Application::GetSolarMutex() );
+ QueryBox aQuery( m_pVCLWindow, getResId( RID_QUERYBOX_INSTALL_FOR_ALL ) );
+
+ String sMsgText = aQuery.GetMessText();
+ sMsgText.SearchAndReplaceAllAscii( "%PRODUCTNAME", BrandName::get() );
+ aQuery.SetMessText( sMsgText );
+
+ USHORT nYesBtnID = aQuery.GetButtonId( 0 );
+ USHORT nNoBtnID = aQuery.GetButtonId( 1 );
+
+ if ( nYesBtnID != BUTTONDIALOG_BUTTON_NOTFOUND )
+ aQuery.SetButtonText( nYesBtnID, getResourceString( RID_STR_INSTALL_FOR_ME ) );
+ if ( nNoBtnID != BUTTONDIALOG_BUTTON_NOTFOUND )
+ aQuery.SetButtonText( nNoBtnID, getResourceString( RID_STR_INSTALL_FOR_ALL ) );
+
+ short nRet = aQuery.Execute();
+
+ if ( nRet == RET_CANCEL )
+ return false;
+
+ bInstallForAll = ( nRet == RET_NO );
+ return true;
+}
+
+//------------------------------------------------------------------------------
+void DialogHelper::PostUserEvent( const Link& rLink, void* pCaller )
+{
+ if ( m_nEventID )
+ Application::RemoveUserEvent( m_nEventID );
+
+ m_nEventID = Application::PostUserEvent( rLink, pCaller );
+}
+
+//------------------------------------------------------------------------------
+// ExtMgrDialog
+//------------------------------------------------------------------------------
+ExtMgrDialog::ExtMgrDialog( Window *pParent, TheExtensionManager *pManager ) :
+ ModelessDialog( pParent, getResId( RID_DLG_EXTENSION_MANAGER ) ),
+ DialogHelper( pManager->getContext(), (Dialog*) this ),
+ m_aAddBtn( this, getResId( RID_EM_BTN_ADD ) ),
+ m_aUpdateBtn( this, getResId( RID_EM_BTN_CHECK_UPDATES ) ),
+ m_aCloseBtn( this, getResId( RID_EM_BTN_CLOSE ) ),
+ m_aHelpBtn( this, getResId( RID_EM_BTN_HELP ) ),
+ m_aDivider( this ),
+ m_aGetExtensions( this, getResId( RID_EM_FT_GET_EXTENSIONS ) ),
+ m_aProgressText( this, getResId( RID_EM_FT_PROGRESS ) ),
+ m_aProgressBar( this, WB_BORDER + WB_3DLOOK ),
+ m_aCancelBtn( this, getResId( RID_EM_BTN_CANCEL ) ),
+ m_sAddPackages( getResourceString( RID_STR_ADD_PACKAGES ) ),
+ m_bHasProgress( false ),
+ m_bProgressChanged( false ),
+ m_bStartProgress( false ),
+ m_bStopProgress( false ),
+ m_bUpdateWarning( false ),
+ m_bEnableWarning( false ),
+ m_bDisableWarning( false ),
+ m_bDeleteWarning( false ),
+ m_nProgress( 0 ),
+ m_pManager( pManager )
+{
+ // free local resources (RID < 256):
+ FreeResource();
+
+ m_pExtensionBox = new ExtBoxWithBtns_Impl( this, pManager );
+ m_pExtensionBox->SetHyperlinkHdl( LINK( this, ExtMgrDialog, HandleHyperlink ) );
+
+ m_aAddBtn.SetClickHdl( LINK( this, ExtMgrDialog, HandleAddBtn ) );
+ m_aUpdateBtn.SetClickHdl( LINK( this, ExtMgrDialog, HandleUpdateBtn ) );
+ m_aGetExtensions.SetClickHdl( LINK( this, ExtMgrDialog, HandleHyperlink ) );
+ m_aCancelBtn.SetClickHdl( LINK( this, ExtMgrDialog, HandleCancelBtn ) );
+
+ // resize update button
+ Size aBtnSize = m_aUpdateBtn.GetSizePixel();
+ String sTitle = m_aUpdateBtn.GetText();
+ long nWidth = m_aUpdateBtn.GetCtrlTextWidth( sTitle );
+ nWidth += 2 * m_aUpdateBtn.GetTextHeight();
+ if ( nWidth > aBtnSize.Width() )
+ m_aUpdateBtn.SetSizePixel( Size( nWidth, aBtnSize.Height() ) );
+
+ // minimum size:
+ SetMinOutputSizePixel(
+ Size( // width:
+ (3 * m_aHelpBtn.GetSizePixel().Width()) +
+ m_aUpdateBtn.GetSizePixel().Width() +
+ (5 * RSC_SP_DLG_INNERBORDER_LEFT ),
+ // height:
+ (1 * m_aHelpBtn.GetSizePixel().Height()) +
+ (1 * m_aGetExtensions.GetSizePixel().Height()) +
+ (1 * m_pExtensionBox->GetMinOutputSizePixel().Height()) +
+ (3 * RSC_SP_DLG_INNERBORDER_LEFT) ) );
+
+ m_aDivider.Show();
+ m_aProgressBar.Hide();
+
+ m_aUpdateBtn.Enable( false );
+
+ m_aTimeoutTimer.SetTimeout( 500 ); // mSec
+ m_aTimeoutTimer.SetTimeoutHdl( LINK( this, ExtMgrDialog, TimeOutHdl ) );
+}
+
+//------------------------------------------------------------------------------
+ExtMgrDialog::~ExtMgrDialog()
+{
+ m_aTimeoutTimer.Stop();
+ delete m_pExtensionBox;
+}
+
+//------------------------------------------------------------------------------
+void ExtMgrDialog::selectEntry( long nPos )
+{
+ m_pExtensionBox->selectEntry( nPos );
+}
+
+//------------------------------------------------------------------------------
+void ExtMgrDialog::setGetExtensionsURL( const ::rtl::OUString &rURL )
+{
+ m_aGetExtensions.SetURL( rURL );
+}
+
+//------------------------------------------------------------------------------
+long ExtMgrDialog::addPackageToList( const uno::Reference< deployment::XPackage > &xPackage,
+ const uno::Reference< deployment::XPackageManager > &xPackageManager )
+{
+ m_aUpdateBtn.Enable( true );
+ return m_pExtensionBox->addEntry( xPackage, xPackageManager );
+}
+
+//------------------------------------------------------------------------------
+void ExtMgrDialog::prepareChecking( const uno::Reference< deployment::XPackageManager > &xPackageManager )
+{
+ if ( xPackageManager.is() )
+ m_pExtensionBox->prepareChecking( xPackageManager );
+}
+
+//------------------------------------------------------------------------------
+void ExtMgrDialog::checkEntries()
+{
+ const ::vos::OGuard guard( Application::GetSolarMutex() );
+ m_pExtensionBox->checkEntries();
+}
+
+//------------------------------------------------------------------------------
+bool ExtMgrDialog::removeExtensionWarn( const OUString &rExtensionName ) const
+{
+ const ::vos::OGuard guard( Application::GetSolarMutex() );
+ WarningBox aInfo( const_cast< ExtMgrDialog* >(this), getResId( RID_WARNINGBOX_REMOVE_EXTENSION ) );
+
+ String sText( aInfo.GetMessText() );
+ sText.SearchAndReplaceAllAscii( "%NAME", rExtensionName );
+ aInfo.SetMessText( sText );
+
+ return ( RET_OK == aInfo.Execute() );
+}
+
+//------------------------------------------------------------------------------
+bool ExtMgrDialog::enablePackage( const uno::Reference< deployment::XPackageManager > &xPackageManager,
+ const uno::Reference< deployment::XPackage > &xPackage,
+ bool bEnable )
+{
+ if ( !xPackageManager.is() || !xPackage.is() )
+ return false;
+
+ if ( bEnable )
+ {
+ if ( ! continueOnSharedExtension( xPackageManager, this, RID_WARNINGBOX_ENABLE_SHARED_EXTENSION, m_bEnableWarning ) )
+ return false;
+ }
+ else
+ {
+ if ( ! continueOnSharedExtension( xPackageManager, this, RID_WARNINGBOX_DISABLE_SHARED_EXTENSION, m_bDisableWarning ) )
+ return false;
+ }
+
+ m_pManager->enablePackage( xPackage, bEnable );
+
+ return true;
+}
+
+//------------------------------------------------------------------------------
+bool ExtMgrDialog::removePackage( const uno::Reference< deployment::XPackageManager > &xPackageManager,
+ const uno::Reference< deployment::XPackage > &xPackage )
+{
+ if ( !xPackageManager.is() || !xPackage.is() )
+ return false;
+
+ if ( !IsSharedPkgMgr( xPackageManager ) || m_bDeleteWarning )
+ {
+ if ( ! removeExtensionWarn( xPackage->getDisplayName() ) )
+ return false;
+ }
+
+ if ( ! continueOnSharedExtension( xPackageManager, this, RID_WARNINGBOX_REMOVE_SHARED_EXTENSION, m_bDeleteWarning ) )
+ return false;
+
+ m_pManager->removePackage( xPackageManager, xPackage );
+
+ return true;
+}
+
+//------------------------------------------------------------------------------
+bool ExtMgrDialog::updatePackage( const uno::Reference< deployment::XPackageManager > &xPackageManager,
+ const uno::Reference< deployment::XPackage > &xPackage )
+{
+ if ( !xPackageManager.is() || !xPackage.is() )
+ return false;
+
+ std::vector< TUpdateListEntry > vEntries;
+ TUpdateListEntry pEntry( new UpdateListEntry( xPackage, xPackageManager ) );
+ vEntries.push_back( pEntry );
+
+ m_pManager->updatePackages( vEntries );
+
+ return true;
+}
+
+//------------------------------------------------------------------------------
+uno::Sequence< OUString > ExtMgrDialog::raiseAddPicker( const uno::Reference< deployment::XPackageManager > &xPackageManager )
+{
+ const uno::Any mode( static_cast< sal_Int16 >( ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE ) );
+ const uno::Reference< uno::XComponentContext > xContext( m_pManager->getContext() );
+ const uno::Reference< ui::dialogs::XFilePicker > xFilePicker(
+ xContext->getServiceManager()->createInstanceWithArgumentsAndContext(
+ OUSTR("com.sun.star.ui.dialogs.FilePicker"),
+ uno::Sequence< uno::Any >( &mode, 1 ), xContext ), uno::UNO_QUERY_THROW );
+ xFilePicker->setTitle( m_sAddPackages );
+
+ if ( m_sLastFolderURL.Len() )
+ xFilePicker->setDisplayDirectory( m_sLastFolderURL );
+
+ // collect and set filter list:
+ typedef ::std::map< OUString, OUString > t_string2string;
+ t_string2string title2filter;
+ OUString sDefaultFilter( StrAllFiles::get() );
+
+ const uno::Sequence< uno::Reference< deployment::XPackageTypeInfo > > packageTypes( xPackageManager->getSupportedPackageTypes() );
+
+ for ( sal_Int32 pos = 0; pos < packageTypes.getLength(); ++pos )
+ {
+ uno::Reference< deployment::XPackageTypeInfo > const & xPackageType = packageTypes[ pos ];
+ const OUString filter( xPackageType->getFileFilter() );
+ if (filter.getLength() > 0)
+ {
+ const OUString title( xPackageType->getShortDescription() );
+ const ::std::pair< t_string2string::iterator, bool > insertion(
+ title2filter.insert( t_string2string::value_type( title, filter ) ) );
+ if ( ! insertion.second )
+ { // already existing, append extensions:
+ ::rtl::OUStringBuffer buf;
+ buf.append( insertion.first->second );
+ buf.append( static_cast<sal_Unicode>(';') );
+ buf.append( filter );
+ insertion.first->second = buf.makeStringAndClear();
+ }
+ if ( xPackageType->getMediaType() == OUSTR( "application/vnd.sun.star.package-bundle" ) )
+ sDefaultFilter = title;
+ }
+ }
+
+ const uno::Reference< ui::dialogs::XFilterManager > xFilterManager( xFilePicker, uno::UNO_QUERY_THROW );
+ // All files at top:
+ xFilterManager->appendFilter( StrAllFiles::get(), OUSTR("*.*") );
+ // then supported ones:
+ t_string2string::const_iterator iPos( title2filter.begin() );
+ const t_string2string::const_iterator iEnd( title2filter.end() );
+ for ( ; iPos != iEnd; ++iPos ) {
+ try {
+ xFilterManager->appendFilter( iPos->first, iPos->second );
+ }
+ catch (lang::IllegalArgumentException & exc) {
+ OSL_ENSURE( 0, ::rtl::OUStringToOString(
+ exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
+ (void) exc;
+ }
+ }
+ xFilterManager->setCurrentFilter( sDefaultFilter );
+
+ if ( xFilePicker->execute() != ui::dialogs::ExecutableDialogResults::OK )
+ return uno::Sequence<OUString>(); // cancelled
+
+ m_sLastFolderURL = xFilePicker->getDisplayDirectory();
+ uno::Sequence< OUString > files( xFilePicker->getFiles() );
+ OSL_ASSERT( files.getLength() > 0 );
+ return files;
+}
+
+//------------------------------------------------------------------------------
+IMPL_LINK( ExtMgrDialog, HandleCancelBtn, void*, EMPTYARG )
+{
+ // m_dialog->m_cmdEnv->m_aborted = true;
+ if ( m_xAbortChannel.is() )
+ {
+ try
+ {
+ m_xAbortChannel->sendAbort();
+ }
+ catch ( uno::RuntimeException & )
+ {
+ OSL_ENSURE( 0, "### unexpected RuntimeException!" );
+ }
+ }
+ return 1;
+}
+
+// ------------------------------------------------------------------------------
+IMPL_LINK( ExtMgrDialog, startProgress, void*, _bLockInterface )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ bool bLockInterface = (bool) _bLockInterface;
+
+ if ( m_bStartProgress && !m_bHasProgress )
+ m_aTimeoutTimer.Start();
+
+ if ( m_bStopProgress )
+ {
+ if ( m_aProgressBar.IsVisible() )
+ m_aProgressBar.SetValue( 100 );
+ m_xAbortChannel.clear();
+
+ OSL_TRACE( " startProgress handler: stop\n" );
+ }
+ else
+ {
+ OSL_TRACE( " startProgress handler: start\n" );
+ }
+
+ m_aCancelBtn.Enable( bLockInterface );
+ m_aAddBtn.Enable( !bLockInterface );
+ m_aUpdateBtn.Enable( !bLockInterface && m_pExtensionBox->getItemCount() );
+ m_pExtensionBox->enableButtons( !bLockInterface );
+
+ clearEventID();
+
+ return 0;
+}
+
+// ------------------------------------------------------------------------------
+void ExtMgrDialog::showProgress( bool _bStart )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ bool bStart = _bStart;
+
+ if ( bStart )
+ {
+ m_nProgress = 0;
+ m_bStartProgress = true;
+ OSL_TRACE( "showProgress start\n" );
+ }
+ else
+ {
+ m_nProgress = 100;
+ m_bStopProgress = true;
+ OSL_TRACE( "showProgress stop!\n" );
+ }
+
+ DialogHelper::PostUserEvent( LINK( this, ExtMgrDialog, startProgress ), (void*) bStart );
+}
+
+// -----------------------------------------------------------------------
+void ExtMgrDialog::updateProgress( const long nProgress )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ m_nProgress = nProgress;
+}
+
+// -----------------------------------------------------------------------
+void ExtMgrDialog::updateProgress( const OUString &rText,
+ const uno::Reference< task::XAbortChannel > &xAbortChannel)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ m_xAbortChannel = xAbortChannel;
+ m_sProgressText = rText;
+ m_bProgressChanged = true;
+}
+
+//------------------------------------------------------------------------------
+void ExtMgrDialog::updatePackageInfo( const uno::Reference< deployment::XPackage > &xPackage )
+{
+ m_pExtensionBox->updateEntry( xPackage );
+}
+
+// -----------------------------------------------------------------------
+IMPL_LINK( ExtMgrDialog, HandleAddBtn, void*, EMPTYARG )
+{
+ setBusy( true );
+
+ uno::Reference< deployment::XPackageManager > xUserPkgMgr = m_pManager->getUserPkgMgr();
+ uno::Sequence< OUString > aFileList = raiseAddPicker( xUserPkgMgr );
+
+ if ( aFileList.getLength() )
+ {
+ m_pManager->installPackage( aFileList[0] );
+ }
+
+ setBusy( false );
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+IMPL_LINK( ExtMgrDialog, HandleUpdateBtn, void*, EMPTYARG )
+{
+ m_pManager->checkUpdates( false, true );
+
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+IMPL_LINK( ExtMgrDialog, HandleHyperlink, svt::FixedHyperlink*, pHyperlink )
+{
+ openWebBrowser( pHyperlink->GetURL(), GetText() );
+
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+IMPL_LINK( ExtMgrDialog, TimeOutHdl, Timer*, EMPTYARG )
+{
+ if ( m_bStopProgress )
+ {
+ m_bHasProgress = false;
+ m_bStopProgress = false;
+ m_aProgressText.Hide();
+ m_aProgressBar.Hide();
+ m_aCancelBtn.Hide();
+ }
+ else
+ {
+ if ( m_bProgressChanged )
+ {
+ m_bProgressChanged = false;
+ m_aProgressText.SetText( m_sProgressText );
+ }
+
+ if ( m_bStartProgress )
+ {
+ m_bStartProgress = false;
+ m_bHasProgress = true;
+ m_aProgressBar.Show();
+ m_aProgressText.Show();
+ m_aCancelBtn.Enable();
+ m_aCancelBtn.Show();
+ }
+
+ if ( m_aProgressBar.IsVisible() )
+ m_aProgressBar.SetValue( (USHORT) m_nProgress );
+
+ m_aTimeoutTimer.Start();
+ }
+
+ return 1;
+}
+
+//------------------------------------------------------------------------------
+// VCL::Window / Dialog
+void ExtMgrDialog::Resize()
+{
+ Size aTotalSize( GetOutputSizePixel() );
+ Size aBtnSize( m_aHelpBtn.GetSizePixel() );
+ Size aUpdBtnSize( m_aUpdateBtn.GetSizePixel() );
+
+ Point aPos( RSC_SP_DLG_INNERBORDER_LEFT,
+ aTotalSize.Height() - RSC_SP_DLG_INNERBORDER_BOTTOM - aBtnSize.Height() );
+
+ m_aHelpBtn.SetPosPixel( aPos );
+
+ aPos.X() = aTotalSize.Width() - RSC_SP_DLG_INNERBORDER_RIGHT - aBtnSize.Width();
+ m_aCloseBtn.SetPosPixel( aPos );
+
+ aPos.X() -= ( RSC_SP_CTRL_X + aUpdBtnSize.Width() );
+ m_aUpdateBtn.SetPosPixel( aPos );
+
+ aPos.X() -= ( RSC_SP_CTRL_GROUP_Y + aBtnSize.Width() );
+ m_aAddBtn.SetPosPixel( aPos );
+
+ Size aDivSize( aTotalSize.Width(), LINE_SIZE );
+ aPos = Point( 0, aPos.Y() - LINE_SIZE - RSC_SP_DLG_INNERBORDER_BOTTOM );
+ m_aDivider.SetPosSizePixel( aPos, aDivSize );
+
+ Size aFTSize( m_aGetExtensions.CalcMinimumSize() );
+ aPos = Point( RSC_SP_DLG_INNERBORDER_LEFT, aPos.Y() - RSC_CD_FIXEDTEXT_HEIGHT - 2*RSC_SP_DLG_INNERBORDER_BOTTOM );
+
+ m_aGetExtensions.SetPosSizePixel( aPos, aFTSize );
+
+ aPos.X() = aTotalSize.Width() - RSC_SP_DLG_INNERBORDER_RIGHT - aBtnSize.Width();
+ m_aCancelBtn.SetPosPixel( Point( aPos.X(), aPos.Y() - ((aBtnSize.Height()-aFTSize.Height())/2) ) );
+
+ // Calc progress height
+ long nProgressHeight = aFTSize.Height();
+
+ if( IsNativeControlSupported( CTRL_PROGRESS, PART_ENTIRE_CONTROL ) )
+ {
+ ImplControlValue aValue;
+ bool bNativeOK;
+ Region aControlRegion( Rectangle( (const Point&)Point(), m_aProgressBar.GetSizePixel() ) );
+ Region aNativeControlRegion, aNativeContentRegion;
+ if( (bNativeOK = GetNativeControlRegion( CTRL_PROGRESS, PART_ENTIRE_CONTROL, aControlRegion,
+ CTRL_STATE_ENABLED, aValue, rtl::OUString(),
+ aNativeControlRegion, aNativeContentRegion ) ) != FALSE )
+ {
+ nProgressHeight = aNativeControlRegion.GetBoundRect().GetHeight();
+ }
+ }
+
+ if ( nProgressHeight < PROGRESS_HEIGHT )
+ nProgressHeight = PROGRESS_HEIGHT;
+
+ aPos.X() -= ( RSC_SP_CTRL_GROUP_Y + PROGRESS_WIDTH );
+ m_aProgressBar.SetPosSizePixel( Point( aPos.X(), aPos.Y() - ((nProgressHeight-aFTSize.Height())/2) ),
+ Size( PROGRESS_WIDTH, nProgressHeight ) );
+
+ Rectangle aRect1( m_aGetExtensions.GetPosPixel(), m_aGetExtensions.GetSizePixel() );
+ Rectangle aRect2( m_aProgressBar.GetPosPixel(), m_aProgressBar.GetSizePixel() );
+
+ aFTSize.Width() = ( aRect2.Left() - aRect1.Right() ) - 2*RSC_SP_DLG_INNERBORDER_LEFT;
+ aPos.X() = aRect1.Right() + RSC_SP_DLG_INNERBORDER_LEFT;
+ m_aProgressText.SetPosSizePixel( aPos, aFTSize );
+
+ Size aSize( aTotalSize.Width() - RSC_SP_DLG_INNERBORDER_LEFT - RSC_SP_DLG_INNERBORDER_RIGHT,
+ aTotalSize.Height() - 2*aBtnSize.Height() - LINE_SIZE -
+ RSC_SP_DLG_INNERBORDER_TOP - 3*RSC_SP_DLG_INNERBORDER_BOTTOM );
+
+ m_pExtensionBox->SetSizePixel( aSize );
+}
+//------------------------------------------------------------------------------
+// VCL::Window / Dialog
+
+long ExtMgrDialog::Notify( NotifyEvent& rNEvt )
+{
+ bool bHandled = false;
+
+ if ( rNEvt.GetType() == EVENT_KEYINPUT )
+ {
+ const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
+ KeyCode aKeyCode = pKEvt->GetKeyCode();
+ USHORT nKeyCode = aKeyCode.GetCode();
+
+ if ( nKeyCode == KEY_TAB )
+ {
+ if ( aKeyCode.IsShift() ) {
+ if ( m_aAddBtn.HasFocus() ) {
+ m_pExtensionBox->GrabFocus();
+ bHandled = true;
+ }
+ } else {
+ if ( m_aGetExtensions.HasFocus() ) {
+ m_pExtensionBox->GrabFocus();
+ bHandled = true;
+ }
+ }
+ }
+ if ( aKeyCode.GetGroup() == KEYGROUP_CURSOR )
+ bHandled = m_pExtensionBox->Notify( rNEvt );
+ }
+// VCLEVENT_WINDOW_CLOSE
+ if ( !bHandled )
+ return ModelessDialog::Notify( rNEvt );
+ else
+ return true;
+}
+
+//------------------------------------------------------------------------------
+BOOL ExtMgrDialog::Close()
+{
+ bool bRet = m_pManager->queryTermination();
+ if ( bRet )
+ {
+ bRet = ModelessDialog::Close();
+ m_pManager->terminateDialog();
+ }
+ return bRet;
+}
+
+//------------------------------------------------------------------------------
+// UpdateRequiredDialog
+//------------------------------------------------------------------------------
+UpdateRequiredDialog::UpdateRequiredDialog( Window *pParent, TheExtensionManager *pManager ) :
+ ModalDialog( pParent, getResId( RID_DLG_UPDATE_REQUIRED ) ),
+ DialogHelper( pManager->getContext(), (Dialog*) this ),
+ m_aUpdateNeeded( this, getResId( RID_EM_FT_MSG ) ),
+ m_aUpdateBtn( this, getResId( RID_EM_BTN_CHECK_UPDATES ) ),
+ m_aCloseBtn( this, getResId( RID_EM_BTN_CLOSE ) ),
+ m_aHelpBtn( this, getResId( RID_EM_BTN_HELP ) ),
+ m_aCancelBtn( this, getResId( RID_EM_BTN_CANCEL ) ),
+ m_aDivider( this ),
+ m_aProgressText( this, getResId( RID_EM_FT_PROGRESS ) ),
+ m_aProgressBar( this, WB_BORDER + WB_3DLOOK ),
+ m_sAddPackages( getResourceString( RID_STR_ADD_PACKAGES ) ),
+ m_sCloseText( getResourceString( RID_STR_CLOSE_BTN ) ),
+ m_bHasProgress( false ),
+ m_bProgressChanged( false ),
+ m_bStartProgress( false ),
+ m_bStopProgress( false ),
+ m_bUpdateWarning( false ),
+ m_bDisableWarning( false ),
+ m_bHasLockedEntries( false ),
+ m_nProgress( 0 ),
+ m_pManager( pManager )
+{
+ // free local resources (RID < 256):
+ FreeResource();
+
+ m_pExtensionBox = new ExtensionBox_Impl( this, pManager );
+ m_pExtensionBox->SetHyperlinkHdl( LINK( this, UpdateRequiredDialog, HandleHyperlink ) );
+
+ m_aUpdateBtn.SetClickHdl( LINK( this, UpdateRequiredDialog, HandleUpdateBtn ) );
+ m_aCloseBtn.SetClickHdl( LINK( this, UpdateRequiredDialog, HandleCloseBtn ) );
+ m_aCancelBtn.SetClickHdl( LINK( this, UpdateRequiredDialog, HandleCancelBtn ) );
+
+ String aText = m_aUpdateNeeded.GetText();
+ aText.SearchAndReplaceAllAscii( "%PRODUCTNAME", BrandName::get() );
+ m_aUpdateNeeded.SetText( aText );
+
+ // resize update button
+ Size aBtnSize = m_aUpdateBtn.GetSizePixel();
+ String sTitle = m_aUpdateBtn.GetText();
+ long nWidth = m_aUpdateBtn.GetCtrlTextWidth( sTitle );
+ nWidth += 2 * m_aUpdateBtn.GetTextHeight();
+ if ( nWidth > aBtnSize.Width() )
+ m_aUpdateBtn.SetSizePixel( Size( nWidth, aBtnSize.Height() ) );
+
+ // resize update button
+ aBtnSize = m_aCloseBtn.GetSizePixel();
+ sTitle = m_aCloseBtn.GetText();
+ nWidth = m_aCloseBtn.GetCtrlTextWidth( sTitle );
+ nWidth += 2 * m_aCloseBtn.GetTextHeight();
+ if ( nWidth > aBtnSize.Width() )
+ m_aCloseBtn.SetSizePixel( Size( nWidth, aBtnSize.Height() ) );
+
+ // minimum size:
+ SetMinOutputSizePixel(
+ Size( // width:
+ (5 * m_aHelpBtn.GetSizePixel().Width()) +
+ (5 * RSC_SP_DLG_INNERBORDER_LEFT ),
+ // height:
+ (1 * m_aHelpBtn.GetSizePixel().Height()) +
+ (1 * m_aUpdateNeeded.GetSizePixel().Height()) +
+ (1 * m_pExtensionBox->GetMinOutputSizePixel().Height()) +
+ (3 * RSC_SP_DLG_INNERBORDER_LEFT) ) );
+
+ m_aDivider.Show();
+ m_aProgressBar.Hide();
+ m_aUpdateBtn.Enable( false );
+ m_aCloseBtn.GrabFocus();
+
+ m_aTimeoutTimer.SetTimeout( 50 ); // mSec
+ m_aTimeoutTimer.SetTimeoutHdl( LINK( this, UpdateRequiredDialog, TimeOutHdl ) );
+}
+
+//------------------------------------------------------------------------------
+UpdateRequiredDialog::~UpdateRequiredDialog()
+{
+ m_aTimeoutTimer.Stop();
+
+ delete m_pExtensionBox;
+}
+
+//------------------------------------------------------------------------------
+long UpdateRequiredDialog::addPackageToList( const uno::Reference< deployment::XPackage > &xPackage,
+ const uno::Reference< deployment::XPackageManager > &xPackageManager )
+{
+ // We will only add entries to the list with unsatisfied dependencies
+ if ( !checkDependencies( xPackage ) )
+ {
+ m_bHasLockedEntries |= (bool) xPackageManager->isReadOnly();
+ m_aUpdateBtn.Enable( true );
+ return m_pExtensionBox->addEntry( xPackage, xPackageManager );
+ }
+ return 0;
+}
+
+//------------------------------------------------------------------------------
+void UpdateRequiredDialog::prepareChecking( const uno::Reference< deployment::XPackageManager > &xPackageManager )
+{
+ if ( xPackageManager.is() )
+ m_pExtensionBox->prepareChecking( xPackageManager );
+}
+
+//------------------------------------------------------------------------------
+void UpdateRequiredDialog::checkEntries()
+{
+ const ::vos::OGuard guard( Application::GetSolarMutex() );
+ m_pExtensionBox->checkEntries();
+
+ if ( ! hasActiveEntries() )
+ {
+ m_aCloseBtn.SetText( m_sCloseText );
+ m_aCloseBtn.GrabFocus();
+ }
+}
+
+//------------------------------------------------------------------------------
+bool UpdateRequiredDialog::enablePackage( const uno::Reference< deployment::XPackageManager > &,
+ const uno::Reference< deployment::XPackage > &xPackage,
+ bool bEnable )
+{
+ m_pManager->enablePackage( xPackage, bEnable );
+
+ return true;
+}
+
+//------------------------------------------------------------------------------
+IMPL_LINK( UpdateRequiredDialog, HandleCancelBtn, void*, EMPTYARG )
+{
+ // m_dialog->m_cmdEnv->m_aborted = true;
+ if ( m_xAbortChannel.is() )
+ {
+ try
+ {
+ m_xAbortChannel->sendAbort();
+ }
+ catch ( uno::RuntimeException & )
+ {
+ OSL_ENSURE( 0, "### unexpected RuntimeException!" );
+ }
+ }
+ return 1;
+}
+
+// ------------------------------------------------------------------------------
+IMPL_LINK( UpdateRequiredDialog, startProgress, void*, _bLockInterface )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ bool bLockInterface = (bool) _bLockInterface;
+
+ if ( m_bStartProgress && !m_bHasProgress )
+ m_aTimeoutTimer.Start();
+
+ if ( m_bStopProgress )
+ {
+ if ( m_aProgressBar.IsVisible() )
+ m_aProgressBar.SetValue( 100 );
+ m_xAbortChannel.clear();
+ OSL_TRACE( " startProgress handler: stop\n" );
+ }
+ else
+ {
+ OSL_TRACE( " startProgress handler: start\n" );
+ }
+
+ m_aCancelBtn.Enable( bLockInterface );
+ m_aUpdateBtn.Enable( false );
+ clearEventID();
+
+ return 0;
+}
+
+// ------------------------------------------------------------------------------
+void UpdateRequiredDialog::showProgress( bool _bStart )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ bool bStart = _bStart;
+
+ if ( bStart )
+ {
+ m_nProgress = 0;
+ m_bStartProgress = true;
+ OSL_TRACE( "showProgress start\n" );
+ }
+ else
+ {
+ m_nProgress = 100;
+ m_bStopProgress = true;
+ OSL_TRACE( "showProgress stop!\n" );
+ }
+
+ DialogHelper::PostUserEvent( LINK( this, UpdateRequiredDialog, startProgress ), (void*) bStart );
+}
+
+// -----------------------------------------------------------------------
+void UpdateRequiredDialog::updateProgress( const long nProgress )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ m_nProgress = nProgress;
+}
+
+// -----------------------------------------------------------------------
+void UpdateRequiredDialog::updateProgress( const OUString &rText,
+ const uno::Reference< task::XAbortChannel > &xAbortChannel)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ m_xAbortChannel = xAbortChannel;
+ m_sProgressText = rText;
+ m_bProgressChanged = true;
+}
+
+//------------------------------------------------------------------------------
+void UpdateRequiredDialog::updatePackageInfo( const uno::Reference< deployment::XPackage > &xPackage )
+{
+ // We will remove all updated packages with satisfied dependencies, but
+ // we will show all disabled entries so the user sees the result
+ // of the 'disable all' button
+ if ( isEnabled( xPackage ) && checkDependencies( xPackage ) )
+ m_pExtensionBox->removeEntry( xPackage );
+ else
+ m_pExtensionBox->updateEntry( xPackage );
+
+ if ( ! hasActiveEntries() )
+ {
+ m_aCloseBtn.SetText( m_sCloseText );
+ m_aCloseBtn.GrabFocus();
+ }
+}
+
+// -----------------------------------------------------------------------
+IMPL_LINK( UpdateRequiredDialog, HandleUpdateBtn, void*, EMPTYARG )
+{
+ ::osl::ClearableMutexGuard aGuard( m_aMutex );
+
+ std::vector< TUpdateListEntry > vUpdateEntries;
+ sal_Int32 nCount = m_pExtensionBox->GetEntryCount();
+
+ for ( sal_Int32 i = 0; i < nCount; ++i )
+ {
+ TEntry_Impl pEntry = m_pExtensionBox->GetEntryData( i );
+ TUpdateListEntry pUpdateEntry( new UpdateListEntry( pEntry->m_xPackage,
+ pEntry->m_xPackageManager ) );
+ vUpdateEntries.push_back( pUpdateEntry );
+ }
+
+ aGuard.clear();
+
+ m_pManager->updatePackages( vUpdateEntries );
+
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+IMPL_LINK( UpdateRequiredDialog, HandleCloseBtn, void*, EMPTYARG )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( !isBusy() )
+ {
+ if ( m_bHasLockedEntries )
+ EndDialog( -1 );
+ else if ( hasActiveEntries() )
+ disableAllEntries();
+ else
+ EndDialog( 0 );
+ }
+
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+IMPL_LINK( UpdateRequiredDialog, HandleHyperlink, svt::FixedHyperlink*, pHyperlink )
+{
+ openWebBrowser( pHyperlink->GetURL(), GetText() );
+
+ return 1;
+}
+
+// -----------------------------------------------------------------------
+IMPL_LINK( UpdateRequiredDialog, TimeOutHdl, Timer*, EMPTYARG )
+{
+ if ( m_bStopProgress )
+ {
+ m_bHasProgress = false;
+ m_bStopProgress = false;
+ m_aProgressText.Hide();
+ m_aProgressBar.Hide();
+ m_aCancelBtn.Hide();
+ }
+ else
+ {
+ if ( m_bProgressChanged )
+ {
+ m_bProgressChanged = false;
+ m_aProgressText.SetText( m_sProgressText );
+ }
+
+ if ( m_bStartProgress )
+ {
+ m_bStartProgress = false;
+ m_bHasProgress = true;
+ m_aProgressBar.Show();
+ m_aProgressText.Show();
+ m_aCancelBtn.Enable();
+ m_aCancelBtn.Show();
+ }
+
+ if ( m_aProgressBar.IsVisible() )
+ m_aProgressBar.SetValue( (USHORT) m_nProgress );
+
+ m_aTimeoutTimer.Start();
+ }
+
+ return 1;
+}
+
+//------------------------------------------------------------------------------
+// VCL::Window / Dialog
+void UpdateRequiredDialog::Resize()
+{
+ Size aTotalSize( GetOutputSizePixel() );
+ Size aBtnSize( m_aHelpBtn.GetSizePixel() );
+
+ Point aPos( RSC_SP_DLG_INNERBORDER_LEFT,
+ aTotalSize.Height() - RSC_SP_DLG_INNERBORDER_BOTTOM - aBtnSize.Height() );
+
+ m_aHelpBtn.SetPosPixel( aPos );
+
+ aPos.X() = aTotalSize.Width() - RSC_SP_DLG_INNERBORDER_RIGHT - m_aCloseBtn.GetSizePixel().Width();
+ m_aCloseBtn.SetPosPixel( aPos );
+
+ aPos.X() -= ( RSC_SP_CTRL_X + m_aUpdateBtn.GetSizePixel().Width() );
+ m_aUpdateBtn.SetPosPixel( aPos );
+
+ Size aDivSize( aTotalSize.Width(), LINE_SIZE );
+ aPos = Point( 0, aPos.Y() - LINE_SIZE - RSC_SP_DLG_INNERBORDER_BOTTOM );
+ m_aDivider.SetPosSizePixel( aPos, aDivSize );
+
+ // Calc fixed text size
+ aPos = Point( RSC_SP_DLG_INNERBORDER_LEFT, RSC_SP_DLG_INNERBORDER_TOP );
+ Size aFTSize = m_aUpdateNeeded.CalcMinimumSize( aTotalSize.Width() - RSC_SP_DLG_INNERBORDER_RIGHT - RSC_SP_DLG_INNERBORDER_LEFT );
+ m_aUpdateNeeded.SetPosSizePixel( aPos, aFTSize );
+
+ // Calc list box size
+ Size aSize( aTotalSize.Width() - RSC_SP_DLG_INNERBORDER_LEFT - RSC_SP_DLG_INNERBORDER_RIGHT,
+ aTotalSize.Height() - 2*aBtnSize.Height() - LINE_SIZE -
+ 2*RSC_SP_DLG_INNERBORDER_TOP - 3*RSC_SP_DLG_INNERBORDER_BOTTOM - aFTSize.Height() );
+ aPos.Y() += aFTSize.Height()+RSC_SP_DLG_INNERBORDER_TOP;
+
+ m_pExtensionBox->SetPosSizePixel( aPos, aSize );
+
+ aPos.X() = aTotalSize.Width() - RSC_SP_DLG_INNERBORDER_RIGHT - aBtnSize.Width();
+ aPos.Y() += aSize.Height()+RSC_SP_DLG_INNERBORDER_TOP;
+ m_aCancelBtn.SetPosPixel( aPos );
+
+ // Calc progress height
+ aFTSize = m_aProgressText.GetSizePixel();
+ long nProgressHeight = aFTSize.Height();
+
+ if( IsNativeControlSupported( CTRL_PROGRESS, PART_ENTIRE_CONTROL ) )
+ {
+ ImplControlValue aValue;
+ bool bNativeOK;
+ Region aControlRegion( Rectangle( (const Point&)Point(), m_aProgressBar.GetSizePixel() ) );
+ Region aNativeControlRegion, aNativeContentRegion;
+ if( (bNativeOK = GetNativeControlRegion( CTRL_PROGRESS, PART_ENTIRE_CONTROL, aControlRegion,
+ CTRL_STATE_ENABLED, aValue, rtl::OUString(),
+ aNativeControlRegion, aNativeContentRegion ) ) != FALSE )
+ {
+ nProgressHeight = aNativeControlRegion.GetBoundRect().GetHeight();
+ }
+ }
+
+ if ( nProgressHeight < PROGRESS_HEIGHT )
+ nProgressHeight = PROGRESS_HEIGHT;
+
+ aPos.X() -= ( RSC_SP_CTRL_GROUP_Y + PROGRESS_WIDTH );
+ m_aProgressBar.SetPosSizePixel( Point( aPos.X(), aPos.Y() + ((aBtnSize.Height()-nProgressHeight)/2) ),
+ Size( PROGRESS_WIDTH, nProgressHeight ) );
+
+ aFTSize.Width() = aPos.X() - 2*RSC_SP_DLG_INNERBORDER_LEFT;
+ aPos.X() = RSC_SP_DLG_INNERBORDER_LEFT;
+ aPos.Y() += ( aBtnSize.Height() - aFTSize.Height() - 1 ) / 2;
+ m_aProgressText.SetPosSizePixel( aPos, aFTSize );
+}
+
+//------------------------------------------------------------------------------
+// VCL::Dialog
+short UpdateRequiredDialog::Execute()
+{
+ if ( m_bHasLockedEntries )
+ {
+ // Set other text, disable update btn, remove not shared entries from list;
+ m_aUpdateNeeded.SetText( DialogHelper::getResourceString( RID_STR_NO_ADMIN_PRIVILEGE ) );
+ m_aCloseBtn.SetText( DialogHelper::getResourceString( RID_STR_EXIT_BTN ) );
+ m_aUpdateBtn.Enable( false );
+ m_pExtensionBox->RemoveUnlocked();
+ Resize();
+ }
+
+ return Dialog::Execute();
+}
+
+//------------------------------------------------------------------------------
+// VCL::Dialog
+BOOL UpdateRequiredDialog::Close()
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( !isBusy() )
+ {
+ if ( m_bHasLockedEntries )
+ EndDialog( -1 );
+ else if ( hasActiveEntries() )
+ disableAllEntries();
+ else
+ EndDialog( 0 );
+ }
+
+ return false;
+}
+
+//------------------------------------------------------------------------------
+// Check dependencies of all packages
+//------------------------------------------------------------------------------
+bool UpdateRequiredDialog::isEnabled( const uno::Reference< deployment::XPackage > &xPackage ) const
+{
+ bool bRegistered = false;
+ try {
+ beans::Optional< beans::Ambiguous< sal_Bool > > option( xPackage->isRegistered( uno::Reference< task::XAbortChannel >(),
+ uno::Reference< ucb::XCommandEnvironment >() ) );
+ if ( option.IsPresent )
+ {
+ ::beans::Ambiguous< sal_Bool > const & reg = option.Value;
+ if ( reg.IsAmbiguous )
+ bRegistered = false;
+ else
+ bRegistered = reg.Value ? true : false;
+ }
+ else
+ bRegistered = false;
+ }
+ catch ( uno::RuntimeException & ) { throw; }
+ catch ( uno::Exception & exc) {
+ (void) exc;
+ OSL_ENSURE( 0, ::rtl::OUStringToOString( exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
+ bRegistered = false;
+ }
+
+ return bRegistered;
+}
+
+//------------------------------------------------------------------------------
+bool UpdateRequiredDialog::checkDependencies( const uno::Reference< deployment::XPackage > &xPackage ) const
+{
+ if ( isEnabled( xPackage ) )
+ {
+ bool bDependenciesValid = false;
+ try {
+ bDependenciesValid = xPackage->checkDependencies( uno::Reference< ucb::XCommandEnvironment >() );
+ }
+ catch ( deployment::DeploymentException & ) {}
+ if ( ! bDependenciesValid )
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+//------------------------------------------------------------------------------
+bool UpdateRequiredDialog::hasActiveEntries()
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ bool bRet = false;
+ long nCount = m_pExtensionBox->GetEntryCount();
+ for ( long nIndex = 0; nIndex < nCount; nIndex++ )
+ {
+ TEntry_Impl pEntry = m_pExtensionBox->GetEntryData( nIndex );
+
+ if ( !checkDependencies( pEntry->m_xPackage ) )
+ {
+ bRet = true;
+ break;
+ }
+ }
+
+ return bRet;
+}
+
+//------------------------------------------------------------------------------
+void UpdateRequiredDialog::disableAllEntries()
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ setBusy( true );
+
+ long nCount = m_pExtensionBox->GetEntryCount();
+ for ( long nIndex = 0; nIndex < nCount; nIndex++ )
+ {
+ TEntry_Impl pEntry = m_pExtensionBox->GetEntryData( nIndex );
+ enablePackage( pEntry->m_xPackageManager, pEntry->m_xPackage, false );
+ }
+
+ setBusy( false );
+
+ if ( ! hasActiveEntries() )
+ m_aCloseBtn.SetText( m_sCloseText );
+}
+
+//=================================================================================
+// UpdateRequiredDialogService
+//=================================================================================
+UpdateRequiredDialogService::UpdateRequiredDialogService( uno::Sequence< uno::Any > const&,
+ uno::Reference< uno::XComponentContext > const& xComponentContext )
+ : m_xComponentContext( xComponentContext )
+{
+}
+
+//------------------------------------------------------------------------------
+// XExecutableDialog
+//------------------------------------------------------------------------------
+void UpdateRequiredDialogService::setTitle( OUString const & ) throw ( uno::RuntimeException )
+{
+}
+
+//------------------------------------------------------------------------------
+sal_Int16 UpdateRequiredDialogService::execute() throw ( uno::RuntimeException )
+{
+ ::rtl::Reference< ::dp_gui::TheExtensionManager > xManager( TheExtensionManager::get(
+ m_xComponentContext,
+ uno::Reference< awt::XWindow >(),
+ OUString() ) );
+ xManager->createDialog( true );
+ sal_Int16 nRet = xManager->execute();
+
+ return nRet;
+}
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+SelectedPackage::~SelectedPackage() {}
+
+} //namespace dp_gui
+
diff --git a/desktop/source/deployment/gui/dp_gui_dialog2.hxx b/desktop/source/deployment/gui/dp_gui_dialog2.hxx
new file mode 100644
index 000000000000..7536aa403cfe
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_dialog2.hxx
@@ -0,0 +1,277 @@
+/*************************************************************************
+ *
+ * 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: dp_gui_dialog2.hxx,v $
+ *
+ * $Revision: 1.4.74.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 INCLUDED_DP_GUI_DIALOG2_HXX
+#define INCLUDED_DP_GUI_DIALOG2_HXX
+
+#include "vcl/dialog.hxx"
+#include "vcl/button.hxx"
+#include "vcl/fixed.hxx"
+#include "vcl/timer.hxx"
+
+#include "svtools/fixedhyper.hxx"
+#include "svtools/prgsbar.hxx"
+
+#include "osl/conditn.hxx"
+#include "osl/mutex.hxx"
+
+#include "rtl/ref.hxx"
+#include "rtl/ustring.hxx"
+
+#include "cppuhelper/implbase1.hxx"
+
+#include "com/sun/star/awt/XWindow.hpp"
+#include "com/sun/star/deployment/XPackage.hpp"
+#include "com/sun/star/deployment/XPackageManager.hpp"
+#include "com/sun/star/uno/XComponentContext.hpp"
+#include "com/sun/star/ui/dialogs/XExecutableDialog.hpp"
+#include "com/sun/star/util/XModifyListener.hpp"
+
+namespace dp_gui {
+
+//==============================================================================
+class ExtBoxWithBtns_Impl;
+class ExtensionBox_Impl;
+class TheExtensionManager;
+
+//==============================================================================
+class DialogHelper
+{
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > m_xContext;
+ Dialog* m_pVCLWindow;
+ ULONG m_nEventID;
+ bool m_bIsBusy;
+
+public:
+ DialogHelper( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > &,
+ Dialog *pWindow );
+ virtual ~DialogHelper();
+
+ void openWebBrowser( const ::rtl::OUString & sURL, const ::rtl::OUString & sTitle ) const;
+ Dialog* getWindow() const { return m_pVCLWindow; };
+ void PostUserEvent( const Link& rLink, void* pCaller );
+ void clearEventID() { m_nEventID = 0; }
+
+ virtual void showProgress( bool bStart ) = 0;
+ virtual void updateProgress( const ::rtl::OUString &rText,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::task::XAbortChannel > &xAbortChannel) = 0;
+ virtual void updateProgress( const long nProgress ) = 0;
+
+ virtual void updatePackageInfo( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage ) = 0;
+ virtual long addPackageToList( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackageManager > & ) = 0;
+
+ virtual void prepareChecking( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackageManager > &xPackageManager ) = 0;
+ virtual void checkEntries() = 0;
+
+ static ResId getResId( USHORT nId );
+ static String getResourceString( USHORT id );
+ static bool IsSharedPkgMgr( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackageManager > &);
+ static bool continueOnSharedExtension( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackageManager > &,
+ Window *pParent,
+ const USHORT nResID,
+ bool &bHadWarning );
+
+ void setBusy( const bool bBusy ) { m_bIsBusy = bBusy; }
+ bool isBusy() const { return m_bIsBusy; }
+ bool installExtensionWarn( const ::rtl::OUString &rExtensionURL ) const;
+ bool installForAllUsers( bool &bInstallForAll ) const;
+};
+
+//==============================================================================
+class ExtMgrDialog : public ModelessDialog,
+ public DialogHelper
+{
+ ExtBoxWithBtns_Impl *m_pExtensionBox;
+ PushButton m_aAddBtn;
+ PushButton m_aUpdateBtn;
+ OKButton m_aCloseBtn;
+ HelpButton m_aHelpBtn;
+ FixedLine m_aDivider;
+ svt::FixedHyperlink m_aGetExtensions;
+ FixedText m_aProgressText;
+ ProgressBar m_aProgressBar;
+ CancelButton m_aCancelBtn;
+ const String m_sAddPackages;
+ String m_sProgressText;
+ String m_sLastFolderURL;
+ ::osl::Mutex m_aMutex;
+ bool m_bHasProgress;
+ bool m_bProgressChanged;
+ bool m_bStartProgress;
+ bool m_bStopProgress;
+ bool m_bUpdateWarning;
+ bool m_bEnableWarning;
+ bool m_bDisableWarning;
+ bool m_bDeleteWarning;
+ long m_nProgress;
+ Timer m_aTimeoutTimer;
+ TheExtensionManager *m_pManager;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::task::XAbortChannel > m_xAbortChannel;
+
+ bool removeExtensionWarn( const ::rtl::OUString &rExtensionTitle ) const;
+
+ DECL_DLLPRIVATE_LINK( HandleAddBtn, void * );
+ DECL_DLLPRIVATE_LINK( HandleUpdateBtn, void * );
+ DECL_DLLPRIVATE_LINK( HandleCancelBtn, void * );
+ DECL_DLLPRIVATE_LINK( HandleHyperlink, svt::FixedHyperlink * );
+ DECL_DLLPRIVATE_LINK( TimeOutHdl, Timer* );
+ DECL_DLLPRIVATE_LINK( startProgress, void * );
+
+public:
+ ExtMgrDialog( Window * pParent, TheExtensionManager *pManager );
+ virtual ~ExtMgrDialog();
+
+ virtual void Resize();
+ virtual long Notify( NotifyEvent& rNEvt );
+ virtual BOOL Close();
+
+ virtual void showProgress( bool bStart );
+ virtual void updateProgress( const ::rtl::OUString &rText,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::task::XAbortChannel > &xAbortChannel);
+ virtual void updateProgress( const long nProgress );
+
+ virtual void updatePackageInfo( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage );
+
+ void setGetExtensionsURL( const ::rtl::OUString &rURL );
+ void selectEntry( long nPos );
+ virtual long addPackageToList( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackageManager > & );
+ bool enablePackage( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackageManager > &xPackageManager,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage,
+ bool bEnable );
+ bool removePackage( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackageManager > &xPackageManager,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage );
+ bool updatePackage( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackageManager > &xPackageManager,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage );
+
+ virtual void prepareChecking( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackageManager > &xPackageManager );
+ virtual void checkEntries();
+
+ ::com::sun::star::uno::Sequence< ::rtl::OUString > raiseAddPicker( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackageManager > &xPackageManager );
+};
+
+//==============================================================================
+class UpdateRequiredDialog : public ModalDialog,
+ public DialogHelper
+{
+ ExtensionBox_Impl *m_pExtensionBox;
+ FixedText m_aUpdateNeeded;
+ PushButton m_aUpdateBtn;
+ PushButton m_aCloseBtn;
+ HelpButton m_aHelpBtn;
+ CancelButton m_aCancelBtn;
+ FixedLine m_aDivider;
+ FixedText m_aProgressText;
+ ProgressBar m_aProgressBar;
+ const String m_sAddPackages;
+ const String m_sCloseText;
+ String m_sProgressText;
+ ::osl::Mutex m_aMutex;
+ bool m_bHasProgress;
+ bool m_bProgressChanged;
+ bool m_bStartProgress;
+ bool m_bStopProgress;
+ bool m_bUpdateWarning;
+ bool m_bDisableWarning;
+ bool m_bHasLockedEntries;
+ long m_nProgress;
+ Timer m_aTimeoutTimer;
+ TheExtensionManager *m_pManager;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::task::XAbortChannel > m_xAbortChannel;
+
+ DECL_DLLPRIVATE_LINK( HandleUpdateBtn, void * );
+ DECL_DLLPRIVATE_LINK( HandleCloseBtn, void * );
+ DECL_DLLPRIVATE_LINK( HandleCancelBtn, void * );
+ DECL_DLLPRIVATE_LINK( TimeOutHdl, Timer* );
+ DECL_DLLPRIVATE_LINK( startProgress, void * );
+ DECL_DLLPRIVATE_LINK( HandleHyperlink, svt::FixedHyperlink * );
+
+ bool isEnabled( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage ) const;
+ bool checkDependencies( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage ) const;
+ bool hasActiveEntries();
+ void disableAllEntries();
+
+public:
+ UpdateRequiredDialog( Window * pParent, TheExtensionManager *pManager );
+ virtual ~UpdateRequiredDialog();
+
+ virtual short Execute();
+ virtual void Resize();
+ virtual BOOL Close();
+// virtual long Notify( NotifyEvent& rNEvt );
+
+ virtual void showProgress( bool bStart );
+ virtual void updateProgress( const ::rtl::OUString &rText,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::task::XAbortChannel > &xAbortChannel);
+ virtual void updateProgress( const long nProgress );
+
+ virtual void updatePackageInfo( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage );
+
+ void selectEntry( long nPos );
+ virtual long addPackageToList( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackageManager > & );
+ bool enablePackage( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackageManager > &xPackageManager,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage,
+ bool bEnable );
+ bool updatePackage( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackageManager > &xPackageManager,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage );
+
+ virtual void prepareChecking( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackageManager > &xPackageManager );
+ virtual void checkEntries();
+
+ ::com::sun::star::uno::Sequence< ::rtl::OUString > raiseAddPicker( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackageManager > &xPackageManager );
+
+ bool installForAllUsers( bool &bInstallForAll ) const;
+ bool installExtensionWarn( const ::rtl::OUString &rExtensionURL ) const;
+};
+
+//==============================================================================
+class UpdateRequiredDialogService : public ::cppu::WeakImplHelper1< ::com::sun::star::ui::dialogs::XExecutableDialog >
+{
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > const m_xComponentContext;
+ ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow > m_xParent;
+ ::rtl::OUString m_sInitialTitle;
+
+public:
+ UpdateRequiredDialogService( ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > const & args,
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext> const & xComponentContext );
+
+ // XExecutableDialog
+ virtual void SAL_CALL setTitle( rtl::OUString const & title ) throw ( ::com::sun::star::uno::RuntimeException );
+ virtual sal_Int16 SAL_CALL execute() throw ( ::com::sun::star::uno::RuntimeException );
+};
+
+} // namespace dp_gui
+
+#endif
diff --git a/desktop/source/deployment/gui/dp_gui_dialog2.src b/desktop/source/deployment/gui/dp_gui_dialog2.src
new file mode 100644
index 000000000000..7e4004bca1d4
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_dialog2.src
@@ -0,0 +1,246 @@
+/*************************************************************************
+ *
+ * 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: dp_gui_dialog2.src,v $
+ *
+ * $Revision: 1.2.86.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.
+ *
+ ************************************************************************/
+
+#include "svtools/controldims.hrc"
+#include "dp_gui.hrc"
+
+ModelessDialog RID_DLG_EXTENSION_MANAGER
+{
+ HelpId = HID_PACKAGE_MANAGER;
+ Text [ en-US ] = "Extension Manager";
+
+ Size = MAP_APPFONT( 300, 200 );
+ OutputSize = TRUE;
+ SVLook = TRUE;
+ Moveable = TRUE;
+ Closeable = TRUE;
+ Sizeable = TRUE;
+ Hide = TRUE;
+
+ PushButton RID_EM_BTN_ADD
+ {
+ TabStop = TRUE;
+ Text [ en-US ] = "~Add...";
+ Size = MAP_APPFONT(RSC_CD_PUSHBUTTON_WIDTH, RSC_CD_PUSHBUTTON_HEIGHT );
+ };
+
+ PushButton RID_EM_BTN_CHECK_UPDATES
+ {
+ TabStop = TRUE;
+ Text [ en-US ] = "Check for ~Updates...";
+ Size = MAP_APPFONT(RSC_CD_PUSHBUTTON_WIDTH, RSC_CD_PUSHBUTTON_HEIGHT );
+ };
+
+ FixedText RID_EM_FT_GET_EXTENSIONS
+ {
+ NoLabel = TRUE;
+ TabStop = TRUE;
+ Text [ en-US ] = "Get more extensions online...";
+ Size = MAP_APPFONT(RSC_CD_PUSHBUTTON_WIDTH, RSC_CD_FIXEDTEXT_HEIGHT );
+ };
+
+ FixedText RID_EM_FT_PROGRESS
+ {
+ Hide = TRUE;
+ Right = TRUE;
+ Text [ en-US ] = "Adding %EXTENSION_NAME";
+ Size = MAP_APPFONT(RSC_CD_PUSHBUTTON_WIDTH, RSC_CD_FIXEDTEXT_HEIGHT );
+ };
+
+ CancelButton RID_EM_BTN_CANCEL
+ {
+ TabStop = TRUE;
+ Hide = TRUE;
+ Size = MAP_APPFONT(RSC_CD_PUSHBUTTON_WIDTH, RSC_CD_PUSHBUTTON_HEIGHT );
+ };
+
+ OKButton RID_EM_BTN_CLOSE
+ {
+ TabStop = TRUE;
+ DefButton = TRUE;
+ Text [ en-US ] = "Close";
+ Size = MAP_APPFONT(RSC_CD_PUSHBUTTON_WIDTH, RSC_CD_PUSHBUTTON_HEIGHT );
+ };
+
+ HelpButton RID_EM_BTN_HELP
+ {
+ TabStop = TRUE;
+ Size = MAP_APPFONT(RSC_CD_PUSHBUTTON_WIDTH, RSC_CD_PUSHBUTTON_HEIGHT );
+ };
+};
+
+ModalDialog RID_DLG_UPDATE_REQUIRED
+{
+ HelpId = HID_PACKAGE_MANAGER_UPD_REQ;
+ Text [ en-US ] = "Extension Update Required";
+
+ Size = MAP_APPFONT( 300, 200 );
+ OutputSize = TRUE;
+ SVLook = TRUE;
+ Moveable = TRUE;
+ Closeable = TRUE;
+ Sizeable = TRUE;
+ Hide = TRUE;
+
+ FixedText RID_EM_FT_MSG
+ {
+ Text [ en-US ] = "%PRODUCTNAME has been updated to a new version. Some installed %PRODUCTNAME extensions are not compatible with this version and need to be updated before they can be used.";
+ WordBreak = TRUE;
+ NoLabel = TRUE;
+ Size = MAP_APPFONT( 280, 3*RSC_BS_CHARHEIGHT );
+ Pos = MAP_APPFONT( 5, 5 );
+ };
+
+ FixedText RID_EM_FT_PROGRESS
+ {
+ Hide = TRUE;
+ Right = TRUE;
+ Text [ en-US ] = "Adding %EXTENSION_NAME";
+ Size = MAP_APPFONT(RSC_CD_PUSHBUTTON_WIDTH, RSC_CD_FIXEDTEXT_HEIGHT );
+ };
+
+ HelpButton RID_EM_BTN_HELP
+ {
+ TabStop = TRUE;
+ Size = MAP_APPFONT(RSC_CD_PUSHBUTTON_WIDTH, RSC_CD_PUSHBUTTON_HEIGHT );
+ };
+
+ PushButton RID_EM_BTN_CHECK_UPDATES
+ {
+ TabStop = TRUE;
+ Text [ en-US ] = "Check for ~Updates...";
+ Size = MAP_APPFONT(RSC_CD_PUSHBUTTON_WIDTH, RSC_CD_PUSHBUTTON_HEIGHT );
+ };
+
+ PushButton RID_EM_BTN_CLOSE
+ {
+ TabStop = TRUE;
+ DefButton = TRUE;
+ Text [ en-US ] = "Disable all";
+ Size = MAP_APPFONT(RSC_CD_PUSHBUTTON_WIDTH, RSC_CD_PUSHBUTTON_HEIGHT );
+ };
+
+ CancelButton RID_EM_BTN_CANCEL
+ {
+ TabStop = TRUE;
+ Hide = TRUE;
+ Size = MAP_APPFONT(RSC_CD_PUSHBUTTON_WIDTH, RSC_CD_PUSHBUTTON_HEIGHT );
+ };
+
+};
+
+Image RID_IMG_WARNING
+{
+ ImageBitmap = Bitmap { File = "caution_16.png"; };
+};
+
+Image RID_IMG_WARNING_HC
+{
+ ImageBitmap = Bitmap { File = "caution_16_h.png"; };
+};
+
+Image RID_IMG_LOCKED
+{
+ ImageBitmap = Bitmap { File = "shared_16.png"; };
+};
+
+Image RID_IMG_LOCKED_HC
+{
+ ImageBitmap = Bitmap { File = "shared_16_h.png"; };
+};
+
+Image RID_IMG_EXTENSION
+{
+ ImageBitmap = Bitmap { File = "extension_32.png"; };
+};
+
+Image RID_IMG_EXTENSION_HC
+{
+ ImageBitmap = Bitmap { File = "extension_32_h.png"; };
+};
+
+QueryBox RID_QUERYBOX_INSTALL_FOR_ALL
+{
+ Buttons = WB_YES_NO_CANCEL;
+ DefButton = WB_DEF_YES;
+ Message[en-US] = "Make sure that no further users are working with the same %PRODUCTNAME, when installing an extension for all users in a multi user environment.\n\nFor whom do you want to install the extension?\n";
+};
+
+
+// Dialog layout
+// ---------------------------------------------------
+// row 1 | multi line edit
+// ---------------------------------------------------
+// row 2 | fixed text
+// ---------------------------------------------------
+// row 3 | img | fixed text | fixed text | button
+// ----------------------------------------------------
+// row 4 | img | fixed text | fixed text
+// ---------------------------------------------------
+// row 5 |fixed line
+// ---------------------------------------------------
+// row 6 | | |button | button
+// ---------------------------------------------------
+// | col 1 | col 2 | col3 | col4 | col5
+
+//To change the overall size of the multi line edit change
+//ROW1_HEIGHT and COL3_WIDTH
+
+#define ROW1_Y RSC_SP_DLG_INNERBORDER_TOP
+#define ROW1_HEIGHT 16*RSC_CD_FIXEDTEXT_HEIGHT
+#define ROW2_Y ROW1_Y+ROW1_HEIGHT+RSC_SP_CTRL_GROUP_Y
+#define ROW2_HEIGHT 2*RSC_CD_FIXEDTEXT_HEIGHT
+#define ROW3_Y ROW2_Y+ROW2_HEIGHT+RSC_SP_CTRL_GROUP_Y
+#define ROW3_HEIGHT 3*RSC_CD_FIXEDTEXT_HEIGHT
+#define ROW4_Y ROW3_Y+ROW3_HEIGHT+RSC_SP_CTRL_GROUP_Y
+#define ROW4_HEIGHT 3*RSC_CD_FIXEDTEXT_HEIGHT
+#define ROW5_Y ROW4_Y+ROW4_HEIGHT+RSC_SP_CTRL_GROUP_Y
+#define ROW5_HEIGHT RSC_CD_FIXEDTEXT_HEIGHT
+#define ROW6_Y ROW5_Y+ROW5_HEIGHT+RSC_SP_CTRL_GROUP_Y
+#define ROW6_HEIGHT RSC_CD_PUSHBUTTON_HEIGHT
+
+#define LIC_DLG_HEIGHT ROW6_Y+ROW6_HEIGHT+RSC_SP_DLG_INNERBORDER_BOTTOM
+
+#define COL1_X RSC_SP_DLG_INNERBORDER_LEFT
+#define IMG_ARROW_WIDTH 16
+#define COL1_WIDTH IMG_ARROW_WIDTH
+#define COL2_X COL1_X+COL1_WIDTH
+#define COL2_WIDTH 10
+#define COL3_X COL2_X+COL2_WIDTH+RSC_SP_CTRL_GROUP_X
+#define COL3_WIDTH 150
+#define COL4_X COL3_X+COL3_WIDTH
+#define COL4_WIDTH RSC_CD_PUSHBUTTON_WIDTH+RSC_SP_CTRL_GROUP_X
+#define COL5_X COL4_X+COL4_WIDTH
+
+#define LIC_DLG_WIDTH COL5_X+RSC_CD_PUSHBUTTON_WIDTH+RSC_SP_DLG_INNERBORDER_RIGHT
+#define BODYWIDTH LIC_DLG_WIDTH-RSC_SP_DLG_INNERBORDER_LEFT-RSC_SP_DLG_INNERBORDER_RIGHT
+
+
diff --git a/desktop/source/deployment/gui/dp_gui_extensioncmdqueue.cxx b/desktop/source/deployment/gui/dp_gui_extensioncmdqueue.cxx
new file mode 100644
index 000000000000..889fdc04c9e1
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_extensioncmdqueue.cxx
@@ -0,0 +1,1188 @@
+/*************************************************************************
+ *
+ * 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: dp_gui_extensioncmdqueue.cxx,v $
+ *
+ * $Revision: 1.7.4.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_desktop.hxx"
+
+
+
+
+#include "sal/config.h"
+
+#include <cstddef>
+
+#include "com/sun/star/beans/PropertyValue.hpp"
+
+#include "com/sun/star/deployment/DependencyException.hpp"
+#include "com/sun/star/deployment/LicenseException.hpp"
+#include "com/sun/star/deployment/LicenseIndividualAgreementException.hpp"
+#include "com/sun/star/deployment/VersionException.hpp"
+#include "com/sun/star/deployment/InstallException.hpp"
+#include "com/sun/star/deployment/PlatformException.hpp"
+
+#include "com/sun/star/deployment/ui/LicenseDialog.hpp"
+#include "com/sun/star/deployment/DeploymentException.hpp"
+#include "com/sun/star/deployment/UpdateInformationProvider.hpp"
+#include "com/sun/star/deployment/XPackage.hpp"
+#include "com/sun/star/deployment/XPackageManager.hpp"
+
+#include "com/sun/star/task/XAbortChannel.hpp"
+#include "com/sun/star/task/XInteractionAbort.hpp"
+#include "com/sun/star/task/XInteractionApprove.hpp"
+
+#include "com/sun/star/ucb/CommandAbortedException.hpp"
+#include "com/sun/star/ucb/CommandFailedException.hpp"
+#include "com/sun/star/ucb/XCommandEnvironment.hpp"
+
+#include "com/sun/star/ui/dialogs/ExecutableDialogResults.hpp"
+
+#include "com/sun/star/uno/Reference.hxx"
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include "com/sun/star/uno/Sequence.hxx"
+#include "com/sun/star/uno/XInterface.hpp"
+#include "com/sun/star/uno/TypeClass.hpp"
+#include "osl/diagnose.h"
+#include "osl/mutex.hxx"
+#include "rtl/ref.hxx"
+#include "rtl/ustring.h"
+#include "rtl/ustring.hxx"
+#include "sal/types.h"
+#include "ucbhelper/content.hxx"
+#include "cppuhelper/exc_hlp.hxx"
+#include "cppuhelper/implbase3.hxx"
+#include "comphelper/anytostring.hxx"
+#include "vcl/msgbox.hxx"
+#include "toolkit/helper/vclunohelper.hxx"
+
+#include "dp_gui.h"
+#include "dp_gui_thread.hxx"
+#include "dp_gui_extensioncmdqueue.hxx"
+#include "dp_gui_dependencydialog.hxx"
+#include "dp_gui_dialog2.hxx"
+#include "dp_gui_shared.hxx"
+#include "dp_gui_theextmgr.hxx"
+#include "dp_gui_updatedialog.hxx"
+#include "dp_gui_updateinstalldialog.hxx"
+#include "dp_dependencies.hxx"
+#include "dp_identifier.hxx"
+#include "dp_version.hxx"
+
+#include <queue>
+#include <boost/shared_ptr.hpp>
+
+#if (defined(_MSC_VER) && (_MSC_VER < 1400))
+#define _WIN32_WINNT 0x0400
+#endif
+
+#ifdef WNT
+#include "tools/prewin.h"
+#include <objbase.h>
+#include "tools/postwin.h"
+#endif
+
+
+using namespace ::com::sun::star;
+using ::rtl::OUString;
+
+namespace {
+
+OUString getVersion( const uno::Reference< deployment::XPackage > &rPackage )
+{
+ OUString sVersion( rPackage->getVersion());
+ return ( sVersion.getLength() == 0 ) ? OUString( RTL_CONSTASCII_USTRINGPARAM( "0" ) ) : sVersion;
+}
+
+}
+
+
+namespace dp_gui {
+
+//==============================================================================
+
+class ProgressCmdEnv
+ : public ::cppu::WeakImplHelper3< ucb::XCommandEnvironment,
+ task::XInteractionHandler,
+ ucb::XProgressHandler >
+{
+ uno::Reference< task::XInteractionHandler> m_xHandler;
+ uno::Reference< uno::XComponentContext > m_xContext;
+ uno::Reference< task::XAbortChannel> m_xAbortChannel;
+
+ DialogHelper *m_pDialogHelper;
+ OUString m_sTitle;
+ bool m_bAborted;
+ bool m_bWarnUser;
+ sal_Int32 m_nCurrentProgress;
+
+ void updateProgress();
+
+ void update_( uno::Any const & Status ) throw ( uno::RuntimeException );
+
+public:
+ virtual ~ProgressCmdEnv();
+
+ /** When param bAskWhenInstalling = true, then the user is asked if he
+ agrees to install this extension. In case this extension is already installed
+ then the user is also notified and asked if he wants to replace that existing
+ extension. In first case an interaction request with an InstallException
+ will be handled and in the second case a VersionException will be handled.
+ */
+
+ ProgressCmdEnv( const uno::Reference< uno::XComponentContext > rContext,
+ DialogHelper *pDialogHelper,
+ const OUString &rTitle )
+ : m_xContext( rContext ),
+ m_pDialogHelper( pDialogHelper ),
+ m_sTitle( rTitle ),
+ m_bAborted( false ),
+ m_bWarnUser( false )
+ {}
+
+ Dialog * activeDialog() { return m_pDialogHelper->getWindow(); }
+
+ void setTitle( const OUString& rNewTitle ) { m_sTitle = rNewTitle; }
+ void startProgress();
+ void stopProgress();
+ void progressSection( const OUString &rText,
+ const uno::Reference< task::XAbortChannel > &xAbortChannel = 0 );
+ inline bool isAborted() const { return m_bAborted; }
+ inline void setWarnUser( bool bNewVal ) { m_bWarnUser = bNewVal; }
+
+ // XCommandEnvironment
+ virtual uno::Reference< task::XInteractionHandler > SAL_CALL getInteractionHandler()
+ throw ( uno::RuntimeException );
+ virtual uno::Reference< ucb::XProgressHandler > SAL_CALL getProgressHandler()
+ throw ( uno::RuntimeException );
+
+ // XInteractionHandler
+ virtual void SAL_CALL handle( uno::Reference< task::XInteractionRequest > const & xRequest )
+ throw ( uno::RuntimeException );
+
+ // XProgressHandler
+ virtual void SAL_CALL push( uno::Any const & Status )
+ throw ( uno::RuntimeException );
+ virtual void SAL_CALL update( uno::Any const & Status )
+ throw ( uno::RuntimeException );
+ virtual void SAL_CALL pop() throw ( uno::RuntimeException );
+};
+
+//------------------------------------------------------------------------------
+struct ExtensionCmd
+{
+ enum E_CMD_TYPE { ADD, ENABLE, DISABLE, REMOVE, CHECK_FOR_UPDATES };
+
+ E_CMD_TYPE m_eCmdType;
+ bool m_bWarnUser;
+ OUString m_sExtensionURL;
+ uno::Reference< deployment::XPackageManager > m_xPackageManager;
+ uno::Reference< deployment::XPackage > m_xPackage;
+ std::vector< TUpdateListEntry > m_vExtensionList;
+
+ ExtensionCmd( const E_CMD_TYPE eCommand,
+ const uno::Reference< deployment::XPackageManager > &rPackageManager,
+ const OUString &rExtensionURL,
+ const bool bWarnUser )
+ : m_eCmdType( eCommand ),
+ m_bWarnUser( bWarnUser ),
+ m_sExtensionURL( rExtensionURL ),
+ m_xPackageManager( rPackageManager ) {};
+ ExtensionCmd( const E_CMD_TYPE eCommand,
+ const uno::Reference< deployment::XPackageManager > &rPackageManager,
+ const uno::Reference< deployment::XPackage > &rPackage )
+ : m_eCmdType( eCommand ),
+ m_bWarnUser( false ),
+ m_xPackageManager( rPackageManager ),
+ m_xPackage( rPackage ) {};
+ ExtensionCmd( const E_CMD_TYPE eCommand,
+ const uno::Reference< deployment::XPackage > &rPackage )
+ : m_eCmdType( eCommand ),
+ m_bWarnUser( false ),
+ m_xPackage( rPackage ) {};
+ ExtensionCmd( const E_CMD_TYPE eCommand,
+ const std::vector< TUpdateListEntry > &vExtensionList )
+ : m_eCmdType( eCommand ),
+ m_bWarnUser( false ),
+ m_vExtensionList( vExtensionList ) {};
+};
+
+typedef ::boost::shared_ptr< ExtensionCmd > TExtensionCmd;
+
+//------------------------------------------------------------------------------
+class ExtensionCmdQueue::Thread: public dp_gui::Thread
+{
+public:
+ Thread( DialogHelper *pDialogHelper,
+ TheExtensionManager *pManager,
+ const uno::Reference< uno::XComponentContext > & rContext );
+
+ void addExtension( const uno::Reference< deployment::XPackageManager > &rPackageManager,
+ const OUString &rExtensionURL,
+ const bool bWarnUser );
+ void removeExtension( const uno::Reference< deployment::XPackageManager > &rPackageManager,
+ const uno::Reference< deployment::XPackage > &rPackage );
+ void enableExtension( const uno::Reference< deployment::XPackage > &rPackage,
+ const bool bEnable );
+ void checkForUpdates( const std::vector< TUpdateListEntry > &vExtensionList );
+ void stop();
+ bool hasTerminated();
+ bool isBusy();
+
+ static OUString searchAndReplaceAll( const OUString &rSource,
+ const OUString &rWhat,
+ const OUString &rWith );
+private:
+ Thread( Thread & ); // not defined
+ void operator =( Thread & ); // not defined
+
+ virtual ~Thread();
+
+ virtual void execute();
+ virtual void SAL_CALL onTerminated();
+
+ void _addExtension( ::rtl::Reference< ProgressCmdEnv > &rCmdEnv,
+ const uno::Reference< deployment::XPackageManager > &xPackageManager,
+ const OUString &rPackageURL,
+ const bool bWarnUser );
+ void _removeExtension( ::rtl::Reference< ProgressCmdEnv > &rCmdEnv,
+ const uno::Reference< deployment::XPackageManager > &xPackageManager,
+ const uno::Reference< deployment::XPackage > &xPackage );
+ void _enableExtension( ::rtl::Reference< ProgressCmdEnv > &rCmdEnv,
+ const uno::Reference< deployment::XPackage > &xPackage );
+ void _disableExtension( ::rtl::Reference< ProgressCmdEnv > &rCmdEnv,
+ const uno::Reference< deployment::XPackage > &xPackage );
+ void _checkForUpdates( const std::vector< TUpdateListEntry > &vExtensionList );
+
+ enum Input { NONE, START, STOP };
+
+ uno::Reference< uno::XComponentContext > m_xContext;
+ std::queue< TExtensionCmd > m_queue;
+
+ DialogHelper *m_pDialogHelper;
+ TheExtensionManager *m_pManager;
+
+ const OUString m_sEnablingPackages;
+ const OUString m_sDisablingPackages;
+ const OUString m_sAddingPackages;
+ const OUString m_sRemovingPackages;
+ const OUString m_sDefaultCmd;
+ osl::Condition m_wakeup;
+ osl::Mutex m_mutex;
+ Input m_eInput;
+ bool m_bTerminated;
+ bool m_bStopped;
+ bool m_bWorking;
+};
+
+//------------------------------------------------------------------------------
+void ProgressCmdEnv::startProgress()
+{
+ m_nCurrentProgress = 0;
+
+ if ( m_pDialogHelper )
+ m_pDialogHelper->showProgress( true );
+}
+
+//------------------------------------------------------------------------------
+void ProgressCmdEnv::stopProgress()
+{
+ if ( m_pDialogHelper )
+ m_pDialogHelper->showProgress( false );
+}
+
+//------------------------------------------------------------------------------
+void ProgressCmdEnv::progressSection( const OUString &rText,
+ const uno::Reference< task::XAbortChannel > &xAbortChannel )
+{
+ m_xAbortChannel = xAbortChannel;
+ if (! m_bAborted)
+ {
+ m_nCurrentProgress = 0;
+ if ( m_pDialogHelper )
+ {
+ m_pDialogHelper->updateProgress( rText, xAbortChannel );
+ m_pDialogHelper->updateProgress( 5 );
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+void ProgressCmdEnv::updateProgress()
+{
+ if ( ! m_bAborted )
+ {
+ long nProgress = ((m_nCurrentProgress*5) % 100) + 5;
+ if ( m_pDialogHelper )
+ m_pDialogHelper->updateProgress( nProgress );
+ }
+}
+
+//------------------------------------------------------------------------------
+ProgressCmdEnv::~ProgressCmdEnv()
+{
+ // TODO: stop all threads and wait
+}
+
+
+//------------------------------------------------------------------------------
+// XCommandEnvironment
+//------------------------------------------------------------------------------
+uno::Reference< task::XInteractionHandler > ProgressCmdEnv::getInteractionHandler()
+ throw ( uno::RuntimeException )
+{
+ return this;
+}
+
+//------------------------------------------------------------------------------
+uno::Reference< ucb::XProgressHandler > ProgressCmdEnv::getProgressHandler()
+ throw ( uno::RuntimeException )
+{
+ return this;
+}
+
+//------------------------------------------------------------------------------
+// XInteractionHandler
+//------------------------------------------------------------------------------
+void ProgressCmdEnv::handle( uno::Reference< task::XInteractionRequest > const & xRequest )
+ throw ( uno::RuntimeException )
+{
+ uno::Any request( xRequest->getRequest() );
+ OSL_ASSERT( request.getValueTypeClass() == uno::TypeClass_EXCEPTION );
+ dp_misc::TRACE( OUSTR("[dp_gui_cmdenv.cxx] incoming request:\n")
+ + ::comphelper::anyToString(request) + OUSTR("\n"));
+
+ lang::WrappedTargetException wtExc;
+ deployment::DependencyException depExc;
+ deployment::LicenseException licExc;
+ deployment::LicenseIndividualAgreementException licAgreementExc;
+ deployment::VersionException verExc;
+ deployment::InstallException instExc;
+ deployment::PlatformException platExc;
+
+ // selections:
+ bool approve = false;
+ bool abort = false;
+
+ if (request >>= wtExc) {
+ // handable deployment error signalled, e.g.
+ // bundle item registration failed, notify cause only:
+ uno::Any cause;
+ deployment::DeploymentException dpExc;
+ if (wtExc.TargetException >>= dpExc)
+ cause = dpExc.Cause;
+ else {
+ ucb::CommandFailedException cfExc;
+ if (wtExc.TargetException >>= cfExc)
+ cause = cfExc.Reason;
+ else
+ cause = wtExc.TargetException;
+ }
+ update_( cause );
+
+ // ignore intermediate errors of legacy packages, i.e.
+ // former pkgchk behaviour:
+ const uno::Reference< deployment::XPackage > xPackage( wtExc.Context, uno::UNO_QUERY );
+ OSL_ASSERT( xPackage.is() );
+ if ( xPackage.is() )
+ {
+ const uno::Reference< deployment::XPackageTypeInfo > xPackageType( xPackage->getPackageType() );
+ OSL_ASSERT( xPackageType.is() );
+ if (xPackageType.is())
+ {
+ approve = ( xPackage->isBundle() &&
+ xPackageType->getMediaType().matchAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(
+ "application/"
+ "vnd.sun.star.legacy-package-bundle") ));
+ }
+ }
+ abort = !approve;
+ }
+ else if (request >>= depExc)
+ {
+ std::vector< rtl::OUString > deps;
+ for (sal_Int32 i = 0; i < depExc.UnsatisfiedDependencies.getLength();
+ ++i)
+ {
+ deps.push_back(
+ dp_misc::Dependencies::getErrorText( depExc.UnsatisfiedDependencies[i]) );
+ }
+ {
+ vos::OGuard guard(Application::GetSolarMutex());
+ short n = DependencyDialog( m_pDialogHelper? m_pDialogHelper->getWindow() : NULL, deps ).Execute();
+ // Distinguish between closing the dialog and programatically
+ // canceling the dialog (headless VCL):
+ approve = n == RET_OK
+ || (n == RET_CANCEL && !Application::IsDialogCancelEnabled());
+ }
+ }
+ else if (request >>= licAgreementExc)
+ {
+ vos::OGuard aSolarGuard( Application::GetSolarMutex() );
+ ResId warnId(WARNINGBOX_NOSHAREDALLOWED, *DeploymentGuiResMgr::get());
+ WarningBox warn( m_pDialogHelper? m_pDialogHelper->getWindow() : NULL, warnId);
+ String msgText = warn.GetMessText();
+ msgText.SearchAndReplaceAllAscii( "%PRODUCTNAME", BrandName::get() );
+ msgText.SearchAndReplaceAllAscii("%NAME", licAgreementExc.ExtensionName);
+ warn.SetMessText(msgText);
+ warn.Execute();
+ abort = true;
+ }
+ else if (request >>= licExc)
+ {
+ uno::Reference< ui::dialogs::XExecutableDialog > xDialog(
+ deployment::ui::LicenseDialog::create(
+ m_xContext, VCLUnoHelper::GetInterface( m_pDialogHelper? m_pDialogHelper->getWindow() : NULL ), licExc.Text ) );
+ sal_Int16 res = xDialog->execute();
+ if ( res == ui::dialogs::ExecutableDialogResults::CANCEL )
+ abort = true;
+ else if ( res == ui::dialogs::ExecutableDialogResults::OK )
+ approve = true;
+ else
+ {
+ OSL_ASSERT(0);
+ }
+ }
+ else if (request >>= verExc)
+ {
+ sal_uInt32 id;
+ switch (dp_misc::comparePackageVersions( verExc.New, verExc.Deployed ))
+ {
+ case dp_misc::LESS:
+ id = RID_WARNINGBOX_VERSION_LESS;
+ break;
+ case dp_misc::EQUAL:
+ id = RID_WARNINGBOX_VERSION_EQUAL;
+ break;
+ default: // dp_misc::GREATER
+ id = RID_WARNINGBOX_VERSION_GREATER;
+ break;
+ }
+ OSL_ASSERT( verExc.New.is() && verExc.Deployed.is() );
+ bool bEqualNames = verExc.New->getDisplayName().equals(
+ verExc.Deployed->getDisplayName());
+ {
+ vos::OGuard guard(Application::GetSolarMutex());
+ WarningBox box( m_pDialogHelper? m_pDialogHelper->getWindow() : NULL, ResId(id, *DeploymentGuiResMgr::get()));
+ String s;
+ if (bEqualNames)
+ {
+ s = box.GetMessText();
+ }
+ else if (id == RID_WARNINGBOX_VERSION_EQUAL)
+ {
+ //hypothetical: requires two instances of an extension with the same
+ //version to have different display names. Probably the developer forgot
+ //to change the version.
+ s = String(ResId(RID_STR_WARNINGBOX_VERSION_EQUAL_DIFFERENT_NAMES, *DeploymentGuiResMgr::get()));
+ }
+ else if (id == RID_WARNINGBOX_VERSION_LESS)
+ {
+ s = String(ResId(RID_STR_WARNINGBOX_VERSION_LESS_DIFFERENT_NAMES, *DeploymentGuiResMgr::get()));
+ }
+ else if (id == RID_WARNINGBOX_VERSION_GREATER)
+ {
+ s = String(ResId(RID_STR_WARNINGBOX_VERSION_GREATER_DIFFERENT_NAMES, *DeploymentGuiResMgr::get()));
+ }
+ s.SearchAndReplaceAllAscii( "$NAME", verExc.New->getDisplayName());
+ s.SearchAndReplaceAllAscii( "$OLDNAME", verExc.Deployed->getDisplayName());
+ s.SearchAndReplaceAllAscii( "$NEW", getVersion(verExc.New) );
+ s.SearchAndReplaceAllAscii( "$DEPLOYED", getVersion(verExc.Deployed) );
+ box.SetMessText(s);
+ approve = box.Execute() == RET_OK;
+ abort = !approve;
+ }
+ }
+ else if (request >>= instExc)
+ {
+ if ( ! m_bWarnUser )
+ {
+ approve = true;
+ }
+ else
+ {
+ if ( m_pDialogHelper )
+ {
+ vos::OGuard guard(Application::GetSolarMutex());
+
+ approve = m_pDialogHelper->installExtensionWarn( instExc.New->getDisplayName() );
+ }
+ else
+ approve = false;
+ abort = !approve;
+ }
+ }
+ else if (request >>= platExc)
+ {
+ vos::OGuard guard( Application::GetSolarMutex() );
+ String sMsg( ResId( RID_STR_UNSUPPORTED_PLATFORM, *DeploymentGuiResMgr::get() ) );
+ sMsg.SearchAndReplaceAllAscii( "%Name", platExc.package->getDisplayName() );
+ ErrorBox box( m_pDialogHelper? m_pDialogHelper->getWindow() : NULL, WB_OK, sMsg );
+ box.Execute();
+ approve = true;
+ }
+
+ if (approve == false && abort == false)
+ {
+ // forward to UUI handler:
+ if (! m_xHandler.is()) {
+ // late init:
+ uno::Sequence< uno::Any > handlerArgs( 1 );
+ handlerArgs[ 0 ] <<= beans::PropertyValue(
+ OUSTR("Context"), -1, uno::Any( m_sTitle ),
+ beans::PropertyState_DIRECT_VALUE );
+ m_xHandler.set( m_xContext->getServiceManager()
+ ->createInstanceWithArgumentsAndContext(
+ OUSTR("com.sun.star.uui.InteractionHandler"),
+ handlerArgs, m_xContext ), uno::UNO_QUERY_THROW );
+ }
+ m_xHandler->handle( xRequest );
+ }
+ else
+ {
+ // select:
+ uno::Sequence< uno::Reference< task::XInteractionContinuation > > conts(
+ xRequest->getContinuations() );
+ uno::Reference< task::XInteractionContinuation > const * pConts = conts.getConstArray();
+ sal_Int32 len = conts.getLength();
+ for ( sal_Int32 pos = 0; pos < len; ++pos )
+ {
+ if (approve) {
+ uno::Reference< task::XInteractionApprove > xInteractionApprove( pConts[ pos ], uno::UNO_QUERY );
+ if (xInteractionApprove.is()) {
+ xInteractionApprove->select();
+ // don't query again for ongoing continuations:
+ approve = false;
+ }
+ }
+ else if (abort) {
+ uno::Reference< task::XInteractionAbort > xInteractionAbort( pConts[ pos ], uno::UNO_QUERY );
+ if (xInteractionAbort.is()) {
+ xInteractionAbort->select();
+ // don't query again for ongoing continuations:
+ abort = false;
+ }
+ }
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+// XProgressHandler
+//------------------------------------------------------------------------------
+void ProgressCmdEnv::push( uno::Any const & rStatus )
+ throw( uno::RuntimeException )
+{
+ update_( rStatus );
+}
+
+//------------------------------------------------------------------------------
+void ProgressCmdEnv::update_( uno::Any const & rStatus )
+ throw( uno::RuntimeException )
+{
+ OUString text;
+ if ( rStatus.hasValue() && !( rStatus >>= text) )
+ {
+ if ( rStatus.getValueTypeClass() == uno::TypeClass_EXCEPTION )
+ text = static_cast< uno::Exception const *>( rStatus.getValue() )->Message;
+ if ( text.getLength() == 0 )
+ text = ::comphelper::anyToString( rStatus ); // fallback
+
+ const ::vos::OGuard aGuard( Application::GetSolarMutex() );
+ const ::std::auto_ptr< ErrorBox > aBox( new ErrorBox( m_pDialogHelper? m_pDialogHelper->getWindow() : NULL, WB_OK, text ) );
+ aBox->Execute();
+ }
+ ++m_nCurrentProgress;
+ updateProgress();
+}
+
+//------------------------------------------------------------------------------
+void ProgressCmdEnv::update( uno::Any const & rStatus )
+ throw( uno::RuntimeException )
+{
+ update_( rStatus );
+}
+
+//------------------------------------------------------------------------------
+void ProgressCmdEnv::pop()
+ throw( uno::RuntimeException )
+{
+ update_( uno::Any() ); // no message
+}
+
+//------------------------------------------------------------------------------
+ExtensionCmdQueue::Thread::Thread( DialogHelper *pDialogHelper,
+ TheExtensionManager *pManager,
+ const uno::Reference< uno::XComponentContext > & rContext ) :
+ m_xContext( rContext ),
+ m_pDialogHelper( pDialogHelper ),
+ m_pManager( pManager ),
+ m_sEnablingPackages( DialogHelper::getResourceString( RID_STR_ENABLING_PACKAGES ) ),
+ m_sDisablingPackages( DialogHelper::getResourceString( RID_STR_DISABLING_PACKAGES ) ),
+ m_sAddingPackages( DialogHelper::getResourceString( RID_STR_ADDING_PACKAGES ) ),
+ m_sRemovingPackages( DialogHelper::getResourceString( RID_STR_REMOVING_PACKAGES ) ),
+ m_sDefaultCmd( DialogHelper::getResourceString( RID_STR_ADD_PACKAGES ) ),
+ m_eInput( NONE ),
+ m_bTerminated( false ),
+ m_bStopped( false ),
+ m_bWorking( false )
+{
+ OSL_ASSERT( pDialogHelper );
+}
+
+//------------------------------------------------------------------------------
+void ExtensionCmdQueue::Thread::addExtension( const uno::Reference< deployment::XPackageManager > &rPackageManager,
+ const ::rtl::OUString &rExtensionURL,
+ const bool bWarnUser )
+{
+ ::osl::MutexGuard aGuard( m_mutex );
+
+ //If someone called stop then we do not add the extension -> game over!
+ if ( m_bStopped )
+ return;
+
+ if ( rExtensionURL.getLength() )
+ {
+ TExtensionCmd pEntry( new ExtensionCmd( ExtensionCmd::ADD, rPackageManager, rExtensionURL, bWarnUser ) );
+
+ m_queue.push( pEntry );
+ m_eInput = START;
+ m_wakeup.set();
+ }
+}
+
+//------------------------------------------------------------------------------
+void ExtensionCmdQueue::Thread::removeExtension( const uno::Reference< deployment::XPackageManager > &rPackageManager,
+ const uno::Reference< deployment::XPackage > &rPackage )
+{
+ ::osl::MutexGuard aGuard( m_mutex );
+
+ //If someone called stop then we do not remove the extension -> game over!
+ if ( m_bStopped )
+ return;
+
+ if ( rPackageManager.is() && rPackage.is() )
+ {
+ TExtensionCmd pEntry( new ExtensionCmd( ExtensionCmd::REMOVE, rPackageManager, rPackage ) );
+
+ m_queue.push( pEntry );
+ m_eInput = START;
+ m_wakeup.set();
+ }
+}
+
+//------------------------------------------------------------------------------
+void ExtensionCmdQueue::Thread::enableExtension( const uno::Reference< deployment::XPackage > &rPackage,
+ const bool bEnable )
+{
+ ::osl::MutexGuard aGuard( m_mutex );
+
+ //If someone called stop then we do not remove the extension -> game over!
+ if ( m_bStopped )
+ return;
+
+ if ( rPackage.is() )
+ {
+ TExtensionCmd pEntry( new ExtensionCmd( bEnable ? ExtensionCmd::ENABLE :
+ ExtensionCmd::DISABLE,
+ rPackage ) );
+ m_queue.push( pEntry );
+ m_eInput = START;
+ m_wakeup.set();
+ }
+}
+
+//------------------------------------------------------------------------------
+void ExtensionCmdQueue::Thread::checkForUpdates( const std::vector< TUpdateListEntry > &vExtensionList )
+{
+ ::osl::MutexGuard aGuard( m_mutex );
+
+ //If someone called stop then we do not update the extension -> game over!
+ if ( m_bStopped )
+ return;
+
+ TExtensionCmd pEntry( new ExtensionCmd( ExtensionCmd::CHECK_FOR_UPDATES, vExtensionList ) );
+ m_queue.push( pEntry );
+ m_eInput = START;
+ m_wakeup.set();
+}
+
+//------------------------------------------------------------------------------
+//Stopping this thread will not abort the installation of extensions.
+void ExtensionCmdQueue::Thread::stop()
+{
+ osl::MutexGuard aGuard( m_mutex );
+ m_bStopped = true;
+ m_eInput = STOP;
+ m_wakeup.set();
+}
+
+//------------------------------------------------------------------------------
+bool ExtensionCmdQueue::Thread::hasTerminated()
+{
+ osl::MutexGuard aGuard( m_mutex );
+ return m_bTerminated;
+}
+
+//------------------------------------------------------------------------------
+bool ExtensionCmdQueue::Thread::isBusy()
+{
+ osl::MutexGuard aGuard( m_mutex );
+ return m_bWorking;
+}
+
+//------------------------------------------------------------------------------
+ExtensionCmdQueue::Thread::~Thread() {}
+
+//------------------------------------------------------------------------------
+void ExtensionCmdQueue::Thread::execute()
+{
+#ifdef WNT
+ //Needed for use of the service "com.sun.star.system.SystemShellExecute" in
+ //DialogHelper::openWebBrowser
+ CoUninitialize();
+ HRESULT r = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
+#endif
+ for (;;)
+ {
+ if ( m_wakeup.wait() != osl::Condition::result_ok )
+ {
+ dp_misc::TRACE( "dp_gui::ExtensionCmdQueue::Thread::run: ignored "
+ "osl::Condition::wait failure\n" );
+ }
+ m_wakeup.reset();
+
+ int nSize;
+ Input eInput;
+ {
+ osl::MutexGuard aGuard( m_mutex );
+ eInput = m_eInput;
+ m_eInput = NONE;
+ nSize = m_queue.size();
+ m_bWorking = false;
+ }
+
+ // If this thread has been woken up by anything else except start, stop
+ // then input is NONE and we wait again.
+ // We only install the extension which are currently in the queue.
+ // The progressbar will be set to show the progress of the current number
+ // of extensions. If we allowed to add extensions now then the progressbar may
+ // have reached the end while we still install newly added extensions.
+ if ( ( eInput == NONE ) || ( nSize == 0 ) )
+ continue;
+ if ( eInput == STOP )
+ break;
+
+ ::rtl::Reference< ProgressCmdEnv > currentCmdEnv( new ProgressCmdEnv( m_xContext, m_pDialogHelper, m_sDefaultCmd ) );
+
+ // Do not lock the following part with addExtension. addExtension may be called in the main thread.
+ // If the message box "Do you want to install the extension (or similar)" is shown and then
+ // addExtension is called, which then blocks the main thread, then we deadlock.
+ bool bStartProgress = true;
+
+ while ( !currentCmdEnv->isAborted() && --nSize >= 0 )
+ {
+ {
+ osl::MutexGuard aGuard( m_mutex );
+ m_bWorking = true;
+ }
+
+ try
+ {
+ TExtensionCmd pEntry;
+ {
+ ::osl::MutexGuard queueGuard( m_mutex );
+ pEntry = m_queue.front();
+ m_queue.pop();
+ }
+
+ if ( bStartProgress && ( pEntry->m_eCmdType != ExtensionCmd::CHECK_FOR_UPDATES ) )
+ {
+ currentCmdEnv->startProgress();
+ bStartProgress = false;
+ }
+
+ switch ( pEntry->m_eCmdType ) {
+ case ExtensionCmd::ADD :
+ _addExtension( currentCmdEnv, pEntry->m_xPackageManager, pEntry->m_sExtensionURL, pEntry->m_bWarnUser );
+ break;
+ case ExtensionCmd::REMOVE :
+ _removeExtension( currentCmdEnv, pEntry->m_xPackageManager, pEntry->m_xPackage );
+ break;
+ case ExtensionCmd::ENABLE :
+ _enableExtension( currentCmdEnv, pEntry->m_xPackage );
+ break;
+ case ExtensionCmd::DISABLE :
+ _disableExtension( currentCmdEnv, pEntry->m_xPackage );
+ break;
+ case ExtensionCmd::CHECK_FOR_UPDATES :
+ _checkForUpdates( pEntry->m_vExtensionList );
+ break;
+ }
+ }
+ //catch ( deployment::DeploymentException &)
+ //{
+ //}
+ //catch ( lang::IllegalArgumentException &)
+ //{
+ //}
+ catch ( ucb::CommandAbortedException & )
+ {
+ //This exception is thrown when the user clicks cancel on the progressbar.
+ //Then we cancel the installation of all extensions and remove them from
+ //the queue.
+ {
+ ::osl::MutexGuard queueGuard2(m_mutex);
+ while ( --nSize >= 0 )
+ m_queue.pop();
+ }
+ break;
+ }
+ catch ( ucb::CommandFailedException & )
+ {
+ //This exception is thrown when a user clicked cancel in the messagebox which was
+ //startet by the interaction handler. For example the user will be asked if he/she
+ //really wants to install the extension.
+ //These interaction are run for exectly one extension at a time. Therefore we continue
+ //with installing the remaining extensions.
+ continue;
+ }
+ catch ( uno::Exception & )
+ {
+ //Todo display the user an error
+ //see also DialogImpl::SyncPushButton::Click()
+ uno::Any exc( ::cppu::getCaughtException() );
+ OUString msg;
+ deployment::DeploymentException dpExc;
+ if ((exc >>= dpExc) &&
+ dpExc.Cause.getValueTypeClass() == uno::TypeClass_EXCEPTION)
+ {
+ // notify error cause only:
+ msg = reinterpret_cast< uno::Exception const * >( dpExc.Cause.getValue() )->Message;
+ }
+ if (msg.getLength() == 0) // fallback for debugging purposes
+ msg = ::comphelper::anyToString(exc);
+
+ const ::vos::OGuard guard( Application::GetSolarMutex() );
+ ::std::auto_ptr<ErrorBox> box(
+ new ErrorBox( currentCmdEnv->activeDialog(), WB_OK, msg ) );
+ if ( m_pDialogHelper )
+ box->SetText( m_pDialogHelper->getWindow()->GetText() );
+ box->Execute();
+ //Continue with installation of the remaining extensions
+ }
+ {
+ osl::MutexGuard aGuard( m_mutex );
+ m_bWorking = false;
+ }
+ }
+
+ {
+ // when leaving the while loop with break, we should set working to false, too
+ osl::MutexGuard aGuard( m_mutex );
+ m_bWorking = false;
+ }
+
+ if ( !bStartProgress )
+ currentCmdEnv->stopProgress();
+ }
+ //end for
+ //enable all buttons
+// m_pDialog->m_bAddingExtensions = false;
+// m_pDialog->updateButtonStates();
+#ifdef WNT
+ CoUninitialize();
+#endif
+}
+
+//------------------------------------------------------------------------------
+void ExtensionCmdQueue::Thread::_addExtension( ::rtl::Reference< ProgressCmdEnv > &rCmdEnv,
+ const uno::Reference< deployment::XPackageManager > &xPackageManager,
+ const OUString &rPackageURL,
+ const bool bWarnUser )
+{
+ //check if we have a string in anyTitle. For example "unopkg gui \" caused anyTitle to be void
+ //and anyTitle.get<OUString> throws as RuntimeException.
+ uno::Any anyTitle;
+ try
+ {
+ anyTitle = ::ucbhelper::Content( rPackageURL, rCmdEnv.get() ).getPropertyValue( OUSTR("Title") );
+ }
+ catch ( uno::Exception & )
+ {
+ return;
+ }
+
+ OUString sName;
+ if ( ! (anyTitle >>= sName) )
+ {
+ OSL_ENSURE(0, "Could not get file name for extension.");
+ return;
+ }
+
+ rCmdEnv->setWarnUser( bWarnUser );
+ uno::Reference< task::XAbortChannel > xAbortChannel( xPackageManager->createAbortChannel() );
+ OUString sTitle = searchAndReplaceAll( m_sAddingPackages, OUSTR("%EXTENSION_NAME"), sName );
+ rCmdEnv->progressSection( sTitle, xAbortChannel );
+
+ try
+ {
+ uno::Reference< deployment::XPackage > xPackage( xPackageManager->addPackage(
+ rPackageURL, OUString() /* detect media-type */,
+ xAbortChannel, rCmdEnv.get() ) );
+ OSL_ASSERT( xPackage.is() );
+ }
+ catch ( ucb::CommandFailedException & )
+ {
+ // When the extension is already installed we'll get a dialog asking if we want to overwrite. If we then press
+ // cancel this exception is thrown.
+ }
+ catch ( ucb::CommandAbortedException & )
+ {
+ // User clicked the cancel button
+ // TODO: handle cancel
+ }
+ rCmdEnv->setWarnUser( false );
+}
+
+//------------------------------------------------------------------------------
+void ExtensionCmdQueue::Thread::_removeExtension( ::rtl::Reference< ProgressCmdEnv > &rCmdEnv,
+ const uno::Reference< deployment::XPackageManager > &xPackageManager,
+ const uno::Reference< deployment::XPackage > &xPackage )
+{
+ uno::Reference< task::XAbortChannel > xAbortChannel( xPackageManager->createAbortChannel() );
+ OUString sTitle = searchAndReplaceAll( m_sRemovingPackages, OUSTR("%EXTENSION_NAME"), xPackage->getDisplayName() );
+ rCmdEnv->progressSection( sTitle, xAbortChannel );
+
+ OUString id( dp_misc::getIdentifier( xPackage ) );
+ try
+ {
+ xPackageManager->removePackage( id, xPackage->getName(), xAbortChannel, rCmdEnv.get() );
+ }
+ catch ( ucb::CommandAbortedException & )
+ {}
+
+ // Check, if there are still updates to be notified via menu bar icon
+ uno::Sequence< uno::Sequence< rtl::OUString > > aItemList;
+ UpdateDialog::createNotifyJob( false, aItemList );
+}
+
+//------------------------------------------------------------------------------
+void ExtensionCmdQueue::Thread::_checkForUpdates( const std::vector< TUpdateListEntry > &vExtensionList )
+{
+ UpdateDialog* pUpdateDialog;
+ std::vector< UpdateData > vData;
+
+ const ::vos::OGuard guard( Application::GetSolarMutex() );
+
+ pUpdateDialog = new UpdateDialog( m_xContext, m_pDialogHelper? m_pDialogHelper->getWindow() : NULL, vExtensionList, &vData );
+
+ pUpdateDialog->notifyMenubar( true, false ); // prepare the checking, if there updates to be notified via menu bar icon
+
+ if ( ( pUpdateDialog->Execute() == RET_OK ) && !vData.empty() )
+ {
+ // If there is at least one directly downloadable dialog then we
+ // open the install dialog.
+ ::std::vector< UpdateData > dataDownload;
+ int countWebsiteDownload = 0;
+ typedef std::vector< dp_gui::UpdateData >::const_iterator cit;
+
+ for ( cit i = vData.begin(); i < vData.end(); i++ )
+ {
+ if ( i->sWebsiteURL.getLength() > 0 )
+ countWebsiteDownload ++;
+ else
+ dataDownload.push_back( *i );
+ }
+
+ short nDialogResult = RET_OK;
+ if ( !dataDownload.empty() )
+ {
+ nDialogResult = UpdateInstallDialog( m_pDialogHelper? m_pDialogHelper->getWindow() : NULL, dataDownload, m_xContext ).Execute();
+ pUpdateDialog->notifyMenubar( false, true ); // Check, if there are still pending updates to be notified via menu bar icon
+ }
+ else
+ pUpdateDialog->notifyMenubar( false, false ); // Check, if there are pending updates to be notified via menu bar icon
+
+ //Now start the webbrowser and navigate to the websites where we get the updates
+ if ( RET_OK == nDialogResult )
+ {
+ for ( cit i = vData.begin(); i < vData.end(); i++ )
+ {
+ if ( m_pDialogHelper && ( i->sWebsiteURL.getLength() > 0 ) )
+ m_pDialogHelper->openWebBrowser( i->sWebsiteURL, m_pDialogHelper->getWindow()->GetText() );
+ }
+ }
+ }
+ else
+ pUpdateDialog->notifyMenubar( false, false ); // check if there updates to be notified via menu bar icon
+
+ delete pUpdateDialog;
+}
+
+//------------------------------------------------------------------------------
+void ExtensionCmdQueue::Thread::_enableExtension( ::rtl::Reference< ProgressCmdEnv > &rCmdEnv,
+ const uno::Reference< deployment::XPackage > &xPackage )
+{
+ if ( !xPackage.is() )
+ return;
+
+ uno::Reference< task::XAbortChannel > xAbortChannel( xPackage->createAbortChannel() );
+ OUString sTitle = searchAndReplaceAll( m_sEnablingPackages, OUSTR("%EXTENSION_NAME"), xPackage->getDisplayName() );
+ rCmdEnv->progressSection( sTitle, xAbortChannel );
+
+ try
+ {
+ xPackage->registerPackage( xAbortChannel, rCmdEnv.get() );
+ if ( m_pDialogHelper )
+ m_pDialogHelper->updatePackageInfo( xPackage );
+ }
+ catch ( ::ucb::CommandAbortedException & )
+ {}
+}
+
+//------------------------------------------------------------------------------
+void ExtensionCmdQueue::Thread::_disableExtension( ::rtl::Reference< ProgressCmdEnv > &rCmdEnv,
+ const uno::Reference< deployment::XPackage > &xPackage )
+{
+ if ( !xPackage.is() )
+ return;
+
+ uno::Reference< task::XAbortChannel > xAbortChannel( xPackage->createAbortChannel() );
+ OUString sTitle = searchAndReplaceAll( m_sDisablingPackages, OUSTR("%EXTENSION_NAME"), xPackage->getDisplayName() );
+ rCmdEnv->progressSection( sTitle, xAbortChannel );
+
+ try
+ {
+ xPackage->revokePackage( xAbortChannel, rCmdEnv.get() );
+ if ( m_pDialogHelper )
+ m_pDialogHelper->updatePackageInfo( xPackage );
+ }
+ catch ( ::ucb::CommandAbortedException & )
+ {}
+}
+
+//------------------------------------------------------------------------------
+void ExtensionCmdQueue::Thread::onTerminated()
+{
+ ::osl::MutexGuard g(m_mutex);
+ m_bTerminated = true;
+}
+
+//------------------------------------------------------------------------------
+OUString ExtensionCmdQueue::Thread::searchAndReplaceAll( const OUString &rSource,
+ const OUString &rWhat,
+ const OUString &rWith )
+{
+ OUString aRet( rSource );
+ sal_Int32 nLen = rWhat.getLength();
+
+ if ( !nLen )
+ return aRet;
+
+ sal_Int32 nIndex = rSource.indexOf( rWhat );
+ while ( nIndex != -1 )
+ {
+ aRet = aRet.replaceAt( nIndex, nLen, rWith );
+ nIndex = aRet.indexOf( rWhat, nIndex + rWith.getLength() );
+ }
+ return aRet;
+}
+
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+ExtensionCmdQueue::ExtensionCmdQueue( DialogHelper * pDialogHelper,
+ TheExtensionManager *pManager,
+ const uno::Reference< uno::XComponentContext > &rContext )
+ : m_thread( new Thread( pDialogHelper, pManager, rContext ) )
+{
+ m_thread->launch();
+}
+
+ExtensionCmdQueue::~ExtensionCmdQueue() {
+ stop();
+}
+
+void ExtensionCmdQueue::addExtension( const uno::Reference< deployment::XPackageManager > &rPackageManager,
+ const ::rtl::OUString & extensionURL,
+ const bool bWarnUser )
+{
+ m_thread->addExtension( rPackageManager, extensionURL, bWarnUser );
+}
+
+void ExtensionCmdQueue::removeExtension( const uno::Reference< deployment::XPackageManager > &rPackageManager,
+ const uno::Reference< deployment::XPackage > &rPackage )
+{
+ m_thread->removeExtension( rPackageManager, rPackage );
+}
+
+void ExtensionCmdQueue::enableExtension( const uno::Reference< deployment::XPackage > &rPackage,
+ const bool bEnable )
+{
+ m_thread->enableExtension( rPackage, bEnable );
+}
+
+void ExtensionCmdQueue::checkForUpdates( const std::vector< TUpdateListEntry > &vExtensionList )
+{
+ m_thread->checkForUpdates( vExtensionList );
+}
+
+void ExtensionCmdQueue::stop()
+{
+ m_thread->stop();
+}
+
+void ExtensionCmdQueue::stopAndWait()
+{
+ m_thread->stop();
+ m_thread->join();
+}
+
+bool ExtensionCmdQueue::hasTerminated()
+{
+ return m_thread->hasTerminated();
+}
+
+bool ExtensionCmdQueue::isBusy()
+{
+ return m_thread->isBusy();
+}
+
+void handleInteractionRequest( const uno::Reference< uno::XComponentContext > & xContext,
+ const uno::Reference< task::XInteractionRequest > & xRequest )
+{
+ ::rtl::Reference< ProgressCmdEnv > xCmdEnv( new ProgressCmdEnv( xContext, NULL, OUSTR("Extension Manager") ) );
+ xCmdEnv->handle( xRequest );
+}
+
+} //namespace dp_gui
+
diff --git a/desktop/source/deployment/gui/dp_gui_extensioncmdqueue.hxx b/desktop/source/deployment/gui/dp_gui_extensioncmdqueue.hxx
new file mode 100644
index 000000000000..2d24f00e3c8e
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_extensioncmdqueue.hxx
@@ -0,0 +1,122 @@
+/*************************************************************************
+ *
+ * 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: dp_gui_extensioncmdqueue.hxx,v $
+ *
+ * $Revision: 1.3.14.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 INCLUDED_DP_GUI_EXTENSIONCMDQUEUE_HXX
+#define INCLUDED_DP_GUI_EXTENSIONCMDQUEUE_HXX
+
+#include "sal/config.h"
+
+#include "com/sun/star/uno/Reference.hxx"
+#include "rtl/ref.hxx"
+
+#include <vector>
+
+#include "dp_gui_updatedata.hxx"
+
+/// @HTML
+
+namespace com { namespace sun { namespace star {
+ namespace deployment { class XPackageManager; }
+ namespace task { class XInteractionRequest; }
+ namespace uno { class XComponentContext; }
+} } }
+
+namespace dp_gui {
+
+class DialogHelper;
+class TheExtensionManager;
+
+/**
+ Manages installing of extensions in the GUI mode. Requests for installing
+ Extensions can be asynchronous. For example, the Extension Manager is running
+ in an office process and someone uses the system integration to install an Extension.
+ That is, the user double clicks an extension symbol in a file browser, which then
+ causes an invocation of "unopkg gui ext". When at that time the Extension Manager
+ already performs a task, triggered by the user (for example, add, update, disable,
+ enable) then adding of the extension will be postponed until the user has finished
+ the task.
+
+ This class also ensures that the extensions are not installed in the main thread.
+ Doing so would cause a deadlock because of the progress bar which needs to be constantly
+ updated.
+*/
+class ExtensionCmdQueue {
+
+public:
+ /**
+ Create an instance.
+ */
+ ExtensionCmdQueue( DialogHelper * pDialogHelper,
+ TheExtensionManager *pManager,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > & rContext);
+
+ ~ExtensionCmdQueue();
+
+ /**
+ */
+ void addExtension( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackageManager > &rPackageManager,
+ const ::rtl::OUString &rExtensionURL,
+ const bool bWarnUser );
+ void removeExtension( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackageManager > &rPackageManager,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &rPackage );
+ void enableExtension( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &rPackage,
+ const bool bEnable );
+ void checkForUpdates( const std::vector< TUpdateListEntry > &vList );
+ /**
+ This call does not block. It signals the internal thread
+ that it should install the remaining extensions and then terminate.
+ */
+ void stop();
+
+ /** Determines if thread of this class has terminated.
+ */
+ bool hasTerminated();
+
+ /** Blocks until the thread has terminated. All URLs in the queue will be processed.
+ */
+ void stopAndWait();
+
+ bool isBusy();
+private:
+ ExtensionCmdQueue(ExtensionCmdQueue &); // not defined
+ void operator =(ExtensionCmdQueue &); // not defined
+
+ class Thread;
+
+ rtl::Reference< Thread > m_thread;
+};
+
+void handleInteractionRequest( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > & xContext,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionRequest > & xRequest );
+
+}
+
+#endif
diff --git a/desktop/source/deployment/gui/dp_gui_extlistbox.cxx b/desktop/source/deployment/gui/dp_gui_extlistbox.cxx
new file mode 100644
index 000000000000..f4473c2c6fd8
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_extlistbox.cxx
@@ -0,0 +1,1175 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2009 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "svtools/controldims.hrc"
+
+#include "dp_gui.h"
+#include "dp_gui_extlistbox.hxx"
+#include "dp_gui_theextmgr.hxx"
+#include "dp_gui_dialog2.hxx"
+#include "dp_dependencies.hxx"
+
+#include "comphelper/processfactory.hxx"
+#include "com/sun/star/i18n/CollatorOptions.hpp"
+#include "com/sun/star/deployment/DependencyException.hpp"
+#include "com/sun/star/deployment/DeploymentException.hpp"
+
+
+#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
+
+using namespace ::com::sun::star;
+
+namespace dp_gui {
+
+//------------------------------------------------------------------------------
+// struct Entry_Impl
+//------------------------------------------------------------------------------
+Entry_Impl::Entry_Impl( const uno::Reference< deployment::XPackage > &xPackage,
+ const uno::Reference< deployment::XPackageManager > &xPackageManager,
+ PackageState eState ) :
+ m_bActive( false ),
+ m_bLocked( false ),
+ m_bHasOptions( false ),
+ m_bShared( false ),
+ m_bNew( false ),
+ m_bChecked( false ),
+ m_bMissingDeps( false ),
+ m_eState( eState ),
+ m_pPublisher( NULL ),
+ m_xPackage( xPackage ),
+ m_xPackageManager( xPackageManager )
+{
+ m_sTitle = xPackage->getDisplayName();
+ m_sVersion = xPackage->getVersion();
+ m_sDescription = xPackage->getDescription();
+
+ beans::StringPair aInfo( m_xPackage->getPublisherInfo() );
+ m_sPublisher = aInfo.First;
+ m_sPublisherURL = aInfo.Second;
+
+ // get the icons for the package if there are any
+ uno::Reference< graphic::XGraphic > xGraphic = xPackage->getIcon( false );
+ if ( xGraphic.is() )
+ m_aIcon = Image( xGraphic );
+
+ xGraphic = xPackage->getIcon( true );
+ if ( xGraphic.is() )
+ m_aIconHC = Image( xGraphic );
+ else
+ m_aIconHC = m_aIcon;
+
+ m_bLocked = m_xPackageManager->isReadOnly();
+
+ if ( eState == AMBIGUOUS )
+ m_sErrorText = DialogHelper::getResourceString( RID_STR_ERROR_UNKNOWN_STATUS );
+ else if ( eState == NOT_REGISTERED )
+ checkDependencies();
+}
+
+//------------------------------------------------------------------------------
+Entry_Impl::~Entry_Impl()
+{}
+
+//------------------------------------------------------------------------------
+StringCompare Entry_Impl::CompareTo( const CollatorWrapper *pCollator, const TEntry_Impl pEntry ) const
+{
+ StringCompare eCompare = (StringCompare) pCollator->compareString( m_sTitle, pEntry->m_sTitle );
+ if ( eCompare == COMPARE_EQUAL )
+ {
+ eCompare = m_sVersion.CompareTo( pEntry->m_sVersion );
+ if ( eCompare == COMPARE_EQUAL )
+ {
+ if ( m_xPackageManager != pEntry->m_xPackageManager )
+ {
+ sal_Int32 nCompare = m_xPackageManager->getContext().compareTo( pEntry->m_xPackageManager->getContext() );
+ if ( nCompare < 0 )
+ eCompare = COMPARE_LESS;
+ else if ( nCompare > 0 )
+ eCompare = COMPARE_GREATER;
+ }
+ }
+ }
+ return eCompare;
+}
+
+//------------------------------------------------------------------------------
+void Entry_Impl::checkDependencies()
+{
+ try {
+ m_xPackage->checkDependencies( uno::Reference< ucb::XCommandEnvironment >() );
+ }
+ catch ( deployment::DeploymentException &e )
+ {
+ deployment::DependencyException depExc;
+ if ( e.Cause >>= depExc )
+ {
+ rtl::OUString aMissingDep( DialogHelper::getResourceString( RID_STR_ERROR_MISSING_DEPENDENCIES ) );
+ for ( sal_Int32 i = 0; i < depExc.UnsatisfiedDependencies.getLength(); ++i )
+ {
+ aMissingDep += OUSTR("\n");
+ aMissingDep += dp_misc::Dependencies::getErrorText( depExc.UnsatisfiedDependencies[i]);
+ }
+ aMissingDep += OUSTR("\n");
+ m_sErrorText = aMissingDep;
+ m_bMissingDeps = true;
+ }
+ }
+}
+//------------------------------------------------------------------------------
+// ExtensionRemovedListener
+//------------------------------------------------------------------------------
+void ExtensionRemovedListener::disposing( lang::EventObject const & rEvt )
+ throw ( uno::RuntimeException )
+{
+ uno::Reference< deployment::XPackage > xPackage( rEvt.Source, uno::UNO_QUERY );
+
+ if ( xPackage.is() )
+ {
+ m_pParent->removeEntry( xPackage );
+ }
+}
+
+//------------------------------------------------------------------------------
+ExtensionRemovedListener::~ExtensionRemovedListener()
+{
+}
+
+//------------------------------------------------------------------------------
+// ExtensionBox_Impl
+//------------------------------------------------------------------------------
+ExtensionBox_Impl::ExtensionBox_Impl( Dialog* pParent, TheExtensionManager *pManager ) :
+ IExtensionListBox( pParent, WB_BORDER | WB_TABSTOP | WB_CHILDDLGCTRL ),
+ m_bHasScrollBar( false ),
+ m_bHasActive( false ),
+ m_bNeedsRecalc( true ),
+ m_bHasNew( false ),
+ m_bInCheckMode( false ),
+ m_bAdjustActive( false ),
+ m_bInDelete( false ),
+ m_nActive( 0 ),
+ m_nTopIndex( 0 ),
+ m_nActiveHeight( 0 ),
+ m_nExtraHeight( 2 ),
+ m_aLockedImage( DialogHelper::getResId( RID_IMG_LOCKED ) ),
+ m_aLockedImageHC( DialogHelper::getResId( RID_IMG_LOCKED_HC ) ),
+ m_aWarningImage( DialogHelper::getResId( RID_IMG_WARNING ) ),
+ m_aWarningImageHC( DialogHelper::getResId( RID_IMG_WARNING_HC ) ),
+ m_aDefaultImage( DialogHelper::getResId( RID_IMG_EXTENSION ) ),
+ m_aDefaultImageHC( DialogHelper::getResId( RID_IMG_EXTENSION_HC ) ),
+ m_pScrollBar( NULL ),
+ m_pManager( pManager )
+{
+ SetHelpId( HID_EXTENSION_MANAGER_LISTBOX );
+
+ m_pScrollBar = new ScrollBar( this, WB_VERT );
+ m_pScrollBar->SetScrollHdl( LINK( this, ExtensionBox_Impl, ScrollHdl ) );
+ m_pScrollBar->EnableDrag();
+
+ SetPaintTransparent( true );
+ SetPosPixel( Point( RSC_SP_DLG_INNERBORDER_LEFT, RSC_SP_DLG_INNERBORDER_TOP ) );
+ long nIconHeight = 2*TOP_OFFSET + SMALL_ICON_SIZE;
+ long nTitleHeight = 2*TOP_OFFSET + GetTextHeight();
+ if ( nIconHeight < nTitleHeight )
+ m_nStdHeight = nTitleHeight;
+ else
+ m_nStdHeight = nIconHeight;
+ m_nStdHeight += GetTextHeight() + TOP_OFFSET;
+
+ nIconHeight = ICON_HEIGHT + 2*TOP_OFFSET + 1;
+ if ( m_nStdHeight < nIconHeight )
+ m_nStdHeight = nIconHeight;
+
+ m_nActiveHeight = m_nStdHeight;
+
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ if( IsControlBackground() )
+ SetBackground( GetControlBackground() );
+ else
+ SetBackground( rStyleSettings.GetFieldColor() );
+
+ m_xRemoveListener = new ExtensionRemovedListener( this );
+
+ m_pLocale = new lang::Locale( Application::GetSettings().GetLocale() );
+ m_pCollator = new CollatorWrapper( ::comphelper::getProcessServiceFactory() );
+ m_pCollator->loadDefaultCollator( *m_pLocale, i18n::CollatorOptions::CollatorOptions_IGNORE_CASE );
+
+ Show();
+}
+
+//------------------------------------------------------------------------------
+ExtensionBox_Impl::~ExtensionBox_Impl()
+{
+ if ( ! m_bInDelete )
+ DeleteRemoved();
+
+ m_bInDelete = true;
+
+ typedef std::vector< TEntry_Impl >::iterator ITER;
+
+ for ( ITER iIndex = m_vEntries.begin(); iIndex < m_vEntries.end(); ++iIndex )
+ {
+ if ( (*iIndex)->m_pPublisher )
+ {
+ delete (*iIndex)->m_pPublisher;
+ (*iIndex)->m_pPublisher = NULL;
+ }
+ (*iIndex)->m_xPackage->removeEventListener( uno::Reference< lang::XEventListener > ( m_xRemoveListener, uno::UNO_QUERY ) );
+ }
+
+ m_vEntries.clear();
+
+ delete m_pScrollBar;
+
+ m_xRemoveListener.clear();
+
+ delete m_pLocale;
+ delete m_pCollator;
+}
+
+//------------------------------------------------------------------------------
+sal_Int32 ExtensionBox_Impl::getItemCount() const
+{
+ return static_cast< sal_Int32 >( m_vEntries.size() );
+}
+
+//------------------------------------------------------------------------------
+sal_Int32 ExtensionBox_Impl::getSelIndex() const
+{
+ if ( m_bHasActive )
+ {
+ OSL_ASSERT( m_nActive >= -1);
+ return static_cast< sal_Int32 >( m_nActive );
+ }
+ else
+ return static_cast< sal_Int32 >( EXTENSION_LISTBOX_ENTRY_NOTFOUND );
+}
+
+//------------------------------------------------------------------------------
+void ExtensionBox_Impl::checkIndex( sal_Int32 nIndex ) const
+{
+ if ( nIndex < 0 )
+ throw lang::IllegalArgumentException( OUSTR("The list index starts with 0"),0, 0 );
+ if ( static_cast< sal_uInt32 >( nIndex ) >= m_vEntries.size())
+ throw lang::IllegalArgumentException( OUSTR("There is no element at the provided position."
+ "The position exceeds the number of available list entries"),0, 0 );
+}
+
+//------------------------------------------------------------------------------
+rtl::OUString ExtensionBox_Impl::getItemName( sal_Int32 nIndex ) const
+{
+ const ::osl::MutexGuard aGuard( m_entriesMutex );
+ checkIndex( nIndex );
+ return m_vEntries[ nIndex ]->m_sTitle;
+}
+
+//------------------------------------------------------------------------------
+rtl::OUString ExtensionBox_Impl::getItemVersion( sal_Int32 nIndex ) const
+{
+ const ::osl::MutexGuard aGuard( m_entriesMutex );
+ checkIndex( nIndex );
+ return m_vEntries[ nIndex ]->m_sVersion;
+}
+
+//------------------------------------------------------------------------------
+rtl::OUString ExtensionBox_Impl::getItemDescription( sal_Int32 nIndex ) const
+{
+ const ::osl::MutexGuard aGuard( m_entriesMutex );
+ checkIndex( nIndex );
+ return m_vEntries[ nIndex ]->m_sDescription;
+}
+
+//------------------------------------------------------------------------------
+rtl::OUString ExtensionBox_Impl::getItemPublisher( sal_Int32 nIndex ) const
+{
+ const ::osl::MutexGuard aGuard( m_entriesMutex );
+ checkIndex( nIndex );
+ return m_vEntries[ nIndex ]->m_sPublisher;
+}
+
+//------------------------------------------------------------------------------
+rtl::OUString ExtensionBox_Impl::getItemPublisherLink( sal_Int32 nIndex ) const
+{
+ const ::osl::MutexGuard aGuard( m_entriesMutex );
+ checkIndex( nIndex );
+ return m_vEntries[ nIndex ]->m_sPublisherURL;
+}
+
+//------------------------------------------------------------------------------
+void ExtensionBox_Impl::select( sal_Int32 nIndex )
+{
+ const ::osl::MutexGuard aGuard( m_entriesMutex );
+ checkIndex( nIndex );
+ selectEntry( nIndex );
+}
+
+//------------------------------------------------------------------------------
+void ExtensionBox_Impl::select( const rtl::OUString & sName )
+{
+ const ::osl::MutexGuard aGuard( m_entriesMutex );
+ typedef ::std::vector< TEntry_Impl >::const_iterator It;
+
+ for ( It iIter = m_vEntries.begin(); iIter < m_vEntries.end(); iIter++ )
+ {
+ if ( sName.equals( (*iIter)->m_sTitle ) )
+ {
+ long nPos = iIter - m_vEntries.begin();
+ selectEntry( nPos );
+ break;
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+// Title + description
+void ExtensionBox_Impl::CalcActiveHeight( const long nPos )
+{
+ const ::osl::MutexGuard aGuard( m_entriesMutex );
+
+ // get title height
+ long aTextHeight;
+ long nIconHeight = 2*TOP_OFFSET + SMALL_ICON_SIZE;
+ long nTitleHeight = 2*TOP_OFFSET + GetTextHeight();
+ if ( nIconHeight < nTitleHeight )
+ aTextHeight = nTitleHeight;
+ else
+ aTextHeight = nIconHeight;
+
+ // calc description height
+ Size aSize = GetOutputSizePixel();
+ if ( m_bHasScrollBar )
+ aSize.Width() -= m_pScrollBar->GetSizePixel().Width();
+
+ aSize.Width() -= ICON_OFFSET;
+ aSize.Height() = 10000;
+
+ rtl::OUString aText( m_vEntries[ nPos ]->m_sErrorText );
+ aText += m_vEntries[ nPos ]->m_sDescription;
+
+ Rectangle aRect = GetTextRect( Rectangle( Point(), aSize ), aText,
+ TEXT_DRAW_MULTILINE | TEXT_DRAW_WORDBREAK );
+ aTextHeight += aRect.GetHeight();
+
+ if ( aTextHeight < m_nStdHeight )
+ aTextHeight = m_nStdHeight;
+
+ m_nActiveHeight = aTextHeight + m_nExtraHeight;
+}
+
+//------------------------------------------------------------------------------
+const Size ExtensionBox_Impl::GetMinOutputSizePixel() const
+{
+ return Size( 200, 80 );
+}
+
+//------------------------------------------------------------------------------
+Rectangle ExtensionBox_Impl::GetEntryRect( const long nPos ) const
+{
+ const ::osl::MutexGuard aGuard( m_entriesMutex );
+
+ Size aSize( GetOutputSizePixel() );
+
+ if ( m_bHasScrollBar )
+ aSize.Width() -= m_pScrollBar->GetSizePixel().Width();
+
+ if ( m_vEntries[ nPos ]->m_bActive )
+ aSize.Height() = m_nActiveHeight;
+ else
+ aSize.Height() = m_nStdHeight;
+
+ Point aPos( 0, -m_nTopIndex + nPos * m_nStdHeight );
+ if ( m_bHasActive && ( nPos < m_nActive ) )
+ aPos.Y() += m_nActiveHeight - m_nStdHeight;
+
+ return Rectangle( aPos, aSize );
+}
+
+//------------------------------------------------------------------------------
+void ExtensionBox_Impl::DeleteRemoved()
+{
+ const ::osl::MutexGuard aGuard( m_entriesMutex );
+
+ m_bInDelete = true;
+
+ if ( ! m_vRemovedEntries.empty() )
+ {
+ typedef std::vector< TEntry_Impl >::iterator ITER;
+
+ for ( ITER iIndex = m_vRemovedEntries.begin(); iIndex < m_vRemovedEntries.end(); ++iIndex )
+ {
+ if ( (*iIndex)->m_pPublisher )
+ {
+ delete (*iIndex)->m_pPublisher;
+ (*iIndex)->m_pPublisher = NULL;
+ }
+ }
+
+ m_vRemovedEntries.clear();
+ }
+
+ m_bInDelete = false;
+}
+
+//------------------------------------------------------------------------------
+//This function may be called with nPos < 0
+void ExtensionBox_Impl::selectEntry( const long nPos )
+{
+ //ToDo whe should not use the guard at such a big scope here.
+ //Currently it is used to gard m_vEntries and m_nActive. m_nActive will be
+ //modified in this function.
+ //It would be probably best to always use a copy of m_vEntries
+ //and some other state variables from ExtensionBox_Impl for
+ //the whole painting operation. See issue i86993
+ ::osl::ClearableMutexGuard guard(m_entriesMutex);
+
+ if ( m_bInCheckMode )
+ return;
+
+ if ( m_bHasActive )
+ {
+ if ( nPos == m_nActive )
+ return;
+
+ m_bHasActive = false;
+ m_vEntries[ m_nActive ]->m_bActive = false;
+ }
+
+ if ( ( nPos >= 0 ) && ( nPos < (long) m_vEntries.size() ) )
+ {
+ m_bHasActive = true;
+ m_nActive = nPos;
+ m_vEntries[ nPos ]->m_bActive = true;
+
+ if ( IsReallyVisible() )
+ {
+ m_bNeedsRecalc = true;
+ m_bAdjustActive = true;
+ }
+ }
+
+ if ( IsReallyVisible() )
+ Invalidate();
+
+ guard.clear();
+}
+
+// -----------------------------------------------------------------------
+void ExtensionBox_Impl::DrawRow( const Rectangle& rRect, const TEntry_Impl pEntry )
+{
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+
+ if ( pEntry->m_bActive )
+ SetTextColor( rStyleSettings.GetHighlightTextColor() );
+ else if ( ( pEntry->m_eState != REGISTERED ) && ( pEntry->m_eState != NOT_AVAILABLE ) )
+ SetTextColor( rStyleSettings.GetDisableColor() );
+ else if ( IsControlForeground() )
+ SetTextColor( GetControlForeground() );
+ else
+ SetTextColor( rStyleSettings.GetFieldTextColor() );
+
+ if ( pEntry->m_bActive )
+ {
+ SetLineColor();
+ SetFillColor( rStyleSettings.GetHighlightColor() );
+ DrawRect( rRect );
+ }
+ else
+ {
+ if( IsControlBackground() )
+ SetBackground( GetControlBackground() );
+ else
+ SetBackground( rStyleSettings.GetFieldColor() );
+
+ SetTextFillColor();
+ Erase( rRect );
+ }
+
+ // Draw extension icon
+ Point aPos( rRect.TopLeft() );
+ aPos += Point( TOP_OFFSET, TOP_OFFSET );
+ Image aImage;
+ if ( ! pEntry->m_aIcon )
+ aImage = isHCMode() ? m_aDefaultImageHC : m_aDefaultImage;
+ else
+ aImage = isHCMode() ? pEntry->m_aIconHC : pEntry->m_aIcon;
+ Size aImageSize = aImage.GetSizePixel();
+ if ( ( aImageSize.Width() <= ICON_HEIGHT ) && ( aImageSize.Height() <= ICON_HEIGHT ) )
+ DrawImage( Point( aPos.X()+((ICON_HEIGHT-aImageSize.Width())/2), aPos.Y()+((ICON_HEIGHT-aImageSize.Height())/2) ), aImage );
+ else
+ DrawImage( aPos, Size( ICON_HEIGHT, ICON_HEIGHT ), aImage );
+
+ // Setup fonts
+ Font aStdFont( GetFont() );
+ Font aBoldFont( aStdFont );
+ aBoldFont.SetWeight( WEIGHT_BOLD );
+ SetFont( aBoldFont );
+ long aTextHeight = GetTextHeight();
+
+ // Init publisher link here
+ if ( !pEntry->m_pPublisher && pEntry->m_sPublisher.Len() )
+ {
+ pEntry->m_pPublisher = new svt::FixedHyperlink( this );
+ pEntry->m_pPublisher->SetBackground();
+ pEntry->m_pPublisher->SetPaintTransparent( true );
+ pEntry->m_pPublisher->SetURL( pEntry->m_sPublisherURL );
+ pEntry->m_pPublisher->SetDescription( pEntry->m_sPublisher );
+ Size aSize = FixedText::CalcMinimumTextSize( pEntry->m_pPublisher );
+ pEntry->m_pPublisher->SetSizePixel( aSize );
+
+ if ( m_aClickHdl.IsSet() )
+ pEntry->m_pPublisher->SetClickHdl( m_aClickHdl );
+ }
+
+ // Get max title width
+ long nMaxTitleWidth = rRect.GetWidth() - ICON_OFFSET;
+ nMaxTitleWidth -= ( 2 * SMALL_ICON_SIZE ) + ( 4 * SPACE_BETWEEN );
+ if ( pEntry->m_pPublisher )
+ {
+ nMaxTitleWidth -= pEntry->m_pPublisher->GetSizePixel().Width() + (2*SPACE_BETWEEN);
+ }
+
+ long aVersionWidth = GetTextWidth( pEntry->m_sVersion );
+ long aTitleWidth = GetTextWidth( pEntry->m_sTitle ) + (aTextHeight / 3);
+
+ aPos = rRect.TopLeft() + Point( ICON_OFFSET, TOP_OFFSET );
+
+ if ( aTitleWidth > nMaxTitleWidth - aVersionWidth )
+ {
+ aTitleWidth = nMaxTitleWidth - aVersionWidth - (aTextHeight / 3);
+ String aShortTitle = GetEllipsisString( pEntry->m_sTitle, aTitleWidth );
+ DrawText( aPos, aShortTitle );
+ aTitleWidth += (aTextHeight / 3);
+ }
+ else
+ DrawText( aPos, pEntry->m_sTitle );
+
+ SetFont( aStdFont );
+ DrawText( Point( aPos.X() + aTitleWidth, aPos.Y() ), pEntry->m_sVersion );
+
+ long nIconHeight = TOP_OFFSET + SMALL_ICON_SIZE;
+ long nTitleHeight = TOP_OFFSET + GetTextHeight();
+ if ( nIconHeight < nTitleHeight )
+ aTextHeight = nTitleHeight;
+ else
+ aTextHeight = nIconHeight;
+
+ // draw description
+ String sDescription;
+ if ( pEntry->m_sErrorText.Len() )
+ {
+ if ( pEntry->m_bActive )
+ sDescription = pEntry->m_sErrorText + OUSTR("\n") + pEntry->m_sDescription;
+ else
+ sDescription = pEntry->m_sErrorText;
+ }
+ else
+ sDescription = pEntry->m_sDescription;
+
+ aPos.Y() += aTextHeight;
+ if ( pEntry->m_bActive )
+ {
+ DrawText( Rectangle( aPos.X(), aPos.Y(), rRect.Right(), rRect.Bottom() - m_nExtraHeight ),
+ sDescription, TEXT_DRAW_MULTILINE | TEXT_DRAW_WORDBREAK );
+ }
+ else
+ {
+ const long nWidth = GetTextWidth( sDescription );
+ if ( nWidth > rRect.GetWidth() - aPos.X() )
+ sDescription = GetEllipsisString( sDescription, rRect.GetWidth() - aPos.X() );
+ DrawText( aPos, sDescription );
+ }
+
+ // Draw publisher link
+ if ( pEntry->m_pPublisher )
+ {
+ pEntry->m_pPublisher->Show();
+ aPos = rRect.TopLeft() + Point( ICON_OFFSET + nMaxTitleWidth + (2*SPACE_BETWEEN), TOP_OFFSET );
+ pEntry->m_pPublisher->SetPosPixel( aPos );
+ }
+
+ // Draw status icons
+ if ( pEntry->m_bShared )
+ {
+ aPos = rRect.TopRight() + Point( -(RIGHT_ICON_OFFSET + SMALL_ICON_SIZE), TOP_OFFSET );
+ DrawImage( aPos, Size( SMALL_ICON_SIZE, SMALL_ICON_SIZE ), isHCMode() ? m_aLockedImageHC : m_aLockedImage );
+ }
+ if ( ( pEntry->m_eState == AMBIGUOUS ) || pEntry->m_bMissingDeps )
+ {
+ aPos = rRect.TopRight() + Point( -(RIGHT_ICON_OFFSET + SPACE_BETWEEN + 2*SMALL_ICON_SIZE), TOP_OFFSET );
+ DrawImage( aPos, Size( SMALL_ICON_SIZE, SMALL_ICON_SIZE ), isHCMode() ? m_aWarningImageHC : m_aWarningImage );
+ }
+
+ SetLineColor( Color( COL_LIGHTGRAY ) );
+ DrawLine( rRect.BottomLeft(), rRect.BottomRight() );
+}
+
+// -----------------------------------------------------------------------
+void ExtensionBox_Impl::RecalcAll()
+{
+ if ( m_bHasActive )
+ CalcActiveHeight( m_nActive );
+
+ SetupScrollBar();
+
+ if ( m_bHasActive )
+ {
+ Rectangle aEntryRect = GetEntryRect( m_nActive );
+
+ if ( m_bAdjustActive )
+ {
+ m_bAdjustActive = false;
+
+ // If the top of the selected entry isn't visible, make it visible
+ if ( aEntryRect.Top() < 0 )
+ {
+ m_nTopIndex += aEntryRect.Top();
+ aEntryRect.Move( 0, -aEntryRect.Top() );
+ }
+
+ // If the bottom of the selected entry isn't visible, make it visible even if now the top
+ // isn't visible any longer ( the buttons are more important )
+ Size aOutputSize = GetOutputSizePixel();
+ if ( aEntryRect.Bottom() > aOutputSize.Height() )
+ {
+ m_nTopIndex += ( aEntryRect.Bottom() - aOutputSize.Height() );
+ aEntryRect.Move( 0, -( aEntryRect.Bottom() - aOutputSize.Height() ) );
+ }
+
+ // If there is unused space below the last entry but all entries don't fit into the box,
+ // move the content down to use the whole space
+ const long nTotalHeight = GetTotalHeight();
+ if ( m_bHasScrollBar && ( aOutputSize.Height() + m_nTopIndex > nTotalHeight ) )
+ {
+ long nOffset = m_nTopIndex;
+ m_nTopIndex = nTotalHeight - aOutputSize.Height();
+ nOffset -= m_nTopIndex;
+ aEntryRect.Move( 0, nOffset );
+ }
+
+ if ( m_bHasScrollBar )
+ m_pScrollBar->SetThumbPos( m_nTopIndex );
+ }
+ }
+
+ m_bNeedsRecalc = false;
+}
+
+// -----------------------------------------------------------------------
+bool ExtensionBox_Impl::HandleTabKey( bool )
+{
+ return false;
+}
+
+// -----------------------------------------------------------------------
+bool ExtensionBox_Impl::HandleCursorKey( USHORT nKeyCode )
+{
+ if ( m_vEntries.empty() )
+ return true;
+
+ long nSelect = 0;
+
+ if ( m_bHasActive )
+ {
+ long nPageSize = GetOutputSizePixel().Height() / m_nStdHeight;
+ if ( nPageSize < 2 )
+ nPageSize = 2;
+
+ if ( ( nKeyCode == KEY_DOWN ) || ( nKeyCode == KEY_RIGHT ) )
+ nSelect = m_nActive + 1;
+ else if ( ( nKeyCode == KEY_UP ) || ( nKeyCode == KEY_LEFT ) )
+ nSelect = m_nActive - 1;
+ else if ( nKeyCode == KEY_HOME )
+ nSelect = 0;
+ else if ( nKeyCode == KEY_END )
+ nSelect = m_vEntries.size() - 1;
+ else if ( nKeyCode == KEY_PAGEUP )
+ nSelect = m_nActive - nPageSize + 1;
+ else if ( nKeyCode == KEY_PAGEDOWN )
+ nSelect = m_nActive + nPageSize - 1;
+ }
+ else // when there is no selected entry, we will select the first or the last.
+ {
+ if ( ( nKeyCode == KEY_DOWN ) || ( nKeyCode == KEY_PAGEDOWN ) || ( nKeyCode == KEY_HOME ) )
+ nSelect = 0;
+ else if ( ( nKeyCode == KEY_UP ) || ( nKeyCode == KEY_PAGEUP ) || ( nKeyCode == KEY_END ) )
+ nSelect = m_vEntries.size() - 1;
+ }
+
+ if ( nSelect < 0 )
+ nSelect = 0;
+ if ( nSelect >= (long) m_vEntries.size() )
+ nSelect = m_vEntries.size() - 1;
+
+ selectEntry( nSelect );
+
+ return true;
+}
+
+// -----------------------------------------------------------------------
+void ExtensionBox_Impl::Paint( const Rectangle &/*rPaintRect*/ )
+{
+ if ( !m_bInDelete )
+ DeleteRemoved();
+
+ if ( m_bNeedsRecalc )
+ RecalcAll();
+
+ Point aStart( 0, -m_nTopIndex );
+ Size aSize( GetOutputSizePixel() );
+
+ if ( m_bHasScrollBar )
+ aSize.Width() -= m_pScrollBar->GetSizePixel().Width();
+
+ const ::osl::MutexGuard aGuard( m_entriesMutex );
+
+ typedef std::vector< TEntry_Impl >::iterator ITER;
+ for ( ITER iIndex = m_vEntries.begin(); iIndex < m_vEntries.end(); ++iIndex )
+ {
+ aSize.Height() = (*iIndex)->m_bActive ? m_nActiveHeight : m_nStdHeight;
+ Rectangle aEntryRect( aStart, aSize );
+ DrawRow( aEntryRect, *iIndex );
+ aStart.Y() += aSize.Height();
+ }
+}
+
+// -----------------------------------------------------------------------
+long ExtensionBox_Impl::GetTotalHeight() const
+{
+ long nHeight = m_vEntries.size() * m_nStdHeight;
+
+ if ( m_bHasActive )
+ {
+ nHeight += m_nActiveHeight - m_nStdHeight;
+ }
+
+ return nHeight;
+}
+
+// -----------------------------------------------------------------------
+void ExtensionBox_Impl::SetupScrollBar()
+{
+ const Size aSize = GetOutputSizePixel();
+ const long nScrBarSize = GetSettings().GetStyleSettings().GetScrollBarSize();
+ const long nTotalHeight = GetTotalHeight();
+ const bool bNeedsScrollBar = ( nTotalHeight > aSize.Height() );
+
+ if ( bNeedsScrollBar )
+ {
+ if ( m_nTopIndex + aSize.Height() > nTotalHeight )
+ m_nTopIndex = nTotalHeight - aSize.Height();
+
+ m_pScrollBar->SetPosSizePixel( Point( aSize.Width() - nScrBarSize, 0 ),
+ Size( nScrBarSize, aSize.Height() ) );
+ m_pScrollBar->SetRangeMax( nTotalHeight );
+ m_pScrollBar->SetVisibleSize( aSize.Height() );
+ m_pScrollBar->SetPageSize( ( aSize.Height() * 4 ) / 5 );
+ m_pScrollBar->SetLineSize( m_nStdHeight );
+ m_pScrollBar->SetThumbPos( m_nTopIndex );
+
+ if ( !m_bHasScrollBar )
+ m_pScrollBar->Show();
+ }
+ else if ( m_bHasScrollBar )
+ {
+ m_pScrollBar->Hide();
+ m_nTopIndex = 0;
+ }
+
+ m_bHasScrollBar = bNeedsScrollBar;
+}
+
+// -----------------------------------------------------------------------
+void ExtensionBox_Impl::Resize()
+{
+ RecalcAll();
+}
+
+//------------------------------------------------------------------------------
+long ExtensionBox_Impl::PointToPos( const Point& rPos )
+{
+ long nPos = ( rPos.Y() + m_nTopIndex ) / m_nStdHeight;
+
+ if ( m_bHasActive && ( nPos > m_nActive ) )
+ {
+ if ( rPos.Y() + m_nTopIndex <= m_nActive*m_nStdHeight + m_nActiveHeight )
+ nPos = m_nActive;
+ else
+ nPos = ( rPos.Y() + m_nTopIndex - (m_nActiveHeight - m_nStdHeight) ) / m_nStdHeight;
+ }
+
+ return nPos;
+}
+
+//------------------------------------------------------------------------------
+void ExtensionBox_Impl::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ long nPos = PointToPos( rMEvt.GetPosPixel() );
+
+ if ( rMEvt.IsLeft() )
+ {
+ if ( rMEvt.IsMod1() && m_bHasActive )
+ selectEntry( m_vEntries.size() ); // Selecting an not existing entry will deselect the current one
+ else
+ selectEntry( nPos );
+ }
+}
+
+//------------------------------------------------------------------------------
+long ExtensionBox_Impl::Notify( NotifyEvent& rNEvt )
+{
+ if ( !m_bInDelete )
+ DeleteRemoved();
+
+ bool bHandled = false;
+
+ if ( rNEvt.GetType() == EVENT_KEYINPUT )
+ {
+ const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
+ KeyCode aKeyCode = pKEvt->GetKeyCode();
+ USHORT nKeyCode = aKeyCode.GetCode();
+
+ if ( nKeyCode == KEY_TAB )
+ bHandled = HandleTabKey( aKeyCode.IsShift() );
+ else if ( aKeyCode.GetGroup() == KEYGROUP_CURSOR )
+ bHandled = HandleCursorKey( nKeyCode );
+ }
+
+ if ( rNEvt.GetType() == EVENT_COMMAND )
+ {
+ if ( m_bHasScrollBar &&
+ ( rNEvt.GetCommandEvent()->GetCommand() == COMMAND_WHEEL ) )
+ {
+ const CommandWheelData* pData = rNEvt.GetCommandEvent()->GetWheelData();
+ if ( pData->GetMode() == COMMAND_WHEEL_SCROLL )
+ {
+ long nThumbPos = m_pScrollBar->GetThumbPos();
+ if ( pData->GetDelta() < 0 )
+ m_pScrollBar->DoScroll( nThumbPos + m_nStdHeight );
+ else
+ m_pScrollBar->DoScroll( nThumbPos - m_nStdHeight );
+ bHandled = true;
+ }
+ }
+ }
+
+ if ( !bHandled )
+ return Control::Notify( rNEvt );
+ else
+ return true;
+}
+
+//------------------------------------------------------------------------------
+bool ExtensionBox_Impl::FindEntryPos( const TEntry_Impl pEntry, const long nStart,
+ const long nEnd, long &nPos )
+{
+ nPos = nStart;
+ if ( nStart > nEnd )
+ return false;
+
+ StringCompare eCompare;
+
+ if ( nStart == nEnd )
+ {
+ eCompare = pEntry->CompareTo( m_pCollator, m_vEntries[ nStart ] );
+ if ( eCompare == COMPARE_LESS )
+ return false;
+ else if ( eCompare == COMPARE_EQUAL )
+ {
+ //Workaround. See i86963.
+ if (pEntry->m_xPackage != m_vEntries[nStart]->m_xPackage)
+ return false;
+
+ if ( m_bInCheckMode )
+ m_vEntries[ nStart ]->m_bChecked = true;
+ return true;
+ }
+ else
+ {
+ nPos = nStart + 1;
+ return false;
+ }
+ }
+
+ const long nMid = nStart + ( ( nEnd - nStart ) / 2 );
+ eCompare = pEntry->CompareTo( m_pCollator, m_vEntries[ nMid ] );
+
+ if ( eCompare == COMPARE_LESS )
+ return FindEntryPos( pEntry, nStart, nMid-1, nPos );
+ else if ( eCompare == COMPARE_GREATER )
+ return FindEntryPos( pEntry, nMid+1, nEnd, nPos );
+ else
+ {
+ //Workaround.See i86963.
+ if (pEntry->m_xPackage != m_vEntries[nMid]->m_xPackage)
+ return false;
+
+ if ( m_bInCheckMode )
+ m_vEntries[ nMid ]->m_bChecked = true;
+ nPos = nMid;
+ return true;
+ }
+}
+
+//------------------------------------------------------------------------------
+long ExtensionBox_Impl::addEntry( const uno::Reference< deployment::XPackage > &xPackage,
+ const uno::Reference< deployment::XPackageManager > &xPackageManager )
+{
+ long nPos = 0;
+ PackageState eState = m_pManager->getPackageState( xPackage );
+
+ TEntry_Impl pEntry( new Entry_Impl( xPackage, xPackageManager, eState ) );
+ xPackage->addEventListener( uno::Reference< lang::XEventListener > ( m_xRemoveListener, uno::UNO_QUERY ) );
+
+ ::osl::ClearableMutexGuard guard(m_entriesMutex);
+ if ( m_vEntries.empty() )
+ {
+ pEntry->m_bHasOptions = m_pManager->supportsOptions( xPackage );
+ pEntry->m_bShared = ( m_pManager->getSharedPkgMgr() == xPackageManager );
+ pEntry->m_bNew = m_bInCheckMode;
+ m_vEntries.push_back( pEntry );
+ }
+ else
+ {
+ if ( !FindEntryPos( pEntry, 0, m_vEntries.size()-1, nPos ) )
+ {
+ pEntry->m_bHasOptions = m_pManager->supportsOptions( xPackage );
+ pEntry->m_bShared = ( m_pManager->getSharedPkgMgr() == xPackageManager );
+ pEntry->m_bNew = m_bInCheckMode;
+ m_vEntries.insert( m_vEntries.begin()+nPos, pEntry );
+ }
+ else if ( !m_bInCheckMode )
+ {
+ OSL_ENSURE( 0, "ExtensionBox_Impl::addEntry(): Will not add duplicate entries" );
+ }
+ }
+ //access to m_nActive must be guarded
+ if ( !m_bInCheckMode && m_bHasActive && ( m_nActive >= nPos ) )
+ m_nActive += 1;
+
+ guard.clear();
+
+ if ( IsReallyVisible() )
+ Invalidate();
+
+ m_bNeedsRecalc = true;
+
+ return nPos;
+}
+
+//------------------------------------------------------------------------------
+void ExtensionBox_Impl::updateEntry( const uno::Reference< deployment::XPackage > &xPackage )
+{
+ typedef std::vector< TEntry_Impl >::iterator ITER;
+ for ( ITER iIndex = m_vEntries.begin(); iIndex < m_vEntries.end(); ++iIndex )
+ {
+ if ( (*iIndex)->m_xPackage == xPackage )
+ {
+ PackageState eState = m_pManager->getPackageState( xPackage );
+ (*iIndex)->m_bHasOptions = m_pManager->supportsOptions( xPackage );
+ (*iIndex)->m_eState = eState;
+ (*iIndex)->m_sTitle = xPackage->getDisplayName();
+ (*iIndex)->m_sVersion = xPackage->getVersion();
+ (*iIndex)->m_sDescription = xPackage->getDescription();
+
+ if ( eState == AMBIGUOUS )
+ (*iIndex)->m_sErrorText = DialogHelper::getResourceString( RID_STR_ERROR_UNKNOWN_STATUS );
+ else
+ (*iIndex)->m_sErrorText = String();
+
+ if ( IsReallyVisible() )
+ Invalidate();
+ break;
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+void ExtensionBox_Impl::removeEntry( const uno::Reference< deployment::XPackage > &xPackage )
+{
+ if ( ! m_bInDelete )
+ {
+ ::osl::ClearableMutexGuard aGuard( m_entriesMutex );
+
+ typedef std::vector< TEntry_Impl >::iterator ITER;
+
+ for ( ITER iIndex = m_vEntries.begin(); iIndex < m_vEntries.end(); ++iIndex )
+ {
+ if ( (*iIndex)->m_xPackage == xPackage )
+ {
+ long nPos = iIndex - m_vEntries.begin();
+
+ // Entries mustn't removed here, because they contain a hyperlink control
+ // which can only be deleted when the thread has the solar mutex. Therefor
+ // the entry will be moved into the m_vRemovedEntries list which will be
+ // cleared on the next paint event
+ m_vRemovedEntries.push_back( *iIndex );
+ m_vEntries.erase( iIndex );
+
+ m_bNeedsRecalc = true;
+
+ if ( IsReallyVisible() )
+ Invalidate();
+
+ if ( m_bHasActive )
+ {
+ if ( nPos < m_nActive )
+ m_nActive -= 1;
+ else if ( ( nPos == m_nActive ) &&
+ ( nPos == (long) m_vEntries.size() ) )
+ m_nActive -= 1;
+
+ m_bHasActive = false;
+ //clear before calling out of this method
+ aGuard.clear();
+ selectEntry( m_nActive );
+ }
+ break;
+ }
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+void ExtensionBox_Impl::RemoveUnlocked()
+{
+ bool bAllRemoved = false;
+
+ while ( ! bAllRemoved )
+ {
+ bAllRemoved = true;
+
+ ::osl::ClearableMutexGuard aGuard( m_entriesMutex );
+
+ typedef std::vector< TEntry_Impl >::iterator ITER;
+
+ for ( ITER iIndex = m_vEntries.begin(); iIndex < m_vEntries.end(); ++iIndex )
+ {
+ if ( !(*iIndex)->m_bLocked )
+ {
+ bAllRemoved = false;
+ uno::Reference< deployment::XPackage> xPackage = (*iIndex)->m_xPackage;
+ aGuard.clear();
+ removeEntry( xPackage );
+ break;
+ }
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+void ExtensionBox_Impl::prepareChecking( const uno::Reference< deployment::XPackageManager > &xPackageMgr )
+{
+ m_bInCheckMode = true;
+ typedef std::vector< TEntry_Impl >::iterator ITER;
+ for ( ITER iIndex = m_vEntries.begin(); iIndex < m_vEntries.end(); ++iIndex )
+ {
+ if ( (*iIndex)->m_xPackageManager == xPackageMgr )
+ (*iIndex)->m_bChecked = false;
+ else
+ (*iIndex)->m_bChecked = true;
+ (*iIndex)->m_bNew = false;
+ }
+}
+
+//------------------------------------------------------------------------------
+void ExtensionBox_Impl::checkEntries()
+{
+ long nNewPos = -1;
+ long nPos = 0;
+ bool bNeedsUpdate = false;
+
+ ::osl::ClearableMutexGuard guard(m_entriesMutex);
+ typedef std::vector< TEntry_Impl >::iterator ITER;
+ ITER iIndex = m_vEntries.begin();
+ while ( iIndex < m_vEntries.end() )
+ {
+ if ( (*iIndex)->m_bChecked == false )
+ {
+ bNeedsUpdate = true;
+ nPos = iIndex-m_vEntries.begin();
+ if ( (*iIndex)->m_bNew )
+ {
+ if ( nNewPos == - 1)
+ nNewPos = nPos;
+ if ( nPos <= m_nActive )
+ m_nActive += 1;
+ }
+ }
+ iIndex++;
+ }
+ guard.clear();
+
+ m_bInCheckMode = false;
+
+ if ( nNewPos != - 1)
+ selectEntry( nNewPos );
+
+ if ( bNeedsUpdate )
+ {
+ m_bNeedsRecalc = true;
+ if ( IsReallyVisible() )
+ Invalidate();
+ }
+}
+//------------------------------------------------------------------------------
+bool ExtensionBox_Impl::isHCMode()
+{
+ return (bool)GetDisplayBackground().GetColor().IsDark();
+}
+
+//------------------------------------------------------------------------------
+void ExtensionBox_Impl::SetScrollHdl( const Link& rLink )
+{
+ if ( m_pScrollBar )
+ m_pScrollBar->SetScrollHdl( rLink );
+}
+
+// -----------------------------------------------------------------------
+void ExtensionBox_Impl::DoScroll( long nDelta )
+{
+ m_nTopIndex += nDelta;
+ Point aNewSBPt( m_pScrollBar->GetPosPixel() );
+
+ Rectangle aScrRect( Point(), GetOutputSizePixel() );
+ aScrRect.Right() -= m_pScrollBar->GetSizePixel().Width();
+ Scroll( 0, -nDelta, aScrRect );
+
+ m_pScrollBar->SetPosPixel( aNewSBPt );
+}
+
+// -----------------------------------------------------------------------
+IMPL_LINK( ExtensionBox_Impl, ScrollHdl, ScrollBar*, pScrBar )
+{
+ DoScroll( pScrBar->GetDelta() );
+
+ return 1;
+}
+
+} //namespace dp_gui
diff --git a/desktop/source/deployment/gui/dp_gui_extlistbox.hxx b/desktop/source/deployment/gui/dp_gui_extlistbox.hxx
new file mode 100644
index 000000000000..e1a17bb06dc9
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_extlistbox.hxx
@@ -0,0 +1,271 @@
+/*************************************************************************
+ *
+ * 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: dp_gui_dialog2.cxx,v $
+ *
+ * $Revision: 1.8.4.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 "rtl/ustring.hxx"
+#include "vcl/scrbar.hxx"
+#include "vcl/fixed.hxx"
+#include "vcl/dialog.hxx"
+
+#include "svtools/extensionlistbox.hxx"
+#include "svtools/fixedhyper.hxx"
+#include "cppuhelper/implbase1.hxx"
+#include "unotools/collatorwrapper.hxx"
+
+#include "com/sun/star/lang/Locale.hpp"
+#include "com/sun/star/lang/XEventListener.hpp"
+#include "com/sun/star/deployment/XPackage.hpp"
+#include "com/sun/star/deployment/XPackageManager.hpp"
+
+#include <boost/shared_ptr.hpp>
+
+namespace dp_gui {
+
+#define SMALL_ICON_SIZE 16
+#define TOP_OFFSET 3
+#define ICON_HEIGHT 42
+#define ICON_OFFSET 50
+#define RIGHT_ICON_OFFSET 5
+#define SPACE_BETWEEN 3
+
+class TheExtensionManager;
+
+typedef ::boost::shared_ptr< svt::FixedHyperlink > TFixedHyperlink;
+
+//------------------------------------------------------------------------------
+// struct Entry_Impl
+//------------------------------------------------------------------------------
+struct Entry_Impl;
+
+typedef ::boost::shared_ptr< Entry_Impl > TEntry_Impl;
+
+struct Entry_Impl
+{
+ bool m_bActive;
+ bool m_bLocked;
+ bool m_bHasOptions;
+ bool m_bShared;
+ bool m_bNew;
+ bool m_bChecked;
+ bool m_bMissingDeps;
+ PackageState m_eState;
+ String m_sTitle;
+ String m_sVersion;
+ String m_sDescription;
+ String m_sPublisher;
+ String m_sPublisherURL;
+ String m_sErrorText;
+ Image m_aIcon;
+ Image m_aIconHC;
+ svt::FixedHyperlink *m_pPublisher;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage> m_xPackage;
+ ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackageManager> m_xPackageManager;
+
+ Entry_Impl( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackageManager > &xPackageManager,
+ PackageState eState );
+ ~Entry_Impl();
+
+ StringCompare CompareTo( const CollatorWrapper *pCollator, const TEntry_Impl pEntry ) const;
+ void checkDependencies();
+};
+
+//------------------------------------------------------------------------------
+// class ExtensionBox_Impl
+//------------------------------------------------------------------------------
+
+class ExtensionBox_Impl;
+
+//------------------------------------------------------------------------------
+class ExtensionRemovedListener : public ::cppu::WeakImplHelper1< ::com::sun::star::lang::XEventListener >
+{
+ ExtensionBox_Impl *m_pParent;
+
+public:
+
+ ExtensionRemovedListener( ExtensionBox_Impl *pParent ) { m_pParent = pParent; }
+ ~ExtensionRemovedListener();
+
+ //===================================================================================
+ // XEventListener
+ virtual void SAL_CALL disposing( ::com::sun::star::lang::EventObject const & evt )
+ throw (::com::sun::star::uno::RuntimeException);
+};
+
+//------------------------------------------------------------------------------
+class ExtensionBox_Impl : public ::svt::IExtensionListBox
+{
+ bool m_bHasScrollBar;
+ bool m_bHasActive;
+ bool m_bNeedsRecalc;
+ bool m_bHasNew;
+ bool m_bInCheckMode;
+ bool m_bAdjustActive;
+ bool m_bInDelete;
+ //Must be guarded together with m_vEntries to ensure a valid index at all times.
+ //Use m_entriesMutex as guard.
+ long m_nActive;
+ long m_nTopIndex;
+ long m_nStdHeight;
+ long m_nActiveHeight;
+ long m_nExtraHeight;
+ Size m_aOutputSize;
+ Image m_aLockedImage;
+ Image m_aLockedImageHC;
+ Image m_aWarningImage;
+ Image m_aWarningImageHC;
+ Image m_aDefaultImage;
+ Image m_aDefaultImageHC;
+ Link m_aClickHdl;
+
+ ScrollBar *m_pScrollBar;
+
+ com::sun::star::uno::Reference< ExtensionRemovedListener > m_xRemoveListener;
+
+ TheExtensionManager *m_pManager;
+ //This mutex is used for synchronizing access to m_vEntries.
+ //Currently it is used to synchronize adding, removing entries and
+ //functions like getItemName, getItemDescription, etc. to prevent
+ //that m_vEntries is accessed at an invalid index.
+ //ToDo: There are many more places where m_vEntries is read and which may
+ //fail. For example the Paint method is probable called from the main thread
+ //while new entries are added / removed in a separate thread.
+ mutable ::osl::Mutex m_entriesMutex;
+ std::vector< TEntry_Impl > m_vEntries;
+ std::vector< TEntry_Impl > m_vRemovedEntries;
+
+ ::com::sun::star::lang::Locale *m_pLocale;
+ CollatorWrapper *m_pCollator;
+
+ void CalcActiveHeight( const long nPos );
+ long GetTotalHeight() const;
+ void SetupScrollBar();
+ void DrawRow( const Rectangle& rRect, const TEntry_Impl pEntry );
+ bool HandleTabKey( bool bReverse );
+ bool HandleCursorKey( USHORT nKeyCode );
+ bool FindEntryPos( const TEntry_Impl pEntry, long nStart, long nEnd, long &nFound );
+ bool isHCMode();
+ void DeleteRemoved();
+
+ //-----------------
+ DECL_DLLPRIVATE_LINK( ScrollHdl, ScrollBar * );
+
+ //Index starts with 1.
+ //Throws an com::sun::star::lang::IllegalArgumentException, when the index is invalid.
+ void checkIndex(sal_Int32 pos) const;
+
+
+public:
+ ExtensionBox_Impl( Dialog* pParent, TheExtensionManager *pManager );
+ ~ExtensionBox_Impl();
+
+ virtual void MouseButtonDown( const MouseEvent& rMEvt );
+ virtual void Paint( const Rectangle &rPaintRect );
+ virtual void Resize();
+ virtual long Notify( NotifyEvent& rNEvt );
+
+ const Size GetMinOutputSizePixel() const;
+ void SetExtraSize( long nSize ) { m_nExtraHeight = nSize; }
+ TEntry_Impl GetEntryData( long nPos ) { return m_vEntries[ nPos ]; }
+ long GetEntryCount() { return (long) m_vEntries.size(); }
+ Rectangle GetEntryRect( const long nPos ) const;
+ bool HasActive() { return m_bHasActive; }
+ long PointToPos( const Point& rPos );
+ void SetScrollHdl( const Link& rLink );
+ void DoScroll( long nDelta );
+ void SetHyperlinkHdl( const Link& rLink ){ m_aClickHdl = rLink; }
+ virtual void RecalcAll();
+ void RemoveUnlocked();
+
+ //-----------------
+ virtual void selectEntry( const long nPos );
+ long addEntry( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackageManager > &xPackageManager );
+ void updateEntry( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage );
+ void removeEntry( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage );
+
+ void prepareChecking( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackageManager > &xPackageMgr );
+ void checkEntries();
+
+ TheExtensionManager* getExtensionManager() const { return m_pManager; }
+
+ //===================================================================================
+ //These functions are used for automatic testing
+
+ /** @return The count of the entries in the list box. */
+ virtual sal_Int32 getItemCount() const;
+
+ /** @return The index of the first selected entry in the list box.
+ When nothing is selected, which is the case when getItemCount returns '0',
+ then this function returns EXTENSION_LISTBOX_ENTRY_NOTFOUND */
+ virtual sal_Int32 getSelIndex() const;
+
+ /** @return The item name of the entry with the given index
+ The index starts with 0.
+ Throws an com::sun::star::lang::IllegalArgumentException, when the position is invalid. */
+ virtual ::rtl::OUString getItemName( sal_Int32 index ) const;
+
+ /** @return The version string of the entry with the given index
+ The index starts with 0.
+ Throws an com::sun::star::lang::IllegalArgumentException, when the position is invalid. */
+ virtual ::rtl::OUString getItemVersion( sal_Int32 index ) const;
+
+ /** @return The description string of the entry with the given index
+ The index starts with 0.
+ Throws an com::sun::star::lang::IllegalArgumentException, when the position is invalid. */
+ virtual ::rtl::OUString getItemDescription( sal_Int32 index ) const;
+
+ /** @return The publisher string of the entry with the given index
+ The index starts with 0.
+ Throws an com::sun::star::lang::IllegalArgumentException, when the position is invalid. */
+ virtual ::rtl::OUString getItemPublisher( sal_Int32 index ) const;
+
+ /** @return The link behind the publisher text of the entry with the given index
+ The index starts with 0.
+ Throws an com::sun::star::lang::IllegalArgumentException, when the position is invalid. */
+ virtual ::rtl::OUString getItemPublisherLink( sal_Int32 index ) const;
+
+ /** The entry at the given position will be selected
+ Index starts with 0.
+ Throws an com::sun::star::lang::IllegalArgumentException, when the position is invalid. */
+ virtual void select( sal_Int32 pos );
+
+ /** The first found entry with the given name will be selected
+ When there was no entry found with the name, the selection doesn't change.
+ Please note that there might be more than one entry with the same
+ name, because:
+ 1. the name is not unique
+ 2. one extension can be installed as user and shared extension.
+ */
+ virtual void select( const ::rtl::OUString & sName );
+};
+
+}
diff --git a/desktop/source/deployment/gui/dp_gui_service.cxx b/desktop/source/deployment/gui/dp_gui_service.cxx
new file mode 100644
index 000000000000..ee8c5d26c24f
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_service.cxx
@@ -0,0 +1,369 @@
+/*************************************************************************
+ *
+ * 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: dp_gui_service.cxx,v $
+ * $Revision: 1.23.86.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_desktop.hxx"
+
+#include "dp_gui_shared.hxx"
+#include "dp_gui.h"
+#include "dp_gui_theextmgr.hxx"
+#include "cppuhelper/implbase2.hxx"
+#include "cppuhelper/implementationentry.hxx"
+#include "unotools/configmgr.hxx"
+#include "comphelper/servicedecl.hxx"
+#include "comphelper/unwrapargs.hxx"
+#include <i18npool/mslangid.hxx>
+#include "vcl/svapp.hxx"
+#include "vcl/msgbox.hxx"
+#include "com/sun/star/lang/XServiceInfo.hpp"
+#include "com/sun/star/task/XJobExecutor.hpp"
+#include "com/sun/star/ui/dialogs/XAsynchronousExecutableDialog.hpp"
+
+#include "boost/bind.hpp"
+#include "license_dialog.hxx"
+#include "dp_gui_dialog2.hxx"
+
+using namespace ::dp_misc;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+
+using ::rtl::OUString;
+
+namespace css = ::com::sun::star;
+namespace dp_gui {
+
+//==============================================================================
+class MyApp : public Application, private boost::noncopyable
+{
+public:
+ MyApp();
+ virtual ~MyApp();
+
+ // Application
+ virtual void Main();
+};
+
+//______________________________________________________________________________
+MyApp::~MyApp()
+{
+}
+
+//______________________________________________________________________________
+MyApp::MyApp()
+{
+}
+
+//______________________________________________________________________________
+void MyApp::Main()
+{
+}
+
+//##############################################################################
+
+namespace
+{
+ struct ProductName
+ : public rtl::Static< String, ProductName > {};
+ struct Version
+ : public rtl::Static< String, Version > {};
+ struct AboutBoxVersion
+ : public rtl::Static< String, AboutBoxVersion > {};
+ struct Extension
+ : public rtl::Static< String, Extension > {};
+}
+
+void ReplaceProductNameHookProc( String& rStr )
+{
+ static int nAll = 0, nPro = 0;
+
+ nAll++;
+ if ( rStr.SearchAscii( "%PRODUCT" ) != STRING_NOTFOUND )
+ {
+ String &rProductName = ProductName::get();
+ String &rVersion = Version::get();
+ String &rAboutBoxVersion = AboutBoxVersion::get();
+ String &rExtension = Extension::get();
+
+ if ( !rProductName.Len() )
+ {
+ rtl::OUString aTmp;
+ Any aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTNAME );
+ aRet >>= aTmp;
+ rProductName = aTmp;
+
+ aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTVERSION );
+ aRet >>= aTmp;
+ rVersion = aTmp;
+
+ aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::ABOUTBOXPRODUCTVERSION );
+ aRet >>= aTmp;
+ rAboutBoxVersion = aTmp;
+
+ if ( !rExtension.Len() )
+ {
+ aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTEXTENSION );
+ aRet >>= aTmp;
+ rExtension = aTmp;
+ }
+ }
+
+ nPro++;
+ rStr.SearchAndReplaceAllAscii( "%PRODUCTNAME", rProductName );
+ rStr.SearchAndReplaceAllAscii( "%PRODUCTVERSION", rVersion );
+ rStr.SearchAndReplaceAllAscii( "%ABOUTBOXPRODUCTVERSION", rAboutBoxVersion );
+ rStr.SearchAndReplaceAllAscii( "%PRODUCTEXTENSION", rExtension );
+ }
+}
+
+//==============================================================================
+class ServiceImpl
+ : public ::cppu::WeakImplHelper2<ui::dialogs::XAsynchronousExecutableDialog,
+ task::XJobExecutor>
+{
+ Reference<XComponentContext> const m_xComponentContext;
+ boost::optional< Reference<awt::XWindow> > /* const */ m_parent;
+ boost::optional<OUString> /* const */ m_view;
+ /* if true then this service is running in an unopkg process and not in an office process */
+ boost::optional<sal_Bool> /* const */ m_unopkg;
+ boost::optional<OUString> m_extensionURL;
+ OUString m_initialTitle;
+ bool m_bShowUpdateOnly;
+
+public:
+ ServiceImpl( Sequence<Any> const & args,
+ Reference<XComponentContext> const & xComponentContext );
+
+ // XAsynchronousExecutableDialog
+ virtual void SAL_CALL setDialogTitle( OUString const & aTitle )
+ throw (RuntimeException);
+ virtual void SAL_CALL startExecuteModal(
+ Reference< ui::dialogs::XDialogClosedListener > const & xListener )
+ throw (RuntimeException);
+
+ // XJobExecutor
+ virtual void SAL_CALL trigger( OUString const & event )
+ throw (RuntimeException);
+};
+
+//______________________________________________________________________________
+ServiceImpl::ServiceImpl( Sequence<Any> const& args,
+ Reference<XComponentContext> const& xComponentContext)
+ : m_xComponentContext(xComponentContext),
+ m_bShowUpdateOnly( false )
+{
+ try {
+ comphelper::unwrapArgs( args, m_parent, m_view, m_unopkg );
+ return;
+ } catch (css::lang::IllegalArgumentException & ) {
+ }
+ try {
+ comphelper::unwrapArgs( args, m_extensionURL);
+ } catch (css::lang::IllegalArgumentException & ) {
+ }
+
+ ResHookProc pProc = ResMgr::GetReadStringHook();
+ if ( !pProc )
+ ResMgr::SetReadStringHook( ReplaceProductNameHookProc );
+}
+
+// XAsynchronousExecutableDialog
+//______________________________________________________________________________
+void ServiceImpl::setDialogTitle( OUString const & title )
+ throw (RuntimeException)
+{
+ if ( dp_gui::TheExtensionManager::s_ExtMgr.is() )
+ {
+ const ::vos::OGuard guard( Application::GetSolarMutex() );
+ ::rtl::Reference< ::dp_gui::TheExtensionManager > dialog(
+ ::dp_gui::TheExtensionManager::get( m_xComponentContext,
+ m_parent ? *m_parent : Reference<awt::XWindow>(),
+ m_extensionURL ? *m_extensionURL : OUString() ) );
+ dialog->SetText( title );
+ }
+ else
+ m_initialTitle = title;
+}
+
+//______________________________________________________________________________
+void ServiceImpl::startExecuteModal(
+ Reference< ui::dialogs::XDialogClosedListener > const & xListener )
+ throw (RuntimeException)
+{
+ bool bCloseDialog = true; // only used if m_bShowUpdateOnly is true
+ ::std::auto_ptr<Application> app;
+ //ToDo: synchronize access to s_dialog !!!
+ if (! dp_gui::TheExtensionManager::s_ExtMgr.is())
+ {
+ const bool bAppUp = (GetpApp() != 0);
+ bool bOfficePipePresent;
+ try {
+ bOfficePipePresent = dp_misc::office_is_running();
+ }
+ catch (Exception & exc) {
+ if (bAppUp) {
+ const vos::OGuard guard( Application::GetSolarMutex() );
+ std::auto_ptr<ErrorBox> box(
+ new ErrorBox( Application::GetActiveTopWindow(),
+ WB_OK, exc.Message ) );
+ box->Execute();
+ }
+ throw;
+ }
+
+ if (! bOfficePipePresent) {
+ OSL_ASSERT( ! bAppUp );
+ app.reset( new MyApp );
+ if (! InitVCL( Reference<lang::XMultiServiceFactory>(
+ m_xComponentContext->getServiceManager(),
+ UNO_QUERY_THROW ) ))
+ throw RuntimeException( OUSTR("Cannot initialize VCL!"),
+ static_cast<OWeakObject *>(this) );
+ AllSettings as = app->GetSettings();
+ OUString slang;
+ if (! (::utl::ConfigManager::GetDirectConfigProperty(
+ ::utl::ConfigManager::LOCALE ) >>= slang))
+ throw RuntimeException( OUSTR("Cannot determine language!"),
+ static_cast<OWeakObject *>(this) );
+ as.SetUILanguage( MsLangId::convertIsoStringToLanguage( slang ) );
+ app->SetSettings( as );
+ String sTitle = ::utl::ConfigManager::GetDirectConfigProperty(
+ ::utl::ConfigManager::PRODUCTNAME).get<OUString>()
+ + String(static_cast<sal_Unicode>(' '))
+ + ::utl::ConfigManager::GetDirectConfigProperty(
+ ::utl::ConfigManager::PRODUCTVERSION).get<OUString>();
+ app->SetDisplayName(sTitle);
+ }
+ }
+ else
+ {
+ // When m_bShowUpdateOnly is set, we are inside the office and the user clicked
+ // the update notification icon in the menu bar. We must not close the extensions
+ // dialog after displaying the update dialog when it has been visible before
+ if ( m_bShowUpdateOnly )
+ bCloseDialog = ! dp_gui::TheExtensionManager::s_ExtMgr->isVisible();
+ }
+
+ {
+ const ::vos::OGuard guard( Application::GetSolarMutex() );
+ ::rtl::Reference< ::dp_gui::TheExtensionManager > myExtMgr(
+ ::dp_gui::TheExtensionManager::get(
+ m_xComponentContext,
+ m_parent ? *m_parent : Reference<awt::XWindow>(),
+ m_extensionURL ? *m_extensionURL : OUString() ) );
+ myExtMgr->createDialog( false );
+ if (m_initialTitle.getLength() > 0) {
+ myExtMgr->SetText( m_initialTitle );
+ m_initialTitle = OUString();
+ }
+ if ( m_bShowUpdateOnly )
+ {
+ myExtMgr->checkUpdates( true, !bCloseDialog );
+ if ( bCloseDialog )
+ myExtMgr->Close();
+ else
+ myExtMgr->ToTop( TOTOP_RESTOREWHENMIN );
+ }
+ else
+ {
+ myExtMgr->Show();
+ myExtMgr->ToTop( TOTOP_RESTOREWHENMIN );
+ }
+ }
+
+ if (app.get() != 0) {
+ Application::Execute();
+ DeInitVCL();
+ }
+
+ if (xListener.is())
+ xListener->dialogClosed(
+ ui::dialogs::DialogClosedEvent(
+ static_cast< ::cppu::OWeakObject * >(this),
+ sal_Int16(0)) );
+}
+
+// XJobExecutor
+//______________________________________________________________________________
+void ServiceImpl::trigger( OUString const &rEvent ) throw (RuntimeException)
+{
+ if ( rEvent == OUSTR("SHOW_UPDATE_DIALOG") )
+ m_bShowUpdateOnly = true;
+ else
+ m_bShowUpdateOnly = false;
+
+ startExecuteModal( Reference< ui::dialogs::XDialogClosedListener >() );
+}
+
+namespace sdecl = comphelper::service_decl;
+sdecl::class_<ServiceImpl, sdecl::with_args<true> > serviceSI;
+sdecl::ServiceDecl const serviceDecl(
+ serviceSI,
+ "com.sun.star.comp.deployment.ui.PackageManagerDialog",
+ "com.sun.star.deployment.ui.PackageManagerDialog" );
+
+sdecl::class_<LicenseDialog, sdecl::with_args<true> > licenseSI;
+sdecl::ServiceDecl const licenseDecl(
+ licenseSI,
+ "com.sun.star.comp.deployment.ui.LicenseDialog",
+ "com.sun.star.deployment.ui.LicenseDialog" );
+
+sdecl::class_<UpdateRequiredDialogService, sdecl::with_args<true> > updateSI;
+sdecl::ServiceDecl const updateDecl(
+ updateSI,
+ "com.sun.star.comp.deployment.ui.UpdateRequiredDialog",
+ "com.sun.star.deployment.ui.UpdateRequiredDialog" );
+} // namespace dp_gui
+
+extern "C" {
+
+void SAL_CALL component_getImplementationEnvironment(
+ const sal_Char ** ppEnvTypeName, uno_Environment ** )
+{
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
+
+sal_Bool SAL_CALL component_writeInfo(
+ lang::XMultiServiceFactory * pServiceManager,
+ registry::XRegistryKey * pRegistryKey )
+{
+ return component_writeInfoHelper(
+ pServiceManager, pRegistryKey, dp_gui::serviceDecl, dp_gui::licenseDecl, dp_gui::updateDecl );
+}
+
+void * SAL_CALL component_getFactory(
+ sal_Char const * pImplName,
+ lang::XMultiServiceFactory * pServiceManager,
+ registry::XRegistryKey * pRegistryKey )
+{
+ return component_getFactoryHelper(
+ pImplName, pServiceManager, pRegistryKey, dp_gui::serviceDecl, dp_gui::licenseDecl, dp_gui::updateDecl );
+}
+
+} // extern "C"
diff --git a/desktop/source/deployment/gui/dp_gui_shared.hxx b/desktop/source/deployment/gui/dp_gui_shared.hxx
new file mode 100644
index 000000000000..0b23ccbd5f4c
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_shared.hxx
@@ -0,0 +1,65 @@
+/*************************************************************************
+ *
+ * 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: dp_gui_shared.hxx,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#if !defined INCLUDED_DP_GUI_SHARED_HXX
+#define INCLUDED_DP_GUI_SHARED_HXX
+
+#include "unotools/configmgr.hxx"
+#include "rtl/instance.hxx"
+#include "tools/resmgr.hxx"
+
+
+namespace css = ::com::sun::star;
+
+namespace dp_gui {
+
+struct DeploymentGuiResMgr :
+ public ::rtl::StaticWithInit< ResMgr *, DeploymentGuiResMgr > {
+ ResMgr * operator () () {
+ return ResMgr::CreateResMgr( "deploymentgui" );
+ }
+};
+
+struct BrandName : public ::rtl::StaticWithInit<const ::rtl::OUString, BrandName> {
+ const ::rtl::OUString operator () () {
+ return ::utl::ConfigManager::GetDirectConfigProperty(
+ ::utl::ConfigManager::PRODUCTNAME ).get< ::rtl::OUString >();
+ }
+};
+
+class DpGuiResId : public ResId
+{
+public:
+ DpGuiResId( USHORT nId ):ResId( nId, *DeploymentGuiResMgr::get() ) {}
+};
+
+} // namespace dp_gui
+
+#endif
diff --git a/desktop/source/deployment/gui/dp_gui_system.cxx b/desktop/source/deployment/gui/dp_gui_system.cxx
new file mode 100644
index 000000000000..15f9597ce2df
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_system.cxx
@@ -0,0 +1,62 @@
+/*************************************************************************
+ *
+ * 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: dp_gui_system.cxx,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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "dp_gui_system.hxx"
+#ifdef WNT
+#define WIN32_LEAN_AND_MEAN
+#ifdef _MSC_VER
+#pragma warning(push,1) /* disable warnings within system headers */
+#endif
+#include <windows.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+#endif
+
+namespace dp_gui {
+
+//We cannot distinguish Vista and 2008 Server
+bool isVista()
+{
+#ifdef WNT
+ OSVERSIONINFO osvi;
+ ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
+ osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+ GetVersionEx(&osvi);
+ return osvi.dwMajorVersion >= 6;
+#else
+ return false;
+#endif
+}
+
+} //namespace dp_gui
diff --git a/desktop/source/deployment/gui/dp_gui_system.hxx b/desktop/source/deployment/gui/dp_gui_system.hxx
new file mode 100644
index 000000000000..68eb0fe28f32
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_system.hxx
@@ -0,0 +1,40 @@
+/*************************************************************************
+ *
+ * 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: dp_gui_system.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 INCLUDED_DESKTOP_SOURCE_DEPLOYMENT_GUI_DP_GUI_SYSTEM_HXX
+#define INCLUDED_DESKTOP_SOURCE_DEPLOYMENT_GUI_DP_GUI_SYSTEM_HXX
+
+
+/// @HTML
+namespace dp_gui {
+bool isVista();
+
+}
+#endif
diff --git a/desktop/source/deployment/gui/dp_gui_theextmgr.cxx b/desktop/source/deployment/gui/dp_gui_theextmgr.cxx
new file mode 100644
index 000000000000..3d994f31c395
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_theextmgr.cxx
@@ -0,0 +1,538 @@
+/*************************************************************************
+ *
+ * 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: dp_gui_theextmgr.cxx,v $
+ *
+ * $Revision: 1.3.14.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_desktop.hxx"
+
+#include "vcl/svapp.hxx"
+#include "vcl/msgbox.hxx"
+
+#include "vos/mutex.hxx"
+
+#include "toolkit/helper/vclunohelper.hxx"
+
+#include "com/sun/star/beans/XPropertySet.hpp"
+#include "com/sun/star/deployment/XPackageManagerFactory.hpp"
+#include "com/sun/star/deployment/thePackageManagerFactory.hpp"
+
+#include "dp_gui_dialog2.hxx"
+#include "dp_gui_extensioncmdqueue.hxx"
+#include "dp_gui_theextmgr.hxx"
+#include "dp_gui_theextmgr.hxx"
+#include "dp_identifier.hxx"
+
+#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
+
+using namespace ::com::sun::star;
+using ::rtl::OUString;
+
+namespace dp_gui {
+
+//------------------------------------------------------------------------------
+
+::rtl::Reference< TheExtensionManager > TheExtensionManager::s_ExtMgr;
+
+//------------------------------------------------------------------------------
+// TheExtensionManager
+//------------------------------------------------------------------------------
+
+TheExtensionManager::TheExtensionManager( Window *pParent,
+ const uno::Reference< uno::XComponentContext > &xContext ) :
+ m_xContext( xContext ),
+ m_pParent( pParent ),
+ m_pExtMgrDialog( NULL ),
+ m_pUpdReqDialog( NULL )
+{
+ if ( dp_misc::office_is_running() )
+ {
+ m_xDesktop.set( xContext->getServiceManager()->createInstanceWithContext(
+ OUSTR("com.sun.star.frame.Desktop"), xContext ), uno::UNO_QUERY );
+ if ( m_xDesktop.is() )
+ m_xDesktop->addTerminateListener( this );
+ }
+
+ m_sPackageManagers.realloc(2);
+ m_sPackageManagers[0] = deployment::thePackageManagerFactory::get( m_xContext )->getPackageManager( OUSTR("user") );
+ m_sPackageManagers[1] = deployment::thePackageManagerFactory::get( m_xContext )->getPackageManager( OUSTR("shared") );;
+
+ for ( sal_Int32 i = 0; i < m_sPackageManagers.getLength(); ++i )
+ {
+ m_sPackageManagers[i]->addModifyListener( this );
+ }
+
+ uno::Reference< lang::XMultiServiceFactory > xConfig(
+ xContext->getServiceManager()->createInstanceWithContext(
+ OUSTR("com.sun.star.configuration.ConfigurationProvider"), xContext ), uno::UNO_QUERY_THROW);
+ uno::Any args[1];
+ beans::PropertyValue aValue( OUSTR("nodepath"), 0, uno::Any( OUSTR("/org.openoffice.Office.OptionsDialog/Nodes") ),
+ beans::PropertyState_DIRECT_VALUE );
+ args[0] <<= aValue;
+ m_xNameAccessNodes = uno::Reference< container::XNameAccess >(
+ xConfig->createInstanceWithArguments( OUSTR("com.sun.star.configuration.ConfigurationAccess"),
+ uno::Sequence< uno::Any >( args, 1 )), uno::UNO_QUERY_THROW);
+
+ // get the 'get more extensions here' url
+ uno::Reference< container::XNameAccess > xNameAccessRepositories;
+ beans::PropertyValue aValue2( OUSTR("nodepath"), 0, uno::Any( OUSTR("/org.openoffice.Office.ExtensionManager/ExtensionRepositories") ),
+ beans::PropertyState_DIRECT_VALUE );
+ args[0] <<= aValue2;
+ xNameAccessRepositories = uno::Reference< container::XNameAccess > (
+ xConfig->createInstanceWithArguments( OUSTR("com.sun.star.configuration.ConfigurationAccess"),
+ uno::Sequence< uno::Any >( args, 1 )), uno::UNO_QUERY_THROW);
+ try
+ { //throws css::container::NoSuchElementException, css::lang::WrappedTargetException
+ uno::Any value = xNameAccessRepositories->getByName( OUSTR( "WebsiteLink" ) );
+ m_sGetExtensionsURL = value.get< OUString > ();
+ }
+ catch ( uno::Exception& )
+ {}
+}
+
+//------------------------------------------------------------------------------
+TheExtensionManager::~TheExtensionManager()
+{
+ if ( m_pUpdReqDialog )
+ delete m_pUpdReqDialog;
+ if ( m_pExtMgrDialog )
+ delete m_pExtMgrDialog;
+}
+
+//------------------------------------------------------------------------------
+void TheExtensionManager::createDialog( const bool bCreateUpdDlg )
+{
+ const ::vos::OGuard guard( Application::GetSolarMutex() );
+
+ if ( bCreateUpdDlg )
+ {
+ if ( !m_pUpdReqDialog )
+ {
+ m_pUpdReqDialog = new UpdateRequiredDialog( NULL, this );
+ m_pExecuteCmdQueue.reset( new ExtensionCmdQueue( (DialogHelper*) m_pUpdReqDialog, this, m_xContext ) );
+ createPackageList();
+ }
+ }
+ else if ( !m_pExtMgrDialog )
+ {
+ m_pExtMgrDialog = new ExtMgrDialog( m_pParent, this );
+ m_pExecuteCmdQueue.reset( new ExtensionCmdQueue( (DialogHelper*) m_pExtMgrDialog, this, m_xContext ) );
+ m_pExtMgrDialog->setGetExtensionsURL( m_sGetExtensionsURL );
+ createPackageList();
+ }
+}
+
+//------------------------------------------------------------------------------
+void TheExtensionManager::Show()
+{
+ const ::vos::OGuard guard( Application::GetSolarMutex() );
+
+ getDialog()->Show();
+}
+
+//------------------------------------------------------------------------------
+void TheExtensionManager::SetText( const ::rtl::OUString &rTitle )
+{
+ const ::vos::OGuard guard( Application::GetSolarMutex() );
+
+ getDialog()->SetText( rTitle );
+}
+
+//------------------------------------------------------------------------------
+void TheExtensionManager::ToTop( USHORT nFlags )
+{
+ const ::vos::OGuard guard( Application::GetSolarMutex() );
+
+ getDialog()->ToTop( nFlags );
+}
+
+//------------------------------------------------------------------------------
+bool TheExtensionManager::Close()
+{
+ if ( m_pExtMgrDialog )
+ return m_pExtMgrDialog->Close();
+ else if ( m_pUpdReqDialog )
+ return m_pUpdReqDialog->Close();
+ else
+ return true;
+}
+
+//------------------------------------------------------------------------------
+sal_Int16 TheExtensionManager::execute()
+{
+ sal_Int16 nRet = 0;
+
+ if ( m_pUpdReqDialog )
+ {
+ nRet = m_pUpdReqDialog->Execute();
+ delete m_pUpdReqDialog;
+ m_pUpdReqDialog = NULL;
+ }
+
+ return nRet;
+}
+
+//------------------------------------------------------------------------------
+bool TheExtensionManager::isVisible()
+{
+ return getDialog()->IsVisible();
+}
+
+//------------------------------------------------------------------------------
+bool TheExtensionManager::checkUpdates( bool /* bShowUpdateOnly */, bool /*bParentVisible*/ )
+{
+ std::vector< TUpdateListEntry > vEntries;
+
+ for ( sal_Int32 i = 0; i < m_sPackageManagers.getLength(); ++i )
+ {
+ uno::Sequence< uno::Reference< deployment::XPackage > > xPackages;
+ try {
+ xPackages = m_sPackageManagers[i]->getDeployedPackages( uno::Reference< task::XAbortChannel >(),
+ uno::Reference< ucb::XCommandEnvironment >() );
+ for ( sal_Int32 k = 0; k < xPackages.getLength(); ++k )
+ {
+ TUpdateListEntry pEntry( new UpdateListEntry( xPackages[k], m_sPackageManagers[i] ) );
+ vEntries.push_back( pEntry );
+ }
+ } catch ( deployment::DeploymentException & ) {
+ continue;
+ } catch ( ucb::CommandFailedException & ) {
+ continue;
+ } catch ( ucb::CommandAbortedException & ) {
+ return true;
+ } catch ( lang::IllegalArgumentException & e ) {
+ throw uno::RuntimeException( e.Message, e.Context );
+ }
+ }
+
+ m_pExecuteCmdQueue->checkForUpdates( vEntries );
+ return true;
+}
+
+//------------------------------------------------------------------------------
+bool TheExtensionManager::enablePackage( const uno::Reference< deployment::XPackage > &xPackage,
+ bool bEnable )
+{
+ m_pExecuteCmdQueue->enableExtension( xPackage, bEnable );
+
+ return true;
+}
+
+//------------------------------------------------------------------------------
+bool TheExtensionManager::removePackage( const uno::Reference< deployment::XPackageManager > &xPackageManager,
+ const uno::Reference< deployment::XPackage > &xPackage )
+{
+ m_pExecuteCmdQueue->removeExtension( xPackageManager, xPackage );
+
+ return true;
+}
+
+//------------------------------------------------------------------------------
+bool TheExtensionManager::updatePackages( const std::vector< TUpdateListEntry > &vList )
+{
+ m_pExecuteCmdQueue->checkForUpdates( vList );
+
+ return true;
+}
+
+//------------------------------------------------------------------------------
+bool TheExtensionManager::installPackage( const OUString &rPackageURL, bool bWarnUser )
+{
+ if ( rPackageURL.getLength() == 0 )
+ return false;
+
+ createDialog( false );
+
+ uno::Reference< deployment::XPackageManager > xUserPkgMgr = getUserPkgMgr();
+ uno::Reference< deployment::XPackageManager > xSharedPkgMgr = getSharedPkgMgr();
+
+ bool bInstall = true;
+ bool bInstallForAll = false;
+
+ if ( !bWarnUser && ! xSharedPkgMgr->isReadOnly() )
+ bInstall = getDialogHelper()->installForAllUsers( bInstallForAll );
+
+ if ( !bInstall )
+ return false;
+
+ if ( bInstallForAll )
+ m_pExecuteCmdQueue->addExtension( xSharedPkgMgr, rPackageURL, false );
+ else
+ m_pExecuteCmdQueue->addExtension( xUserPkgMgr, rPackageURL, bWarnUser );
+
+ return true;
+}
+
+//------------------------------------------------------------------------------
+bool TheExtensionManager::queryTermination()
+{
+ if ( dp_misc::office_is_running() )
+ return true;
+ // the standalone application unopkg must not close ( and quit ) the dialog
+ // when there are still actions in the queue
+ return true;
+}
+
+//------------------------------------------------------------------------------
+void TheExtensionManager::terminateDialog()
+{
+ if ( ! dp_misc::office_is_running() )
+ {
+ const ::vos::OGuard guard( Application::GetSolarMutex() );
+ delete m_pExtMgrDialog;
+ m_pExtMgrDialog = NULL;
+ delete m_pUpdReqDialog;
+ m_pUpdReqDialog = NULL;
+ Application::Quit();
+ }
+}
+
+//------------------------------------------------------------------------------
+bool TheExtensionManager::createPackageList( const uno::Reference< deployment::XPackageManager > &xPackageManager )
+{
+ uno::Sequence< uno::Reference< deployment::XPackage > > packages;
+
+ try {
+ packages = xPackageManager->getDeployedPackages( uno::Reference< task::XAbortChannel >(),
+ uno::Reference< ucb::XCommandEnvironment >() );
+ } catch ( deployment::DeploymentException & ) {
+ //handleGeneralError(e.Cause);
+ return true;
+ } catch ( ucb::CommandFailedException & ) {
+ //handleGeneralError(e.Reason);
+ return true;
+ } catch ( ucb::CommandAbortedException & ) {
+ return false;
+ } catch ( lang::IllegalArgumentException & e ) {
+ throw uno::RuntimeException( e.Message, e.Context );
+ }
+
+ for ( sal_Int32 j = 0; j < packages.getLength(); ++j )
+ {
+ getDialogHelper()->addPackageToList( packages[j], xPackageManager );
+ }
+
+ return true;
+}
+
+//------------------------------------------------------------------------------
+void TheExtensionManager::createPackageList()
+{
+ for ( sal_Int32 i = 0; i < m_sPackageManagers.getLength(); ++i )
+ {
+ if ( ! createPackageList( m_sPackageManagers[i] ) )
+ break;
+ }
+}
+
+//------------------------------------------------------------------------------
+PackageState TheExtensionManager::getPackageState( const uno::Reference< deployment::XPackage > &xPackage ) const
+{
+ try {
+ beans::Optional< beans::Ambiguous< sal_Bool > > option(
+ xPackage->isRegistered( uno::Reference< task::XAbortChannel >(),
+ uno::Reference< ucb::XCommandEnvironment >() ) );
+ if ( option.IsPresent )
+ {
+ ::beans::Ambiguous< sal_Bool > const & reg = option.Value;
+ if ( reg.IsAmbiguous )
+ return AMBIGUOUS;
+ else
+ return reg.Value ? REGISTERED : NOT_REGISTERED;
+ }
+ else
+ return NOT_AVAILABLE;
+ }
+ catch ( uno::RuntimeException & ) {
+ throw;
+ }
+ catch ( uno::Exception & exc) {
+ (void) exc;
+ OSL_ENSURE( 0, ::rtl::OUStringToOString( exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
+ return NOT_AVAILABLE;
+ }
+}
+
+//------------------------------------------------------------------------------
+// The function investigates if the extension supports options.
+bool TheExtensionManager::supportsOptions( const uno::Reference< deployment::XPackage > &xPackage ) const
+{
+ bool bOptions = false;
+
+ if ( ! xPackage->isBundle() )
+ return false;
+
+ beans::Optional< OUString > aId = xPackage->getIdentifier();
+
+ //a bundle must always have an id
+ OSL_ASSERT( aId.IsPresent );
+
+ //iterate over all available nodes
+ uno::Sequence< OUString > seqNames = m_xNameAccessNodes->getElementNames();
+
+ for ( int i = 0; i < seqNames.getLength(); i++ )
+ {
+ uno::Any anyNode = m_xNameAccessNodes->getByName( seqNames[i] );
+ //If we have a node then then it must contain the set of leaves. This is part of OptionsDialog.xcs
+ uno::Reference< XInterface> xIntNode = anyNode.get< uno::Reference< XInterface > >();
+ uno::Reference< container::XNameAccess > xNode( xIntNode, uno::UNO_QUERY_THROW );
+
+ uno::Any anyLeaves = xNode->getByName( OUSTR("Leaves") );
+ uno::Reference< XInterface > xIntLeaves = anyLeaves.get< uno::Reference< XInterface > >();
+ uno::Reference< container::XNameAccess > xLeaves( xIntLeaves, uno::UNO_QUERY_THROW );
+
+ //iterate over all available leaves
+ uno::Sequence< OUString > seqLeafNames = xLeaves->getElementNames();
+ for ( int j = 0; j < seqLeafNames.getLength(); j++ )
+ {
+ uno::Any anyLeaf = xLeaves->getByName( seqLeafNames[j] );
+ uno::Reference< XInterface > xIntLeaf = anyLeaf.get< uno::Reference< XInterface > >();
+ uno::Reference< beans::XPropertySet > xLeaf( xIntLeaf, uno::UNO_QUERY_THROW );
+ //investigate the Id property if it matches the extension identifier which
+ //has been passed in.
+ uno::Any anyValue = xLeaf->getPropertyValue( OUSTR("Id") );
+
+ OUString sId = anyValue.get< OUString >();
+ if ( sId == aId.Value )
+ {
+ bOptions = true;
+ break;
+ }
+ }
+ if ( bOptions )
+ break;
+ }
+ return bOptions;
+}
+
+//------------------------------------------------------------------------------
+// XEventListener
+void TheExtensionManager::disposing( lang::EventObject const & rEvt )
+ throw ( uno::RuntimeException )
+{
+ bool shutDown = (rEvt.Source == m_xDesktop);
+
+ if ( shutDown && m_xDesktop.is() )
+ {
+ m_xDesktop->removeTerminateListener( this );
+ m_xDesktop.clear();
+ }
+
+ if ( shutDown )
+ {
+ if ( dp_misc::office_is_running() )
+ {
+ const ::vos::OGuard guard( Application::GetSolarMutex() );
+ delete m_pExtMgrDialog;
+ m_pExtMgrDialog = NULL;
+ delete m_pUpdReqDialog;
+ m_pUpdReqDialog = NULL;
+ }
+ s_ExtMgr.clear();
+ }
+}
+
+//------------------------------------------------------------------------------
+// XTerminateListener
+void TheExtensionManager::queryTermination( ::lang::EventObject const & )
+ throw ( frame::TerminationVetoException, uno::RuntimeException )
+{
+ DialogHelper *pDialogHelper = getDialogHelper();
+
+ if ( m_pExecuteCmdQueue->isBusy() || ( pDialogHelper && pDialogHelper->isBusy() ) )
+ {
+ ToTop( TOTOP_RESTOREWHENMIN );
+ throw frame::TerminationVetoException(
+ OUSTR("The office cannot be closed while the Extension Manager is running"),
+ uno::Reference<XInterface>(static_cast<frame::XTerminateListener*>(this), uno::UNO_QUERY));
+ }
+ else
+ {
+ if ( m_pExtMgrDialog )
+ m_pExtMgrDialog->Close();
+ if ( m_pUpdReqDialog )
+ m_pUpdReqDialog->Close();
+ }
+}
+
+//------------------------------------------------------------------------------
+void TheExtensionManager::notifyTermination( ::lang::EventObject const & rEvt )
+ throw ( uno::RuntimeException )
+{
+ disposing( rEvt );
+}
+
+//------------------------------------------------------------------------------
+// XModifyListener
+void TheExtensionManager::modified( ::lang::EventObject const & rEvt )
+ throw ( uno::RuntimeException )
+{
+ uno::Reference< deployment::XPackageManager > xPackageManager( rEvt.Source, uno::UNO_QUERY );
+ if ( xPackageManager.is() )
+ {
+ getDialogHelper()->prepareChecking( xPackageManager );
+ createPackageList( xPackageManager );
+ getDialogHelper()->checkEntries();
+ }
+}
+
+//------------------------------------------------------------------------------
+::rtl::Reference< TheExtensionManager > TheExtensionManager::get( const uno::Reference< uno::XComponentContext > &xContext,
+ const uno::Reference< awt::XWindow > &xParent,
+ const OUString & extensionURL )
+{
+ if ( s_ExtMgr.is() )
+ {
+ OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
+ if ( extensionURL.getLength() )
+ s_ExtMgr->installPackage( extensionURL, true );
+ return s_ExtMgr;
+ }
+
+ Window * pParent = DIALOG_NO_PARENT;
+ if ( xParent.is() )
+ pParent = VCLUnoHelper::GetWindow(xParent);
+
+ ::rtl::Reference<TheExtensionManager> that( new TheExtensionManager( pParent, xContext ) );
+
+ const ::vos::OGuard guard( Application::GetSolarMutex() );
+ if ( ! s_ExtMgr.is() )
+ {
+ OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
+ s_ExtMgr = that;
+ }
+
+ if ( extensionURL.getLength() )
+ s_ExtMgr->installPackage( extensionURL, true );
+
+ return s_ExtMgr;
+}
+
+} //namespace dp_gui
+
diff --git a/desktop/source/deployment/gui/dp_gui_theextmgr.hxx b/desktop/source/deployment/gui/dp_gui_theextmgr.hxx
new file mode 100644
index 000000000000..4ce6005a9346
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_theextmgr.hxx
@@ -0,0 +1,143 @@
+/*************************************************************************
+ *
+ * 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: dp_gui_theextmgr.hxx,v $
+ *
+ * $Revision: 1.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 INCLUDED_DP_GUI_THEEXTMGR_HXX
+#define INCLUDED_DP_GUI_THEEXTMGR_HXX
+
+#include "comphelper/sequence.hxx"
+
+#include "cppuhelper/implbase2.hxx"
+
+#include "com/sun/star/container/XNameAccess.hpp"
+#include "com/sun/star/deployment/XPackageManager.hpp"
+#include "com/sun/star/frame/XDesktop.hpp"
+#include "com/sun/star/frame/XTerminateListener.hpp"
+#include "com/sun/star/uno/XComponentContext.hpp"
+#include "com/sun/star/util/XModifyListener.hpp"
+
+#include "dp_gui.h"
+#include "dp_gui_dialog2.hxx"
+#include "dp_gui_updatedata.hxx"
+
+//==============================================================================
+namespace dp_gui {
+
+//------------------------------------------------------------------------------
+class ExtensionCmdQueue;
+
+//------------------------------------------------------------------------------
+class TheExtensionManager :
+ public ::cppu::WeakImplHelper2< ::com::sun::star::frame::XTerminateListener,
+ ::com::sun::star::util::XModifyListener >
+{
+private:
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > m_xContext;
+ ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDesktop > m_xDesktop;
+ ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackageManager> > m_sPackageManagers;
+ ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > m_xNameAccessNodes;
+
+ ::std::auto_ptr< ExtensionCmdQueue > m_pExecuteCmdQueue;
+
+ Window *m_pParent;
+ ExtMgrDialog *m_pExtMgrDialog;
+ UpdateRequiredDialog *m_pUpdReqDialog;
+
+ ::rtl::OUString m_sGetExtensionsURL;
+
+ // liste der packages ( xpackage?, mit parent manager, ... )
+
+ void createPackageList();
+ bool createPackageList( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackageManager > &xPackageManager );
+
+public:
+ static ::rtl::Reference<TheExtensionManager> s_ExtMgr;
+
+ TheExtensionManager( Window * pParent,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > &xContext );
+ ~TheExtensionManager();
+
+ void createDialog( const bool bCreateUpdDlg );
+ sal_Int16 execute();
+
+ Dialog* getDialog() { return m_pExtMgrDialog ? (Dialog*) m_pExtMgrDialog : (Dialog*) m_pUpdReqDialog; }
+ DialogHelper* getDialogHelper() { return m_pExtMgrDialog ? (DialogHelper*) m_pExtMgrDialog : (DialogHelper*) m_pUpdReqDialog; }
+
+ void SetText( const ::rtl::OUString &rTitle );
+ void Show();
+ void ToTop( USHORT nFlags );
+ bool Close();
+ bool isVisible();
+
+ //-----------------
+ bool checkUpdates( bool showUpdateOnly, bool parentVisible );
+ bool updatePackages( const std::vector< TUpdateListEntry > &vList );
+
+ bool enablePackage( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage,
+ bool bEnable );
+ bool removePackage( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackageManager > &xPackageManager,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage );
+ bool installPackage( const ::rtl::OUString &rPackageURL, bool bWarnUser = false );
+
+ bool queryTermination();
+ void terminateDialog();
+
+ // Tools
+ bool supportsOptions( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage ) const;
+ PackageState getPackageState( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage ) const;
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > getContext() const { return m_xContext; }
+ ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackageManager > getUserPkgMgr() const { return m_sPackageManagers[0]; }
+ ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackageManager > getSharedPkgMgr() const { return m_sPackageManagers[1]; }
+
+ //-----------------
+ static ::rtl::Reference<TheExtensionManager> get(
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext> const & xContext,
+ ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow> const & xParent = 0,
+ ::rtl::OUString const & view = ::rtl::OUString() );
+
+ // XEventListener
+ virtual void SAL_CALL disposing( ::com::sun::star::lang::EventObject const & evt )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // XTerminateListener
+ virtual void SAL_CALL queryTermination( ::com::sun::star::lang::EventObject const & evt )
+ throw (::com::sun::star::frame::TerminationVetoException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL notifyTermination( ::com::sun::star::lang::EventObject const & evt )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // XModifyListener
+ virtual void SAL_CALL modified( ::com::sun::star::lang::EventObject const & evt )
+ throw (::com::sun::star::uno::RuntimeException);
+};
+
+} // namespace dp_gui
+
+#endif
+
diff --git a/desktop/source/deployment/gui/dp_gui_thread.cxx b/desktop/source/deployment/gui/dp_gui_thread.cxx
new file mode 100644
index 000000000000..d8a60b0ca4e5
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_thread.cxx
@@ -0,0 +1,85 @@
+/*************************************************************************
+ *
+ * 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: dp_gui_thread.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_desktop.hxx"
+
+#include "sal/config.h"
+
+#include <cstddef>
+#include <new>
+
+#include "osl/thread.hxx"
+#include "salhelper/simplereferenceobject.hxx"
+
+#include "dp_gui_thread.hxx"
+
+using dp_gui::Thread;
+
+Thread::Thread() {}
+
+void Thread::launch() {
+ // Assumption is that osl::Thread::create returns normally iff it causes
+ // osl::Thread::run to start executing:
+ acquire();
+ try {
+ create();
+ } catch (...) {
+ release();
+ throw;
+ }
+}
+
+void * Thread::operator new(std::size_t size)
+ throw (std::bad_alloc)
+{
+ return SimpleReferenceObject::operator new(size);
+}
+
+void Thread::operator delete(void * p) throw () {
+ SimpleReferenceObject::operator delete(p);
+}
+
+Thread::~Thread() {}
+
+void Thread::run() {
+ try {
+ execute();
+ } catch (...) {
+ // Work around the problem that onTerminated is not called if run throws
+ // an exception:
+ onTerminated();
+ throw;
+ }
+}
+
+void Thread::onTerminated() {
+ release();
+}
diff --git a/desktop/source/deployment/gui/dp_gui_thread.hxx b/desktop/source/deployment/gui/dp_gui_thread.hxx
new file mode 100644
index 000000000000..a58469c41c3b
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_thread.hxx
@@ -0,0 +1,87 @@
+/*************************************************************************
+ *
+ * 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: dp_gui_thread.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 INCLUDED_DESKTOP_SOURCE_DEPLOYMENT_GUI_DP_GUI_THREAD_HXX
+#define INCLUDED_DESKTOP_SOURCE_DEPLOYMENT_GUI_DP_GUI_THREAD_HXX
+
+#include "sal/config.h"
+
+#include <cstddef>
+#include <new>
+#include "osl/thread.hxx"
+#include "sal/types.h"
+#include "salhelper/simplereferenceobject.hxx"
+
+/// @HTML
+
+namespace dp_gui {
+
+/**
+ A safe encapsulation of <code>osl::Thread</code>.
+*/
+class Thread: public salhelper::SimpleReferenceObject, private osl::Thread {
+public:
+ Thread();
+
+ /**
+ Launch the thread.
+
+ <p>This function must be called at most once.</p>
+ */
+ void launch();
+
+ using osl::Thread::join;
+
+ static void * operator new(std::size_t size) throw (std::bad_alloc);
+
+ static void operator delete(void * p) throw ();
+
+protected:
+ virtual ~Thread();
+
+ /**
+ The main function executed by the thread.
+
+ <p>Any exceptions terminate the thread and are effectively ignored.</p>
+ */
+ virtual void execute() = 0;
+
+private:
+ Thread(Thread &); // not defined
+ void operator =(Thread &); // not defined
+
+ virtual void SAL_CALL run();
+
+ virtual void SAL_CALL onTerminated();
+};
+
+}
+
+#endif
diff --git a/desktop/source/deployment/gui/dp_gui_updatability.cxx b/desktop/source/deployment/gui/dp_gui_updatability.cxx
new file mode 100644
index 000000000000..4d3d8efbce2b
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_updatability.cxx
@@ -0,0 +1,280 @@
+/*************************************************************************
+ *
+ * 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: dp_gui_updatability.cxx,v $
+ * $Revision: 1.6.86.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_desktop.hxx"
+
+#include "sal/config.h"
+
+#include <cstddef>
+
+#include "com/sun/star/deployment/DeploymentException.hpp"
+#include "com/sun/star/deployment/UpdateInformationProvider.hpp"
+#include "com/sun/star/deployment/XPackage.hpp"
+#include "com/sun/star/deployment/XPackageManager.hpp"
+#include "com/sun/star/deployment/XUpdateInformationProvider.hpp"
+#include "com/sun/star/task/XAbortChannel.hpp"
+#include "com/sun/star/ucb/CommandAbortedException.hpp"
+#include "com/sun/star/ucb/CommandFailedException.hpp"
+#include "com/sun/star/ucb/XCommandEnvironment.hpp"
+#include "com/sun/star/uno/Reference.hxx"
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include "com/sun/star/uno/Sequence.hxx"
+#include "com/sun/star/uno/XInterface.hpp"
+#include "osl/conditn.hxx"
+#include "osl/diagnose.h"
+#include "osl/mutex.hxx"
+#include "rtl/ref.hxx"
+#include "rtl/ustring.h"
+#include "rtl/ustring.hxx"
+#include "sal/types.h"
+#include "vcl/svapp.hxx"
+#include "vcl/window.hxx"
+#include "vos/mutex.hxx"
+
+#include "dp_misc.h"
+#include "dp_gui_thread.hxx"
+#include "dp_gui_updatability.hxx"
+
+namespace com { namespace sun { namespace star { namespace uno {
+ class XComponentContext;
+} } } }
+
+using dp_gui::Updatability;
+
+namespace {
+
+namespace css = com::sun::star;
+
+}
+
+class Updatability::Thread: public dp_gui::Thread {
+public:
+ Thread(
+ css::uno::Sequence< css::uno::Reference<
+ css::deployment::XPackageManager > > const & packageManagers,
+ Window & enabled);
+
+ void start();
+
+ void stop();
+
+private:
+ Thread(Thread &); // not defined
+ void operator =(Thread &); // not defined
+
+ virtual ~Thread();
+
+ virtual void execute();
+
+ enum Input { NONE, START, STOP };
+
+ bool m_predeterminedUpdateUrl;
+ css::uno::Sequence< css::uno::Reference<
+ css::deployment::XPackageManager > > m_packageManagers;
+
+ osl::Condition m_wakeup;
+ osl::Mutex m_mutex;
+ Window * m_enabled;
+ Input m_input;
+ css::uno::Reference< css::task::XAbortChannel > m_abort;
+};
+
+Updatability::Thread::Thread(
+ css::uno::Sequence< css::uno::Reference<
+ css::deployment::XPackageManager > > const & packageManagers,
+ Window & enabled):
+ m_predeterminedUpdateUrl(dp_misc::getExtensionDefaultUpdateURL().getLength() > 0),
+ m_packageManagers(packageManagers),
+ m_enabled(&enabled),
+ m_input(NONE)
+{}
+
+void Updatability::Thread::start() {
+ css::uno::Reference< css::task::XAbortChannel > abort;
+ {
+ osl::MutexGuard g(m_mutex);
+ m_input = START;
+ abort = m_abort;
+ m_abort.clear();
+ }
+ m_wakeup.set();
+ if (abort.is()) {
+ abort->sendAbort();
+ }
+}
+
+void Updatability::Thread::stop() {
+ css::uno::Reference< css::task::XAbortChannel > abort;
+ {
+ vos::OGuard g1(Application::GetSolarMutex());
+ osl::MutexGuard g2(m_mutex);
+ m_input = STOP;
+ m_enabled = NULL;
+ abort = m_abort;
+ m_abort.clear();
+ }
+ m_wakeup.set();
+ if (abort.is()) {
+ abort->sendAbort();
+ }
+}
+
+Updatability::Thread::~Thread() {}
+
+void Updatability::Thread::execute() {
+ for (;;) {
+
+ if (m_wakeup.wait() != osl::Condition::result_ok) {
+ dp_misc::TRACE("dp_gui::Updatability::Thread::run: ignored \n");
+ dp_misc::TRACE("osl::Condition::wait failure\n");
+ }
+ m_wakeup.reset();
+ Input input;
+ {
+ osl::MutexGuard g(m_mutex);
+ input = m_input;
+ m_input = NONE;
+ }
+ if (input == NONE) {
+ continue;
+ }
+ start:
+ if (input == STOP) {
+ break;
+ }
+ bool enabled = false;
+ for (sal_Int32 i = 0; !enabled && i < m_packageManagers.getLength();
+ ++i)
+ {
+ css::uno::Reference< css::task::XAbortChannel > abort(
+ m_packageManagers[i]->createAbortChannel());
+ {
+ osl::MutexGuard g(m_mutex);
+ input = m_input;
+ m_input = NONE;
+ if (input == NONE) {
+ //In case input would be STOP then we would later break out of the loop
+ //before further calls to the XPackageManger are done. That is, the abort
+ //channel would not be used anyway.
+ m_abort = abort;
+ }
+ if (input != NONE) {
+ goto start;
+ }
+ }
+ css::uno::Sequence<
+ css::uno::Reference< css::deployment::XPackage > > ps;
+ try {
+ ps = m_packageManagers[i]->getDeployedPackages(
+ abort,
+ css::uno::Reference< css::ucb::XCommandEnvironment >());
+ } catch (css::deployment::DeploymentException &) {
+ // If there are any problematic package managers, enable the
+ // update button and let the update process report any problems
+ // to the user:
+ enabled = true;
+ continue;
+ } catch (css::ucb::CommandFailedException &) {
+ throw css::uno::RuntimeException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "CommandFailedException: cannot happen")),
+ css::uno::Reference< css::uno::XInterface >());
+ } catch (css::ucb::CommandAbortedException &) {
+ osl::MutexGuard g(m_mutex);
+ input = m_input;
+ m_input = NONE;
+ OSL_ASSERT(input != NONE);
+ goto start;
+ } catch (css::lang::IllegalArgumentException &) {
+ throw css::uno::RuntimeException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "IllegalArgumentException: cannot happen")),
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ if (m_predeterminedUpdateUrl && ps.getLength() != 0) {
+ enabled = true;
+ } else {
+ for (sal_Int32 j = 0; j < ps.getLength(); ++j) {
+ if (ps[j]->getUpdateInformationURLs().getLength() != 0) {
+ enabled = true;
+ break;
+ }
+ {
+ osl::MutexGuard g(m_mutex);
+ input = m_input;
+ m_input = NONE;
+ }
+ if (input != NONE) {
+ goto start;
+ }
+ }
+ }
+ }
+ vos::OGuard g1(Application::GetSolarMutex());
+ Window * e;
+ {
+ osl::MutexGuard g2(m_mutex);
+ e = m_enabled;
+ }
+ if (e != NULL) {
+ e->Enable(enabled);
+ }
+ }
+}
+
+Updatability::Updatability(
+ css::uno::Sequence<
+ css::uno::Reference< css::deployment::XPackageManager > > const &
+ packageManagers,
+ Window & enabled):
+ m_thread(new Thread(packageManagers, enabled))
+{
+ m_thread->launch();
+}
+
+Updatability::~Updatability() {
+
+}
+
+void Updatability::start() {
+ m_thread->start();
+}
+
+void Updatability::stop() {
+ m_thread->stop();
+ // Bad hack; m_thread calls Application::GetSolarMutex, which only works
+ // as long as DeInitVCL has not been called:
+ ULONG n = Application::ReleaseSolarMutex();
+ m_thread->join();
+ Application::AcquireSolarMutex(n);
+}
diff --git a/desktop/source/deployment/gui/dp_gui_updatability.hxx b/desktop/source/deployment/gui/dp_gui_updatability.hxx
new file mode 100644
index 000000000000..3cefdb019f6d
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_updatability.hxx
@@ -0,0 +1,104 @@
+/*************************************************************************
+ *
+ * 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: dp_gui_updatability.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 INCLUDED_DESKTOP_SOURCE_DEPLOYMENT_GUI_DP_GUI_UPDATABILITY_HXX
+#define INCLUDED_DESKTOP_SOURCE_DEPLOYMENT_GUI_DP_GUI_UPDATABILITY_HXX
+
+#include "sal/config.h"
+#include "com/sun/star/uno/Reference.hxx"
+#include "com/sun/star/uno/Sequence.hxx"
+#include "rtl/ref.hxx"
+
+/// @HTML
+
+class Window;
+namespace com { namespace sun { namespace star {
+ namespace deployment { class XPackageManager; }
+ namespace uno { class XComponentContext; }
+} } }
+
+namespace dp_gui {
+
+/**
+ Asynchronously determine whether <code>dp_gui::DialogImpl</code>'s
+ &ldquo;Check for Updates...&rdquo; button shall be enabled (which
+ theoretically can take some time).
+
+ <p>Note that, due to the asynchronous operation, the button may be enabled
+ even if there are no updatable extensions.</p>
+
+ <p>Each instance of this class must be called from a single thread in order
+ to adhere to the following protocol: <code>stop</code> must be called exactly
+ once, with no intervening calls to <code>start</code>, before the destructor
+ is called.</p>
+*/
+class Updatability {
+public:
+ /**
+ Create an instance.
+
+ @param packageManagers
+ a list of non-null package managers
+
+ @param enabled
+ <code>dp_gui::DialogImpl</code>'s &ldquo;Check for Updates...&rdquo;
+ button; will only be accessed with the solar mutex locked
+ */
+ Updatability(
+ com::sun::star::uno::Sequence< com::sun::star::uno::Reference<
+ com::sun::star::deployment::XPackageManager > > const &
+ packageManagers,
+ Window & enabled);
+
+ ~Updatability();
+
+ /**
+ (Re-)start determining whether <code>dp_gui::DialogImpl</code>'s
+ &ldquo;Check for Updates...&rdquo; button shall be enabled.
+ */
+ void start();
+
+ /**
+ Orderly shut down this instance.
+ */
+ void stop();
+
+private:
+ Updatability(Updatability &); // not defined
+ void operator =(Updatability &); // not defined
+
+ class Thread;
+
+ rtl::Reference< Thread > m_thread;
+};
+
+}
+
+#endif
diff --git a/desktop/source/deployment/gui/dp_gui_updatedata.hxx b/desktop/source/deployment/gui/dp_gui_updatedata.hxx
new file mode 100644
index 000000000000..610960b99734
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_updatedata.hxx
@@ -0,0 +1,79 @@
+/*************************************************************************
+ *
+ * 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: dp_gui_updatedata.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.
+ *
+ ************************************************************************/
+#if ! defined INCLUDED_DP_GUI_UPDATEDATA_HXX
+#define INCLUDED_DP_GUI_UPDATEDATA_HXX
+
+#include "sal/config.h"
+#include "rtl/ustring.hxx"
+#include "com/sun/star/uno/Reference.hxx"
+
+#include <boost/shared_ptr.hpp>
+
+
+namespace com { namespace sun { namespace star { namespace deployment {
+ class XPackageManager;
+ class XPackage;
+}}}}
+namespace com { namespace sun { namespace star { namespace xml { namespace dom {
+ class XNode;
+}}}}}
+
+
+namespace dp_gui {
+
+struct UpdateListEntry
+{
+ ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage> m_xPackage;
+ ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackageManager> m_xPackageManager;
+
+ UpdateListEntry( const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > &xPackage,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackageManager > &xPackageManager );
+ ~UpdateListEntry();
+};
+
+typedef ::boost::shared_ptr< UpdateListEntry > TUpdateListEntry;
+
+
+struct UpdateData
+{
+ ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage > aInstalledPackage;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackageManager > aPackageManager;
+ // The content of the update information
+ ::com::sun::star::uno::Reference< ::com::sun::star::xml::dom::XNode > aUpdateInfo;
+ //The URL of the locally downloaded extension. It will only be set if there were no errors
+ //during the download
+ ::rtl::OUString sLocalURL;
+ //The URL of the website wher the download can be obtained.
+ ::rtl::OUString sWebsiteURL;
+};
+}
+
+#endif
diff --git a/desktop/source/deployment/gui/dp_gui_updatedialog.cxx b/desktop/source/deployment/gui/dp_gui_updatedialog.cxx
new file mode 100644
index 000000000000..0e1955359bbc
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_updatedialog.cxx
@@ -0,0 +1,1274 @@
+/*************************************************************************
+ *
+ * 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
+ *
+ * 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_desktop.hxx"
+
+#include "sal/config.h"
+
+#include <cstddef>
+#include <limits>
+#include <map>
+#include <memory>
+#include <utility>
+#include <vector>
+
+
+#include "boost/optional.hpp"
+#include "com/sun/star/awt/Rectangle.hpp"
+#include "com/sun/star/awt/WindowAttribute.hpp"
+#include "com/sun/star/awt/WindowClass.hpp"
+#include "com/sun/star/awt/WindowDescriptor.hpp"
+#include "com/sun/star/awt/XThrobber.hpp"
+#include "com/sun/star/awt/XToolkit.hpp"
+#include "com/sun/star/awt/XWindow.hpp"
+#include "com/sun/star/awt/XWindowPeer.hpp"
+#include "com/sun/star/beans/NamedValue.hpp"
+#include "com/sun/star/beans/Optional.hpp"
+#include "com/sun/star/beans/PropertyValue.hpp"
+#include "com/sun/star/container/XNameAccess.hpp"
+#include "com/sun/star/deployment/DeploymentException.hpp"
+#include "com/sun/star/deployment/UpdateInformationProvider.hpp"
+#include "com/sun/star/deployment/XPackage.hpp"
+#include "com/sun/star/deployment/XPackageManager.hpp"
+#include "com/sun/star/deployment/XUpdateInformationProvider.hpp"
+#include "com/sun/star/frame/XDesktop.hpp"
+#include "com/sun/star/frame/XDispatch.hpp"
+#include "com/sun/star/frame/XDispatchProvider.hpp"
+#include "com/sun/star/lang/IllegalArgumentException.hpp"
+#include "com/sun/star/lang/XMultiComponentFactory.hpp"
+#include "com/sun/star/system/SystemShellExecuteFlags.hpp"
+#include "com/sun/star/system/XSystemShellExecute.hpp"
+#include "com/sun/star/task/XAbortChannel.hpp"
+#include "com/sun/star/task/XJob.hpp"
+#include "com/sun/star/ucb/CommandAbortedException.hpp"
+#include "com/sun/star/ucb/CommandFailedException.hpp"
+#include "com/sun/star/ucb/XCommandEnvironment.hpp"
+#include "com/sun/star/uno/Any.hxx"
+#include "com/sun/star/uno/Exception.hpp"
+#include "com/sun/star/uno/Reference.hxx"
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include "com/sun/star/uno/Sequence.hxx"
+#include "com/sun/star/uno/XInterface.hpp"
+#include "com/sun/star/util/URL.hpp"
+#include "com/sun/star/util/XURLTransformer.hpp"
+#include "com/sun/star/xml/dom/XElement.hpp"
+#include "com/sun/star/xml/dom/XNode.hpp"
+#include "osl/diagnose.h"
+#include "rtl/bootstrap.hxx"
+#include "rtl/ref.hxx"
+#include "rtl/string.h"
+#include "rtl/ustrbuf.hxx"
+#include "rtl/ustring.h"
+#include "rtl/ustring.hxx"
+#include "sal/types.h"
+#include "svtools/svlbitm.hxx"
+#include "svtools/svlbox.hxx"
+#include <svtools/controldims.hrc>
+#include "svx/checklbx.hxx"
+#include "tools/gen.hxx"
+#include "tools/link.hxx"
+#include "tools/resid.hxx"
+#include "tools/resmgr.hxx"
+#include "tools/solar.h"
+#include "tools/string.hxx"
+#include "vcl/button.hxx"
+#include "vcl/dialog.hxx"
+#include "vcl/fixed.hxx"
+#include "vcl/image.hxx"
+#include "vcl/msgbox.hxx"
+#include "vcl/svapp.hxx"
+#include "vos/mutex.hxx"
+
+#include "comphelper/processfactory.hxx"
+
+#include "dp_dependencies.hxx"
+#include "dp_descriptioninfoset.hxx"
+#include "dp_identifier.hxx"
+#include "dp_version.hxx"
+#include "dp_misc.h"
+
+#include "dp_gui.h"
+#include "dp_gui.hrc"
+#include "dp_gui_thread.hxx"
+#include "dp_gui_updatedata.hxx"
+#include "dp_gui_updatedialog.hxx"
+#include "dp_gui_shared.hxx"
+#include "dp_gui_system.hxx"
+
+class KeyEvent;
+class MouseEvent;
+class Window;
+namespace com { namespace sun { namespace star { namespace uno {
+ class XComponentContext;
+} } } }
+
+namespace css = ::com::sun::star;
+
+using dp_gui::UpdateDialog;
+
+namespace {
+
+static sal_Unicode const LF = 0x000A;
+static sal_Unicode const CR = 0x000D;
+
+enum Kind { ENABLED_UPDATE, DISABLED_UPDATE, GENERAL_ERROR, SPECIFIC_ERROR };
+
+rtl::OUString confineToParagraph(rtl::OUString const & text) {
+ // Confine arbitrary text to a single paragraph in a dp_gui::AutoScrollEdit.
+ // This assumes that U+000A and U+000D are the only paragraph separators in
+ // a dp_gui::AutoScrollEdit, and that replacing them with a single space
+ // each is acceptable:
+ return text.replace(LF, ' ').replace(CR, ' ');
+}
+}
+
+struct UpdateDialog::DisabledUpdate {
+ rtl::OUString name;
+ css::uno::Sequence< rtl::OUString > unsatisfiedDependencies;
+ bool permission;
+ // We also want to show release notes and publisher for disabled updates
+ ::com::sun::star::uno::Reference< ::com::sun::star::xml::dom::XNode > aUpdateInfo;
+};
+
+struct UpdateDialog::SpecificError {
+ rtl::OUString name;
+ rtl::OUString message;
+};
+
+union UpdateDialog::IndexUnion{
+ std::vector< dp_gui::UpdateData >::size_type enabledUpdate;
+ std::vector< UpdateDialog::DisabledUpdate >::size_type disabledUpdate;
+ std::vector< rtl::OUString >::size_type generalError;
+ std::vector< UpdateDialog::SpecificError >::size_type specificError;
+};
+
+struct UpdateDialog::Index {
+ static std::auto_ptr< UpdateDialog::Index const > newEnabledUpdate(
+ std::vector< dp_gui::UpdateData >::size_type n);
+
+ static std::auto_ptr< UpdateDialog::Index const > newDisabledUpdate(
+ std::vector< UpdateDialog::DisabledUpdate >::size_type n);
+
+ static std::auto_ptr< UpdateDialog::Index const > newGeneralError(
+ std::vector< rtl::OUString >::size_type n);
+
+ static std::auto_ptr< UpdateDialog::Index const > newSpecificError(
+ std::vector< UpdateDialog::SpecificError >::size_type n);
+
+ Kind kind;
+ IndexUnion index;
+
+private:
+ explicit Index(Kind theKind);
+};
+
+std::auto_ptr< UpdateDialog::Index const >
+UpdateDialog::Index::newEnabledUpdate(
+ std::vector< dp_gui::UpdateData >::size_type n)
+{
+ UpdateDialog::Index * p = new UpdateDialog::Index(ENABLED_UPDATE);
+ p->index.enabledUpdate = n;
+ return std::auto_ptr< UpdateDialog::Index const >(p);
+}
+
+std::auto_ptr< UpdateDialog::Index const >
+UpdateDialog::Index::newDisabledUpdate(
+ std::vector< UpdateDialog::DisabledUpdate >::size_type n)
+{
+ UpdateDialog::Index * p = new UpdateDialog::Index(DISABLED_UPDATE);
+ p->index.disabledUpdate = n;
+ return std::auto_ptr< UpdateDialog::Index const >(p);
+}
+
+std::auto_ptr< UpdateDialog::Index const > UpdateDialog::Index::newGeneralError(
+ std::vector< rtl::OUString >::size_type n)
+{
+ UpdateDialog::Index * p = new UpdateDialog::Index(GENERAL_ERROR);
+ p->index.generalError = n;
+ return std::auto_ptr< UpdateDialog::Index const >(p);
+}
+
+std::auto_ptr< UpdateDialog::Index const >
+UpdateDialog::Index::newSpecificError(
+ std::vector< UpdateDialog::SpecificError >::size_type n)
+{
+ UpdateDialog::Index * p = new UpdateDialog::Index(SPECIFIC_ERROR);
+ p->index.specificError = n;
+ return std::auto_ptr< UpdateDialog::Index const >(p);
+}
+
+UpdateDialog::Index::Index(Kind theKind): kind(theKind) {}
+
+class UpdateDialog::Thread: public dp_gui::Thread {
+public:
+ Thread(
+ css::uno::Reference< css::uno::XComponentContext > const & context,
+ UpdateDialog & dialog,
+ const std::vector< TUpdateListEntry > &vExtensionList);
+
+ void stop();
+
+private:
+ Thread(UpdateDialog::Thread &); // not defined
+ void operator =(UpdateDialog::Thread &); // not defined
+
+ struct Entry {
+ explicit Entry(
+ css::uno::Reference< css::deployment::XPackage > const & thePackage,
+ css::uno::Reference< css::deployment::XPackageManager > const &
+ thePackageManager,
+ rtl::OUString const & theVersion);
+
+ css::uno::Reference< css::deployment::XPackage > package;
+ css::uno::Reference< css::deployment::XPackageManager > packageManager;
+ rtl::OUString version;
+ css::uno::Reference< css::xml::dom::XNode > info;
+ };
+
+ // A multimap in case an extension is installed in both "user" and "shared":
+ typedef std::multimap< rtl::OUString, Entry > Map;
+
+ virtual ~Thread();
+
+ virtual void execute();
+
+ void handleGeneralError(css::uno::Any const & exception) const;
+
+ void handleSpecificError(
+ css::uno::Reference< css::deployment::XPackage > const & package,
+ css::uno::Any const & exception) const;
+
+ css::uno::Sequence< css::uno::Reference< css::xml::dom::XElement > >
+ getUpdateInformation(
+ css::uno::Reference< css::deployment::XPackage > const & package,
+ css::uno::Sequence< rtl::OUString > const & urls,
+ rtl::OUString const & identifier) const;
+
+ void handle(
+ css::uno::Reference< css::deployment::XPackage > const & package,
+ css::uno::Reference< css::deployment::XPackageManager > const &
+ packageManager,
+ Map * map);
+
+ bool update(
+ css::uno::Reference< css::deployment::XPackage > const & package,
+ css::uno::Reference< css::deployment::XPackageManager > const &
+ packageManager,
+ css::uno::Reference< css::xml::dom::XNode > const & updateInfo) const;
+
+ css::uno::Reference< css::uno::XComponentContext > m_context;
+ UpdateDialog & m_dialog;
+ std::vector< dp_gui::TUpdateListEntry > m_vExtensionList;
+ css::uno::Reference< css::deployment::XUpdateInformationProvider >
+ m_updateInformation;
+
+ // guarded by Application::GetSolarMutex():
+ css::uno::Reference< css::task::XAbortChannel > m_abort;
+ bool m_stop;
+};
+
+UpdateDialog::Thread::Thread(
+ css::uno::Reference< css::uno::XComponentContext > const & context,
+ UpdateDialog & dialog,
+ const std::vector< dp_gui::TUpdateListEntry > &vExtensionList):
+ m_context(context),
+ m_dialog(dialog),
+ m_vExtensionList(vExtensionList),
+ m_updateInformation(
+ css::deployment::UpdateInformationProvider::create(context)),
+ m_stop(false)
+{}
+
+void UpdateDialog::Thread::stop() {
+ css::uno::Reference< css::task::XAbortChannel > abort;
+ {
+ vos::OGuard g(Application::GetSolarMutex());
+ abort = m_abort;
+ m_stop = true;
+ }
+ if (abort.is()) {
+ abort->sendAbort();
+ }
+ m_updateInformation->cancel();
+}
+
+UpdateDialog::Thread::Entry::Entry(
+ css::uno::Reference< css::deployment::XPackage > const & thePackage,
+ css::uno::Reference< css::deployment::XPackageManager > const &
+ thePackageManager,
+ rtl::OUString const & theVersion):
+ package(thePackage),
+ packageManager(thePackageManager),
+ version(theVersion)
+{}
+
+UpdateDialog::Thread::~Thread() {}
+
+void UpdateDialog::Thread::execute()
+{
+ OSL_ASSERT( ! m_vExtensionList.empty() );
+ Map map;
+
+ typedef std::vector< TUpdateListEntry >::const_iterator ITER;
+ for ( ITER iIndex = m_vExtensionList.begin(); iIndex < m_vExtensionList.end(); ++iIndex )
+ {
+ css::uno::Reference< css::deployment::XPackage > p = (*iIndex)->m_xPackage;
+ css::uno::Reference< css::deployment::XPackageManager > m = (*iIndex)->m_xPackageManager;
+ if ( p.is() )
+ {
+ {
+ vos::OGuard g( Application::GetSolarMutex() );
+ if ( m_stop ) {
+ return;
+ }
+ }
+ handle( p, m, &map );
+ }
+ }
+
+ if (!map.empty()) {
+ const rtl::OUString sDefaultURL(dp_misc::getExtensionDefaultUpdateURL());
+ if (sDefaultURL.getLength())
+ {
+ css::uno::Sequence< css::uno::Reference< css::xml::dom::XElement > >
+ infos(
+ getUpdateInformation(
+ css::uno::Reference< css::deployment::XPackage >(),
+ css::uno::Sequence< rtl::OUString >(&sDefaultURL, 1), rtl::OUString()));
+ for (sal_Int32 i = 0; i < infos.getLength(); ++i) {
+ css::uno::Reference< css::xml::dom::XNode > node(
+ infos[i], css::uno::UNO_QUERY_THROW);
+ dp_misc::DescriptionInfoset infoset(m_context, node);
+ boost::optional< rtl::OUString > id(infoset.getIdentifier());
+ if (!id) {
+ continue;
+ }
+ Map::iterator end(map.upper_bound(*id));
+ for (Map::iterator j(map.lower_bound(*id)); j != end; ++j) {
+ rtl::OUString v(infoset.getVersion());
+ if (dp_misc::compareVersions(v, j->second.version) ==
+ dp_misc::GREATER)
+ {
+ j->second.version = v;
+ j->second.info = node;
+ }
+ }
+ }
+ for (Map::const_iterator i(map.begin()); i != map.end(); ++i) {
+ if (i->second.info.is() &&
+ !update(
+ i->second.package, i->second.packageManager,
+ i->second.info))
+ {
+ break;
+ }
+ }
+ }
+ }
+ vos::OGuard g(Application::GetSolarMutex());
+ if (!m_stop) {
+ m_dialog.checkingDone();
+ }
+}
+
+void UpdateDialog::Thread::handleGeneralError(css::uno::Any const & exception)
+ const
+{
+ rtl::OUString message;
+ css::uno::Exception e;
+ if (exception >>= e) {
+ message = e.Message;
+ }
+ vos::OGuard g(Application::GetSolarMutex());
+ if (!m_stop) {
+ m_dialog.addGeneralError(message);
+ }
+}
+
+//Parameter package can be null
+void UpdateDialog::Thread::handleSpecificError(
+ css::uno::Reference< css::deployment::XPackage > const & package,
+ css::uno::Any const & exception) const
+{
+ UpdateDialog::SpecificError data;
+ if (package.is())
+ data.name = package->getDisplayName();
+ css::uno::Exception e;
+ if (exception >>= e) {
+ data.message = e.Message;
+ }
+ vos::OGuard g(Application::GetSolarMutex());
+ if (!m_stop) {
+ m_dialog.addSpecificError(data);
+ }
+}
+
+css::uno::Sequence< css::uno::Reference< css::xml::dom::XElement > >
+UpdateDialog::Thread::getUpdateInformation(
+ css::uno::Reference< css::deployment::XPackage > const & package,
+ css::uno::Sequence< rtl::OUString > const & urls,
+ rtl::OUString const & identifier) const
+{
+ try {
+ return m_updateInformation->getUpdateInformation(urls, identifier);
+ } catch (css::uno::RuntimeException &) {
+ throw;
+ } catch (css::ucb::CommandFailedException & e) {
+ handleSpecificError(package, e.Reason);
+ } catch (css::ucb::CommandAbortedException &) {
+ } catch (css::uno::Exception & e) {
+ handleSpecificError(package, css::uno::makeAny(e));
+ }
+ return
+ css::uno::Sequence< css::uno::Reference< css::xml::dom::XElement > >();
+}
+
+void UpdateDialog::Thread::handle(
+ css::uno::Reference< css::deployment::XPackage > const & package,
+ css::uno::Reference< css::deployment::XPackageManager > const &
+ packageManager,
+ Map * map)
+{
+ rtl::OUString id(dp_misc::getIdentifier(package));
+ css::uno::Sequence< rtl::OUString > urls(
+ package->getUpdateInformationURLs());
+ if (urls.getLength() == 0) {
+ map->insert(
+ Map::value_type(
+ id, Entry(package, packageManager, package->getVersion())));
+ } else {
+ css::uno::Sequence< css::uno::Reference< css::xml::dom::XElement > >
+ infos(getUpdateInformation(package, urls, id));
+ rtl::OUString latestVersion(package->getVersion());
+ sal_Int32 latestIndex = -1;
+ for (sal_Int32 i = 0; i < infos.getLength(); ++i) {
+ dp_misc::DescriptionInfoset infoset(
+ m_context,
+ css::uno::Reference< css::xml::dom::XNode >(
+ infos[i], css::uno::UNO_QUERY_THROW));
+ boost::optional< rtl::OUString > id2(infoset.getIdentifier());
+ if (!id2) {
+ continue;
+ }
+ if (*id2 == id) {
+ rtl::OUString v(infoset.getVersion());
+ if (dp_misc::compareVersions(v, latestVersion) ==
+ dp_misc::GREATER)
+ {
+ latestVersion = v;
+ latestIndex = i;
+ }
+ }
+ }
+ if (latestIndex != -1) {
+ update(
+ package, packageManager,
+ css::uno::Reference< css::xml::dom::XNode >(
+ infos[latestIndex], css::uno::UNO_QUERY_THROW));
+ }
+ }
+}
+
+bool UpdateDialog::Thread::update(
+ css::uno::Reference< css::deployment::XPackage > const & package,
+ css::uno::Reference< css::deployment::XPackageManager > const &
+ packageManager,
+ css::uno::Reference< css::xml::dom::XNode > const & updateInfo) const
+{
+ dp_misc::DescriptionInfoset infoset(m_context, updateInfo);
+ OSL_ASSERT(infoset.getVersion().getLength() != 0);
+ css::uno::Sequence< css::uno::Reference< css::xml::dom::XElement > > ds(
+ dp_misc::Dependencies::check(infoset));
+
+ UpdateDialog::DisabledUpdate du;
+ du.aUpdateInfo = updateInfo;
+ du.unsatisfiedDependencies.realloc(ds.getLength());
+ for (sal_Int32 i = 0; i < ds.getLength(); ++i) {
+ du.unsatisfiedDependencies[i] = dp_misc::Dependencies::getErrorText(ds[i]);
+ }
+ du.permission = ! packageManager->isReadOnly();
+ const ::boost::optional< ::rtl::OUString> updateWebsiteURL(infoset.getLocalizedUpdateWebsiteURL());
+ rtl::OUStringBuffer b(package->getDisplayName());
+ b.append(static_cast< sal_Unicode >(' '));
+ {
+ vos::OGuard g( Application::GetSolarMutex() );
+ if ( m_stop )
+ return !m_stop;
+ else
+ b.append(m_dialog.m_version);
+ }
+ b.append(static_cast< sal_Unicode >(' '));
+ b.append(infoset.getVersion());
+ if (updateWebsiteURL)
+ {
+ b.append(static_cast< sal_Unicode >(' '));
+ {
+ vos::OGuard g( Application::GetSolarMutex() );
+ if ( m_stop )
+ return !m_stop;
+ else
+ b.append(m_dialog.m_browserbased);
+ }
+ }
+ du.name = b.makeStringAndClear();
+
+ if (du.unsatisfiedDependencies.getLength() == 0 && du.permission)
+ {
+ dp_gui::UpdateData data;
+ data.aInstalledPackage = package;
+ data.aPackageManager = packageManager;
+ data.aUpdateInfo = updateInfo;
+ if (updateWebsiteURL)
+ data.sWebsiteURL = *updateWebsiteURL;
+ vos::OGuard g(Application::GetSolarMutex());
+ if (!m_stop) {
+ m_dialog.addEnabledUpdate(du.name, data);
+ }
+ return !m_stop;
+ } else {
+ vos::OGuard g(Application::GetSolarMutex());
+ if (!m_stop) {
+ m_dialog.addDisabledUpdate(du);
+ }
+ return !m_stop;
+ }
+}
+
+// UpdateDialog ----------------------------------------------------------
+UpdateDialog::UpdateDialog(
+ css::uno::Reference< css::uno::XComponentContext > const & context,
+ Window * parent,
+ const std::vector< dp_gui::TUpdateListEntry > &vExtensionList,
+ std::vector< dp_gui::UpdateData > * updateData):
+ ModalDialog(parent,DpGuiResId(RID_DLG_UPDATE)),
+ m_context(context),
+ m_checking(this, DpGuiResId(RID_DLG_UPDATE_CHECKING)),
+ m_update(this, DpGuiResId(RID_DLG_UPDATE_UPDATE)),
+ m_updates(
+ *this, DpGuiResId(RID_DLG_UPDATE_UPDATES),
+ Image(DpGuiResId(RID_DLG_UPDATE_NORMALALERT)),
+ Image(DpGuiResId(RID_DLG_UPDATE_HIGHCONTRASTALERT))),
+ m_all(this, DpGuiResId(RID_DLG_UPDATE_ALL)),
+ m_description(this, DpGuiResId(RID_DLG_UPDATE_DESCRIPTION)),
+ m_PublisherLabel(this, DpGuiResId(RID_DLG_UPDATE_PUBLISHER_LABEL)),
+ m_PublisherLink(this, DpGuiResId(RID_DLG_UPDATE_PUBLISHER_LINK)),
+ m_ReleaseNotesLabel(this, DpGuiResId(RID_DLG_UPDATE_RELEASENOTES_LABEL)),
+ m_ReleaseNotesLink(this, DpGuiResId(RID_DLG_UPDATE_RELEASENOTES_LINK)),
+ m_descriptions(this, DpGuiResId(RID_DLG_UPDATE_DESCRIPTIONS)),
+ m_line(this, DpGuiResId(RID_DLG_UPDATE_LINE)),
+ m_help(this, DpGuiResId(RID_DLG_UPDATE_HELP)),
+ m_ok(this, DpGuiResId(RID_DLG_UPDATE_OK)),
+ m_cancel(this, DpGuiResId(RID_DLG_UPDATE_CANCEL)),
+ m_error(String(DpGuiResId(RID_DLG_UPDATE_ERROR))),
+ m_none(String(DpGuiResId(RID_DLG_UPDATE_NONE))),
+ m_noInstallable(String(DpGuiResId(RID_DLG_UPDATE_NOINSTALLABLE))),
+ m_failure(String(DpGuiResId(RID_DLG_UPDATE_FAILURE))),
+ m_unknownError(String(DpGuiResId(RID_DLG_UPDATE_UNKNOWNERROR))),
+ m_noDescription(String(DpGuiResId(RID_DLG_UPDATE_NODESCRIPTION))),
+ m_noInstall(String(DpGuiResId(RID_DLG_UPDATE_NOINSTALL))),
+ m_noDependency(String(DpGuiResId(RID_DLG_UPDATE_NODEPENDENCY))),
+ m_noDependencyCurVer(String(DpGuiResId(RID_DLG_UPDATE_NODEPENDENCY_CUR_VER))),
+ m_noPermission(String(DpGuiResId(RID_DLG_UPDATE_NOPERMISSION))),
+ m_noPermissionVista(String(DpGuiResId(RID_DLG_UPDATE_NOPERMISSION_VISTA))),
+ m_browserbased(String(DpGuiResId(RID_DLG_UPDATE_BROWSERBASED))),
+ m_version(String(DpGuiResId(RID_DLG_UPDATE_VERSION))),
+ m_updateData(*updateData),
+ m_thread(
+ new UpdateDialog::Thread(
+ context, *this, vExtensionList)),
+ m_nFirstLineDelta(0),
+ m_nOneLineMissing(0)
+ // TODO: check!
+// ,
+// m_extensionManagerDialog(extensionManagerDialog)
+{
+ OSL_ASSERT(updateData != NULL);
+ css::uno::Reference< css::awt::XToolkit > toolkit;
+ try {
+ toolkit = css::uno::Reference< css::awt::XToolkit >(
+ (css::uno::Reference< css::lang::XMultiComponentFactory >(
+ m_context->getServiceManager(),
+ css::uno::UNO_QUERY_THROW)->
+ createInstanceWithContext(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.Toolkit")),
+ m_context)),
+ css::uno::UNO_QUERY_THROW);
+ } catch (css::uno::RuntimeException &) {
+ throw;
+ } catch (css::uno::Exception & e) {
+ throw css::uno::RuntimeException(e.Message, e.Context);
+ }
+ Control c(this, DpGuiResId(RID_DLG_UPDATE_THROBBER));
+ Point pos(c.GetPosPixel());
+ Size size(c.GetSizePixel());
+ try {
+ m_throbber = css::uno::Reference< css::awt::XThrobber >(
+ toolkit->createWindow(
+ css::awt::WindowDescriptor(
+ css::awt::WindowClass_SIMPLE,
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Throbber")),
+ GetComponentInterface(), 0,
+ css::awt::Rectangle(
+ pos.X(), pos.Y(), size.Width(), size.Height()),
+ css::awt::WindowAttribute::SHOW)),
+ css::uno::UNO_QUERY_THROW);
+ } catch (css::lang::IllegalArgumentException & e) {
+ throw css::uno::RuntimeException(e.Message, e.Context);
+ }
+ m_updates.SetSelectHdl(LINK(this, UpdateDialog, selectionHandler));
+ m_all.SetToggleHdl(LINK(this, UpdateDialog, allHandler));
+ m_ok.SetClickHdl(LINK(this, UpdateDialog, okHandler));
+ m_cancel.SetClickHdl(LINK(this, UpdateDialog, cancelHandler));
+ if ( ! dp_misc::office_is_running())
+ m_help.Disable();
+ FreeResource();
+ String sTemp(m_noPermissionVista);
+ sTemp.SearchAndReplaceAllAscii( "%PRODUCTNAME", BrandName::get() );
+ m_noPermissionVista = sTemp;
+
+ initDescription();
+}
+
+UpdateDialog::~UpdateDialog() {
+ for (USHORT i = 0; i < m_updates.getItemCount(); ++i) {
+ delete static_cast< UpdateDialog::Index const * >(
+ m_updates.GetEntryData(i));
+ }
+}
+
+BOOL UpdateDialog::Close() {
+ m_thread->stop();
+ return ModalDialog::Close();
+}
+
+short UpdateDialog::Execute() {
+ m_throbber->start();
+ m_thread->launch();
+ return ModalDialog::Execute();
+}
+
+UpdateDialog::CheckListBox::CheckListBox(
+ UpdateDialog & dialog, ResId const & resource,
+ Image const & normalStaticImage, Image const & highContrastStaticImage):
+ SvxCheckListBox(
+ &dialog, resource, normalStaticImage, highContrastStaticImage),
+ m_dialog(dialog)
+{}
+
+UpdateDialog::CheckListBox::~CheckListBox() {}
+
+USHORT UpdateDialog::CheckListBox::getItemCount() const {
+ ULONG i = GetEntryCount();
+ OSL_ASSERT(i <= std::numeric_limits< USHORT >::max());
+ return sal::static_int_cast< USHORT >(i);
+}
+
+void UpdateDialog::CheckListBox::MouseButtonDown(MouseEvent const & event) {
+ // When clicking on a selected entry in an SvxCheckListBox, the entry's
+ // checkbox is toggled on mouse button down:
+ SvxCheckListBox::MouseButtonDown(event);
+ m_dialog.enableOk();
+}
+
+void UpdateDialog::CheckListBox::MouseButtonUp(MouseEvent const & event) {
+ // When clicking on an entry's checkbox in an SvxCheckListBox, the entry's
+ // checkbox is toggled on mouse button up:
+ SvxCheckListBox::MouseButtonUp(event);
+ m_dialog.enableOk();
+}
+
+void UpdateDialog::CheckListBox::KeyInput(KeyEvent const & event) {
+ SvxCheckListBox::KeyInput(event);
+ m_dialog.enableOk();
+}
+
+void UpdateDialog::insertItem(
+ rtl::OUString const & name, USHORT position,
+ std::auto_ptr< UpdateDialog::Index const > index, SvLBoxButtonKind kind)
+{
+ m_updates.InsertEntry(
+ name, position,
+ const_cast< void * >(static_cast< void const * >(index.release())),
+ kind);
+ //TODO #i72487#: UpdateDialog::Index potentially leaks as the exception
+ // behavior of SvxCheckListBox::InsertEntry is unspecified
+}
+
+void UpdateDialog::addAdditional(
+ rtl::OUString const & name, USHORT position,
+ std::auto_ptr< UpdateDialog::Index const > index, SvLBoxButtonKind kind)
+{
+ m_all.Enable();
+ if (m_all.IsChecked()) {
+ insertItem(name, position, index, kind);
+ m_update.Enable();
+ m_updates.Enable();
+ m_description.Enable();
+ m_descriptions.Enable();
+ }
+}
+
+void UpdateDialog::addEnabledUpdate(
+ rtl::OUString const & name, dp_gui::UpdateData const & data)
+{
+ std::vector< dp_gui::UpdateData >::size_type n = m_enabledUpdates.size();
+ m_enabledUpdates.push_back(data);
+ insertItem(
+ name, sal::static_int_cast< USHORT >(n),
+ UpdateDialog::Index::newEnabledUpdate(n),
+ SvLBoxButtonKind_enabledCheckbox);
+ // position overflow is rather harmless
+ m_updates.CheckEntryPos(sal::static_int_cast< USHORT >(n));
+ //TODO #i72487#: fragile computation; insertItem should instead return
+ // pos
+ m_update.Enable();
+ m_updates.Enable();
+ m_description.Enable();
+ m_descriptions.Enable();
+}
+
+void UpdateDialog::addDisabledUpdate(UpdateDialog::DisabledUpdate const & data)
+{
+ std::vector< UpdateDialog::DisabledUpdate >::size_type n =
+ m_disabledUpdates.size();
+ m_disabledUpdates.push_back(data);
+ addAdditional(
+ data.name, sal::static_int_cast< USHORT >(m_enabledUpdates.size() + n),
+ UpdateDialog::Index::newDisabledUpdate(n),
+ SvLBoxButtonKind_disabledCheckbox);
+ // position overflow is rather harmless
+}
+
+void UpdateDialog::addGeneralError(rtl::OUString const & message) {
+ std::vector< rtl::OUString >::size_type n = m_generalErrors.size();
+ m_generalErrors.push_back(message);
+ addAdditional(
+ m_error,
+ sal::static_int_cast< USHORT >(
+ m_enabledUpdates.size() + m_disabledUpdates.size() + n),
+ UpdateDialog::Index::newGeneralError(n), SvLBoxButtonKind_staticImage);
+ // position overflow is rather harmless
+}
+
+void UpdateDialog::addSpecificError(UpdateDialog::SpecificError const & data) {
+ std::vector< UpdateDialog::SpecificError >::size_type n =
+ m_specificErrors.size();
+ m_specificErrors.push_back(data);
+ addAdditional(
+ data.name, LISTBOX_APPEND, UpdateDialog::Index::newSpecificError(n),
+ SvLBoxButtonKind_staticImage);
+}
+
+void UpdateDialog::checkingDone() {
+ m_checking.Hide();
+ m_throbber->stop();
+ css::uno::Reference< css::awt::XWindow >(
+ m_throbber, css::uno::UNO_QUERY_THROW)->setVisible(false);
+ if (m_updates.getItemCount() == 0)
+ {
+ clearDescription();
+ m_description.Enable();
+ m_descriptions.Enable();
+ showDescription(
+ ( m_disabledUpdates.empty() && m_generalErrors.empty() && m_specificErrors.empty() )
+ ? m_none : m_noInstallable, false );
+ }
+ enableOk();
+}
+
+void UpdateDialog::enableOk() {
+ if (!m_checking.IsVisible()) {
+ m_ok.Enable(m_updates.GetCheckedEntryCount() != 0);
+ }
+}
+
+// *********************************************************************************
+void UpdateDialog::createNotifyJob( bool bPrepareOnly,
+ css::uno::Sequence< css::uno::Sequence< rtl::OUString > > &rItemList )
+{
+ if ( !dp_misc::office_is_running() )
+ return;
+
+ // notify update check job
+ try
+ {
+ css::uno::Reference< css::lang::XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory() );
+ css::uno::Reference< css::lang::XMultiServiceFactory > xConfigProvider(
+ xFactory->createInstance( OUSTR( "com.sun.star.configuration.ConfigurationProvider" )),
+ css::uno::UNO_QUERY_THROW);
+
+ css::beans::PropertyValue aProperty;
+ aProperty.Name = OUSTR( "nodepath" );
+ aProperty.Value = css::uno::makeAny( OUSTR("org.openoffice.Office.Addons/AddonUI/OfficeHelp/UpdateCheckJob") );
+
+ css::uno::Sequence< css::uno::Any > aArgumentList( 1 );
+ aArgumentList[0] = css::uno::makeAny( aProperty );
+
+ css::uno::Reference< css::container::XNameAccess > xNameAccess(
+ xConfigProvider->createInstanceWithArguments(
+ OUSTR("com.sun.star.configuration.ConfigurationAccess"), aArgumentList ),
+ css::uno::UNO_QUERY_THROW );
+
+ css::util::URL aURL;
+ xNameAccess->getByName(OUSTR("URL")) >>= aURL.Complete;
+
+ css::uno::Reference < css::util::XURLTransformer > xTransformer( xFactory->createInstance( OUSTR( "com.sun.star.util.URLTransformer" ) ),
+ css::uno::UNO_QUERY_THROW );
+
+ xTransformer->parseStrict(aURL);
+
+ css::uno::Reference < css::frame::XDesktop > xDesktop( xFactory->createInstance( OUSTR( "com.sun.star.frame.Desktop" ) ),
+ css::uno::UNO_QUERY_THROW );
+ css::uno::Reference< css::frame::XDispatchProvider > xDispatchProvider( xDesktop->getCurrentFrame(),
+ css::uno::UNO_QUERY_THROW );
+ css::uno::Reference< css::frame::XDispatch > xDispatch = xDispatchProvider->queryDispatch(aURL, rtl::OUString(), 0);
+
+ if( xDispatch.is() )
+ {
+ css::uno::Sequence< css::beans::PropertyValue > aPropList(2);
+ aProperty.Name = OUSTR( "updateList" );
+ aProperty.Value = css::uno::makeAny( rItemList );
+ aPropList[0] = aProperty;
+ aProperty.Name = OUSTR( "prepareOnly" );
+ aProperty.Value = css::uno::makeAny( bPrepareOnly );
+ aPropList[1] = aProperty;
+
+ xDispatch->dispatch(aURL, aPropList );
+ }
+ }
+ catch( const css::uno::Exception& e )
+ {
+ dp_misc::TRACE( OUSTR("Caught exception: ")
+ + e.Message + OUSTR("\n thread terminated.\n\n"));
+ }
+}
+
+// *********************************************************************************
+void UpdateDialog::notifyMenubar( bool bPrepareOnly, bool bRecheckOnly )
+{
+ if ( !dp_misc::office_is_running() )
+ return;
+
+ css::uno::Sequence< css::uno::Sequence< rtl::OUString > > aItemList;
+ sal_Int32 nCount = 0;
+
+ if ( ! bRecheckOnly )
+ {
+ for ( sal_Int16 i = 0; i < m_updates.getItemCount(); ++i )
+ {
+ css::uno::Sequence< rtl::OUString > aItem(2);
+
+ UpdateDialog::Index const * p = static_cast< UpdateDialog::Index const * >(m_updates.GetEntryData(i));
+
+ if ( p->kind == ENABLED_UPDATE )
+ {
+ dp_gui::UpdateData aUpdData = m_enabledUpdates[ p->index.enabledUpdate ];
+ aItem[0] = dp_misc::getIdentifier( aUpdData.aInstalledPackage );
+
+ dp_misc::DescriptionInfoset aInfoset( m_context, aUpdData.aUpdateInfo );
+ aItem[1] = aInfoset.getVersion();
+ }
+ else if ( p->kind == DISABLED_UPDATE )
+ continue;
+ else
+ continue;
+
+ aItemList.realloc( nCount + 1 );
+ aItemList[ nCount ] = aItem;
+ nCount += 1;
+ }
+ }
+ createNotifyJob( bPrepareOnly, aItemList );
+}
+
+// *********************************************************************************
+
+void UpdateDialog::initDescription()
+{
+ m_PublisherLabel.Hide();
+ m_PublisherLink.Hide();
+ m_ReleaseNotesLabel.Hide();
+ m_ReleaseNotesLink.Hide();
+ m_descriptions.Hide();
+
+ Link aLink = LINK( this, UpdateDialog, hyperlink_clicked );
+ m_PublisherLink.SetClickHdl( aLink );
+ m_ReleaseNotesLink.SetClickHdl( aLink );
+
+ long nTextWidth = m_PublisherLabel.GetCtrlTextWidth( m_PublisherLabel.GetText() );
+ long nTemp = m_ReleaseNotesLabel.GetTextWidth( m_ReleaseNotesLabel.GetText() );
+ if ( nTemp > nTextWidth )
+ nTextWidth = nTemp;
+ nTextWidth = nTextWidth * 110 / 100;
+
+ Size aNewSize = m_PublisherLabel.GetSizePixel();
+ if ( nTextWidth > aNewSize.Width() )
+ {
+ long nDelta = nTextWidth - aNewSize.Width();
+ aNewSize.Width() = nTextWidth;
+ m_PublisherLabel.SetSizePixel( aNewSize );
+ m_ReleaseNotesLabel.SetSizePixel( aNewSize );
+
+ aNewSize = m_PublisherLink.GetSizePixel();
+ aNewSize.Width() = aNewSize.Width() - nDelta;
+ Point aNewPos = m_PublisherLink.GetPosPixel();
+ aNewPos.X() = aNewPos.X() + nDelta;
+ m_PublisherLink.SetPosSizePixel( aNewPos, aNewSize );
+ aNewPos.Y() = m_ReleaseNotesLink.GetPosPixel().Y();
+ m_ReleaseNotesLink.SetPosSizePixel( aNewPos, aNewSize );
+ }
+
+ m_aFirstLinePos = m_descriptions.GetPosPixel();
+ m_aFirstLineSize = m_descriptions.GetSizePixel();
+ Size aMarginSize = LogicToPixel( Size( RSC_SP_CTRL_GROUP_X, RSC_SP_CTRL_GROUP_Y ), MAP_APPFONT );
+ Point aThirdLinePos = m_ReleaseNotesLabel.GetPosPixel();
+ aThirdLinePos.Y() = aThirdLinePos.Y() + m_ReleaseNotesLabel.GetSizePixel().Height() + aMarginSize.Height();
+ m_nFirstLineDelta = aThirdLinePos.Y() - m_aFirstLinePos.Y();
+ m_nOneLineMissing = m_ReleaseNotesLabel.GetPosPixel().Y() - m_PublisherLabel.GetPosPixel().Y();
+}
+
+void UpdateDialog::clearDescription()
+{
+ String sEmpty;
+ m_PublisherLabel.Hide();
+ m_PublisherLink.Hide();
+ m_PublisherLink.SetDescription( sEmpty );
+ m_PublisherLink.SetURL( sEmpty );
+ m_ReleaseNotesLabel.Hide();
+ m_ReleaseNotesLink.Hide();
+ m_ReleaseNotesLink.SetURL( sEmpty );
+ if ( m_PublisherLabel.GetPosPixel().Y() == m_ReleaseNotesLabel.GetPosPixel().Y() )
+ {
+ Point aNewPos = m_ReleaseNotesLabel.GetPosPixel();
+ aNewPos.Y() += m_nOneLineMissing;
+ m_ReleaseNotesLabel.SetPosPixel( aNewPos );
+ aNewPos = m_ReleaseNotesLink.GetPosPixel();
+ aNewPos.Y() += m_nOneLineMissing;
+ m_ReleaseNotesLink.SetPosPixel( aNewPos );
+ }
+ m_descriptions.Hide();
+ m_descriptions.Clear();
+ m_descriptions.SetPosSizePixel( m_aFirstLinePos, m_aFirstLineSize );
+}
+
+bool UpdateDialog::showDescription(css::uno::Reference< css::xml::dom::XNode > const & aUpdateInfo)
+{
+ dp_misc::DescriptionInfoset infoset(m_context, aUpdateInfo);
+ std::pair< rtl::OUString, rtl::OUString > pairPub = infoset.getLocalizedPublisherNameAndURL();
+ rtl::OUString sPub = pairPub.first;
+ rtl::OUString sURL = pairPub.second;
+ rtl::OUString sRel = infoset.getLocalizedReleaseNotesURL();
+
+ if ( sPub.getLength() == 0 && sURL.getLength() == 0 && sRel.getLength() == 0 )
+ // nothing to show
+ return false;
+
+ bool bPublisher = false;
+ if ( sPub.getLength() > 0 )
+ {
+ m_PublisherLabel.Show();
+ m_PublisherLink.Show();
+ m_PublisherLink.SetDescription( sPub );
+ m_PublisherLink.SetURL( sURL );
+ bPublisher = true;
+ }
+
+ if ( sRel.getLength() > 0 )
+ {
+ if ( !bPublisher )
+ {
+ m_ReleaseNotesLabel.SetPosPixel( m_PublisherLabel.GetPosPixel() );
+ m_ReleaseNotesLink.SetPosPixel( m_PublisherLink.GetPosPixel() );
+ }
+ m_ReleaseNotesLabel.Show();
+ m_ReleaseNotesLink.Show();
+ m_ReleaseNotesLink.SetURL( sRel );
+ }
+ return true;
+}
+
+bool UpdateDialog::showDescription( const String& rDescription, bool bWithPublisher )
+{
+ if ( rDescription.Len() == 0 )
+ // nothing to show
+ return false;
+
+ if ( bWithPublisher )
+ {
+ bool bOneLineMissing = !m_ReleaseNotesLabel.IsVisible() || !m_PublisherLabel.IsVisible();
+ Point aNewPos = m_aFirstLinePos;
+ aNewPos.Y() += m_nFirstLineDelta;
+ if ( bOneLineMissing )
+ aNewPos.Y() -= m_nOneLineMissing;
+ Size aNewSize = m_aFirstLineSize;
+ aNewSize.Height() -= m_nFirstLineDelta;
+ if ( bOneLineMissing )
+ aNewSize.Height() += m_nOneLineMissing;
+ m_descriptions.SetPosSizePixel( aNewPos, aNewSize );
+ }
+ m_descriptions.Show();
+ m_descriptions.SetDescription( rDescription );
+ return true;
+}
+
+IMPL_LINK(UpdateDialog, selectionHandler, void *, EMPTYARG)
+{
+ rtl::OUStringBuffer b;
+ bool bInserted = false;
+ UpdateDialog::Index const * p = static_cast< UpdateDialog::Index const * >(
+ m_updates.GetEntryData(m_updates.GetSelectEntryPos()));
+ clearDescription();
+
+ if (p != NULL)
+ {
+ //When the index is greater or equal than the amount of enabled updates then the "Show all"
+ //button is probably checked. Then we show first all enabled and then the disabled
+ //updates.
+ USHORT pos = m_updates.GetSelectEntryPos();
+ const std::vector< dp_gui::UpdateData >::size_type sizeEnabled =
+ m_enabledUpdates.size();
+ const std::vector< UpdateDialog::DisabledUpdate >::size_type sizeDisabled =
+ m_disabledUpdates.size();
+ if (pos < sizeEnabled)
+ bInserted = showDescription(m_enabledUpdates[pos].aUpdateInfo);
+ else if (pos >= sizeEnabled
+ && pos < (sizeEnabled + sizeDisabled))
+ bInserted = showDescription(m_disabledUpdates[pos - sizeEnabled].aUpdateInfo);
+
+ switch (p->kind)
+ {
+ case ENABLED_UPDATE:
+ {
+ b.append(m_noDescription);
+ break;
+ }
+ case DISABLED_UPDATE:
+ {
+ UpdateDialog::DisabledUpdate & data = m_disabledUpdates[
+ p->index.disabledUpdate];
+ if (data.unsatisfiedDependencies.getLength() != 0)
+ {
+ // create error string for version mismatch
+ ::rtl::OUString sVersion( RTL_CONSTASCII_USTRINGPARAM("%VERSION") );
+ sal_Int32 nPos = m_noDependencyCurVer.indexOf( sVersion );
+ if ( nPos >= 0 )
+ {
+ ::rtl::OUString sCurVersion( RTL_CONSTASCII_USTRINGPARAM( "${$OOO_BASE_DIR/program/" SAL_CONFIGFILE("version") ":Version:OOOPackageVersion}"));
+ ::rtl::Bootstrap::expandMacros(sCurVersion);
+ m_noDependencyCurVer = m_noDependencyCurVer.replaceAt( nPos, sVersion.getLength(), sCurVersion );
+ }
+
+ b.append(m_noInstall);
+ b.append(LF);
+ b.append(m_noDependency);
+ for (sal_Int32 i = 0;
+ i < data.unsatisfiedDependencies.getLength(); ++i)
+ {
+ b.append(LF);
+ b.appendAscii(RTL_CONSTASCII_STRINGPARAM(" "));
+ // U+2003 EM SPACE would be better than two spaces,
+ // but some fonts do not contain it
+ b.append(
+ confineToParagraph(
+ data.unsatisfiedDependencies[i]));
+ }
+ b.append(LF);
+ b.appendAscii(RTL_CONSTASCII_STRINGPARAM(" "));
+ b.append(m_noDependencyCurVer);
+ }
+ if (!data.permission) {
+ if (b.getLength() == 0) {
+ b.append(m_noInstall);
+ }
+ b.append(LF);
+ if (isVista())
+ b.append(m_noPermissionVista);
+ else
+ b.append(m_noPermission);
+ }
+ break;
+ }
+ case GENERAL_ERROR:
+ {
+ rtl::OUString & msg = m_generalErrors[p->index.generalError];
+ b.append(m_failure);
+ b.append(LF);
+ b.append(msg.getLength() == 0 ? m_unknownError : msg);
+ break;
+ }
+ case SPECIFIC_ERROR:
+ {
+ UpdateDialog::SpecificError & data = m_specificErrors[
+ p->index.specificError];
+ b.append(m_failure);
+ b.append(LF);
+ b.append(
+ data.message.getLength() == 0
+ ? m_unknownError : data.message);
+ break;
+ }
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ }
+
+ showDescription( b.makeStringAndClear(), bInserted );
+ return 0;
+}
+
+IMPL_LINK(UpdateDialog, allHandler, void *, EMPTYARG) {
+ if (m_all.IsChecked()) {
+ m_update.Enable();
+ m_updates.Enable();
+ m_description.Enable();
+ m_descriptions.Enable();
+ std::vector< UpdateDialog::DisabledUpdate >::size_type n1 = 0;
+ for (std::vector< UpdateDialog::DisabledUpdate >::iterator i(
+ m_disabledUpdates.begin());
+ i != m_disabledUpdates.end(); ++i)
+ {
+ insertItem(
+ i->name, LISTBOX_APPEND,
+ UpdateDialog::Index::newDisabledUpdate(n1++),
+ SvLBoxButtonKind_disabledCheckbox);
+ }
+ std::vector< rtl::OUString >::size_type n2 = 0;
+ for (std::vector< rtl::OUString >::iterator i(m_generalErrors.begin());
+ i != m_generalErrors.end(); ++i)
+ {
+ insertItem(
+ m_error, LISTBOX_APPEND,
+ UpdateDialog::Index::newGeneralError(n2++),
+ SvLBoxButtonKind_staticImage);
+ }
+ std::vector< UpdateDialog::SpecificError >::size_type n3 = 0;
+ for (std::vector< UpdateDialog::SpecificError >::iterator i(
+ m_specificErrors.begin());
+ i != m_specificErrors.end(); ++i)
+ {
+ insertItem(
+ i->name, LISTBOX_APPEND,
+ UpdateDialog::Index::newSpecificError(n3++),
+ SvLBoxButtonKind_staticImage);
+ }
+ } else {
+ for (USHORT i = 0; i < m_updates.getItemCount();) {
+ UpdateDialog::Index const * p =
+ static_cast< UpdateDialog::Index const * >(
+ m_updates.GetEntryData(i));
+ if (p->kind != ENABLED_UPDATE) {
+ m_updates.RemoveEntry(i);
+ //TODO #i72487#: UpdateDialog::Index potentially leaks as
+ // SvxCheckListBox::RemoveEntry's exception behavior is
+ // unspecified
+ delete p;
+ } else {
+ ++i;
+ }
+ }
+
+ if (m_updates.getItemCount() == 0)
+ {
+ clearDescription();
+ m_update.Disable();
+ m_updates.Disable();
+ if (m_checking.IsVisible())
+ m_description.Disable();
+ else
+ showDescription(m_noInstallable,false);
+ }
+ }
+ return 0;
+}
+
+IMPL_LINK(UpdateDialog, okHandler, void *, EMPTYARG)
+{
+ //If users are going to update a shared extension then we need
+ //to warn them
+ typedef ::std::vector<UpdateData>::const_iterator CIT;
+ for (CIT i = m_enabledUpdates.begin(); i < m_enabledUpdates.end(); i++)
+ {
+ OSL_ASSERT(i->aPackageManager.is());
+ //If the user has no write access to the shared folder then the update
+ //for a shared extension is disable, that is it cannot be in m_enabledUpdates
+ OSL_ASSERT(i->aPackageManager->isReadOnly() == sal_False);
+#if 0
+ // TODO: check!
+ OSL_ASSERT(m_extensionManagerDialog.get());
+ if (RET_CANCEL == m_extensionManagerDialog->continueUpdateForSharedExtension(
+ this, i->aPackageManager))
+ {
+ EndDialog(RET_CANCEL);
+ }
+#endif
+ }
+
+ for (USHORT i = 0; i < m_updates.getItemCount(); ++i) {
+ UpdateDialog::Index const * p =
+ static_cast< UpdateDialog::Index const * >(
+ m_updates.GetEntryData(i));
+ if (p->kind == ENABLED_UPDATE && m_updates.IsChecked(i)) {
+ m_updateData.push_back(m_enabledUpdates[p->index.enabledUpdate]);
+ }
+ }
+ EndDialog(RET_OK);
+ return 0;
+}
+
+IMPL_LINK(UpdateDialog, cancelHandler, void *, EMPTYARG) {
+ m_thread->stop();
+ EndDialog(RET_CANCEL);
+ return 0;
+}
+
+IMPL_LINK( UpdateDialog, hyperlink_clicked, svt::FixedHyperlink*, pHyperlink )
+{
+ ::rtl::OUString sURL;
+ if ( pHyperlink )
+ sURL = ::rtl::OUString( pHyperlink->GetURL() );
+ if ( sURL.getLength() == 0 )
+ return 0;
+
+ try
+ {
+ css::uno::Reference< css::system::XSystemShellExecute > xSystemShellExecute(
+ m_context->getServiceManager()->createInstanceWithContext(
+ ::rtl::OUString::createFromAscii( "com.sun.star.system.SystemShellExecute" ),
+ m_context), css::uno::UNO_QUERY_THROW);
+ //throws css::lang::IllegalArgumentException, css::system::SystemShellExecuteException
+ xSystemShellExecute->execute(
+ sURL, ::rtl::OUString(), css::system::SystemShellExecuteFlags::DEFAULTS);
+ }
+ catch (css::uno::Exception& )
+ {
+ }
+
+ return 1;
+}
diff --git a/desktop/source/deployment/gui/dp_gui_updatedialog.hxx b/desktop/source/deployment/gui/dp_gui_updatedialog.hxx
new file mode 100644
index 000000000000..578ad6b6f01d
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_updatedialog.hxx
@@ -0,0 +1,226 @@
+/*************************************************************************
+ *
+ * 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
+ *
+ * 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 INCLUDED_DESKTOP_SOURCE_DEPLOYMENT_GUI_DP_GUI_UPDATEDIALOG_HXX
+#define INCLUDED_DESKTOP_SOURCE_DEPLOYMENT_GUI_DP_GUI_UPDATEDIALOG_HXX
+
+#include "sal/config.h"
+
+#include <memory>
+#include <vector>
+#include "com/sun/star/uno/Reference.hxx"
+#include "com/sun/star/uno/Sequence.hxx"
+#include "rtl/ref.hxx"
+#include "rtl/ustring.hxx"
+#include "svtools/svlbitm.hxx"
+#include "svx/checklbx.hxx"
+#include "tools/link.hxx"
+#include "tools/solar.h"
+#ifndef _SV_BUTTON_HXX
+#include "vcl/button.hxx"
+#endif
+#include "vcl/dialog.hxx"
+#include "vcl/fixed.hxx"
+#include <svtools/fixedhyper.hxx>
+
+#include "descedit.hxx"
+#include "dp_gui_updatedata.hxx"
+
+/// @HTML
+
+class Image;
+class KeyEvent;
+class MouseEvent;
+class ResId;
+class Window;
+
+namespace com { namespace sun { namespace star {
+ namespace awt { class XThrobber; }
+ namespace deployment { class XPackageManager; }
+ namespace uno { class XComponentContext; }
+} } }
+
+namespace dp_gui {
+/**
+ The modal &ldquo;Check for Updates&rdquo; dialog.
+*/
+class UpdateDialog: public ModalDialog {
+public:
+ /**
+ Create an instance.
+
+ <p>Exactly one of <code>selectedPackages</code> and
+ <code>packageManagers</code> must be non-null.</p>
+
+ @param context
+ a non-null component context
+
+ @param parent
+ the parent window, may be null
+
+ @param selectedPackages
+ if non-null, only check for updates for the selected packages
+
+ @param packageManagers
+ if non-null, check for updates for all managed packages
+ */
+ UpdateDialog(
+ com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > const & context,
+ Window * parent,
+ const std::vector< dp_gui::TUpdateListEntry > &vExtensionList,
+ std::vector< dp_gui::UpdateData > * updateData);
+
+ ~UpdateDialog();
+
+ virtual BOOL Close();
+
+ virtual short Execute();
+
+ void notifyMenubar( bool bPrepareOnly, bool bRecheckOnly );
+ static void createNotifyJob( bool bPrepareOnly,
+ com::sun::star::uno::Sequence< com::sun::star::uno::Sequence< rtl::OUString > > &rItemList );
+
+private:
+ UpdateDialog(UpdateDialog &); // not defined
+ void operator =(UpdateDialog &); // not defined
+
+ struct DisabledUpdate;
+ struct SpecificError;
+ union IndexUnion;
+ friend union IndexUnion;
+ struct Index;
+ friend struct Index;
+ class Thread;
+ friend class Thread;
+
+ class CheckListBox: public SvxCheckListBox {
+ public:
+ CheckListBox(
+ UpdateDialog & dialog, ResId const & resource,
+ Image const & normalStaticImage,
+ Image const & highContrastStaticImage);
+
+ virtual ~CheckListBox();
+
+ USHORT getItemCount() const;
+
+ private:
+ CheckListBox(UpdateDialog::CheckListBox &); // not defined
+ void operator =(UpdateDialog::CheckListBox &); // not defined
+
+ virtual void MouseButtonDown(MouseEvent const & event);
+
+ virtual void MouseButtonUp(MouseEvent const & event);
+
+ virtual void KeyInput(KeyEvent const & event);
+
+ UpdateDialog & m_dialog;
+ };
+
+ friend class CheckListBox;
+
+ void insertItem(
+ rtl::OUString const & name, USHORT position,
+ std::auto_ptr< UpdateDialog::Index const > index,
+ SvLBoxButtonKind kind);
+
+ void addAdditional(
+ rtl::OUString const & name, USHORT position,
+ std::auto_ptr< UpdateDialog::Index const > index,
+ SvLBoxButtonKind kind);
+
+ void addEnabledUpdate(
+ rtl::OUString const & name, dp_gui::UpdateData const & data);
+
+ void addDisabledUpdate(UpdateDialog::DisabledUpdate const & data);
+
+ void addGeneralError(rtl::OUString const & message);
+
+ void addSpecificError(UpdateDialog::SpecificError const & data);
+
+ void checkingDone();
+
+ void enableOk();
+
+ void initDescription();
+ void clearDescription();
+ bool showDescription( ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::dom::XNode > const & aUpdateInfo);
+ bool showDescription( const String& rDescription, bool bWithPublisher );
+
+ DECL_LINK(selectionHandler, void *);
+ DECL_LINK(allHandler, void *);
+ DECL_LINK(okHandler, void *);
+ DECL_LINK(cancelHandler, void *);
+ DECL_LINK(hyperlink_clicked, svt::FixedHyperlink *);
+
+ com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext >
+ m_context;
+ FixedText m_checking;
+ com::sun::star::uno::Reference< com::sun::star::awt::XThrobber > m_throbber;
+ FixedText m_update;
+ UpdateDialog::CheckListBox m_updates;
+ CheckBox m_all;
+ FixedLine m_description;
+ FixedText m_PublisherLabel;
+ svt::FixedHyperlink m_PublisherLink;
+ FixedText m_ReleaseNotesLabel;
+ svt::FixedHyperlink m_ReleaseNotesLink;
+ dp_gui::DescriptionEdit m_descriptions;
+ FixedLine m_line;
+ HelpButton m_help;
+ PushButton m_ok;
+ CancelButton m_cancel;
+ rtl::OUString m_error;
+ rtl::OUString m_none;
+ rtl::OUString m_noInstallable;
+ rtl::OUString m_failure;
+ rtl::OUString m_unknownError;
+ rtl::OUString m_noDescription;
+ rtl::OUString m_noInstall;
+ rtl::OUString m_noDependency;
+ rtl::OUString m_noDependencyCurVer;
+ rtl::OUString m_noPermission;
+ rtl::OUString m_noPermissionVista;
+ rtl::OUString m_browserbased;
+ rtl::OUString m_version;
+ std::vector< dp_gui::UpdateData > m_enabledUpdates;
+ std::vector< UpdateDialog::DisabledUpdate > m_disabledUpdates;
+ std::vector< rtl::OUString > m_generalErrors;
+ std::vector< UpdateDialog::SpecificError > m_specificErrors;
+ std::vector< dp_gui::UpdateData > & m_updateData;
+ rtl::Reference< UpdateDialog::Thread > m_thread;
+
+ Point m_aFirstLinePos;
+ Size m_aFirstLineSize;
+ long m_nFirstLineDelta;
+ long m_nOneLineMissing;
+};
+
+}
+
+#endif
diff --git a/desktop/source/deployment/gui/dp_gui_updatedialog.src b/desktop/source/deployment/gui/dp_gui_updatedialog.src
new file mode 100644
index 000000000000..49d3c1c0cf8e
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_updatedialog.src
@@ -0,0 +1,277 @@
+/*************************************************************************
+ *
+ * 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
+ *
+ * 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 "svtools/controldims.hrc"
+
+#include "dp_gui.hrc"
+
+#define LOCAL_WIDTH (60 * RSC_BS_CHARWIDTH)
+#define LABEL_WIDTH (1 * RSC_BS_CHARWIDTH)
+#define LOCAL_LIST_HEIGHT1 (6 * RSC_BS_CHARHEIGHT) + 4
+#define LOCAL_LIST_HEIGHT2 (7 * RSC_BS_CHARHEIGHT) + 3
+
+ModalDialog RID_DLG_UPDATE {
+ HelpID = HID_DEPLOYMENT_GUI_UPDATE;
+ Size = MAP_APPFONT(
+ (RSC_SP_DLG_INNERBORDER_LEFT + LOCAL_WIDTH +
+ RSC_SP_DLG_INNERBORDER_RIGHT),
+ (RSC_SP_DLG_INNERBORDER_TOP + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + LOCAL_LIST_HEIGHT1 + RSC_SP_CTRL_GROUP_Y +
+ RSC_CD_CHECKBOX_HEIGHT + RSC_SP_CTRL_GROUP_Y + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + LOCAL_LIST_HEIGHT2 + RSC_SP_FLGR_SPACE_Y +
+ RSC_CD_FIXEDLINE_HEIGHT + RSC_SP_FLGR_SPACE_Y +
+ RSC_CD_PUSHBUTTON_HEIGHT + RSC_SP_DLG_INNERBORDER_BOTTOM));
+ Text[en-US] = "Extension Update";
+ Moveable = TRUE;
+ Closeable = TRUE;
+ FixedText RID_DLG_UPDATE_CHECKING {
+ Pos = MAP_APPFONT(
+ RSC_SP_DLG_INNERBORDER_LEFT + LOCAL_WIDTH * 2 / 3,
+ RSC_SP_DLG_INNERBORDER_TOP);
+ Size = MAP_APPFONT(
+ (LOCAL_WIDTH - LOCAL_WIDTH * 2 / 3 - RSC_SP_CTRL_DESC_X -
+ RSC_CD_FIXEDTEXT_HEIGHT),
+ RSC_CD_FIXEDTEXT_HEIGHT);
+ Text[en-US] = "Checking...";
+ Right = TRUE;
+ NoLabel = TRUE;
+ };
+ Control RID_DLG_UPDATE_THROBBER {
+ Pos = MAP_APPFONT(
+ RSC_SP_DLG_INNERBORDER_LEFT + LOCAL_WIDTH - RSC_CD_FIXEDTEXT_HEIGHT,
+ RSC_SP_DLG_INNERBORDER_TOP);
+ Size = MAP_APPFONT(RSC_CD_FIXEDTEXT_HEIGHT, RSC_CD_FIXEDTEXT_HEIGHT);
+ };
+ FixedText RID_DLG_UPDATE_UPDATE {
+ Disable = TRUE;
+ Pos = MAP_APPFONT(
+ RSC_SP_DLG_INNERBORDER_LEFT, RSC_SP_DLG_INNERBORDER_TOP);
+ Size = MAP_APPFONT(
+ LOCAL_WIDTH * 2 / 3 - RSC_SP_CTRL_GROUP_X, RSC_CD_FIXEDTEXT_HEIGHT);
+ Text[en-US] = "~Available extension updates";
+ };
+ Control RID_DLG_UPDATE_UPDATES {
+ HelpId = HID_DEPLOYMENT_GUI_UPDATE_AVAILABLE_UPDATES;
+ Disable = TRUE;
+ Border = TRUE;
+ Pos = MAP_APPFONT(
+ RSC_SP_DLG_INNERBORDER_LEFT,
+ (RSC_SP_DLG_INNERBORDER_TOP + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y));
+ Size = MAP_APPFONT(LOCAL_WIDTH, LOCAL_LIST_HEIGHT1);
+ TabStop = TRUE;
+ };
+ CheckBox RID_DLG_UPDATE_ALL {
+ Disable = TRUE;
+ Pos = MAP_APPFONT(
+ RSC_SP_DLG_INNERBORDER_LEFT,
+ (RSC_SP_DLG_INNERBORDER_TOP + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + LOCAL_LIST_HEIGHT1 + RSC_SP_CTRL_GROUP_Y));
+ Size = MAP_APPFONT(LOCAL_WIDTH, RSC_CD_CHECKBOX_HEIGHT);
+ Text[en-US] = "~Show all updates";
+ };
+ FixedLine RID_DLG_UPDATE_DESCRIPTION {
+ Disable = TRUE;
+ Pos = MAP_APPFONT(
+ RSC_SP_DLG_INNERBORDER_LEFT,
+ (RSC_SP_DLG_INNERBORDER_TOP + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + LOCAL_LIST_HEIGHT1 + RSC_SP_CTRL_GROUP_Y +
+ RSC_CD_CHECKBOX_HEIGHT + RSC_SP_CTRL_GROUP_Y));
+ Size = MAP_APPFONT(LOCAL_WIDTH, RSC_CD_FIXEDTEXT_HEIGHT);
+ Text[en-US] = "Description";
+ };
+ FixedText RID_DLG_UPDATE_PUBLISHER_LABEL
+ {
+ Pos = MAP_APPFONT(
+ RSC_SP_DLG_INNERBORDER_LEFT,
+ (RSC_SP_DLG_INNERBORDER_TOP + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + LOCAL_LIST_HEIGHT1 + RSC_SP_CTRL_GROUP_Y +
+ RSC_CD_CHECKBOX_HEIGHT + RSC_SP_CTRL_GROUP_Y + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y));
+ Size = MAP_APPFONT(LABEL_WIDTH, RSC_CD_FIXEDTEXT_HEIGHT);
+ Text[en-US] = "Publisher:";
+ };
+ FixedText RID_DLG_UPDATE_PUBLISHER_LINK
+ {
+ HelpId = HID_DEPLOYMENT_GUI_UPDATE_PUBLISHER;
+ Pos = MAP_APPFONT(
+ RSC_SP_DLG_INNERBORDER_LEFT + LABEL_WIDTH + RSC_SP_CTRL_DESC_X,
+ (RSC_SP_DLG_INNERBORDER_TOP + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + LOCAL_LIST_HEIGHT1 + RSC_SP_CTRL_GROUP_Y +
+ RSC_CD_CHECKBOX_HEIGHT + RSC_SP_CTRL_GROUP_Y + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y));
+ Size = MAP_APPFONT(LOCAL_WIDTH - LABEL_WIDTH - RSC_SP_CTRL_DESC_X, RSC_CD_FIXEDTEXT_HEIGHT);
+ };
+ FixedText RID_DLG_UPDATE_RELEASENOTES_LABEL
+ {
+ Pos = MAP_APPFONT(
+ RSC_SP_DLG_INNERBORDER_LEFT,
+ (RSC_SP_DLG_INNERBORDER_TOP + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + LOCAL_LIST_HEIGHT1 + RSC_SP_CTRL_GROUP_Y +
+ RSC_CD_CHECKBOX_HEIGHT + RSC_SP_CTRL_GROUP_Y + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + RSC_CD_FIXEDTEXT_HEIGHT + RSC_SP_CTRL_DESC_Y));
+ Size = MAP_APPFONT(LABEL_WIDTH, RSC_CD_FIXEDTEXT_HEIGHT);
+ Text[en-US] = "What is new:";
+ };
+ FixedText RID_DLG_UPDATE_RELEASENOTES_LINK
+ {
+ HelpId = HID_DEPLOYMENT_GUI_UPDATE_RELEASENOTES;
+ Pos = MAP_APPFONT(
+ RSC_SP_DLG_INNERBORDER_LEFT + LABEL_WIDTH + RSC_SP_CTRL_DESC_X,
+ (RSC_SP_DLG_INNERBORDER_TOP + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + LOCAL_LIST_HEIGHT1 + RSC_SP_CTRL_GROUP_Y +
+ RSC_CD_CHECKBOX_HEIGHT + RSC_SP_CTRL_GROUP_Y + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + RSC_CD_FIXEDTEXT_HEIGHT + RSC_SP_CTRL_DESC_Y));
+ Size = MAP_APPFONT(LOCAL_WIDTH - LABEL_WIDTH - RSC_SP_CTRL_DESC_X, RSC_CD_FIXEDTEXT_HEIGHT);
+ Text[en-US] = "Release Notes";
+ };
+ MultiLineEdit RID_DLG_UPDATE_DESCRIPTIONS {
+ Disable = TRUE;
+ Border = TRUE;
+ Pos = MAP_APPFONT(
+ RSC_SP_DLG_INNERBORDER_LEFT,
+ (RSC_SP_DLG_INNERBORDER_TOP + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + LOCAL_LIST_HEIGHT1 + RSC_SP_CTRL_GROUP_Y +
+ RSC_CD_CHECKBOX_HEIGHT + RSC_SP_CTRL_GROUP_Y + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y));
+ Size = MAP_APPFONT(LOCAL_WIDTH, LOCAL_LIST_HEIGHT2);
+ ReadOnly = TRUE;
+ VScroll = TRUE;
+ IgnoreTab = TRUE;
+ };
+ FixedLine RID_DLG_UPDATE_LINE {
+ Pos = MAP_APPFONT(
+ RSC_SP_DLG_INNERBORDER_LEFT,
+ (RSC_SP_DLG_INNERBORDER_TOP + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + LOCAL_LIST_HEIGHT1 + RSC_SP_CTRL_GROUP_Y +
+ RSC_CD_CHECKBOX_HEIGHT + RSC_SP_CTRL_GROUP_Y + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + LOCAL_LIST_HEIGHT2 + RSC_SP_FLGR_SPACE_Y));
+ Size = MAP_APPFONT(LOCAL_WIDTH, RSC_CD_FIXEDLINE_HEIGHT);
+ };
+ HelpButton RID_DLG_UPDATE_HELP {
+ Pos = MAP_APPFONT(
+ RSC_SP_DLG_INNERBORDER_LEFT,
+ (RSC_SP_DLG_INNERBORDER_TOP + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + LOCAL_LIST_HEIGHT1 + RSC_SP_CTRL_GROUP_Y +
+ RSC_CD_CHECKBOX_HEIGHT + RSC_SP_CTRL_GROUP_Y + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + LOCAL_LIST_HEIGHT2 + RSC_SP_FLGR_SPACE_Y +
+ RSC_CD_FIXEDLINE_HEIGHT + RSC_SP_FLGR_SPACE_Y));
+ Size = MAP_APPFONT(RSC_CD_PUSHBUTTON_WIDTH, RSC_CD_PUSHBUTTON_HEIGHT);
+ };
+ PushButton RID_DLG_UPDATE_OK {
+ Disable = TRUE;
+ Pos = MAP_APPFONT(
+ (RSC_SP_DLG_INNERBORDER_LEFT + LOCAL_WIDTH - RSC_CD_PUSHBUTTON_WIDTH -
+ RSC_SP_CTRL_GROUP_X - RSC_CD_PUSHBUTTON_WIDTH),
+ (RSC_SP_DLG_INNERBORDER_TOP + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + LOCAL_LIST_HEIGHT1 + RSC_SP_CTRL_GROUP_Y +
+ RSC_CD_CHECKBOX_HEIGHT + RSC_SP_CTRL_GROUP_Y + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + LOCAL_LIST_HEIGHT2 + RSC_SP_FLGR_SPACE_Y +
+ RSC_CD_FIXEDLINE_HEIGHT + RSC_SP_FLGR_SPACE_Y));
+ Size = MAP_APPFONT(RSC_CD_PUSHBUTTON_WIDTH, RSC_CD_PUSHBUTTON_HEIGHT);
+ Text[en-US] = "~Install";
+ DefButton = TRUE;
+ };
+ CancelButton RID_DLG_UPDATE_CANCEL {
+ Pos = MAP_APPFONT(
+ RSC_SP_DLG_INNERBORDER_LEFT + LOCAL_WIDTH - RSC_CD_PUSHBUTTON_WIDTH,
+ (RSC_SP_DLG_INNERBORDER_TOP + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + LOCAL_LIST_HEIGHT1 + RSC_SP_CTRL_GROUP_Y +
+ RSC_CD_CHECKBOX_HEIGHT + RSC_SP_CTRL_GROUP_Y + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + LOCAL_LIST_HEIGHT2 + RSC_SP_FLGR_SPACE_Y +
+ RSC_CD_FIXEDLINE_HEIGHT + RSC_SP_FLGR_SPACE_Y));
+ Size = MAP_APPFONT(RSC_CD_PUSHBUTTON_WIDTH, RSC_CD_PUSHBUTTON_HEIGHT);
+ };
+
+ Image RID_DLG_UPDATE_NORMALALERT {
+ ImageBitmap = Bitmap {
+ File = "caution_12.png";
+ };
+ };
+ Image RID_DLG_UPDATE_HIGHCONTRASTALERT {
+ ImageBitmap = Bitmap {
+ File = "caution_12_h.png";
+ };
+ };
+ String RID_DLG_UPDATE_ERROR {
+ Text[en-US] = "Error";
+ };
+ String RID_DLG_UPDATE_NONE {
+ Text[en-US] = "No new updates are available.";
+ };
+ String RID_DLG_UPDATE_NOINSTALLABLE {
+ Text[en-US] = "No installable updates are available. To see all updates, mark the check box 'Show all updates'.";
+ };
+ String RID_DLG_UPDATE_FAILURE {
+ Text[en-US] = "An error occurred:";
+ };
+ String RID_DLG_UPDATE_UNKNOWNERROR {
+ Text[en-US] = "Unknown error.";
+ };
+ String RID_DLG_UPDATE_NODESCRIPTION {
+ Text[en-US] = "No descriptions available for this extension.";
+ };
+ String RID_DLG_UPDATE_NOINSTALL {
+ Text[en-US] = "The extension cannot be updated because:";
+ };
+ String RID_DLG_UPDATE_NODEPENDENCY {
+ Text[en-US] = "Required OpenOffice.org version doesn't match:";
+ };
+ String RID_DLG_UPDATE_NODEPENDENCY_CUR_VER {
+ Text[en-US] = "You have OpenOffice.org %VERSION";
+ };
+ String RID_DLG_UPDATE_NOPERMISSION {
+ Text[en-US] = "No write permission (shared extension).";
+ };
+ String RID_DLG_UPDATE_NOPERMISSION_VISTA {
+ Text[en-US] = "No write permission. %PRODUCTNAME needs to run as administrator.\n"
+ "Please follow these steps to update this shared extension:\n"
+ "1. Close Extension Manager dialog.\n"
+ "2. Exit %PRODUCTNAME.\n"
+ "3. Exit %PRODUCTNAME Quickstarter located in the tray area of Windows.\n"
+ "4. Run %PRODUCTNAME as administrator. In order to do this call the context menu of the %PRODUCTNAME program icon and choose \'Run as administrator\'.\n"
+ "5. Call the Extension Manager dialog and update this shared extension.\n";
+ };
+ String RID_DLG_UPDATE_BROWSERBASED {
+ Text[en-US] = "browser based update";
+ };
+
+ String RID_DLG_UPDATE_VERSION {
+ Text[en-US] = "Version";
+ };
+};
+
+WarningBox RID_WARNINGBOX_UPDATE_SHARED_EXTENSION
+{
+ Buttons = WB_OK_CANCEL;
+ DefButton = WB_DEF_CANCEL;
+ Message[en-US] = "Make sure that no further users are working with the same "
+ "%PRODUCTNAME, when changing shared extensions in a multi user environment.\n"
+ "Click \'OK\' to update the extensions.\n"
+ "Click \'Cancel\' to stop updating the extensions.";
+};
+
diff --git a/desktop/source/deployment/gui/dp_gui_updateinstalldialog.cxx b/desktop/source/deployment/gui/dp_gui_updateinstalldialog.cxx
new file mode 100644
index 000000000000..76e182825397
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_updateinstalldialog.cxx
@@ -0,0 +1,731 @@
+/*************************************************************************
+ *
+ * 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: dp_gui_updateinstalldialog.cxx,v $
+ * $Revision: 1.9.76.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_desktop.hxx"
+
+#include "dp_gui_updatedata.hxx"
+
+#include "sal/config.h"
+#include "osl/file.hxx"
+#include "osl/conditn.hxx"
+#include "cppuhelper/exc_hlp.hxx"
+#include "tools/resid.hxx"
+#include "tools/resmgr.hxx"
+#include "tools/solar.h"
+#include "tools/string.hxx"
+#include "vcl/dialog.hxx"
+#include "vcl/msgbox.hxx"
+#include "vcl/svapp.hxx"
+#include "vos/mutex.hxx"
+#include "vcl/dialog.hxx"
+#include "cppuhelper/implbase3.hxx"
+
+#include "com/sun/star/beans/PropertyValue.hpp"
+#include "com/sun/star/xml/dom/XElement.hpp"
+#include "com/sun/star/xml/dom/XNode.hpp"
+#include "com/sun/star/xml/dom/XNodeList.hpp"
+#include "com/sun/star/ucb/NameClash.hpp"
+#include "com/sun/star/ucb/InteractiveAugmentedIOException.hpp"
+#include "com/sun/star/ucb/XCommandEnvironment.hpp"
+#include "com/sun/star/ucb/XProgressHandler.hpp"
+#include "com/sun/star/deployment/XPackageManager.hpp"
+#include "com/sun/star/deployment/XUpdateInformationProvider.hpp"
+#include "com/sun/star/deployment/DependencyException.hpp"
+#include "com/sun/star/deployment/LicenseException.hpp"
+#include "com/sun/star/deployment/VersionException.hpp"
+#include "com/sun/star/deployment/ui/LicenseDialog.hpp"
+#include "com/sun/star/task/XInteractionHandler.hpp"
+#include "com/sun/star/ui/dialogs/XExecutableDialog.hpp"
+#include "com/sun/star/ui/dialogs/ExecutableDialogResults.hpp"
+#include "com/sun/star/task/XInteractionAbort.hpp"
+#include "com/sun/star/task/XInteractionApprove.hpp"
+
+#include "dp_descriptioninfoset.hxx"
+#include "dp_gui.hrc"
+#include "dp_gui_updateinstalldialog.hxx"
+#include "dp_gui_shared.hxx"
+#include "dp_gui_updatedata.hxx"
+#include "dp_ucb.h"
+#include "dp_misc.h"
+#include "dp_version.hxx"
+#include "dp_gui_thread.hxx"
+#include "dp_gui_extensioncmdqueue.hxx"
+#include "ucbhelper/content.hxx"
+#include "osl/mutex.hxx"
+#include "vos/mutex.hxx"
+#include "rtl/ref.hxx"
+#include "com/sun/star/uno/Sequence.h"
+#include "comphelper/anytostring.hxx"
+#include "toolkit/helper/vclunohelper.hxx"
+
+#include <vector>
+
+class Window;
+
+namespace cssu = ::com::sun::star::uno;
+namespace css = ::com::sun::star;
+
+using ::rtl::OUString;
+
+
+namespace dp_gui {
+
+class UpdateInstallDialog::Thread: public dp_gui::Thread {
+ friend class UpdateCommandEnv;
+public:
+ Thread(cssu::Reference< cssu::XComponentContext > ctx,
+ UpdateInstallDialog & dialog, std::vector< dp_gui::UpdateData > & aVecUpdateData);
+
+ void stop();
+
+
+
+private:
+ Thread(Thread &); // not defined
+ void operator =(Thread &); // not defined
+
+ virtual ~Thread();
+
+ virtual void execute();
+ void downloadExtensions();
+ void download(::rtl::OUString const & aUrls, UpdateData & aUpdatData);
+ void installExtensions();
+ void removeTempDownloads();
+
+ UpdateInstallDialog & m_dialog;
+ cssu::Reference< css::deployment::XUpdateInformationProvider >
+ m_updateInformation;
+
+ // guarded by Application::GetSolarMutex():
+ cssu::Reference< css::task::XAbortChannel > m_abort;
+ cssu::Reference< cssu::XComponentContext > m_xComponentContext;
+ std::vector< dp_gui::UpdateData > & m_aVecUpdateData;
+ ::rtl::Reference<UpdateCommandEnv> m_updateCmdEnv;
+
+ //A folder which is created in the temp directory in which then the updates are downloaded
+ ::rtl::OUString m_sDownloadFolder;
+
+ bool m_stop;
+
+};
+
+class UpdateCommandEnv
+ : public ::cppu::WeakImplHelper3< css::ucb::XCommandEnvironment,
+ css::task::XInteractionHandler,
+ css::ucb::XProgressHandler >
+{
+ friend class UpdateInstallDialog::Thread;
+
+ UpdateInstallDialog & m_updateDialog;
+ ::rtl::Reference<UpdateInstallDialog::Thread> m_installThread;
+ cssu::Reference< cssu::XComponentContext > m_xContext;
+
+public:
+ virtual ~UpdateCommandEnv();
+ UpdateCommandEnv( cssu::Reference< cssu::XComponentContext > const & xCtx,
+ UpdateInstallDialog & updateDialog,
+ ::rtl::Reference<UpdateInstallDialog::Thread>const & thread);
+
+ // XCommandEnvironment
+ virtual cssu::Reference<css::task::XInteractionHandler > SAL_CALL
+ getInteractionHandler() throw (cssu::RuntimeException);
+ virtual cssu::Reference<css::ucb::XProgressHandler >
+ SAL_CALL getProgressHandler() throw (cssu::RuntimeException);
+
+ // XInteractionHandler
+ virtual void SAL_CALL handle(
+ cssu::Reference<css::task::XInteractionRequest > const & xRequest )
+ throw (cssu::RuntimeException);
+
+ // XProgressHandler
+ virtual void SAL_CALL push( cssu::Any const & Status )
+ throw (cssu::RuntimeException);
+ virtual void SAL_CALL update( cssu::Any const & Status )
+ throw (cssu::RuntimeException);
+ virtual void SAL_CALL pop() throw (cssu::RuntimeException);
+};
+
+
+UpdateInstallDialog::Thread::Thread(
+ cssu::Reference< cssu::XComponentContext> xCtx,
+ UpdateInstallDialog & dialog,
+ std::vector< dp_gui::UpdateData > & aVecUpdateData):
+ m_dialog(dialog),
+ m_xComponentContext(xCtx),
+ m_aVecUpdateData(aVecUpdateData),
+ m_updateCmdEnv(new UpdateCommandEnv(xCtx, m_dialog, this)),
+ m_stop(false)
+{}
+
+void UpdateInstallDialog::Thread::stop() {
+ cssu::Reference< css::task::XAbortChannel > abort;
+ {
+ vos::OGuard g(Application::GetSolarMutex());
+ abort = m_abort;
+ m_stop = true;
+ }
+ if (abort.is()) {
+ abort->sendAbort();
+ }
+}
+
+UpdateInstallDialog::Thread::~Thread() {}
+
+void UpdateInstallDialog::Thread::execute()
+{
+ try {
+ downloadExtensions();
+ installExtensions();
+ }
+ catch (...)
+ {
+ }
+
+ //clean up the temp directories
+ try {
+ removeTempDownloads();
+ } catch( ... ) {
+ }
+
+ {
+ //make sure m_dialog is still alive
+ ::vos::OGuard g(Application::GetSolarMutex());
+ if (! m_stop)
+ m_dialog.updateDone();
+ }
+ //UpdateCommandEnv keeps a reference to Thread and prevents destruction. Therefore remove it.
+ m_updateCmdEnv->m_installThread.clear();
+}
+
+
+UpdateInstallDialog::UpdateInstallDialog(
+ Window * parent,
+ std::vector<dp_gui::UpdateData> & aVecUpdateData,
+ cssu::Reference< cssu::XComponentContext > const & xCtx):
+ ModalDialog(
+ parent,
+ DpGuiResId(RID_DLG_UPDATEINSTALL)),
+
+ m_thread(new Thread(xCtx, *this, aVecUpdateData)),
+ m_xComponentContext(xCtx),
+ m_bError(false),
+ m_bNoEntry(true),
+ m_bActivated(false),
+ m_sInstalling(String(DpGuiResId(RID_DLG_UPDATE_INSTALL_INSTALLING))),
+ m_sFinished(String(DpGuiResId(RID_DLG_UPDATE_INSTALL_FINISHED))),
+ m_sNoErrors(String(DpGuiResId(RID_DLG_UPDATE_INSTALL_NO_ERRORS))),
+ m_sErrorDownload(String(DpGuiResId(RID_DLG_UPDATE_INSTALL_ERROR_DOWNLOAD))),
+ m_sErrorInstallation(String(DpGuiResId(RID_DLG_UPDATE_INSTALL_ERROR_INSTALLATION))),
+ m_sErrorLicenseDeclined(String(DpGuiResId(RID_DLG_UPDATE_INSTALL_ERROR_LIC_DECLINED))),
+ m_sNoInstall(String(DpGuiResId(RID_DLG_UPDATE_INSTALL_EXTENSION_NOINSTALL))),
+ m_sThisErrorOccurred(String(DpGuiResId(RID_DLG_UPDATE_INSTALL_THIS_ERROR_OCCURRED))),
+ m_ft_action(this, DpGuiResId(RID_DLG_UPDATE_INSTALL_DOWNLOADING)),
+ m_statusbar(this,DpGuiResId(RID_DLG_UPDATE_INSTALL_STATUSBAR)),
+ m_ft_extension_name(this, DpGuiResId(RID_DLG_UPDATE_INSTALL_EXTENSION_NAME)),
+ m_ft_results(this, DpGuiResId(RID_DLG_UPDATE_INSTALL_RESULTS)),
+ m_mle_info(this, DpGuiResId(RID_DLG_UPDATE_INSTALL_INFO)),
+ m_line(this, DpGuiResId(RID_DLG_UPDATE_INSTALL_LINE)),
+ m_help(this, DpGuiResId(RID_DLG_UPDATE_INSTALL_HELP)),
+ m_ok(this, DpGuiResId(RID_DLG_UPDATE_INSTALL_OK)),
+ m_cancel(this, DpGuiResId(RID_DLG_UPDATE_INSTALL_ABORT))
+{
+ FreeResource();
+
+ m_cancel.SetClickHdl(LINK(this, UpdateInstallDialog, cancelHandler));
+ m_mle_info.EnableCursor(FALSE);
+ if ( ! dp_misc::office_is_running())
+ m_help.Disable();
+}
+
+UpdateInstallDialog::~UpdateInstallDialog() {}
+
+BOOL UpdateInstallDialog::Close()
+{
+ m_thread->stop();
+ return ModalDialog::Close();
+}
+
+short UpdateInstallDialog::Execute()
+{
+ m_thread->launch();
+ return ModalDialog::Execute();
+}
+
+
+// make sure the solar mutex is locked before calling
+void UpdateInstallDialog::updateDone()
+{
+ if (!m_bError)
+ m_mle_info.InsertText(m_sNoErrors);
+ m_ok.Enable();
+ m_ok.GrabFocus();
+ m_cancel.Disable();
+}
+// make sure the solar mutex is locked before calling
+//sets an error message in the text area
+void UpdateInstallDialog::setError(INSTALL_ERROR err, ::rtl::OUString const & sExtension,
+ OUString const & exceptionMessage)
+{
+ String sError;
+ m_bError = true;
+
+ switch (err)
+ {
+ case ERROR_DOWNLOAD:
+ sError = m_sErrorDownload;
+ break;
+ case ERROR_INSTALLATION:
+ sError = m_sErrorInstallation;
+ break;
+ case ERROR_LICENSE_DECLINED:
+ sError = m_sErrorLicenseDeclined;
+ break;
+
+ default:
+ OSL_ASSERT(0);
+ }
+
+ sError.SearchAndReplace(String(OUSTR("%NAME")), String(sExtension), 0);
+ //We want to have an empty line between the error messages. However,
+ //there shall be no empty line after the last entry.
+ if (m_bNoEntry)
+ m_bNoEntry = false;
+ else
+ m_mle_info.InsertText(OUSTR("\n"));
+ m_mle_info.InsertText(sError);
+ //Insert more information about the error
+ if (exceptionMessage.getLength())
+ m_mle_info.InsertText(m_sThisErrorOccurred + exceptionMessage + OUSTR("\n"));
+
+ m_mle_info.InsertText(m_sNoInstall);
+ m_mle_info.InsertText(OUSTR("\n"));
+}
+
+void UpdateInstallDialog::setError(OUString const & exceptionMessage)
+{
+ m_bError = true;
+ m_mle_info.InsertText(exceptionMessage + OUSTR("\n"));
+}
+
+IMPL_LINK(UpdateInstallDialog, cancelHandler, void *, EMPTYARG)
+{
+ m_thread->stop();
+ EndDialog(RET_CANCEL);
+ return 0;
+}
+
+//------------------------------------------------------------------------------------------------
+
+void UpdateInstallDialog::Thread::downloadExtensions()
+{
+ try
+ {
+ //create the download directory in the temp folder
+ OUString sTempDir;
+ if (::osl::FileBase::getTempDirURL(sTempDir) != ::osl::FileBase::E_None)
+ throw cssu::Exception(OUSTR("Could not get URL for the temp directory. No extensions will be installed."), 0);
+
+ //create a unique name for the directory
+ OUString tempEntry, destFolder;
+ if (::osl::File::createTempFile(&sTempDir, 0, &tempEntry ) != ::osl::File::E_None)
+ throw cssu::Exception(OUSTR("Could not create a temporary file in ") + sTempDir +
+ OUSTR(". No extensions will be installed"), 0 );
+
+ tempEntry = tempEntry.copy( tempEntry.lastIndexOf( '/' ) + 1 );
+
+ destFolder = dp_misc::makeURL( sTempDir, tempEntry );
+ destFolder += OUSTR("_");
+ m_sDownloadFolder = destFolder;
+ try
+ {
+ dp_misc::create_folder(0, destFolder, m_updateCmdEnv.get(), true );
+ } catch (cssu::Exception & e)
+ {
+ throw cssu::Exception(e.Message + OUSTR(" No extensions will be installed."), 0);
+ }
+
+
+ sal_uInt16 count = 0;
+ typedef std::vector<UpdateData>::iterator It;
+ for (It i = m_aVecUpdateData.begin(); i != m_aVecUpdateData.end(); i++)
+ {
+ UpdateData & curData = *i;
+
+ OSL_ASSERT(curData.aUpdateInfo.is());
+ //We assume that m_aVecUpdateData contains only information about extensions which
+ //can be downloaded directly.
+ OSL_ASSERT(curData.sWebsiteURL.getLength() == 0);
+
+ if (!curData.aUpdateInfo.is())
+ continue;
+ //update the name of the extension which is to be downloaded
+ {
+ ::vos::OGuard g(Application::GetSolarMutex());
+ if (m_stop) {
+ return;
+ }
+ m_dialog.m_ft_extension_name.SetText(curData.aInstalledPackage->getDisplayName());
+ sal_uInt16 prog = (sal::static_int_cast<sal_uInt16>(100) * ++count) /
+ sal::static_int_cast<sal_uInt16>(m_aVecUpdateData.size());
+ m_dialog.m_statusbar.SetValue(prog);
+ }
+ dp_misc::DescriptionInfoset info(m_xComponentContext, curData.aUpdateInfo);
+ //remember occurring exceptions in case we need to print out error information
+ ::std::vector< ::std::pair<OUString, cssu::Exception> > vecExceptions;
+ cssu::Sequence<OUString> seqDownloadURLs = info.getUpdateDownloadUrls();
+ OSL_ENSURE(seqDownloadURLs.getLength() > 0, "No download URL provided!");
+ for (sal_Int32 j = 0; j < seqDownloadURLs.getLength(); j++)
+ {
+ try
+ {
+ OSL_ENSURE(seqDownloadURLs[j].getLength() > 0, "Download URL is empty!");
+ download(seqDownloadURLs[j], curData);
+ if (curData.sLocalURL.getLength() > 0)
+ break;
+ }
+ catch ( cssu::Exception & e )
+ {
+ vecExceptions.push_back( ::std::make_pair(seqDownloadURLs[j], e));
+ //There can be several different errors, for example, the URL is wrong, webserver cannot be reached,
+ //name cannot be resolved. The UCB helper API does not specify different special exceptions for these
+ //cases. Therefore ignore and continue.
+ continue;
+ }
+ }
+ //update the progress and display download error
+ {
+ ::vos::OGuard g(Application::GetSolarMutex());
+ if (m_stop) {
+ return;
+ }
+ if (curData.sLocalURL.getLength() == 0)
+ {
+ //Construct a string of all messages contained in the exceptions plus the respective download URLs
+ ::rtl::OUStringBuffer buf(256);
+ typedef ::std::vector< ::std::pair<OUString, cssu::Exception > >::const_iterator CIT;
+ for (CIT j = vecExceptions.begin(); j != vecExceptions.end(); j++)
+ {
+ if (j != vecExceptions.begin())
+ buf.appendAscii("\n");
+ buf.append(OUSTR("Could not download "));
+ buf.append(j->first);
+ buf.appendAscii(". ");
+ buf.append(j->second.Message);
+ }
+ m_dialog.setError(UpdateInstallDialog::ERROR_DOWNLOAD, curData.aInstalledPackage->getDisplayName(),
+ buf.makeStringAndClear());
+ }
+ }
+
+ }
+ }
+ catch (cssu::Exception & e)
+ {
+ ::vos::OGuard g(Application::GetSolarMutex());
+ if (m_stop) {
+ return;
+ }
+ m_dialog.setError(e.Message);
+ }
+}
+void UpdateInstallDialog::Thread::installExtensions()
+{
+ //Update the fix text in the dialog to "Installing extensions..."
+ {
+ vos::OGuard g(Application::GetSolarMutex());
+ if (m_stop) {
+ return;
+ }
+ m_dialog.m_ft_action.SetText(m_dialog.m_sInstalling);
+ m_dialog.m_statusbar.SetValue(0);
+ }
+
+ sal_uInt16 count = 0;
+ typedef std::vector<UpdateData>::iterator It;
+ for (It i = m_aVecUpdateData.begin(); i != m_aVecUpdateData.end(); i++, count++)
+ {
+ //update the name of the extension which is to be installed
+ {
+ ::vos::OGuard g(Application::GetSolarMutex());
+ if (m_stop) {
+ return;
+ }
+ //we only show progress after an extension has been installed.
+ if (count > 0) {
+ m_dialog.m_statusbar.SetValue(
+ (sal::static_int_cast<sal_uInt16>(100) * count) /
+ sal::static_int_cast<sal_uInt16>(m_aVecUpdateData.size()));
+ }
+ m_dialog.m_ft_extension_name.SetText(i->aInstalledPackage->getDisplayName());
+ }
+// TimeValue v = {1, 0};
+// osl::Thread::wait(v);
+ bool bError = false;
+ bool bLicenseDeclined = false;
+ cssu::Reference<css::deployment::XPackage> xPackage;
+ UpdateData & curData = *i;
+ cssu::Exception exc;
+ try
+ {
+ if (curData.sLocalURL.getLength() == 0)
+ continue;
+ cssu::Reference< css::task::XAbortChannel > xAbortChannel(
+ curData.aPackageManager->createAbortChannel() );
+ {
+ vos::OGuard g(Application::GetSolarMutex());
+ if (m_stop) {
+ return;
+ }
+ m_abort = xAbortChannel;
+ }
+ xPackage = curData.aPackageManager->addPackage(
+ curData.sLocalURL, OUString(), xAbortChannel, m_updateCmdEnv.get());
+ }
+ catch (css::deployment::DeploymentException & de)
+ {
+ if (de.Cause.has<css::deployment::LicenseException>())
+ {
+ bLicenseDeclined = true;
+ }
+ else
+ {
+ exc = de.Cause.get<cssu::Exception>();
+ bError = true;
+ }
+ }
+ catch (cssu::Exception& e)
+ {
+ exc = e;
+ bError = true;
+ }
+
+ if (bLicenseDeclined)
+ {
+ ::vos::OGuard g(Application::GetSolarMutex());
+ if (m_stop) {
+ return;
+ }
+ m_dialog.setError(UpdateInstallDialog::ERROR_LICENSE_DECLINED,
+ curData.aInstalledPackage->getDisplayName(), OUString());
+ }
+ else if (!xPackage.is() || bError)
+ {
+ ::vos::OGuard g(Application::GetSolarMutex());
+ if (m_stop) {
+ return;
+ }
+ m_dialog.setError(UpdateInstallDialog::ERROR_INSTALLATION,
+ curData.aInstalledPackage->getDisplayName(), exc.Message);
+ }
+ }
+ {
+ vos::OGuard g(Application::GetSolarMutex());
+ if (m_stop) {
+ return;
+ }
+ m_dialog.m_statusbar.SetValue(100);
+ m_dialog.m_ft_extension_name.SetText(OUString());
+ m_dialog.m_ft_action.SetText(m_dialog.m_sFinished);
+ }
+}
+
+void UpdateInstallDialog::Thread::removeTempDownloads()
+{
+ if (m_sDownloadFolder.getLength())
+ {
+ dp_misc::erase_path(m_sDownloadFolder,
+ cssu::Reference<css::ucb::XCommandEnvironment>(),false /* no throw: ignore errors */ );
+ //remove also the temp file which we have used to create the unique name
+ OUString tempFile = m_sDownloadFolder.copy(0, m_sDownloadFolder.getLength() - 1);
+ dp_misc::erase_path(tempFile, cssu::Reference<css::ucb::XCommandEnvironment>(),false);
+ m_sDownloadFolder = OUString();
+ }
+}
+
+
+void UpdateInstallDialog::Thread::download(OUString const & sDownloadURL, UpdateData & aUpdateData)
+{
+ {
+ ::vos::OGuard g(Application::GetSolarMutex());
+ if (m_stop) {
+ return;
+ }
+ }
+
+ OSL_ASSERT(m_sDownloadFolder.getLength());
+ OUString destFolder, tempEntry;
+ if (::osl::File::createTempFile(
+ &m_sDownloadFolder,
+ 0, &tempEntry ) != ::osl::File::E_None)
+ {
+ //ToDo feedback in window that download of this component failed
+ throw cssu::Exception(OUSTR("Could not create temporary file in folder ") + destFolder + OUSTR("."), 0);
+ }
+ tempEntry = tempEntry.copy( tempEntry.lastIndexOf( '/' ) + 1 );
+
+ destFolder = dp_misc::makeURL( m_sDownloadFolder, tempEntry );
+ destFolder += OUSTR("_");
+
+ ::ucbhelper::Content destFolderContent;
+ dp_misc::create_folder( &destFolderContent, destFolder, m_updateCmdEnv.get() );
+
+ ::ucbhelper::Content sourceContent;
+ dp_misc::create_ucb_content( &sourceContent, sDownloadURL, m_updateCmdEnv.get() );
+
+ const OUString sTitle(sourceContent.getPropertyValue(
+ dp_misc::StrTitle::get() ).get<OUString>() );
+
+ if (destFolderContent.transferContent(
+ sourceContent, ::ucbhelper::InsertOperation_COPY,
+ sTitle, css::ucb::NameClash::OVERWRITE ))
+ {
+ //the user may have cancelled the dialog because downloading took to long
+ {
+ ::vos::OGuard g(Application::GetSolarMutex());
+ if (m_stop) {
+ return;
+ }
+ //all errors should be handeld by the command environment.
+ aUpdateData.sLocalURL = destFolder + OUString( RTL_CONSTASCII_USTRINGPARAM( "/" ) ) + sTitle;
+ }
+ }
+}
+
+
+// -------------------------------------------------------------------------------------------------------
+
+UpdateCommandEnv::UpdateCommandEnv( cssu::Reference< cssu::XComponentContext > const & xCtx,
+ UpdateInstallDialog & updateDialog,
+ ::rtl::Reference<UpdateInstallDialog::Thread>const & thread)
+ : m_updateDialog( updateDialog ),
+ m_installThread(thread),
+ m_xContext(xCtx)
+{
+}
+
+UpdateCommandEnv::~UpdateCommandEnv()
+{
+}
+
+
+// XCommandEnvironment
+//______________________________________________________________________________
+cssu::Reference<css::task::XInteractionHandler> UpdateCommandEnv::getInteractionHandler()
+throw (cssu::RuntimeException)
+{
+ return this;
+}
+
+//______________________________________________________________________________
+cssu::Reference<css::ucb::XProgressHandler> UpdateCommandEnv::getProgressHandler()
+throw (cssu::RuntimeException)
+{
+ return this;
+}
+
+// XInteractionHandler
+void UpdateCommandEnv::handle(
+ cssu::Reference< css::task::XInteractionRequest> const & xRequest )
+ throw (cssu::RuntimeException)
+{
+ cssu::Any request( xRequest->getRequest() );
+ OSL_ASSERT( request.getValueTypeClass() == cssu::TypeClass_EXCEPTION );
+ dp_misc::TRACE(OUSTR("[dp_gui_cmdenv.cxx] incoming request:\n")
+ + ::comphelper::anyToString(request) + OUSTR("\n\n"));
+
+ css::deployment::VersionException verExc;
+ bool approve = false;
+ bool abort = false;
+
+ if (request >>= verExc)
+ { //We must catch the version exception during the update,
+ //because otherwise the user would be confronted with the dialogs, asking
+ //them if they want to replace an already installed version of the same extension.
+ //During an update we assume that we always want to replace the old version with the
+ //new version.
+ approve = true;
+ }
+
+ if (approve == false && abort == false)
+ {
+ //forward to interaction handler for main dialog.
+ handleInteractionRequest( m_xContext, xRequest );
+ }
+ else
+ {
+ // select:
+ cssu::Sequence< cssu::Reference< css::task::XInteractionContinuation > > conts(
+ xRequest->getContinuations() );
+ cssu::Reference< css::task::XInteractionContinuation > const * pConts =
+ conts.getConstArray();
+ sal_Int32 len = conts.getLength();
+ for ( sal_Int32 pos = 0; pos < len; ++pos )
+ {
+ if (approve) {
+ cssu::Reference< css::task::XInteractionApprove > xInteractionApprove(
+ pConts[ pos ], cssu::UNO_QUERY );
+ if (xInteractionApprove.is()) {
+ xInteractionApprove->select();
+ // don't query again for ongoing continuations:
+ approve = false;
+ }
+ }
+ else if (abort) {
+ cssu::Reference< css::task::XInteractionAbort > xInteractionAbort(
+ pConts[ pos ], cssu::UNO_QUERY );
+ if (xInteractionAbort.is()) {
+ xInteractionAbort->select();
+ // don't query again for ongoing continuations:
+ abort = false;
+ }
+ }
+ }
+ }
+}
+
+// XProgressHandler
+void UpdateCommandEnv::push( cssu::Any const & /*Status*/ )
+throw (cssu::RuntimeException)
+{
+}
+
+
+void UpdateCommandEnv::update( cssu::Any const & /*Status */)
+throw (cssu::RuntimeException)
+{
+}
+
+void UpdateCommandEnv::pop() throw (cssu::RuntimeException)
+{
+}
+
+
+} //end namespace dp_gui
diff --git a/desktop/source/deployment/gui/dp_gui_updateinstalldialog.hxx b/desktop/source/deployment/gui/dp_gui_updateinstalldialog.hxx
new file mode 100644
index 000000000000..9c755354fbf6
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_updateinstalldialog.hxx
@@ -0,0 +1,141 @@
+/*************************************************************************
+ *
+ * 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: dp_gui_updateinstalldialog.hxx,v $
+ * $Revision: 1.4.126.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 INCLUDED_DESKTOP_SOURCE_DEPLOYMENT_GUI_DP_GUI_INSTALLDIALOG_HXX
+#define INCLUDED_DESKTOP_SOURCE_DEPLOYMENT_GUI_DP_GUI_INSTALLDIALOG_HXX
+
+#include "sal/config.h"
+#ifndef _SV_BUTTON_HXX
+#include "vcl/button.hxx"
+#endif
+#include "vcl/fixed.hxx"
+#include "vcl/dialog.hxx"
+#include "svtools/prgsbar.hxx"
+#include "rtl/ref.hxx"
+#include <vector>
+
+#include "dp_gui_autoscrolledit.hxx"
+/// @HTML
+
+namespace com { namespace sun { namespace star { namespace uno {
+ class XComponentContext;
+}}}}
+namespace com { namespace sun { namespace star { namespace xml { namespace dom {
+ class XNode;
+}}}}}
+namespace com { namespace sun { namespace star { namespace xml { namespace xpath {
+ class XXPathAPI;
+}}}}}
+
+class Window;
+namespace osl {
+ class Condition;
+}
+
+namespace dp_gui {
+
+ struct UpdateData;
+ class UpdateCommandEnv;
+
+
+/**
+ The modal &ldquo;Download and Installation&rdquo; dialog.
+*/
+class UpdateInstallDialog: public ModalDialog {
+public:
+ /**
+ Create an instance.
+
+ @param parent
+ the parent window, may be null
+ */
+ UpdateInstallDialog(Window * parent, std::vector<UpdateData> & aVecUpdateData,
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > const & xCtx);
+
+ ~UpdateInstallDialog();
+
+ BOOL Close();
+ virtual short Execute();
+
+private:
+ UpdateInstallDialog(UpdateInstallDialog &); // not defined
+ void operator =(UpdateInstallDialog &); // not defined
+
+ class Thread;
+ friend class Thread;
+ friend class UpdateCommandEnv;
+
+ DECL_LINK(cancelHandler, void *);
+
+ //signals in the dialog that we have finished.
+ void updateDone();
+ //Writes a particular error into the info listbox.
+ enum INSTALL_ERROR
+ {
+ ERROR_DOWNLOAD,
+ ERROR_INSTALLATION,
+ ERROR_LICENSE_DECLINED
+ };
+ void setError(INSTALL_ERROR err, ::rtl::OUString const & sExtension, ::rtl::OUString const & exceptionMessage);
+ void setError(::rtl::OUString const & exceptionMessage);
+
+ rtl::Reference< Thread > m_thread;
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > m_xComponentContext;
+ //Signals that an error occurred during download and installation
+ bool m_bError;
+ bool m_bNoEntry;
+ bool m_bActivated;
+
+ ::rtl::OUString m_sInstalling;
+ ::rtl::OUString m_sFinished;
+ ::rtl::OUString m_sNoErrors;
+ ::rtl::OUString m_sErrorDownload;
+ ::rtl::OUString m_sErrorInstallation;
+ ::rtl::OUString m_sErrorLicenseDeclined;
+ ::rtl::OUString m_sNoInstall;
+ ::rtl::OUString m_sThisErrorOccurred;
+
+ FixedText m_ft_action;
+ ProgressBar m_statusbar;
+ FixedText m_ft_extension_name;
+ FixedText m_ft_results;
+ AutoScrollEdit m_mle_info;
+ FixedLine m_line;
+ HelpButton m_help;
+ OKButton m_ok;
+ CancelButton m_cancel;
+};
+
+
+
+
+}
+
+#endif
diff --git a/desktop/source/deployment/gui/dp_gui_updateinstalldialog.src b/desktop/source/deployment/gui/dp_gui_updateinstalldialog.src
new file mode 100644
index 000000000000..873eaabbf23f
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_updateinstalldialog.src
@@ -0,0 +1,206 @@
+/*************************************************************************
+ *
+ * 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: dp_gui_updateinstalldialog.src,v $
+ * $Revision: 1.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.
+ *
+ ************************************************************************/
+
+#include "svtools/controldims.hrc"
+
+#include "dp_gui.hrc"
+
+
+#define LOCAL_WIDTH (60 * RSC_BS_CHARWIDTH)
+#define LOCAL_LIST_HEIGHT (7 * RSC_BS_CHARHEIGHT)
+#define LOCAL_BUTTON_WIDTH 80
+
+ModalDialog RID_DLG_UPDATEINSTALL {
+ HelpId = HID_DEPLOYMENT_GUI_UPDATEINSTALL;
+ Size = MAP_APPFONT(
+ (RSC_SP_DLG_INNERBORDER_LEFT + LOCAL_WIDTH +
+ RSC_SP_DLG_INNERBORDER_RIGHT),
+ (RSC_SP_DLG_INNERBORDER_TOP + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + RSC_CD_CHECKBOX_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_Y + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_FLGR_SPACE_Y + LOCAL_LIST_HEIGHT +
+ RSC_SP_FLGR_SPACE_Y + RSC_CD_FIXEDLINE_HEIGHT +
+ RSC_SP_FLGR_SPACE_Y + RSC_CD_PUSHBUTTON_HEIGHT +
+ RSC_SP_DLG_INNERBORDER_BOTTOM));
+ Text[en-US] = "Download and Installation";
+ Moveable = TRUE;
+ Closeable = TRUE;
+ FixedText RID_DLG_UPDATE_INSTALL_DOWNLOADING {
+ Pos = MAP_APPFONT(
+ RSC_SP_DLG_INNERBORDER_LEFT, RSC_SP_DLG_INNERBORDER_TOP);
+ Size = MAP_APPFONT(LOCAL_WIDTH, RSC_CD_FIXEDTEXT_HEIGHT);
+ Text[en-US] = "Downloading extensions...";
+ NoLabel = TRUE;
+ };
+
+ Window RID_DLG_UPDATE_INSTALL_STATUSBAR {
+ Pos = MAP_APPFONT(
+ RSC_SP_DLG_INNERBORDER_LEFT,
+ (RSC_SP_DLG_INNERBORDER_TOP + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y));
+
+ Size = MAP_APPFONT(LOCAL_WIDTH, RSC_CD_CHECKBOX_HEIGHT);
+ Border = TRUE;
+ };
+
+ FixedText RID_DLG_UPDATE_INSTALL_EXTENSION_NAME {
+ Pos = MAP_APPFONT(
+ RSC_SP_DLG_INNERBORDER_LEFT,
+ RSC_SP_DLG_INNERBORDER_TOP + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + RSC_CD_CHECKBOX_HEIGHT + RSC_SP_CTRL_DESC_Y);
+ Size = MAP_APPFONT(LOCAL_WIDTH, RSC_CD_FIXEDTEXT_HEIGHT);
+ Text[en-US] = "";
+ NoLabel = TRUE;
+ };
+
+ FixedText RID_DLG_UPDATE_INSTALL_RESULTS {
+ Pos = MAP_APPFONT(
+ RSC_SP_DLG_INNERBORDER_LEFT,
+ RSC_SP_DLG_INNERBORDER_TOP + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + RSC_CD_CHECKBOX_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_Y);
+ Size = MAP_APPFONT(LOCAL_WIDTH, RSC_CD_FIXEDTEXT_HEIGHT);
+ Text[en-US] = "Result";
+ };
+
+ MultiLineEdit RID_DLG_UPDATE_INSTALL_INFO {
+ Pos = MAP_APPFONT(
+ RSC_SP_DLG_INNERBORDER_LEFT,
+ RSC_SP_DLG_INNERBORDER_TOP + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + RSC_CD_CHECKBOX_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_Y + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y);
+
+ Size = MAP_APPFONT(LOCAL_WIDTH, LOCAL_LIST_HEIGHT);
+ Border = TRUE;
+ ReadOnly = TRUE;
+ VScroll = TRUE;
+ TabStop = FALSE;
+ };
+
+ FixedLine RID_DLG_UPDATE_INSTALL_LINE {
+ Pos = MAP_APPFONT(
+ RSC_SP_DLG_INNERBORDER_LEFT,
+ RSC_SP_DLG_INNERBORDER_TOP + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + RSC_CD_CHECKBOX_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_Y + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + LOCAL_LIST_HEIGHT +
+ RSC_SP_FLGR_SPACE_Y);
+
+ Size = MAP_APPFONT(LOCAL_WIDTH, RSC_CD_FIXEDLINE_HEIGHT);
+ };
+
+ OKButton RID_DLG_UPDATE_INSTALL_OK {
+ Disable = TRUE;
+ Pos = MAP_APPFONT(
+ RSC_SP_DLG_INNERBORDER_LEFT + LOCAL_WIDTH - LOCAL_BUTTON_WIDTH -
+ RSC_SP_CTRL_GROUP_X - RSC_CD_PUSHBUTTON_WIDTH,
+ RSC_SP_DLG_INNERBORDER_TOP + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + RSC_CD_CHECKBOX_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_Y + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + LOCAL_LIST_HEIGHT +
+ RSC_SP_FLGR_SPACE_Y + RSC_CD_FIXEDLINE_HEIGHT +
+ RSC_SP_FLGR_SPACE_Y);
+
+
+ Size = MAP_APPFONT(RSC_CD_PUSHBUTTON_WIDTH, RSC_CD_PUSHBUTTON_HEIGHT);
+ Text[en-US] = "OK";
+ };
+
+ CancelButton RID_DLG_UPDATE_INSTALL_ABORT {
+ Pos = MAP_APPFONT(
+ RSC_SP_DLG_INNERBORDER_LEFT + LOCAL_WIDTH - LOCAL_BUTTON_WIDTH,
+ RSC_SP_DLG_INNERBORDER_TOP + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + RSC_CD_CHECKBOX_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_Y + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + LOCAL_LIST_HEIGHT +
+ RSC_SP_FLGR_SPACE_Y + RSC_CD_FIXEDLINE_HEIGHT +
+ RSC_SP_FLGR_SPACE_Y);
+
+ Size = MAP_APPFONT(LOCAL_BUTTON_WIDTH, RSC_CD_PUSHBUTTON_HEIGHT);
+ Text[en-US] = "Cancel Update";
+ DefButton = TRUE;
+ };
+
+ HelpButton RID_DLG_UPDATE_INSTALL_HELP {
+ Pos = MAP_APPFONT(
+ RSC_SP_DLG_INNERBORDER_LEFT,
+ RSC_SP_DLG_INNERBORDER_TOP + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + RSC_CD_CHECKBOX_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_Y + RSC_CD_FIXEDTEXT_HEIGHT +
+ RSC_SP_CTRL_DESC_Y + LOCAL_LIST_HEIGHT +
+ RSC_SP_FLGR_SPACE_Y + RSC_CD_FIXEDLINE_HEIGHT +
+ RSC_SP_FLGR_SPACE_Y);
+ Size = MAP_APPFONT(RSC_CD_PUSHBUTTON_WIDTH, RSC_CD_PUSHBUTTON_HEIGHT);
+ };
+
+
+ String RID_DLG_UPDATE_INSTALL_INSTALLING {
+ Text[en-US] = "Installing extensions...";
+ };
+
+ String RID_DLG_UPDATE_INSTALL_FINISHED {
+ Text[en-US] = "Installation finished";
+ };
+
+ String RID_DLG_UPDATE_INSTALL_NO_ERRORS {
+ Text[en-US] = "No errors.";
+ };
+
+ String RID_DLG_UPDATE_INSTALL_ERROR_DOWNLOAD {
+ Text[en-US] = "Error while downloading extension %NAME. ";
+ };
+
+ String RID_DLG_UPDATE_INSTALL_THIS_ERROR_OCCURRED {
+ Text[en-US] = "The error message is: ";
+ };
+
+
+ String RID_DLG_UPDATE_INSTALL_ERROR_INSTALLATION {
+ Text[en-US] = "Error while installing extension %NAME. ";
+ };
+
+ String RID_DLG_UPDATE_INSTALL_ERROR_LIC_DECLINED {
+ Text[en-US] = "The license agreement for extension %NAME was refused. ";
+ };
+
+ String RID_DLG_UPDATE_INSTALL_EXTENSION_NOINSTALL{
+ Text[en-US] = "The extension will not be installed.";
+ };
+
+};
+
diff --git a/desktop/source/deployment/gui/dp_gui_versionboxes.src b/desktop/source/deployment/gui/dp_gui_versionboxes.src
new file mode 100644
index 000000000000..1e154c017328
--- /dev/null
+++ b/desktop/source/deployment/gui/dp_gui_versionboxes.src
@@ -0,0 +1,79 @@
+/*************************************************************************
+ *
+ * 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: dp_gui_versionboxes.src,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "dp_gui.hrc"
+
+WarningBox RID_WARNINGBOX_VERSION_LESS {
+ Buttons = WB_OK_CANCEL;
+ DefButton = WB_DEF_CANCEL;
+ Message[en-US] = "You are about to install version $NEW of the extension \'$NAME\'.\n"
+ "The newer version $DEPLOYED is already installed.\n"
+ "Click \'OK\' to replace the installed extension.\n"
+ "Click \'Cancel\' to stop the installation.";
+};
+
+String RID_STR_WARNINGBOX_VERSION_LESS_DIFFERENT_NAMES {
+ Text [en-US] = "You are about to install version $NEW of the extension \'$NAME\'.\n"
+ "The newer version $DEPLOYED, named \'$OLDNAME\', is already installed.\n"
+ "Click \'OK\' to replace the installed extension.\n"
+ "Click \'Cancel\' to stop the installation.";
+};
+
+WarningBox RID_WARNINGBOX_VERSION_EQUAL {
+ Buttons = WB_OK_CANCEL;
+ DefButton = WB_DEF_CANCEL;
+ Message[en-US] = "You are about to install version $NEW of the extension \'$NAME\'.\n"
+ "That version is already installed.\n"
+ "Click \'OK\' to replace the installed extension.\n"
+ "Click \'Cancel\' to stop the installation.";
+};
+
+String RID_STR_WARNINGBOX_VERSION_EQUAL_DIFFERENT_NAMES {
+ Text [en-US] = "You are about to install version $NEW of the extension \'$NAME\'.\n"
+ "That version, named \'$OLDNAME\', is already installed.\n"
+ "Click \'OK\' to replace the installed extension.\n"
+ "Click \'Cancel\' to stop the installation.";
+};
+
+WarningBox RID_WARNINGBOX_VERSION_GREATER {
+ Buttons = WB_OK_CANCEL;
+ DefButton = WB_DEF_OK;
+ Message[en-US] = "You are about to install version $NEW of the extension \'$NAME\'.\n"
+ "The older version $DEPLOYED is already installed.\n"
+ "Click \'OK\' to replace the installed extension.\n"
+ "Click \'Cancel\' to stop the installation.";
+};
+
+String RID_STR_WARNINGBOX_VERSION_GREATER_DIFFERENT_NAMES {
+ TEXT [en-US] = "You are about to install version $NEW of the extension \'$NAME\'.\n"
+ "The older version $DEPLOYED, named \'$OLDNAME\', is already installed.\n"
+ "Click \'OK\' to replace the installed extension.\n"
+ "Click \'Cancel\' to stop the installation.";
+}; \ No newline at end of file
diff --git a/desktop/source/deployment/gui/license_dialog.cxx b/desktop/source/deployment/gui/license_dialog.cxx
new file mode 100644
index 000000000000..bbc6a983c1fd
--- /dev/null
+++ b/desktop/source/deployment/gui/license_dialog.cxx
@@ -0,0 +1,328 @@
+/*************************************************************************
+ *
+ * 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: license_dialog.cxx,v $
+ * $Revision: 1.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_desktop.hxx"
+
+#include "cppuhelper/implbase2.hxx"
+#include "cppuhelper/implementationentry.hxx"
+#include "unotools/configmgr.hxx"
+#include "comphelper/servicedecl.hxx"
+#include "comphelper/unwrapargs.hxx"
+#include "i18npool/mslangid.hxx"
+#include "vcl/svapp.hxx"
+#include "vcl/msgbox.hxx"
+#include "toolkit/helper/vclunohelper.hxx"
+#include "com/sun/star/lang/XServiceInfo.hpp"
+#include "com/sun/star/task/XJobExecutor.hpp"
+#include "svtools/svmedit.hxx"
+#include "svtools/lstner.hxx"
+#include "svtools/xtextedt.hxx"
+#include <vcl/scrbar.hxx>
+#include "vcl/threadex.hxx"
+
+
+
+#include "boost/bind.hpp"
+#include "dp_gui_shared.hxx"
+#include "license_dialog.hxx"
+#include "dp_gui.hrc"
+
+using namespace ::dp_misc;
+namespace cssu = ::com::sun::star::uno;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using ::rtl::OUString;
+
+namespace dp_gui {
+
+class LicenseView : public MultiLineEdit, public SfxListener
+{
+ BOOL mbEndReached;
+ Link maEndReachedHdl;
+ Link maScrolledHdl;
+
+public:
+ LicenseView( Window* pParent, const ResId& rResId );
+ ~LicenseView();
+
+ void ScrollDown( ScrollType eScroll );
+
+ BOOL IsEndReached() const;
+ BOOL EndReached() const { return mbEndReached; }
+ void SetEndReached( BOOL bEnd ) { mbEndReached = bEnd; }
+
+ void SetEndReachedHdl( const Link& rHdl ) { maEndReachedHdl = rHdl; }
+ const Link& GetAutocompleteHdl() const { return maEndReachedHdl; }
+
+ void SetScrolledHdl( const Link& rHdl ) { maScrolledHdl = rHdl; }
+ const Link& GetScrolledHdl() const { return maScrolledHdl; }
+
+ virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
+
+protected:
+ using MultiLineEdit::Notify;
+};
+
+struct LicenseDialogImpl : public ModalDialog
+{
+ cssu::Reference<cssu::XComponentContext> m_xComponentContext;
+ FixedText m_ftHead;
+ FixedText m_ftBody1;
+ FixedText m_ftBody1Txt;
+ FixedText m_ftBody2;
+ FixedText m_ftBody2Txt;
+ FixedImage m_fiArrow1;
+ FixedImage m_fiArrow2;
+ LicenseView m_mlLicense;
+ PushButton m_pbDown;
+ FixedLine m_flBottom;
+
+ OKButton m_acceptButton;
+ CancelButton m_declineButton;
+
+ DECL_LINK(PageDownHdl, PushButton*);
+ DECL_LINK(ScrolledHdl, LicenseView*);
+ DECL_LINK(EndReachedHdl, LicenseView*);
+
+ bool m_bLicenseRead;
+
+ virtual ~LicenseDialogImpl();
+
+ LicenseDialogImpl(
+ Window * pParent,
+ css::uno::Reference< css::uno::XComponentContext > const & xContext,
+ const ::rtl::OUString & sLicenseText);
+
+ virtual void Activate();
+
+};
+
+LicenseView::LicenseView( Window* pParent, const ResId& rResId )
+ : MultiLineEdit( pParent, rResId )
+{
+ SetLeftMargin( 5 );
+ mbEndReached = IsEndReached();
+ StartListening( *GetTextEngine() );
+}
+
+LicenseView::~LicenseView()
+{
+ maEndReachedHdl = Link();
+ maScrolledHdl = Link();
+ EndListeningAll();
+}
+
+void LicenseView::ScrollDown( ScrollType eScroll )
+{
+ ScrollBar* pScroll = GetVScrollBar();
+ if ( pScroll )
+ pScroll->DoScrollAction( eScroll );
+}
+
+BOOL LicenseView::IsEndReached() const
+{
+ BOOL bEndReached;
+
+ ExtTextView* pView = GetTextView();
+ ExtTextEngine* pEdit = GetTextEngine();
+ ULONG nHeight = pEdit->GetTextHeight();
+ Size aOutSize = pView->GetWindow()->GetOutputSizePixel();
+ Point aBottom( 0, aOutSize.Height() );
+
+ if ( (ULONG) pView->GetDocPos( aBottom ).Y() >= nHeight - 1 )
+ bEndReached = TRUE;
+ else
+ bEndReached = FALSE;
+
+ return bEndReached;
+}
+
+void LicenseView::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ if ( rHint.IsA( TYPE(TextHint) ) )
+ {
+ BOOL bLastVal = EndReached();
+ ULONG nId = ((const TextHint&)rHint).GetId();
+
+ if ( nId == TEXT_HINT_PARAINSERTED )
+ {
+ if ( bLastVal )
+ mbEndReached = IsEndReached();
+ }
+ else if ( nId == TEXT_HINT_VIEWSCROLLED )
+ {
+ if ( ! mbEndReached )
+ mbEndReached = IsEndReached();
+ maScrolledHdl.Call( this );
+ }
+
+ if ( EndReached() && !bLastVal )
+ {
+ maEndReachedHdl.Call( this );
+ }
+ }
+}
+
+//==============================================================================================================
+
+LicenseDialogImpl::LicenseDialogImpl(
+ Window * pParent,
+ cssu::Reference< cssu::XComponentContext > const & xContext,
+ const ::rtl::OUString & sLicenseText):
+ ModalDialog(pParent, DpGuiResId(RID_DLG_LICENSE))
+ ,m_xComponentContext(xContext)
+ ,m_ftHead(this, DpGuiResId(FT_LICENSE_HEADER))
+ ,m_ftBody1(this, DpGuiResId(FT_LICENSE_BODY_1))
+ ,m_ftBody1Txt(this, DpGuiResId(FT_LICENSE_BODY_1_TXT))
+ ,m_ftBody2(this, DpGuiResId(FT_LICENSE_BODY_2))
+ ,m_ftBody2Txt(this, DpGuiResId(FT_LICENSE_BODY_2_TXT))
+ ,m_fiArrow1(this, DpGuiResId(FI_LICENSE_ARROW1))
+ ,m_fiArrow2(this, DpGuiResId(FI_LICENSE_ARROW2))
+ ,m_mlLicense(this, DpGuiResId(ML_LICENSE))
+ ,m_pbDown(this, DpGuiResId(PB_LICENSE_DOWN))
+ ,m_flBottom(this, DpGuiResId(FL_LICENSE))
+ ,m_acceptButton(this, DpGuiResId(BTN_LICENSE_ACCEPT))
+ ,m_declineButton(this, DpGuiResId(BTN_LICENSE_DECLINE))
+ ,m_bLicenseRead(false)
+
+{
+
+ if (GetBackground().GetColor().IsDark())
+ {
+ // high contrast mode needs other images
+ m_fiArrow1.SetImage(Image(DpGuiResId(IMG_LICENCE_ARROW_HC)));
+ m_fiArrow2.SetImage(Image(DpGuiResId(IMG_LICENCE_ARROW_HC)));
+ }
+
+ FreeResource();
+
+ m_acceptButton.SetUniqueId(UID_BTN_LICENSE_ACCEPT);
+ m_fiArrow1.Show(true);
+ m_fiArrow2.Show(false);
+ m_mlLicense.SetText(sLicenseText);
+
+ m_mlLicense.SetEndReachedHdl( LINK(this, LicenseDialogImpl, EndReachedHdl) );
+ m_mlLicense.SetScrolledHdl( LINK(this, LicenseDialogImpl, ScrolledHdl) );
+ m_pbDown.SetClickHdl( LINK(this, LicenseDialogImpl, PageDownHdl) );
+
+ // We want a automatic repeating page down button
+ WinBits aStyle = m_pbDown.GetStyle();
+ aStyle |= WB_REPEAT;
+ m_pbDown.SetStyle( aStyle );
+}
+
+LicenseDialogImpl::~LicenseDialogImpl()
+{
+}
+
+void LicenseDialogImpl::Activate()
+{
+ if (!m_bLicenseRead)
+ {
+ //Only enable the scroll down button if the license text does not fit into the window
+ if (m_mlLicense.IsEndReached())
+ {
+ m_pbDown.Disable();
+ m_acceptButton.Enable();
+ m_acceptButton.GrabFocus();
+ }
+ else
+ {
+ m_pbDown.Enable();
+ m_pbDown.GrabFocus();
+ m_acceptButton.Disable();
+ }
+ }
+}
+
+IMPL_LINK( LicenseDialogImpl, ScrolledHdl, LicenseView *, EMPTYARG )
+{
+
+ if (m_mlLicense.IsEndReached())
+ m_pbDown.Disable();
+ else
+ m_pbDown.Enable();
+
+ return 0;
+}
+
+IMPL_LINK( LicenseDialogImpl, PageDownHdl, PushButton *, EMPTYARG )
+{
+ m_mlLicense.ScrollDown( SCROLL_PAGEDOWN );
+ return 0;
+}
+
+IMPL_LINK( LicenseDialogImpl, EndReachedHdl, LicenseView *, EMPTYARG )
+{
+ m_acceptButton.Enable();
+ m_acceptButton.GrabFocus();
+ m_fiArrow1.Show(false);
+ m_fiArrow2.Show(true);
+ m_bLicenseRead = true;
+ return 0;
+}
+
+//=================================================================================
+
+
+
+
+LicenseDialog::LicenseDialog( Sequence<Any> const& args,
+ Reference<XComponentContext> const& xComponentContext)
+ : m_xComponentContext(xComponentContext)
+{
+ comphelper::unwrapArgs( args, m_parent, m_sLicenseText );
+}
+
+// XExecutableDialog
+//______________________________________________________________________________
+void LicenseDialog::setTitle( OUString const & ) throw (RuntimeException)
+{
+
+}
+
+//______________________________________________________________________________
+sal_Int16 LicenseDialog::execute() throw (RuntimeException)
+{
+ return vcl::solarthread::syncExecute(
+ boost::bind( &LicenseDialog::solar_execute, this));
+}
+
+sal_Int16 LicenseDialog::solar_execute()
+{
+ std::auto_ptr<LicenseDialogImpl> dlg(new LicenseDialogImpl(
+ VCLUnoHelper::GetWindow(m_parent), m_xComponentContext, m_sLicenseText));
+
+ return dlg->Execute();
+}
+
+} // namespace dp_gui
+
diff --git a/desktop/source/deployment/gui/license_dialog.hxx b/desktop/source/deployment/gui/license_dialog.hxx
new file mode 100644
index 000000000000..76bba106917f
--- /dev/null
+++ b/desktop/source/deployment/gui/license_dialog.hxx
@@ -0,0 +1,73 @@
+/*************************************************************************
+ *
+ * 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: license_dialog.hxx,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef INCLUDED_DESKTOP_SOURCE_DEPLOYMENT_GUI_LICENSE_DIALOG_HXX
+#define INCLUDED_DESKTOP_SOURCE_DEPLOYMENT_GUI_LICENSE_DIALOG_HXX
+
+#include "dp_gui.h"
+#include "cppuhelper/implbase1.hxx"
+#include "com/sun/star/lang/XServiceInfo.hpp"
+#include "com/sun/star/task/XJobExecutor.hpp"
+#include "com/sun/star/ui/dialogs/XExecutableDialog.hpp"
+
+#include "boost/bind.hpp"
+
+using namespace ::dp_misc;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using ::rtl::OUString;
+
+namespace dp_gui {
+
+class LicenseDialog
+ : public ::cppu::WeakImplHelper1<ui::dialogs::XExecutableDialog>
+// task::XJobExecutor>
+{
+ Reference<XComponentContext> const m_xComponentContext;
+ Reference<awt::XWindow> /* const */ m_parent;
+ OUString /* const */ m_sLicenseText;
+ OUString m_initialTitle;
+
+ sal_Int16 solar_execute();
+
+public:
+ LicenseDialog( Sequence<Any> const & args,
+ Reference<XComponentContext> const & xComponentContext );
+
+ // XExecutableDialog
+ virtual void SAL_CALL setTitle( OUString const & title )
+ throw (RuntimeException);
+ virtual sal_Int16 SAL_CALL execute() throw (RuntimeException);
+
+ //// XJobExecutor
+ //virtual void SAL_CALL trigger( OUString const & event )
+ // throw (RuntimeException);
+};
+}
+#endif
diff --git a/desktop/source/deployment/gui/makefile.mk b/desktop/source/deployment/gui/makefile.mk
new file mode 100644
index 000000000000..4d563ae1591a
--- /dev/null
+++ b/desktop/source/deployment/gui/makefile.mk
@@ -0,0 +1,113 @@
+#*************************************************************************
+#
+# 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.20.30.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.
+#
+#*************************************************************************
+
+PRJ = ..$/..$/..
+
+PRJNAME = desktop
+TARGET = deploymentgui
+ENABLE_EXCEPTIONS = TRUE
+#USE_DEFFILE = TRUE
+NO_BSYMBOLIC = TRUE
+USE_PCH :=
+ENABLE_PCH :=
+PRJINC:=..$/..
+
+.IF "$(GUI)"=="OS2"
+TARGET = deplgui
+.ENDIF
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/source$/deployment$/inc$/dp_misc.mk
+DLLPRE =
+
+SLOFILES = \
+ $(SLO)$/dp_gui_service.obj \
+ $(SLO)$/dp_gui_extlistbox.obj \
+ $(SLO)$/dp_gui_dialog2.obj \
+ $(SLO)$/dp_gui_theextmgr.obj \
+ $(SLO)$/license_dialog.obj \
+ $(SLO)$/dp_gui_dependencydialog.obj \
+ $(SLO)$/dp_gui_thread.obj \
+ $(SLO)$/dp_gui_updatability.obj \
+ $(SLO)$/dp_gui_updatedialog.obj \
+ $(SLO)$/dp_gui_updateinstalldialog.obj \
+ $(SLO)$/dp_gui_autoscrolledit.obj \
+ $(SLO)$/dp_gui_system.obj \
+ $(SLO)$/dp_gui_extensioncmdqueue.obj \
+ $(SLO)$/descedit.obj
+
+SHL1TARGET = $(TARGET)$(DLLPOSTFIX).uno
+SHL1VERSIONMAP = ..$/deployment.map
+
+SHL1STDLIBS = \
+ $(SALLIB) \
+ $(SALHELPERLIB) \
+ $(CPPULIB) \
+ $(CPPUHELPERLIB) \
+ $(UCBHELPERLIB) \
+ $(COMPHELPERLIB) \
+ $(UNOTOOLSLIB) \
+ $(TOOLSLIB) \
+ $(I18NISOLANGLIB) \
+ $(TKLIB) \
+ $(VCLLIB) \
+ $(SVTOOLLIB) \
+ $(SVLLIB) \
+ $(SVXLIB) \
+ $(SFXLIB) \
+ $(DEPLOYMENTMISCLIB) \
+ $(OLE32LIB)
+
+SHL1DEPN =
+SHL1IMPLIB = i$(TARGET)
+SHL1LIBS = $(SLB)$/$(TARGET).lib
+SHL1DEF = $(MISC)$/$(SHL1TARGET).def
+
+DEF1NAME = $(SHL1TARGET)
+#DEFLIB1NAME = $(TARGET)
+#DEF1DEPN =
+
+SRS1NAME = $(TARGET)
+SRC1FILES = \
+ dp_gui_dialog.src \
+ dp_gui_dialog2.src \
+ dp_gui_backend.src \
+ dp_gui_dependencydialog.src \
+ dp_gui_updatedialog.src \
+ dp_gui_versionboxes.src \
+ dp_gui_updateinstalldialog.src
+
+RESLIB1NAME = $(TARGET)
+RESLIB1SRSFILES = $(SRS)$/$(TARGET).srs
+RESLIB1IMAGES= $(PRJ)$/res
+
+.INCLUDE : target.mk
+
diff --git a/desktop/source/deployment/inc/db.hxx b/desktop/source/deployment/inc/db.hxx
new file mode 100644
index 000000000000..42c0e734cf0f
--- /dev/null
+++ b/desktop/source/deployment/inc/db.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: db.hxx,v $
+ * $Revision: 1.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 BERKELEYDBPROXY_DB_HXX_
+#define BERKELEYDBPROXY_DB_HXX_
+
+#ifdef SYSTEM_DB
+#include <db.h>
+#else
+#include <berkeleydb/db.h>
+#endif
+
+#include <rtl/string.hxx>
+#include "dp_misc_api.hxx"
+
+extern "C" {
+ typedef void *(*db_malloc_fcn_type)(size_t);
+ typedef void *(*db_realloc_fcn_type)(void *, size_t);
+ typedef void (*db_free_fcn_type)(void *);
+}
+
+
+namespace berkeleydbproxy {
+
+ class DbEnv;
+ class Dbc;
+ class Dbt;
+
+ namespace db_internal
+ {
+ class Noncopyable
+ {
+ // not implemented
+ Noncopyable(const Noncopyable&);
+ void operator=(const Noncopyable&);
+ protected:
+ Noncopyable() {}
+ ~Noncopyable() {}
+ };
+ }
+
+ class DESKTOP_DEPLOYMENTMISC_DLLPUBLIC DbException
+ {
+ rtl::OString what_;
+ public:
+ explicit DbException(rtl::OString const & theWhat)
+ : what_(theWhat)
+ {}
+
+ const char *what() const
+ { return what_.getStr(); }
+ int get_errno() const
+ { return 0; }
+ };
+
+
+ class DESKTOP_DEPLOYMENTMISC_DLLPUBLIC DbEnv : db_internal::Noncopyable
+ {
+ friend class Db;
+
+ private:
+ DB_ENV* m_pDBENV;
+
+ public:
+ static char *strerror(int);
+ };
+
+ class DESKTOP_DEPLOYMENTMISC_DLLPUBLIC Db : db_internal::Noncopyable
+ {
+ private:
+ DB* m_pDBP;
+
+ public:
+ Db(DbEnv* dbbenv,u_int32_t flags);
+ ~Db();
+
+ int close(u_int32_t flags);
+
+ int open(DB_TXN *txnid,
+ const char *file,
+ const char *database,
+ DBTYPE type,
+ u_int32_t flags,
+ int mode);
+
+ int sync(u_int32_t flags);
+ int del(Dbt *key, u_int32_t flags);
+
+ int get(DB_TXN* txnid, Dbt *key, Dbt *data, u_int32_t flags);
+ int put(DB_TXN* txnid, Dbt *key, Dbt *data, u_int32_t flags);
+
+ int cursor(DB_TXN *txnid, Dbc **cursorp, u_int32_t flags);
+ };
+
+ class DESKTOP_DEPLOYMENTMISC_DLLPUBLIC Dbc : db_internal::Noncopyable
+ {
+ friend class Db;
+ friend class Dbt;
+
+ private:
+ DBC* m_pDBC;
+
+ SAL_DLLPRIVATE explicit Dbc(DBC* pDBC);
+ SAL_DLLPRIVATE ~Dbc();
+
+ public:
+ int close();
+
+ int get(Dbt *key, Dbt *data, u_int32_t flags);
+ };
+
+ class DESKTOP_DEPLOYMENTMISC_DLLPUBLIC Dbt: private DBT
+ {
+ friend class Db;
+ friend class Dbc;
+
+ public:
+ Dbt(void *data_arg, u_int32_t size_arg);
+
+ Dbt();
+ Dbt(const Dbt & other);
+ Dbt & operator=(const Dbt & other);
+
+ ~Dbt();
+
+ void *get_data() const;
+ void set_data(void *value);
+
+ u_int32_t get_size() const;
+ void set_size(u_int32_t value);
+ };
+}
+
+#endif
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/desktop/source/deployment/inc/dp_dependencies.hxx b/desktop/source/deployment/inc/dp_dependencies.hxx
new file mode 100644
index 000000000000..bff5e2c8a89f
--- /dev/null
+++ b/desktop/source/deployment/inc/dp_dependencies.hxx
@@ -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: dp_dependencies.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 INCLUDED_DESKTOP_SOURCE_DEPLOYMENT_INC_DP_DEPENDENCIES_HXX
+#define INCLUDED_DESKTOP_SOURCE_DEPLOYMENT_INC_DP_DEPENDENCIES_HXX
+
+#include "sal/config.h"
+#include "com/sun/star/uno/Reference.hxx"
+#include "com/sun/star/uno/Sequence.hxx"
+#include "dp_misc_api.hxx"
+
+/// @HTML
+
+namespace com { namespace sun { namespace star { namespace xml { namespace dom {
+ class XElement;
+} } } } }
+namespace dp_misc { class DescriptionInfoset; }
+namespace rtl { class OUString; }
+
+namespace dp_misc {
+
+/**
+ Dependency handling.
+*/
+namespace Dependencies {
+ /**
+ Check for unsatisfied dependencies.
+
+ @param infoset
+ the infoset containing the dependencies to check
+
+ @return
+ a list of the unsatisfied dependencies from <code>infoset</code> (in no
+ specific order)
+ */
+ DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
+ ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::dom::XElement > >
+ check(::dp_misc::DescriptionInfoset const & infoset);
+
+ /**
+ Obtain the (human-readable) name of a dependency.
+
+ @param dependency
+ a dependency represented as a non-null XML element
+
+ @return
+ the name of the dependency; will never be empty, as a localized
+ &ldquo;unknown&rdquo; is substituted for an empty/missing name
+ */
+ DESKTOP_DEPLOYMENTMISC_DLLPUBLIC ::rtl::OUString name(
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::dom::XElement > const & dependency);
+
+ /**
+ Obtain the (human-readable) error message of a failed dependency.
+
+ @param dependency
+ a dependency represented as a non-null XML element
+
+ @return
+ the name of the dependency; will never be empty, as a localized
+ &ldquo;unknown&rdquo; is substituted for an empty/missing name
+ */
+ DESKTOP_DEPLOYMENTMISC_DLLPUBLIC ::rtl::OUString getErrorText(
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::dom::XElement > const & dependency);
+}
+
+}
+
+#endif
diff --git a/desktop/source/deployment/inc/dp_descriptioninfoset.hxx b/desktop/source/deployment/inc/dp_descriptioninfoset.hxx
new file mode 100644
index 000000000000..0ad48316e0fa
--- /dev/null
+++ b/desktop/source/deployment/inc/dp_descriptioninfoset.hxx
@@ -0,0 +1,281 @@
+/*************************************************************************
+ *
+ * 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: dp_descriptioninfoset.hxx,v $
+ * $Revision: 1.9.34.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 INCLUDED_DESKTOP_SOURCE_DEPLOYMENT_INC_DP_DESCRIPTIONINFOSET_HXX
+#define INCLUDED_DESKTOP_SOURCE_DEPLOYMENT_INC_DP_DESCRIPTIONINFOSET_HXX
+
+#include "sal/config.h"
+
+#include "boost/optional.hpp"
+#include "com/sun/star/uno/Reference.hxx"
+#include "com/sun/star/uno/Sequence.hxx"
+#include "sal/types.h"
+#include "dp_misc_api.hxx"
+
+/// @HTML
+
+namespace com { namespace sun { namespace star {
+ namespace lang { struct Locale; }
+ namespace uno { class XComponentContext; }
+ namespace xml {
+ namespace dom {
+ class XNode;
+ class XNodeList;
+ }
+ namespace xpath { class XXPathAPI; }
+ }
+} } }
+namespace rtl { class OUString; }
+
+namespace dp_misc {
+
+/**
+ Access to the content of an XML <code>description</code> element.
+
+ <p>This works for <code>description</code> elements in both the
+ <code>description.xml</code> file and online update information formats.</p>
+*/
+class DESKTOP_DEPLOYMENTMISC_DLLPUBLIC DescriptionInfoset {
+public:
+ /**
+ Create an instance.
+
+ @param context
+ a non-null component context
+
+ @param element
+ a <code>description</code> element; may be null (equivalent to an element
+ with no content)
+ */
+ DescriptionInfoset(
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::uno::XComponentContext > const & context,
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::dom::XNode > const & element);
+
+ ~DescriptionInfoset();
+
+ /**
+ Return the identifier.
+
+ @return
+ the identifier, or an empty <code>optional</code> if none is specified
+ */
+ ::boost::optional< ::rtl::OUString > getIdentifier() const;
+
+ /**
+ Return the textual version representation.
+
+ @return
+ textual version representation
+ */
+ ::rtl::OUString getVersion() const;
+
+ /**
+ Returns a list of supported platforms.
+
+ If the extension does not specify a platform by leaving out the platform element
+ then we assume that the extension supports all platforms. In this case the returned
+ sequence will have one element, which is &quot;all&quot;.
+ If the platform element is present but does not specify a platform then an empty
+ sequence is returned. Examples for invalid platform elements:
+ <pre>
+ <platform />, <platform value="" />, <platfrom value=",">
+ </pre>
+
+ The value attribute can contain various platform tokens. They must be separated by
+ commas.Each token will be stripped from leading and trailing white space (trim()).
+ */
+ ::com::sun::star::uno::Sequence< ::rtl::OUString > getSupportedPlaforms() const;
+
+ /**
+ Returns the localized publisher name and the corresponding URL.
+
+ In case there is no publisher element then a pair of two empty strings is returned.
+ */
+ ::std::pair< ::rtl::OUString, ::rtl::OUString > getLocalizedPublisherNameAndURL() const;
+
+ /**
+ Returns the URL for the release notes corresponding to the office's locale.
+
+ In case there is no release-notes element then an empty string is returned.
+ */
+ ::rtl::OUString getLocalizedReleaseNotesURL() const;
+
+ /** returns the relative path to the license file.
+
+ In case there is no simple-license element then an empty string is returned.
+ */
+ ::rtl::OUString getLocalizedLicenseURL() const;
+
+ /** returns the localized display name of the extensions.
+
+ In case there is no localized display-name then an empty string is returned.
+ */
+ ::rtl::OUString getLocalizedDisplayName() const;
+
+ /**
+ returns the download website URL from the update information.
+
+ There can be multiple URLs where each is assigned to a particular locale.
+ The function returs the URL which locale matches best the one used in the office.
+
+ The return value is an optional because it may be necessary to find out if there
+ was a value provided or not. This is necessary to flag the extension in the update dialog
+ properly as "browser based update". The return value will only then not be initialized
+ if there is no <code>&lt;update-website&gt;</code>. If the element exists, then it must
+ have at least one child element containing an URL.
+
+ The <code>&lt;update-website&gt;</code> and <code>&lt;update-download&gt;</code>
+ elements are mutually exclusiv.
+
+ @return
+ the download website URL, or an empty <code>optional</code> if none is
+ specified
+ */
+ ::boost::optional< ::rtl::OUString > getLocalizedUpdateWebsiteURL() const;
+
+ /** returns the relative URL to the description.
+
+ The URL is relative to the root directory of the extensions.
+ */
+ ::rtl::OUString getLocalizedDescriptionURL() const;
+ /**
+ Return the dependencies.
+
+ @return
+ dependencies; will never be null
+ */
+ ::com::sun::star::uno::Reference< ::com::sun::star::xml::dom::XNodeList >
+ getDependencies() const;
+
+ /**
+ Return the update information URLs.
+
+ @return
+ update information URLs
+ */
+ ::com::sun::star::uno::Sequence< ::rtl::OUString >
+ getUpdateInformationUrls() const;
+
+ /**
+ Return the download URLs from the update information.
+
+ Because the <code>&lt;update-download&gt;</code> and the <code>&lt;update-website&gt;</code>
+ elements are mutually exclusive one may need to determine exacty if the element
+ was provided.
+
+ @return
+ download URLs
+ */
+ ::com::sun::star::uno::Sequence< ::rtl::OUString >
+ getUpdateDownloadUrls() const;
+
+ /**
+ Returns the URL for the icon image.
+ */
+ ::rtl::OUString getIconURL( sal_Bool bHighContrast ) const;
+
+ /**
+ Allow direct access to the XPath functionality.
+
+ @return
+ direct access to the XPath functionality; null iff this instance was
+ constructed with a null <code>element</code>
+ */
+ ::com::sun::star::uno::Reference< ::com::sun::star::xml::xpath::XXPathAPI >
+ getXpath() const;
+
+private:
+ SAL_DLLPRIVATE ::boost::optional< ::rtl::OUString > getOptionalValue(
+ ::rtl::OUString const & expression) const;
+
+ SAL_DLLPRIVATE ::com::sun::star::uno::Sequence< ::rtl::OUString > getUrls(
+ ::rtl::OUString const & expression) const;
+
+ /** Retrieves a child element which as lang attribute which matches the office locale.
+
+ Only top-level children are taken into account. It is also assumed that they are all
+ of the same element type and have a lang attribute. The matching algoritm is according
+ to RFC 3066, with the exception that only one variant is allowed.
+ @param parent
+ the expression used to obtain the parent of the localized children. It can be null.
+ Then a null reference is returned.
+ */
+ SAL_DLLPRIVATE ::com::sun::star::uno::Reference< ::com::sun::star::xml::dom::XNode >
+ getLocalizedChild( ::rtl::OUString const & sParent) const;
+ SAL_DLLPRIVATE ::com::sun::star::uno::Reference< ::com::sun::star::xml::dom::XNode>
+ matchFullLocale(::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::dom::XNode > const & xParent, ::rtl::OUString const & sLocale) const;
+ SAL_DLLPRIVATE ::com::sun::star::uno::Reference< ::com::sun::star::xml::dom::XNode>
+ matchCountryAndLanguage(::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::dom::XNode > const & xParent,
+ ::com::sun::star::lang::Locale const & officeLocale) const;
+ SAL_DLLPRIVATE ::com::sun::star::uno::Reference< ::com::sun::star::xml::dom::XNode>
+ matchLanguage(
+ ::com::sun::star::uno::Reference< ::com::sun::star::xml::dom::XNode > const & xParent,
+ ::com::sun::star::lang::Locale const & officeLocale) const;
+
+ /** If there is no child element with a locale matching the office locale, then we use
+ the first child. In the case of the simple-license we also use the former default locale, which
+ was determined by the default-license-id (/description/registration/simple-license/@default-license-id)
+ and the license-id attributes (/description/registration/simple-license/license-text/@license-id).
+ However, since OOo 2.4 we use also the first child as default for the license
+ unless the two attributes are present.
+ */
+ SAL_DLLPRIVATE ::com::sun::star::uno::Reference< ::com::sun::star::xml::dom::XNode>
+ getChildWithDefaultLocale(
+ ::com::sun::star::uno::Reference< ::com::sun::star::xml::dom::XNode > const & xParent) const;
+ /**
+ @param out_bParentExists
+ indicates if the element node specified in sXPathParent exists.
+ */
+ SAL_DLLPRIVATE ::rtl::OUString getLocalizedHREFAttrFromChild(
+ ::rtl::OUString const & sXPathParent, bool * out_bParentExists) const;
+
+ static SAL_DLLPRIVATE ::rtl::OUString
+ localeToString(::com::sun::star::lang::Locale const & locale);
+
+ /** Gets the node value for a given expression. The expression is used in
+ m_xpath-selectSingleNode. The value of the returned node is return value
+ of this function.
+ */
+ SAL_DLLPRIVATE ::rtl::OUString
+ getNodeValueFromExpression(::rtl::OUString const & expression) const;
+
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::dom::XNode > m_element;
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::xpath::XXPathAPI > m_xpath;
+};
+
+}
+
+#endif
diff --git a/desktop/source/deployment/inc/dp_identifier.hxx b/desktop/source/deployment/inc/dp_identifier.hxx
new file mode 100644
index 000000000000..ac7b89ba6fbd
--- /dev/null
+++ b/desktop/source/deployment/inc/dp_identifier.hxx
@@ -0,0 +1,95 @@
+/*************************************************************************
+ *
+ * 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: dp_identifier.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 INCLUDED_DESKTOP_SOURCE_DEPLOYMENT_INC_DP_IDENTIFIER_HXX
+#define INCLUDED_DESKTOP_SOURCE_DEPLOYMENT_INC_DP_IDENTIFIER_HXX
+
+#include "sal/config.h"
+
+#include "boost/optional.hpp"
+#include "com/sun/star/uno/Reference.hxx"
+
+#include "dp_misc_api.hxx"
+
+namespace com { namespace sun { namespace star { namespace deployment {
+ class XPackage;
+} } } }
+namespace rtl { class OUString; }
+
+namespace dp_misc {
+
+/**
+ Generates an identifier from an optional identifier.
+
+ @param optional
+ an optional identifier
+
+ @param fileName
+ a file name
+
+ @return
+ the given optional identifier if present, otherwise a legacy identifier based
+ on the given file name
+*/
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC ::rtl::OUString generateIdentifier(
+ ::boost::optional< ::rtl::OUString > const & optional,
+ ::rtl::OUString const & fileName);
+
+/**
+ Gets the identifier of a package.
+
+ @param package
+ a non-null package
+
+ @return
+ the explicit identifier of the given package if present, otherwise the
+ implicit legacy identifier of the given package
+
+ @throws com::sun::star::uno::RuntimeException
+*/
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC ::rtl::OUString getIdentifier(
+ ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage >
+ const & package);
+
+/**
+ Generates a legacy identifier based on a file name.
+
+ @param fileName
+ a file name
+
+ @return
+ a legacy identifier based on the given file name
+*/
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC ::rtl::OUString generateLegacyIdentifier(
+ ::rtl::OUString const & fileName);
+
+}
+
+#endif
diff --git a/desktop/source/deployment/inc/dp_interact.h b/desktop/source/deployment/inc/dp_interact.h
new file mode 100644
index 000000000000..dd93cf2baf1a
--- /dev/null
+++ b/desktop/source/deployment/inc/dp_interact.h
@@ -0,0 +1,153 @@
+/*************************************************************************
+ *
+ * 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: dp_interact.h,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#if ! defined INCLUDED_DP_INTERACT_H
+#define INCLUDED_DP_INTERACT_H
+
+#include "rtl/ref.hxx"
+#include "cppuhelper/implbase1.hxx"
+#include "com/sun/star/uno/XComponentContext.hpp"
+#include "com/sun/star/ucb/XCommandEnvironment.hpp"
+#include "com/sun/star/task/XAbortChannel.hpp"
+#include "dp_misc_api.hxx"
+
+namespace css = ::com::sun::star;
+
+namespace dp_misc
+{
+
+inline void progressUpdate(
+ ::rtl::OUString const & status,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv )
+{
+ if (xCmdEnv.is()) {
+ css::uno::Reference<css::ucb::XProgressHandler> xProgressHandler(
+ xCmdEnv->getProgressHandler() );
+ if (xProgressHandler.is()) {
+ xProgressHandler->update( css::uno::makeAny(status) );
+ }
+ }
+}
+
+//==============================================================================
+class ProgressLevel
+{
+ css::uno::Reference<css::ucb::XProgressHandler> m_xProgressHandler;
+
+public:
+ inline ~ProgressLevel();
+ inline ProgressLevel(
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv,
+ ::rtl::OUString const & status );
+
+ inline void update( ::rtl::OUString const & status ) const;
+ inline void update( css::uno::Any const & status ) const;
+};
+
+//______________________________________________________________________________
+inline ProgressLevel::ProgressLevel(
+ css::uno::Reference< css::ucb::XCommandEnvironment > const & xCmdEnv,
+ ::rtl::OUString const & status )
+{
+ if (xCmdEnv.is())
+ m_xProgressHandler = xCmdEnv->getProgressHandler();
+ if (m_xProgressHandler.is())
+ m_xProgressHandler->push( css::uno::makeAny(status) );
+}
+
+//______________________________________________________________________________
+inline ProgressLevel::~ProgressLevel()
+{
+ if (m_xProgressHandler.is())
+ m_xProgressHandler->pop();
+}
+
+//______________________________________________________________________________
+inline void ProgressLevel::update( ::rtl::OUString const & status ) const
+{
+ if (m_xProgressHandler.is())
+ m_xProgressHandler->update( css::uno::makeAny(status) );
+}
+
+//______________________________________________________________________________
+inline void ProgressLevel::update( css::uno::Any const & status ) const
+{
+ if (m_xProgressHandler.is())
+ m_xProgressHandler->update( status );
+}
+
+//##############################################################################
+
+/** @return true if ia handler is present and any selection has been chosen
+ */
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC bool interactContinuation(
+ css::uno::Any const & request,
+ css::uno::Type const & continuation,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv,
+ bool * pcont, bool * pabort );
+
+//##############################################################################
+
+//==============================================================================
+class DESKTOP_DEPLOYMENTMISC_DLLPUBLIC AbortChannel :
+ public ::cppu::WeakImplHelper1<css::task::XAbortChannel>
+{
+ bool m_aborted;
+ css::uno::Reference<css::task::XAbortChannel> m_xNext;
+
+public:
+ inline AbortChannel() : m_aborted( false ) {}
+ inline static AbortChannel * get(
+ css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel )
+ { return static_cast<AbortChannel *>(xAbortChannel.get()); }
+
+ inline bool isAborted() const { return m_aborted; }
+
+ // XAbortChannel
+ virtual void SAL_CALL sendAbort() throw (css::uno::RuntimeException);
+
+ class SAL_DLLPRIVATE Chain
+ {
+ const ::rtl::Reference<AbortChannel> m_abortChannel;
+ public:
+ inline Chain(
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ css::uno::Reference<css::task::XAbortChannel> const & xNext )
+ : m_abortChannel( abortChannel )
+ { if (m_abortChannel.is()) m_abortChannel->m_xNext = xNext; }
+ inline ~Chain()
+ { if (m_abortChannel.is()) m_abortChannel->m_xNext.clear(); }
+ };
+ friend class Chain;
+};
+
+}
+
+#endif
diff --git a/desktop/source/deployment/inc/dp_misc.h b/desktop/source/deployment/inc/dp_misc.h
new file mode 100644
index 000000000000..0c90ed25375a
--- /dev/null
+++ b/desktop/source/deployment/inc/dp_misc.h
@@ -0,0 +1,159 @@
+/*************************************************************************
+ *
+ * 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: dp_misc.h,v $
+ * $Revision: 1.13.86.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.
+ *
+ ************************************************************************/
+
+#if ! defined INCLUDED_DP_MISC_H
+#define INCLUDED_DP_MISC_H
+
+#include "rtl/ustrbuf.hxx"
+#include "rtl/instance.hxx"
+#include "osl/mutex.hxx"
+#include "osl/process.h"
+#include "com/sun/star/uno/XComponentContext.hpp"
+#include "com/sun/star/lang/XComponent.hpp"
+#include "com/sun/star/lang/DisposedException.hpp"
+#include "com/sun/star/deployment/XPackageRegistry.hpp"
+#include "com/sun/star/awt/XWindow.hpp"
+#include "dp_misc_api.hxx"
+
+#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
+#define ARLEN(x) (sizeof (x) / sizeof *(x))
+
+namespace dp_misc {
+
+const sal_Char CR = 0x0d;
+const sal_Char LF = 0x0a;
+
+//==============================================================================
+class MutexHolder
+{
+ mutable ::osl::Mutex m_mutex;
+protected:
+ inline ::osl::Mutex & getMutex() const { return m_mutex; }
+};
+
+//==============================================================================
+inline void try_dispose( ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface> const & x )
+{
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent> xComp( x, ::com::sun::star::uno::UNO_QUERY );
+ if (xComp.is())
+ xComp->dispose();
+}
+
+//##############################################################################
+
+//==============================================================================
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
+::rtl::OUString expandUnoRcTerm( ::rtl::OUString const & term );
+
+//==============================================================================
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
+::rtl::OUString expandUnoRcUrl( ::rtl::OUString const & url );
+
+//==============================================================================
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC ::rtl::OUString makeURL(
+ ::rtl::OUString const & baseURL, ::rtl::OUString const & relPath );
+
+//==============================================================================
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC ::rtl::OUString generateRandomPipeId();
+
+class AbortChannel;
+//==============================================================================
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
+::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface> resolveUnoURL(
+ ::rtl::OUString const & connectString,
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext> const & xLocalContext,
+ AbortChannel * abortChannel = 0 );
+
+//==============================================================================
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC bool office_is_running();
+
+//==============================================================================
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
+oslProcess raiseProcess( ::rtl::OUString const & appURL,
+ ::com::sun::star::uno::Sequence< ::rtl::OUString > const & args );
+
+//==============================================================================
+/** returns the default update URL (for the update information) which
+ is used when an extension does not provide its own URL.
+*/
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
+::rtl::OUString getExtensionDefaultUpdateURL();
+
+/** writes the argument string to the console.
+ On Linux/Unix/etc. it converts the UTF16 string to an ANSI string using
+ osl_getThreadTextEncoding() as target encoding. On Windows it uses WriteFile
+ with the standard out stream. unopkg.com reads the data and prints them out using
+ WriteConsoleW.
+*/
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
+void writeConsole(::rtl::OUString const & sText);
+
+/** writes the argument string to the console.
+ On Linux/Unix/etc. the string is passed into fprintf without any conversion.
+ On Windows the string is converted to UTF16 assuming the argument is UTF8
+ encoded. The UTF16 string is written to stdout with WriteFile. unopkg.com
+ reads the data and prints them out using WriteConsoleW.
+*/
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
+void writeConsole(::rtl::OString const & sText);
+
+/** writes the argument to the console using the error stream.
+ Otherwise the same as writeConsole.
+*/
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
+void writeConsoleError(::rtl::OUString const & sText);
+
+
+/** writes the argument to the console using the error stream.
+ Otherwise the same as writeConsole.
+*/
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
+void writeConsoleError(::rtl::OString const & sText);
+
+
+/** reads from the console.
+ On Linux/Unix/etc. it uses fgets to read char values and converts them to OUString
+ using osl_getThreadTextEncoding as target encoding. The returned string has a maximum
+ size of 1024 and does NOT include leading and trailing white space(applied OUString::trim())
+*/
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
+::rtl::OUString readConsole();
+
+/** print the text to the console in a debug build.
+ The argument is forwarded to writeConsole. The function does not add new line.
+ The code is only executed if OSL_DEBUG_LEVEL > 1
+*/
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
+void TRACE(::rtl::OUString const & sText);
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
+void TRACE(::rtl::OString const & sText);
+}
+
+#endif
diff --git a/desktop/source/deployment/inc/dp_misc.mk b/desktop/source/deployment/inc/dp_misc.mk
new file mode 100644
index 000000000000..29ba4d489860
--- /dev/null
+++ b/desktop/source/deployment/inc/dp_misc.mk
@@ -0,0 +1,46 @@
+#*************************************************************************
+#
+# 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: dp_misc.mk,v $
+#
+# $Revision: 1.6 $
+#
+# 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.
+#
+#*************************************************************************
+
+# To be included after settings.mk
+
+# Although the deployment shared library is a UNO component, it also exports
+# some C++ functionality:
+.IF "$(OS)" == "WNT"
+.IF "$(COM)" == "GCC"
+DEPLOYMENTMISCLIB = -ldeploymentmisc$(DLLPOSTFIX)
+.ELSE
+DEPLOYMENTMISCLIB = ideploymentmisc$(DLLPOSTFIX).lib
+.ENDIF
+.ELIF "$(OS)" == "OS2"
+DEPLOYMENTMISCLIB = ideploymentmisc$(DLLPOSTFIX).lib
+.ELSE
+DEPLOYMENTMISCLIB = -ldeploymentmisc$(DLLPOSTFIX)
+.ENDIF
diff --git a/desktop/source/deployment/inc/dp_misc_api.hxx b/desktop/source/deployment/inc/dp_misc_api.hxx
new file mode 100644
index 000000000000..ba95bdcc1135
--- /dev/null
+++ b/desktop/source/deployment/inc/dp_misc_api.hxx
@@ -0,0 +1,43 @@
+/*************************************************************************
+ *
+ * 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: dp_misc_api.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 INCLUDED_DESKTOP_SOURCE_DEPLOYMENT_INC_DP_MISC_API_HXX
+#define INCLUDED_DESKTOP_SOURCE_DEPLOYMENT_INC_DP_MISC_API_HXX
+
+#include "sal/config.h"
+#include "sal/types.h"
+
+#if defined DESKTOP_DEPLOYMENTMISC_DLLIMPLEMENTATION
+#define DESKTOP_DEPLOYMENTMISC_DLLPUBLIC SAL_DLLPUBLIC_EXPORT
+#else
+#define DESKTOP_DEPLOYMENTMISC_DLLPUBLIC SAL_DLLPUBLIC_IMPORT
+#endif
+
+#endif
diff --git a/desktop/source/deployment/inc/dp_persmap.h b/desktop/source/deployment/inc/dp_persmap.h
new file mode 100644
index 000000000000..3a0873e5c05b
--- /dev/null
+++ b/desktop/source/deployment/inc/dp_persmap.h
@@ -0,0 +1,70 @@
+/*************************************************************************
+ *
+ * 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: dp_persmap.h,v $
+ * $Revision: 1.10 $
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#if ! defined INCLUDED_DP_PERSMAP_H
+#define INCLUDED_DP_PERSMAP_H
+
+#include "rtl/ustring.hxx"
+#include "db.hxx"
+#include <hash_map>
+
+using namespace berkeleydbproxy;
+
+namespace dp_misc
+{
+
+typedef ::std::hash_map<
+ ::rtl::OString, ::rtl::OString, ::rtl::OStringHash > t_string2string_map;
+
+//==============================================================================
+class PersistentMap
+{
+ ::rtl::OUString m_sysPath;
+ mutable Db m_db;
+ void throw_rtexc( int err, char const * msg = 0 ) const;
+
+public:
+ ~PersistentMap();
+ PersistentMap( ::rtl::OUString const & url, bool readOnly );
+ /** in mem db */
+ PersistentMap();
+
+ void flush() const;
+
+ bool has( ::rtl::OString const & key ) const;
+ bool get( ::rtl::OString * value, ::rtl::OString const & key ) const;
+ t_string2string_map getEntries() const;
+ void put( ::rtl::OString const & key, ::rtl::OString const & value );
+ bool erase( ::rtl::OString const & key, bool flush_immediately = true );
+};
+
+}
+
+#endif
diff --git a/desktop/source/deployment/inc/dp_platform.hxx b/desktop/source/deployment/inc/dp_platform.hxx
new file mode 100644
index 000000000000..51c33f49dffe
--- /dev/null
+++ b/desktop/source/deployment/inc/dp_platform.hxx
@@ -0,0 +1,60 @@
+/*************************************************************************
+ *
+ * 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: dp_platform.hxx,v $
+ *
+ * $Revision: 1.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.
+ *
+ ************************************************************************/
+
+#if ! defined INCLUDED_DP_PLATFORM_HXX
+#define INCLUDED_DP_PLATFORM_HXX
+
+
+#ifndef INCLUDED_DESKTOP_SOURCE_DEPLOYMENT_INC_DP_MISC_API_HXX
+#include "dp_misc_api.hxx"
+#endif
+
+#include "com/sun/star/uno/Sequence.hxx"
+#include "rtl/ustring.hxx"
+
+namespace dp_misc
+{
+
+
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC ::rtl::OUString const & getPlatformString();
+
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
+ bool platform_fits( ::rtl::OUString const & platform_string );
+
+/** determines if the current platform corresponds to one of the platform strings.
+
+*/
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
+bool hasValidPlatform( ::com::sun::star::uno::Sequence< ::rtl::OUString > const & platformStrings);
+
+}
+
+#endif
diff --git a/desktop/source/deployment/inc/dp_resource.h b/desktop/source/deployment/inc/dp_resource.h
new file mode 100644
index 000000000000..c7b5045d268a
--- /dev/null
+++ b/desktop/source/deployment/inc/dp_resource.h
@@ -0,0 +1,70 @@
+/*************************************************************************
+ *
+ * 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: dp_resource.h,v $
+ * $Revision: 1.12 $
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#if ! defined INCLUDED_DP_RESOURCE_H
+#define INCLUDED_DP_RESOURCE_H
+
+#include "tools/resmgr.hxx"
+#include "tools/string.hxx"
+#include "tools/resid.hxx"
+#include "com/sun/star/lang/Locale.hpp"
+#include "dp_misc.h"
+#include <memory>
+#include "dp_misc_api.hxx"
+
+namespace dp_misc {
+
+//==============================================================================
+ResId getResId( USHORT id );
+
+//==============================================================================
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC String getResourceString( USHORT id );
+
+template <typename Unique, USHORT id>
+struct StaticResourceString :
+ public ::rtl::StaticWithInit<const ::rtl::OUString, Unique> {
+ const ::rtl::OUString operator () () { return getResourceString(id); }
+};
+
+//==============================================================================
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
+::com::sun::star::lang::Locale toLocale( ::rtl::OUString const & slang );
+
+//==============================================================================
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
+::com::sun::star::lang::Locale getOfficeLocale();
+
+//==============================================================================
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
+::rtl::OUString getOfficeLocaleString();
+
+}
+
+#endif
diff --git a/desktop/source/deployment/inc/dp_ucb.h b/desktop/source/deployment/inc/dp_ucb.h
new file mode 100644
index 000000000000..1d8aabb72a50
--- /dev/null
+++ b/desktop/source/deployment/inc/dp_ucb.h
@@ -0,0 +1,87 @@
+/*************************************************************************
+ *
+ * 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: dp_ucb.h,v $
+ * $Revision: 1.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.
+ *
+ ************************************************************************/
+
+#if ! defined INCLUDED_DP_UCB_H
+#define INCLUDED_DP_UCB_H
+
+#include "rtl/byteseq.hxx"
+#include "rtl/instance.hxx"
+#include "com/sun/star/ucb/XCommandEnvironment.hpp"
+#include "dp_misc_api.hxx"
+
+namespace ucbhelper
+{
+class Content;
+}
+
+namespace css = ::com::sun::star;
+
+namespace dp_misc {
+
+struct DESKTOP_DEPLOYMENTMISC_DLLPUBLIC StrTitle :
+ public rtl::StaticWithInit<const rtl::OUString, StrTitle>
+{
+ const rtl::OUString operator () ();
+};
+
+//==============================================================================
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC bool create_ucb_content(
+ ::ucbhelper::Content * ucb_content,
+ ::rtl::OUString const & url,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv,
+ bool throw_exc = true );
+
+//==============================================================================
+/** @return true if previously non-existing folder has been created
+ */
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC bool create_folder(
+ ::ucbhelper::Content * ucb_content,
+ ::rtl::OUString const & url,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv,
+ bool throw_exc = true );
+
+//==============================================================================
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC bool erase_path(
+ ::rtl::OUString const & url,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv,
+ bool throw_exc = true );
+
+//==============================================================================
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
+::rtl::ByteSequence readFile( ::ucbhelper::Content & ucb_content );
+
+//==============================================================================
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC
+bool readLine( ::rtl::OUString * res, ::rtl::OUString const & startingWith,
+ ::ucbhelper::Content & ucb_content, rtl_TextEncoding textenc );
+
+}
+
+#endif
diff --git a/desktop/source/deployment/inc/dp_version.hxx b/desktop/source/deployment/inc/dp_version.hxx
new file mode 100644
index 000000000000..94a01fa6601f
--- /dev/null
+++ b/desktop/source/deployment/inc/dp_version.hxx
@@ -0,0 +1,58 @@
+/*************************************************************************
+ *
+ * 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: dp_version.hxx,v $
+ * $Revision: 1.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 INCLUDED_DESKTOP_SOURCE_DEPLOYMENT_INC_DP_VERSION_HXX
+#define INCLUDED_DESKTOP_SOURCE_DEPLOYMENT_INC_DP_VERSION_HXX
+
+#include "sal/config.h"
+#include "com/sun/star/uno/Reference.hxx"
+#include "dp_misc_api.hxx"
+
+namespace com { namespace sun { namespace star { namespace deployment {
+ class XPackage;
+} } } }
+namespace rtl { class OUString; }
+
+namespace dp_misc {
+
+enum Order { LESS, EQUAL, GREATER };
+
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC Order compareVersions(
+ ::rtl::OUString const & version1, ::rtl::OUString const & version2);
+
+DESKTOP_DEPLOYMENTMISC_DLLPUBLIC Order comparePackageVersions(
+ ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage >
+ const & package1,
+ ::com::sun::star::uno::Reference< ::com::sun::star::deployment::XPackage >
+ const & package2);
+
+}
+
+#endif
diff --git a/desktop/source/deployment/inc/dp_xml.h b/desktop/source/deployment/inc/dp_xml.h
new file mode 100644
index 000000000000..4f175010306e
--- /dev/null
+++ b/desktop/source/deployment/inc/dp_xml.h
@@ -0,0 +1,164 @@
+/*************************************************************************
+ *
+ * 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: dp_xml.h,v $
+ * $Revision: 1.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.
+ *
+ ************************************************************************/
+
+#if ! defined INCLUDED_DP_XML_H
+#define INCLUDED_DP_XML_H
+
+#include "rtl/ref.hxx"
+#include "rtl/ustrbuf.hxx"
+#include "cppuhelper/implbase1.hxx"
+#include "com/sun/star/uno/XComponentContext.hpp"
+#include "com/sun/star/xml/input/XRoot.hpp"
+#include "com/sun/star/xml/sax/XDocumentHandler.hpp"
+
+
+namespace ucbhelper
+{
+class Content;
+}
+
+namespace css = ::com::sun::star;
+
+namespace dp_misc
+{
+
+//==============================================================================
+void xml_parse(
+ css::uno::Reference< css::xml::sax::XDocumentHandler > const & xDocHandler,
+ ::ucbhelper::Content & ucb_content,
+ css::uno::Reference< css::uno::XComponentContext > const & xContext );
+
+//==============================================================================
+void xml_parse(
+ css::uno::Reference< css::xml::input::XRoot > const & xRoot,
+ ::ucbhelper::Content & ucb_content,
+ css::uno::Reference< css::uno::XComponentContext > const & xContext );
+
+//==============================================================================
+class XmlElement : public ::cppu::WeakImplHelper1< css::xml::input::XElement >
+{
+protected:
+ css::uno::Reference<css::xml::input::XNamespaceMapping> m_xNamespaceMapping;
+ const css::uno::Reference<css::xml::input::XElement> m_xParent;
+ sal_Int32 m_uid;
+ ::rtl::OUString m_localname;
+ css::uno::Reference<css::xml::input::XAttributes> m_xAttributes;
+ ::rtl::OUString m_characters;
+ bool m_got_endElement;
+
+ void check_xmlns( sal_Int32 uid ) const throw (css::xml::sax::SAXException);
+
+ inline XmlElement()
+ : m_uid( -1 ),
+ m_got_endElement( false )
+ {}
+ virtual ~XmlElement();
+public:
+ inline bool isParsed() const { return m_got_endElement; }
+
+ inline XmlElement(
+ css::uno::Reference<css::xml::input::XNamespaceMapping>
+ const & xMapping,
+ css::uno::Reference<css::xml::input::XElement> const & xParent,
+ sal_Int32 uid, ::rtl::OUString const & localname,
+ css::uno::Reference< css::xml::input::XAttributes >
+ const & xAttributes )
+ : m_xNamespaceMapping( xMapping ),
+ m_xParent( xParent ),
+ m_uid( uid ),
+ m_localname( localname ),
+ m_xAttributes( xAttributes ),
+ m_got_endElement( false )
+ {}
+
+ // XElement
+ virtual css::uno::Reference<css::xml::input::XElement> SAL_CALL
+ getParent() throw (css::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getLocalName()
+ throw (css::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getUid()
+ throw (css::uno::RuntimeException);
+ virtual css::uno::Reference<css::xml::input::XAttributes> SAL_CALL
+ getAttributes() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL ignorableWhitespace(
+ ::rtl::OUString const & rWhitespaces )
+ throw (css::xml::sax::SAXException, css::uno::RuntimeException);
+ virtual void SAL_CALL characters( ::rtl::OUString const & rChars )
+ throw (css::xml::sax::SAXException, css::uno::RuntimeException);
+ virtual void SAL_CALL processingInstruction(
+ ::rtl::OUString const & Target, ::rtl::OUString const & Data )
+ throw (css::xml::sax::SAXException, css::uno::RuntimeException);
+ virtual void SAL_CALL endElement()
+ throw (css::xml::sax::SAXException, css::uno::RuntimeException);
+ virtual css::uno::Reference<css::xml::input::XElement> SAL_CALL
+ startChildElement(
+ sal_Int32 nUid, ::rtl::OUString const & rLocalName,
+ css::uno::Reference<css::xml::input::XAttributes> const & xAttributes )
+ throw (css::xml::sax::SAXException, css::uno::RuntimeException);
+};
+
+//==============================================================================
+class XmlRootElement : public ::cppu::ImplInheritanceHelper1<
+ XmlElement, css::xml::input::XRoot >
+{
+ const ::rtl::OUString m_uri;
+
+protected:
+ virtual ~XmlRootElement();
+public:
+ inline ::rtl::OUString const & getUri() const
+ { return m_uri; }
+
+ XmlRootElement(
+ ::rtl::OUString const & uri, ::rtl::OUString const & localname );
+
+ // XRoot
+ virtual void SAL_CALL startDocument(
+ css::uno::Reference<css::xml::input::XNamespaceMapping>
+ const & xMapping )
+ throw (css::xml::sax::SAXException, css::uno::RuntimeException);
+ virtual void SAL_CALL endDocument()
+ throw (css::xml::sax::SAXException, css::uno::RuntimeException);
+ virtual void SAL_CALL processingInstruction(
+ ::rtl::OUString const & target, ::rtl::OUString const & data )
+ throw (css::xml::sax::SAXException, css::uno::RuntimeException);
+ virtual void SAL_CALL setDocumentLocator(
+ css::uno::Reference<css::xml::sax::XLocator> const & xLocator )
+ throw (css::xml::sax::SAXException, css::uno::RuntimeException);
+ virtual css::uno::Reference<css::xml::input::XElement> SAL_CALL
+ startRootElement(
+ sal_Int32 uid, ::rtl::OUString const & localname,
+ css::uno::Reference<css::xml::input::XAttributes> const & xAttributes )
+ throw (css::xml::sax::SAXException, css::uno::RuntimeException);
+};
+
+}
+
+#endif
diff --git a/desktop/source/deployment/makefile.mk b/desktop/source/deployment/makefile.mk
new file mode 100644
index 000000000000..8ee3efd34f63
--- /dev/null
+++ b/desktop/source/deployment/makefile.mk
@@ -0,0 +1,116 @@
+#*************************************************************************
+#
+# 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.18 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ = ..$/..
+
+PRJNAME = desktop
+TARGET = deployment
+ENABLE_EXCEPTIONS = TRUE
+#USE_DEFFILE = TRUE
+NO_BSYMBOLIC = TRUE
+
+.IF "$(GUI)"=="OS2"
+TARGET = deploy
+.ENDIF
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/source$/deployment$/inc$/dp_misc.mk
+
+.IF "$(SYSTEM_DB)" == "YES"
+CFLAGS+=-DSYSTEM_DB -I$(DB_INCLUDES)
+.ENDIF
+
+INCPRE += inc
+
+DLLPRE =
+
+SHL1TARGET = $(TARGET)$(DLLPOSTFIX).uno
+SHL1VERSIONMAP = deployment.map
+
+SHL1LIBS = \
+ $(SLB)$/deployment_manager.lib \
+ $(SLB)$/deployment_migration.lib \
+ $(SLB)$/deployment_registry.lib \
+ $(SLB)$/deployment_registry_executable.lib \
+ $(SLB)$/deployment_registry_component.lib \
+ $(SLB)$/deployment_registry_configuration.lib \
+ $(SLB)$/deployment_registry_package.lib \
+ $(SLB)$/deployment_registry_script.lib \
+ $(SLB)$/deployment_registry_sfwk.lib \
+ $(SLB)$/deployment_registry_help.lib
+
+SHL1OBJS = \
+ $(SLO)$/dp_log.obj \
+ $(SLO)$/dp_persmap.obj \
+ $(SLO)$/dp_services.obj \
+ $(SLO)$/dp_xml.obj
+
+SHL1STDLIBS = \
+ $(SALLIB) \
+ $(CPPULIB) \
+ $(CPPUHELPERLIB) \
+ $(UCBHELPERLIB) \
+ $(COMPHELPERLIB) \
+ $(TOOLSLIB) \
+ $(XMLSCRIPTLIB) \
+ $(SVLLIB) \
+ $(DEPLOYMENTMISCLIB) \
+ $(HELPLINKERLIB)
+
+SHL1DEPN =
+SHL1IMPLIB = i$(TARGET)
+SHL1DEF = $(MISC)$/$(SHL1TARGET).def
+
+DEF1NAME = $(SHL1TARGET)
+
+SLOFILES = $(LIB1OBJFILES)
+
+RESLIB1NAME = $(TARGET)
+
+RESLIB1SRSFILES = \
+ $(SRS)$/deployment_registry_configuration.srs \
+ $(SRS)$/deployment_registry_component.srs \
+ $(SRS)$/deployment_registry_script.srs \
+ $(SRS)$/deployment_registry_sfwk.srs \
+ $(SRS)$/deployment_registry_package.srs \
+ $(SRS)$/deployment_registry_help.srs \
+ $(SRS)$/deployment_registry.srs \
+ $(SRS)$/deployment_manager.srs \
+ $(SRS)$/deployment_unopkg.srs
+
+.IF "$(GUI)"=="OS2"
+RESLIB1SRSFILES += $(SRS)$/deplmisc.srs
+.ELSE
+RESLIB1SRSFILES += $(SRS)$/deployment_misc.srs
+.ENDIF
+
+.INCLUDE : target.mk
+
diff --git a/desktop/source/deployment/manager/dp_activepackages.cxx b/desktop/source/deployment/manager/dp_activepackages.cxx
new file mode 100644
index 000000000000..d97b94d62acb
--- /dev/null
+++ b/desktop/source/deployment/manager/dp_activepackages.cxx
@@ -0,0 +1,187 @@
+/*************************************************************************
+ *
+ * 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: dp_activepackages.cxx,v $
+ * $Revision: 1.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.
+ *
+ ************************************************************************/
+
+#include "precompiled_desktop.hxx"
+
+#include "sal/config.h"
+
+#include <cstddef>
+#include <utility>
+#include <vector>
+
+#include "osl/diagnose.h"
+#include "rtl/strbuf.hxx"
+#include "rtl/string.hxx"
+#include "rtl/textenc.h"
+#include "rtl/uri.h"
+#include "rtl/uri.hxx"
+#include "rtl/ustring.hxx"
+#include <hash_map>
+
+#include "dp_identifier.hxx"
+#include "dp_persmap.h"
+
+#include "dp_activepackages.hxx"
+
+// Old format of database entry:
+// key: UTF8(filename)
+// value: UTF8(tempname ";" mediatype)
+// New format of database entry:
+// key: 0xFF UTF8(identifier)
+// value: UTF8(tempname) 0xFF UTF8(filename) 0xFF UTF8(mediatype)
+
+namespace {
+
+static char const separator = static_cast< char >(
+ static_cast< unsigned char >(0xFF));
+
+static char const legacyPrefix[] = "org.openoffice.legacy.";
+
+::rtl::OString oldKey(::rtl::OUString const & fileName) {
+ return ::rtl::OUStringToOString(fileName, RTL_TEXTENCODING_UTF8);
+}
+
+::rtl::OString newKey(::rtl::OUString const & id) {
+ ::rtl::OStringBuffer b;
+ b.append(separator);
+ b.append(::rtl::OUStringToOString(id, RTL_TEXTENCODING_UTF8));
+ return b.makeStringAndClear();
+}
+
+::dp_manager::ActivePackages::Data decodeOldData(
+ ::rtl::OUString const & fileName, ::rtl::OString const & value)
+{
+ ::dp_manager::ActivePackages::Data d;
+ sal_Int32 i = value.indexOf(';');
+ OSL_ASSERT(i >= 0);
+ d.temporaryName = ::rtl::OUString(value.getStr(), i, RTL_TEXTENCODING_UTF8);
+ d.fileName = fileName;
+ d.mediaType = ::rtl::OUString(
+ value.getStr() + i + 1, value.getLength() - i - 1,
+ RTL_TEXTENCODING_UTF8);
+ return d;
+}
+
+::dp_manager::ActivePackages::Data decodeNewData(::rtl::OString const & value) {
+ ::dp_manager::ActivePackages::Data d;
+ sal_Int32 i1 = value.indexOf(separator);
+ OSL_ASSERT(i1 >= 0);
+ d.temporaryName = ::rtl::OUString(
+ value.getStr(), i1, RTL_TEXTENCODING_UTF8);
+ sal_Int32 i2 = value.indexOf(separator, i1 + 1);
+ OSL_ASSERT(i2 >= 0);
+ d.fileName = ::rtl::OUString(
+ value.getStr() + i1 + 1, i2 - i1 - 1, RTL_TEXTENCODING_UTF8);
+ d.mediaType = ::rtl::OUString(
+ value.getStr() + i2 + 1, value.getLength() - i2 - 1,
+ RTL_TEXTENCODING_UTF8);
+ return d;
+}
+
+}
+
+namespace dp_manager {
+
+ActivePackages::ActivePackages() {}
+
+ActivePackages::ActivePackages(::rtl::OUString const & url, bool readOnly):
+ m_map(url, readOnly) {}
+
+ActivePackages::~ActivePackages() {}
+
+bool ActivePackages::has(
+ ::rtl::OUString const & id, ::rtl::OUString const & fileName) const
+{
+ return get(NULL, id, fileName);
+}
+
+bool ActivePackages::get(
+ Data * data, ::rtl::OUString const & id, ::rtl::OUString const & fileName)
+ const
+{
+ ::rtl::OString v;
+ if (m_map.get(&v, newKey(id))) {
+ if (data != NULL) {
+ *data = decodeNewData(v);
+ }
+ return true;
+ } else if (m_map.get(&v, oldKey(fileName))) {
+ if (data != NULL) {
+ *data = decodeOldData(fileName, v);
+ }
+ return true;
+ } else {
+ return false;
+ }
+}
+
+ActivePackages::Entries ActivePackages::getEntries() const {
+ Entries es;
+ ::dp_misc::t_string2string_map m(m_map.getEntries());
+ for (::dp_misc::t_string2string_map::const_iterator i(m.begin());
+ i != m.end(); ++i)
+ {
+ if (i->first.getLength() > 0 && i->first[0] == separator) {
+ es.push_back(
+ ::std::make_pair(
+ ::rtl::OUString(
+ i->first.getStr() + 1, i->first.getLength() - 1,
+ RTL_TEXTENCODING_UTF8),
+ decodeNewData(i->second)));
+ } else {
+ ::rtl::OUString fn(
+ ::rtl::OStringToOUString(i->first, RTL_TEXTENCODING_UTF8));
+ es.push_back(
+ ::std::make_pair(
+ ::dp_misc::generateLegacyIdentifier(fn),
+ decodeOldData(fn, i->second)));
+ }
+ }
+ return es;
+}
+
+void ActivePackages::put(::rtl::OUString const & id, Data const & data) {
+ ::rtl::OStringBuffer b;
+ b.append(
+ ::rtl::OUStringToOString(data.temporaryName, RTL_TEXTENCODING_UTF8));
+ b.append(separator);
+ b.append(::rtl::OUStringToOString(data.fileName, RTL_TEXTENCODING_UTF8));
+ b.append(separator);
+ b.append(::rtl::OUStringToOString(data.mediaType, RTL_TEXTENCODING_UTF8));
+ m_map.put(newKey(id), b.makeStringAndClear());
+}
+
+void ActivePackages::erase(
+ ::rtl::OUString const & id, ::rtl::OUString const & fileName)
+{
+ m_map.erase(newKey(id), true) || m_map.erase(oldKey(fileName), true);
+}
+
+}
diff --git a/desktop/source/deployment/manager/dp_activepackages.hxx b/desktop/source/deployment/manager/dp_activepackages.hxx
new file mode 100644
index 000000000000..8ef57c3fe56d
--- /dev/null
+++ b/desktop/source/deployment/manager/dp_activepackages.hxx
@@ -0,0 +1,83 @@
+/*************************************************************************
+ *
+ * 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: dp_activepackages.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 INCLUDED_DESKTOP_SOURCE_DEPLOYMENT_MANAGER_DP_ACTIVEPACKAGES_HXX
+#define INCLUDED_DESKTOP_SOURCE_DEPLOYMENT_MANAGER_DP_ACTIVEPACKAGES_HXX
+
+#include "sal/config.h"
+
+#include <utility>
+#include <vector>
+
+#include "dp_persmap.h"
+
+namespace rtl { class OUString; }
+
+namespace dp_manager {
+
+class ActivePackages {
+public:
+ struct Data {
+ ::rtl::OUString temporaryName;
+ ::rtl::OUString fileName;
+ ::rtl::OUString mediaType;
+ };
+
+ typedef ::std::vector< ::std::pair< ::rtl::OUString, Data > > Entries;
+
+ ActivePackages();
+
+ ActivePackages(::rtl::OUString const & url, bool readOnly);
+
+ ~ActivePackages();
+
+ bool has(::rtl::OUString const & id, ::rtl::OUString const & fileName)
+ const;
+
+ bool get(
+ Data * data, ::rtl::OUString const & id,
+ ::rtl::OUString const & fileName) const;
+
+ Entries getEntries() const;
+
+ void put(::rtl::OUString const & id, Data const & value);
+
+ void erase(::rtl::OUString const & id, ::rtl::OUString const & fileName);
+
+private:
+ ActivePackages(ActivePackages &); // not defined
+ void operator =(ActivePackages &); // not defined
+
+ ::dp_misc::PersistentMap m_map;
+};
+
+}
+
+#endif
diff --git a/desktop/source/deployment/manager/dp_informationprovider.cxx b/desktop/source/deployment/manager/dp_informationprovider.cxx
new file mode 100644
index 000000000000..a769d083e75f
--- /dev/null
+++ b/desktop/source/deployment/manager/dp_informationprovider.cxx
@@ -0,0 +1,507 @@
+/*************************************************************************
+ *
+ * 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
+ *
+ * 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_desktop.hxx"
+
+#include <cppuhelper/implbase3.hxx>
+
+#include "comphelper/servicedecl.hxx"
+
+#include "com/sun/star/deployment/thePackageManagerFactory.hpp"
+#include "com/sun/star/deployment/UpdateInformationProvider.hpp"
+#include "com/sun/star/deployment/XPackage.hpp"
+#include "com/sun/star/deployment/XPackageInformationProvider.hpp"
+#include "com/sun/star/deployment/XPackageManager.hpp"
+#include "com/sun/star/deployment/XUpdateInformationProvider.hpp"
+#include "com/sun/star/lang/XServiceInfo.hpp"
+#include "com/sun/star/registry/XRegistryKey.hpp"
+#include "com/sun/star/task/XAbortChannel.hpp"
+#include "com/sun/star/ucb/CommandFailedException.hpp"
+#include "com/sun/star/ucb/XCommandEnvironment.hpp"
+#include "com/sun/star/uno/XComponentContext.hpp"
+#include "com/sun/star/xml/dom/XElement.hpp"
+#include "com/sun/star/xml/dom/XNode.hpp"
+
+#include "com/sun/star/uno/Reference.hxx"
+#include "rtl/ustring.hxx"
+#include "ucbhelper/content.hxx"
+
+#include "dp_dependencies.hxx"
+#include "dp_descriptioninfoset.hxx"
+#include "dp_identifier.hxx"
+#include "dp_version.hxx"
+#include "dp_misc.h"
+
+namespace beans = com::sun::star::beans ;
+namespace deployment = com::sun::star::deployment ;
+namespace lang = com::sun::star::lang ;
+namespace registry = com::sun::star::registry ;
+namespace task = com::sun::star::task ;
+namespace css_ucb = com::sun::star::ucb ;
+namespace uno = com::sun::star::uno ;
+namespace xml = com::sun::star::xml ;
+
+#define UNISTRING(s) rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(s))
+
+namespace dp_info {
+
+class PackageInformationProvider :
+ public ::cppu::WeakImplHelper3< deployment::XPackageInformationProvider,
+ css_ucb::XCommandEnvironment,
+ task::XInteractionHandler >
+{
+ public:
+ PackageInformationProvider( uno::Reference< uno::XComponentContext >const& xContext);
+ virtual ~PackageInformationProvider();
+
+ static uno::Sequence< rtl::OUString > getServiceNames();
+ static rtl::OUString getImplName();
+
+ // XInteractionHandler
+ virtual void SAL_CALL handle( const uno::Reference< task::XInteractionRequest >& Request )
+ throw( uno::RuntimeException );
+ // XCommandEnvironment
+ virtual uno::Reference< task::XInteractionHandler > SAL_CALL getInteractionHandler()
+ throw ( uno::RuntimeException ) { return static_cast<task::XInteractionHandler*>(this); };
+
+ virtual uno::Reference< css_ucb::XProgressHandler > SAL_CALL getProgressHandler()
+ throw ( uno::RuntimeException ) { return uno::Reference< css_ucb::XProgressHandler >(); };
+
+ // XPackageInformationProvider
+ virtual rtl::OUString SAL_CALL getPackageLocation( const rtl::OUString& extensionId )
+ throw ( uno::RuntimeException );
+ virtual uno::Sequence< uno::Sequence< rtl::OUString > > SAL_CALL isUpdateAvailable( const rtl::OUString& extensionId )
+ throw ( uno::RuntimeException );
+ virtual uno::Sequence< uno::Sequence< rtl::OUString > > SAL_CALL getExtensionList()
+ throw ( uno::RuntimeException );
+//---------
+private:
+
+ uno::Reference< uno::XComponentContext> mxContext;
+
+ rtl::OUString getPackageLocation( const uno::Reference< deployment::XPackageManager > _xManager,
+ const rtl::OUString& _sExtensionId );
+
+ uno::Reference< deployment::XUpdateInformationProvider > mxUpdateInformation;
+
+ uno::Sequence< uno::Reference< xml::dom::XElement > >
+ getUpdateInformation( uno::Sequence< rtl::OUString > const & urls,
+ rtl::OUString const & identifier ) const;
+ uno::Sequence< uno::Reference< deployment::XPackage > >
+ getPackages( const uno::Reference< deployment::XPackageManager > _xManager );
+ uno::Sequence< uno::Sequence< rtl::OUString > > isUpdateAvailable( const uno::Reference< deployment::XPackageManager > _xManager,
+ const rtl::OUString& _sExtensionId );
+ uno::Sequence< uno::Sequence< rtl::OUString > > getExtensionList( const uno::Reference< deployment::XPackageManager > _xManager );
+ uno::Sequence< uno::Sequence< rtl::OUString > > concatLists( uno::Sequence< uno::Sequence< rtl::OUString > > aFirst,
+ uno::Sequence< uno::Sequence< rtl::OUString > > aSecond );
+};
+
+//------------------------------------------------------------------------------
+
+PackageInformationProvider::PackageInformationProvider( uno::Reference< uno::XComponentContext > const& xContext) :
+ mxContext( xContext ),
+ mxUpdateInformation( deployment::UpdateInformationProvider::create( xContext ) )
+{
+}
+
+//------------------------------------------------------------------------------
+
+PackageInformationProvider::~PackageInformationProvider()
+{
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL PackageInformationProvider::handle( uno::Reference< task::XInteractionRequest > const & rRequest)
+ throw (uno::RuntimeException)
+{
+ uno::Sequence< uno::Reference< task::XInteractionContinuation > > xContinuations = rRequest->getContinuations();
+ if ( xContinuations.getLength() == 1 )
+ {
+ xContinuations[0]->select();
+ }
+}
+
+//------------------------------------------------------------------------------
+rtl::OUString PackageInformationProvider::getPackageLocation(
+ const uno::Reference< deployment::XPackageManager > _xManager,
+ const rtl::OUString& _rExtensionId )
+{
+ rtl::OUString aLocationURL;
+
+ if ( _xManager.is() )
+ {
+ const uno::Sequence< uno::Reference< deployment::XPackage > > packages(
+ _xManager->getDeployedPackages(
+ uno::Reference< task::XAbortChannel >(),
+ static_cast < XCommandEnvironment *> (this) ) );
+
+ for ( int pos = packages.getLength(); pos--; )
+ {
+ try
+ {
+ const rtl::OUString aName = packages[ pos ]->getName();
+ const beans::Optional< rtl::OUString > aID = packages[ pos ]->getIdentifier();
+ if ( aID.IsPresent && aID.Value.compareTo( _rExtensionId ) == 0 )
+ {
+ aLocationURL = packages[ pos ]->getURL();
+ break;
+ }
+ }
+ catch ( uno::RuntimeException & ) {}
+ }
+ }
+
+ return aLocationURL;
+}
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+rtl::OUString SAL_CALL
+PackageInformationProvider::getPackageLocation( const rtl::OUString& _sExtensionId )
+ throw ( uno::RuntimeException )
+{
+ uno::Reference< deployment::XPackageManager > xManager;
+ try {
+ xManager = deployment::thePackageManagerFactory::get( mxContext )->getPackageManager( UNISTRING("user") );
+ }
+ catch ( css_ucb::CommandFailedException & ){}
+ catch ( uno::RuntimeException & ) {}
+
+ rtl::OUString aLocationURL = getPackageLocation( xManager, _sExtensionId );
+
+ if ( aLocationURL.getLength() == 0 )
+ {
+ try {
+ xManager = deployment::thePackageManagerFactory::get( mxContext )->getPackageManager( UNISTRING("shared") );
+ }
+ catch ( css_ucb::CommandFailedException & ){}
+ catch ( uno::RuntimeException & ) {}
+
+ aLocationURL = getPackageLocation( xManager, _sExtensionId );
+ }
+
+ if ( aLocationURL.getLength() )
+ {
+ ::ucbhelper::Content aContent( aLocationURL, NULL );
+ aLocationURL = aContent.getURL();
+ }
+
+ return aLocationURL;
+}
+
+//------------------------------------------------------------------------------
+
+uno::Sequence< uno::Sequence< rtl::OUString > > SAL_CALL
+PackageInformationProvider::isUpdateAvailable( const rtl::OUString& _sExtensionId )
+ throw ( uno::RuntimeException )
+{
+ uno::Sequence< uno::Sequence< rtl::OUString > > aUpdateListUser;
+
+ uno::Reference< deployment::XPackageManager > xManager;
+ try {
+ xManager = deployment::thePackageManagerFactory::get( mxContext )->getPackageManager( UNISTRING("user") );
+ }
+ catch ( css_ucb::CommandFailedException & ){}
+ catch ( uno::RuntimeException & ) {}
+
+ aUpdateListUser = isUpdateAvailable( xManager, _sExtensionId );
+
+ uno::Sequence< uno::Sequence< rtl::OUString > > aUpdateListShared;
+ try {
+ xManager = deployment::thePackageManagerFactory::get( mxContext )->getPackageManager( UNISTRING("shared") );
+ }
+ catch ( css_ucb::CommandFailedException & ){}
+ catch ( uno::RuntimeException & ) {}
+
+ aUpdateListShared = isUpdateAvailable( xManager, _sExtensionId );
+
+ if ( !aUpdateListUser.hasElements() )
+ return aUpdateListShared;
+ else if ( !aUpdateListShared.hasElements() )
+ return aUpdateListUser;
+ else
+ return concatLists( aUpdateListUser, aUpdateListShared );
+}
+
+//------------------------------------------------------------------------------
+uno::Sequence< uno::Sequence< rtl::OUString > > SAL_CALL PackageInformationProvider::getExtensionList()
+ throw ( uno::RuntimeException )
+{
+ uno::Sequence< uno::Sequence< rtl::OUString > > aListUser;
+
+ uno::Reference< deployment::XPackageManager > xManager;
+ try {
+ xManager = deployment::thePackageManagerFactory::get( mxContext )->getPackageManager( UNISTRING("user") );
+ }
+ catch ( css_ucb::CommandFailedException & ){}
+ catch ( uno::RuntimeException & ) {}
+
+ aListUser = getExtensionList( xManager );
+
+ uno::Sequence< uno::Sequence< rtl::OUString > > aListShared;
+ try {
+ xManager = deployment::thePackageManagerFactory::get( mxContext )->getPackageManager( UNISTRING("shared") );
+ }
+ catch ( css_ucb::CommandFailedException & ){}
+ catch ( uno::RuntimeException & ) {}
+
+ aListShared = getExtensionList( xManager );
+
+ if ( !aListUser.hasElements() )
+ return aListShared;
+ else if ( !aListShared.hasElements() )
+ return aListUser;
+ else
+ return concatLists( aListUser, aListShared );
+}
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+uno::Sequence< uno::Reference< deployment::XPackage > >
+ PackageInformationProvider::getPackages( const uno::Reference< deployment::XPackageManager > _xMgr )
+{
+ uno::Sequence< uno::Reference< deployment::XPackage > > packages;
+ try {
+ packages = _xMgr->getDeployedPackages( uno::Reference< task::XAbortChannel >(),
+ static_cast < XCommandEnvironment *> (this) );
+ }
+ catch ( deployment::DeploymentException & )
+ {}
+ catch ( css_ucb::CommandFailedException & )
+ {}
+ catch ( css_ucb::CommandAbortedException & )
+ {}
+ catch ( lang::IllegalArgumentException & e )
+ {
+ throw uno::RuntimeException(e.Message, e.Context);
+ }
+
+ return packages;
+}
+
+//------------------------------------------------------------------------------
+uno::Sequence< uno::Reference< xml::dom::XElement > >
+ PackageInformationProvider::getUpdateInformation( uno::Sequence< rtl::OUString > const & urls,
+ rtl::OUString const & identifier ) const
+{
+ try
+ {
+ return mxUpdateInformation->getUpdateInformation( urls, identifier );
+ }
+ catch ( uno::RuntimeException & ) {
+ throw;
+ }
+ catch ( css_ucb::CommandFailedException & ) {}
+ catch ( css_ucb::CommandAbortedException & ) {}
+ catch ( uno::Exception & ) {}
+
+ return uno::Sequence< uno::Reference< xml::dom::XElement > >();
+}
+
+//------------------------------------------------------------------------------
+uno::Sequence< uno::Sequence< rtl::OUString > >
+ PackageInformationProvider::isUpdateAvailable(
+ const uno::Reference< deployment::XPackageManager > _xManager,
+ const rtl::OUString& _sExtensionId )
+{
+ uno::Sequence< uno::Sequence< rtl::OUString > > aList;
+ sal_Int32 nCount = 0;
+ bool bPackageFound = false;
+
+ // If the package manager is readonly then the user cannot modify anything anyway
+ // so we can abort the search here
+ if ( _xManager.is() && ! _xManager->isReadOnly() )
+ {
+ uno::Sequence< uno::Reference< deployment::XPackage > > packages( getPackages( _xManager ) );
+ uno::Sequence< uno::Reference< xml::dom::XElement > > defaultInfos;
+
+ for ( int pos = packages.getLength(); pos-- && !bPackageFound; )
+ {
+ uno::Reference< deployment::XPackage > package( packages[ pos ] );
+ uno::Sequence< rtl::OUString > urls( package->getUpdateInformationURLs());
+ uno::Sequence< uno::Reference< xml::dom::XElement > > infos;
+ rtl::OUString id( dp_misc::getIdentifier( package ) );
+
+ if ( _sExtensionId.getLength() )
+ {
+ if ( _sExtensionId == id )
+ bPackageFound = true;
+ else /* we have an ID and the IDs don't match, continue with next package */
+ continue;
+ }
+
+ if ( urls.getLength() != 0)
+ {
+ infos = getUpdateInformation( urls, id );
+ }
+ else
+ {
+ if ( defaultInfos.getLength() == 0 )
+ {
+ const rtl::OUString defaultURL( dp_misc::getExtensionDefaultUpdateURL() );
+ if ( defaultURL.getLength() )
+ defaultInfos = getUpdateInformation( uno::Sequence< rtl::OUString >( &defaultURL, 1 ),
+ rtl::OUString() );
+ }
+ infos = defaultInfos;
+ }
+ rtl::OUString latestVersion( package->getVersion() );
+ sal_Int32 latestIndex = -1;
+ for ( sal_Int32 i = 0; i < infos.getLength(); ++i )
+ {
+ dp_misc::DescriptionInfoset infoset( mxContext,
+ uno::Reference< xml::dom::XNode >( infos[i], uno::UNO_QUERY_THROW));
+ boost::optional< rtl::OUString > id2( infoset.getIdentifier() );
+
+ if (!id2)
+ continue;
+
+ if (*id2 == id)
+ {
+ // check, if there are unsatisfied dependencies and ignore those updates
+ uno::Sequence< uno::Reference< xml::dom::XElement > > ds( dp_misc::Dependencies::check( infoset ) );
+ if ( ds.getLength() )
+ continue;
+
+ rtl::OUString v( infoset.getVersion() );
+ if ( dp_misc::compareVersions( v, latestVersion ) == dp_misc::GREATER )
+ {
+ latestVersion = v;
+ latestIndex = i;
+ }
+ }
+ }
+ if ( latestIndex != -1 )
+ {
+ rtl::OUString aNewEntry[2];
+ aNewEntry[0] = id;
+ aNewEntry[1] = latestVersion;
+ aList.realloc( ++nCount );
+ aList[ nCount-1 ] = ::uno::Sequence< rtl::OUString >( aNewEntry, 2 );
+ }
+ }
+ }
+ return aList;
+}
+
+//------------------------------------------------------------------------------
+uno::Sequence< uno::Sequence< rtl::OUString > >
+ PackageInformationProvider::getExtensionList(
+ const uno::Reference< deployment::XPackageManager > _xManager )
+{
+ uno::Sequence< uno::Sequence< rtl::OUString > > aList;
+
+ if ( _xManager.is() )
+ {
+ uno::Sequence< uno::Reference< deployment::XPackage > > packages( getPackages( _xManager ) );
+
+ aList.realloc( packages.getLength() );
+
+ for ( int pos = packages.getLength(); pos--; )
+ {
+ uno::Reference< deployment::XPackage > package( packages[ pos ] );
+ rtl::OUString aNewEntry[2];
+
+ aNewEntry[0] = dp_misc::getIdentifier( package );
+ aNewEntry[1] = package->getVersion();
+ aList[ pos ] = ::uno::Sequence< rtl::OUString >( aNewEntry, 2 );
+ }
+ }
+ return aList;
+}
+
+//------------------------------------------------------------------------------
+uno::Sequence< uno::Sequence< rtl::OUString > > PackageInformationProvider::concatLists(
+ uno::Sequence< uno::Sequence< rtl::OUString > > aFirst,
+ uno::Sequence< uno::Sequence< rtl::OUString > > aSecond )
+{
+ sal_Int32 nFirstCount = aFirst.getLength();
+ sal_Int32 nSecondCount = aSecond.getLength();
+ sal_Int32 nIndex = nFirstCount;
+
+ for ( sal_Int32 i=0; i < nSecondCount; i++ )
+ {
+ bool bDuplicateEntry = false;
+ for ( sal_Int32 j=0; j < nFirstCount; j++ )
+ {
+ if ( aFirst[ j ][0] == aSecond[ i ][0] )
+ {
+ bDuplicateEntry = true;
+ break;
+ }
+ }
+ if ( !bDuplicateEntry )
+ {
+ nIndex += 1;
+ aFirst.realloc( nIndex );
+ aFirst[ nIndex - 1 ] = aSecond[ i ];
+ }
+ }
+ return aFirst;
+}
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+
+namespace sdecl = comphelper::service_decl;
+sdecl::class_<PackageInformationProvider> servicePIP;
+extern sdecl::ServiceDecl const serviceDecl(
+ servicePIP,
+ // a private one:
+ "com.sun.star.comp.deployment.PackageInformationProvider",
+ "com.sun.star.comp.deployment.PackageInformationProvider" );
+
+//------------------------------------------------------------------------------
+bool singleton_entries(
+ uno::Reference< registry::XRegistryKey > const & xRegistryKey )
+{
+ try {
+ uno::Reference< registry::XRegistryKey > xKey(
+ xRegistryKey->createKey(
+ serviceDecl.getImplementationName() +
+ // xxx todo: use future generated function to get singleton name
+ UNISTRING("/UNO/SINGLETONS/"
+ "com.sun.star.deployment.PackageInformationProvider") ) );
+ xKey->setStringValue( serviceDecl.getSupportedServiceNames()[0] );
+ return true;
+ }
+ catch (registry::InvalidRegistryException & exc) {
+ (void) exc; // avoid warnings
+ OSL_ENSURE( 0, ::rtl::OUStringToOString(
+ exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
+ return false;
+ }
+}
+
+} // namespace dp_info
+
+
diff --git a/desktop/source/deployment/manager/dp_manager.cxx b/desktop/source/deployment/manager/dp_manager.cxx
new file mode 100644
index 000000000000..d7177f90dc77
--- /dev/null
+++ b/desktop/source/deployment/manager/dp_manager.cxx
@@ -0,0 +1,1283 @@
+/*************************************************************************
+ *
+ * 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: dp_manager.cxx,v $
+ * $Revision: 1.33.8.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_desktop.hxx"
+
+#include "dp_ucb.h"
+#include "dp_resource.h"
+#include "dp_platform.hxx"
+#include "dp_manager.h"
+#include "dp_identifier.hxx"
+#include "rtl/ustrbuf.hxx"
+#include "rtl/string.hxx"
+#include "rtl/uri.hxx"
+#include "rtl/bootstrap.hxx"
+#include "osl/diagnose.h"
+#include "osl/file.hxx"
+#include "cppuhelper/weakref.hxx"
+#include "cppuhelper/exc_hlp.hxx"
+#include "cppuhelper/implbase1.hxx"
+#include "cppuhelper/interfacecontainer.hxx"
+#include "comphelper/servicedecl.hxx"
+#include "comphelper/sequence.hxx"
+#include "xmlscript/xml_helper.hxx"
+#include "svtools/inettype.hxx"
+#include "com/sun/star/lang/DisposedException.hpp"
+#include "com/sun/star/lang/WrappedTargetRuntimeException.hpp"
+#include "com/sun/star/beans/UnknownPropertyException.hpp"
+#include "com/sun/star/util/XUpdatable.hpp"
+#include "com/sun/star/sdbc/XResultSet.hpp"
+#include "com/sun/star/sdbc/XRow.hpp"
+#include "com/sun/star/ucb/XContentAccess.hpp"
+#include "com/sun/star/ucb/NameClash.hpp"
+#include "com/sun/star/deployment/VersionException.hpp"
+#include "com/sun/star/deployment/InstallException.hpp"
+#include "com/sun/star/task/XInteractionApprove.hpp"
+#include "com/sun/star/ucb/UnsupportedCommandException.hpp"
+#include "boost/bind.hpp"
+#include <vector>
+
+
+using namespace ::dp_misc;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::ucb;
+using ::rtl::OUString;
+
+namespace dp_log {
+extern comphelper::service_decl::ServiceDecl const serviceDecl;
+}
+
+namespace dp_registry {
+Reference<deployment::XPackageRegistry> create(
+ OUString const & context,
+ OUString const & cachePath, bool readOnly,
+ Reference<XComponentContext> const & xComponentContext );
+}
+
+namespace dp_manager {
+
+struct MatchTempDir
+{
+ OUString m_str;
+ MatchTempDir( OUString const & str ) : m_str( str ) {}
+ bool operator () ( ActivePackages::Entries::value_type const & v ) const {
+ return v.second.temporaryName.equalsIgnoreAsciiCase( m_str );
+ }
+};
+
+//______________________________________________________________________________
+void PackageManagerImpl::initActivationLayer(
+ Reference<XCommandEnvironment> const & xCmdEnv )
+{
+ if (m_activePackages.getLength() == 0)
+ {
+ OSL_ASSERT( m_registryCache.getLength() == 0 );
+ // documents temp activation:
+ m_activePackagesDB.reset( new ActivePackages );
+ ::ucbhelper::Content ucbContent;
+ if (create_ucb_content( &ucbContent, m_context, xCmdEnv,
+ false /* no throw */ ))
+ {
+ // scan for all entries in m_packagesDir:
+ Reference<sdbc::XResultSet> xResultSet(
+ ucbContent.createCursor(
+ Sequence<OUString>( &StrTitle::get(), 1 ),
+ ::ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS ) );
+ while (xResultSet->next())
+ {
+ Reference<sdbc::XRow> xRow( xResultSet, UNO_QUERY_THROW );
+ OUString title( xRow->getString( 1 /* Title */ ) );
+ // xxx todo: remove workaround for tdoc
+ if (title.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(
+ "this_is_a_dummy_stream_just_there_"
+ "as_a_workaround_for_a_"
+ "temporary_limitation_of_the_"
+ "storage_api_implementation") ))
+ continue;
+ if (title.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(
+ "META-INF") ) )
+ continue;
+
+ ::ucbhelper::Content sourceContent(
+ Reference<XContentAccess>(
+ xResultSet, UNO_QUERY_THROW )->queryContent(),
+ xCmdEnv );
+
+ OUString mediaType( detectMediaType( sourceContent,
+ false /* no throw */) );
+ if (mediaType.getLength() >0)
+ {
+ ActivePackages::Data dbData;
+ insertToActivationLayer(
+ mediaType, sourceContent, title, &dbData );
+
+ insertToActivationLayerDB( title, dbData );
+ //TODO #i73136#: insertToActivationLayerDB needs id not
+ // title, but the whole m_activePackages.getLength()==0
+ // case (i.e., document-relative deployment) currently
+ // does not work, anyway.
+ }
+ }
+ }
+ }
+ else
+ {
+ // user|share:
+ OSL_ASSERT( m_activePackages.getLength() > 0 );
+ m_activePackages_expanded = expandUnoRcUrl( m_activePackages );
+ create_folder( 0, m_activePackages_expanded, xCmdEnv, !m_readOnly );
+ m_activePackagesDB.reset(
+ new ActivePackages(
+ m_activePackages_expanded + OUSTR(".db"), m_readOnly ) );
+
+ if (! m_readOnly)
+ {
+ // clean up activation layer, scan for zombie temp dirs:
+ ActivePackages::Entries id2temp( m_activePackagesDB->getEntries() );
+
+ ::ucbhelper::Content tempFolder(
+ m_activePackages_expanded, xCmdEnv );
+ Reference<sdbc::XResultSet> xResultSet(
+ tempFolder.createCursor(
+ Sequence<OUString>( &StrTitle::get(), 1 ),
+ ::ucbhelper::INCLUDE_DOCUMENTS_ONLY ) );
+ // get all temp directories:
+ ::std::vector<OUString> tempEntries;
+ while (xResultSet->next()) {
+ OUString title(
+ Reference<sdbc::XRow>(
+ xResultSet, UNO_QUERY_THROW )->getString(
+ 1 /* Title */ ) );
+ tempEntries.push_back( ::rtl::Uri::encode(
+ title, rtl_UriCharClassPchar,
+ rtl_UriEncodeIgnoreEscapes,
+ RTL_TEXTENCODING_UTF8 ) );
+ }
+
+ for ( ::std::size_t pos = 0; pos < tempEntries.size(); ++pos )
+ {
+ OUString const & tempEntry = tempEntries[ pos ];
+ const MatchTempDir match( tempEntry );
+ if (::std::find_if( id2temp.begin(), id2temp.end(), match ) ==
+ id2temp.end())
+ {
+ // temp entry not needed anymore:
+ const OUString url( makeURL( m_activePackages_expanded,
+ tempEntry ) );
+ erase_path( url + OUSTR("_"),
+ Reference<XCommandEnvironment>(),
+ false /* no throw: ignore errors */ );
+ erase_path( url, Reference<XCommandEnvironment>(),
+ false /* no throw: ignore errors */ );
+ }
+ }
+ }
+ }
+}
+
+//______________________________________________________________________________
+void PackageManagerImpl::initRegistryBackends()
+{
+ if (m_registryCache.getLength() > 0)
+ create_folder( 0, m_registryCache,
+ Reference<XCommandEnvironment>(), !m_readOnly );
+ m_xRegistry.set( ::dp_registry::create(
+ m_context, m_registryCache, m_readOnly,
+ m_xComponentContext ) );
+}
+
+//______________________________________________________________________________
+Reference<deployment::XPackageManager> PackageManagerImpl::create(
+ Reference<XComponentContext> const & xComponentContext,
+ OUString const & context )
+{
+ PackageManagerImpl * that = new PackageManagerImpl(
+ xComponentContext, context );
+ Reference<deployment::XPackageManager> xPackageManager( that );
+
+ OUString packages, logFile, stampURL;
+ if (context.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("user") )) {
+ that->m_activePackages = OUSTR("vnd.sun.star.expand:$UNO_"
+ "USER_PACKAGES_CACHE/uno_packages");
+ that->m_registryCache = OUSTR("vnd.sun.star.expand:$UNO_"
+ "USER_PACKAGES_CACHE/registry");
+ logFile = OUSTR("vnd.sun.star.expand:$UNO_"
+ "USER_PACKAGES_CACHE/log.txt");
+ //We use the extension .sys for the file because on Windows Vista a sys
+ //(as well as exe and dll) file
+ //will not be written in the VirtualStore. For example if the process has no
+ //admin right once cannot write to the %programfiles% folder. However, when
+ //virtualization is used, the file will be written into the VirtualStore and
+ //it appears as if one could write to %programfiles%. When we test for write
+ //access to the office/shared folder for shared extensions then this typically
+ //fails because a normal user typically cannot write to this folder. However,
+ //using virtualization it appears that he/she can. Then a shared extension can
+ //be installed but is only visible for the user (because the extension is in
+ //the virtual store).
+ stampURL = OUSTR("vnd.sun.star.expand:$UNO_"
+ "USER_PACKAGES_CACHE/stamp.sys");
+ }
+ else if (context.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("shared") )) {
+ that->m_activePackages = OUSTR("vnd.sun.star.expand:$UNO_"
+ "SHARED_PACKAGES_CACHE/uno_packages");
+ that->m_registryCache = OUSTR("vnd.sun.star.expand:$UNO_"
+ "SHARED_PACKAGES_CACHE/registry");
+// The current logging implementation does not work for shared, because it requires
+// write access to the logfile. When two users run OOo at the same time on the same machine
+// then the
+// second will fail because it does not get write access. One cannot write into the
+// user's home, because then people may complain that when installing shared extension
+// stuff is written in their home.
+// logFile = OUSTR("vnd.sun.star.expand:$UNO_"
+// "SHARED_PACKAGES_CACHE/log.txt");
+ //See description for stampURL for user packages.
+ stampURL = OUSTR("vnd.sun.star.expand:$UNO_"
+ "SHARED_PACKAGES_CACHE/stamp.sys");
+ }
+ else if (! context.matchAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("vnd.sun.star.tdoc:/") )) {
+ throw lang::IllegalArgumentException(
+ OUSTR("invalid context given: ") + context,
+ Reference<XInterface>(), static_cast<sal_Int16>(-1) );
+ }
+
+ Reference<XCommandEnvironment> xCmdEnv;
+
+ try {
+ bool renewal = false;
+
+ if (stampURL.getLength() > 0)
+ {
+ // currently no automatic renewal possible, because quickstarter
+ // already hinders from deleting registry directory...
+
+#define CURRENT_STAMP "1"
+// renewal = true;
+// {
+// ::ucbhelper::Content ucbStamp;
+// if (create_ucb_content(
+// &ucbStamp, stampURL, xCmdEnv, false /* no throw */ ))
+// {
+// OUString line;
+// renewal = !readLine( &line, OUSTR(CURRENT_STAMP), ucbStamp,
+// RTL_TEXTENCODING_ASCII_US );
+// }
+// }
+
+ try {
+ // probe writing:
+ erase_path( stampURL, xCmdEnv );
+ ::ucbhelper::Content ucbStamp( stampURL, xCmdEnv );
+ ::rtl::OString stamp(
+ RTL_CONSTASCII_STRINGPARAM(CURRENT_STAMP) );
+ Reference<io::XInputStream> xData(
+ ::xmlscript::createInputStream(
+ ::rtl::ByteSequence(
+ reinterpret_cast<sal_Int8 const *>(stamp.getStr()),
+ stamp.getLength() ) ) );
+ ucbStamp.writeStream( xData, true /* replace existing */ );
+ }
+ catch (RuntimeException &) {
+ throw;
+ }
+ catch (Exception &) {
+ that->m_readOnly = true;
+ }
+ }
+
+ //Workaround. See issue http://www.openoffice.org/issues/show_bug.cgi?id=99257
+ //This prevents the copying of the common.rdbf and native rdbs. It disables the
+ //feature to add shared extensions in a running office.
+ if (!that->m_readOnly && context.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("shared") ))
+ {
+ OUString sNoRdb;
+ ::rtl::Bootstrap::get(OUSTR("NORDBCOPY"), sNoRdb);
+ if (sNoRdb.equalsIgnoreAsciiCase(OUSTR("true"))
+ && dp_misc::office_is_running())
+ that->m_readOnly = true;
+ }
+
+ if (!that->m_readOnly && logFile.getLength() > 0)
+ {
+ const Any any_logFile(logFile);
+ that->m_xLogFile.set(
+ that->m_xComponentContext->getServiceManager()
+ ->createInstanceWithArgumentsAndContext(
+ dp_log::serviceDecl.getSupportedServiceNames()[0],
+ Sequence<Any>( &any_logFile, 1 ),
+ that->m_xComponentContext ),
+ UNO_QUERY_THROW );
+ xCmdEnv.set( new CmdEnvWrapperImpl( xCmdEnv, that->m_xLogFile ) );
+ }
+
+ OSL_ENSURE( !that->m_readOnly || !renewal,
+ "### ought to reinstall all packages, but cannot write!" );
+ if (!that->m_readOnly && renewal) // try to reinstall
+ that->reinstallDeployedPackages(
+ Reference<task::XAbortChannel>(), xCmdEnv );
+
+ that->initRegistryBackends();
+ that->initActivationLayer( xCmdEnv );
+
+ return xPackageManager;
+
+ }
+ catch (RuntimeException &) {
+ throw;
+ }
+ catch (Exception &) {
+ Any exc( ::cppu::getCaughtException() );
+ ::rtl::OUStringBuffer buf;
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[context=\"") );
+ buf.append( context );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
+ "\"] caught unexpected exception!") );
+ throw lang::WrappedTargetRuntimeException(
+ buf.makeStringAndClear(), Reference<XInterface>(), exc );
+ }
+}
+
+//______________________________________________________________________________
+PackageManagerImpl::~PackageManagerImpl()
+{
+}
+
+//______________________________________________________________________________
+void PackageManagerImpl::fireModified()
+{
+ ::cppu::OInterfaceContainerHelper * pContainer = rBHelper.getContainer(
+ util::XModifyListener::static_type() );
+ if (pContainer != 0) {
+ pContainer->forEach<util::XModifyListener>(
+ boost::bind(&util::XModifyListener::modified, _1,
+ lang::EventObject(static_cast<OWeakObject *>(this))) );
+ }
+}
+
+//______________________________________________________________________________
+void PackageManagerImpl::disposing()
+{
+ try {
+// // xxx todo: guarding?
+// ::osl::MutexGuard guard( getMutex() );
+ try_dispose( m_xLogFile );
+ m_xLogFile.clear();
+ try_dispose( m_xRegistry );
+ m_xRegistry.clear();
+ m_activePackagesDB.reset(0);
+ m_xComponentContext.clear();
+
+ t_pm_helper::disposing();
+
+ }
+ catch (RuntimeException &) {
+ throw;
+ }
+ catch (Exception &) {
+ Any exc( ::cppu::getCaughtException() );
+ throw lang::WrappedTargetRuntimeException(
+ OUSTR("caught unexpected exception while disposing..."),
+ static_cast<OWeakObject *>(this), exc );
+ }
+}
+
+// XComponent
+//______________________________________________________________________________
+void PackageManagerImpl::dispose() throw (RuntimeException)
+{
+ check();
+ WeakComponentImplHelperBase::dispose();
+}
+
+//______________________________________________________________________________
+void PackageManagerImpl::addEventListener(
+ Reference<lang::XEventListener> const & xListener ) throw (RuntimeException)
+{
+ check();
+ WeakComponentImplHelperBase::addEventListener( xListener );
+}
+
+//______________________________________________________________________________
+void PackageManagerImpl::removeEventListener(
+ Reference<lang::XEventListener> const & xListener ) throw (RuntimeException)
+{
+ check();
+ WeakComponentImplHelperBase::removeEventListener( xListener );
+}
+
+// XPackageManager
+//______________________________________________________________________________
+OUString PackageManagerImpl::getContext() throw (RuntimeException)
+{
+ check();
+ return m_context;
+}
+
+//______________________________________________________________________________
+Sequence< Reference<deployment::XPackageTypeInfo> >
+PackageManagerImpl::getSupportedPackageTypes() throw (RuntimeException)
+{
+ OSL_ASSERT( m_xRegistry.is() );
+ return m_xRegistry->getSupportedPackageTypes();
+}
+
+//______________________________________________________________________________
+Reference<task::XAbortChannel> PackageManagerImpl::createAbortChannel()
+ throw (RuntimeException)
+{
+ check();
+ return new AbortChannel;
+}
+
+// XModifyBroadcaster
+//______________________________________________________________________________
+void PackageManagerImpl::addModifyListener(
+ Reference<util::XModifyListener> const & xListener )
+ throw (RuntimeException)
+{
+ check();
+ rBHelper.addListener( ::getCppuType( &xListener ), xListener );
+}
+
+//______________________________________________________________________________
+void PackageManagerImpl::removeModifyListener(
+ Reference<util::XModifyListener> const & xListener )
+ throw (RuntimeException)
+{
+ check();
+ rBHelper.removeListener( ::getCppuType( &xListener ), xListener );
+}
+
+//______________________________________________________________________________
+OUString PackageManagerImpl::detectMediaType(
+ ::ucbhelper::Content const & ucbContent_, bool throw_exc )
+{
+ ::ucbhelper::Content ucbContent(ucbContent_);
+ OUString url( ucbContent.getURL() );
+ OUString mediaType;
+ if (url.matchAsciiL( RTL_CONSTASCII_STRINGPARAM("vnd.sun.star.tdoc:") ) ||
+ url.matchAsciiL( RTL_CONSTASCII_STRINGPARAM("vnd.sun.star.pkg:") ))
+ {
+ try {
+ ucbContent.getPropertyValue( OUSTR("MediaType") ) >>= mediaType;
+ }
+ catch (beans::UnknownPropertyException &) {
+ }
+ OSL_ENSURE( mediaType.getLength() > 0, "### no media-type?!" );
+ }
+ if (mediaType.getLength() == 0)
+ {
+ try {
+ Reference<deployment::XPackage> xPackage(
+ m_xRegistry->bindPackage(
+ url, OUString(), ucbContent.getCommandEnvironment() ) );
+ const Reference<deployment::XPackageTypeInfo> xPackageType(
+ xPackage->getPackageType() );
+ OSL_ASSERT( xPackageType.is() );
+ if (xPackageType.is())
+ mediaType = xPackageType->getMediaType();
+ }
+ catch (lang::IllegalArgumentException & exc) {
+ if (throw_exc)
+ throw;
+ (void) exc;
+ OSL_ENSURE( 0, ::rtl::OUStringToOString(
+ exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
+ }
+ }
+ return mediaType;
+}
+
+//______________________________________________________________________________
+OUString PackageManagerImpl::insertToActivationLayer(
+ OUString const & mediaType, ::ucbhelper::Content const & sourceContent_,
+ OUString const & title, ActivePackages::Data * dbData )
+{
+ ::ucbhelper::Content sourceContent(sourceContent_);
+ Reference<XCommandEnvironment> xCmdEnv(
+ sourceContent.getCommandEnvironment() );
+ OUString destFolder, tempEntry;
+ if (::osl::File::createTempFile(
+ m_activePackages_expanded.getLength() == 0
+ ? 0 : &m_activePackages_expanded,
+ 0, &tempEntry ) != ::osl::File::E_None)
+ throw RuntimeException(
+ OUSTR("::osl::File::createTempFile() failed!"), 0 );
+ if (m_activePackages_expanded.getLength() == 0) {
+ destFolder = tempEntry;
+ }
+ else {
+ tempEntry = tempEntry.copy( tempEntry.lastIndexOf( '/' ) + 1 );
+ // tweak user|share to macrofied url:
+ destFolder = makeURL( m_activePackages, tempEntry );
+ }
+ destFolder += OUSTR("_");
+
+ // prepare activation folder:
+ ::ucbhelper::Content destFolderContent;
+ create_folder( &destFolderContent, destFolder, xCmdEnv );
+
+ // copy content into activation temp dir:
+ if (mediaType.matchIgnoreAsciiCaseAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(
+ "application/vnd.sun.star.package-bundle") ) ||
+ // xxx todo: more sophisticated parsing
+ mediaType.matchIgnoreAsciiCaseAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(
+ "application/vnd.sun.star.legacy-package-bundle") ))
+ {
+ // inflate content:
+ ::rtl::OUStringBuffer buf;
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("vnd.sun.star.zip://") );
+ buf.append( ::rtl::Uri::encode( sourceContent.getURL(),
+ rtl_UriCharClassRegName,
+ rtl_UriEncodeIgnoreEscapes,
+ RTL_TEXTENCODING_UTF8 ) );
+ buf.append( static_cast<sal_Unicode>('/') );
+ sourceContent = ::ucbhelper::Content(
+ buf.makeStringAndClear(), xCmdEnv );
+ }
+ if (! destFolderContent.transferContent(
+ sourceContent, ::ucbhelper::InsertOperation_COPY,
+ title, NameClash::OVERWRITE ))
+ throw RuntimeException( OUSTR("UCB transferContent() failed!"), 0 );
+
+ // write to DB:
+ dbData->temporaryName = tempEntry;
+ dbData->fileName = title;
+ dbData->mediaType = mediaType;
+ return destFolder;
+}
+
+//______________________________________________________________________________
+void PackageManagerImpl::insertToActivationLayerDB(
+ OUString const & id, ActivePackages::Data const & dbData )
+{
+ m_activePackagesDB->put( id, dbData );
+}
+
+//______________________________________________________________________________
+/* The function returns true if there is an extension with the same id already
+ installed which needs to be uninstalled, before the new extension can be installed.
+*/
+bool PackageManagerImpl::checkUpdate(
+ Reference<deployment::XPackage> const & package,
+ Reference<XCommandEnvironment> const & origCmdEnv,
+ Reference<XCommandEnvironment> const & wrappedCmdEnv )
+{
+ OUString id(dp_misc::getIdentifier(package));
+ OUString fn(package->getName());
+ bool removeExisting = false;
+ if (m_activePackagesDB->has( id, fn ))
+ {
+ // package already deployed, interact --force:
+ Any request(
+ (deployment::VersionException(
+ getResourceString( RID_STR_PACKAGE_ALREADY_ADDED ) + id,
+ static_cast<OWeakObject *>(this), package,
+ getDeployedPackage_( id, fn, origCmdEnv ) ) ) );
+ bool replace = false, abort = false;
+ if (! interactContinuation(
+ request, task::XInteractionApprove::static_type(),
+ wrappedCmdEnv, &replace, &abort )) {
+ OSL_ASSERT( !replace && !abort );
+ throw deployment::DeploymentException(
+ getResourceString(RID_STR_ERROR_WHILE_ADDING) + id,
+ static_cast<OWeakObject *>(this), request );
+ }
+ if (abort || !replace)
+ throw CommandFailedException(
+ getResourceString(RID_STR_PACKAGE_ALREADY_ADDED) + id,
+ static_cast<OWeakObject *>(this), request );
+
+ // remove clashing package before registering new version:
+ removeExisting = true;
+ }
+ return removeExisting;
+}
+//______________________________________________________________________________
+// Notify the user when a new extension is to be installed. This is only the case
+//when unopkg gui extension1 is used (used by system integration (double click on .oxt
+// file etc.)). In case there is already this extension then the function returns
+//true.
+//ToDo: Function always returns true or throws an exception
+bool PackageManagerImpl::checkInstall(
+ Reference<deployment::XPackage> const & package,
+ Reference<XCommandEnvironment> const & cmdEnv)
+{
+ OUString id(dp_misc::getIdentifier(package));
+ if ( ! m_activePackagesDB->has( id, package->getName() ))
+ {
+ Any request(
+ deployment::InstallException(
+ OUSTR("Extension ") + id + OUSTR(" is about to be installed."),
+ static_cast<OWeakObject *>(this), package));
+ bool approve = false, abort = false;
+ if (! interactContinuation(
+ request, task::XInteractionApprove::static_type(),
+ cmdEnv, &approve, &abort ))
+ {
+ OSL_ASSERT( !approve && !abort );
+ throw deployment::DeploymentException(
+ getResourceString(RID_STR_ERROR_WHILE_ADDING) + id,
+ static_cast<OWeakObject *>(this), request );
+ }
+ if (abort || !approve)
+ throw CommandFailedException(
+ getResourceString(RID_STR_ERROR_WHILE_ADDING) + id,
+ static_cast<OWeakObject *>(this), request );
+
+ }
+ return true;
+}
+
+// XPackageManager
+//______________________________________________________________________________
+Reference<deployment::XPackage> PackageManagerImpl::addPackage(
+ OUString const & url, OUString const & mediaType_,
+ Reference<task::XAbortChannel> const & xAbortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv_ )
+ throw (deployment::DeploymentException, CommandFailedException,
+ CommandAbortedException, lang::IllegalArgumentException,
+ RuntimeException)
+{
+ check();
+ if (m_readOnly)
+ {
+ OUString message;
+ if (m_context == OUSTR("shared"))
+ message = OUSTR("You need write permissions to install a shared extension!");
+ else
+ message = OUSTR("You need write permissions to install this extension!");
+ throw deployment::DeploymentException(
+ message, static_cast<OWeakObject *>(this), Any() );
+ }
+ Reference<XCommandEnvironment> xCmdEnv;
+ if (m_xLogFile.is())
+ xCmdEnv.set( new CmdEnvWrapperImpl( xCmdEnv_, m_xLogFile ) );
+ else
+ xCmdEnv.set( xCmdEnv_ );
+
+ try {
+ ::ucbhelper::Content sourceContent;
+ create_ucb_content( &sourceContent, url, xCmdEnv ); // throws exc
+ const OUString title(sourceContent.getPropertyValue(
+ StrTitle::get() ).get<OUString>() );
+ const OUString title_enc( ::rtl::Uri::encode(
+ title, rtl_UriCharClassPchar,
+ rtl_UriEncodeIgnoreEscapes,
+ RTL_TEXTENCODING_UTF8 ) );
+ OUString destFolder;
+
+ OUString mediaType(mediaType_);
+ if (mediaType.getLength() == 0)
+ mediaType = detectMediaType( sourceContent );
+
+ Reference<deployment::XPackage> xPackage;
+ // copy file:
+ progressUpdate(
+ getResourceString(RID_STR_COPYING_PACKAGE) + title, xCmdEnv );
+ if (m_activePackages.getLength() == 0)
+ {
+ ::ucbhelper::Content docFolderContent;
+ create_folder( &docFolderContent, m_context, xCmdEnv );
+ // copy into document, first:
+ if (! docFolderContent.transferContent(
+ sourceContent, ::ucbhelper::InsertOperation_COPY,
+ OUString(),
+ NameClash::ASK /* xxx todo: ASK not needed? */))
+ throw RuntimeException(
+ OUSTR("UCB transferContent() failed!"), 0 );
+ // set media-type:
+ ::ucbhelper::Content docContent(
+ makeURL( m_context, title_enc ), xCmdEnv );
+ //TODO #i73136#: using title instead of id can lead to
+ // clashes, but the whole m_activePackages.getLength()==0
+ // case (i.e., document-relative deployment) currently does
+ // not work, anyway.
+ docContent.setPropertyValue(
+ OUSTR("MediaType"), Any(mediaType) );
+
+ // xxx todo: obsolete in the future
+ try {
+ docFolderContent.executeCommand( OUSTR("flush"), Any() );
+ }
+ catch (UnsupportedCommandException &) {
+ }
+ }
+ ActivePackages::Data dbData;
+ destFolder = insertToActivationLayer(
+ mediaType, sourceContent, title, &dbData );
+
+
+ // bind activation package:
+ //Because every extension will be unpacked in a folder, which was created with a unique name
+ //we will always have two different XPackage objects, even if the second extension is the same.
+ //Therefore bindPackage does not need a guard here.
+ xPackage = m_xRegistry->bindPackage(
+ makeURL( destFolder, title_enc ), mediaType, xCmdEnv );
+
+ OSL_ASSERT( xPackage.is() );
+ if (xPackage.is())
+ {
+ bool install = false;
+ OUString id;
+
+ try
+ {
+ id = dp_misc::getIdentifier( xPackage );
+ //checkInstall throws an exception if the user denies the installation
+ checkInstall(xPackage, xCmdEnv);
+ //checkUpdate throws an exception if the user cancels the interaction.
+ //For example, he may be asked if he wants to replace the older version
+ //with the new version.
+ //checkUpdates must be called before checkPrerequisites
+ bool bAlreadyInstalled = checkUpdate(
+ xPackage, xCmdEnv_, xCmdEnv );
+
+ if (xPackage->checkPrerequisites(xAbortChannel, xCmdEnv, bAlreadyInstalled, m_context))
+ {
+ //This guard is used to prevent that an extension is installed twice. Do not use it in other
+ //functions.
+ //Imagine addPackage is called two times by different threads for the same extension quickly
+ //after each other.
+ //The second call would calculate "bAlreadyInstalled = false" if the first thread has not yet reached
+ //insertToActivationLayerDB.
+ ::osl::MutexGuard g(m_addMutex);
+
+ //Holds the database data of the old extension, in case we need to roll back.
+ ActivePackages::Data oldDbData;
+ if (bAlreadyInstalled)
+ {
+ // Remove extension which is already installed. It is not removed from disk, only
+ // the different contents are being unregisterd. We remember the databas information
+ // in case we need to roll back this operation.
+ // When the user canceled the operation (CommandAbortedException) than the package is still
+ // fully functional.
+ // Do not guard the complete function with the getMutex
+ removePackage_(id, xPackage->getName(), xAbortChannel,
+ xCmdEnv, & oldDbData);
+ }
+ install = true;
+ const ::osl::MutexGuard guard( getMutex() );
+ try
+ {
+ //throws CommandAbortedException if the user cancelled the installation.
+ xPackage->registerPackage(xAbortChannel, xCmdEnv);
+ }
+ catch(CommandAbortedException & )
+ { //ToDo: Interaction so that the gui can display an appropriate string.
+ //See also removePackage_
+ //User aborted installation, restore the previous situation.
+ //Use a private AbortChannel so the user cannot interrupt.
+ xPackage->revokePackage(new AbortChannel(), xCmdEnv);
+ if (bAlreadyInstalled)
+ {
+ OUString instFolder = makeURL( m_activePackages, oldDbData.temporaryName)
+ + OUSTR("_");
+ Reference<deployment::XPackage> xOldPgk = m_xRegistry->bindPackage(
+ makeURL( instFolder, oldDbData.fileName ), oldDbData.mediaType, xCmdEnv );
+ xOldPgk->registerPackage(new AbortChannel(), xCmdEnv);
+ insertToActivationLayerDB(dp_misc::getIdentifier( xOldPgk ), oldDbData);
+ }
+ throw;
+ }
+ //access to the database must be guarded. See removePackage_
+ insertToActivationLayerDB(id, dbData);
+ }
+ }
+ catch (...)
+ {
+ deletePackageFromCache( xPackage, destFolder );
+ throw;
+ }
+ if (!install)
+ {
+ deletePackageFromCache( xPackage, destFolder );
+ }
+ fireModified();
+ }
+ return xPackage;
+ }
+ catch (RuntimeException &) {
+ throw;
+ }
+ catch (CommandFailedException & exc) {
+ logIntern( Any(exc) );
+ throw;
+ }
+ catch (CommandAbortedException & exc) {
+ logIntern( Any(exc) );
+ throw;
+ }
+ catch (deployment::DeploymentException & exc) {
+ logIntern( Any(exc) );
+ throw;
+ }
+ catch (Exception &) {
+ Any exc( ::cppu::getCaughtException() );
+ logIntern( exc );
+ throw deployment::DeploymentException(
+ getResourceString(RID_STR_ERROR_WHILE_ADDING) + url,
+ static_cast<OWeakObject *>(this), exc );
+ }
+}
+void PackageManagerImpl::deletePackageFromCache(
+ Reference<deployment::XPackage> const & xPackage,
+ OUString const & destFolder)
+{
+ try_dispose( xPackage );
+
+ //we remove the package from the uno cache
+ //no service from the package may be loaded at this time!!!
+ erase_path( destFolder, Reference<XCommandEnvironment>(),
+ false /* no throw: ignore errors */ );
+ //rm last character '_'
+ OUString url = destFolder.copy(0, destFolder.getLength() - 1);
+ erase_path( url, Reference<XCommandEnvironment>(),
+ false /* no throw: ignore errors */ );
+
+}
+//______________________________________________________________________________
+void PackageManagerImpl::removePackage_(
+ OUString const & id, OUString const & fileName,
+ Reference<task::XAbortChannel> const & xAbortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv,
+ ActivePackages::Data * out_dbData)
+{
+ Reference<deployment::XPackage> xPackage;
+ {
+ try {
+ const ::osl::MutexGuard guard(getMutex());
+ xPackage = getDeployedPackage_(id, fileName, xCmdEnv );
+ m_activePackagesDB->get(out_dbData, id, fileName);
+ beans::Optional< beans::Ambiguous<sal_Bool> > option(
+ xPackage->isRegistered( Reference<task::XAbortChannel>(),
+ xCmdEnv ) );
+ if (!option.IsPresent || option.Value.IsAmbiguous || option.Value.Value)
+ xPackage->revokePackage( xAbortChannel, xCmdEnv );
+ m_activePackagesDB->erase( id, fileName ); // to be removed upon next start
+ }
+ catch (CommandAbortedException &)
+ {
+ //ToDo: interaction, so that gui can show an appropriate string
+ //reregister the package
+ //Create our own XAbortChannel, so the user cannot interrupt the registration.
+ xPackage->registerPackage(new AbortChannel(), xCmdEnv);
+ throw;
+ }
+ }
+ try_dispose( xPackage );
+}
+
+//______________________________________________________________________________
+void PackageManagerImpl::removePackage(
+ OUString const & id, ::rtl::OUString const & fileName,
+ Reference<task::XAbortChannel> const & xAbortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv_ )
+ throw (deployment::DeploymentException, CommandFailedException,
+ CommandAbortedException, lang::IllegalArgumentException,
+ RuntimeException)
+{
+ check();
+ if (m_readOnly)
+ {
+ OUString message;
+ if (m_context == OUSTR("shared"))
+ message = OUSTR("You need write permissions in order to remove a shared extension!");
+ else
+ message = OUSTR("You need write permissions in order to remove this extension!");
+ throw deployment::DeploymentException(
+ message, static_cast<OWeakObject *>(this), Any() );
+ }
+
+ Reference<XCommandEnvironment> xCmdEnv;
+ if (m_xLogFile.is())
+ xCmdEnv.set( new CmdEnvWrapperImpl( xCmdEnv_, m_xLogFile ) );
+ else
+ xCmdEnv.set( xCmdEnv_ );
+
+ try {
+ removePackage_( id, fileName, xAbortChannel, xCmdEnv, NULL);
+ fireModified();
+ }
+ catch (RuntimeException &) {
+ throw;
+ }
+ catch (lang::IllegalArgumentException &) {
+ throw;
+ }
+ catch (CommandFailedException & exc) {
+ logIntern( Any(exc) );
+ throw;
+ }
+ catch (CommandAbortedException & exc) {
+ logIntern( Any(exc) );
+ throw;
+ }
+ catch (deployment::DeploymentException & exc) {
+ logIntern( Any(exc) );
+ throw;
+ }
+ catch (Exception &) {
+ Any exc( ::cppu::getCaughtException() );
+ logIntern( exc );
+ throw deployment::DeploymentException(
+ getResourceString(RID_STR_ERROR_WHILE_REMOVING) + id,
+ static_cast<OWeakObject *>(this), exc );
+ }
+}
+
+//______________________________________________________________________________
+OUString PackageManagerImpl::getDeployPath( ActivePackages::Data const & data )
+{
+ ::rtl::OUStringBuffer buf;
+ buf.append( data.temporaryName );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("_/") );
+ buf.append( ::rtl::Uri::encode( data.fileName, rtl_UriCharClassPchar,
+ rtl_UriEncodeIgnoreEscapes,
+ RTL_TEXTENCODING_UTF8 ) );
+ return makeURL( m_activePackages, buf.makeStringAndClear() );
+}
+
+//______________________________________________________________________________
+Reference<deployment::XPackage> PackageManagerImpl::getDeployedPackage_(
+ OUString const & id, OUString const & fileName,
+ Reference<XCommandEnvironment> const & xCmdEnv )
+{
+ ActivePackages::Data val;
+ if (m_activePackagesDB->get( &val, id, fileName ))
+ {
+ return getDeployedPackage_( id, val, xCmdEnv, false );
+ }
+ throw lang::IllegalArgumentException(
+ getResourceString(RID_STR_NO_SUCH_PACKAGE) + id,
+ static_cast<OWeakObject *>(this), static_cast<sal_Int16>(-1) );
+}
+
+//______________________________________________________________________________
+Reference<deployment::XPackage> PackageManagerImpl::getDeployedPackage_(
+ OUString const & id, ActivePackages::Data const & data,
+ Reference<XCommandEnvironment> const & xCmdEnv, bool ignoreAlienPlatforms )
+{
+ if (ignoreAlienPlatforms)
+ {
+ String type, subType;
+ INetContentTypeParameterList params;
+ if (INetContentTypes::parse( data.mediaType, type, subType, &params ))
+ {
+ INetContentTypeParameter const * param = params.find(
+ ByteString("platform") );
+ if (param != 0 && !platform_fits( param->m_sValue ))
+ throw lang::IllegalArgumentException(
+ getResourceString(RID_STR_NO_SUCH_PACKAGE) + id,
+ static_cast<OWeakObject *>(this),
+ static_cast<sal_Int16>(-1) );
+ }
+ }
+ return m_xRegistry->bindPackage(
+ getDeployPath( data ), data.mediaType, xCmdEnv );
+}
+
+//______________________________________________________________________________
+Sequence< Reference<deployment::XPackage> >
+PackageManagerImpl::getDeployedPackages_(
+ Reference<XCommandEnvironment> const & xCmdEnv )
+{
+ ::std::vector< Reference<deployment::XPackage> > packages;
+ ActivePackages::Entries id2temp( m_activePackagesDB->getEntries() );
+ ActivePackages::Entries::const_iterator iPos( id2temp.begin() );
+ ActivePackages::Entries::const_iterator const iEnd( id2temp.end() );
+ for ( ; iPos != iEnd; ++iPos )
+ {
+ try {
+ packages.push_back(
+ getDeployedPackage_(
+ iPos->first, iPos->second, xCmdEnv,
+ true /* xxx todo: think of GUI:
+ ignore other platforms than the current one */ ) );
+ }
+ catch (lang::IllegalArgumentException & exc) {
+ // ignore
+ (void) exc; // avoid warnings
+ OSL_ENSURE( 0, ::rtl::OUStringToOString(
+ exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
+ }
+ catch (deployment::DeploymentException& exc) {
+ // ignore
+ (void) exc; // avoid warnings
+ OSL_ENSURE( 0, ::rtl::OUStringToOString(
+ exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
+ }
+ }
+ return comphelper::containerToSequence(packages);
+}
+
+//______________________________________________________________________________
+Reference<deployment::XPackage> PackageManagerImpl::getDeployedPackage(
+ OUString const & id, ::rtl::OUString const & fileName,
+ Reference<XCommandEnvironment> const & xCmdEnv_ )
+ throw (deployment::DeploymentException, CommandFailedException,
+ lang::IllegalArgumentException, RuntimeException)
+{
+ check();
+ Reference<XCommandEnvironment> xCmdEnv;
+ if (m_xLogFile.is())
+ xCmdEnv.set( new CmdEnvWrapperImpl( xCmdEnv_, m_xLogFile ) );
+ else
+ xCmdEnv.set( xCmdEnv_ );
+
+ try {
+ const ::osl::MutexGuard guard( getMutex() );
+ return getDeployedPackage_( id, fileName, xCmdEnv );
+ }
+ catch (RuntimeException &) {
+ throw;
+ }
+ catch (CommandFailedException & exc) {
+ logIntern( Any(exc) );
+ throw;
+ }
+ catch (lang::IllegalArgumentException & exc) {
+ logIntern( Any(exc) );
+ throw;
+ }
+ catch (deployment::DeploymentException & exc) {
+ logIntern( Any(exc) );
+ throw;
+ }
+ catch (Exception &) {
+ Any exc( ::cppu::getCaughtException() );
+ logIntern( exc );
+ throw deployment::DeploymentException(
+ // ought never occur...
+ OUSTR("error while accessing deployed package: ") + id,
+ static_cast<OWeakObject *>(this), exc );
+ }
+}
+
+//______________________________________________________________________________
+Sequence< Reference<deployment::XPackage> >
+PackageManagerImpl::getDeployedPackages(
+ Reference<task::XAbortChannel> const &,
+ Reference<XCommandEnvironment> const & xCmdEnv_ )
+ throw (deployment::DeploymentException, CommandFailedException,
+ CommandAbortedException, lang::IllegalArgumentException,
+ RuntimeException)
+{
+ check();
+ Reference<XCommandEnvironment> xCmdEnv;
+ if (m_xLogFile.is())
+ xCmdEnv.set( new CmdEnvWrapperImpl( xCmdEnv_, m_xLogFile ) );
+ else
+ xCmdEnv.set( xCmdEnv_ );
+
+ try {
+ const ::osl::MutexGuard guard( getMutex() );
+ return getDeployedPackages_( xCmdEnv );
+ }
+ catch (RuntimeException &) {
+ throw;
+ }
+ catch (CommandFailedException & exc) {
+ logIntern( Any(exc) );
+ throw;
+ }
+ catch (CommandAbortedException & exc) {
+ logIntern( Any(exc) );
+ throw;
+ }
+ catch (deployment::DeploymentException & exc) {
+ logIntern( Any(exc) );
+ throw;
+ }
+ catch (Exception &) {
+ Any exc( ::cppu::getCaughtException() );
+ logIntern( exc );
+ throw deployment::DeploymentException(
+ // ought never occur...
+ OUSTR("error while getting all deployed packages: ") + m_context,
+ static_cast<OWeakObject *>(this), exc );
+ }
+}
+
+//______________________________________________________________________________
+void PackageManagerImpl::reinstallDeployedPackages(
+ Reference<task::XAbortChannel> const & xAbortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv_ )
+ throw (deployment::DeploymentException,
+ CommandFailedException, CommandAbortedException,
+ lang::IllegalArgumentException, RuntimeException)
+{
+ check();
+ if (m_readOnly)
+ {
+ OUString message;
+ if (m_context == OUSTR("shared"))
+ message = OUSTR("You need write permissions in order to install shared extensions!");
+ else
+ message = OUSTR("You need write permissions in order to install extensions!");
+ throw deployment::DeploymentException(
+ message, static_cast<OWeakObject *>(this), Any() );
+ }
+
+ if (office_is_running())
+ throw RuntimeException(
+ OUSTR("You must close any running Office process before "
+ "reinstalling packages!"), static_cast<OWeakObject *>(this) );
+
+ Reference<XCommandEnvironment> xCmdEnv;
+ if (m_xLogFile.is())
+ xCmdEnv.set( new CmdEnvWrapperImpl( xCmdEnv_, m_xLogFile ) );
+ else
+ xCmdEnv.set( xCmdEnv_ );
+
+ try {
+ ProgressLevel progress(
+ xCmdEnv, OUSTR("Reinstalling all deployed packages...") );
+
+ try_dispose( m_xRegistry );
+ m_xRegistry.clear();
+ if (m_registryCache.getLength() > 0)
+ erase_path( m_registryCache, xCmdEnv );
+ initRegistryBackends();
+ Reference<util::XUpdatable> xUpdatable( m_xRegistry, UNO_QUERY );
+ if (xUpdatable.is())
+ xUpdatable->update();
+
+ // reregister all:
+ const ::osl::MutexGuard guard( getMutex() );
+ const Sequence< Reference<deployment::XPackage> > packages(
+ getDeployedPackages_( xCmdEnv ) );
+ for ( sal_Int32 pos = 0; pos < packages.getLength(); ++pos )
+ packages[ pos ]->registerPackage( xAbortChannel, xCmdEnv );
+ }
+ catch (RuntimeException &) {
+ throw;
+ }
+ catch (CommandFailedException & exc) {
+ logIntern( Any(exc) );
+ throw;
+ }
+ catch (CommandAbortedException & exc) {
+ logIntern( Any(exc) );
+ throw;
+ }
+ catch (deployment::DeploymentException & exc) {
+ logIntern( Any(exc) );
+ throw;
+ }
+ catch (Exception &) {
+ Any exc( ::cppu::getCaughtException() );
+ logIntern( exc );
+ throw deployment::DeploymentException(
+ OUSTR("Error while reinstalling all previously deployed "
+ "packages of context ") + m_context,
+ static_cast<OWeakObject *>(this), exc );
+ }
+}
+
+
+::sal_Bool SAL_CALL PackageManagerImpl::isReadOnly( )
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ return m_readOnly;
+}
+
+//##############################################################################
+
+//______________________________________________________________________________
+PackageManagerImpl::CmdEnvWrapperImpl::~CmdEnvWrapperImpl()
+{
+}
+
+//______________________________________________________________________________
+PackageManagerImpl::CmdEnvWrapperImpl::CmdEnvWrapperImpl(
+ Reference<XCommandEnvironment> const & xUserCmdEnv,
+ Reference<XProgressHandler> const & xLogFile )
+ : m_xLogFile( xLogFile )
+{
+ if (xUserCmdEnv.is()) {
+ m_xUserProgress.set( xUserCmdEnv->getProgressHandler() );
+ m_xUserInteractionHandler.set( xUserCmdEnv->getInteractionHandler() );
+ }
+}
+
+// XCommandEnvironment
+//______________________________________________________________________________
+Reference<task::XInteractionHandler>
+PackageManagerImpl::CmdEnvWrapperImpl::getInteractionHandler()
+ throw (RuntimeException)
+{
+ return m_xUserInteractionHandler;
+}
+
+//______________________________________________________________________________
+Reference<XProgressHandler>
+PackageManagerImpl::CmdEnvWrapperImpl::getProgressHandler()
+ throw (RuntimeException)
+{
+ return this;
+}
+
+// XProgressHandler
+//______________________________________________________________________________
+void PackageManagerImpl::CmdEnvWrapperImpl::push( Any const & Status )
+ throw (RuntimeException)
+{
+ if (m_xLogFile.is())
+ m_xLogFile->push( Status );
+ if (m_xUserProgress.is())
+ m_xUserProgress->push( Status );
+}
+
+//______________________________________________________________________________
+void PackageManagerImpl::CmdEnvWrapperImpl::update( Any const & Status )
+ throw (RuntimeException)
+{
+ if (m_xLogFile.is())
+ m_xLogFile->update( Status );
+ if (m_xUserProgress.is())
+ m_xUserProgress->update( Status );
+}
+
+//______________________________________________________________________________
+void PackageManagerImpl::CmdEnvWrapperImpl::pop() throw (RuntimeException)
+{
+ if (m_xLogFile.is())
+ m_xLogFile->pop();
+ if (m_xUserProgress.is())
+ m_xUserProgress->pop();
+}
+
+} // namespace dp_manager
+
diff --git a/desktop/source/deployment/manager/dp_manager.h b/desktop/source/deployment/manager/dp_manager.h
new file mode 100644
index 000000000000..6051eea9f757
--- /dev/null
+++ b/desktop/source/deployment/manager/dp_manager.h
@@ -0,0 +1,270 @@
+/*************************************************************************
+ *
+ * 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: dp_manager.h,v $
+ * $Revision: 1.17 $
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#if ! defined INCLUDED_DP_MANAGER_H
+#define INCLUDED_DP_MANAGER_H
+
+#include "dp_manager.hrc"
+#include "dp_misc.h"
+#include "dp_interact.h"
+#include "dp_activepackages.hxx"
+#include "rtl/ref.hxx"
+#include "cppuhelper/compbase1.hxx"
+#include "cppuhelper/implbase2.hxx"
+#include "ucbhelper/content.hxx"
+#include "com/sun/star/deployment/XPackageRegistry.hpp"
+#include "com/sun/star/deployment/XPackageManager.hpp"
+#include <memory>
+
+
+namespace css = ::com::sun::star;
+
+namespace dp_manager {
+
+typedef ::cppu::WeakComponentImplHelper1<
+ css::deployment::XPackageManager > t_pm_helper;
+
+//==============================================================================
+class PackageManagerImpl : private ::dp_misc::MutexHolder, public t_pm_helper
+{
+ css::uno::Reference<css::uno::XComponentContext> m_xComponentContext;
+ ::rtl::OUString m_context;
+ ::rtl::OUString m_registryCache;
+ bool m_readOnly;
+
+ ::rtl::OUString m_activePackages;
+ ::rtl::OUString m_activePackages_expanded;
+ ::std::auto_ptr< ActivePackages > m_activePackagesDB;
+ //This mutex is only used for synchronization in addPackage
+ ::osl::Mutex m_addMutex;
+ css::uno::Reference<css::ucb::XProgressHandler> m_xLogFile;
+ inline void logIntern( css::uno::Any const & status );
+ void fireModified();
+
+ css::uno::Reference<css::deployment::XPackageRegistry> m_xRegistry;
+
+ void initRegistryBackends();
+ void initActivationLayer(
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv );
+ ::rtl::OUString detectMediaType(
+ ::ucbhelper::Content const & ucbContent, bool throw_exc = true );
+ ::rtl::OUString insertToActivationLayer(
+ ::rtl::OUString const & mediaType,
+ ::ucbhelper::Content const & sourceContent,
+ ::rtl::OUString const & title, ActivePackages::Data * dbData );
+ void insertToActivationLayerDB(
+ ::rtl::OUString const & id, ActivePackages::Data const & dbData );
+
+ void deletePackageFromCache(
+ css::uno::Reference<css::deployment::XPackage> const & xPackage,
+ ::rtl::OUString const & destFolder );
+
+ bool checkUpdate(
+ css::uno::Reference<css::deployment::XPackage> const & package,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & origCmdEnv,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const &
+ wrappedCmdEnv );
+
+ bool checkInstall(
+ css::uno::Reference<css::deployment::XPackage> const & package,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & cmdEnv);
+
+
+ class CmdEnvWrapperImpl
+ : public ::cppu::WeakImplHelper2< css::ucb::XCommandEnvironment,
+ css::ucb::XProgressHandler >
+ {
+ css::uno::Reference<css::ucb::XProgressHandler> m_xLogFile;
+ css::uno::Reference<css::ucb::XProgressHandler> m_xUserProgress;
+ css::uno::Reference<css::task::XInteractionHandler>
+ m_xUserInteractionHandler;
+
+ public:
+ virtual ~CmdEnvWrapperImpl();
+ CmdEnvWrapperImpl(
+ css::uno::Reference<css::ucb::XCommandEnvironment>
+ const & xUserCmdEnv,
+ css::uno::Reference<css::ucb::XProgressHandler> const & xLogFile );
+
+ // XCommandEnvironment
+ virtual css::uno::Reference<css::task::XInteractionHandler> SAL_CALL
+ getInteractionHandler() throw (css::uno::RuntimeException);
+ virtual css::uno::Reference<css::ucb::XProgressHandler> SAL_CALL
+ getProgressHandler() throw (css::uno::RuntimeException);
+
+ // XProgressHandler
+ virtual void SAL_CALL push( css::uno::Any const & Status )
+ throw (css::uno::RuntimeException);
+ virtual void SAL_CALL update( css::uno::Any const & Status )
+ throw (css::uno::RuntimeException);
+ virtual void SAL_CALL pop() throw (css::uno::RuntimeException);
+ };
+
+protected:
+ inline void check();
+ virtual void SAL_CALL disposing();
+
+ virtual ~PackageManagerImpl();
+ inline PackageManagerImpl(
+ css::uno::Reference<css::uno::XComponentContext>
+ const & xComponentContext, ::rtl::OUString const & context )
+ : t_pm_helper( getMutex() ),
+ m_xComponentContext( xComponentContext ),
+ m_context( context ),
+ m_readOnly( false )
+ {}
+
+public:
+ static css::uno::Reference<css::deployment::XPackageManager> create(
+ css::uno::Reference<css::uno::XComponentContext>
+ const & xComponentContext, ::rtl::OUString const & context );
+
+ // XComponent
+ virtual void SAL_CALL dispose() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL addEventListener(
+ css::uno::Reference<css::lang::XEventListener> const & xListener )
+ throw (css::uno::RuntimeException);
+ virtual void SAL_CALL removeEventListener(
+ css::uno::Reference<css::lang::XEventListener> const & xListener )
+ throw (css::uno::RuntimeException);
+
+ // XModifyBroadcaster
+ virtual void SAL_CALL addModifyListener(
+ css::uno::Reference<css::util::XModifyListener> const & xListener )
+ throw (css::uno::RuntimeException);
+ virtual void SAL_CALL removeModifyListener(
+ css::uno::Reference<css::util::XModifyListener> const & xListener )
+ throw (css::uno::RuntimeException);
+
+ // XPackageManager
+ virtual ::rtl::OUString SAL_CALL getContext()
+ throw (css::uno::RuntimeException);
+ virtual css::uno::Sequence<
+ css::uno::Reference<css::deployment::XPackageTypeInfo> > SAL_CALL
+ getSupportedPackageTypes() throw (css::uno::RuntimeException);
+
+ virtual css::uno::Reference<css::task::XAbortChannel> SAL_CALL
+ createAbortChannel() throw (css::uno::RuntimeException);
+
+ virtual css::uno::Reference<css::deployment::XPackage> SAL_CALL addPackage(
+ ::rtl::OUString const & url, ::rtl::OUString const & mediaType,
+ css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (css::deployment::DeploymentException,
+ css::ucb::CommandFailedException,
+ css::ucb::CommandAbortedException,
+ css::lang::IllegalArgumentException,
+ css::uno::RuntimeException);
+
+ /* Unregisters the package but does not remove it from disk.
+ When the operation is canceled by the user, a CommandAbortedException
+ is thrown. Then the package is still fully functional.
+ @param out_oldData
+ can be NULL
+ */
+ void removePackage_(
+ ::rtl::OUString const & id, ::rtl::OUString const & fileName,
+ css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv,
+ ActivePackages::Data * out_oldData);
+
+ virtual void SAL_CALL removePackage(
+ ::rtl::OUString const & id, ::rtl::OUString const & fileName,
+ css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (css::deployment::DeploymentException,
+ css::ucb::CommandFailedException,
+ css::ucb::CommandAbortedException,
+ css::lang::IllegalArgumentException,
+ css::uno::RuntimeException);
+
+ ::rtl::OUString getDeployPath( ActivePackages::Data const & data );
+ css::uno::Reference<css::deployment::XPackage> SAL_CALL getDeployedPackage_(
+ ::rtl::OUString const & id, ::rtl::OUString const & fileName,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv );
+ css::uno::Reference<css::deployment::XPackage> getDeployedPackage_(
+ ::rtl::OUString const & id, ActivePackages::Data const & data,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv,
+ bool ignoreAlienPlatforms = false );
+ virtual css::uno::Reference<css::deployment::XPackage> SAL_CALL
+ getDeployedPackage(
+ ::rtl::OUString const & id, ::rtl::OUString const & fileName,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (css::deployment::DeploymentException,
+ css::ucb::CommandFailedException,
+ css::lang::IllegalArgumentException, css::uno::RuntimeException);
+
+ css::uno::Sequence< css::uno::Reference<css::deployment::XPackage> >
+ getDeployedPackages_(
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv );
+ virtual css::uno::Sequence< css::uno::Reference<css::deployment::XPackage> >
+ SAL_CALL getDeployedPackages(
+ css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (css::deployment::DeploymentException,
+ css::ucb::CommandFailedException,
+ css::ucb::CommandAbortedException,
+ css::lang::IllegalArgumentException,
+ css::uno::RuntimeException);
+
+ virtual void SAL_CALL reinstallDeployedPackages(
+ css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (css::deployment::DeploymentException,
+ css::ucb::CommandFailedException,
+ css::ucb::CommandAbortedException,
+ css::lang::IllegalArgumentException,
+ css::uno::RuntimeException);
+
+ virtual ::sal_Bool SAL_CALL isReadOnly( )
+ throw (::com::sun::star::uno::RuntimeException);
+};
+
+//______________________________________________________________________________
+inline void PackageManagerImpl::check()
+{
+ ::osl::MutexGuard guard( getMutex() );
+ if (rBHelper.bInDispose || rBHelper.bDisposed)
+ throw css::lang::DisposedException(
+ OUSTR("PackageManager instance has already been disposed!"),
+ static_cast< ::cppu::OWeakObject * >(this) );
+}
+
+//______________________________________________________________________________
+inline void PackageManagerImpl::logIntern( css::uno::Any const & status )
+{
+ if (m_xLogFile.is())
+ m_xLogFile->update( status );
+}
+
+}
+
+#endif
+
diff --git a/desktop/source/deployment/manager/dp_manager.hrc b/desktop/source/deployment/manager/dp_manager.hrc
new file mode 100644
index 000000000000..fc5ddf95fc50
--- /dev/null
+++ b/desktop/source/deployment/manager/dp_manager.hrc
@@ -0,0 +1,42 @@
+/*************************************************************************
+ *
+ * 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: dp_manager.hrc,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.
+ *
+ ************************************************************************/
+
+#if ! defined INCLUDED_DP_MANAGER_HRC
+#define INCLUDED_DP_MANAGER_HRC
+
+#include "deployment.hrc"
+
+#define RID_STR_ERROR_WHILE_ADDING (RID_DEPLOYMENT_MANAGER_START+0)
+#define RID_STR_ERROR_WHILE_REMOVING (RID_DEPLOYMENT_MANAGER_START+1)
+#define RID_STR_PACKAGE_ALREADY_ADDED (RID_DEPLOYMENT_MANAGER_START+2)
+#define RID_STR_COPYING_PACKAGE (RID_DEPLOYMENT_MANAGER_START+3)
+#define RID_STR_NO_SUCH_PACKAGE (RID_DEPLOYMENT_MANAGER_START+4)
+
+#endif
diff --git a/desktop/source/deployment/manager/dp_manager.src b/desktop/source/deployment/manager/dp_manager.src
new file mode 100644
index 000000000000..34a8bfa3ac5e
--- /dev/null
+++ b/desktop/source/deployment/manager/dp_manager.src
@@ -0,0 +1,58 @@
+/*************************************************************************
+ *
+ * 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: dp_manager.src,v $
+ * $Revision: 1.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 "dp_manager.hrc"
+
+
+String RID_STR_COPYING_PACKAGE
+{
+ Text [ en-US ] = "Copying: ";
+};
+
+String RID_STR_ERROR_WHILE_ADDING
+{
+ Text [ en-US ] = "Error while adding: ";
+};
+
+String RID_STR_ERROR_WHILE_REMOVING
+{
+ Text [ en-US ] = "Error while removing: ";
+};
+
+String RID_STR_PACKAGE_ALREADY_ADDED
+{
+ Text [ en-US ] = "Extension has already been added: ";
+};
+
+String RID_STR_NO_SUCH_PACKAGE
+{
+ Text [ en-US ] = "There is no such extension deployed: ";
+};
+
diff --git a/desktop/source/deployment/manager/dp_managerfac.cxx b/desktop/source/deployment/manager/dp_managerfac.cxx
new file mode 100644
index 000000000000..a96284d2ff1a
--- /dev/null
+++ b/desktop/source/deployment/manager/dp_managerfac.cxx
@@ -0,0 +1,199 @@
+/*************************************************************************
+ *
+ * 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: dp_managerfac.cxx,v $
+ * $Revision: 1.10 $
+ *
+ * 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_desktop.hxx"
+
+#include "dp_manager.h"
+#include "dp_resource.h"
+#include "cppuhelper/compbase1.hxx"
+#include "comphelper/servicedecl.hxx"
+#include "com/sun/star/deployment/thePackageManagerFactory.hpp"
+
+
+using namespace ::dp_misc;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using ::rtl::OUString;
+
+namespace dp_manager {
+namespace factory {
+
+typedef ::cppu::WeakComponentImplHelper1<
+ deployment::XPackageManagerFactory > t_pmfac_helper;
+
+//==============================================================================
+class PackageManagerFactoryImpl : private MutexHolder, public t_pmfac_helper
+{
+ Reference<XComponentContext> m_xComponentContext;
+
+ Reference<deployment::XPackageManager> m_xUserMgr;
+ Reference<deployment::XPackageManager> m_xSharedMgr;
+ typedef ::std::hash_map<
+ OUString, WeakReference<deployment::XPackageManager>,
+ ::rtl::OUStringHash > t_string2weakref;
+ t_string2weakref m_managers;
+
+protected:
+ inline void check();
+ virtual void SAL_CALL disposing();
+
+public:
+ virtual ~PackageManagerFactoryImpl();
+ PackageManagerFactoryImpl(
+ Reference<XComponentContext> const & xComponentContext );
+
+ // XPackageManagerFactory
+ virtual Reference<deployment::XPackageManager> SAL_CALL getPackageManager(
+ OUString const & context ) throw (RuntimeException);
+};
+
+//==============================================================================
+namespace sdecl = comphelper::service_decl;
+sdecl::class_<PackageManagerFactoryImpl> servicePMFI;
+extern sdecl::ServiceDecl const serviceDecl(
+ servicePMFI,
+ // a private one:
+ "com.sun.star.comp.deployment.PackageManagerFactory",
+ "com.sun.star.comp.deployment.PackageManagerFactory" );
+
+//==============================================================================
+bool singleton_entries(
+ Reference<registry::XRegistryKey> const & xRegistryKey )
+{
+ try {
+ Reference<registry::XRegistryKey> xKey(
+ xRegistryKey->createKey(
+ serviceDecl.getImplementationName() +
+ // xxx todo: use future generated function to get singleton name
+ OUSTR("/UNO/SINGLETONS/"
+ "com.sun.star.deployment.thePackageManagerFactory") ) );
+ xKey->setStringValue( serviceDecl.getSupportedServiceNames()[0] );
+ return true;
+ }
+ catch (registry::InvalidRegistryException & exc) {
+ (void) exc; // avoid warnings
+ OSL_ENSURE( 0, ::rtl::OUStringToOString(
+ exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
+ return false;
+ }
+}
+
+//______________________________________________________________________________
+PackageManagerFactoryImpl::PackageManagerFactoryImpl(
+ Reference<XComponentContext> const & xComponentContext )
+ : t_pmfac_helper( getMutex() ),
+ m_xComponentContext( xComponentContext )
+{
+}
+
+//______________________________________________________________________________
+PackageManagerFactoryImpl::~PackageManagerFactoryImpl()
+{
+}
+
+//______________________________________________________________________________
+inline void PackageManagerFactoryImpl::check()
+{
+ ::osl::MutexGuard guard( getMutex() );
+ if (rBHelper.bInDispose || rBHelper.bDisposed)
+ {
+ throw lang::DisposedException(
+ OUSTR("PackageManagerFactory instance has already been disposed!"),
+ static_cast<OWeakObject *>(this) );
+ }
+}
+
+//______________________________________________________________________________
+void PackageManagerFactoryImpl::disposing()
+{
+ // dispose all managers:
+ ::osl::MutexGuard guard( getMutex() );
+ t_string2weakref::const_iterator iPos( m_managers.begin() );
+ t_string2weakref::const_iterator const iEnd( m_managers.end() );
+ for ( ; iPos != iEnd; ++iPos )
+ try_dispose( iPos->second );
+ m_managers = t_string2weakref();
+ // the below are already disposed:
+ m_xUserMgr.clear();
+ m_xSharedMgr.clear();
+}
+
+// XPackageManagerFactory
+//______________________________________________________________________________
+Reference<deployment::XPackageManager>
+PackageManagerFactoryImpl::getPackageManager( OUString const & context )
+ throw (RuntimeException)
+{
+ Reference< deployment::XPackageManager > xRet;
+ ::osl::ResettableMutexGuard guard( getMutex() );
+ check();
+ t_string2weakref::const_iterator const iFind( m_managers.find( context ) );
+ if (iFind != m_managers.end()) {
+ xRet = iFind->second;
+ if (xRet.is())
+ return xRet;
+ }
+
+ guard.clear();
+ xRet.set( PackageManagerImpl::create( m_xComponentContext, context ) );
+ guard.reset();
+ ::std::pair< t_string2weakref::iterator, bool > insertion(
+ m_managers.insert( t_string2weakref::value_type( context, xRet ) ) );
+ if (insertion.second)
+ {
+ OSL_ASSERT( insertion.first->second.get() == xRet );
+ // hold user, shared mgrs for whole process: live deployment
+ if (context.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("user") ))
+ m_xUserMgr = xRet;
+ else if (context.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("shared") ))
+ m_xSharedMgr = xRet;
+ }
+ else
+ {
+ Reference< deployment::XPackageManager > xAlreadyIn(
+ insertion.first->second );
+ if (xAlreadyIn.is())
+ {
+ guard.clear();
+ try_dispose( xRet );
+ xRet = xAlreadyIn;
+ }
+ else
+ {
+ insertion.first->second = xRet;
+ }
+ }
+ return xRet;
+}
+
+} // namespace factory
+} // namespace dp_manager
+
diff --git a/desktop/source/deployment/manager/makefile.mk b/desktop/source/deployment/manager/makefile.mk
new file mode 100644
index 000000000000..6e4c282b3573
--- /dev/null
+++ b/desktop/source/deployment/manager/makefile.mk
@@ -0,0 +1,56 @@
+#*************************************************************************
+#
+# 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.10 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ = ..$/..$/..
+
+PRJNAME = desktop
+TARGET = deployment_manager
+ENABLE_EXCEPTIONS = TRUE
+
+.INCLUDE : settings.mk
+
+.IF "$(SYSTEM_DB)" == "YES"
+CFLAGS+=-DSYSTEM_DB -I$(DB_INCLUDES)
+.ENDIF
+
+SRS1NAME = $(TARGET)
+SRC1FILES = \
+ dp_manager.src
+
+SLOFILES = \
+ $(SLO)$/dp_activepackages.obj \
+ $(SLO)$/dp_manager.obj \
+ $(SLO)$/dp_managerfac.obj \
+ $(SLO)$/dp_informationprovider.obj
+
+.INCLUDE : ..$/target.pmk
+.INCLUDE : target.mk
+
diff --git a/desktop/source/deployment/migration/dp_migration.cxx b/desktop/source/deployment/migration/dp_migration.cxx
new file mode 100644
index 000000000000..c09abd5e89cb
--- /dev/null
+++ b/desktop/source/deployment/migration/dp_migration.cxx
@@ -0,0 +1,254 @@
+/*************************************************************************
+ *
+ * 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: dp_migration.cxx,v $
+ * $Revision: 1.10 $
+ *
+ * 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_desktop.hxx"
+
+#include "dp_misc.h"
+#include "dp_ucb.h"
+#include "cppuhelper/implbase1.hxx"
+#include "cppuhelper/implbase2.hxx"
+#include "cppuhelper/exc_hlp.hxx"
+#include "ucbhelper/content.hxx"
+#include "comphelper/anytostring.hxx"
+#include "comphelper/servicedecl.hxx"
+#include "com/sun/star/lang/WrappedTargetException.hpp"
+#include "com/sun/star/task/XJob.hpp"
+#include "com/sun/star/task/XInteractionAbort.hpp"
+#include "com/sun/star/task/XInteractionApprove.hpp"
+#include "com/sun/star/sdbc/XResultSet.hpp"
+#include "com/sun/star/sdbc/XRow.hpp"
+#include "com/sun/star/ucb/XContentAccess.hpp"
+#include "com/sun/star/deployment/thePackageManagerFactory.hpp"
+
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::ucb;
+using namespace ::com::sun::star::uno;
+using namespace ::dp_misc;
+using ::rtl::OUString;
+
+namespace dp_migration {
+
+class MigrationImpl : public ::cppu::WeakImplHelper1<task::XJob>
+{
+ struct CommandEnvironmentImpl
+ : public ::cppu::WeakImplHelper2< XCommandEnvironment,
+ task::XInteractionHandler >
+ {
+ // XCommandEnvironment
+ virtual Reference<task::XInteractionHandler> SAL_CALL
+ getInteractionHandler() throw (RuntimeException);
+ virtual Reference<XProgressHandler> SAL_CALL getProgressHandler()
+ throw (RuntimeException);
+ // XInteractionHandler
+ virtual void SAL_CALL handle(
+ Reference<task::XInteractionRequest> const & xRequest )
+ throw (RuntimeException);
+ };
+
+ const Reference<XComponentContext> m_xContext;
+ OUString m_userData;
+
+protected:
+ virtual ~MigrationImpl();
+public:
+ MigrationImpl( Sequence<Any> const & args,
+ Reference<XComponentContext> const & xComponentContext );
+
+ // XJob
+ virtual Any SAL_CALL execute( Sequence<beans::NamedValue> const & args )
+ throw (lang::IllegalArgumentException, Exception, RuntimeException);
+};
+
+MigrationImpl::~MigrationImpl()
+{
+}
+
+MigrationImpl::MigrationImpl(
+ Sequence<Any> const & args, Reference<XComponentContext> const & xContext )
+ : m_xContext(xContext)
+{
+ for ( sal_Int32 pos = args.getLength(); pos--; )
+ {
+ const beans::NamedValue nv(args[pos].get<beans::NamedValue>());
+ if (nv.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("UserData") ))
+ m_userData = nv.Value.get<OUString>();
+ }
+ if (m_userData.getLength() == 0)
+ throw lang::IllegalArgumentException( OUSTR("missing UserData!"), 0,
+ static_cast<sal_Int16>(-1) );
+}
+
+// XJob
+Any MigrationImpl::execute( Sequence<beans::NamedValue> const & )
+ throw (lang::IllegalArgumentException, Exception, RuntimeException)
+{
+ const Reference<deployment::XPackageManager> xManager(
+ deployment::thePackageManagerFactory::get(
+ m_xContext )->getPackageManager( OUSTR("user") ) );
+ ::ucbhelper::Content packagesDir;
+ if (create_ucb_content( &packagesDir,
+ makeURL( m_userData, OUSTR("user/uno_packages") ),
+ Reference<XCommandEnvironment>(),
+ false /* no throw */ ))
+ {
+ const Reference<XCommandEnvironment> xCmdEnv(
+ new CommandEnvironmentImpl );
+ OUString const & strTitle = StrTitle::get();
+ const Reference<sdbc::XResultSet> xResultSet(
+ packagesDir.createCursor( Sequence<OUString>( &strTitle, 1 ),
+ ::ucbhelper::INCLUDE_DOCUMENTS_ONLY ) );
+ while (xResultSet->next())
+ {
+ Reference<sdbc::XRow> xRow( xResultSet, UNO_QUERY_THROW );
+ const OUString title( xRow->getString( 1 /* Title */ ) );
+ // exclude stampIt, not migratable to OOo 2.0:
+ if (title.matchIgnoreAsciiCaseAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("SSICONCT.") ))
+ continue;
+ const OUString sourceURL( Reference<XContentAccess>(
+ xResultSet, UNO_QUERY_THROW )
+ ->queryContentIdentifierString() );
+ try {
+ xManager->addPackage(
+ sourceURL, OUString() /* detect media-type */,
+ Reference<task::XAbortChannel>(), xCmdEnv );
+ }
+ catch (RuntimeException &) {
+ throw;
+ }
+ catch (Exception &) {
+ OSL_ENSURE( 0, ::rtl::OUStringToOString(
+ ::comphelper::anyToString(
+ ::cppu::getCaughtException() ),
+ RTL_TEXTENCODING_UTF8 ).getStr() );
+ }
+ }
+ }
+ return Any();
+}
+
+// XCommandEnvironment
+Reference<task::XInteractionHandler>
+MigrationImpl::CommandEnvironmentImpl::getInteractionHandler()
+ throw (RuntimeException)
+{
+ return this;
+}
+
+Reference<XProgressHandler>
+MigrationImpl::CommandEnvironmentImpl::getProgressHandler()
+ throw (RuntimeException)
+{
+ return Reference<XProgressHandler>();
+}
+
+// XInteractionHandler
+void MigrationImpl::CommandEnvironmentImpl::handle(
+ Reference<task::XInteractionRequest> const & xRequest )
+ throw (RuntimeException)
+{
+ Any request( xRequest->getRequest() );
+ OSL_ASSERT( request.getValueTypeClass() == TypeClass_EXCEPTION );
+#if OSL_DEBUG_LEVEL > 1
+ OSL_TRACE( "[dp_migration.cxx] incoming request:\n%s\n",
+ ::rtl::OUStringToOString( ::comphelper::anyToString(request),
+ RTL_TEXTENCODING_UTF8 ).getStr() );
+#endif
+
+ // selections:
+ bool approve = false;
+ bool abort = false;
+
+ lang::WrappedTargetException wtExc;
+ if (request >>= wtExc) {
+ OSL_ENSURE( 0, ::rtl::OUStringToOString(
+ ::comphelper::anyToString(wtExc.TargetException),
+ RTL_TEXTENCODING_UTF8 ).getStr() );
+
+ // ignore intermediate errors of legacy packages, i.e.
+ // former pkgchk behaviour:
+ const Reference<deployment::XPackage> xPackage(
+ wtExc.Context, UNO_QUERY );
+ OSL_ASSERT( xPackage.is() );
+ if (xPackage.is()) {
+ const Reference<deployment::XPackageTypeInfo> xPackageType(
+ xPackage->getPackageType() );
+ OSL_ASSERT( xPackageType.is() );
+ if (xPackageType.is()) {
+ approve = (xPackage->isBundle() &&
+ xPackageType->getMediaType().matchAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(
+ "application/"
+ "vnd.sun.star.legacy-package-bundle") ));
+ }
+ }
+ abort = !approve;
+ }
+ else
+ return; // unknown request => no selection at all
+
+ // select:
+ const Sequence< Reference<task::XInteractionContinuation> > conts(
+ xRequest->getContinuations() );
+ for ( sal_Int32 pos = 0; pos < conts.getLength(); ++pos )
+ {
+ if (approve) {
+ const Reference<task::XInteractionApprove> xInteractionApprove(
+ conts[ pos ], UNO_QUERY );
+ if (xInteractionApprove.is()) {
+ xInteractionApprove->select();
+ // don't query again for ongoing continuations:
+ approve = false;
+ }
+ }
+ else if (abort) {
+ const Reference<task::XInteractionAbort> xInteractionAbort(
+ conts[ pos ], UNO_QUERY );
+ if (xInteractionAbort.is()) {
+ xInteractionAbort->select();
+ // don't query again for ongoing continuations:
+ abort = false;
+ }
+ }
+ }
+}
+
+namespace sdecl = comphelper::service_decl;
+sdecl::class_<MigrationImpl, sdecl::with_args<true> > serviceMI;
+extern sdecl::ServiceDecl const serviceDecl(
+ serviceMI,
+ // a private one (config entry):
+ "com.sun.star.comp.deployment.migration.Migration_2_0",
+ "com.sun.star.comp.deployment.migration.Migration_2_0" );
+
+} // namespace dp_migration
+
diff --git a/desktop/source/deployment/migration/makefile.mk b/desktop/source/deployment/migration/makefile.mk
new file mode 100644
index 000000000000..8eaccc68cd8b
--- /dev/null
+++ b/desktop/source/deployment/migration/makefile.mk
@@ -0,0 +1,45 @@
+#*************************************************************************
+#
+# 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.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 = ..$/..$/..
+
+PRJNAME = desktop
+TARGET = deployment_migration
+ENABLE_EXCEPTIONS = TRUE
+
+.INCLUDE : settings.mk
+
+SLOFILES = \
+ $(SLO)$/dp_migration.obj
+
+.INCLUDE : ..$/target.pmk
+.INCLUDE : target.mk
+
diff --git a/desktop/source/deployment/misc/db.cxx b/desktop/source/deployment/misc/db.cxx
new file mode 100644
index 000000000000..c51c0bcadc8c
--- /dev/null
+++ b/desktop/source/deployment/misc/db.cxx
@@ -0,0 +1,275 @@
+/*************************************************************************
+ *
+ * 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: db.cxx,v $
+ * $Revision: 1.6 $
+ *
+ * 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_desktop.hxx"
+
+#include <db.hxx>
+
+#include <rtl/alloc.h>
+#include <cstring>
+#include <errno.h>
+
+namespace berkeleydbproxy {
+
+//----------------------------------------------------------------------------
+ namespace db_internal
+ {
+ static void raise_error(int dberr, const char * where);
+
+ static inline int check_error(int dberr, const char * where)
+ {
+ if (dberr) raise_error(dberr,where);
+ return dberr;
+ }
+ }
+
+//----------------------------------------------------------------------------
+
+char *DbEnv::strerror(int error) {
+ return (db_strerror(error));
+}
+
+//----------------------------------------------------------------------------
+
+Db::Db(DbEnv* pDbenv,u_int32_t flags)
+: m_pDBP(0)
+{
+ db_internal::check_error( db_create(&m_pDBP,pDbenv ? pDbenv->m_pDBENV:0,flags),"Db::Db" );
+}
+
+
+Db::~Db()
+{
+ if (m_pDBP)
+ {
+ // should not happen
+ // TODO: add assert
+ }
+
+}
+
+
+int Db::close(u_int32_t flags)
+{
+ int error = m_pDBP->close(m_pDBP,flags);
+ m_pDBP = 0;
+ return db_internal::check_error(error,"Db::close");
+}
+
+int Db::open(DB_TXN *txnid,
+ const char *file,
+ const char *database,
+ DBTYPE type,
+ u_int32_t flags,
+ int mode)
+{
+ int err = m_pDBP->open(m_pDBP,txnid,file,database,type,flags,mode);
+ return db_internal::check_error( err,"Db::open" );
+}
+
+
+int Db::get(DB_TXN *txnid, Dbt *key, Dbt *data, u_int32_t flags)
+{
+ int err = m_pDBP->get(m_pDBP,txnid,key,data,flags);
+
+ // these are non-exceptional outcomes
+ if (err != DB_NOTFOUND && err != DB_KEYEMPTY)
+ db_internal::check_error( err,"Db::get" );
+
+ return err;
+}
+
+int Db::put(DB_TXN* txnid, Dbt *key, Dbt *data, u_int32_t flags)
+{
+ int err = m_pDBP->put(m_pDBP,txnid,key,data,flags);
+
+ if (err != DB_KEYEXIST) // this is a non-exceptional outcome
+ db_internal::check_error( err,"Db::put" );
+ return err;
+}
+
+int Db::cursor(DB_TXN *txnid, Dbc **cursorp, u_int32_t flags)
+{
+ DBC * dbc = 0;
+ int error = m_pDBP->cursor(m_pDBP,txnid,&dbc,flags);
+
+ if (!db_internal::check_error(error,"Db::cursor"))
+ *cursorp = new Dbc(dbc);
+
+ return error;
+}
+
+
+#define DB_INCOMPLETE (-30999)/* Sync didn't finish. */
+
+int Db::sync(u_int32_t flags)
+{
+ int err;
+ DB *db = m_pDBP;
+
+ if (!db) {
+ db_internal::check_error(EINVAL,"Db::sync");
+ return (EINVAL);
+ }
+ if ((err = db->sync(db, flags)) != 0 && err != DB_INCOMPLETE) {
+ db_internal::check_error(err, "Db::sync");
+ return (err);
+ }
+ return (err);
+}
+
+int Db::del(Dbt *key, u_int32_t flags)
+{
+ DB *db = m_pDBP;
+ int err;
+
+ if ((err = db->del(db, 0, key, flags)) != 0) {
+ // DB_NOTFOUND is a "normal" return, so should not be
+ // thrown as an error
+ //
+ if (err != DB_NOTFOUND) {
+ db_internal::check_error(err, "Db::del");
+ return (err);
+ }
+ }
+ return (err);
+}
+
+//----------------------------------------------------------------------------
+
+Dbc::Dbc(DBC * dbc)
+: m_pDBC(dbc)
+{
+}
+
+Dbc::~Dbc()
+{
+}
+
+int Dbc::close()
+{
+ int err = m_pDBC->c_close(m_pDBC);
+ delete this;
+ return db_internal::check_error( err,"Dbcursor::close" );
+}
+
+int Dbc::get(Dbt *key, Dbt *data, u_int32_t flags)
+{
+ int err = m_pDBC->c_get(m_pDBC,key,data,flags);
+
+ // these are non-exceptional outcomes
+ if (err != DB_NOTFOUND && err != DB_KEYEMPTY)
+ db_internal::check_error( err, "Dbcursor::get" );
+
+ return err;
+}
+
+//----------------------------------------------------------------------------
+
+Dbt::Dbt()
+{
+ using namespace std;
+ DBT * thispod = this;
+ memset(thispod, 0, sizeof *thispod);
+}
+
+
+Dbt::Dbt(void *data_arg, u_int32_t size_arg)
+{
+ using namespace std;
+ DBT * thispod = this;
+ memset(thispod, 0, sizeof *thispod);
+ this->set_data(data_arg);
+ this->set_size(size_arg);
+}
+
+Dbt::Dbt(const Dbt & other)
+{
+ using namespace std;
+ const DBT *otherpod = &other;
+ DBT *thispod = this;
+ memcpy(thispod, otherpod, sizeof *thispod);
+}
+
+Dbt& Dbt::operator = (const Dbt & other)
+{
+ if (this != &other)
+ {
+ using namespace std;
+ const DBT *otherpod = &other;
+ DBT *thispod = this;
+ memcpy(thispod, otherpod, sizeof *thispod);
+ }
+ return *this;
+}
+
+Dbt::~Dbt()
+{
+}
+
+void * Dbt::get_data() const
+{
+ return this->data;
+}
+
+void Dbt::set_data(void *value)
+{
+ this->data = value;
+}
+
+u_int32_t Dbt::get_size() const
+{
+ return this->size;
+}
+
+void Dbt::set_size(u_int32_t value)
+{
+ this->size = value;
+}
+
+//----------------------------------------------------------------------------
+void db_internal::raise_error(int dberr, const char * where)
+{
+ if (!where) where = "<unknown>";
+
+ const char * dberrmsg = db_strerror(dberr);
+ if (!dberrmsg || !*dberrmsg) dberrmsg = "<unknown DB error>";
+
+ rtl::OString msg = where;
+ msg += ": ";
+ msg += dberrmsg;
+
+ throw DbException(msg);
+}
+
+//----------------------------------------------------------------------------
+} // namespace ecomp
+
diff --git a/desktop/source/deployment/misc/dp_dependencies.cxx b/desktop/source/deployment/misc/dp_dependencies.cxx
new file mode 100644
index 000000000000..6ddadcf7c24a
--- /dev/null
+++ b/desktop/source/deployment/misc/dp_dependencies.cxx
@@ -0,0 +1,181 @@
+/*************************************************************************
+ *
+ * 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
+ *
+ * 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_desktop.hxx"
+
+#include "sal/config.h"
+
+#include "com/sun/star/uno/Reference.hxx"
+#include "com/sun/star/uno/Sequence.hxx"
+#include "com/sun/star/xml/dom/XElement.hpp"
+#include "com/sun/star/xml/dom/XNode.hpp"
+#include "com/sun/star/xml/dom/XNodeList.hpp"
+#include "rtl/bootstrap.hxx"
+#include "rtl/string.h"
+#include "rtl/ustring.h"
+#include "rtl/ustring.hxx"
+#include "sal/types.h"
+#include "tools/string.hxx"
+
+#include "deployment.hrc"
+#include "dp_resource.h"
+
+#include "dp_dependencies.hxx"
+#include "dp_descriptioninfoset.hxx"
+#include "dp_version.hxx"
+
+namespace {
+
+namespace css = ::com::sun::star;
+
+static char const xmlNamespace[] =
+ "http://openoffice.org/extensions/description/2006";
+
+::dp_misc::Order compareWithVersion(::rtl::OUString const & version) {
+ ::rtl::OUString v(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "${$OOO_BASE_DIR/program/" SAL_CONFIGFILE("version")
+ ":Version:OOOPackageVersion}"));
+ ::rtl::Bootstrap::expandMacros(v);
+ return ::dp_misc::compareVersions(v, version);
+}
+
+bool satisfiesMinimalVersion(::rtl::OUString const & version) {
+ return compareWithVersion(version) != ::dp_misc::LESS;
+}
+
+}
+
+namespace dp_misc {
+
+namespace Dependencies {
+
+css::uno::Sequence< css::uno::Reference< css::xml::dom::XElement > >
+check(::dp_misc::DescriptionInfoset const & infoset) {
+ css::uno::Reference< css::xml::dom::XNodeList > deps(
+ infoset.getDependencies());
+ ::sal_Int32 n = deps->getLength();
+ css::uno::Sequence< css::uno::Reference< css::xml::dom::XElement > >
+ unsatisfied(n);
+ ::sal_Int32 unsat = 0;
+ for (::sal_Int32 i = 0; i < n; ++i) {
+ static char const minimalVersion[] = "OpenOffice.org-minimal-version";
+ css::uno::Reference< css::xml::dom::XElement > e(
+ deps->item(i), css::uno::UNO_QUERY_THROW);
+ bool sat = false;
+ if (e->getNamespaceURI().equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(xmlNamespace))
+ && e->getTagName().equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(minimalVersion)))
+ {
+ sat = satisfiesMinimalVersion(
+ e->getAttribute(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("value"))));
+ } else if (e->getNamespaceURI().equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(xmlNamespace))
+ && e->getTagName().equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(
+ "OpenOffice.org-maximal-version")))
+ {
+ sat =
+ compareWithVersion(
+ e->getAttribute(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("value"))))
+ != ::dp_misc::GREATER;
+ } else if (e->hasAttributeNS(
+ ::rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(xmlNamespace)),
+ ::rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(minimalVersion))))
+ {
+ sat = satisfiesMinimalVersion(
+ e->getAttributeNS(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(xmlNamespace)),
+ ::rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(minimalVersion))));
+ }
+ if (!sat) {
+ unsatisfied[unsat++] = e;
+ }
+ }
+ unsatisfied.realloc(unsat);
+ return unsatisfied;
+}
+
+::rtl::OUString
+name(css::uno::Reference< css::xml::dom::XElement > const & dependency) {
+ ::rtl::OUString n(
+ dependency->getAttributeNS(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(xmlNamespace)),
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("name"))));
+ return n.getLength() == 0
+ ? ::rtl::OUString(
+ ::String(::dp_misc::getResId(RID_DEPLYOMENT_DEPENDENCIES_UNKNOWN)))
+ : n;
+}
+
+::rtl::OUString getErrorText( css::uno::Reference< css::xml::dom::XElement > const & dependency )
+{
+ ::rtl::OUString sReason;
+ ::rtl::OUString sValue;
+ ::rtl::OUString sVersion(RTL_CONSTASCII_USTRINGPARAM("%VERSION"));
+
+ if ( dependency->getNamespaceURI().equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( xmlNamespace ) )
+ && dependency->getTagName().equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "OpenOffice.org-minimal-version" ) ) )
+ {
+ sValue = dependency->getAttribute( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "value" ) ) );
+ sReason = ::rtl::OUString( ::String(::dp_misc::getResId(RID_DEPLYOMENT_DEPENDENCIES_MIN)) );
+ }
+ else if ( dependency->getNamespaceURI().equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( xmlNamespace ) )
+ && dependency->getTagName().equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "OpenOffice.org-maximal-version" ) ) )
+ {
+ sValue = dependency->getAttribute( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("value") ) );
+ sReason = ::rtl::OUString( ::String(::dp_misc::getResId(RID_DEPLYOMENT_DEPENDENCIES_MAX)) );
+ }
+ else if ( dependency->hasAttributeNS( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( xmlNamespace ) ),
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OpenOffice.org-minimal-version" ))))
+ {
+ sValue = dependency->getAttributeNS( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( xmlNamespace ) ),
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OpenOffice.org-minimal-version" ) ) );
+ sReason = ::rtl::OUString( ::String(::dp_misc::getResId(RID_DEPLYOMENT_DEPENDENCIES_MIN)) );
+ }
+ else
+ return ::rtl::OUString( ::String(::dp_misc::getResId(RID_DEPLYOMENT_DEPENDENCIES_UNKNOWN)) );
+
+ if ( sValue.getLength() == 0 )
+ sValue = ::rtl::OUString( ::String(::dp_misc::getResId(RID_DEPLYOMENT_DEPENDENCIES_UNKNOWN)) );
+
+ sal_Int32 nPos = sReason.indexOf( sVersion );
+ if ( nPos >= 0 )
+ sReason = sReason.replaceAt( nPos, sVersion.getLength(), sValue );
+ return sReason;
+}
+
+}
+
+}
diff --git a/desktop/source/deployment/misc/dp_descriptioninfoset.cxx b/desktop/source/deployment/misc/dp_descriptioninfoset.cxx
new file mode 100644
index 000000000000..2d5d8835b7f3
--- /dev/null
+++ b/desktop/source/deployment/misc/dp_descriptioninfoset.cxx
@@ -0,0 +1,581 @@
+/*************************************************************************
+ *
+ * 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: dp_descriptioninfoset.cxx,v $
+ * $Revision: 1.7.34.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_desktop.hxx"
+
+#include "dp_descriptioninfoset.hxx"
+
+#include "dp_resource.h"
+#include "sal/config.h"
+
+#include "comphelper/sequence.hxx"
+#include "comphelper/makesequence.hxx"
+#include "boost/optional.hpp"
+#include "com/sun/star/beans/Optional.hpp"
+#include "com/sun/star/lang/XMultiComponentFactory.hpp"
+#include "com/sun/star/lang/Locale.hpp"
+#include "com/sun/star/uno/Reference.hxx"
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include "com/sun/star/uno/Sequence.hxx"
+#include "com/sun/star/uno/XComponentContext.hpp"
+#include "com/sun/star/uno/XInterface.hpp"
+#include "com/sun/star/xml/dom/DOMException.hpp"
+#include "com/sun/star/xml/dom/XNode.hpp"
+#include "com/sun/star/xml/dom/XNodeList.hpp"
+#include "com/sun/star/xml/xpath/XXPathAPI.hpp"
+#include "cppuhelper/implbase1.hxx"
+#include "cppuhelper/weak.hxx"
+#include "rtl/ustring.h"
+#include "rtl/ustring.hxx"
+#include "sal/types.h"
+
+
+namespace {
+
+namespace css = ::com::sun::star;
+
+class EmptyNodeList: public ::cppu::WeakImplHelper1< css::xml::dom::XNodeList >
+{
+public:
+ EmptyNodeList();
+
+ virtual ~EmptyNodeList();
+
+ virtual ::sal_Int32 SAL_CALL getLength() throw (css::uno::RuntimeException);
+
+ virtual css::uno::Reference< css::xml::dom::XNode > SAL_CALL
+ item(::sal_Int32 index) throw (css::uno::RuntimeException);
+
+private:
+ EmptyNodeList(EmptyNodeList &); // not defined
+ void operator =(EmptyNodeList &); // not defined
+};
+
+EmptyNodeList::EmptyNodeList() {}
+
+EmptyNodeList::~EmptyNodeList() {}
+
+::sal_Int32 EmptyNodeList::getLength() throw (css::uno::RuntimeException) {
+ return 0;
+}
+
+css::uno::Reference< css::xml::dom::XNode > EmptyNodeList::item(::sal_Int32)
+ throw (css::uno::RuntimeException)
+{
+ throw css::uno::RuntimeException(
+ ::rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "bad EmptyNodeList com.sun.star.xml.dom.XNodeList.item call")),
+ static_cast< ::cppu::OWeakObject * >(this));
+}
+
+::rtl::OUString getNodeValue(
+ css::uno::Reference< css::xml::dom::XNode > const & node)
+{
+ OSL_ASSERT(node.is());
+ try {
+ return node->getNodeValue();
+ } catch (css::xml::dom::DOMException & e) {
+ throw css::uno::RuntimeException(
+ (::rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.xml.dom.DOMException: ")) +
+ e.Message),
+ css::uno::Reference< css::uno::XInterface >());
+ }
+}
+
+}
+
+namespace dp_misc {
+
+DescriptionInfoset::DescriptionInfoset(
+ css::uno::Reference< css::uno::XComponentContext > const & context,
+ css::uno::Reference< css::xml::dom::XNode > const & element):
+ m_element(element)
+{
+ css::uno::Reference< css::lang::XMultiComponentFactory > manager(
+ context->getServiceManager(), css::uno::UNO_QUERY_THROW);
+ if (m_element.is()) {
+ m_xpath = css::uno::Reference< css::xml::xpath::XXPathAPI >(
+ manager->createInstanceWithContext(
+ ::rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.xml.xpath.XPathAPI")),
+ context),
+ css::uno::UNO_QUERY_THROW);
+ m_xpath->registerNS(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("desc")),
+ element->getNamespaceURI());
+ m_xpath->registerNS(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("xlink")),
+ ::rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("http://www.w3.org/1999/xlink")));
+ }
+}
+
+DescriptionInfoset::~DescriptionInfoset() {}
+
+::boost::optional< ::rtl::OUString > DescriptionInfoset::getIdentifier() const {
+ return getOptionalValue(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("desc:identifier/@value")));
+}
+
+::rtl::OUString DescriptionInfoset::getNodeValueFromExpression(::rtl::OUString const & expression) const
+{
+ css::uno::Reference< css::xml::dom::XNode > n;
+ if (m_element.is()) {
+ try {
+ n = m_xpath->selectSingleNode(m_element, expression);
+ } catch (css::xml::xpath::XPathException &) {
+ // ignore
+ }
+ }
+ return n.is() ? getNodeValue(n) : ::rtl::OUString();
+}
+
+
+::rtl::OUString DescriptionInfoset::getVersion() const
+{
+ return getNodeValueFromExpression( ::rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("desc:version/@value")));
+}
+
+css::uno::Sequence< ::rtl::OUString > DescriptionInfoset::getSupportedPlaforms() const
+{
+ //When there is no description.xml then we assume that we support all platforms
+ if (! m_element.is())
+ {
+ return comphelper::makeSequence(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("all")));
+ }
+
+ //Check if the <platform> element was provided. If not the default is "all" platforms
+ css::uno::Reference< css::xml::dom::XNode > nodePlatform(
+ m_xpath->selectSingleNode(m_element, ::rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("desc:platform"))));
+ if (!nodePlatform.is())
+ {
+ return comphelper::makeSequence(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("all")));
+ }
+
+ //There is a platform element.
+ const ::rtl::OUString value = getNodeValueFromExpression(::rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("desc:platform/@value")));
+ //parse the string, it can contained multiple strings separated by commas
+ ::std::vector< ::rtl::OUString> vec;
+ sal_Int32 nIndex = 0;
+ do
+ {
+ ::rtl::OUString aToken = value.getToken( 0, ',', nIndex );
+ aToken = aToken.trim();
+ if (aToken.getLength())
+ vec.push_back(aToken);
+
+ }
+ while (nIndex >= 0);
+
+ return comphelper::containerToSequence(vec);
+}
+
+css::uno::Reference< css::xml::dom::XNodeList >
+DescriptionInfoset::getDependencies() const {
+ if (m_element.is()) {
+ try {
+ return m_xpath->selectNodeList(m_element, ::rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("desc:dependencies/*")));
+ } catch (css::xml::xpath::XPathException &) {
+ // ignore
+ }
+ }
+ return new EmptyNodeList;
+}
+
+css::uno::Sequence< ::rtl::OUString >
+DescriptionInfoset::getUpdateInformationUrls() const {
+ return getUrls(
+ ::rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "desc:update-information/desc:src/@xlink:href")));
+}
+
+css::uno::Sequence< ::rtl::OUString >
+DescriptionInfoset::getUpdateDownloadUrls() const
+{
+ return getUrls(
+ ::rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "desc:update-download/desc:src/@xlink:href")));
+}
+
+::rtl::OUString DescriptionInfoset::getIconURL( sal_Bool bHighContrast ) const
+{
+ css::uno::Sequence< ::rtl::OUString > aStrList = getUrls( ::rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "desc:icon/desc:default/@xlink:href")));
+ css::uno::Sequence< ::rtl::OUString > aStrListHC = getUrls( ::rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "desc:icon/desc:high-contrast/@xlink:href")));
+
+ if ( bHighContrast && aStrListHC.hasElements() && aStrListHC[0].getLength() )
+ return aStrListHC[0];
+
+ if ( aStrList.hasElements() && aStrList[0].getLength() )
+ return aStrList[0];
+
+ return ::rtl::OUString();
+}
+
+::boost::optional< ::rtl::OUString > DescriptionInfoset::getLocalizedUpdateWebsiteURL()
+ const
+{
+ bool bParentExists = false;
+ const ::rtl::OUString sURL (getLocalizedHREFAttrFromChild(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "/desc:description/desc:update-website")), &bParentExists ));
+
+ if (sURL.getLength() > 0)
+ return ::boost::optional< ::rtl::OUString >(sURL);
+ else
+ return bParentExists ? ::boost::optional< ::rtl::OUString >(::rtl::OUString()) :
+ ::boost::optional< ::rtl::OUString >();
+}
+
+css::uno::Reference< css::xml::xpath::XXPathAPI > DescriptionInfoset::getXpath()
+ const
+{
+ return m_xpath;
+}
+
+::boost::optional< ::rtl::OUString > DescriptionInfoset::getOptionalValue(
+ ::rtl::OUString const & expression) const
+{
+ css::uno::Reference< css::xml::dom::XNode > n;
+ if (m_element.is()) {
+ try {
+ n = m_xpath->selectSingleNode(m_element, expression);
+ } catch (css::xml::xpath::XPathException &) {
+ // ignore
+ }
+ }
+ return n.is()
+ ? ::boost::optional< ::rtl::OUString >(getNodeValue(n))
+ : ::boost::optional< ::rtl::OUString >();
+}
+
+css::uno::Sequence< ::rtl::OUString > DescriptionInfoset::getUrls(
+ ::rtl::OUString const & expression) const
+{
+ css::uno::Reference< css::xml::dom::XNodeList > ns;
+ if (m_element.is()) {
+ try {
+ ns = m_xpath->selectNodeList(m_element, expression);
+ } catch (css::xml::xpath::XPathException &) {
+ // ignore
+ }
+ }
+ css::uno::Sequence< ::rtl::OUString > urls(ns.is() ? ns->getLength() : 0);
+ for (::sal_Int32 i = 0; i < urls.getLength(); ++i) {
+ urls[i] = getNodeValue(ns->item(i));
+ }
+ return urls;
+}
+
+::std::pair< ::rtl::OUString, ::rtl::OUString > DescriptionInfoset::getLocalizedPublisherNameAndURL() const
+{
+ css::uno::Reference< css::xml::dom::XNode > node =
+ getLocalizedChild(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("desc:publisher")));
+
+ ::rtl::OUString sPublisherName;
+ ::rtl::OUString sURL;
+ if (node.is())
+ {
+ const ::rtl::OUString exp1(RTL_CONSTASCII_USTRINGPARAM("text()"));
+ css::uno::Reference< css::xml::dom::XNode > xPathName;
+ try {
+ xPathName = m_xpath->selectSingleNode(node, exp1);
+ } catch (css::xml::xpath::XPathException &) {
+ // ignore
+ }
+ OSL_ASSERT(xPathName.is());
+ if (xPathName.is())
+ sPublisherName = xPathName->getNodeValue();
+
+ const ::rtl::OUString exp2(RTL_CONSTASCII_USTRINGPARAM("@xlink:href"));
+ css::uno::Reference< css::xml::dom::XNode > xURL;
+ try {
+ xURL = m_xpath->selectSingleNode(node, exp2);
+ } catch (css::xml::xpath::XPathException &) {
+ // ignore
+ }
+ OSL_ASSERT(xURL.is());
+ if (xURL.is())
+ sURL = xURL->getNodeValue();
+ }
+ return ::std::make_pair(sPublisherName, sURL);
+}
+
+::rtl::OUString DescriptionInfoset::getLocalizedReleaseNotesURL() const
+{
+ return getLocalizedHREFAttrFromChild(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "/desc:description/desc:release-notes")), NULL);
+}
+
+::rtl::OUString DescriptionInfoset::getLocalizedDisplayName() const
+{
+ css::uno::Reference< css::xml::dom::XNode > node =
+ getLocalizedChild(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("desc:display-name")));
+ if (node.is())
+ {
+ const ::rtl::OUString exp(RTL_CONSTASCII_USTRINGPARAM("text()"));
+ css::uno::Reference< css::xml::dom::XNode > xtext;
+ try {
+ xtext = m_xpath->selectSingleNode(node, exp);
+ } catch (css::xml::xpath::XPathException &) {
+ // ignore
+ }
+ if (xtext.is())
+ return xtext->getNodeValue();
+ }
+ return ::rtl::OUString();
+}
+
+::rtl::OUString DescriptionInfoset::getLocalizedLicenseURL() const
+{
+ return getLocalizedHREFAttrFromChild(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "/desc:description/desc:registration/desc:simple-license")), NULL);
+
+}
+
+::rtl::OUString DescriptionInfoset::getLocalizedDescriptionURL() const
+{
+ return getLocalizedHREFAttrFromChild(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "/desc:description/desc:extension-description")), NULL);
+}
+
+css::uno::Reference< css::xml::dom::XNode >
+DescriptionInfoset::getLocalizedChild( const ::rtl::OUString & sParent) const
+{
+ if ( ! m_element.is() || !sParent.getLength())
+ return css::uno::Reference< css::xml::dom::XNode > ();
+
+ css::uno::Reference< css::xml::dom::XNode > xParent;
+ try {
+ xParent = m_xpath->selectSingleNode(m_element, sParent);
+ } catch (css::xml::xpath::XPathException &) {
+ // ignore
+ }
+ css::uno::Reference<css::xml::dom::XNode> nodeMatch;
+ if (xParent.is())
+ {
+ const ::rtl::OUString sLocale = getOfficeLocaleString();
+ nodeMatch = matchFullLocale(xParent, sLocale);
+
+ //office: en-DE, en, en-DE-altmark
+ if (! nodeMatch.is())
+ {
+ const css::lang::Locale officeLocale = getOfficeLocale();
+ nodeMatch = matchCountryAndLanguage(xParent, officeLocale);
+ if ( ! nodeMatch.is())
+ {
+ nodeMatch = matchLanguage(xParent, officeLocale);
+ if (! nodeMatch.is())
+ nodeMatch = getChildWithDefaultLocale(xParent);
+ }
+ }
+ }
+
+ return nodeMatch;
+}
+
+css::uno::Reference<css::xml::dom::XNode>
+DescriptionInfoset::matchFullLocale(css::uno::Reference< css::xml::dom::XNode >
+ const & xParent, ::rtl::OUString const & sLocale) const
+{
+ OSL_ASSERT(xParent.is());
+ const ::rtl::OUString exp1(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("*[@lang=\""))
+ + sLocale +
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\"]")));
+ try {
+ return m_xpath->selectSingleNode(xParent, exp1);
+ } catch (css::xml::xpath::XPathException &) {
+ // ignore
+ return 0;
+ }
+}
+
+css::uno::Reference<css::xml::dom::XNode>
+DescriptionInfoset::matchCountryAndLanguage(
+ css::uno::Reference< css::xml::dom::XNode > const & xParent, css::lang::Locale const & officeLocale) const
+{
+ OSL_ASSERT(xParent.is());
+ css::uno::Reference<css::xml::dom::XNode> nodeMatch;
+
+ if (officeLocale.Country.getLength())
+ {
+ const ::rtl::OUString sLangCountry(officeLocale.Language +
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("-")) +
+ officeLocale.Country);
+ //first try exact match for lang-country
+ const ::rtl::OUString exp1(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("*[@lang=\""))
+ + sLangCountry +
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\"]")));
+ try {
+ nodeMatch = m_xpath->selectSingleNode(xParent, exp1);
+ } catch (css::xml::xpath::XPathException &) {
+ // ignore
+ }
+
+ //try to match in strings that also have a variant, for example en-US matches in
+ //en-US-montana
+ if (!nodeMatch.is())
+ {
+ const ::rtl::OUString exp2(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("*[starts-with(@lang,\""))
+ + sLangCountry +
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("-\")]")));
+ try {
+ nodeMatch = m_xpath->selectSingleNode(xParent, exp2);
+ } catch (css::xml::xpath::XPathException &) {
+ // ignore
+ }
+ }
+ }
+
+ return nodeMatch;
+}
+
+
+css::uno::Reference<css::xml::dom::XNode>
+DescriptionInfoset::matchLanguage(
+ css::uno::Reference< css::xml::dom::XNode > const & xParent, css::lang::Locale const & officeLocale) const
+{
+ OSL_ASSERT(xParent.is());
+ css::uno::Reference<css::xml::dom::XNode> nodeMatch;
+
+ //first try exact match for lang
+ const ::rtl::OUString exp1(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("*[@lang=\""))
+ + officeLocale.Language
+ + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\"]")));
+ try {
+ nodeMatch = m_xpath->selectSingleNode(xParent, exp1);
+ } catch (css::xml::xpath::XPathException &) {
+ // ignore
+ }
+
+ //try to match in strings that also have a country and/orvariant, for example en matches in
+ //en-US-montana, en-US, en-montana
+ if (!nodeMatch.is())
+ {
+ const ::rtl::OUString exp2(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("*[starts-with(@lang,\""))
+ + officeLocale.Language
+ + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("-\")]")));
+ try {
+ nodeMatch = m_xpath->selectSingleNode(xParent, exp2);
+ } catch (css::xml::xpath::XPathException &) {
+ // ignore
+ }
+ }
+ return nodeMatch;
+}
+
+css::uno::Reference<css::xml::dom::XNode>
+DescriptionInfoset::getChildWithDefaultLocale(css::uno::Reference< css::xml::dom::XNode >
+ const & xParent) const
+{
+ OSL_ASSERT(xParent.is());
+ if (xParent->getNodeName().equals(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("simple-license"))))
+ {
+ css::uno::Reference<css::xml::dom::XNode> nodeDefault;
+ try {
+ nodeDefault = m_xpath->selectSingleNode(xParent, ::rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("@default-license-id")));
+ } catch (css::xml::xpath::XPathException &) {
+ // ignore
+ }
+ if (nodeDefault.is())
+ {
+ //The old way
+ const ::rtl::OUString exp1(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("desc:license-text[@license-id = \""))
+ + nodeDefault->getNodeValue()
+ + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\"]")));
+ try {
+ return m_xpath->selectSingleNode(xParent, exp1);
+ } catch (css::xml::xpath::XPathException &) {
+ // ignore
+ }
+ }
+ }
+
+ const ::rtl::OUString exp2(RTL_CONSTASCII_USTRINGPARAM("*[1]"));
+ try {
+ return m_xpath->selectSingleNode(xParent, exp2);
+ } catch (css::xml::xpath::XPathException &) {
+ // ignore
+ return 0;
+ }
+}
+
+::rtl::OUString DescriptionInfoset::getLocalizedHREFAttrFromChild(
+ ::rtl::OUString const & sXPathParent, bool * out_bParentExists)
+ const
+{
+ css::uno::Reference< css::xml::dom::XNode > node =
+ getLocalizedChild(sXPathParent);
+
+ ::rtl::OUString sURL;
+ if (node.is())
+ {
+ if (out_bParentExists)
+ *out_bParentExists = true;
+ const ::rtl::OUString exp(RTL_CONSTASCII_USTRINGPARAM("@xlink:href"));
+ css::uno::Reference< css::xml::dom::XNode > xURL;
+ try {
+ xURL = m_xpath->selectSingleNode(node, exp);
+ } catch (css::xml::xpath::XPathException &) {
+ // ignore
+ }
+ OSL_ASSERT(xURL.is());
+ if (xURL.is())
+ sURL = xURL->getNodeValue();
+ }
+ else
+ {
+ if (out_bParentExists)
+ *out_bParentExists = false;
+ }
+ return sURL;
+}
+
+}
diff --git a/desktop/source/deployment/misc/dp_identifier.cxx b/desktop/source/deployment/misc/dp_identifier.cxx
new file mode 100644
index 000000000000..639672449454
--- /dev/null
+++ b/desktop/source/deployment/misc/dp_identifier.cxx
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * 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: dp_identifier.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_desktop.hxx"
+
+#include "sal/config.h"
+
+#include "boost/optional.hpp"
+#include "com/sun/star/beans/Optional.hpp"
+#include "com/sun/star/deployment/XPackage.hpp"
+#include "com/sun/star/uno/Reference.hxx"
+#include "osl/diagnose.h"
+#include "rtl/string.h"
+#include "rtl/ustrbuf.hxx"
+#include "rtl/ustring.hxx"
+
+#include "dp_identifier.hxx"
+
+namespace {
+ namespace css = ::com::sun::star;
+}
+
+namespace dp_misc {
+
+::rtl::OUString generateIdentifier(
+ ::boost::optional< ::rtl::OUString > const & optional,
+ ::rtl::OUString const & fileName)
+{
+ return optional ? *optional : generateLegacyIdentifier(fileName);
+}
+
+::rtl::OUString getIdentifier(
+ css::uno::Reference< css::deployment::XPackage > const & package)
+{
+ OSL_ASSERT(package.is());
+ css::beans::Optional< ::rtl::OUString > id(package->getIdentifier());
+ return id.IsPresent
+ ? id.Value : generateLegacyIdentifier(package->getName());
+}
+
+::rtl::OUString generateLegacyIdentifier(::rtl::OUString const & fileName) {
+ rtl::OUStringBuffer b;
+ b.appendAscii(RTL_CONSTASCII_STRINGPARAM("org.openoffice.legacy."));
+ b.append(fileName);
+ return b.makeStringAndClear();
+}
+
+}
diff --git a/desktop/source/deployment/misc/dp_interact.cxx b/desktop/source/deployment/misc/dp_interact.cxx
new file mode 100644
index 000000000000..76688ff2ae58
--- /dev/null
+++ b/desktop/source/deployment/misc/dp_interact.cxx
@@ -0,0 +1,188 @@
+/*************************************************************************
+ *
+ * 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: dp_interact.cxx,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "dp_interact.h"
+#include "cppuhelper/exc_hlp.hxx"
+#include "cppuhelper/implbase1.hxx"
+#include "com/sun/star/task/XInteractionAbort.hpp"
+
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::ucb;
+using ::rtl::OUString;
+
+namespace dp_misc {
+namespace {
+
+//==============================================================================
+class InteractionContinuationImpl : public ::cppu::OWeakObject,
+ public task::XInteractionContinuation
+{
+ const Type m_type;
+ bool * m_pselect;
+
+public:
+ inline InteractionContinuationImpl( Type const & type, bool * pselect )
+ : m_type( type ),
+ m_pselect( pselect )
+ { OSL_ASSERT(
+ ::getCppuType(
+ static_cast< Reference<task::XInteractionContinuation>
+ const *>(0) ).isAssignableFrom(m_type) ); }
+
+ // XInterface
+ virtual void SAL_CALL acquire() throw ();
+ virtual void SAL_CALL release() throw ();
+ virtual Any SAL_CALL queryInterface( Type const & type )
+ throw (RuntimeException);
+
+ // XInteractionContinuation
+ virtual void SAL_CALL select() throw (RuntimeException);
+};
+
+// XInterface
+//______________________________________________________________________________
+void InteractionContinuationImpl::acquire() throw ()
+{
+ OWeakObject::acquire();
+}
+
+//______________________________________________________________________________
+void InteractionContinuationImpl::release() throw ()
+{
+ OWeakObject::release();
+}
+
+//______________________________________________________________________________
+Any InteractionContinuationImpl::queryInterface( Type const & type )
+ throw (RuntimeException)
+{
+ if (type.isAssignableFrom( m_type )) {
+ Reference<task::XInteractionContinuation> xThis(this);
+ return Any( &xThis, type );
+ }
+ else
+ return OWeakObject::queryInterface(type);
+}
+
+// XInteractionContinuation
+//______________________________________________________________________________
+void InteractionContinuationImpl::select() throw (RuntimeException)
+{
+ *m_pselect = true;
+}
+
+//==============================================================================
+class InteractionRequest :
+ public ::cppu::WeakImplHelper1<task::XInteractionRequest>
+{
+ Any m_request;
+ Sequence< Reference<task::XInteractionContinuation> > m_conts;
+
+public:
+ inline InteractionRequest(
+ Any const & request,
+ Sequence< Reference<task::XInteractionContinuation> > const & conts )
+ : m_request( request ),
+ m_conts( conts )
+ {}
+
+ // XInteractionRequest
+ virtual Any SAL_CALL getRequest()
+ throw (RuntimeException);
+ virtual Sequence< Reference<task::XInteractionContinuation> >
+ SAL_CALL getContinuations() throw (RuntimeException);
+};
+
+// XInteractionRequest
+//______________________________________________________________________________
+Any InteractionRequest::getRequest() throw (RuntimeException)
+{
+ return m_request;
+}
+
+//______________________________________________________________________________
+Sequence< Reference< task::XInteractionContinuation > >
+InteractionRequest::getContinuations() throw (RuntimeException)
+{
+ return m_conts;
+}
+
+} // anon namespace
+
+//==============================================================================
+bool interactContinuation( Any const & request,
+ Type const & continuation,
+ Reference<XCommandEnvironment> const & xCmdEnv,
+ bool * pcont, bool * pabort )
+{
+ OSL_ASSERT(
+ task::XInteractionContinuation::static_type().isAssignableFrom(
+ continuation ) );
+ if (xCmdEnv.is()) {
+ Reference<task::XInteractionHandler> xInteractionHandler(
+ xCmdEnv->getInteractionHandler() );
+ if (xInteractionHandler.is()) {
+ bool cont = false;
+ bool abort = false;
+ Sequence< Reference<task::XInteractionContinuation> > conts( 2 );
+ conts[ 0 ] = new InteractionContinuationImpl(
+ continuation, &cont );
+ conts[ 1 ] = new InteractionContinuationImpl(
+ task::XInteractionAbort::static_type(), &abort );
+ xInteractionHandler->handle(
+ new InteractionRequest( request, conts ) );
+ if (cont || abort) {
+ if (pcont != 0)
+ *pcont = cont;
+ if (pabort != 0)
+ *pabort = abort;
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+// XAbortChannel
+//______________________________________________________________________________
+void AbortChannel::sendAbort() throw (RuntimeException)
+{
+ m_aborted = true;
+ if (m_xNext.is())
+ m_xNext->sendAbort();
+}
+
+} // dp_misc
+
diff --git a/desktop/source/deployment/misc/dp_misc.cxx b/desktop/source/deployment/misc/dp_misc.cxx
new file mode 100644
index 000000000000..d63d901290a0
--- /dev/null
+++ b/desktop/source/deployment/misc/dp_misc.cxx
@@ -0,0 +1,473 @@
+/*************************************************************************
+ *
+ * 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: dp_misc.cxx,v $
+ * $Revision: 1.19.8.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_desktop.hxx"
+
+
+#include "dp_misc.h"
+#include "dp_interact.h"
+#include "rtl/uri.hxx"
+#include "rtl/digest.h"
+#include "rtl/random.h"
+#include "rtl/bootstrap.hxx"
+#include "unotools/bootstrap.hxx"
+#include "osl/file.hxx"
+#include "osl/pipe.hxx"
+#include "osl/security.hxx"
+#include "osl/thread.hxx"
+#include "osl/mutex.hxx"
+#include "com/sun/star/ucb/CommandAbortedException.hpp"
+#include "com/sun/star/bridge/UnoUrlResolver.hpp"
+#include "com/sun/star/bridge/XUnoUrlResolver.hpp"
+#include "boost/scoped_array.hpp"
+#include "boost/shared_ptr.hpp"
+
+#ifdef WNT
+//#include "tools/prewin.h"
+#define UNICODE
+#define _UNICODE
+#define WIN32_LEAN_AND_MEAN
+#include <Windows.h>
+//#include "tools/postwin.h"
+#endif
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using ::rtl::OUString;
+using ::rtl::OString;
+
+
+#define SOFFICE1 "soffice.exe"
+#define SOFFICE2 "soffice.bin"
+#define SBASE "sbase.exe"
+#define SCALC "scalc.exe"
+#define SDRAW "sdraw.exe"
+#define SIMPRESS "simpress.exe"
+#define SWRITER "swriter.exe"
+
+namespace dp_misc {
+namespace {
+
+struct UnoRc : public rtl::StaticWithInit<
+ const boost::shared_ptr<rtl::Bootstrap>, UnoRc> {
+ const boost::shared_ptr<rtl::Bootstrap> operator () () {
+ OUString unorc( RTL_CONSTASCII_USTRINGPARAM(
+ "$OOO_BASE_DIR/program/" SAL_CONFIGFILE("uno")) );
+ ::rtl::Bootstrap::expandMacros( unorc );
+ ::boost::shared_ptr< ::rtl::Bootstrap > ret(
+ new ::rtl::Bootstrap( unorc ) );
+ OSL_ASSERT( ret->getHandle() != 0 );
+ return ret;
+ }
+};
+
+struct OfficePipeId : public rtl::StaticWithInit<const OUString, OfficePipeId> {
+ const OUString operator () ();
+};
+
+const OUString OfficePipeId::operator () ()
+{
+ OUString userPath;
+ ::utl::Bootstrap::PathStatus aLocateResult =
+ ::utl::Bootstrap::locateUserInstallation( userPath );
+ if (!(aLocateResult == ::utl::Bootstrap::PATH_EXISTS ||
+ aLocateResult == ::utl::Bootstrap::PATH_VALID))
+ {
+ throw Exception(OUSTR("Extension Manager: Could not obtain path for UserInstallation."), 0);
+ }
+
+ rtlDigest digest = rtl_digest_create( rtl_Digest_AlgorithmMD5 );
+ if (digest <= 0) {
+ throw RuntimeException(
+ OUSTR("cannot get digest rtl_Digest_AlgorithmMD5!"), 0 );
+ }
+
+ sal_uInt8 const * data =
+ reinterpret_cast<sal_uInt8 const *>(userPath.getStr());
+ sal_Size size = (userPath.getLength() * sizeof (sal_Unicode));
+ sal_uInt32 md5_key_len = rtl_digest_queryLength( digest );
+ ::boost::scoped_array<sal_uInt8> md5_buf( new sal_uInt8 [ md5_key_len ] );
+
+ rtl_digest_init( digest, data, static_cast<sal_uInt32>(size) );
+ rtl_digest_update( digest, data, static_cast<sal_uInt32>(size) );
+ rtl_digest_get( digest, md5_buf.get(), md5_key_len );
+ rtl_digest_destroy( digest );
+
+ // create hex-value string from the MD5 value to keep
+ // the string size minimal
+ ::rtl::OUStringBuffer buf;
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("SingleOfficeIPC_") );
+ for ( sal_uInt32 i = 0; i < md5_key_len; ++i ) {
+ buf.append( static_cast<sal_Int32>(md5_buf[ i ]), 0x10 );
+ }
+ return buf.makeStringAndClear();
+}
+
+bool existsOfficePipe()
+{
+ OUString const & pipeId = OfficePipeId::get();
+ if (pipeId.getLength() == 0)
+ return false;
+ ::osl::Security sec;
+ ::osl::Pipe pipe( pipeId, osl_Pipe_OPEN, sec );
+ return pipe.is();
+}
+
+} // anon namespace
+
+//==============================================================================
+
+namespace {
+inline OUString encodeForRcFile( OUString const & str )
+{
+ // escape $\{} (=> rtl bootstrap files)
+ ::rtl::OUStringBuffer buf;
+ sal_Int32 pos = 0;
+ const sal_Int32 len = str.getLength();
+ for ( ; pos < len; ++pos ) {
+ sal_Unicode c = str[ pos ];
+ switch (c) {
+ case '$':
+ case '\\':
+ case '{':
+ case '}':
+ buf.append( static_cast<sal_Unicode>('\\') );
+ break;
+ }
+ buf.append( c );
+ }
+ return buf.makeStringAndClear();
+}
+}
+
+//==============================================================================
+OUString makeURL( OUString const & baseURL, OUString const & relPath_ )
+{
+ ::rtl::OUStringBuffer buf;
+ if (baseURL.getLength() > 1 && baseURL[ baseURL.getLength() - 1 ] == '/')
+ buf.append( baseURL.copy( 0, baseURL.getLength() - 1 ) );
+ else
+ buf.append( baseURL );
+ OUString relPath(relPath_);
+ if (relPath.getLength() > 0 && relPath[ 0 ] == '/')
+ relPath = relPath.copy( 1 );
+ if (relPath.getLength() > 0)
+ {
+ buf.append( static_cast<sal_Unicode>('/') );
+ if (baseURL.matchAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("vnd.sun.star.expand:") )) {
+ // encode for macro expansion: relPath is supposed to have no
+ // macros, so encode $, {} \ (bootstrap mimic)
+ relPath = encodeForRcFile(relPath);
+
+ // encode once more for vnd.sun.star.expand schema:
+ // vnd.sun.star.expand:$UNO_...
+ // will expand to file-url
+ relPath = ::rtl::Uri::encode( relPath, rtl_UriCharClassUric,
+ rtl_UriEncodeIgnoreEscapes,
+ RTL_TEXTENCODING_UTF8 );
+ }
+ buf.append( relPath );
+ }
+ return buf.makeStringAndClear();
+}
+
+//==============================================================================
+OUString expandUnoRcTerm( OUString const & term_ )
+{
+ OUString term(term_);
+ UnoRc::get()->expandMacrosFrom( term );
+ return term;
+}
+
+//==============================================================================
+OUString expandUnoRcUrl( OUString const & url )
+{
+ if (url.matchAsciiL( RTL_CONSTASCII_STRINGPARAM("vnd.sun.star.expand:") )) {
+ // cut protocol:
+ OUString rcurl( url.copy( sizeof ("vnd.sun.star.expand:") - 1 ) );
+ // decode uric class chars:
+ rcurl = ::rtl::Uri::decode(
+ rcurl, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 );
+ // expand macro string:
+ UnoRc::get()->expandMacrosFrom( rcurl );
+ return rcurl;
+ }
+ else {
+ return url;
+ }
+}
+
+//==============================================================================
+bool office_is_running()
+{
+ //We need to check if we run within the office process. Then we must not use the pipe, because
+ //this could cause a deadlock. This is actually a workaround for i82778
+ OUString sFile;
+ oslProcessError err = osl_getExecutableFile(& sFile.pData);
+ bool ret = false;
+ if (osl_Process_E_None == err)
+ {
+ sFile = sFile.copy(sFile.lastIndexOf('/') + 1);
+ if (
+#if defined UNIX
+ sFile.equals(OUString(RTL_CONSTASCII_USTRINGPARAM(SOFFICE2)))
+#elif defined WNT || defined OS2
+ //osl_getExecutableFile should deliver "soffice.bin" on windows
+ //even if swriter.exe, scalc.exe etc. was started. This is a bug
+ //in osl_getExecutableFile
+ sFile.equals(OUString(RTL_CONSTASCII_USTRINGPARAM(SOFFICE1)))
+ || sFile.equals(OUString(RTL_CONSTASCII_USTRINGPARAM(SOFFICE2)))
+ || sFile.equals(OUString(RTL_CONSTASCII_USTRINGPARAM(SBASE)))
+ || sFile.equals(OUString(RTL_CONSTASCII_USTRINGPARAM(SCALC)))
+ || sFile.equals(OUString(RTL_CONSTASCII_USTRINGPARAM(SDRAW)))
+ || sFile.equals(OUString(RTL_CONSTASCII_USTRINGPARAM(SIMPRESS)))
+ || sFile.equals(OUString(RTL_CONSTASCII_USTRINGPARAM(SWRITER)))
+#else
+#error "Unsupported platform"
+#endif
+
+ )
+ ret = true;
+ else
+ ret = existsOfficePipe();
+ }
+ else
+ {
+ OSL_ENSURE(0, "NOT osl_Process_E_None ");
+ //if osl_getExecutable file than we take the risk of creating a pipe
+ ret = existsOfficePipe();
+ }
+ return ret;
+}
+
+//==============================================================================
+oslProcess raiseProcess(
+ OUString const & appURL, Sequence<OUString> const & args )
+{
+ ::osl::Security sec;
+ oslProcess hProcess = 0;
+ oslProcessError rc = osl_executeProcess(
+ appURL.pData,
+ reinterpret_cast<rtl_uString **>(
+ const_cast<OUString *>(args.getConstArray()) ),
+ args.getLength(),
+ osl_Process_DETACHED,
+ sec.getHandle(),
+ 0, // => current working dir
+ 0, 0, // => no env vars
+ &hProcess );
+
+ switch (rc) {
+ case osl_Process_E_None:
+ break;
+ case osl_Process_E_NotFound:
+ throw RuntimeException( OUSTR("image not found!"), 0 );
+ case osl_Process_E_TimedOut:
+ throw RuntimeException( OUSTR("timout occured!"), 0 );
+ case osl_Process_E_NoPermission:
+ throw RuntimeException( OUSTR("permission denied!"), 0 );
+ case osl_Process_E_Unknown:
+ throw RuntimeException( OUSTR("unknown error!"), 0 );
+ case osl_Process_E_InvalidError:
+ default:
+ throw RuntimeException( OUSTR("unmapped error!"), 0 );
+ }
+
+ return hProcess;
+}
+
+//==============================================================================
+OUString generateRandomPipeId()
+{
+ // compute some good pipe id:
+ static rtlRandomPool s_hPool = rtl_random_createPool();
+ if (s_hPool == 0)
+ throw RuntimeException( OUSTR("cannot create random pool!?"), 0 );
+ sal_uInt8 bytes[ 32 ];
+ if (rtl_random_getBytes(
+ s_hPool, bytes, ARLEN(bytes) ) != rtl_Random_E_None) {
+ throw RuntimeException( OUSTR("random pool error!?"), 0 );
+ }
+ ::rtl::OUStringBuffer buf;
+ for ( sal_uInt32 i = 0; i < ARLEN(bytes); ++i ) {
+ buf.append( static_cast<sal_Int32>(bytes[ i ]), 0x10 );
+ }
+ return buf.makeStringAndClear();
+}
+
+//==============================================================================
+Reference<XInterface> resolveUnoURL(
+ OUString const & connectString,
+ Reference<XComponentContext> const & xLocalContext,
+ AbortChannel * abortChannel )
+{
+ Reference<bridge::XUnoUrlResolver> xUnoUrlResolver(
+ bridge::UnoUrlResolver::create( xLocalContext ) );
+
+ for (;;)
+ {
+ if (abortChannel != 0 && abortChannel->isAborted()) {
+ throw ucb::CommandAbortedException(
+ OUSTR("abort!"), Reference<XInterface>() );
+ }
+ try {
+ return xUnoUrlResolver->resolve( connectString );
+ }
+ catch (connection::NoConnectException &) {
+ TimeValue tv = { 0 /* secs */, 500000000 /* nanosecs */ };
+ ::osl::Thread::wait( tv );
+ }
+ }
+}
+
+OUString getExtensionDefaultUpdateURL()
+{
+ ::rtl::OUString sUrl(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "${$BRAND_BASE_DIR/program/" SAL_CONFIGFILE("version")
+ ":Version:ExtensionUpdateURL}"));
+ ::rtl::Bootstrap::expandMacros(sUrl);
+ return sUrl;
+}
+
+
+#ifdef WNT
+void writeConsoleWithStream(::rtl::OUString const & sText, HANDLE stream)
+{
+ DWORD nWrittenChars = 0;
+ WriteFile(stream, sText.getStr(),
+ sText.getLength() * 2, &nWrittenChars, NULL);
+}
+#else
+void writeConsoleWithStream(::rtl::OUString const & sText, FILE * stream)
+{
+ OString s = OUStringToOString(sText, osl_getThreadTextEncoding());
+ fprintf(stream, "%s", s.getStr());
+ fflush(stream);
+}
+#endif
+
+#ifdef WNT
+void writeConsoleWithStream(::rtl::OString const & sText, HANDLE stream)
+{
+ writeConsoleWithStream(OStringToOUString(
+ sText, RTL_TEXTENCODING_UTF8), stream);
+}
+#else
+void writeConsoleWithStream(::rtl::OString const & sText, FILE * stream)
+{
+ fprintf(stream, "%s", sText.getStr());
+ fflush(stream);
+}
+#endif
+
+void writeConsole(::rtl::OUString const & sText)
+{
+#ifdef WNT
+ writeConsoleWithStream(sText, GetStdHandle(STD_OUTPUT_HANDLE));
+#else
+ writeConsoleWithStream(sText, stdout);
+#endif
+}
+
+void writeConsole(::rtl::OString const & sText)
+{
+#ifdef WNT
+ writeConsoleWithStream(sText, GetStdHandle(STD_OUTPUT_HANDLE));
+#else
+ writeConsoleWithStream(sText, stdout);
+#endif
+}
+
+void writeConsoleError(::rtl::OUString const & sText)
+{
+#ifdef WNT
+ writeConsoleWithStream(sText, GetStdHandle(STD_ERROR_HANDLE));
+#else
+ writeConsoleWithStream(sText, stderr);
+#endif
+}
+
+
+void writeConsoleError(::rtl::OString const & sText)
+{
+#ifdef WNT
+ writeConsoleWithStream(sText, GetStdHandle(STD_ERROR_HANDLE));
+#else
+ writeConsoleWithStream(sText, stderr);
+#endif
+}
+
+
+
+OUString readConsole()
+{
+#ifdef WNT
+ sal_Unicode aBuffer[1024];
+ DWORD dwRead = 0;
+ //unopkg.com feeds unopkg.exe with wchar_t|s
+ if (ReadFile( GetStdHandle(STD_INPUT_HANDLE), &aBuffer, sizeof(aBuffer), &dwRead, NULL ) )
+ {
+ OSL_ASSERT((dwRead % 2) == 0);
+ OUString value( aBuffer, dwRead / 2);
+ value = value.trim();
+ return value;
+ }
+ return OUString();
+
+#else
+ char buf[1024];
+ rtl_zeroMemory(buf, 1024);
+ // read one char less so that the last char in buf is always zero
+ fgets(buf, 1024, stdin);
+ OUString value = ::rtl::OStringToOUString(::rtl::OString(buf), osl_getThreadTextEncoding());
+ return value.trim();
+#endif
+}
+
+void TRACE(::rtl::OUString const & sText)
+{
+ (void) sText;
+#if OSL_DEBUG_LEVEL > 1
+ writeConsole(sText);
+#endif
+}
+
+void TRACE(::rtl::OString const & sText)
+{
+ (void) sText;
+#if OSL_DEBUG_LEVEL > 1
+ writeConsole(sText);
+#endif
+}
+
+}
diff --git a/desktop/source/deployment/misc/dp_misc.hrc b/desktop/source/deployment/misc/dp_misc.hrc
new file mode 100644
index 000000000000..287ce3d99def
--- /dev/null
+++ b/desktop/source/deployment/misc/dp_misc.hrc
@@ -0,0 +1,36 @@
+/*************************************************************************
+ *
+ * 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: dp_misc.hrc,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.
+ *
+ ************************************************************************/
+
+#if ! defined INCLUDED_DP_MISC_HRC
+#define INCLUDED_DP_MISC_HRC
+
+#include "deployment.hrc"
+
+#endif
diff --git a/desktop/source/deployment/misc/dp_misc.src b/desktop/source/deployment/misc/dp_misc.src
new file mode 100644
index 000000000000..98f3d8bc2211
--- /dev/null
+++ b/desktop/source/deployment/misc/dp_misc.src
@@ -0,0 +1,40 @@
+/*************************************************************************
+ *
+ * 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
+ *
+ * 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 "dp_misc.hrc"
+
+String RID_DEPLYOMENT_DEPENDENCIES_UNKNOWN {
+ Text[en-US] = "Unknown";
+};
+
+String RID_DEPLYOMENT_DEPENDENCIES_MIN {
+ Text[en-US] = "Extensions requires at least OpenOffice.org %VERSION";
+};
+
+String RID_DEPLYOMENT_DEPENDENCIES_MAX {
+ Text[en-US] = "Extension doesn't support versions greater than: OpenOffice.org %VERSION";
+};
diff --git a/desktop/source/deployment/misc/dp_platform.cxx b/desktop/source/deployment/misc/dp_platform.cxx
new file mode 100644
index 000000000000..218eb0a98113
--- /dev/null
+++ b/desktop/source/deployment/misc/dp_platform.cxx
@@ -0,0 +1,221 @@
+/*************************************************************************
+ *
+ * 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: dp_platform.cxx,v $
+ *
+ * $Revision: 1.2.86.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_desktop.hxx"
+
+#include "dp_misc.h"
+#include "dp_platform.hxx"
+#include "rtl/ustring.hxx"
+#include "rtl/ustrbuf.hxx"
+#include "rtl/instance.hxx"
+#include "rtl/bootstrap.hxx"
+
+#define PLATFORM_ALL "all"
+#define PLATFORM_WIN_X86 "windows_x86"
+#define PLATFORM_LINUX_X86 "linux_x86"
+#define PLATFORM_LINUX_X86_64 "linux_x86_64"
+#define PLATFORM_LINUX_SPARC "linux_sparc"
+#define PLATFORM_LINUX_POWERPC "linux_powerpc"
+#define PLATFORM_LINUX_POWERPC64 "linux_powerpc64"
+#define PLATFORM_LINUX_ARM_EABI "linux_arm_eabi"
+#define PLATFORM_LINUX_ARM_OABI "linux_arm_oabi"
+#define PLATFORM_LINUX_MIPS_EL "linux_mips_el"
+#define PLATFORM_LINUX_MIPS_EB "linux_mips_eb"
+#define PLATFORM_LINUX_IA64 "linux_ia64"
+#define PLATFORM_LINUX_S390 "linux_s390"
+#define PLATFORM_LINUX_S390x "linux_s390x"
+
+
+
+#define PLATFORM_SOLARIS_SPARC "solaris_sparc"
+#define PLATFORM_SOLARIS_SPARC64 "solaris_sparc64"
+#define PLATFORM_SOLARIS_X86 "solaris_x86"
+#define PLATFORM_FREEBSD_X86 "freebsd_x86"
+#define PLATFORM_FREEBSD_X86_64 "freebsd_x86_64"
+#define PLATFORM_MACOSX_X86 "macosx_x86"
+#define PLATFORM_MACOSX_PPC "macosx_powerpc"
+#define PLATFORM_OS2_X86 "os2_x86"
+
+
+
+
+
+
+
+
+
+#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
+using ::rtl::OUString;
+namespace css = ::com::sun::star;
+
+namespace dp_misc
+{
+namespace
+{
+ struct StrOperatingSystem :
+ public rtl::StaticWithInit<const OUString, StrOperatingSystem> {
+ const OUString operator () () {
+ OUString os( RTL_CONSTASCII_USTRINGPARAM("$_OS") );
+ ::rtl::Bootstrap::expandMacros( os );
+ return os;
+ }
+ };
+
+ struct StrCPU :
+ public rtl::StaticWithInit<const OUString, StrCPU> {
+ const OUString operator () () {
+ OUString arch( RTL_CONSTASCII_USTRINGPARAM("$_ARCH") );
+ ::rtl::Bootstrap::expandMacros( arch );
+ return arch;
+ }
+ };
+
+
+ struct StrPlatform : public rtl::StaticWithInit<
+ const OUString, StrPlatform> {
+ const OUString operator () () {
+ ::rtl::OUStringBuffer buf;
+ buf.append( StrOperatingSystem::get() );
+ buf.append( static_cast<sal_Unicode>('_') );
+ OUString arch( RTL_CONSTASCII_USTRINGPARAM("$_ARCH") );
+ ::rtl::Bootstrap::expandMacros( arch );
+ buf.append( arch );
+ return buf.makeStringAndClear();
+ }
+ };
+
+ bool checkOSandCPU(OUString const & os, OUString const & cpu)
+ {
+ return os.equals(StrOperatingSystem::get())
+ && cpu.equals(StrCPU::get());
+ }
+
+ bool isValidPlatform(OUString const & token )
+ {
+ bool ret = false;
+ if (token.equals(OUSTR(PLATFORM_ALL)))
+ ret = true;
+ else if (token.equals(OUSTR(PLATFORM_WIN_X86)))
+ ret = checkOSandCPU(OUSTR("Windows"), OUSTR("x86"));
+ else if (token.equals(OUSTR(PLATFORM_LINUX_X86)))
+ ret = checkOSandCPU(OUSTR("Linux"), OUSTR("x86"));
+ else if (token.equals(OUSTR(PLATFORM_LINUX_X86_64)))
+ ret = checkOSandCPU(OUSTR("Linux"), OUSTR("X86_64"));
+ else if (token.equals(OUSTR(PLATFORM_LINUX_SPARC)))
+ ret = checkOSandCPU(OUSTR("Linux"), OUSTR("SPARC"));
+ else if (token.equals(OUSTR(PLATFORM_LINUX_POWERPC)))
+ ret = checkOSandCPU(OUSTR("Linux"), OUSTR("PowerPC"));
+ else if (token.equals(OUSTR(PLATFORM_LINUX_POWERPC64)))
+ ret = checkOSandCPU(OUSTR("Linux"), OUSTR("PowerPC_64"));
+ else if (token.equals(OUSTR(PLATFORM_LINUX_ARM_EABI)))
+ ret = checkOSandCPU(OUSTR("Linux"), OUSTR("ARM_EABI"));
+ else if (token.equals(OUSTR(PLATFORM_LINUX_ARM_OABI)))
+ ret = checkOSandCPU(OUSTR("Linux"), OUSTR("ARM_OABI"));
+ else if (token.equals(OUSTR(PLATFORM_LINUX_MIPS_EL)))
+ ret = checkOSandCPU(OUSTR("Linux"), OUSTR("MIPS_EL"));
+ else if (token.equals(OUSTR(PLATFORM_LINUX_MIPS_EB)))
+ ret = checkOSandCPU(OUSTR("Linux"), OUSTR("MIPS_EB"));
+ else if (token.equals(OUSTR(PLATFORM_LINUX_IA64)))
+ ret = checkOSandCPU(OUSTR("Linux"), OUSTR("IA64"));
+ else if (token.equals(OUSTR(PLATFORM_LINUX_S390)))
+ ret = checkOSandCPU(OUSTR("Linux"), OUSTR("S390"));
+ else if (token.equals(OUSTR(PLATFORM_LINUX_S390x)))
+ ret = checkOSandCPU(OUSTR("Linux"), OUSTR("S390x"));
+ else if (token.equals(OUSTR(PLATFORM_SOLARIS_SPARC)))
+ ret = checkOSandCPU(OUSTR("Solaris"), OUSTR("SPARC"));
+ else if (token.equals(OUSTR(PLATFORM_SOLARIS_SPARC64)))
+ ret = checkOSandCPU(OUSTR("Solaris"), OUSTR("SPARC64"));
+ else if (token.equals(OUSTR(PLATFORM_SOLARIS_X86)))
+ ret = checkOSandCPU(OUSTR("Solaris"), OUSTR("x86"));
+ else if (token.equals(OUSTR(PLATFORM_FREEBSD_X86)))
+ ret = checkOSandCPU(OUSTR("FreeBSD"), OUSTR("x86"));
+ else if (token.equals(OUSTR(PLATFORM_FREEBSD_X86_64)))
+ ret = checkOSandCPU(OUSTR("FreeBSD"), OUSTR("X86_64"));
+ else if (token.equals(OUSTR(PLATFORM_MACOSX_X86)))
+ ret = checkOSandCPU(OUSTR("MacOSX"), OUSTR("x86"));
+ else if (token.equals(OUSTR(PLATFORM_MACOSX_PPC)))
+ ret = checkOSandCPU(OUSTR("MacOSX"), OUSTR("PowerPC"));
+ else if (token.equals(OUSTR(PLATFORM_OS2_X86)))
+ ret = checkOSandCPU(OUSTR("OS2"), OUSTR("x86"));
+ else
+ {
+ OSL_ENSURE(0, "Extension Manager: The extension supports an unknown platform. "
+ "Check the platform element in the descripion.xml");
+ ret = false;
+ }
+ return ret;
+ }
+
+} // anon namespace
+//=============================================================================
+
+OUString const & getPlatformString()
+{
+ return StrPlatform::get();
+}
+
+bool platform_fits( OUString const & platform_string )
+{
+ sal_Int32 index = 0;
+ for (;;)
+ {
+ const OUString token(
+ platform_string.getToken( 0, ',', index ).trim() );
+ // check if this platform:
+ if (token.equalsIgnoreAsciiCase( StrPlatform::get() ) ||
+ (token.indexOf( '_' ) < 0 && /* check OS part only */
+ token.equalsIgnoreAsciiCase( StrOperatingSystem::get() )))
+ {
+ return true;
+ }
+ if (index < 0)
+ break;
+ }
+ return false;
+}
+
+bool hasValidPlatform( css::uno::Sequence<OUString> const & platformStrings)
+{
+ bool ret = false;
+ for (sal_Int32 i = 0; i < platformStrings.getLength(); i++)
+ {
+ if (isValidPlatform(platformStrings[i]))
+ {
+ ret = true;
+ break;
+ }
+ }
+ return ret;
+}
+
+}
+
diff --git a/desktop/source/deployment/misc/dp_resource.cxx b/desktop/source/deployment/misc/dp_resource.cxx
new file mode 100644
index 000000000000..e89fb9358b26
--- /dev/null
+++ b/desktop/source/deployment/misc/dp_resource.cxx
@@ -0,0 +1,236 @@
+/*************************************************************************
+ *
+ * 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: dp_resource.cxx,v $
+ * $Revision: 1.19 $
+ *
+ * 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_desktop.hxx"
+
+#include "dp_misc.h"
+#include "dp_resource.h"
+#include "osl/module.hxx"
+#include "osl/mutex.hxx"
+#include "rtl/ustring.h"
+#include "cppuhelper/implbase1.hxx"
+#include "unotools/configmgr.hxx"
+
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using ::rtl::OUString;
+
+namespace dp_misc {
+namespace {
+
+struct OfficeLocale :
+ public rtl::StaticWithInit<const OUString, OfficeLocale> {
+ const OUString operator () () {
+ OUString slang;
+ if (! (::utl::ConfigManager::GetDirectConfigProperty(
+ ::utl::ConfigManager::LOCALE ) >>= slang))
+ throw RuntimeException( OUSTR("Cannot determine language!"), 0 );
+ //fallback, the locale is currently only set when the user starts the
+ //office for the first time.
+ if (slang.getLength() == 0)
+ slang = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("en-US"));
+ return slang;
+ }
+};
+
+struct DeploymentResMgr : public rtl::StaticWithInit<
+ ResMgr *, DeploymentResMgr> {
+ ResMgr * operator () () {
+ return ResMgr::CreateResMgr( "deployment", getOfficeLocale() );
+ }
+};
+
+osl::Mutex s_mutex;
+
+} // anon namespace
+
+//==============================================================================
+ResId getResId( USHORT id )
+{
+ const osl::MutexGuard guard( s_mutex );
+ return ResId( id, *DeploymentResMgr::get() );
+}
+
+//==============================================================================
+String getResourceString( USHORT id )
+{
+ const osl::MutexGuard guard( s_mutex );
+ String ret( ResId( id, *DeploymentResMgr::get() ) );
+ if (ret.SearchAscii( "%PRODUCTNAME" ) != STRING_NOTFOUND) {
+ static String s_brandName;
+ if (s_brandName.Len() == 0) {
+ OUString brandName(
+ ::utl::ConfigManager::GetDirectConfigProperty(
+ ::utl::ConfigManager::PRODUCTNAME ).get<OUString>() );
+ s_brandName = brandName;
+ }
+ ret.SearchAndReplaceAllAscii( "%PRODUCTNAME", s_brandName );
+ }
+ return ret;
+}
+
+//throws an Exception on failure
+//primary subtag 2 or three letters(A-Z, a-z), i or x
+void checkPrimarySubtag(::rtl::OUString const & tag)
+{
+ sal_Int32 len = tag.getLength();
+ sal_Unicode const * arLang = tag.getStr();
+ if (len < 1 || len > 3)
+ throw Exception(OUSTR("Invalid language string."), 0);
+
+ if (len == 1
+ && (arLang[0] != 'i' && arLang[0] != 'x'))
+ throw Exception(OUSTR("Invalid language string."), 0);
+
+ if (len == 2 || len == 3)
+ {
+ for (sal_Int32 i = 0; i < len; i++)
+ {
+ if ( !((arLang[i] >= 'A' && arLang[i] <= 'Z')
+ || (arLang[i] >= 'a' && arLang[i] <= 'z')))
+ {
+ throw Exception(OUSTR("Invalid language string."), 0);
+ }
+ }
+ }
+}
+
+//throws an Exception on failure
+//second subtag 2 letter country code or 3-8 letter other code(A-Z, a-z, 0-9)
+void checkSecondSubtag(::rtl::OUString const & tag, bool & bIsCountry)
+{
+ sal_Int32 len = tag.getLength();
+ sal_Unicode const * arLang = tag.getStr();
+ if (len < 2 || len > 8)
+ throw Exception(OUSTR("Invalid language string."), 0);
+ //country code
+ bIsCountry = false;
+ if (len == 2)
+ {
+ for (sal_Int32 i = 0; i < 2; i++)
+ {
+ if (!( (arLang[i] >= 'A' && arLang[i] <= 'Z')
+ || (arLang[i] >= 'a' && arLang[i] <= 'z')))
+ {
+ throw Exception(OUSTR("Invalid language string."), 0);
+ }
+ }
+ bIsCountry = true;
+ }
+
+ if (len > 2)
+ {
+ for (sal_Int32 i = 0; i < len; i++)
+ {
+ if (!( (arLang[i] >= 'A' && arLang[i] <= 'Z')
+ || (arLang[i] >= 'a' && arLang[i] <= 'z')
+ || (arLang[i] >= '0' && arLang[i] <= '9') ))
+ {
+ throw Exception(OUSTR("Invalid language string."), 0);
+ }
+ }
+ }
+}
+
+void checkThirdSubtag(::rtl::OUString const & tag)
+{
+ sal_Int32 len = tag.getLength();
+ sal_Unicode const * arLang = tag.getStr();
+ if (len < 1 || len > 8)
+ throw Exception(OUSTR("Invalid language string."), 0);
+
+ for (sal_Int32 i = 0; i < len; i++)
+ {
+ if (!( (arLang[i] >= 'A' && arLang[i] <= 'Z')
+ || (arLang[i] >= 'a' && arLang[i] <= 'z')
+ || (arLang[i] >= '0' && arLang[i] <= '9') ))
+ {
+ throw Exception(OUSTR("Invalid language string."), 0);
+ }
+ }
+}
+
+//=============================================================================
+
+//We parse the string acording to RFC 3066
+//We only use the primary sub-tag and two subtags. That is lang-country-variant
+//We do some simple tests if the string is correct. Actually this should do a
+//validating parser
+//We may have the case that there is no country tag, for example en-welsh
+::com::sun::star::lang::Locale toLocale( ::rtl::OUString const & slang )
+{
+ OUString _sLang = slang.trim();
+ ::com::sun::star::lang::Locale locale;
+ sal_Int32 nIndex = 0;
+ OUString lang = _sLang.getToken( 0, '-', nIndex );
+ checkPrimarySubtag(lang);
+ locale.Language = lang;
+ OUString country = _sLang.getToken( 0, '-', nIndex );
+ if (country.getLength() > 0)
+ {
+ bool bIsCountry = false;
+ checkSecondSubtag(country, bIsCountry);
+ if (bIsCountry)
+ {
+ locale.Country = country;
+ }
+ else
+ {
+ locale.Variant = country;
+ }
+ }
+ if (locale.Variant.getLength() == 0)
+ {
+ OUString variant = _sLang.getToken( 0, '-', nIndex );
+ if (variant.getLength() > 0)
+ {
+ checkThirdSubtag(variant);
+ locale.Variant = variant;
+ }
+ }
+
+ return locale;
+}
+
+//==============================================================================
+lang::Locale getOfficeLocale()
+{
+ return toLocale(OfficeLocale::get());
+}
+
+::rtl::OUString getOfficeLocaleString()
+{
+ return OfficeLocale::get();
+}
+
+}
+
diff --git a/desktop/source/deployment/misc/dp_ucb.cxx b/desktop/source/deployment/misc/dp_ucb.cxx
new file mode 100644
index 000000000000..8a4f55caae1a
--- /dev/null
+++ b/desktop/source/deployment/misc/dp_ucb.cxx
@@ -0,0 +1,282 @@
+/*************************************************************************
+ *
+ * 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: dp_ucb.cxx,v $
+ * $Revision: 1.13 $
+ *
+ * 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_desktop.hxx"
+
+#include "dp_misc.hrc"
+#include "dp_misc.h"
+#include "dp_ucb.h"
+#include "rtl/uri.hxx"
+#include "rtl/ustrbuf.hxx"
+#include "ucbhelper/content.hxx"
+#include "xmlscript/xml_helper.hxx"
+#include "com/sun/star/io/XInputStream.hpp"
+#include "com/sun/star/ucb/CommandFailedException.hpp"
+#include "com/sun/star/ucb/XContentCreator.hpp"
+#include "com/sun/star/ucb/ContentInfo.hpp"
+#include "com/sun/star/ucb/ContentInfoAttribute.hpp"
+
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::ucb;
+using ::rtl::OUString;
+
+namespace dp_misc
+{
+
+const OUString StrTitle::operator () ()
+{
+ return OUSTR("Title");
+}
+
+//==============================================================================
+bool create_ucb_content(
+ ::ucbhelper::Content * ret_ucbContent, OUString const & url,
+ Reference<XCommandEnvironment> const & xCmdEnv,
+ bool throw_exc )
+{
+ try {
+ // Existense check...
+ // content ctor/isFolder() will throw exception in case the resource
+ // does not exist.
+
+ // dilemma: no chance to use the given iahandler here, because it would
+ // raise no such file dialogs, else no interaction for
+ // passwords, ...? xxx todo
+ ::ucbhelper::Content ucbContent(
+ url, Reference<XCommandEnvironment>() );
+
+ ucbContent.isFolder();
+
+ if (ret_ucbContent != 0)
+ {
+ ucbContent.setCommandEnvironment( xCmdEnv );
+ *ret_ucbContent = ucbContent;
+ }
+ return true;
+ }
+ catch (RuntimeException &) {
+ throw;
+ }
+ catch (Exception &) {
+ if (throw_exc)
+ throw;
+ }
+ return false;
+}
+
+//==============================================================================
+bool create_folder(
+ ::ucbhelper::Content * ret_ucb_content, OUString const & url_,
+ Reference<XCommandEnvironment> const & xCmdEnv, bool throw_exc )
+{
+ ::ucbhelper::Content ucb_content;
+ if (create_ucb_content(
+ &ucb_content, url_, xCmdEnv, false /* no throw */ ))
+ {
+ if (ucb_content.isFolder()) {
+ if (ret_ucb_content != 0)
+ *ret_ucb_content = ucb_content;
+ return true;
+ }
+ }
+
+ OUString url( url_ );
+ // xxx todo: find parent
+ sal_Int32 slash = url.lastIndexOf( '/' );
+ if (slash < 0) {
+ // fallback:
+ url = expandUnoRcUrl( url );
+ slash = url.lastIndexOf( '/' );
+ }
+ if (slash < 0) {
+ // invalid: has to be at least "auth:/..."
+ if (throw_exc)
+ throw ContentCreationException(
+ OUSTR("Cannot create folder (invalid path): ") + url,
+ Reference<XInterface>(), ContentCreationError_UNKNOWN );
+ return false;
+ }
+ ::ucbhelper::Content parentContent;
+ if (! create_folder(
+ &parentContent, url.copy( 0, slash ), xCmdEnv, throw_exc ))
+ return false;
+ Reference<XContentCreator> xCreator( parentContent.get(), UNO_QUERY );
+ if (xCreator.is())
+ {
+ const Any title( ::rtl::Uri::decode( url.copy( slash + 1 ),
+ rtl_UriDecodeWithCharset,
+ RTL_TEXTENCODING_UTF8 ) );
+ const Sequence<ContentInfo> infos(
+ xCreator->queryCreatableContentsInfo() );
+ for ( sal_Int32 pos = 0; pos < infos.getLength(); ++pos )
+ {
+ // look KIND_FOLDER:
+ ContentInfo const & info = infos[ pos ];
+ if ((info.Attributes & ContentInfoAttribute::KIND_FOLDER) != 0)
+ {
+ // make sure the only required bootstrap property is "Title":
+ Sequence<beans::Property> const & rProps = info.Properties;
+ if (rProps.getLength() != 1 ||
+ !rProps[ 0 ].Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("Title") ))
+ continue;
+
+ try {
+ if (parentContent.insertNewContent(
+ info.Type,
+ Sequence<OUString>( &StrTitle::get(), 1 ),
+ Sequence<Any>( &title, 1 ),
+ ucb_content )) {
+ if (ret_ucb_content != 0)
+ *ret_ucb_content = ucb_content;
+ return true;
+ }
+ }
+ catch (RuntimeException &) {
+ throw;
+ }
+ catch (CommandFailedException &) {
+ // Interaction Handler already handled the error
+ // that has occured...
+ }
+ catch (Exception &) {
+ if (throw_exc)
+ throw;
+ return false;
+ }
+ }
+ }
+ }
+ if (throw_exc)
+ throw ContentCreationException(
+ OUSTR("Cannot create folder: ") + url,
+ Reference<XInterface>(), ContentCreationError_UNKNOWN );
+ return false;
+}
+
+//==============================================================================
+bool erase_path( OUString const & url,
+ Reference<XCommandEnvironment> const & xCmdEnv,
+ bool throw_exc )
+{
+ ::ucbhelper::Content ucb_content;
+ if (create_ucb_content( &ucb_content, url, xCmdEnv, false /* no throw */ ))
+ {
+ try {
+ ucb_content.executeCommand(
+ OUSTR("delete"), Any( true /* delete physically */ ) );
+ }
+ catch (RuntimeException &) {
+ throw;
+ }
+ catch (Exception &) {
+ if (throw_exc)
+ throw;
+ return false;
+ }
+ }
+ return true;
+}
+
+//==============================================================================
+::rtl::ByteSequence readFile( ::ucbhelper::Content & ucb_content )
+{
+ ::rtl::ByteSequence bytes;
+ Reference<io::XOutputStream> xStream(
+ ::xmlscript::createOutputStream( &bytes ) );
+ if (! ucb_content.openStream( xStream ))
+ throw RuntimeException(
+ OUSTR(
+ "::ucbhelper::Content::openStream( XOutputStream ) failed!"),
+ 0 );
+ return bytes;
+}
+
+//==============================================================================
+bool readLine( OUString * res, OUString const & startingWith,
+ ::ucbhelper::Content & ucb_content, rtl_TextEncoding textenc )
+{
+ // read whole file:
+ ::rtl::ByteSequence bytes( readFile( ucb_content ) );
+ OUString file( reinterpret_cast<sal_Char const *>(bytes.getConstArray()),
+ bytes.getLength(), textenc );
+ sal_Int32 pos = 0;
+ for (;;)
+ {
+ if (file.match( startingWith, pos ))
+ {
+ ::rtl::OUStringBuffer buf;
+ sal_Int32 start = pos;
+ pos += startingWith.getLength();
+ for (;;)
+ {
+ pos = file.indexOf( LF, pos );
+ if (pos < 0) { // EOF
+ buf.append( file.copy( start ) );
+ }
+ else
+ {
+ if (pos > 0 && file[ pos - 1 ] == CR)
+ {
+ // consume extra CR
+ buf.append( file.copy( start, pos - start - 1 ) );
+ ++pos;
+ }
+ else
+ buf.append( file.copy( start, pos - start ) );
+ ++pos; // consume LF
+ // check next line:
+ if (pos < file.getLength() &&
+ (file[ pos ] == ' ' || file[ pos ] == '\t'))
+ {
+ buf.append( static_cast<sal_Unicode>(' ') );
+ ++pos;
+ start = pos;
+ continue;
+ }
+ }
+ break;
+ }
+ *res = buf.makeStringAndClear();
+ return true;
+ }
+ // next line:
+ sal_Int32 next_lf = file.indexOf( LF, pos );
+ if (next_lf < 0) // EOF
+ break;
+ pos = next_lf + 1;
+ }
+ return false;
+}
+
+}
diff --git a/desktop/source/deployment/misc/dp_version.cxx b/desktop/source/deployment/misc/dp_version.cxx
new file mode 100644
index 000000000000..dac726583693
--- /dev/null
+++ b/desktop/source/deployment/misc/dp_version.cxx
@@ -0,0 +1,83 @@
+/*************************************************************************
+ *
+ * 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: dp_version.cxx,v $
+ * $Revision: 1.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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "sal/config.h"
+
+#include "com/sun/star/deployment/XPackage.hpp"
+#include "rtl/ustring.hxx"
+
+#include "dp_version.hxx"
+
+namespace {
+
+namespace css = ::com::sun::star;
+
+::rtl::OUString getElement(::rtl::OUString const & version, ::sal_Int32 * index)
+{
+ while (*index < version.getLength() && version[*index] == '0') {
+ ++*index;
+ }
+ return version.getToken(0, '.', *index);
+}
+
+}
+
+namespace dp_misc {
+
+::dp_misc::Order compareVersions(
+ ::rtl::OUString const & version1, ::rtl::OUString const & version2)
+{
+ for (::sal_Int32 i1 = 0, i2 = 0; i1 >= 0 || i2 >= 0;) {
+ ::rtl::OUString e1(getElement(version1, &i1));
+ ::rtl::OUString e2(getElement(version2, &i2));
+ if (e1.getLength() < e2.getLength()) {
+ return ::dp_misc::LESS;
+ } else if (e1.getLength() > e2.getLength()) {
+ return ::dp_misc::GREATER;
+ } else if (e1 < e2) {
+ return ::dp_misc::LESS;
+ } else if (e1 > e2) {
+ return ::dp_misc::GREATER;
+ }
+ }
+ return ::dp_misc::EQUAL;
+}
+
+::dp_misc::Order comparePackageVersions(
+ css::uno::Reference< css::deployment::XPackage > const & package1,
+ css::uno::Reference< css::deployment::XPackage > const & package2)
+{
+ return compareVersions(package1->getVersion(), package2->getVersion());
+}
+
+}
diff --git a/desktop/source/deployment/misc/makefile.mk b/desktop/source/deployment/misc/makefile.mk
new file mode 100644
index 000000000000..b06788de8d8b
--- /dev/null
+++ b/desktop/source/deployment/misc/makefile.mk
@@ -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: makefile.mk,v $
+#
+# $Revision: 1.17 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ = ..$/..$/..
+
+PRJNAME = desktop
+TARGET = deployment_misc
+USE_DEFFILE = TRUE
+ENABLE_EXCEPTIONS = TRUE
+VISIBILITY_HIDDEN=TRUE
+
+.IF "$(GUI)"=="OS2"
+TARGET = deplmisc
+.ENDIF
+
+.INCLUDE : settings.mk
+
+# Reduction of exported symbols:
+CDEFS += -DDESKTOP_DEPLOYMENTMISC_DLLIMPLEMENTATION
+
+.IF "$(SYSTEM_DB)" == "YES"
+CFLAGS+=-DSYSTEM_DB -I$(DB_INCLUDES)
+.ENDIF
+
+SRS1NAME = $(TARGET)
+SRC1FILES = \
+ dp_misc.src
+
+.IF "$(GUI)"=="OS2"
+SHL1TARGET = $(TARGET)
+.ELSE
+SHL1TARGET = deploymentmisc$(DLLPOSTFIX)
+.ENDIF
+SHL1OBJS = \
+ $(SLO)$/dp_misc.obj \
+ $(SLO)$/dp_resource.obj \
+ $(SLO)$/dp_identifier.obj \
+ $(SLO)$/dp_interact.obj \
+ $(SLO)$/dp_ucb.obj \
+ $(SLO)$/db.obj \
+ $(SLO)$/dp_version.obj \
+ $(SLO)$/dp_descriptioninfoset.obj \
+ $(SLO)$/dp_dependencies.obj \
+ $(SLO)$/dp_platform.obj
+
+SHL1STDLIBS = \
+ $(BERKELEYLIB) \
+ $(CPPUHELPERLIB) \
+ $(CPPULIB) \
+ $(SALLIB) \
+ $(TOOLSLIB) \
+ $(UCBHELPERLIB) \
+ $(UNOTOOLSLIB) \
+ $(XMLSCRIPTLIB)
+.IF "$(GUI)"=="OS2"
+SHL1IMPLIB = ideploymentmisc$(DLLPOSTFIX)
+LIB1TARGET = $(SLB)$/_deplmisc.lib
+LIB1OBJFILES = $(SHL1OBJS)
+DEFLIB1NAME = _deplmisc
+.ELSE
+SHL1IMPLIB = i$(SHL1TARGET)
+.ENDIF
+DEF1NAME = $(SHL1TARGET)
+
+SLOFILES = $(SHL1OBJS)
+
+.INCLUDE : ..$/target.pmk
+.INCLUDE : target.mk
+
diff --git a/desktop/source/deployment/registry/component/dp_component.cxx b/desktop/source/deployment/registry/component/dp_component.cxx
new file mode 100644
index 000000000000..e9f8a07a96ae
--- /dev/null
+++ b/desktop/source/deployment/registry/component/dp_component.cxx
@@ -0,0 +1,1389 @@
+/*************************************************************************
+ *
+ * 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: dp_component.cxx,v $
+ * $Revision: 1.24 $
+ *
+ * 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_desktop.hxx"
+
+#include "dp_component.hrc"
+#include "dp_backend.h"
+#include "dp_platform.hxx"
+#include "dp_ucb.h"
+#include "rtl/string.hxx"
+#include "rtl/strbuf.hxx"
+#include "rtl/ustrbuf.hxx"
+#include "rtl/uri.hxx"
+#include "cppuhelper/exc_hlp.hxx"
+#include "ucbhelper/content.hxx"
+#include "comphelper/anytostring.hxx"
+#include "comphelper/servicedecl.hxx"
+#include "comphelper/sequence.hxx"
+#include "xmlscript/xml_helper.hxx"
+#include "svtools/inettype.hxx"
+#include "com/sun/star/lang/WrappedTargetRuntimeException.hpp"
+#include "com/sun/star/container/XNameContainer.hpp"
+#include "com/sun/star/container/XHierarchicalNameAccess.hpp"
+#include "com/sun/star/container/XSet.hpp"
+#include "com/sun/star/registry/XSimpleRegistry.hpp"
+#include "com/sun/star/registry/XImplementationRegistration.hpp"
+#include "com/sun/star/loader/XImplementationLoader.hpp"
+#include "com/sun/star/io/XInputStream.hpp"
+#include "com/sun/star/ucb/NameClash.hpp"
+#include "com/sun/star/util/XMacroExpander.hpp"
+#include <list>
+#include <hash_map>
+#include <vector>
+#include <memory>
+#include <algorithm>
+
+
+using namespace ::dp_misc;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::ucb;
+using ::rtl::OUString;
+
+namespace dp_registry {
+namespace backend {
+namespace component {
+namespace {
+
+typedef ::std::list<OUString> t_stringlist;
+typedef ::std::vector< ::std::pair<OUString, OUString> > t_stringpairvec;
+
+/** return a vector of bootstrap variables which have been provided
+ as command arguments.
+*/
+::std::vector<OUString> getCmdBootstrapVariables()
+{
+ ::std::vector<OUString> ret;
+ sal_uInt32 count = osl_getCommandArgCount();
+ for (sal_uInt32 i = 0; i < count; i++)
+ {
+ OUString arg;
+ osl_getCommandArg(i, &arg.pData);
+ if (arg.matchAsciiL("-env:", 5))
+ ret.push_back(arg);
+ }
+ return ret;
+}
+
+bool jarManifestHeaderPresent(
+ OUString const & url, OUString const & name,
+ Reference<XCommandEnvironment> const & xCmdEnv )
+{
+ ::rtl::OUStringBuffer buf;
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("vnd.sun.star.zip://") );
+ buf.append(
+ ::rtl::Uri::encode(
+ url, rtl_UriCharClassRegName, rtl_UriEncodeIgnoreEscapes,
+ RTL_TEXTENCODING_UTF8 ) );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("/META-INF/MANIFEST.MF") );
+ ::ucbhelper::Content manifestContent;
+ OUString line;
+ return
+ create_ucb_content(
+ &manifestContent, buf.makeStringAndClear(), xCmdEnv,
+ false /* no throw */ )
+ && readLine( &line, name, manifestContent, RTL_TEXTENCODING_ASCII_US );
+}
+
+//==============================================================================
+class BackendImpl : public ::dp_registry::backend::PackageRegistryBackend
+{
+ class ComponentPackageImpl : public ::dp_registry::backend::Package
+ {
+ BackendImpl * getMyBackend() const;
+
+ const OUString m_loader;
+ Reference<XComponentContext> m_xRemoteContext;
+
+ enum reg {
+ REG_UNINIT, REG_VOID, REG_REGISTERED, REG_NOT_REGISTERED
+ } m_registered;
+
+ Reference<loader::XImplementationLoader> getComponentInfo(
+ t_stringlist * pImplNames, t_stringpairvec * pSingletons,
+ Reference<XComponentContext> const & xContext );
+
+ virtual void SAL_CALL disposing();
+
+ // Package
+ virtual beans::Optional< beans::Ambiguous<sal_Bool> > isRegistered_(
+ ::osl::ResettableMutexGuard & guard,
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+ virtual void processPackage_(
+ ::osl::ResettableMutexGuard & guard,
+ bool registerPackage,
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+
+ const Reference<registry::XSimpleRegistry> getRDB() const;
+
+ public:
+ inline ComponentPackageImpl(
+ ::rtl::Reference<PackageRegistryBackend> const & myBackend,
+ OUString const & url, OUString const & name,
+ Reference<deployment::XPackageTypeInfo> const & xPackageType,
+ OUString const & loader )
+ : Package( myBackend, url, name, name /* display-name */,
+ xPackageType ),
+ m_loader( loader ),
+ m_registered( REG_UNINIT )
+ {}
+ };
+ friend class ComponentPackageImpl;
+
+ class TypelibraryPackageImpl : public ::dp_registry::backend::Package
+ {
+ BackendImpl * getMyBackend() const;
+
+ const bool m_jarFile;
+ Reference<container::XHierarchicalNameAccess> m_xTDprov;
+
+ virtual void SAL_CALL disposing();
+
+ // Package
+ virtual beans::Optional< beans::Ambiguous<sal_Bool> > isRegistered_(
+ ::osl::ResettableMutexGuard & guard,
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+ virtual void processPackage_(
+ ::osl::ResettableMutexGuard & guard,
+ bool registerPackage,
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+
+ public:
+ inline TypelibraryPackageImpl(
+ ::rtl::Reference<PackageRegistryBackend> const & myBackend,
+ OUString const & url, OUString const & name,
+ Reference<deployment::XPackageTypeInfo> const & xPackageType,
+ bool jarFile )
+ : Package( myBackend, url, name, name /* display-name */,
+ xPackageType ),
+ m_jarFile( jarFile )
+ {}
+ };
+ friend class TypelibraryPackageImpl;
+
+ t_stringlist m_jar_typelibs;
+ t_stringlist m_rdb_typelibs;
+ t_stringlist & getTypelibs( bool jar ) {
+ return jar ? m_jar_typelibs : m_rdb_typelibs;
+ }
+
+ bool m_unorc_inited;
+ bool m_unorc_modified;
+ bool bSwitchedRdbFiles;
+
+ typedef ::std::hash_map< OUString, Reference<XInterface>,
+ ::rtl::OUStringHash > t_string2object;
+ t_string2object m_backendObjects;
+
+ // PackageRegistryBackend
+ virtual Reference<deployment::XPackage> bindPackage_(
+ OUString const & url, OUString const & mediaType,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+
+ virtual void SAL_CALL disposing();
+
+ const Reference<deployment::XPackageTypeInfo> m_xDynComponentTypeInfo;
+ const Reference<deployment::XPackageTypeInfo> m_xJavaComponentTypeInfo;
+ const Reference<deployment::XPackageTypeInfo> m_xPythonComponentTypeInfo;
+ const Reference<deployment::XPackageTypeInfo> m_xRDBTypelibTypeInfo;
+ const Reference<deployment::XPackageTypeInfo> m_xJavaTypelibTypeInfo;
+ Sequence< Reference<deployment::XPackageTypeInfo> > m_typeInfos;
+
+ OUString m_commonRDB;
+ OUString m_nativeRDB;
+ Reference<registry::XSimpleRegistry> m_xCommonRDB;
+ Reference<registry::XSimpleRegistry> m_xNativeRDB;
+
+ void unorc_verify_init( Reference<XCommandEnvironment> const & xCmdEnv );
+ void unorc_flush( Reference<XCommandEnvironment> const & xCmdEnv );
+
+ Reference<XInterface> getObject( OUString const & id );
+ Reference<XInterface> insertObject(
+ OUString const & id, Reference<XInterface> const & xObject );
+ void releaseObject( OUString const & id );
+
+ bool addToUnoRc( bool jarFile, OUString const & url,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+ bool removeFromUnoRc( bool jarFile, OUString const & url,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+ bool hasInUnoRc( bool jarFile, OUString const & url );
+
+
+
+public:
+ BackendImpl( Sequence<Any> const & args,
+ Reference<XComponentContext> const & xComponentContext );
+
+ // XPackageRegistry
+ virtual Sequence< Reference<deployment::XPackageTypeInfo> > SAL_CALL
+ getSupportedPackageTypes() throw (RuntimeException);
+
+ using PackageRegistryBackend::disposing;
+
+ //Will be called from ComponentPackageImpl
+ void initServiceRdbFiles();
+};
+
+//______________________________________________________________________________
+const Reference<registry::XSimpleRegistry>
+BackendImpl::ComponentPackageImpl::getRDB() const
+{
+ BackendImpl * that = getMyBackend();
+ //Late "initialization" of the services rdb files
+ //This is to prevent problems when running several
+ //instances of OOo with root rights in parallel. This
+ //would otherwise cause problems when copying the rdbs.
+ //Now this code is only performed if isRegistered or processPackage
+ //is called.
+ {
+ const ::osl::MutexGuard guard( getMutex() );
+ if (!that->bSwitchedRdbFiles)
+ {
+ that->bSwitchedRdbFiles = true;
+ that->initServiceRdbFiles();
+ }
+ }
+
+ if (m_loader.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("com.sun.star.loader.SharedLibrary") ))
+ return that->m_xNativeRDB;
+ else
+ return that->m_xCommonRDB;
+}
+
+BackendImpl * BackendImpl::ComponentPackageImpl::getMyBackend() const
+{
+ BackendImpl * pBackend = static_cast<BackendImpl *>(m_myBackend.get());
+ if (NULL == pBackend)
+ {
+ //Throws a DisposedException
+ check();
+ //We should never get here...
+ throw RuntimeException(
+ OUSTR("Failed to get the BackendImpl"),
+ static_cast<OWeakObject*>(const_cast<ComponentPackageImpl *>(this)));
+ }
+ return pBackend;
+}
+
+
+//______________________________________________________________________________
+void BackendImpl::ComponentPackageImpl::disposing()
+{
+ m_xRemoteContext.clear();
+ Package::disposing();
+}
+
+//______________________________________________________________________________
+void BackendImpl::TypelibraryPackageImpl::disposing()
+{
+ m_xTDprov.clear();
+ Package::disposing();
+}
+
+//______________________________________________________________________________
+void BackendImpl::disposing()
+{
+ try {
+ m_backendObjects = t_string2object();
+ if (m_xNativeRDB.is()) {
+ m_xNativeRDB->close();
+ m_xNativeRDB.clear();
+ }
+ if (m_xCommonRDB.is()) {
+ m_xCommonRDB->close();
+ m_xCommonRDB.clear();
+ }
+ unorc_flush( Reference<XCommandEnvironment>() );
+
+ PackageRegistryBackend::disposing();
+ }
+ catch (RuntimeException &) {
+ throw;
+ }
+ catch (Exception &) {
+ Any exc( ::cppu::getCaughtException() );
+ throw lang::WrappedTargetRuntimeException(
+ OUSTR("caught unexpected exception while disposing..."),
+ static_cast<OWeakObject *>(this), exc );
+ }
+}
+
+void BackendImpl::initServiceRdbFiles()
+{
+ const Reference<XCommandEnvironment> xCmdEnv;
+ if (! m_readOnly) {
+ ::ucbhelper::Content cacheDir( getCachePath(), xCmdEnv );
+ ::ucbhelper::Content oldRDB;
+ // switch common rdb:
+ if (m_commonRDB.getLength() > 0)
+ create_ucb_content(
+ &oldRDB, makeURL( getCachePath(), m_commonRDB ),
+ xCmdEnv, false /* no throw */ );
+ m_commonRDB = m_commonRDB.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("common.rdb") )
+ ? OUSTR("common_.rdb") : OUSTR("common.rdb");
+ if (oldRDB.get().is())
+ {
+
+ if (! cacheDir.transferContent(
+ oldRDB, ::ucbhelper::InsertOperation_COPY,
+ m_commonRDB, NameClash::OVERWRITE ))
+ {
+
+ throw RuntimeException(
+ OUSTR("UCB transferContent() failed!"), 0 );
+ }
+ oldRDB = ::ucbhelper::Content();
+ }
+ // switch native rdb:
+ if (m_nativeRDB.getLength() > 0)
+ create_ucb_content(
+ &oldRDB, makeURL( getCachePath(), m_nativeRDB ),
+ xCmdEnv, false /* no throw */ );
+ const OUString plt_rdb( getPlatformString() + OUSTR(".rdb") );
+ const OUString plt_rdb_( getPlatformString() + OUSTR("_.rdb") );
+ m_nativeRDB = m_nativeRDB.equals( plt_rdb ) ? plt_rdb_ : plt_rdb;
+ if (oldRDB.get().is())
+ {
+ if (! cacheDir.transferContent(
+ oldRDB, ::ucbhelper::InsertOperation_COPY,
+ m_nativeRDB, NameClash::OVERWRITE ))
+ throw RuntimeException(
+ OUSTR("UCB transferContent() failed!"), 0 );
+ }
+
+ // UNO is bootstrapped, flush for next process start:
+ m_unorc_modified = true;
+ unorc_flush( Reference<XCommandEnvironment>() );
+ }
+
+ // common rdb for java, native rdb for shared lib components
+ if (m_commonRDB.getLength() > 0) {
+ m_xCommonRDB.set(
+ m_xComponentContext->getServiceManager()
+ ->createInstanceWithContext(
+ OUSTR("com.sun.star.registry.SimpleRegistry"),
+ m_xComponentContext ), UNO_QUERY_THROW );
+ m_xCommonRDB->open(
+ makeURL( expandUnoRcUrl(getCachePath()), m_commonRDB ),
+ m_readOnly, !m_readOnly );
+ }
+ if (m_nativeRDB.getLength() > 0) {
+ m_xNativeRDB.set(
+ m_xComponentContext->getServiceManager()
+ ->createInstanceWithContext(
+ OUSTR("com.sun.star.registry.SimpleRegistry"),
+ m_xComponentContext ), UNO_QUERY_THROW );
+ m_xNativeRDB->open(
+ makeURL( expandUnoRcUrl(getCachePath()), m_nativeRDB ),
+ m_readOnly, !m_readOnly );
+ }
+}
+
+//______________________________________________________________________________
+BackendImpl::BackendImpl(
+ Sequence<Any> const & args,
+ Reference<XComponentContext> const & xComponentContext )
+ : PackageRegistryBackend( args, xComponentContext ),
+ m_unorc_inited( false ),
+ m_unorc_modified( false ),
+ bSwitchedRdbFiles(false),
+ m_xDynComponentTypeInfo( new Package::TypeInfo(
+ OUSTR("application/"
+ "vnd.sun.star.uno-component;"
+ "type=native;platform=") +
+ getPlatformString(),
+ OUSTR("*" SAL_DLLEXTENSION),
+ getResourceString(RID_STR_DYN_COMPONENT),
+ RID_IMG_COMPONENT,
+ RID_IMG_COMPONENT_HC ) ),
+ m_xJavaComponentTypeInfo( new Package::TypeInfo(
+ OUSTR("application/"
+ "vnd.sun.star.uno-component;"
+ "type=Java"),
+ OUSTR("*.jar"),
+ getResourceString(RID_STR_JAVA_COMPONENT),
+ RID_IMG_JAVA_COMPONENT,
+ RID_IMG_JAVA_COMPONENT_HC ) ),
+ m_xPythonComponentTypeInfo( new Package::TypeInfo(
+ OUSTR("application/"
+ "vnd.sun.star.uno-component;"
+ "type=Python"),
+ OUSTR("*.py"),
+ getResourceString(
+ RID_STR_PYTHON_COMPONENT),
+ RID_IMG_COMPONENT,
+ RID_IMG_COMPONENT_HC ) ),
+ m_xRDBTypelibTypeInfo( new Package::TypeInfo(
+ OUSTR("application/"
+ "vnd.sun.star.uno-typelibrary;"
+ "type=RDB"),
+ OUSTR("*.rdb"),
+ getResourceString(RID_STR_RDB_TYPELIB),
+ RID_IMG_TYPELIB, RID_IMG_TYPELIB_HC ) ),
+ m_xJavaTypelibTypeInfo( new Package::TypeInfo(
+ OUSTR("application/"
+ "vnd.sun.star.uno-typelibrary;"
+ "type=Java"),
+ OUSTR("*.jar"),
+ getResourceString(RID_STR_JAVA_TYPELIB),
+ RID_IMG_JAVA_TYPELIB,
+ RID_IMG_JAVA_TYPELIB_HC ) ),
+ m_typeInfos( 5 )
+{
+ m_typeInfos[ 0 ] = m_xDynComponentTypeInfo;
+ m_typeInfos[ 1 ] = m_xJavaComponentTypeInfo;
+ m_typeInfos[ 2 ] = m_xPythonComponentTypeInfo;
+ m_typeInfos[ 3 ] = m_xRDBTypelibTypeInfo;
+ m_typeInfos[ 4 ] = m_xJavaTypelibTypeInfo;
+
+ const Reference<XCommandEnvironment> xCmdEnv;
+
+ if (transientMode())
+ {
+ // in-mem rdbs:
+ // common rdb for java, native rdb for shared lib components
+ m_xCommonRDB.set(
+ xComponentContext->getServiceManager()->createInstanceWithContext(
+ OUSTR("com.sun.star.registry.SimpleRegistry"),
+ xComponentContext ), UNO_QUERY_THROW );
+ m_xCommonRDB->open( OUString() /* in-mem */,
+ false /* ! read-only */, true /* create */ );
+ m_xNativeRDB.set(
+ xComponentContext->getServiceManager()->createInstanceWithContext(
+ OUSTR("com.sun.star.registry.SimpleRegistry"),
+ xComponentContext ), UNO_QUERY_THROW );
+ m_xNativeRDB->open( OUString() /* in-mem */,
+ false /* ! read-only */, true /* create */ );
+ }
+ else
+ {
+ unorc_verify_init( xCmdEnv );
+ }
+}
+
+// XPackageRegistry
+//______________________________________________________________________________
+Sequence< Reference<deployment::XPackageTypeInfo> >
+BackendImpl::getSupportedPackageTypes() throw (RuntimeException)
+{
+ return m_typeInfos;
+}
+
+// PackageRegistryBackend
+//______________________________________________________________________________
+Reference<deployment::XPackage> BackendImpl::bindPackage_(
+ OUString const & url, OUString const & mediaType_,
+ Reference<XCommandEnvironment> const & xCmdEnv )
+{
+ OUString mediaType(mediaType_);
+ if (mediaType.getLength() == 0 ||
+ mediaType.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(
+ "application/vnd.sun.star.uno-component") ) ||
+ mediaType.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(
+ "application/vnd.sun.star.uno-typelibrary") ))
+ {
+ // detect exact media-type:
+ ::ucbhelper::Content ucbContent;
+ if (create_ucb_content( &ucbContent, url, xCmdEnv )) {
+ const OUString title( ucbContent.getPropertyValue(
+ StrTitle::get() ).get<OUString>() );
+ if (title.endsWithIgnoreAsciiCaseAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(SAL_DLLEXTENSION) ))
+ {
+ mediaType = OUSTR("application/vnd.sun.star.uno-component;"
+ "type=native;platform=") +
+ getPlatformString();
+ }
+ else if (title.endsWithIgnoreAsciiCaseAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(".jar") ))
+ {
+ if (jarManifestHeaderPresent(
+ url, OUSTR("RegistrationClassName"), xCmdEnv ))
+ mediaType = OUSTR(
+ "application/vnd.sun.star.uno-component;type=Java");
+ if (mediaType.getLength() == 0)
+ mediaType = OUSTR(
+ "application/vnd.sun.star.uno-typelibrary;type=Java");
+ }
+ else if (title.endsWithIgnoreAsciiCaseAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(".py") ))
+ mediaType =
+ OUSTR("application/vnd.sun.star.uno-component;type=Python");
+ else if (title.endsWithIgnoreAsciiCaseAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(".rdb") ))
+ mediaType =
+ OUSTR("application/vnd.sun.star.uno-typelibrary;type=RDB");
+ }
+ if (mediaType.getLength() == 0)
+ throw lang::IllegalArgumentException(
+ StrCannotDetectMediaType::get() + url,
+ static_cast<OWeakObject *>(this), static_cast<sal_Int16>(-1) );
+ }
+
+ String type, subType;
+ INetContentTypeParameterList params;
+ if (INetContentTypes::parse( mediaType, type, subType, &params ))
+ {
+ if (type.EqualsIgnoreCaseAscii("application"))
+ {
+ ::ucbhelper::Content ucbContent( url, xCmdEnv );
+ const OUString name( ucbContent.getPropertyValue(
+ StrTitle::get() ).get<OUString>() );
+ if (subType.EqualsIgnoreCaseAscii("vnd.sun.star.uno-component"))
+ {
+ // xxx todo: probe and evaluate component xml description
+
+ INetContentTypeParameter const * param = params.find(
+ ByteString("platform") );
+ if (param == 0 || platform_fits( param->m_sValue )) {
+ param = params.find( ByteString("type") );
+ if (param != 0)
+ {
+ String const & value = param->m_sValue;
+ if (value.EqualsIgnoreCaseAscii("native")) {
+ return new BackendImpl::ComponentPackageImpl(
+ this, url, name, m_xDynComponentTypeInfo,
+ OUSTR("com.sun.star.loader.SharedLibrary") );
+ }
+ if (value.EqualsIgnoreCaseAscii("Java")) {
+ return new BackendImpl::ComponentPackageImpl(
+ this, url, name, m_xJavaComponentTypeInfo,
+ OUSTR("com.sun.star.loader.Java2") );
+ }
+ if (value.EqualsIgnoreCaseAscii("Python")) {
+ return new BackendImpl::ComponentPackageImpl(
+ this, url, name, m_xPythonComponentTypeInfo,
+ OUSTR("com.sun.star.loader.Python") );
+ }
+ }
+ }
+ }
+ else if (subType.EqualsIgnoreCaseAscii(
+ "vnd.sun.star.uno-typelibrary"))
+ {
+ INetContentTypeParameter const * param = params.find(
+ ByteString("type") );
+ if (param != 0) {
+ String const & value = param->m_sValue;
+ if (value.EqualsIgnoreCaseAscii("RDB"))
+ {
+ return new BackendImpl::TypelibraryPackageImpl(
+ this, url, name, m_xRDBTypelibTypeInfo,
+ false /* rdb */ );
+ }
+ if (value.EqualsIgnoreCaseAscii("Java")) {
+ return new BackendImpl::TypelibraryPackageImpl(
+ this, url, name, m_xJavaTypelibTypeInfo,
+ true /* jar */ );
+ }
+ }
+ }
+ }
+ }
+ throw lang::IllegalArgumentException(
+ StrUnsupportedMediaType::get() + mediaType,
+ static_cast<OWeakObject *>(this),
+ static_cast<sal_Int16>(-1) );
+}
+
+//##############################################################################
+
+//______________________________________________________________________________
+void BackendImpl::unorc_verify_init(
+ Reference<XCommandEnvironment> const & xCmdEnv )
+{
+ if (transientMode())
+ return;
+ const ::osl::MutexGuard guard( getMutex() );
+ if (! m_unorc_inited)
+ {
+ // common rc:
+ ::ucbhelper::Content ucb_content;
+ if (create_ucb_content(
+ &ucb_content,
+ makeURL( getCachePath(), OUSTR("unorc") ),
+ xCmdEnv, false /* no throw */ ))
+ {
+ OUString line;
+ if (readLine( &line, OUSTR("UNO_JAVA_CLASSPATH="), ucb_content,
+ RTL_TEXTENCODING_UTF8 ))
+ {
+ sal_Int32 index = sizeof ("UNO_JAVA_CLASSPATH=") - 1;
+ do {
+ OUString token( line.getToken( 0, ' ', index ).trim() );
+ if (token.getLength() > 0) {
+ // cleanup, check if existing:
+ if (create_ucb_content(
+ 0, expandUnoRcTerm(token), xCmdEnv,
+ false /* no throw */ )) {
+ m_jar_typelibs.push_back( token );
+ }
+ else
+ OSL_ENSURE(
+ 0, "### invalid UNO_JAVA_CLASSPATH entry!" );
+ }
+ }
+ while (index >= 0);
+ }
+ if (readLine( &line, OUSTR("UNO_TYPES="), ucb_content,
+ RTL_TEXTENCODING_UTF8 )) {
+ sal_Int32 index = sizeof ("UNO_TYPES=") - 1;
+ do {
+ OUString token( line.getToken( 0, ' ', index ).trim() );
+ if (token.getLength() > 0) {
+ if (token[ 0 ] == '?')
+ token = token.copy( 1 );
+ // cleanup, check if existing:
+ if (create_ucb_content(
+ 0, expandUnoRcTerm(token),
+ xCmdEnv, false /* no throw */ )) {
+ m_rdb_typelibs.push_back( token );
+ }
+ else
+ OSL_ENSURE( 0, "### invalid UNO_TYPES entry!" );
+ }
+ }
+ while (index >= 0);
+ }
+ if (readLine( &line, OUSTR("UNO_SERVICES="), ucb_content,
+ RTL_TEXTENCODING_UTF8 )) {
+ sal_Int32 start = sizeof ("UNO_SERVICES=?$ORIGIN/") - 1;
+ sal_Int32 sep = line.indexOf( ' ', start );
+ OSL_ASSERT( sep > 0 );
+ m_commonRDB = line.copy( start, sep - start );
+ }
+
+ // native rc:
+ if (create_ucb_content(
+ &ucb_content,
+ makeURL( getCachePath(), getPlatformString() + OUSTR("rc")),
+ xCmdEnv, false /* no throw */ )) {
+ if (readLine( &line, OUSTR("UNO_SERVICES="), ucb_content,
+ RTL_TEXTENCODING_UTF8 )) {
+ m_nativeRDB = line.copy(
+ sizeof ("UNO_SERVICES=?$ORIGIN/") - 1 );
+ }
+ }
+ }
+ m_unorc_modified = false;
+ m_unorc_inited = true;
+ }
+}
+
+//______________________________________________________________________________
+void BackendImpl::unorc_flush( Reference<XCommandEnvironment> const & xCmdEnv )
+{
+ if (transientMode())
+ return;
+ if (!m_unorc_inited || !m_unorc_modified)
+ return;
+
+ ::rtl::OStringBuffer buf;
+ // UNO_USER_PACKAGES_CACHE, UNO_SHARED_PACKAGES_CACHE have to be resolved
+ // locally:
+ if (m_eContext == CONTEXT_USER) {
+ buf.append( RTL_CONSTASCII_STRINGPARAM(
+ "UNO_USER_PACKAGES_CACHE=$ORIGIN/../..") );
+ }
+ else if (m_eContext == CONTEXT_SHARED) {
+ buf.append( RTL_CONSTASCII_STRINGPARAM(
+ "UNO_SHARED_PACKAGES_CACHE=$ORIGIN/../..") );
+ }
+ else
+ OSL_ASSERT(0);
+ buf.append(LF);
+
+ if (! m_jar_typelibs.empty())
+ {
+ t_stringlist::const_iterator iPos( m_jar_typelibs.begin() );
+ t_stringlist::const_iterator const iEnd( m_jar_typelibs.end() );
+ buf.append( RTL_CONSTASCII_STRINGPARAM("UNO_JAVA_CLASSPATH=") );
+ while (iPos != iEnd) {
+ // encoded ASCII file-urls:
+ const ::rtl::OString item(
+ ::rtl::OUStringToOString( *iPos, RTL_TEXTENCODING_ASCII_US ) );
+ buf.append( item );
+ ++iPos;
+ if (iPos != iEnd)
+ buf.append( ' ' );
+ }
+ buf.append(LF);
+ }
+ if (! m_rdb_typelibs.empty())
+ {
+ t_stringlist::const_iterator iPos( m_rdb_typelibs.begin() );
+ t_stringlist::const_iterator const iEnd( m_rdb_typelibs.end() );
+ buf.append( RTL_CONSTASCII_STRINGPARAM("UNO_TYPES=") );
+ while (iPos != iEnd) {
+ buf.append( '?' );
+ // encoded ASCII file-urls:
+ const ::rtl::OString item(
+ ::rtl::OUStringToOString( *iPos, RTL_TEXTENCODING_ASCII_US ) );
+ buf.append( item );
+ ++iPos;
+ if (iPos != iEnd)
+ buf.append( ' ' );
+ }
+ buf.append(LF);
+ }
+ if (m_commonRDB.getLength() > 0 || m_nativeRDB.getLength() > 0)
+ {
+ buf.append( RTL_CONSTASCII_STRINGPARAM("UNO_SERVICES=?$ORIGIN/") );
+ buf.append( ::rtl::OUStringToOString(
+ m_commonRDB, RTL_TEXTENCODING_ASCII_US ) );
+ if (m_nativeRDB.getLength() > 0)
+ {
+ buf.append( RTL_CONSTASCII_STRINGPARAM(
+ " ${$ORIGIN/${_OS}_${_ARCH}rc:UNO_SERVICES}") );
+ buf.append(LF);
+
+ // write native rc:
+ ::rtl::OStringBuffer buf2;
+ buf2.append( RTL_CONSTASCII_STRINGPARAM("UNO_SERVICES=?$ORIGIN/") );
+ buf2.append( ::rtl::OUStringToOString(
+ m_nativeRDB, RTL_TEXTENCODING_ASCII_US ) );
+ buf2.append(LF);
+
+ const Reference<io::XInputStream> xData(
+ ::xmlscript::createInputStream(
+ ::rtl::ByteSequence(
+ reinterpret_cast<sal_Int8 const *>(buf2.getStr()),
+ buf2.getLength() ) ) );
+ ::ucbhelper::Content ucb_content(
+ makeURL( getCachePath(), getPlatformString() + OUSTR("rc") ),
+ xCmdEnv );
+ ucb_content.writeStream( xData, true /* replace existing */ );
+ }
+ }
+
+ // write unorc:
+ const Reference<io::XInputStream> xData(
+ ::xmlscript::createInputStream(
+ ::rtl::ByteSequence(
+ reinterpret_cast<sal_Int8 const *>(buf.getStr()),
+ buf.getLength() ) ) );
+ ::ucbhelper::Content ucb_content(
+ makeURL( getCachePath(), OUSTR("unorc") ), xCmdEnv );
+ ucb_content.writeStream( xData, true /* replace existing */ );
+
+ m_unorc_modified = false;
+}
+
+//------------------------------------------------------------------------------
+inline OUString makeRcTerm( OUString const & url )
+{
+ OSL_ASSERT( url.matchAsciiL( RTL_CONSTASCII_STRINGPARAM(
+ "vnd.sun.star.expand:") ) );
+ if (url.matchAsciiL( RTL_CONSTASCII_STRINGPARAM("vnd.sun.star.expand:") )) {
+ // cut protocol:
+ OUString rcterm( url.copy( sizeof ("vnd.sun.star.expand:") - 1 ) );
+ // decode uric class chars:
+ rcterm = ::rtl::Uri::decode(
+ rcterm, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 );
+ return rcterm;
+ }
+ else
+ return url;
+}
+
+//______________________________________________________________________________
+bool BackendImpl::addToUnoRc( bool jarFile, OUString const & url_,
+ Reference<XCommandEnvironment> const & xCmdEnv )
+{
+ const OUString rcterm( makeRcTerm(url_) );
+ const ::osl::MutexGuard guard( getMutex() );
+ unorc_verify_init( xCmdEnv );
+ t_stringlist & rSet = getTypelibs(jarFile);
+ if (::std::find( rSet.begin(), rSet.end(), rcterm ) == rSet.end()) {
+ rSet.push_front( rcterm ); // prepend to list, thus overriding
+ // write immediately:
+ m_unorc_modified = true;
+ unorc_flush( xCmdEnv );
+ return true;
+ }
+ else
+ return false;
+}
+
+//______________________________________________________________________________
+bool BackendImpl::removeFromUnoRc(
+ bool jarFile, OUString const & url_,
+ Reference<XCommandEnvironment> const & xCmdEnv )
+{
+ const OUString rcterm( makeRcTerm(url_) );
+ const ::osl::MutexGuard guard( getMutex() );
+ unorc_verify_init( xCmdEnv );
+ getTypelibs(jarFile).remove( rcterm );
+ // write immediately:
+ m_unorc_modified = true;
+ unorc_flush( xCmdEnv );
+ return true;
+}
+
+//______________________________________________________________________________
+bool BackendImpl::hasInUnoRc(
+ bool jarFile, OUString const & url_ )
+{
+ const OUString rcterm( makeRcTerm(url_) );
+ const ::osl::MutexGuard guard( getMutex() );
+ t_stringlist const & rSet = getTypelibs(jarFile);
+ return ::std::find( rSet.begin(), rSet.end(), rcterm ) != rSet.end();
+}
+
+//______________________________________________________________________________
+void BackendImpl::releaseObject( OUString const & id )
+{
+ const ::osl::MutexGuard guard( getMutex() );
+ if ( m_backendObjects.erase( id ) != 1 )
+ {
+ OSL_ASSERT( false );
+ }
+}
+
+//______________________________________________________________________________
+Reference<XInterface> BackendImpl::getObject( OUString const & id )
+{
+ const ::osl::MutexGuard guard( getMutex() );
+ const t_string2object::const_iterator iFind( m_backendObjects.find( id ) );
+ if (iFind == m_backendObjects.end())
+ return Reference<XInterface>();
+ else
+ return iFind->second;
+}
+
+//______________________________________________________________________________
+Reference<XInterface> BackendImpl::insertObject(
+ OUString const & id, Reference<XInterface> const & xObject )
+{
+ const ::osl::MutexGuard guard( getMutex() );
+ const ::std::pair<t_string2object::iterator, bool> insertion(
+ m_backendObjects.insert( t_string2object::value_type(
+ id, xObject ) ) );
+ return insertion.first->second;
+}
+
+//------------------------------------------------------------------------------
+Reference<XComponentContext> raise_uno_process(
+ Reference<XComponentContext> const & xContext,
+ ::rtl::Reference<AbortChannel> const & abortChannel )
+{
+ OSL_ASSERT( xContext.is() );
+
+ ::rtl::OUString url(
+ Reference<util::XMacroExpander>(
+ xContext->getValueByName(
+ OUSTR("/singletons/com.sun.star.util.theMacroExpander") ),
+ UNO_QUERY_THROW )->
+ expandMacros( OUSTR("$URE_BIN_DIR/uno") ) );
+
+ ::rtl::OUStringBuffer buf;
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("uno:pipe,name=") );
+ OUString pipeId( generateRandomPipeId() );
+ buf.append( pipeId );
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM(";urp;uno.ComponentContext") );
+ const OUString connectStr( buf.makeStringAndClear() );
+
+ // raise core UNO process to register/run a component,
+ // javavm service uses unorc next to executable to retrieve deployed
+ // jar typelibs
+
+ ::std::vector<OUString> args;
+#if OSL_DEBUG_LEVEL <= 1
+ args.push_back( OUSTR("--quiet") );
+#endif
+ args.push_back( OUSTR("--singleaccept") );
+ args.push_back( OUSTR("-u") );
+ args.push_back( connectStr );
+ // don't inherit from unorc:
+ args.push_back( OUSTR("-env:INIFILENAME=") );
+
+ //now add the bootstrap variables which were supplied on the command line
+ ::std::vector<OUString> bootvars = getCmdBootstrapVariables();
+ args.insert(args.end(), bootvars.begin(), bootvars.end());
+
+ oslProcess hProcess = raiseProcess(
+ url, comphelper::containerToSequence(args) );
+ try {
+ return Reference<XComponentContext>(
+ resolveUnoURL( connectStr, xContext, abortChannel.get() ),
+ UNO_QUERY_THROW );
+ }
+ catch (...) {
+ // try to terminate process:
+ if ( osl_terminateProcess( hProcess ) != osl_Process_E_None )
+ {
+ OSL_ASSERT( false );
+ }
+ throw;
+ }
+}
+
+//------------------------------------------------------------------------------
+Reference<loader::XImplementationLoader>
+BackendImpl::ComponentPackageImpl::getComponentInfo(
+ t_stringlist * pImplNames, t_stringpairvec * pSingletons,
+ Reference<XComponentContext> const & xContext )
+{
+ const Reference<loader::XImplementationLoader> xLoader(
+ xContext->getServiceManager()->createInstanceWithContext(
+ m_loader, xContext ), UNO_QUERY );
+ if (! xLoader.is())
+ return Reference<loader::XImplementationLoader>();
+
+ // HACK: highly dependent on stoc/source/servicemanager
+ // and stoc/source/implreg implementation which rely on the same
+ // services.rdb format!
+
+ const Reference<registry::XSimpleRegistry> xMemReg(
+ xContext->getServiceManager()->createInstanceWithContext(
+ OUSTR("com.sun.star.registry.SimpleRegistry"), xContext ),
+ UNO_QUERY_THROW );
+ xMemReg->open( OUString() /* in mem */, false, true );
+ xLoader->writeRegistryInfo( xMemReg->getRootKey(), OUString(), getURL() );
+
+ const Sequence< Reference<registry::XRegistryKey> > keys(
+ xMemReg->getRootKey()->openKeys() );
+ for ( sal_Int32 pos = keys.getLength(); pos--; )
+ {
+ Reference<registry::XRegistryKey> const & xImplKey = keys[ pos ];
+ const OUString implName(
+ xImplKey->getKeyName().copy( 1 /*leading slash*/ ) );
+
+ // check for singletons:
+ const Reference<registry::XRegistryKey> xSingletonKey(
+ xImplKey->openKey( OUSTR("UNO/SINGLETONS") ) );
+ if (xSingletonKey.is() && xSingletonKey->isValid())
+ {
+ const Sequence< Reference<registry::XRegistryKey> > singletonKeys(
+ xSingletonKey->openKeys() );
+ for ( sal_Int32 i = singletonKeys.getLength(); i--; )
+ {
+ Reference<registry::XRegistryKey> const & xSingleton =
+ singletonKeys[ i ];
+ pSingletons->push_back(
+ ::std::pair<OUString, OUString>(
+ xSingleton->getKeyName().copy(
+ implName.getLength() +
+ sizeof ("//UNO/SINGLETONS/") - 1 ),
+ xSingleton->getStringValue() ) );
+ }
+ }
+ else
+ {
+ pImplNames->push_back( implName );
+ }
+ }
+
+ return xLoader;
+}
+
+// Package
+//______________________________________________________________________________
+beans::Optional< beans::Ambiguous<sal_Bool> >
+BackendImpl::ComponentPackageImpl::isRegistered_(
+ ::osl::ResettableMutexGuard &,
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ Reference<XCommandEnvironment> const & )
+{
+ if (m_registered == REG_UNINIT)
+ {
+ m_registered = REG_NOT_REGISTERED;
+ const Reference<registry::XSimpleRegistry> xRDB( getRDB() );
+ if (xRDB.is())
+ {
+ // lookup rdb for location URL:
+ const Reference<registry::XRegistryKey> xRootKey(
+ xRDB->getRootKey() );
+ const Reference<registry::XRegistryKey> xImplKey(
+ xRootKey->openKey( OUSTR("IMPLEMENTATIONS") ) );
+ Sequence<OUString> implNames;
+ if (xImplKey.is() && xImplKey->isValid())
+ implNames = xImplKey->getKeyNames();
+ OUString const * pImplNames = implNames.getConstArray();
+ sal_Int32 pos = implNames.getLength();
+ for ( ; pos--; )
+ {
+ checkAborted( abortChannel );
+ const OUString key(
+ pImplNames[ pos ] + OUSTR("/UNO/LOCATION") );
+ const Reference<registry::XRegistryKey> xKey(
+ xRootKey->openKey(key) );
+ if (xKey.is() && xKey->isValid()) {
+ const OUString location( xKey->getAsciiValue() );
+ if (location.equalsIgnoreAsciiCase( getURL() ))
+ break;
+ }
+ }
+ if (pos >= 0)
+ m_registered = REG_REGISTERED;
+ }
+ }
+ return beans::Optional< beans::Ambiguous<sal_Bool> >(
+ true /* IsPresent */,
+ beans::Ambiguous<sal_Bool>(
+ m_registered == REG_REGISTERED,
+ m_registered == REG_VOID /* IsAmbiguous */ ) );
+}
+
+//______________________________________________________________________________
+void BackendImpl::ComponentPackageImpl::processPackage_(
+ ::osl::ResettableMutexGuard &,
+ bool doRegisterPackage,
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv )
+{
+ BackendImpl * that = getMyBackend();
+ const bool java = m_loader.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("com.sun.star.loader.Java2") );
+ const OUString url( getURL() );
+ bool isJavaTypelib = java &&
+ !jarManifestHeaderPresent( url, OUSTR("UNO-Type-Path"), xCmdEnv );
+
+ if (doRegisterPackage)
+ {
+ if (isJavaTypelib)
+ that->addToUnoRc( java, url, xCmdEnv );
+
+ if (! m_xRemoteContext.is()) {
+ m_xRemoteContext.set(
+ that->getObject( url ), UNO_QUERY );
+ if (! m_xRemoteContext.is()) {
+ m_xRemoteContext.set(
+ that->insertObject( url, raise_uno_process(
+ that->getComponentContext(),
+ abortChannel ) ),
+ UNO_QUERY_THROW );
+ }
+ }
+
+ const Reference<registry::XSimpleRegistry> xServicesRDB( getRDB() );
+ const Reference<registry::XImplementationRegistration> xImplReg(
+ m_xRemoteContext->getServiceManager()->createInstanceWithContext(
+ OUSTR("com.sun.star.registry.ImplementationRegistration"),
+ m_xRemoteContext ), UNO_QUERY_THROW );
+ xImplReg->registerImplementation( m_loader, url, xServicesRDB );
+
+ t_stringlist implNames;
+ t_stringpairvec singletons;
+ const Reference<loader::XImplementationLoader> xLoader(
+ getComponentInfo( &implNames, &singletons, m_xRemoteContext ) );
+
+ // factories live insertion:
+ const Reference<container::XSet> xSet(
+ that->getComponentContext()->getServiceManager(), UNO_QUERY_THROW );
+ for ( t_stringlist::const_iterator iPos( implNames.begin() );
+ iPos != implNames.end(); ++iPos )
+ {
+ checkAborted( abortChannel );
+ OUString const & implName = *iPos;
+ // activate factory:
+ const Reference<XInterface> xFactory(
+ xLoader->activate(
+ implName, OUString(), url,
+ xServicesRDB->getRootKey()->openKey(
+ OUSTR("/IMPLEMENTATIONS/") + implName ) ) );
+ try {
+ xSet->insert( Any(xFactory) );
+ } // ignore if factory has already been inserted:
+ catch (container::ElementExistException &) {
+ OSL_ENSURE( 0, "### factory already registered?" );
+ }
+ }
+
+ if (! singletons.empty())
+ {
+ // singletons live insertion:
+ const Reference<container::XNameContainer> xRootContext(
+ that->getComponentContext()->getValueByName(
+ OUSTR("_root") ), UNO_QUERY );
+ if (xRootContext.is())
+ {
+ for ( t_stringpairvec::const_iterator iPos(
+ singletons.begin() );
+ iPos != singletons.end(); ++iPos )
+ {
+ ::std::pair<OUString, OUString> const & sp = *iPos;
+ const OUString name( OUSTR("/singletons/") + sp.first );
+ // assure no arguments:
+ try {
+ xRootContext->removeByName( name + OUSTR("/arguments"));
+ } catch (container::NoSuchElementException &) {}
+ // used service:
+ try {
+ xRootContext->insertByName(
+ name + OUSTR("/service"), Any(sp.second) );
+ } catch (container::ElementExistException &) {
+ xRootContext->replaceByName(
+ name + OUSTR("/service"), Any(sp.second) );
+ }
+ // singleton entry:
+ try {
+ xRootContext->insertByName( name, Any() );
+ } catch (container::ElementExistException & exc) {
+ (void) exc; // avoid warnings
+ OSL_ENSURE(
+ 0, OUStringToOString(
+ exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
+ xRootContext->replaceByName( name, Any() );
+ }
+ }
+ }
+ }
+
+ m_registered = REG_REGISTERED;
+ }
+ else // revokePackage()
+ {
+ // set to VOID during revocation process:
+ m_registered = REG_VOID;
+
+ Reference<XComponentContext> xContext;
+ if (m_xRemoteContext.is()) // has been activated in this process
+ xContext = m_xRemoteContext;
+ else // has been deployed in former times
+ xContext = that->getComponentContext();
+
+ t_stringlist implNames;
+ t_stringpairvec singletons;
+ getComponentInfo( &implNames, &singletons, xContext );
+
+ // factories live removal:
+ const Reference<container::XSet> xSet(
+ that->getComponentContext()->getServiceManager(), UNO_QUERY_THROW );
+ for ( t_stringlist::const_iterator iPos( implNames.begin() );
+ iPos != implNames.end(); ++iPos )
+ {
+ OUString const & implName = *iPos;
+ try {
+ xSet->remove( Any(implName) );
+ } // ignore if factory has not been live deployed:
+ catch (container::NoSuchElementException &) {
+ }
+ }
+
+ if (! singletons.empty())
+ {
+ // singletons live removal:
+ const Reference<container::XNameContainer> xRootContext(
+ that->getComponentContext()->getValueByName(
+ OUSTR("_root") ), UNO_QUERY );
+ if (xRootContext.is())
+ {
+ for ( t_stringpairvec::const_iterator iPos(
+ singletons.begin() );
+ iPos != singletons.end(); ++iPos )
+ {
+ ::std::pair<OUString, OUString> const & sp = *iPos;
+ const OUString name( OUSTR("/singletons/") + sp.first );
+ // arguments:
+ try {
+ xRootContext->removeByName( name + OUSTR("/arguments"));
+ }
+ catch (container::NoSuchElementException &) {}
+ // used service:
+ try {
+ xRootContext->removeByName( name + OUSTR("/service") );
+ }
+ catch (container::NoSuchElementException &) {}
+ // singleton entry:
+ try {
+ xRootContext->removeByName( name );
+ }
+ catch (container::NoSuchElementException & exc) {
+ (void) exc; // avoid warnings
+ OSL_ENSURE(
+ 0, OUStringToOString(
+ exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
+ }
+ }
+ }
+ }
+
+ const Reference<registry::XSimpleRegistry> xServicesRDB( getRDB() );
+ const Reference<registry::XImplementationRegistration> xImplReg(
+ xContext->getServiceManager()->createInstanceWithContext(
+ OUSTR("com.sun.star.registry.ImplementationRegistration"),
+ xContext ), UNO_QUERY_THROW );
+ xImplReg->revokeImplementation( url, xServicesRDB );
+
+ if (isJavaTypelib)
+ that->removeFromUnoRc( java, url, xCmdEnv );
+
+ if (m_xRemoteContext.is()) {
+ that->releaseObject( url );
+ m_xRemoteContext.clear();
+ }
+
+ m_registered = REG_NOT_REGISTERED;
+ }
+}
+
+//##############################################################################
+
+// Package
+BackendImpl * BackendImpl::TypelibraryPackageImpl::getMyBackend() const
+{
+ BackendImpl * pBackend = static_cast<BackendImpl *>(m_myBackend.get());
+ if (NULL == pBackend)
+ {
+ //May throw a DisposedException
+ check();
+ //We should never get here...
+ throw RuntimeException(
+ OUSTR("Failed to get the BackendImpl"),
+ static_cast<OWeakObject*>(const_cast<TypelibraryPackageImpl *>(this)));
+ }
+ return pBackend;
+}
+//______________________________________________________________________________
+beans::Optional< beans::Ambiguous<sal_Bool> >
+BackendImpl::TypelibraryPackageImpl::isRegistered_(
+ ::osl::ResettableMutexGuard &,
+ ::rtl::Reference<AbortChannel> const &,
+ Reference<XCommandEnvironment> const & )
+{
+ BackendImpl * that = getMyBackend();
+ return beans::Optional< beans::Ambiguous<sal_Bool> >(
+ true /* IsPresent */,
+ beans::Ambiguous<sal_Bool>(
+ that->hasInUnoRc( m_jarFile, getURL() ),
+ false /* IsAmbiguous */ ) );
+}
+
+//______________________________________________________________________________
+void BackendImpl::TypelibraryPackageImpl::processPackage_(
+ ::osl::ResettableMutexGuard &,
+ bool doRegisterPackage,
+ ::rtl::Reference<AbortChannel> const &,
+ Reference<XCommandEnvironment> const & xCmdEnv )
+{
+ BackendImpl * that = getMyBackend();
+ const OUString url( getURL() );
+
+ if (doRegisterPackage)
+ {
+ // live insertion:
+ if (m_jarFile) {
+ // xxx todo add to classpath at runtime: ???
+ //SB: It is probably not worth it to add the live inserted type
+ // library JAR to the UnoClassLoader in the soffice process. Any
+ // live inserted component JAR that might reference this type
+ // library JAR runs in its own uno process, so there is probably no
+ // Java code in the soffice process that would see any UNO types
+ // introduced by this type library JAR.
+ }
+ else // RDB:
+ {
+ Reference<XComponentContext> const & xContext =
+ that->getComponentContext();
+ if (! m_xTDprov.is())
+ {
+ m_xTDprov.set( that->getObject( url ), UNO_QUERY );
+ if (! m_xTDprov.is())
+ {
+ const Reference<registry::XSimpleRegistry> xReg(
+ xContext->getServiceManager()
+ ->createInstanceWithContext(
+ OUSTR("com.sun.star.registry.SimpleRegistry"),
+ xContext ), UNO_QUERY_THROW );
+ xReg->open( expandUnoRcUrl(url),
+ true /* read-only */, false /* ! create */ );
+ const Any arg(xReg);
+ Reference<container::XHierarchicalNameAccess> xTDprov(
+ xContext->getServiceManager()
+ ->createInstanceWithArgumentsAndContext(
+ OUSTR("com.sun.star.comp.stoc."
+ "RegistryTypeDescriptionProvider"),
+ Sequence<Any>( &arg, 1 ), xContext ), UNO_QUERY );
+ OSL_ASSERT( xTDprov.is() );
+ if (xTDprov.is())
+ m_xTDprov.set( that->insertObject( url, xTDprov ),
+ UNO_QUERY_THROW );
+ }
+ }
+ if (m_xTDprov.is()) {
+ Reference<container::XSet> xSet(
+ xContext->getValueByName(
+ OUSTR("/singletons/com.sun.star."
+ "reflection.theTypeDescriptionManager") ),
+ UNO_QUERY_THROW );
+ xSet->insert( Any(m_xTDprov) );
+ }
+ }
+
+ that->addToUnoRc( m_jarFile, url, xCmdEnv );
+ }
+ else // revokePackage()
+ {
+ that->removeFromUnoRc( m_jarFile, url, xCmdEnv );
+
+ // revoking types at runtime, possible, sensible?
+ if (!m_xTDprov.is())
+ m_xTDprov.set( that->getObject( url ), UNO_QUERY );
+ if (m_xTDprov.is()) {
+ // remove live:
+ const Reference<container::XSet> xSet(
+ that->getComponentContext()->getValueByName(
+ OUSTR("/singletons/com.sun.star."
+ "reflection.theTypeDescriptionManager") ),
+ UNO_QUERY_THROW );
+ xSet->remove( Any(m_xTDprov) );
+
+ that->releaseObject( url );
+ m_xTDprov.clear();
+ }
+ }
+}
+
+} // anon namespace
+
+namespace sdecl = comphelper::service_decl;
+sdecl::class_<BackendImpl, sdecl::with_args<true> > serviceBI;
+extern sdecl::ServiceDecl const serviceDecl(
+ serviceBI,
+ "com.sun.star.comp.deployment.component.PackageRegistryBackend",
+ BACKEND_SERVICE_NAME );
+
+} // namespace component
+} // namespace backend
+} // namespace dp_registry
+
+
diff --git a/desktop/source/deployment/registry/component/dp_component.hrc b/desktop/source/deployment/registry/component/dp_component.hrc
new file mode 100644
index 000000000000..9324eb0eed1a
--- /dev/null
+++ b/desktop/source/deployment/registry/component/dp_component.hrc
@@ -0,0 +1,42 @@
+/*************************************************************************
+ *
+ * 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: dp_component.hrc,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.
+ *
+ ************************************************************************/
+
+#if ! defined INCLUDED_DP_COMPONENT_HRC
+#define INCLUDED_DP_COMPONENT_HRC
+
+#include "deployment.hrc"
+
+#define RID_STR_DYN_COMPONENT (RID_DEPLOYMENT_COMPONENT_START+10)
+#define RID_STR_JAVA_COMPONENT (RID_DEPLOYMENT_COMPONENT_START+11)
+#define RID_STR_PYTHON_COMPONENT (RID_DEPLOYMENT_COMPONENT_START+12)
+#define RID_STR_RDB_TYPELIB (RID_DEPLOYMENT_COMPONENT_START+20)
+#define RID_STR_JAVA_TYPELIB (RID_DEPLOYMENT_COMPONENT_START+21)
+
+#endif
diff --git a/desktop/source/deployment/registry/component/dp_component.src b/desktop/source/deployment/registry/component/dp_component.src
new file mode 100644
index 000000000000..2f2b04610610
--- /dev/null
+++ b/desktop/source/deployment/registry/component/dp_component.src
@@ -0,0 +1,57 @@
+/*************************************************************************
+ *
+ * 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: dp_component.src,v $
+ * $Revision: 1.6 $
+ *
+ * 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 "dp_component.hrc"
+
+String RID_STR_DYN_COMPONENT
+{
+ Text [ en-US ] = "UNO Dynamic Library Component";
+};
+
+String RID_STR_JAVA_COMPONENT
+{
+ Text [ en-US ] = "UNO Java Component";
+};
+
+String RID_STR_PYTHON_COMPONENT
+{
+ Text [ en-US ] = "UNO Python Component";
+};
+
+String RID_STR_RDB_TYPELIB
+{
+ Text [ en-US ] = "UNO RDB Type Library";
+};
+
+String RID_STR_JAVA_TYPELIB
+{
+ Text [ en-US ] = "UNO Java Type Library";
+};
+
diff --git a/desktop/source/deployment/registry/component/makefile.mk b/desktop/source/deployment/registry/component/makefile.mk
new file mode 100644
index 000000000000..af5e4c6d49ea
--- /dev/null
+++ b/desktop/source/deployment/registry/component/makefile.mk
@@ -0,0 +1,51 @@
+#*************************************************************************
+#
+# 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.7 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ = ..$/..$/..$/..
+
+PRJNAME = desktop
+TARGET = deployment_registry_component
+ENABLE_EXCEPTIONS = TRUE
+
+.INCLUDE : settings.mk
+
+SRS1NAME = $(TARGET)
+SRC1FILES = \
+ dp_component.src
+
+INCPRE += ..$/..$/inc
+
+SLOFILES = \
+ $(SLO)$/dp_component.obj
+
+.INCLUDE : ..$/..$/target.pmk
+.INCLUDE : target.mk
+
diff --git a/desktop/source/deployment/registry/configuration/dp_configuration.cxx b/desktop/source/deployment/registry/configuration/dp_configuration.cxx
new file mode 100644
index 000000000000..b24000d43dbb
--- /dev/null
+++ b/desktop/source/deployment/registry/configuration/dp_configuration.cxx
@@ -0,0 +1,648 @@
+/*************************************************************************
+ *
+ * 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: dp_configuration.cxx,v $
+ * $Revision: 1.15 $
+ *
+ * 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_desktop.hxx"
+
+#include "dp_configuration.hrc"
+#include "dp_backend.h"
+#include "dp_persmap.h"
+#include "dp_ucb.h"
+#include "dp_xml.h"
+#include "rtl/string.hxx"
+#include "rtl/ustrbuf.hxx"
+#include "rtl/uri.hxx"
+#include "rtl/memory.h"
+#include "osl/file.hxx"
+#include "ucbhelper/content.hxx"
+#include "comphelper/anytostring.hxx"
+#include "comphelper/servicedecl.hxx"
+#include "xmlscript/xml_helper.hxx"
+#include "svtools/inettype.hxx"
+#include "com/sun/star/ucb/NameClash.hpp"
+#include "com/sun/star/io/XActiveDataSink.hpp"
+#include "com/sun/star/lang/WrappedTargetRuntimeException.hpp"
+#include "com/sun/star/util/XRefreshable.hpp"
+#include "com/sun/star/configuration/backend/XLayerImporter.hpp"
+#include <memory>
+
+
+using namespace ::dp_misc;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::ucb;
+using ::rtl::OUString;
+
+namespace dp_registry {
+namespace backend {
+namespace configuration {
+namespace {
+
+//==============================================================================
+class BackendImpl : public ::dp_registry::backend::PackageRegistryBackend
+{
+ class PackageImpl : public ::dp_registry::backend::Package
+ {
+ BackendImpl * getMyBackend() const ;
+
+ const bool m_isSchema;
+
+ // Package
+ virtual beans::Optional< beans::Ambiguous<sal_Bool> > isRegistered_(
+ ::osl::ResettableMutexGuard & guard,
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+ virtual void processPackage_(
+ ::osl::ResettableMutexGuard & guard,
+ bool registerPackage,
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+
+ public:
+ inline PackageImpl(
+ ::rtl::Reference<PackageRegistryBackend> const & myBackend,
+ OUString const & url, OUString const & name,
+ Reference<deployment::XPackageTypeInfo> const & xPackageType,
+ bool isSchema )
+ : Package( myBackend, url, name, name /* display-name */,
+ xPackageType ),
+ m_isSchema( isSchema )
+ {}
+ };
+ friend class PackageImpl;
+
+ Reference< ::com::sun::star::configuration::backend::XLayerImporter >
+ m_xMergeImporter;
+ OUString m_configLayer;
+
+ // PackageRegistryBackend
+ virtual Reference<deployment::XPackage> bindPackage_(
+ OUString const & url, OUString const & mediaType,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+
+ void xcu_merge_in( OUString const & url,
+ Reference< XCommandEnvironment > const & xCmdEnv );
+ void xcs_merge_in( OUString const & url,
+ Reference< XCommandEnvironment > const & xCmdEnv );
+ ::std::auto_ptr<PersistentMap> m_registeredPackages;
+ OUString const & getConfigLayer();
+ Reference<util::XRefreshable> m_defaultProvider;
+
+ const Reference<deployment::XPackageTypeInfo> m_xConfDataTypeInfo;
+ const Reference<deployment::XPackageTypeInfo> m_xConfSchemaTypeInfo;
+ Sequence< Reference<deployment::XPackageTypeInfo> > m_typeInfos;
+
+public:
+ BackendImpl( Sequence<Any> const & args,
+ Reference<XComponentContext> const & xComponentContext );
+
+ // XPackageRegistry
+ virtual Sequence< Reference<deployment::XPackageTypeInfo> > SAL_CALL
+ getSupportedPackageTypes() throw (RuntimeException);
+};
+
+//______________________________________________________________________________
+BackendImpl::BackendImpl(
+ Sequence<Any> const & args,
+ Reference<XComponentContext> const & xComponentContext )
+ : PackageRegistryBackend( args, xComponentContext ),
+ m_defaultProvider( xComponentContext->getValueByName(
+ OUSTR("/singletons/com.sun.star."
+ "configuration.theDefaultProvider") ),
+ UNO_QUERY ),
+ m_xConfDataTypeInfo( new Package::TypeInfo(
+ OUSTR("application/"
+ "vnd.sun.star.configuration-data"),
+ OUSTR("*.xcu"),
+ getResourceString(RID_STR_CONF_DATA),
+ RID_IMG_CONF_XML, RID_IMG_CONF_XML_HC ) ),
+ m_xConfSchemaTypeInfo( new Package::TypeInfo(
+ OUSTR("application/"
+ "vnd.sun.star.configuration-schema"),
+ OUSTR("*.xcs"),
+ getResourceString(RID_STR_CONF_SCHEMA),
+ RID_IMG_CONF_XML, RID_IMG_CONF_XML_HC ) ),
+ m_typeInfos( 2 )
+{
+ m_typeInfos[ 0 ] = m_xConfDataTypeInfo;
+ m_typeInfos[ 1 ] = m_xConfSchemaTypeInfo;
+
+ OSL_ASSERT( m_defaultProvider.is() );
+
+ if (transientMode()) {
+ m_registeredPackages.reset( new PersistentMap );
+ }
+ else {
+ m_registeredPackages.reset(
+ new PersistentMap(
+ makeURL( getCachePath(), OUSTR("registered_packages.db") ),
+ m_readOnly ) );
+ if (! m_readOnly)
+ create_folder( 0, getConfigLayer(),
+ Reference<XCommandEnvironment>() );
+ }
+}
+
+// XPackageRegistry
+//______________________________________________________________________________
+Sequence< Reference<deployment::XPackageTypeInfo> >
+BackendImpl::getSupportedPackageTypes() throw (RuntimeException)
+{
+ return m_typeInfos;
+}
+
+// PackageRegistryBackend
+//______________________________________________________________________________
+Reference<deployment::XPackage> BackendImpl::bindPackage_(
+ OUString const & url, OUString const & mediaType_,
+ Reference<XCommandEnvironment> const & xCmdEnv )
+{
+ OUString mediaType( mediaType_ );
+ if (mediaType.getLength() == 0)
+ {
+ // detect media-type:
+ ::ucbhelper::Content ucbContent;
+ if (create_ucb_content( &ucbContent, url, xCmdEnv ))
+ {
+ const OUString title( ucbContent.getPropertyValue(
+ StrTitle::get() ).get<OUString>() );
+ if (title.endsWithIgnoreAsciiCaseAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(".xcu") )) {
+ mediaType = OUSTR("application/"
+ "vnd.sun.star.configuration-data");
+ }
+ if (title.endsWithIgnoreAsciiCaseAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(".xcs") )) {
+ mediaType = OUSTR("application/"
+ "vnd.sun.star.configuration-schema");
+ }
+ }
+ if (mediaType.getLength() == 0)
+ throw lang::IllegalArgumentException(
+ StrCannotDetectMediaType::get() + url,
+ static_cast<OWeakObject *>(this), static_cast<sal_Int16>(-1) );
+ }
+
+ String type, subType;
+ INetContentTypeParameterList params;
+ if (INetContentTypes::parse( mediaType, type, subType, &params ))
+ {
+ if (type.EqualsIgnoreCaseAscii("application"))
+ {
+ ::ucbhelper::Content ucbContent( url, xCmdEnv );
+ if (subType.EqualsIgnoreCaseAscii(
+ "vnd.sun.star.configuration-data")) {
+ return new PackageImpl(
+ this, url, ucbContent.getPropertyValue(
+ StrTitle::get() ).get<OUString>(),
+ m_xConfDataTypeInfo, false /* data file */ );
+ }
+ else if (subType.EqualsIgnoreCaseAscii(
+ "vnd.sun.star.configuration-schema")) {
+ return new PackageImpl(
+ this, url, ucbContent.getPropertyValue(
+ StrTitle::get() ).get<OUString>(),
+ m_xConfSchemaTypeInfo, true /* schema file */ );
+ }
+ }
+ }
+ throw lang::IllegalArgumentException(
+ StrUnsupportedMediaType::get() + mediaType,
+ static_cast<OWeakObject *>(this),
+ static_cast<sal_Int16>(-1) );
+}
+
+//______________________________________________________________________________
+OUString const & BackendImpl::getConfigLayer()
+{
+ if (m_configLayer.getLength() == 0)
+ {
+ OUString path(
+ makeURL( expandUnoRcUrl( getCachePath() ), OUSTR("registry") ) );
+ ::osl::FileBase::RC rc = ::osl::File::getAbsoluteFileURL(
+ OUString(), path, m_configLayer );
+ if (rc != ::osl::FileBase::E_None)
+ throw RuntimeException(
+ OUSTR("making file URL absolute failed: ") + path,
+ static_cast<OWeakObject *>(this) );
+ }
+ return m_configLayer;
+}
+
+//==============================================================================
+class SchemaFileRoot : public ::dp_misc::XmlRootElement
+{
+public:
+ OUString m_name;
+ OUString m_package;
+
+ inline SchemaFileRoot()
+ : XmlRootElement( OUSTR("http://openoffice.org/2001/registry"),
+ OUSTR("component-schema") )
+ {}
+
+ // XRoot
+ virtual Reference< xml::input::XElement > SAL_CALL startRootElement(
+ sal_Int32 uid, OUString const & localname,
+ Reference< xml::input::XAttributes > const & xAttributes )
+ throw (xml::sax::SAXException, RuntimeException);
+};
+
+//______________________________________________________________________________
+Reference< xml::input::XElement > SchemaFileRoot::startRootElement(
+ sal_Int32 uid, OUString const & localname,
+ Reference< xml::input::XAttributes > const & xAttributes )
+ throw (xml::sax::SAXException, RuntimeException)
+{
+ // check root element:
+ XmlRootElement::startRootElement( uid, localname, xAttributes );
+
+ // "name" attribute
+ m_name = xAttributes->getValueByUidName( getUid(), OUSTR("name") );
+ if (m_name.getLength() == 0)
+ throw xml::sax::SAXException(
+ OUSTR("missing schema name attribute!"),
+ static_cast< OWeakObject * >(this), Any() );
+
+ // "package" attribute
+ m_package = xAttributes->getValueByUidName( getUid(), OUSTR("package") );
+ if (m_package.getLength() == 0)
+ throw xml::sax::SAXException(
+ OUSTR("missing schema package attribute!"),
+ static_cast<OWeakObject *>(this), Any() );
+
+ // don't go deeper...
+ return Reference<xml::input::XElement>();
+}
+
+//______________________________________________________________________________
+void BackendImpl::xcs_merge_in(
+ OUString const & url,
+ Reference<XCommandEnvironment> const & xCmdEnv )
+{
+ // parse out schema package:
+ SchemaFileRoot * root = new SchemaFileRoot;
+ Reference<xml::input::XRoot> xRoot( root );
+ ::ucbhelper::Content ucb_content( url, xCmdEnv );
+ xml_parse( xRoot, ucb_content, getComponentContext() );
+
+ OUString dest_folder(
+ makeURL( getConfigLayer(), OUSTR("schema/") + ::rtl::Uri::encode(
+ root->m_package, rtl_UriCharClassPchar,
+ rtl_UriEncodeIgnoreEscapes,
+ RTL_TEXTENCODING_UTF8 ).replace( '.', '/' ) ) );
+ OUString title( root->m_name + OUSTR(".xcs") );
+ OUString dest_url( makeURL( dest_folder, ::rtl::Uri::encode(
+ title, rtl_UriCharClassPchar,
+ rtl_UriEncodeIgnoreEscapes,
+ RTL_TEXTENCODING_UTF8 ) ) );
+ // assure dest folder is existing:
+ ::ucbhelper::Content ucb_dest_folder;
+ create_folder( &ucb_dest_folder, dest_folder, xCmdEnv );
+ if (! ucb_dest_folder.transferContent(
+ ::ucbhelper::Content( url, xCmdEnv ),
+ ::ucbhelper::InsertOperation_COPY,
+ title, NameClash::OVERWRITE ))
+ throw RuntimeException(
+ OUSTR("::ucb::Content::transferContent() failed!"), 0 );
+}
+
+//##############################################################################
+
+//------------------------------------------------------------------------------
+OUString encodeForXml( OUString const & text )
+{
+ // encode conforming xml:
+ sal_Int32 len = text.getLength();
+ ::rtl::OUStringBuffer buf;
+ for ( sal_Int32 pos = 0; pos < len; ++pos )
+ {
+ sal_Unicode c = text[ pos ];
+ switch (c) {
+ case '<':
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("&lt;") );
+ break;
+ case '>':
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("&gt;") );
+ break;
+ case '&':
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("&amp;") );
+ break;
+ case '\'':
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("&apos;") );
+ break;
+ case '\"':
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("&quot;") );
+ break;
+ default:
+ buf.append( c );
+ break;
+ }
+ }
+ return buf.makeStringAndClear();
+}
+
+//______________________________________________________________________________
+void BackendImpl::xcu_merge_in(
+ OUString const & url, Reference< XCommandEnvironment > const & xCmdEnv )
+{
+ // looking for %origin%:
+ ::ucbhelper::Content ucb_content( url, xCmdEnv );
+ ::rtl::ByteSequence bytes( readFile( ucb_content ) );
+ ::rtl::ByteSequence filtered( bytes.getLength() * 2,
+ ::rtl::BYTESEQ_NODEFAULT );
+ bool use_filtered = false;
+ ::rtl::OString origin;
+ sal_Char const * pBytes = reinterpret_cast<sal_Char const *>(
+ bytes.getConstArray());
+ sal_Size nBytes = bytes.getLength();
+ sal_Int32 write_pos = 0;
+ while (nBytes > 0)
+ {
+ sal_Int32 index = rtl_str_indexOfChar_WithLength( pBytes, nBytes, '%' );
+ if (index < 0) {
+ if (! use_filtered) // opt
+ break;
+ index = nBytes;
+ }
+
+ if ((write_pos + index) > filtered.getLength())
+ filtered.realloc( (filtered.getLength() + index) * 2 );
+ rtl_copyMemory( filtered.getArray() + write_pos, pBytes, index );
+ write_pos += index;
+ pBytes += index;
+ nBytes -= index;
+ if (nBytes == 0)
+ break;
+
+ // consume %:
+ ++pBytes;
+ --nBytes;
+ sal_Char const * pAdd = "%";
+ sal_Int32 nAdd = 1;
+ if (nBytes > 1 && pBytes[ 0 ] == '%')
+ {
+ // %% => %
+ ++pBytes;
+ --nBytes;
+ use_filtered = true;
+ }
+ else if (rtl_str_shortenedCompare_WithLength(
+ pBytes, nBytes,
+ RTL_CONSTASCII_STRINGPARAM("origin%"),
+ sizeof ("origin%") - 1 ) == 0)
+ {
+ if (origin.getLength() == 0) {
+ // encode only once
+ origin = ::rtl::OUStringToOString(
+ encodeForXml( url.copy( 0, url.lastIndexOf( '/' ) ) ),
+ // xxx todo: encode always for UTF-8? => lookup doc-header?
+ RTL_TEXTENCODING_UTF8 );
+ }
+ pAdd = origin.getStr();
+ nAdd = origin.getLength();
+ pBytes += (sizeof ("origin%") - 1);
+ nBytes -= (sizeof ("origin%") - 1);
+ use_filtered = true;
+ }
+ if ((write_pos + nAdd) > filtered.getLength())
+ filtered.realloc( (filtered.getLength() + nAdd) * 2 );
+ rtl_copyMemory( filtered.getArray() + write_pos, pAdd, nAdd );
+ write_pos += nAdd;
+ }
+ if (use_filtered && write_pos < filtered.getLength())
+ filtered.realloc( write_pos );
+
+ Reference<XComponentContext> const & xContext = getComponentContext();
+ if (! m_xMergeImporter.is()) {
+ m_xMergeImporter.set(
+ xContext->getServiceManager()->createInstanceWithContext(
+ OUSTR("com.sun.star.configuration.backend.MergeImporter"),
+ xContext ), UNO_QUERY_THROW );
+ }
+
+ Reference< ::com::sun::star::configuration::backend::XLayer > xLayer(
+ xContext->getServiceManager()->createInstanceWithContext(
+ OUSTR("com.sun.star.configuration.backend.xml.LayerParser"),
+ xContext ), UNO_QUERY_THROW );
+
+ Reference< io::XActiveDataSink > xActiveDataSink( xLayer, UNO_QUERY_THROW );
+ if (use_filtered)
+ xActiveDataSink->setInputStream( ::xmlscript::createInputStream(
+ filtered ) );
+ else
+ ucb_content.openStream( xActiveDataSink );
+
+ if (transientMode())
+ m_xMergeImporter->importLayer( xLayer );
+ else
+ m_xMergeImporter->importLayerForEntity( xLayer, getConfigLayer() );
+}
+
+//##############################################################################
+
+// Package
+//______________________________________________________________________________
+BackendImpl * BackendImpl::PackageImpl::getMyBackend() const
+{
+ BackendImpl * pBackend = static_cast<BackendImpl *>(m_myBackend.get());
+ if (NULL == pBackend)
+ {
+ //May throw a DisposedException
+ check();
+ //We should never get here...
+ throw RuntimeException(
+ OUSTR("Failed to get the BackendImpl"),
+ static_cast<OWeakObject*>(const_cast<PackageImpl *>(this)));
+ }
+ return pBackend;
+}
+
+beans::Optional< beans::Ambiguous<sal_Bool> >
+BackendImpl::PackageImpl::isRegistered_(
+ ::osl::ResettableMutexGuard &,
+ ::rtl::Reference<AbortChannel> const &,
+ Reference<XCommandEnvironment> const & )
+{
+ BackendImpl * that = getMyBackend();
+ return beans::Optional< beans::Ambiguous<sal_Bool> >(
+ true /* IsPresent */,
+ beans::Ambiguous<sal_Bool>(
+ that->m_registeredPackages->has(
+ rtl::OUStringToOString( m_url, RTL_TEXTENCODING_UTF8 ) ),
+ false /* IsAmbiguous */ ) );
+}
+
+//______________________________________________________________________________
+void BackendImpl::PackageImpl::processPackage_(
+ ::osl::ResettableMutexGuard &,
+ bool doRegisterPackage,
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv )
+{
+ BackendImpl * that = getMyBackend();
+ if (doRegisterPackage)
+ {
+ if (m_isSchema)
+ {
+ OSL_ENSURE( ! that->transientMode(),
+ "### schema cannot be deployed transiently!" );
+ if (! that->transientMode()) {
+ that->xcs_merge_in( m_url, xCmdEnv );
+ that->m_registeredPackages->put(
+ rtl::OUStringToOString( m_url, RTL_TEXTENCODING_UTF8),
+ rtl::OString(
+ RTL_CONSTASCII_STRINGPARAM(
+ "vnd.sun.star.configuration-schema" ) ) );
+ }
+ }
+ else
+ {
+ that->xcu_merge_in( m_url, xCmdEnv );
+ that->m_registeredPackages->put(
+ rtl::OUStringToOString( m_url, RTL_TEXTENCODING_UTF8 ),
+ rtl::OString(
+ RTL_CONSTASCII_STRINGPARAM(
+ "vnd.sun.star.configuration-data" ) ) );
+ }
+ }
+ else // revoke
+ {
+ OSL_ASSERT(
+ that->m_registeredPackages->has(
+ rtl::OUStringToOString( m_url, RTL_TEXTENCODING_UTF8 ) ) );
+ t_string2string_map entries( that->m_registeredPackages->getEntries() );
+ t_string2string_map::const_iterator iPos( entries.begin() );
+ t_string2string_map::const_iterator const iEnd( entries.end() );
+
+ if (m_isSchema)
+ {
+ if (! that->transientMode())
+ {
+ ::ucbhelper::Content ucbSaveLayer(
+ makeURL( that->getConfigLayer(), OUSTR("schema") ),
+ xCmdEnv );
+ ucbSaveLayer.setPropertyValue(
+ StrTitle::get(), Any( OUSTR("schema.bak") ) );
+ try {
+ for ( ; iPos != iEnd; ++iPos )
+ {
+ checkAborted( abortChannel );
+ if (iPos->second == "vnd.sun.star.configuration-schema")
+ {
+ OUString url(
+ rtl::OStringToOUString(
+ iPos->first, RTL_TEXTENCODING_UTF8 ) );
+ if (!url.equals( m_url )) {
+ that->xcs_merge_in( url, xCmdEnv );
+ }
+ }
+ }
+ }
+ catch (RuntimeException &) {
+ throw;
+ }
+ catch (Exception &) {
+ ucbSaveLayer.setPropertyValue(
+ StrTitle::get(), Any( OUSTR("schema") ) );
+ throw;
+ }
+ that->m_registeredPackages->erase(
+ rtl::OUStringToOString( m_url, RTL_TEXTENCODING_UTF8 ) );
+ ucbSaveLayer.executeCommand(
+ OUSTR("delete"), Any( true /* delete physically */ ) );
+ }
+ }
+ else // data
+ {
+ if (! that->transientMode())
+ {
+ ::ucbhelper::Content ucbSaveLayer(
+ makeURL( that->getConfigLayer(), OUSTR("data") ),
+ xCmdEnv );
+ ucbSaveLayer.setPropertyValue(
+ StrTitle::get(), Any( OUSTR("data.bak") ) );
+ try {
+ for ( ; iPos != iEnd; ++iPos )
+ {
+ checkAborted( abortChannel );
+ if (iPos->second == "vnd.sun.star.configuration-data") {
+ OUString url(
+ rtl::OStringToOUString(
+ iPos->first, RTL_TEXTENCODING_UTF8 ) );
+ if (!url.equals( m_url )) {
+ that->xcu_merge_in( url, xCmdEnv );
+ }
+ }
+ }
+ }
+ catch (RuntimeException &) {
+ throw;
+ }
+ catch (Exception &) {
+ ucbSaveLayer.setPropertyValue(
+ StrTitle::get(), Any( OUSTR("data") ) );
+ throw;
+ }
+ that->m_registeredPackages->erase(
+ rtl::OUStringToOString( m_url, RTL_TEXTENCODING_UTF8 ) );
+ ucbSaveLayer.executeCommand(
+ OUSTR("delete"), Any( true /* delete physically */ ) );
+ }
+ }
+ }
+
+ if (!m_isSchema && getMyBackend()->m_defaultProvider.is()) {
+ // temp workaround for config bug:
+ try {
+ getMyBackend()->m_defaultProvider->refresh();
+ }
+ catch (lang::WrappedTargetRuntimeException & exc) {
+ (void) exc;
+ OSL_ENSURE( 0, ::rtl::OUStringToOString(
+ ::comphelper::anyToString(exc.TargetException),
+ RTL_TEXTENCODING_UTF8 ).getStr() );
+ }
+ }
+}
+
+} // anon namespace
+
+namespace sdecl = comphelper::service_decl;
+sdecl::class_<BackendImpl, sdecl::with_args<true> > serviceBI;
+extern sdecl::ServiceDecl const serviceDecl(
+ serviceBI,
+ "com.sun.star.comp.deployment.configuration.PackageRegistryBackend",
+ BACKEND_SERVICE_NAME );
+
+} // namespace configuration
+} // namespace backend
+} // namespace dp_registry
+
diff --git a/desktop/source/deployment/registry/configuration/dp_configuration.hrc b/desktop/source/deployment/registry/configuration/dp_configuration.hrc
new file mode 100644
index 000000000000..4dfb8db84a24
--- /dev/null
+++ b/desktop/source/deployment/registry/configuration/dp_configuration.hrc
@@ -0,0 +1,39 @@
+/*************************************************************************
+ *
+ * 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: dp_configuration.hrc,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.
+ *
+ ************************************************************************/
+
+#if ! defined INCLUDED_DP_CONFIGURATION_HRC
+#define INCLUDED_DP_CONFIGURATION_HRC
+
+#include "deployment.hrc"
+
+#define RID_STR_CONF_SCHEMA (RID_DEPLOYMENT_CONF_START+10)
+#define RID_STR_CONF_DATA (RID_DEPLOYMENT_CONF_START+11)
+
+#endif
diff --git a/desktop/source/deployment/registry/configuration/dp_configuration.src b/desktop/source/deployment/registry/configuration/dp_configuration.src
new file mode 100644
index 000000000000..13f8ff08556d
--- /dev/null
+++ b/desktop/source/deployment/registry/configuration/dp_configuration.src
@@ -0,0 +1,42 @@
+/*************************************************************************
+ *
+ * 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: dp_configuration.src,v $
+ * $Revision: 1.6 $
+ *
+ * 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 "dp_configuration.hrc"
+
+String RID_STR_CONF_SCHEMA
+{
+ Text [ en-US ] = "Configuration Schema";
+};
+
+String RID_STR_CONF_DATA
+{
+ Text [ en-US ] = "Configuration Data";
+};
+
diff --git a/desktop/source/deployment/registry/configuration/makefile.mk b/desktop/source/deployment/registry/configuration/makefile.mk
new file mode 100644
index 000000000000..433b1e638f49
--- /dev/null
+++ b/desktop/source/deployment/registry/configuration/makefile.mk
@@ -0,0 +1,55 @@
+#*************************************************************************
+#
+# 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.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.
+#
+#*************************************************************************
+
+PRJ = ..$/..$/..$/..
+
+PRJNAME = desktop
+TARGET = deployment_registry_configuration
+ENABLE_EXCEPTIONS = TRUE
+
+INCPRE += ..$/..$/inc
+
+.INCLUDE : settings.mk
+
+.IF "$(SYSTEM_DB)" == "YES"
+CFLAGS+=-DSYSTEM_DB -I$(DB_INCLUDES)
+.ENDIF
+
+SRS1NAME = $(TARGET)
+SRC1FILES = \
+ dp_configuration.src
+
+SLOFILES = \
+ $(SLO)$/dp_configuration.obj
+
+.INCLUDE : ..$/..$/target.pmk
+.INCLUDE : target.mk
+
diff --git a/desktop/source/deployment/registry/dp_backend.cxx b/desktop/source/deployment/registry/dp_backend.cxx
new file mode 100644
index 000000000000..aa67536bd425
--- /dev/null
+++ b/desktop/source/deployment/registry/dp_backend.cxx
@@ -0,0 +1,594 @@
+/*************************************************************************
+ *
+ * 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: dp_backend.cxx,v $
+ * $Revision: 1.20 $
+ *
+ * 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_desktop.hxx"
+
+#include "dp_backend.h"
+#include "dp_ucb.h"
+#include "rtl/uri.hxx"
+#include "cppuhelper/exc_hlp.hxx"
+#include "comphelper/servicedecl.hxx"
+#include "comphelper/unwrapargs.hxx"
+#include "ucbhelper/content.hxx"
+#include "com/sun/star/lang/WrappedTargetRuntimeException.hpp"
+#include "com/sun/star/beans/StringPair.hpp"
+
+
+using namespace ::dp_misc;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::ucb;
+using ::rtl::OUString;
+
+namespace dp_registry {
+namespace backend {
+
+//______________________________________________________________________________
+PackageRegistryBackend::~PackageRegistryBackend()
+{
+}
+
+//______________________________________________________________________________
+void PackageRegistryBackend::disposing( lang::EventObject const & event )
+ throw (RuntimeException)
+{
+ Reference<deployment::XPackage> xPackage(
+ event.Source, UNO_QUERY_THROW );
+ OUString url( xPackage->getURL() );
+ ::osl::MutexGuard guard( getMutex() );
+ if ( m_bound.erase( url ) != 1 )
+ {
+ OSL_ASSERT( false );
+ }
+}
+
+//______________________________________________________________________________
+PackageRegistryBackend::PackageRegistryBackend(
+ Sequence<Any> const & args,
+ Reference<XComponentContext> const & xContext )
+ : t_BackendBase( getMutex() ),
+ m_xComponentContext( xContext ),
+ m_eContext( CONTEXT_UNKNOWN ),
+ m_readOnly( false )
+{
+ boost::optional<OUString> cachePath;
+ boost::optional<bool> readOnly;
+ comphelper::unwrapArgs( args, m_context, cachePath, readOnly );
+ if (cachePath)
+ m_cachePath = *cachePath;
+ if (readOnly)
+ m_readOnly = *readOnly;
+
+ if (m_context.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("user") ))
+ m_eContext = CONTEXT_USER;
+ else if (m_context.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("shared") ))
+ m_eContext = CONTEXT_SHARED;
+ else if (m_context.matchIgnoreAsciiCaseAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("vnd.sun.star.tdoc:/") ))
+ m_eContext = CONTEXT_DOCUMENT;
+ else
+ m_eContext = CONTEXT_UNKNOWN;
+}
+
+//______________________________________________________________________________
+void PackageRegistryBackend::check()
+{
+ ::osl::MutexGuard guard( getMutex() );
+ if (rBHelper.bInDispose || rBHelper.bDisposed) {
+ throw lang::DisposedException(
+ OUSTR("PackageRegistryBackend instance has already been disposed!"),
+ static_cast<OWeakObject *>(this) );
+ }
+}
+
+//______________________________________________________________________________
+void PackageRegistryBackend::disposing()
+{
+ try {
+ m_xComponentContext.clear();
+ WeakComponentImplHelperBase::disposing();
+ }
+ catch (RuntimeException &) {
+ throw;
+ }
+ catch (Exception &) {
+ Any exc( ::cppu::getCaughtException() );
+ throw lang::WrappedTargetRuntimeException(
+ OUSTR("caught unexpected exception while disposing!"),
+ static_cast<OWeakObject *>(this), exc );
+ }
+}
+
+// XPackageRegistry
+//______________________________________________________________________________
+Reference<deployment::XPackage> PackageRegistryBackend::bindPackage(
+ OUString const & url, OUString const & mediaType,
+ Reference<XCommandEnvironment> const & xCmdEnv )
+ throw (deployment::DeploymentException, CommandFailedException,
+ lang::IllegalArgumentException, RuntimeException)
+{
+ ::osl::ResettableMutexGuard guard( getMutex() );
+ check();
+ t_string2weakref::const_iterator const iFind( m_bound.find( url ) );
+ if (iFind != m_bound.end()) {
+ Reference<deployment::XPackage> xPackage( iFind->second );
+ if (xPackage.is())
+ return xPackage;
+ }
+ guard.clear();
+
+ Reference<deployment::XPackage> xNewPackage;
+ try {
+ xNewPackage = bindPackage_( url, mediaType, xCmdEnv );
+ }
+ catch (RuntimeException &) {
+ throw;
+ }
+ catch (lang::IllegalArgumentException &) {
+ throw;
+ }
+ catch (CommandFailedException &) {
+ throw;
+ }
+ catch (deployment::DeploymentException &) {
+ throw;
+ }
+ catch (Exception &) {
+ Any exc( ::cppu::getCaughtException() );
+ throw deployment::DeploymentException(
+ OUSTR("Error binding package: ") + url,
+ static_cast<OWeakObject *>(this), exc );
+ }
+
+ guard.reset();
+ ::std::pair< t_string2weakref::iterator, bool > insertion(
+ m_bound.insert( t_string2weakref::value_type( url, xNewPackage ) ) );
+ if (insertion.second)
+ { // first insertion
+ OSL_ASSERT( Reference<XInterface>(insertion.first->second)
+ == xNewPackage );
+ }
+ else
+ { // found existing entry
+ Reference<deployment::XPackage> xPackage( insertion.first->second );
+ if (xPackage.is())
+ return xPackage;
+ insertion.first->second = xNewPackage;
+ }
+ guard.clear();
+ xNewPackage->addEventListener( this ); // listen for disposing events
+ return xNewPackage;
+}
+
+//##############################################################################
+
+//______________________________________________________________________________
+Package::~Package()
+{
+}
+
+//______________________________________________________________________________
+Package::Package( ::rtl::Reference<PackageRegistryBackend> const & myBackend,
+ OUString const & url,
+ OUString const & name,
+ OUString const & displayName,
+ Reference<deployment::XPackageTypeInfo> const & xPackageType )
+ : t_PackageBase( getMutex() ),
+ m_myBackend( myBackend ),
+ m_url( url ),
+ m_name( name ),
+ m_displayName( displayName ),
+ m_xPackageType( xPackageType )
+{
+}
+
+//______________________________________________________________________________
+void Package::disposing()
+{
+ m_myBackend.clear();
+ WeakComponentImplHelperBase::disposing();
+}
+
+//______________________________________________________________________________
+void Package::check() const
+{
+ ::osl::MutexGuard guard( getMutex() );
+ if (rBHelper.bInDispose || rBHelper.bDisposed) {
+ throw lang::DisposedException(
+ OUSTR("Package instance has already been disposed!"),
+ static_cast<OWeakObject *>(const_cast<Package *>(this)));
+ }
+}
+
+// XComponent
+//______________________________________________________________________________
+void Package::dispose() throw (RuntimeException)
+{
+ check();
+ WeakComponentImplHelperBase::dispose();
+}
+
+//______________________________________________________________________________
+void Package::addEventListener(
+ Reference<lang::XEventListener> const & xListener ) throw (RuntimeException)
+{
+ check();
+ WeakComponentImplHelperBase::addEventListener( xListener );
+}
+
+//______________________________________________________________________________
+void Package::removeEventListener(
+ Reference<lang::XEventListener> const & xListener ) throw (RuntimeException)
+{
+ check();
+ WeakComponentImplHelperBase::removeEventListener( xListener );
+}
+
+// XModifyBroadcaster
+//______________________________________________________________________________
+void Package::addModifyListener(
+ Reference<util::XModifyListener> const & xListener )
+ throw (RuntimeException)
+{
+ check();
+ rBHelper.addListener( ::getCppuType( &xListener ), xListener );
+}
+
+//______________________________________________________________________________
+void Package::removeModifyListener(
+ Reference<util::XModifyListener> const & xListener )
+ throw (RuntimeException)
+{
+ check();
+ rBHelper.removeListener( ::getCppuType( &xListener ), xListener );
+}
+
+//______________________________________________________________________________
+void Package::checkAborted(
+ ::rtl::Reference<AbortChannel> const & abortChannel )
+{
+ if (abortChannel.is() && abortChannel->isAborted()) {
+ throw CommandAbortedException(
+ OUSTR("abort!"), static_cast<OWeakObject *>(this) );
+ }
+}
+
+// XPackage
+//______________________________________________________________________________
+Reference<task::XAbortChannel> Package::createAbortChannel()
+ throw (RuntimeException)
+{
+ check();
+ return new AbortChannel;
+}
+
+//______________________________________________________________________________
+sal_Bool Package::isBundle() throw (RuntimeException)
+{
+ return false; // default
+}
+
+//______________________________________________________________________________
+::sal_Bool Package::checkPrerequisites(
+ const css::uno::Reference< css::task::XAbortChannel >&,
+ const css::uno::Reference< css::ucb::XCommandEnvironment >&,
+ sal_Bool, ::rtl::OUString const &)
+ throw (css::deployment::DeploymentException,
+ css::ucb::CommandFailedException,
+ css::ucb::CommandAbortedException,
+ css::uno::RuntimeException)
+{
+ return true;
+}
+
+//______________________________________________________________________________
+::sal_Bool Package::checkDependencies(
+ const css::uno::Reference< css::ucb::XCommandEnvironment >& )
+ throw (css::deployment::DeploymentException,
+ css::ucb::CommandFailedException,
+ css::uno::RuntimeException)
+{
+ return true;
+}
+
+
+//______________________________________________________________________________
+Sequence< Reference<deployment::XPackage> > Package::getBundle(
+ Reference<task::XAbortChannel> const &,
+ Reference<XCommandEnvironment> const & )
+ throw (deployment::DeploymentException,
+ CommandFailedException, CommandAbortedException,
+ lang::IllegalArgumentException, RuntimeException)
+{
+ return Sequence< Reference<deployment::XPackage> >();
+}
+
+//______________________________________________________________________________
+OUString Package::getName() throw (RuntimeException)
+{
+ return m_name;
+}
+
+beans::Optional<OUString> Package::getIdentifier() throw (RuntimeException)
+{
+ return beans::Optional<OUString>();
+}
+
+//______________________________________________________________________________
+OUString Package::getVersion() throw (RuntimeException)
+{
+ return OUString();
+}
+
+//______________________________________________________________________________
+OUString Package::getURL() throw (RuntimeException)
+{
+ return m_url;
+}
+
+//______________________________________________________________________________
+OUString Package::getDisplayName() throw (RuntimeException)
+{
+ return m_displayName;
+}
+
+//______________________________________________________________________________
+OUString Package::getDescription() throw (RuntimeException)
+{
+ return OUString();
+}
+
+//______________________________________________________________________________
+Sequence<OUString> Package::getUpdateInformationURLs() throw (RuntimeException)
+{
+ return Sequence<OUString>();
+}
+
+//______________________________________________________________________________
+css::beans::StringPair Package::getPublisherInfo() throw (RuntimeException)
+{
+ css::beans::StringPair aEmptyPair;
+ return aEmptyPair;
+}
+
+//______________________________________________________________________________
+uno::Reference< css::graphic::XGraphic > Package::getIcon( sal_Bool /*bHighContrast*/ ) throw ( RuntimeException )
+{
+ uno::Reference< css::graphic::XGraphic > aEmpty;
+ return aEmpty;
+}
+
+//______________________________________________________________________________
+Reference<deployment::XPackageTypeInfo> Package::getPackageType()
+ throw (RuntimeException)
+{
+ return m_xPackageType;
+}
+
+//______________________________________________________________________________
+void Package::exportTo(
+ OUString const & destFolderURL, OUString const & newTitle,
+ sal_Int32 nameClashAction, Reference<XCommandEnvironment> const & xCmdEnv )
+ throw (CommandFailedException, CommandAbortedException, RuntimeException)
+{
+ ::ucbhelper::Content destFolder( destFolderURL, xCmdEnv );
+ ::ucbhelper::Content sourceContent( getURL(), xCmdEnv );
+ if (! destFolder.transferContent(
+ sourceContent, ::ucbhelper::InsertOperation_COPY,
+ newTitle, nameClashAction ))
+ throw RuntimeException( OUSTR("UCB transferContent() failed!"), 0 );
+}
+
+//______________________________________________________________________________
+void Package::fireModified()
+{
+ ::cppu::OInterfaceContainerHelper * container = rBHelper.getContainer(
+ ::getCppuType( static_cast<Reference<
+ util::XModifyListener> const *>(0) ) );
+ if (container != 0) {
+ Sequence< Reference<XInterface> > elements(
+ container->getElements() );
+ lang::EventObject evt( static_cast<OWeakObject *>(this) );
+ for ( sal_Int32 pos = 0; pos < elements.getLength(); ++pos )
+ {
+ Reference<util::XModifyListener> xListener(
+ elements[ pos ], UNO_QUERY );
+ if (xListener.is())
+ xListener->modified( evt );
+ }
+ }
+}
+
+// XPackage
+//______________________________________________________________________________
+beans::Optional< beans::Ambiguous<sal_Bool> > Package::isRegistered(
+ Reference<task::XAbortChannel> const & xAbortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv )
+ throw (deployment::DeploymentException,
+ CommandFailedException, CommandAbortedException, RuntimeException)
+{
+ try {
+ ::osl::ResettableMutexGuard guard( getMutex() );
+ return isRegistered_( guard,
+ AbortChannel::get(xAbortChannel),
+ xCmdEnv );
+ }
+ catch (RuntimeException &) {
+ throw;
+ }
+ catch (CommandFailedException &) {
+ throw;
+ }
+ catch (CommandAbortedException &) {
+ throw;
+ }
+ catch (deployment::DeploymentException &) {
+ throw;
+ }
+ catch (Exception &) {
+ Any exc( ::cppu::getCaughtException() );
+ throw deployment::DeploymentException(
+ OUSTR("unexpected exception occured!"),
+ static_cast<OWeakObject *>(this), exc );
+ }
+}
+
+//______________________________________________________________________________
+void Package::processPackage_impl(
+ bool doRegisterPackage,
+ Reference<task::XAbortChannel> const & xAbortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv )
+{
+ check();
+ bool action = false;
+
+ try {
+ try {
+ ::osl::ResettableMutexGuard guard( getMutex() );
+ beans::Optional< beans::Ambiguous<sal_Bool> > option(
+ isRegistered_( guard, AbortChannel::get(xAbortChannel),
+ xCmdEnv ) );
+ action = (option.IsPresent &&
+ (option.Value.IsAmbiguous ||
+ (doRegisterPackage ? !option.Value.Value
+ : option.Value.Value)));
+ if (action) {
+ OUString displayName( getDisplayName() );
+ ProgressLevel progress(
+ xCmdEnv,
+ (doRegisterPackage
+ ? PackageRegistryBackend::StrRegisteringPackage::get()
+ : PackageRegistryBackend::StrRevokingPackage::get())
+ + displayName );
+ processPackage_( guard,
+ doRegisterPackage,
+ AbortChannel::get(xAbortChannel),
+ xCmdEnv );
+ }
+ }
+ catch (RuntimeException &) {
+ OSL_ENSURE( 0, "### unexpected RuntimeException!" );
+ throw;
+ }
+ catch (CommandFailedException &) {
+ throw;
+ }
+ catch (CommandAbortedException &) {
+ throw;
+ }
+ catch (deployment::DeploymentException &) {
+ throw;
+ }
+ catch (Exception &) {
+ Any exc( ::cppu::getCaughtException() );
+ throw deployment::DeploymentException(
+ (doRegisterPackage
+ ? getResourceString(RID_STR_ERROR_WHILE_REGISTERING)
+ : getResourceString(RID_STR_ERROR_WHILE_REVOKING))
+ + getDisplayName(), static_cast<OWeakObject *>(this), exc );
+ }
+ }
+ catch (...) {
+ if (action)
+ fireModified();
+ throw;
+ }
+ if (action)
+ fireModified();
+}
+
+//______________________________________________________________________________
+void Package::registerPackage(
+ Reference<task::XAbortChannel> const & xAbortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv )
+ throw (deployment::DeploymentException,
+ CommandFailedException, CommandAbortedException,
+ lang::IllegalArgumentException, RuntimeException)
+{
+ processPackage_impl( true /* register */, xAbortChannel, xCmdEnv );
+}
+
+//______________________________________________________________________________
+void Package::revokePackage(
+ Reference<task::XAbortChannel> const & xAbortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv )
+ throw (deployment::DeploymentException,
+ CommandFailedException, CommandAbortedException,
+ lang::IllegalArgumentException, RuntimeException)
+{
+ processPackage_impl( false /* revoke */, xAbortChannel, xCmdEnv );
+}
+
+//##############################################################################
+
+//______________________________________________________________________________
+Package::TypeInfo::~TypeInfo()
+{
+}
+
+// XPackageTypeInfo
+//______________________________________________________________________________
+OUString Package::TypeInfo::getMediaType() throw (RuntimeException)
+{
+ return m_mediaType;
+}
+
+//______________________________________________________________________________
+OUString Package::TypeInfo::getDescription() throw (RuntimeException)
+{
+ return getShortDescription();
+}
+
+//______________________________________________________________________________
+OUString Package::TypeInfo::getShortDescription() throw (RuntimeException)
+{
+ return m_shortDescr;
+}
+
+//______________________________________________________________________________
+OUString Package::TypeInfo::getFileFilter() throw (RuntimeException)
+{
+ return m_fileFilter;
+}
+
+//______________________________________________________________________________
+Any Package::TypeInfo::getIcon( sal_Bool highContrast, sal_Bool smallIcon )
+ throw (RuntimeException)
+{
+ if (! smallIcon)
+ return Any();
+ const sal_uInt16 nIconId = (highContrast ? m_smallIcon_HC : m_smallIcon);
+ return Any( &nIconId, getCppuType( static_cast<sal_uInt16 const *>(0) ) );
+}
+
+}
+}
+
diff --git a/desktop/source/deployment/registry/dp_registry.cxx b/desktop/source/deployment/registry/dp_registry.cxx
new file mode 100644
index 000000000000..0c3e8bd214d4
--- /dev/null
+++ b/desktop/source/deployment/registry/dp_registry.cxx
@@ -0,0 +1,531 @@
+/*************************************************************************
+ *
+ * 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: dp_registry.cxx,v $
+ * $Revision: 1.12.86.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_desktop.hxx"
+
+#include "dp_registry.hrc"
+#include "dp_misc.h"
+#include "dp_resource.h"
+#include "dp_interact.h"
+#include "dp_ucb.h"
+#include "osl/diagnose.h"
+#include "rtl/ustrbuf.hxx"
+#include "rtl/uri.hxx"
+#include "cppuhelper/compbase2.hxx"
+#include "cppuhelper/exc_hlp.hxx"
+#include "comphelper/sequence.hxx"
+#include "ucbhelper/content.hxx"
+#include "com/sun/star/uno/DeploymentException.hpp"
+#include "com/sun/star/lang/DisposedException.hpp"
+#include "com/sun/star/lang/WrappedTargetRuntimeException.hpp"
+#include "com/sun/star/lang/XServiceInfo.hpp"
+#include "com/sun/star/lang/XSingleComponentFactory.hpp"
+#include "com/sun/star/lang/XSingleServiceFactory.hpp"
+#include "com/sun/star/util/XUpdatable.hpp"
+#include "com/sun/star/container/XContentEnumerationAccess.hpp"
+#include "com/sun/star/deployment/PackageRegistryBackend.hpp"
+#include <hash_map>
+#include <set>
+#include <hash_set>
+#include <memory>
+
+using namespace ::dp_misc;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::ucb;
+using ::rtl::OUString;
+
+
+namespace dp_registry {
+
+namespace backend {
+namespace bundle {
+Reference<deployment::XPackageRegistry> create(
+ Reference<deployment::XPackageRegistry> const & xRootRegistry,
+ OUString const & context, OUString const & cachePath, bool readOnly,
+ Reference<XComponentContext> const & xComponentContext );
+}
+}
+
+namespace {
+
+typedef ::cppu::WeakComponentImplHelper2<
+ deployment::XPackageRegistry, util::XUpdatable > t_helper;
+
+//==============================================================================
+class PackageRegistryImpl : private MutexHolder, public t_helper
+{
+ struct ci_string_hash {
+ ::std::size_t operator () ( OUString const & str ) const {
+ return str.toAsciiLowerCase().hashCode();
+ }
+ };
+ struct ci_string_equals {
+ bool operator () ( OUString const & str1, OUString const & str2 ) const{
+ return str1.equalsIgnoreAsciiCase( str2 );
+ }
+ };
+ typedef ::std::hash_map<
+ OUString, Reference<deployment::XPackageRegistry>,
+ ci_string_hash, ci_string_equals > t_string2registry;
+ typedef ::std::hash_map<
+ OUString, OUString,
+ ci_string_hash, ci_string_equals > t_string2string;
+ typedef ::std::set<
+ Reference<deployment::XPackageRegistry> > t_registryset;
+
+ t_string2registry m_mediaType2backend;
+ t_string2string m_filter2mediaType;
+ t_registryset m_ambiguousBackends;
+ t_registryset m_allBackends;
+ ::std::vector< Reference<deployment::XPackageTypeInfo> > m_typesInfos;
+
+ void insertBackend(
+ Reference<deployment::XPackageRegistry> const & xBackend );
+
+protected:
+ inline void check();
+ virtual void SAL_CALL disposing();
+
+ virtual ~PackageRegistryImpl();
+ PackageRegistryImpl() : t_helper( getMutex() ) {}
+
+public:
+ static Reference<deployment::XPackageRegistry> create(
+ OUString const & context,
+ OUString const & cachePath, bool readOnly,
+ Reference<XComponentContext> const & xComponentContext );
+
+ // XUpdatable
+ virtual void SAL_CALL update() throw (RuntimeException);
+
+ // XPackageRegistry
+ virtual Reference<deployment::XPackage> SAL_CALL bindPackage(
+ OUString const & url, OUString const & mediaType,
+ Reference<XCommandEnvironment> const & xCmdEnv )
+ throw (deployment::DeploymentException, CommandFailedException,
+ lang::IllegalArgumentException, RuntimeException);
+ virtual Sequence< Reference<deployment::XPackageTypeInfo> > SAL_CALL
+ getSupportedPackageTypes() throw (RuntimeException);
+};
+
+//______________________________________________________________________________
+inline void PackageRegistryImpl::check()
+{
+ ::osl::MutexGuard guard( getMutex() );
+ if (rBHelper.bInDispose || rBHelper.bDisposed) {
+ throw lang::DisposedException(
+ OUSTR("PackageRegistry instance has already been disposed!"),
+ static_cast<OWeakObject *>(this) );
+ }
+}
+
+//______________________________________________________________________________
+void PackageRegistryImpl::disposing()
+{
+ // dispose all backends:
+ t_registryset::const_iterator iPos( m_allBackends.begin() );
+ t_registryset::const_iterator const iEnd( m_allBackends.end() );
+ for ( ; iPos != iEnd; ++iPos ) {
+ try_dispose( *iPos );
+ }
+ m_mediaType2backend = t_string2registry();
+ m_ambiguousBackends = t_registryset();
+ m_allBackends = t_registryset();
+
+ t_helper::disposing();
+}
+
+//______________________________________________________________________________
+PackageRegistryImpl::~PackageRegistryImpl()
+{
+}
+
+//______________________________________________________________________________
+OUString normalizeMediaType( OUString const & mediaType )
+{
+ ::rtl::OUStringBuffer buf;
+ sal_Int32 index = 0;
+ for (;;) {
+ buf.append( mediaType.getToken( 0, '/', index ).trim() );
+ if (index < 0)
+ break;
+ buf.append( static_cast< sal_Unicode >('/') );
+ }
+ return buf.makeStringAndClear();
+}
+
+//______________________________________________________________________________
+void PackageRegistryImpl::insertBackend(
+ Reference<deployment::XPackageRegistry> const & xBackend )
+{
+ m_allBackends.insert( xBackend );
+ typedef ::std::hash_set<OUString, ::rtl::OUStringHash> t_stringset;
+ t_stringset ambiguousFilters;
+
+ const Sequence< Reference<deployment::XPackageTypeInfo> > packageTypes(
+ xBackend->getSupportedPackageTypes() );
+ for ( sal_Int32 pos = 0; pos < packageTypes.getLength(); ++pos )
+ {
+ Reference<deployment::XPackageTypeInfo> const & xPackageType =
+ packageTypes[ pos ];
+ m_typesInfos.push_back( xPackageType );
+
+ const OUString mediaType( normalizeMediaType(
+ xPackageType->getMediaType() ) );
+ ::std::pair<t_string2registry::iterator, bool> mb_insertion(
+ m_mediaType2backend.insert( t_string2registry::value_type(
+ mediaType, xBackend ) ) );
+ if (mb_insertion.second) {
+ // add parameterless media-type, too:
+ sal_Int32 semi = mediaType.indexOf( ';' );
+ if (semi >= 0) {
+ m_mediaType2backend.insert(
+ t_string2registry::value_type(
+ mediaType.copy( 0, semi ), xBackend ) );
+ }
+ const OUString fileFilter( xPackageType->getFileFilter() );
+ if (fileFilter.getLength() == 0 ||
+ fileFilter.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("*.*") ) ||
+ fileFilter.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("*") ))
+ {
+ m_ambiguousBackends.insert( xBackend );
+ }
+ else
+ {
+ sal_Int32 nIndex = 0;
+ do {
+ OUString token( fileFilter.getToken( 0, ';', nIndex ) );
+ if (token.matchAsciiL( RTL_CONSTASCII_STRINGPARAM("*.") ))
+ token = token.copy( 1 );
+ if (token.getLength() == 0)
+ continue;
+ // mark any further wildcards ambig:
+ bool ambig = (token.indexOf('*') >= 0 ||
+ token.indexOf('?') >= 0);
+ if (! ambig) {
+ ::std::pair<t_string2string::iterator, bool> ins(
+ m_filter2mediaType.insert(
+ t_string2string::value_type(
+ token, mediaType ) ) );
+ ambig = !ins.second;
+ if (ambig) {
+ // filter has already been in: add previously
+ // added backend to ambig set
+ const t_string2registry::const_iterator iFind(
+ m_mediaType2backend.find(
+ /* media-type of pr. added backend */
+ ins.first->second ) );
+ OSL_ASSERT(
+ iFind != m_mediaType2backend.end() );
+ if (iFind != m_mediaType2backend.end())
+ m_ambiguousBackends.insert( iFind->second );
+ }
+ }
+ if (ambig) {
+ m_ambiguousBackends.insert( xBackend );
+ // mark filter to be removed later from filters map:
+ ambiguousFilters.insert( token );
+ }
+ }
+ while (nIndex >= 0);
+ }
+ }
+#if OSL_DEBUG_LEVEL > 0
+ else {
+ ::rtl::OUStringBuffer buf;
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM(
+ "more than one PackageRegistryBackend for "
+ "media-type=\"") );
+ buf.append( mediaType );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\" => ") );
+ buf.append( Reference<lang::XServiceInfo>(
+ xBackend, UNO_QUERY_THROW )->
+ getImplementationName() );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\"!") );
+ OSL_ENSURE( 0, ::rtl::OUStringToOString(
+ buf.makeStringAndClear(),
+ RTL_TEXTENCODING_UTF8 ) );
+ }
+#endif
+ }
+
+ // cut out ambiguous filters:
+ t_stringset::const_iterator iPos( ambiguousFilters.begin() );
+ const t_stringset::const_iterator iEnd( ambiguousFilters.end() );
+ for ( ; iPos != iEnd; ++iPos ) {
+ m_filter2mediaType.erase( *iPos );
+ }
+}
+
+//______________________________________________________________________________
+Reference<deployment::XPackageRegistry> PackageRegistryImpl::create(
+ OUString const & context,
+ OUString const & cachePath, bool readOnly,
+ Reference<XComponentContext> const & xComponentContext )
+{
+ PackageRegistryImpl * that = new PackageRegistryImpl;
+ Reference<deployment::XPackageRegistry> xRet(that);
+
+ // auto-detect all registered package registries:
+ Reference<container::XEnumeration> xEnum(
+ Reference<container::XContentEnumerationAccess>(
+ xComponentContext->getServiceManager(),
+ UNO_QUERY_THROW )->createContentEnumeration(
+ OUSTR("com.sun.star.deployment.PackageRegistryBackend") ) );
+ if (xEnum.is())
+ {
+ while (xEnum->hasMoreElements())
+ {
+ Any element( xEnum->nextElement() );
+ Sequence<Any> registryArgs(
+ cachePath.getLength() == 0 ? 1 : 3 );
+ registryArgs[ 0 ] <<= context;
+ if (cachePath.getLength() > 0)
+ {
+ Reference<lang::XServiceInfo> xServiceInfo(
+ element, UNO_QUERY_THROW );
+ OUString registryCachePath(
+ makeURL( cachePath,
+ ::rtl::Uri::encode(
+ xServiceInfo->getImplementationName(),
+ rtl_UriCharClassPchar,
+ rtl_UriEncodeIgnoreEscapes,
+ RTL_TEXTENCODING_UTF8 ) ) );
+ registryArgs[ 1 ] <<= registryCachePath;
+ registryArgs[ 2 ] <<= readOnly;
+ if (! readOnly)
+ create_folder( 0, registryCachePath,
+ Reference<XCommandEnvironment>() );
+ }
+
+ Reference<deployment::XPackageRegistry> xBackend;
+ Reference<lang::XSingleComponentFactory> xFac( element, UNO_QUERY );
+ if (xFac.is()) {
+ xBackend.set(
+ xFac->createInstanceWithArgumentsAndContext(
+ registryArgs, xComponentContext ), UNO_QUERY );
+ }
+ else {
+ Reference<lang::XSingleServiceFactory> xSingleServiceFac(
+ element, UNO_QUERY_THROW );
+ xBackend.set(
+ xSingleServiceFac->createInstanceWithArguments(
+ registryArgs ), UNO_QUERY );
+ }
+ if (! xBackend.is()) {
+ throw DeploymentException(
+ OUSTR("cannot instantiate PackageRegistryBackend service: ")
+ + Reference<lang::XServiceInfo>(
+ element, UNO_QUERY_THROW )->getImplementationName(),
+ static_cast<OWeakObject *>(that) );
+ }
+
+ that->insertBackend( xBackend );
+ }
+ }
+
+ // insert bundle be:
+ that->insertBackend(
+ ::dp_registry::backend::bundle::create(
+ that, context, cachePath, readOnly, xComponentContext ) );
+
+#if OSL_DEBUG_LEVEL > 1
+ // dump tables:
+ {
+ t_registryset allBackends;
+ dp_misc::TRACE("> [dp_registry.cxx] media-type detection:\n\n" );
+ for ( t_string2string::const_iterator iPos(
+ that->m_filter2mediaType.begin() );
+ iPos != that->m_filter2mediaType.end(); ++iPos )
+ {
+ ::rtl::OUStringBuffer buf;
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("extension \"") );
+ buf.append( iPos->first );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
+ "\" maps to media-type \"") );
+ buf.append( iPos->second );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
+ "\" maps to backend ") );
+ const Reference<deployment::XPackageRegistry> xBackend(
+ that->m_mediaType2backend.find( iPos->second )->second );
+ allBackends.insert( xBackend );
+ buf.append( Reference<lang::XServiceInfo>(
+ xBackend, UNO_QUERY_THROW )
+ ->getImplementationName() );
+ dp_misc::writeConsole( buf.makeStringAndClear() + OUSTR("\n"));
+ }
+ dp_misc::TRACE( "> [dp_registry.cxx] ambiguous backends:\n\n" );
+ for ( t_registryset::const_iterator iPos(
+ that->m_ambiguousBackends.begin() );
+ iPos != that->m_ambiguousBackends.end(); ++iPos )
+ {
+ ::rtl::OUStringBuffer buf;
+ buf.append(
+ Reference<lang::XServiceInfo>(
+ *iPos, UNO_QUERY_THROW )->getImplementationName() );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(": ") );
+ const Sequence< Reference<deployment::XPackageTypeInfo> > types(
+ (*iPos)->getSupportedPackageTypes() );
+ for ( sal_Int32 pos = 0; pos < types.getLength(); ++pos ) {
+ Reference<deployment::XPackageTypeInfo> const & xInfo =
+ types[ pos ];
+ buf.append( xInfo->getMediaType() );
+ const OUString filter( xInfo->getFileFilter() );
+ if (filter.getLength() > 0) {
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" (") );
+ buf.append( filter );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(")") );
+ }
+ if (pos < (types.getLength() - 1))
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(", ") );
+ }
+ dp_misc::TRACE(buf.makeStringAndClear() + OUSTR("\n\n"));
+ }
+ allBackends.insert( that->m_ambiguousBackends.begin(),
+ that->m_ambiguousBackends.end() );
+ OSL_ASSERT( allBackends == that->m_allBackends );
+ }
+#endif
+
+ return xRet;
+}
+
+// XUpdatable: broadcast to backends
+//______________________________________________________________________________
+void PackageRegistryImpl::update() throw (RuntimeException)
+{
+ check();
+ t_registryset::const_iterator iPos( m_allBackends.begin() );
+ const t_registryset::const_iterator iEnd( m_allBackends.end() );
+ for ( ; iPos != iEnd; ++iPos ) {
+ const Reference<util::XUpdatable> xUpdatable( *iPos, UNO_QUERY );
+ if (xUpdatable.is())
+ xUpdatable->update();
+ }
+}
+
+// XPackageRegistry
+//______________________________________________________________________________
+Reference<deployment::XPackage> PackageRegistryImpl::bindPackage(
+ OUString const & url, OUString const & mediaType_,
+ Reference<XCommandEnvironment> const & xCmdEnv )
+ throw (deployment::DeploymentException, CommandFailedException,
+ lang::IllegalArgumentException, RuntimeException)
+{
+ check();
+ OUString mediaType(mediaType_);
+ if (mediaType.getLength() == 0)
+ {
+ ::ucbhelper::Content ucbContent;
+ if (create_ucb_content(
+ &ucbContent, url, xCmdEnv, false /* no throw */ ))
+ {
+ OUString title( ucbContent.getPropertyValue(
+ StrTitle::get() ).get<OUString>() );
+ for (;;)
+ {
+ const t_string2string::const_iterator iFind(
+ m_filter2mediaType.find(title) );
+ if (iFind != m_filter2mediaType.end()) {
+ mediaType = iFind->second;
+ break;
+ }
+ sal_Int32 point = title.indexOf( '.', 1 /* consume . */ );
+ if (point < 0)
+ break;
+ title = title.copy(point);
+ }
+ }
+ }
+ if (mediaType.getLength() == 0)
+ {
+ // try ambiguous backends:
+ t_registryset::const_iterator iPos( m_ambiguousBackends.begin() );
+ const t_registryset::const_iterator iEnd( m_ambiguousBackends.end() );
+ for ( ; iPos != iEnd; ++iPos )
+ {
+ try {
+ return (*iPos)->bindPackage( url, mediaType, xCmdEnv );
+ }
+ catch (lang::IllegalArgumentException &) {
+ }
+ }
+ throw lang::IllegalArgumentException(
+ getResourceString(RID_STR_CANNOT_DETECT_MEDIA_TYPE) + url,
+ static_cast<OWeakObject *>(this), static_cast<sal_Int16>(-1) );
+ }
+ else
+ {
+ // get backend by media-type:
+ t_string2registry::const_iterator iFind(
+ m_mediaType2backend.find( normalizeMediaType(mediaType) ) );
+ if (iFind == m_mediaType2backend.end()) {
+ // xxx todo: more sophisticated media-type argument parsing...
+ sal_Int32 q = mediaType.indexOf( ';' );
+ if (q >= 0) {
+ iFind = m_mediaType2backend.find(
+ normalizeMediaType(
+ // cut parameters:
+ mediaType.copy( 0, q ) ) );
+ }
+ }
+ if (iFind == m_mediaType2backend.end()) {
+ throw lang::IllegalArgumentException(
+ getResourceString(RID_STR_UNSUPPORTED_MEDIA_TYPE) + mediaType,
+ static_cast<OWeakObject *>(this), static_cast<sal_Int16>(-1) );
+ }
+ return iFind->second->bindPackage( url, mediaType, xCmdEnv );
+ }
+}
+
+//______________________________________________________________________________
+Sequence< Reference<deployment::XPackageTypeInfo> >
+PackageRegistryImpl::getSupportedPackageTypes() throw (RuntimeException)
+{
+ return comphelper::containerToSequence(m_typesInfos);
+}
+
+} // anon namespace
+
+//==============================================================================
+Reference<deployment::XPackageRegistry> SAL_CALL create(
+ OUString const & context,
+ OUString const & cachePath, bool readOnly,
+ Reference<XComponentContext> const & xComponentContext )
+{
+ return PackageRegistryImpl::create(
+ context, cachePath, readOnly, xComponentContext );
+}
+
+} // namespace dp_registry
+
diff --git a/desktop/source/deployment/registry/dp_registry.src b/desktop/source/deployment/registry/dp_registry.src
new file mode 100644
index 000000000000..7a29c802f03e
--- /dev/null
+++ b/desktop/source/deployment/registry/dp_registry.src
@@ -0,0 +1,62 @@
+/*************************************************************************
+ *
+ * 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: dp_registry.src,v $
+ * $Revision: 1.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 "dp_registry.hrc"
+
+String RID_STR_REGISTERING_PACKAGE
+{
+ Text [ en-US ] = "Enabling: ";
+};
+
+String RID_STR_REVOKING_PACKAGE
+{
+ Text [ en-US ] = "Disabling: ";
+};
+
+String RID_STR_CANNOT_DETECT_MEDIA_TYPE
+{
+ Text [ en-US ] = "Cannot detect media-type: ";
+};
+
+String RID_STR_UNSUPPORTED_MEDIA_TYPE
+{
+ Text [ en-US ] = "This media-type is not supported: ";
+};
+
+String RID_STR_ERROR_WHILE_REGISTERING
+{
+ Text [ en-US ] = "An error occurred while enabling: ";
+};
+
+String RID_STR_ERROR_WHILE_REVOKING
+{
+ Text [ en-US ] = "An error occurred while disabling: ";
+};
+
diff --git a/desktop/source/deployment/registry/executable/dp_executable.cxx b/desktop/source/deployment/registry/executable/dp_executable.cxx
new file mode 100644
index 000000000000..3afcb8d35636
--- /dev/null
+++ b/desktop/source/deployment/registry/executable/dp_executable.cxx
@@ -0,0 +1,292 @@
+/*************************************************************************
+ *
+ * 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: dp_executable.cxx,v $
+ * $Revision: 1.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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "dp_backend.h"
+#include "dp_ucb.h"
+#include "dp_interact.h"
+#include "rtl/string.hxx"
+#include "osl/file.hxx"
+#include "ucbhelper/content.hxx"
+#include "comphelper/servicedecl.hxx"
+#include "svtools/inettype.hxx"
+#include "cppuhelper/implbase1.hxx"
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::ucb;
+using ::rtl::OUString;
+
+namespace dp_registry {
+namespace backend {
+namespace executable {
+namespace {
+
+class BackendImpl : public ::dp_registry::backend::PackageRegistryBackend
+{
+ class ExecutablePackageImpl : public ::dp_registry::backend::Package
+ {
+ BackendImpl * getMyBackend() const;
+
+ // Package
+ virtual beans::Optional< beans::Ambiguous<sal_Bool> > isRegistered_(
+ ::osl::ResettableMutexGuard & guard,
+ ::rtl::Reference<dp_misc::AbortChannel> const & abortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+ virtual void processPackage_(
+ ::osl::ResettableMutexGuard & guard,
+ bool registerPackage,
+ ::rtl::Reference<dp_misc::AbortChannel> const & abortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+
+ bool getFileAttributes(sal_uInt64& out_Attributes);
+ bool isUrlTargetInExtension();
+
+ public:
+ inline ExecutablePackageImpl(
+ ::rtl::Reference<PackageRegistryBackend> const & myBackend,
+ OUString const & url, OUString const & name,
+ Reference<deployment::XPackageTypeInfo> const & xPackageType)
+ : Package( myBackend, url, name, name /* display-name */,
+ xPackageType ) //,
+ {}
+ };
+ friend class ExecutablePackageImpl;
+
+ typedef ::std::hash_map< OUString, Reference<XInterface>,
+ ::rtl::OUStringHash > t_string2object;
+
+ // PackageRegistryBackend
+ virtual Reference<deployment::XPackage> bindPackage_(
+ OUString const & url, OUString const & mediaType,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+
+ Reference<deployment::XPackageTypeInfo> m_xExecutableTypeInfo;
+
+public:
+ BackendImpl( Sequence<Any> const & args,
+ Reference<XComponentContext> const & xComponentContext );
+
+ // XPackageRegistry
+ virtual Sequence< Reference<deployment::XPackageTypeInfo> > SAL_CALL
+ getSupportedPackageTypes() throw (RuntimeException);
+
+ using PackageRegistryBackend::disposing;
+};
+
+
+BackendImpl::BackendImpl(
+ Sequence<Any> const & args,
+ Reference<XComponentContext> const & xComponentContext )
+ : PackageRegistryBackend( args, xComponentContext ),
+ m_xExecutableTypeInfo(new Package::TypeInfo(
+ OUSTR("application/vnd.sun.star.executable"),
+ OUSTR(""),
+ OUSTR("Executable"),
+ RID_IMG_COMPONENT,
+ RID_IMG_COMPONENT_HC ) )
+{
+
+}
+
+// XPackageRegistry
+Sequence< Reference<deployment::XPackageTypeInfo> >
+BackendImpl::getSupportedPackageTypes() throw (RuntimeException)
+{
+ return Sequence<Reference<deployment::XPackageTypeInfo> >(
+ & m_xExecutableTypeInfo, 1);
+}
+
+// PackageRegistryBackend
+Reference<deployment::XPackage> BackendImpl::bindPackage_(
+ OUString const & url, OUString const & mediaType,
+ Reference<XCommandEnvironment> const & xCmdEnv )
+{
+ if (mediaType.getLength() == 0)
+ {
+ throw lang::IllegalArgumentException(
+ StrCannotDetectMediaType::get() + url,
+ static_cast<OWeakObject *>(this), static_cast<sal_Int16>(-1) );
+ }
+
+ String type, subType;
+ INetContentTypeParameterList params;
+ if (INetContentTypes::parse( mediaType, type, subType, &params ))
+ {
+ if (type.EqualsIgnoreCaseAscii("application"))
+ {
+ ::ucbhelper::Content ucbContent( url, xCmdEnv );
+ const OUString name( ucbContent.getPropertyValue(
+ dp_misc::StrTitle::get() ).get<OUString>() );
+ if (subType.EqualsIgnoreCaseAscii("vnd.sun.star.executable"))
+ {
+ return new BackendImpl::ExecutablePackageImpl(
+ this, url, name, m_xExecutableTypeInfo);
+ }
+ }
+ }
+ return Reference<deployment::XPackage>();
+}
+
+//##############################################################################
+
+
+// Package
+BackendImpl * BackendImpl::ExecutablePackageImpl::getMyBackend() const
+{
+ BackendImpl * pBackend = static_cast<BackendImpl *>(m_myBackend.get());
+ if (NULL == pBackend)
+ {
+ //May throw a DisposedException
+ check();
+ //We should never get here...
+ throw RuntimeException(
+ OUSTR("Failed to get the BackendImpl"),
+ static_cast<OWeakObject*>(const_cast<ExecutablePackageImpl *>(this)));
+ }
+ return pBackend;
+}
+
+beans::Optional< beans::Ambiguous<sal_Bool> >
+BackendImpl::ExecutablePackageImpl::isRegistered_(
+ ::osl::ResettableMutexGuard &,
+ ::rtl::Reference<dp_misc::AbortChannel> const &,
+ Reference<XCommandEnvironment> const & )
+{
+ //We must return Optional.isPresent = true, otherwise
+ //processPackage is not called.
+ //The user shall not be able to enable/disable the executable. This is not needed since
+ //the executable does not affect the office. The best thing is to show no
+ //status at all. See also BackendImpl::PackageImpl::isRegistered_ (dp_package.cxx)
+ //On Windows there is no executable file attribute. One has to use security API for this.
+ //However, on Windows we do not have the problem, that after unzipping the file cannot be
+ //executed.
+ return beans::Optional< beans::Ambiguous<sal_Bool> >(
+ sal_True /* IsPresent */,
+ beans::Ambiguous<sal_Bool>(
+ sal_True, sal_True /* IsAmbiguous */ ) );
+}
+
+void BackendImpl::ExecutablePackageImpl::processPackage_(
+ ::osl::ResettableMutexGuard &,
+ bool doRegisterPackage,
+ ::rtl::Reference<dp_misc::AbortChannel> const & abortChannel,
+ Reference<XCommandEnvironment> const & /*xCmdEnv*/ )
+{
+ checkAborted(abortChannel);
+ if (doRegisterPackage)
+ {
+ if (!isUrlTargetInExtension())
+ {
+ OSL_ASSERT(0);
+ return;
+ }
+ sal_uInt64 attributes = 0;
+ //Setting the executable attribut does not affect executables on Windows
+ if (getFileAttributes(attributes))
+ {
+ if(getMyBackend()->m_context.equals(OUSTR("user")))
+ attributes |= osl_File_Attribute_OwnExe;
+ else if (getMyBackend()->m_context.equals(OUSTR("shared")))
+ attributes |= (osl_File_Attribute_OwnExe | osl_File_Attribute_GrpExe
+ | osl_File_Attribute_OthExe);
+ else
+ OSL_ASSERT(0);
+
+ //This won't have affect on Windows
+ if (osl::File::E_None != osl::File::setAttributes(
+ dp_misc::expandUnoRcUrl(m_url), attributes))
+ OSL_ENSURE(0, "Extension Manager: Could not set executable file attribute.");
+ }
+ }
+}
+
+//We currently cannot check if this XPackage represents a content of a particular exension
+//But we can check if we are within $UNO_USER_PACKAGES_CACHE etc.
+bool BackendImpl::ExecutablePackageImpl::isUrlTargetInExtension()
+{
+ bool bSuccess = false;
+ OUString sExtensionDir;
+ if(getMyBackend()->m_context.equals(OUSTR("user")))
+ sExtensionDir = dp_misc::expandUnoRcTerm(OUSTR("$UNO_USER_PACKAGES_CACHE"));
+ else if (getMyBackend()->m_context.equals(OUSTR("shared")))
+ sExtensionDir = dp_misc::expandUnoRcTerm(OUSTR("$UNO_SHARED_PACKAGES_CACHE"));
+ else
+ OSL_ASSERT(0);
+ //remove file ellipses
+ if (osl::File::E_None == osl::File::getAbsoluteFileURL(OUString(), sExtensionDir, sExtensionDir))
+ {
+ OUString sFile;
+ if (osl::File::E_None == osl::File::getAbsoluteFileURL(
+ OUString(), dp_misc::expandUnoRcUrl(m_url), sFile))
+ {
+ if (sal_True == sFile.match(sExtensionDir, 0))
+ bSuccess = true;
+ }
+ }
+ return bSuccess;
+}
+
+bool BackendImpl::ExecutablePackageImpl::getFileAttributes(sal_uInt64& out_Attributes)
+{
+ bool bSuccess = false;
+ const OUString url(dp_misc::expandUnoRcUrl(m_url));
+ osl::DirectoryItem item;
+ if (osl::FileBase::E_None == osl::DirectoryItem::get(url, item))
+ {
+ osl::FileStatus aStatus(osl_FileStatus_Mask_Attributes);
+ if( osl::FileBase::E_None == item.getFileStatus(aStatus))
+ {
+ out_Attributes = aStatus.getAttributes();
+ bSuccess = true;
+ }
+ }
+ return bSuccess;
+}
+
+//##############################################################################
+
+
+} // anon namespace
+
+namespace sdecl = comphelper::service_decl;
+sdecl::class_<BackendImpl, sdecl::with_args<true> > serviceBI;
+extern sdecl::ServiceDecl const serviceDecl(
+ serviceBI,
+ "com.sun.star.comp.deployment.executable.PackageRegistryBackend",
+ BACKEND_SERVICE_NAME );
+
+} // namespace component
+} // namespace backend
+} // namespace dp_registry
+
+
diff --git a/desktop/source/deployment/registry/executable/makefile.mk b/desktop/source/deployment/registry/executable/makefile.mk
new file mode 100644
index 000000000000..7ad5289655a6
--- /dev/null
+++ b/desktop/source/deployment/registry/executable/makefile.mk
@@ -0,0 +1,47 @@
+#*************************************************************************
+#
+# 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 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ = ..$/..$/..$/..
+
+PRJNAME = desktop
+TARGET = deployment_registry_executable
+ENABLE_EXCEPTIONS = TRUE
+
+.INCLUDE : settings.mk
+
+INCPRE += ..$/..$/inc
+
+SLOFILES = \
+ $(SLO)$/dp_executable.obj
+
+.INCLUDE : ..$/..$/target.pmk
+.INCLUDE : target.mk
+
diff --git a/desktop/source/deployment/registry/help/dp_help.cxx b/desktop/source/deployment/registry/help/dp_help.cxx
new file mode 100644
index 000000000000..dd9e009e90cc
--- /dev/null
+++ b/desktop/source/deployment/registry/help/dp_help.cxx
@@ -0,0 +1,592 @@
+/*************************************************************************
+ *
+ * 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: dp_help.cxx,v $
+ * $Revision: 1.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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_desktop.hxx"
+
+#include "dp_help.hrc"
+#include "dp_backend.h"
+#include "dp_ucb.h"
+#include "rtl/uri.hxx"
+#include "osl/file.hxx"
+#include "ucbhelper/content.hxx"
+#include "comphelper/servicedecl.hxx"
+#include "svtools/inettype.hxx"
+
+#include <transex3/compilehelp.hxx>
+#include <com/sun/star/ucb/XSimpleFileAccess.hpp>
+#include <com/sun/star/util/XMacroExpander.hpp>
+#include <com/sun/star/uri/XUriReferenceFactory.hpp>
+#include <com/sun/star/uri/XVndSunStarExpandUrl.hpp>
+#include <com/sun/star/script/XInvocation.hpp>
+
+using namespace ::dp_misc;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::ucb;
+using ::rtl::OUString;
+
+namespace dp_registry {
+namespace backend {
+namespace help {
+namespace {
+
+//==============================================================================
+class BackendImpl : public ::dp_registry::backend::PackageRegistryBackend
+{
+ class PackageImpl : public ::dp_registry::backend::Package
+ {
+ BackendImpl * getMyBackend() const;
+
+ // Package
+ virtual beans::Optional< beans::Ambiguous<sal_Bool> > isRegistered_(
+ ::osl::ResettableMutexGuard & guard,
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+ virtual void processPackage_(
+ ::osl::ResettableMutexGuard & guard,
+ bool registerPackage,
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+
+ public:
+ inline PackageImpl(
+ ::rtl::Reference<PackageRegistryBackend> const & myBackend,
+ OUString const & url, OUString const & name,
+ Reference<deployment::XPackageTypeInfo> const & xPackageType )
+ : Package( myBackend, url, name, name, xPackageType )
+ {}
+ };
+ friend class PackageImpl;
+
+ // PackageRegistryBackend
+ virtual Reference<deployment::XPackage> bindPackage_(
+ OUString const & url, OUString const & mediaType,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+
+ void implProcessHelp( Reference< deployment::XPackage > xPackage, bool doRegisterPackage );
+ void implCollectXhpFiles( const rtl::OUString& aDir,
+ std::vector< rtl::OUString >& o_rXhpFileVector );
+ rtl::OUString getFlagFileURL( Reference< deployment::XPackage > xPackage, const char* pFlagStr );
+ rtl::OUString getRegisteredFlagFileURL( Reference< deployment::XPackage > xPackage );
+ rtl::OUString getCompiledFlagFileURL( Reference< deployment::XPackage > xPackage );
+ rtl::OUString expandURL( const rtl::OUString& aURL );
+ Reference< ucb::XSimpleFileAccess > getFileAccess( void );
+ Reference< ucb::XSimpleFileAccess > m_xSFA;
+
+ const Reference<deployment::XPackageTypeInfo> m_xHelpTypeInfo;
+ Sequence< Reference<deployment::XPackageTypeInfo> > m_typeInfos;
+
+public:
+ BackendImpl( Sequence<Any> const & args,
+ Reference<XComponentContext> const & xComponentContext );
+
+ // XPackageRegistry
+ virtual Sequence< Reference<deployment::XPackageTypeInfo> > SAL_CALL
+ getSupportedPackageTypes() throw (RuntimeException);
+};
+
+//______________________________________________________________________________
+BackendImpl::BackendImpl(
+ Sequence<Any> const & args,
+ Reference<XComponentContext> const & xComponentContext )
+ : PackageRegistryBackend( args, xComponentContext ),
+ m_xHelpTypeInfo( new Package::TypeInfo(
+ OUSTR("application/vnd.sun.star.help"),
+ rtl::OUString(),
+ getResourceString(RID_STR_HELP),
+ RID_IMG_HELP, RID_IMG_HELP_HC ) ),
+ m_typeInfos( 1 )
+{
+ m_typeInfos[ 0 ] = m_xHelpTypeInfo;
+}
+
+// XPackageRegistry
+//______________________________________________________________________________
+Sequence< Reference<deployment::XPackageTypeInfo> >
+BackendImpl::getSupportedPackageTypes() throw (RuntimeException)
+{
+ return m_typeInfos;
+}
+
+// PackageRegistryBackend
+//______________________________________________________________________________
+Reference<deployment::XPackage> BackendImpl::bindPackage_(
+ OUString const & url, OUString const & mediaType_,
+ Reference<XCommandEnvironment> const & xCmdEnv )
+{
+ // we don't support auto detection:
+ if (mediaType_.getLength() == 0)
+ throw lang::IllegalArgumentException(
+ StrCannotDetectMediaType::get() + url,
+ static_cast<OWeakObject *>(this), static_cast<sal_Int16>(-1) );
+
+ String type, subType;
+ INetContentTypeParameterList params;
+ if (INetContentTypes::parse( mediaType_, type, subType, &params ))
+ {
+ if (type.EqualsIgnoreCaseAscii("application"))
+ {
+ ::ucbhelper::Content ucbContent( url, xCmdEnv );
+ if (subType.EqualsIgnoreCaseAscii(
+ "vnd.sun.star.help"))
+ {
+ return new PackageImpl( this, url,
+ ucbContent.getPropertyValue( StrTitle::get() ).get<OUString>(), m_xHelpTypeInfo );
+ }
+ }
+ }
+ throw lang::IllegalArgumentException(
+ StrUnsupportedMediaType::get() + mediaType_,
+ static_cast<OWeakObject *>(this),
+ static_cast<sal_Int16>(-1) );
+}
+
+
+//##############################################################################
+
+// Package
+BackendImpl * BackendImpl::PackageImpl::getMyBackend() const
+{
+ BackendImpl * pBackend = static_cast<BackendImpl *>(m_myBackend.get());
+ if (NULL == pBackend)
+ {
+ //May throw a DisposedException
+ check();
+ //We should never get here...
+ throw RuntimeException(
+ OUSTR("Failed to get the BackendImpl"),
+ static_cast<OWeakObject*>(const_cast<PackageImpl *>(this)));
+ }
+ return pBackend;
+}
+
+//______________________________________________________________________________
+beans::Optional< beans::Ambiguous<sal_Bool> >
+BackendImpl::PackageImpl::isRegistered_(
+ ::osl::ResettableMutexGuard &,
+ ::rtl::Reference<AbortChannel> const &,
+ Reference<XCommandEnvironment> const & )
+{
+ BackendImpl * that = getMyBackend();
+ Reference< deployment::XPackage > xThisPackage( this );
+ rtl::OUString aRegisteredFlagFile = that->getRegisteredFlagFileURL( xThisPackage );
+
+ Reference< ucb::XSimpleFileAccess > xSFA = that->getFileAccess();
+ bool bReg = xSFA->exists( aRegisteredFlagFile );
+
+ return beans::Optional< beans::Ambiguous<sal_Bool> >( true, beans::Ambiguous<sal_Bool>( bReg, false ) );
+}
+
+//______________________________________________________________________________
+void BackendImpl::PackageImpl::processPackage_(
+ ::osl::ResettableMutexGuard &,
+ bool doRegisterPackage,
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv )
+{
+ (void)doRegisterPackage;
+ (void)abortChannel;
+ (void)xCmdEnv;
+
+ BackendImpl* that = getMyBackend();
+ Reference< deployment::XPackage > xThisPackage( this );
+ that->implProcessHelp( xThisPackage, doRegisterPackage );
+}
+
+//##############################################################################
+
+static rtl::OUString aSlash( rtl::OUString::createFromAscii( "/" ) );
+static rtl::OUString aHelpStr( rtl::OUString::createFromAscii( "help" ) );
+
+void BackendImpl::implProcessHelp
+ ( Reference< deployment::XPackage > xPackage, bool doRegisterPackage )
+{
+ if( !xPackage.is() )
+ return;
+
+ Reference< ucb::XSimpleFileAccess > xSFA = getFileAccess();
+
+ rtl::OUString aRegisteredFlagFile = getRegisteredFlagFileURL( xPackage );
+ if( !doRegisterPackage )
+ {
+ if( xSFA->exists( aRegisteredFlagFile ) )
+ xSFA->kill( aRegisteredFlagFile );
+ return;
+ }
+
+ bool bCompile = true;
+ rtl::OUString aCompiledFlagFile = getCompiledFlagFileURL( xPackage );
+ if( xSFA->exists( aCompiledFlagFile ) )
+ bCompile = false;
+
+ if( bCompile )
+ {
+ rtl::OUString aHelpURL = xPackage->getURL();
+ rtl::OUString aExpandedHelpURL = expandURL( aHelpURL );
+ rtl::OUString aName = xPackage->getName();
+ if( !xSFA->isFolder( aExpandedHelpURL ) )
+ {
+ rtl::OUString aErrStr = getResourceString( RID_STR_HELPPROCESSING_GENERAL_ERROR );
+ aErrStr += rtl::OUString::createFromAscii( "No help folder" );
+ OWeakObject* oWeakThis = static_cast<OWeakObject *>(this);
+ throw deployment::DeploymentException( rtl::OUString(), oWeakThis,
+ makeAny( uno::Exception( aErrStr, oWeakThis ) ) );
+ }
+
+ Reference<XComponentContext> const & xContext = getComponentContext();
+ Reference< script::XInvocation > xInvocation;
+ if( xContext.is() )
+ {
+ try
+ {
+ xInvocation = Reference< script::XInvocation >(
+ xContext->getServiceManager()->createInstanceWithContext( rtl::OUString::createFromAscii(
+ "com.sun.star.help.HelpIndexer" ), xContext ) , UNO_QUERY );
+ }
+ catch (Exception &)
+ {
+ // i98680: Survive missing lucene
+ }
+ }
+
+ // Scan languages
+ Sequence< rtl::OUString > aLanguageFolderSeq = xSFA->getFolderContents( aExpandedHelpURL, true );
+ sal_Int32 nLangCount = aLanguageFolderSeq.getLength();
+ const rtl::OUString* pSeq = aLanguageFolderSeq.getConstArray();
+ for( sal_Int32 iLang = 0 ; iLang < nLangCount ; ++iLang )
+ {
+ rtl::OUString aLangURL = pSeq[iLang];
+ if( xSFA->isFolder( aLangURL ) )
+ {
+ std::vector< rtl::OUString > aXhpFileVector;
+
+ // Delete (old) files in any case to allow compiler to be started every time
+ rtl::OUString aLangWithPureNameURL( aLangURL );
+ aLangWithPureNameURL += aSlash;
+ aLangWithPureNameURL += aHelpStr;
+ rtl::OUString aDbFile( aLangWithPureNameURL );
+ aDbFile += rtl::OUString::createFromAscii( ".db" );
+ if( xSFA->exists( aDbFile ) )
+ xSFA->kill( aDbFile );
+ rtl::OUString aHtFile( aLangWithPureNameURL );
+ aHtFile += rtl::OUString::createFromAscii( ".ht" );
+ if( xSFA->exists( aHtFile ) )
+ xSFA->kill( aHtFile );
+ rtl::OUString aKeyFile( aLangWithPureNameURL );
+ aKeyFile += rtl::OUString::createFromAscii( ".key" );
+ if( xSFA->exists( aKeyFile ) )
+ xSFA->kill( aKeyFile );
+
+ // calculate jar file URL
+ rtl::OUString aJarFile( aLangURL );
+ aJarFile += aSlash;
+ aJarFile += aHelpStr;
+ aJarFile += rtl::OUString::createFromAscii( ".jar" );
+ // remove in any case to clean up
+ if( xSFA->exists( aJarFile ) )
+ xSFA->kill( aJarFile );
+
+ rtl::OUString aEncodedJarFilePath = rtl::Uri::encode( aJarFile,
+ rtl_UriCharClassPchar, rtl_UriEncodeIgnoreEscapes, RTL_TEXTENCODING_UTF8 );
+ rtl::OUString aDestBasePath = rtl::OUString::createFromAscii( "vnd.sun.star.pkg://" );
+ aDestBasePath += aEncodedJarFilePath;
+ aDestBasePath += rtl::OUString::createFromAscii( "/" );
+
+ sal_Int32 nLenLangFolderURL = aLangURL.getLength() + 1;
+
+ Sequence< rtl::OUString > aSubLangSeq = xSFA->getFolderContents( aLangURL, true );
+ sal_Int32 nSubLangCount = aSubLangSeq.getLength();
+ const rtl::OUString* pSubLangSeq = aSubLangSeq.getConstArray();
+ for( sal_Int32 iSubLang = 0 ; iSubLang < nSubLangCount ; ++iSubLang )
+ {
+ rtl::OUString aSubFolderURL = pSubLangSeq[iSubLang];
+ if( !xSFA->isFolder( aSubFolderURL ) )
+ continue;
+
+ implCollectXhpFiles( aSubFolderURL, aXhpFileVector );
+
+ // Copy to package (later: move?)
+ rtl::OUString aDestPath = aDestBasePath;
+ rtl::OUString aPureFolderName = aSubFolderURL.copy( nLenLangFolderURL );
+ aDestPath += aPureFolderName;
+ xSFA->copy( aSubFolderURL, aDestPath );
+ }
+
+ // Call compiler
+ sal_Int32 nXhpFileCount = aXhpFileVector.size();
+ rtl::OUString* pXhpFiles = new rtl::OUString[nXhpFileCount];
+ for( sal_Int32 iXhp = 0 ; iXhp < nXhpFileCount ; ++iXhp )
+ {
+ rtl::OUString aXhpFile = aXhpFileVector[iXhp];
+ rtl::OUString aXhpRelFile = aXhpFile.copy( nLenLangFolderURL );
+ pXhpFiles[iXhp] = aXhpRelFile;
+ }
+
+ HelpProcessingErrorInfo aErrorInfo;
+ bool bSuccess = compileExtensionHelp( aHelpStr, aLangURL,
+ nXhpFileCount, pXhpFiles, aErrorInfo );
+
+ if( bSuccess && xInvocation.is() )
+ {
+ Sequence<uno::Any> aParamsSeq( 6 );
+
+ aParamsSeq[0] = uno::makeAny( rtl::OUString::createFromAscii( "-lang" ) );
+
+ rtl::OUString aLang;
+ sal_Int32 nLastSlash = aLangURL.lastIndexOf( '/' );
+ if( nLastSlash != -1 )
+ aLang = aLangURL.copy( nLastSlash + 1 );
+ else
+ aLang = rtl::OUString::createFromAscii( "en" );
+ aParamsSeq[1] = uno::makeAny( aLang );
+
+ aParamsSeq[2] = uno::makeAny( rtl::OUString::createFromAscii( "-mod" ) );
+ aParamsSeq[3] = uno::makeAny( rtl::OUString::createFromAscii( "help" ) );
+
+ aParamsSeq[4] = uno::makeAny( rtl::OUString::createFromAscii( "-zipdir" ) );
+ rtl::OUString aSystemPath;
+ osl::FileBase::getSystemPathFromFileURL( aLangURL, aSystemPath );
+ aParamsSeq[5] = uno::makeAny( aSystemPath );
+
+ Sequence< sal_Int16 > aOutParamIndex;
+ Sequence< uno::Any > aOutParam;
+ uno::Any aRet = xInvocation->invoke( rtl::OUString::createFromAscii( "createIndex" ),
+ aParamsSeq, aOutParamIndex, aOutParam );
+ }
+
+ if( !bSuccess )
+ {
+ USHORT nErrStrId = 0;
+ switch( aErrorInfo.m_eErrorClass )
+ {
+ case HELPPROCESSING_GENERAL_ERROR:
+ case HELPPROCESSING_INTERNAL_ERROR: nErrStrId = RID_STR_HELPPROCESSING_GENERAL_ERROR; break;
+ case HELPPROCESSING_XMLPARSING_ERROR: nErrStrId = RID_STR_HELPPROCESSING_XMLPARSING_ERROR; break;
+ default: ;
+ };
+
+ rtl::OUString aErrStr;
+ if( nErrStrId != 0 )
+ {
+ aErrStr = getResourceString( nErrStrId );
+
+ // Remoce CR/LF
+ rtl::OUString aErrMsg( aErrorInfo.m_aErrorMsg );
+ sal_Unicode nCR = 13, nLF = 10;
+ sal_Int32 nSearchCR = aErrMsg.indexOf( nCR );
+ sal_Int32 nSearchLF = aErrMsg.indexOf( nLF );
+ sal_Int32 nCopy;
+ if( nSearchCR != -1 || nSearchLF != -1 )
+ {
+ if( nSearchCR == -1 )
+ nCopy = nSearchLF;
+ else if( nSearchLF == -1 )
+ nCopy = nSearchCR;
+ else
+ nCopy = ( nSearchCR < nSearchLF ) ? nSearchCR : nSearchLF;
+
+ aErrMsg = aErrMsg.copy( 0, nCopy );
+ }
+ aErrStr += aErrMsg;
+ if( nErrStrId == RID_STR_HELPPROCESSING_XMLPARSING_ERROR && aErrorInfo.m_aXMLParsingFile.getLength() )
+ {
+ aErrStr += rtl::OUString::createFromAscii( " in " );
+
+ rtl::OUString aDecodedFile = rtl::Uri::decode( aErrorInfo.m_aXMLParsingFile,
+ rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 );
+ aErrStr += aDecodedFile;
+ if( aErrorInfo.m_nXMLParsingLine != -1 )
+ {
+ aErrStr += rtl::OUString::createFromAscii( ", line " );
+ aErrStr += ::rtl::OUString::valueOf( aErrorInfo.m_nXMLParsingLine );
+ }
+ }
+ }
+
+ OWeakObject* oWeakThis = static_cast<OWeakObject *>(this);
+ throw deployment::DeploymentException( rtl::OUString(), oWeakThis,
+ makeAny( uno::Exception( aErrStr, oWeakThis ) ) );
+ }
+ }
+ }
+
+ // Write compiled flag file (this code is only reached in case of success)
+ Reference< io::XOutputStream > xOutputStream = xSFA->openFileWrite( aCompiledFlagFile );
+ if( xOutputStream.is() )
+ xOutputStream->closeOutput();
+
+ } // if( bCompile )
+
+ // Write registered flag file (this code is only reached in case of success)
+ if( !xSFA->exists( aRegisteredFlagFile ) )
+ {
+ Reference< io::XOutputStream > xOutputStream = xSFA->openFileWrite( aRegisteredFlagFile );
+ if( xOutputStream.is() )
+ xOutputStream->closeOutput();
+ }
+}
+
+rtl::OUString BackendImpl::getFlagFileURL( Reference< deployment::XPackage > xPackage, const char* pFlagStr )
+{
+ rtl::OUString aRetURL;
+ if( !xPackage.is() )
+ return aRetURL;
+ rtl::OUString aHelpURL = xPackage->getURL();
+ aRetURL = expandURL( aHelpURL );
+ aRetURL += rtl::OUString::createFromAscii( pFlagStr );
+ return aRetURL;
+}
+
+rtl::OUString BackendImpl::getRegisteredFlagFileURL( Reference< deployment::XPackage > xPackage )
+{
+ return getFlagFileURL( xPackage, "/RegisteredFlag" );
+}
+
+rtl::OUString BackendImpl::getCompiledFlagFileURL( Reference< deployment::XPackage > xPackage )
+{
+ return getFlagFileURL( xPackage, "/CompiledFlag" );
+}
+
+rtl::OUString BackendImpl::expandURL( const rtl::OUString& aURL )
+{
+ static Reference< util::XMacroExpander > xMacroExpander;
+ static Reference< uri::XUriReferenceFactory > xFac;
+
+ if( !xMacroExpander.is() || !xFac.is() )
+ {
+ Reference<XComponentContext> const & xContext = getComponentContext();
+ if( xContext.is() )
+ {
+ xFac = Reference< uri::XUriReferenceFactory >(
+ xContext->getServiceManager()->createInstanceWithContext( rtl::OUString::createFromAscii(
+ "com.sun.star.uri.UriReferenceFactory"), xContext ) , UNO_QUERY );
+ }
+ if( !xFac.is() )
+ {
+ throw RuntimeException(
+ ::rtl::OUString::createFromAscii(
+ "dp_registry::backend::help::BackendImpl::expandURL(), "
+ "could not instatiate UriReferenceFactory." ),
+ Reference< XInterface >() );
+ }
+
+ xMacroExpander = Reference< util::XMacroExpander >(
+ xContext->getValueByName(
+ ::rtl::OUString::createFromAscii( "/singletons/com.sun.star.util.theMacroExpander" ) ),
+ UNO_QUERY_THROW );
+ }
+
+ rtl::OUString aRetURL = aURL;
+ if( xMacroExpander.is() )
+ {
+ Reference< uri::XUriReference > uriRef;
+ for (;;)
+ {
+ uriRef = Reference< uri::XUriReference >( xFac->parse( aRetURL ), UNO_QUERY );
+ if ( uriRef.is() )
+ {
+ Reference < uri::XVndSunStarExpandUrl > sxUri( uriRef, UNO_QUERY );
+ if( !sxUri.is() )
+ break;
+
+ aRetURL = sxUri->expand( xMacroExpander );
+ }
+ }
+ }
+ return aRetURL;
+}
+
+void BackendImpl::implCollectXhpFiles( const rtl::OUString& aDir,
+ std::vector< rtl::OUString >& o_rXhpFileVector )
+{
+ Reference< ucb::XSimpleFileAccess > xSFA = getFileAccess();
+
+ // Scan xhp files recursively
+ Sequence< rtl::OUString > aSeq = xSFA->getFolderContents( aDir, true );
+ sal_Int32 nCount = aSeq.getLength();
+ const rtl::OUString* pSeq = aSeq.getConstArray();
+ for( sal_Int32 i = 0 ; i < nCount ; ++i )
+ {
+ rtl::OUString aURL = pSeq[i];
+ if( xSFA->isFolder( aURL ) )
+ {
+ implCollectXhpFiles( aURL, o_rXhpFileVector );
+ }
+ else
+ {
+ sal_Int32 nLastDot = aURL.lastIndexOf( '.' );
+ if( nLastDot != -1 )
+ {
+ rtl::OUString aExt = aURL.copy( nLastDot + 1 );
+ if( aExt.equalsIgnoreAsciiCase( rtl::OUString::createFromAscii( "xhp" ) ) )
+ o_rXhpFileVector.push_back( aURL );
+ }
+ }
+ }
+}
+
+Reference< ucb::XSimpleFileAccess > BackendImpl::getFileAccess( void )
+{
+ if( !m_xSFA.is() )
+ {
+ Reference<XComponentContext> const & xContext = getComponentContext();
+ if( xContext.is() )
+ {
+ m_xSFA = Reference< ucb::XSimpleFileAccess >(
+ xContext->getServiceManager()->createInstanceWithContext(
+ rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ),
+ xContext ), UNO_QUERY );
+ }
+ if( !m_xSFA.is() )
+ {
+ throw RuntimeException(
+ ::rtl::OUString::createFromAscii(
+ "dp_registry::backend::help::BackendImpl::getFileAccess(), "
+ "could not instatiate SimpleFileAccess." ),
+ Reference< XInterface >() );
+ }
+ }
+ return m_xSFA;
+}
+
+} // anon namespace
+
+namespace sdecl = comphelper::service_decl;
+sdecl::class_<BackendImpl, sdecl::with_args<true> > serviceBI;
+extern sdecl::ServiceDecl const serviceDecl(
+ serviceBI,
+ "com.sun.star.comp.deployment.help.PackageRegistryBackend",
+ BACKEND_SERVICE_NAME );
+
+} // namespace help
+} // namespace backend
+} // namespace dp_registry
+
diff --git a/desktop/source/deployment/registry/help/dp_help.hrc b/desktop/source/deployment/registry/help/dp_help.hrc
new file mode 100644
index 000000000000..3cdd12cb5bdb
--- /dev/null
+++ b/desktop/source/deployment/registry/help/dp_help.hrc
@@ -0,0 +1,42 @@
+/*************************************************************************
+ *
+ * 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: dp_help.hrc,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.
+ *
+ ************************************************************************/
+
+#if ! defined INCLUDED_DP_HELP_HRC
+#define INCLUDED_DP_HELP_HRC
+
+#include "deployment.hrc"
+
+#define RID_STR_HELP (RID_DEPLOYMENT_HELP_START+2)
+
+#define RID_STR_HELPPROCESSING_GENERAL_ERROR (RID_DEPLOYMENT_HELP_START+3)
+#define RID_STR_HELPPROCESSING_XMLPARSING_ERROR (RID_DEPLOYMENT_HELP_START+4)
+
+
+#endif
diff --git a/desktop/source/deployment/registry/help/dp_help.src b/desktop/source/deployment/registry/help/dp_help.src
new file mode 100644
index 000000000000..be85542dc3b0
--- /dev/null
+++ b/desktop/source/deployment/registry/help/dp_help.src
@@ -0,0 +1,47 @@
+/*************************************************************************
+ *
+ * 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: dp_help.src,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.
+ *
+ ************************************************************************/
+
+#include "dp_help.hrc"
+
+String RID_STR_HELP
+{
+ Text [ en-US ] = "Help";
+};
+
+String RID_STR_HELPPROCESSING_GENERAL_ERROR
+{
+ Text [ en-US ] = "The extension cannot be installed because:\n";
+};
+
+String RID_STR_HELPPROCESSING_XMLPARSING_ERROR
+{
+ Text [ en-US ] = "The extension will not be installed because an error occurred in the Help files:\n";
+};
+
diff --git a/desktop/source/deployment/registry/help/makefile.mk b/desktop/source/deployment/registry/help/makefile.mk
new file mode 100644
index 000000000000..9e11f82d3a02
--- /dev/null
+++ b/desktop/source/deployment/registry/help/makefile.mk
@@ -0,0 +1,55 @@
+#*************************************************************************
+#
+# 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 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ = ..$/..$/..$/..
+
+PRJNAME = desktop
+TARGET = deployment_registry_help
+ENABLE_EXCEPTIONS = TRUE
+
+INCPRE += ..$/..$/inc
+
+.INCLUDE : settings.mk
+
+.IF "$(SYSTEM_DB)" == "YES"
+CFLAGS+=-DSYSTEM_DB -I$(DB_INCLUDES)
+.ENDIF
+
+SRS1NAME = $(TARGET)
+SRC1FILES = \
+ dp_help.src
+
+SLOFILES = \
+ $(SLO)$/dp_help.obj
+
+.INCLUDE : ..$/..$/target.pmk
+.INCLUDE : target.mk
+
diff --git a/desktop/source/deployment/registry/inc/dp_backend.h b/desktop/source/deployment/registry/inc/dp_backend.h
new file mode 100644
index 000000000000..256d4680d795
--- /dev/null
+++ b/desktop/source/deployment/registry/inc/dp_backend.h
@@ -0,0 +1,319 @@
+/*************************************************************************
+ *
+ * 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: dp_backend.h,v $
+ * $Revision: 1.18 $
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#if ! defined INCLUDED_DP_REGISTRY_H
+#define INCLUDED_DP_REGISTRY_H
+
+#include "dp_misc.h"
+#include "dp_resource.h"
+#include "dp_interact.h"
+#include "rtl/ref.hxx"
+#include "cppuhelper/weakref.hxx"
+#include "cppuhelper/implbase1.hxx"
+#include "cppuhelper/compbase1.hxx"
+#include "cppuhelper/compbase2.hxx"
+#include "tools/inetmime.hxx"
+#include "com/sun/star/lang/XEventListener.hpp"
+#include "com/sun/star/deployment/XPackageRegistry.hpp"
+#include "com/sun/star/deployment/XPackageManager.hpp"
+#include <memory>
+#include <hash_map>
+#include "dp_registry.hrc"
+
+namespace dp_registry
+{
+namespace backend
+{
+
+namespace css = ::com::sun::star;
+
+class PackageRegistryBackend;
+
+char const* const BACKEND_SERVICE_NAME =
+"com.sun.star.deployment.PackageRegistryBackend";
+
+typedef ::cppu::WeakComponentImplHelper1<
+ css::deployment::XPackage > t_PackageBase;
+
+//==============================================================================
+class Package : protected ::dp_misc::MutexHolder, public t_PackageBase
+{
+ void processPackage_impl(
+ bool registerPackage,
+ css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv );
+
+protected:
+ ::rtl::Reference<PackageRegistryBackend> m_myBackend;
+ const ::rtl::OUString m_url;
+ ::rtl::OUString m_name;
+ ::rtl::OUString m_displayName;
+ const css::uno::Reference<css::deployment::XPackageTypeInfo> m_xPackageType;
+
+ void check() const;
+ void fireModified();
+ virtual void SAL_CALL disposing();
+
+ void checkAborted(
+ ::rtl::Reference< ::dp_misc::AbortChannel > const & abortChannel );
+
+ // @@@ to be implemented by specific backend:
+ virtual css::beans::Optional< css::beans::Ambiguous<sal_Bool> >
+ isRegistered_(
+ ::osl::ResettableMutexGuard & guard,
+ ::rtl::Reference< ::dp_misc::AbortChannel > const & abortChannel,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv )
+ = 0;
+ virtual void processPackage_(
+ ::osl::ResettableMutexGuard & guard,
+ bool registerPackage,
+ ::rtl::Reference< ::dp_misc::AbortChannel > const & abortChannel,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv )
+ = 0;
+
+ virtual ~Package();
+ Package( ::rtl::Reference<PackageRegistryBackend> const & myBackend,
+ ::rtl::OUString const & url,
+ ::rtl::OUString const & name,
+ ::rtl::OUString const & displayName,
+ css::uno::Reference<css::deployment::XPackageTypeInfo> const &
+ xPackageType );
+
+public:
+
+ class TypeInfo :
+ public ::cppu::WeakImplHelper1<css::deployment::XPackageTypeInfo>
+ {
+ const ::rtl::OUString m_mediaType;
+ const ::rtl::OUString m_fileFilter;
+ const ::rtl::OUString m_shortDescr;
+ const sal_uInt16 m_smallIcon, m_smallIcon_HC;
+ public:
+ virtual ~TypeInfo();
+ TypeInfo( ::rtl::OUString const & mediaType,
+ ::rtl::OUString const & fileFilter,
+ ::rtl::OUString const & shortDescr,
+ sal_uInt16 smallIcon, sal_uInt16 smallIcon_HC )
+ : m_mediaType(mediaType), m_fileFilter(fileFilter),
+ m_shortDescr(shortDescr),
+ m_smallIcon(smallIcon), m_smallIcon_HC(smallIcon_HC)
+ {}
+ // XPackageTypeInfo
+ virtual ::rtl::OUString SAL_CALL getMediaType()
+ throw (css::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getDescription()
+ throw (css::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getShortDescription()
+ throw (css::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getFileFilter()
+ throw (css::uno::RuntimeException);
+ virtual css::uno::Any SAL_CALL getIcon( sal_Bool highContrast,
+ sal_Bool smallIcon )
+ throw (css::uno::RuntimeException);
+ };
+
+ // XComponent
+ virtual void SAL_CALL dispose() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL addEventListener(
+ css::uno::Reference<css::lang::XEventListener> const & xListener )
+ throw (css::uno::RuntimeException);
+ virtual void SAL_CALL removeEventListener(
+ css::uno::Reference<css::lang::XEventListener> const & xListener )
+ throw (css::uno::RuntimeException);
+
+ // XModifyBroadcaster
+ virtual void SAL_CALL addModifyListener(
+ css::uno::Reference<css::util::XModifyListener> const & xListener )
+ throw (css::uno::RuntimeException);
+ virtual void SAL_CALL removeModifyListener(
+ css::uno::Reference<css::util::XModifyListener> const & xListener )
+ throw (css::uno::RuntimeException);
+
+ // XPackage
+ virtual css::uno::Reference<css::task::XAbortChannel> SAL_CALL
+ createAbortChannel() throw (css::uno::RuntimeException);
+ virtual css::beans::Optional< css::beans::Ambiguous<sal_Bool> >
+ SAL_CALL isRegistered(
+ css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (css::deployment::DeploymentException,
+ css::ucb::CommandFailedException,
+ css::ucb::CommandAbortedException,
+ css::uno::RuntimeException);
+
+ virtual ::sal_Bool SAL_CALL checkPrerequisites(
+ const css::uno::Reference< css::task::XAbortChannel >& xAbortChannel,
+ const css::uno::Reference< css::ucb::XCommandEnvironment >& xCmdEnv,
+ sal_Bool bInstalled, ::rtl::OUString const & aContextName)
+ throw (css::deployment::DeploymentException,
+ css::ucb::CommandFailedException,
+ css::ucb::CommandAbortedException,
+ css::uno::RuntimeException);
+
+ virtual ::sal_Bool SAL_CALL checkDependencies(
+ const css::uno::Reference< css::ucb::XCommandEnvironment >& xCmdEnv )
+ throw (css::deployment::DeploymentException,
+ css::ucb::CommandFailedException,
+ css::uno::RuntimeException);
+
+ virtual void SAL_CALL registerPackage(
+ css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (css::deployment::DeploymentException,
+ css::ucb::CommandFailedException,
+ css::ucb::CommandAbortedException,
+ css::lang::IllegalArgumentException, css::uno::RuntimeException);
+ virtual void SAL_CALL revokePackage(
+ css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (css::deployment::DeploymentException,
+ css::ucb::CommandFailedException,
+ css::ucb::CommandAbortedException,
+ css::lang::IllegalArgumentException,
+ css::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL isBundle()
+ throw (css::uno::RuntimeException);
+ virtual css::uno::Sequence< css::uno::Reference<css::deployment::XPackage> >
+ SAL_CALL getBundle(
+ css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (css::deployment::DeploymentException,
+ css::ucb::CommandFailedException,
+ css::ucb::CommandAbortedException,
+ css::lang::IllegalArgumentException,
+ css::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getName()
+ throw (css::uno::RuntimeException);
+ virtual css::beans::Optional< ::rtl::OUString > SAL_CALL getIdentifier()
+ throw (css::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getVersion()
+ throw (css::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getURL()
+ throw (css::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getDisplayName()
+ throw (css::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getDescription()
+ throw (css::uno::RuntimeException);
+ virtual css::uno::Sequence< ::rtl::OUString > SAL_CALL
+ getUpdateInformationURLs() throw (css::uno::RuntimeException);
+
+ virtual css::beans::StringPair SAL_CALL getPublisherInfo() throw (css::uno::RuntimeException);
+ virtual css::uno::Reference< css::graphic::XGraphic > SAL_CALL getIcon( sal_Bool bHighContrast ) throw (css::uno::RuntimeException);
+
+ virtual css::uno::Reference<css::deployment::XPackageTypeInfo> SAL_CALL
+ getPackageType() throw (css::uno::RuntimeException);
+ virtual void SAL_CALL exportTo(
+ ::rtl::OUString const & destFolderURL,
+ ::rtl::OUString const & newTitle,
+ sal_Int32 nameClashAction,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (css::ucb::CommandFailedException,
+ css::ucb::CommandAbortedException, css::uno::RuntimeException);
+};
+
+typedef ::cppu::WeakComponentImplHelper2<
+ css::lang::XEventListener,
+ css::deployment::XPackageRegistry > t_BackendBase;
+
+//==============================================================================
+class PackageRegistryBackend
+ : protected ::dp_misc::MutexHolder, public t_BackendBase
+{
+ ::rtl::OUString m_cachePath;
+
+ typedef ::std::hash_map<
+ ::rtl::OUString, css::uno::WeakReference<css::deployment::XPackage>,
+ ::rtl::OUStringHash > t_string2weakref;
+ t_string2weakref m_bound;
+
+protected:
+ css::uno::Reference<css::uno::XComponentContext> m_xComponentContext;
+
+ ::rtl::OUString m_context;
+ // currently only for library containers:
+ enum context {
+ CONTEXT_UNKNOWN,
+ CONTEXT_USER, CONTEXT_SHARED,
+ CONTEXT_DOCUMENT
+ } m_eContext;
+ bool m_readOnly;
+
+ struct StrCannotDetectMediaType : public ::dp_misc::StaticResourceString<
+ StrCannotDetectMediaType, RID_STR_CANNOT_DETECT_MEDIA_TYPE> {};
+ struct StrUnsupportedMediaType : public ::dp_misc::StaticResourceString<
+ StrUnsupportedMediaType, RID_STR_UNSUPPORTED_MEDIA_TYPE> {};
+
+ // @@@ to be implemented by specific backend:
+ virtual css::uno::Reference<css::deployment::XPackage> bindPackage_(
+ ::rtl::OUString const & url, ::rtl::OUString const & mediaType,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv )
+ = 0;
+
+ void check();
+ virtual void SAL_CALL disposing();
+
+ virtual ~PackageRegistryBackend();
+ PackageRegistryBackend(
+ css::uno::Sequence<css::uno::Any> const & args,
+ css::uno::Reference<css::uno::XComponentContext> const & xContext );
+
+public:
+ struct StrRegisteringPackage : public ::dp_misc::StaticResourceString<
+ StrRegisteringPackage, RID_STR_REGISTERING_PACKAGE> {};
+ struct StrRevokingPackage : public ::dp_misc::StaticResourceString<
+ StrRevokingPackage, RID_STR_REVOKING_PACKAGE> {};
+
+ inline css::uno::Reference<css::uno::XComponentContext> const &
+ getComponentContext() const { return m_xComponentContext; }
+
+ inline ::rtl::OUString const & getCachePath() const { return m_cachePath; }
+ inline bool transientMode() const { return m_cachePath.getLength() == 0; }
+
+ // XEventListener
+ virtual void SAL_CALL disposing( css::lang::EventObject const & evt )
+ throw (css::uno::RuntimeException);
+
+ // XPackageRegistry
+ virtual css::uno::Reference<css::deployment::XPackage> SAL_CALL bindPackage(
+ ::rtl::OUString const & url, ::rtl::OUString const & mediaType,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv )
+ throw (css::deployment::DeploymentException,
+ css::ucb::CommandFailedException,
+ css::lang::IllegalArgumentException, css::uno::RuntimeException);
+// virtual css::uno::Sequence<
+// css::uno::Reference<css::deployment::XPackageTypeInfo> > SAL_CALL
+// getSupportedPackageTypes() throw (css::uno::RuntimeException);
+};
+
+}
+}
+
+#endif
+
diff --git a/desktop/source/deployment/registry/inc/dp_registry.hrc b/desktop/source/deployment/registry/inc/dp_registry.hrc
new file mode 100644
index 000000000000..12dd5c5ba8c3
--- /dev/null
+++ b/desktop/source/deployment/registry/inc/dp_registry.hrc
@@ -0,0 +1,43 @@
+/*************************************************************************
+ *
+ * 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: dp_registry.hrc,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.
+ *
+ ************************************************************************/
+
+#if ! defined INCLUDED_DP_REGISTRY_HRC
+#define INCLUDED_DP_REGISTRY_HRC
+
+#include "deployment.hrc"
+
+#define RID_STR_CANNOT_DETECT_MEDIA_TYPE (RID_DEPLOYMENT_REGISTRY_START+0)
+#define RID_STR_UNSUPPORTED_MEDIA_TYPE (RID_DEPLOYMENT_REGISTRY_START+1)
+#define RID_STR_ERROR_WHILE_REGISTERING (RID_DEPLOYMENT_REGISTRY_START+2)
+#define RID_STR_ERROR_WHILE_REVOKING (RID_DEPLOYMENT_REGISTRY_START+3)
+#define RID_STR_REGISTERING_PACKAGE (RID_DEPLOYMENT_REGISTRY_START+4)
+#define RID_STR_REVOKING_PACKAGE (RID_DEPLOYMENT_REGISTRY_START+5)
+
+#endif
diff --git a/desktop/source/deployment/registry/makefile.mk b/desktop/source/deployment/registry/makefile.mk
new file mode 100644
index 000000000000..7741583d930a
--- /dev/null
+++ b/desktop/source/deployment/registry/makefile.mk
@@ -0,0 +1,52 @@
+#*************************************************************************
+#
+# 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.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.
+#
+#*************************************************************************
+
+PRJ = ..$/..$/..
+
+PRJNAME = desktop
+TARGET = deployment_registry
+ENABLE_EXCEPTIONS = TRUE
+
+.INCLUDE : settings.mk
+
+SRS1NAME = $(TARGET)
+SRC1FILES = \
+ dp_registry.src
+
+INCPRE += inc
+
+SLOFILES = \
+ $(SLO)$/dp_backend.obj \
+ $(SLO)$/dp_registry.obj
+
+.INCLUDE : ..$/target.pmk
+.INCLUDE : target.mk
+
diff --git a/desktop/source/deployment/registry/package/dp_description.cxx b/desktop/source/deployment/registry/package/dp_description.cxx
new file mode 100644
index 000000000000..846205a5faf0
--- /dev/null
+++ b/desktop/source/deployment/registry/package/dp_description.cxx
@@ -0,0 +1,208 @@
+/*************************************************************************
+ *
+ * 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: dp_description.cxx,v $
+ * $Revision: 1.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_desktop.hxx"
+
+#include "dp_description.hxx"
+
+#include "cppuhelper/exc_hlp.hxx"
+#include "ucbhelper/content.hxx"
+#include "com/sun/star/deployment/DeploymentException.hpp"
+#include "com/sun/star/xml/dom/XDocumentBuilder.hpp"
+#include "com/sun/star/uno/XComponentContext.hpp"
+#include "com/sun/star/ucb/CommandFailedException.hpp"
+#include "com/sun/star/ucb/InteractiveAugmentedIOException.hpp"
+#include "com/sun/star/ucb/IOErrorCode.hpp"
+
+#include "com/sun/star/beans/PropertyValue.hpp"
+
+
+#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
+
+namespace css = com::sun::star;
+namespace cssu = com::sun::star::uno;
+
+namespace dp_registry {
+namespace backend {
+namespace bundle {
+
+ExtensionDescription::ExtensionDescription(
+ const cssu::Reference<cssu::XComponentContext>& xContext,
+ const ::rtl::OUString& installDir,
+ const cssu::Reference< css::ucb::XCommandEnvironment >& xCmdEnv)
+{
+ try {
+ m_sExtensionRootUrl = installDir;
+ //may throw ::com::sun::star::ucb::ContentCreationException
+ //If there is no description.xml then ucb will start an interaction which
+ //brings up a dialog.We want to prevent this. Therefore we wrap the xCmdEnv
+ //and filter the respective exception out.
+ ::rtl::OUString sDescriptionUri(installDir + OUSTR("/description.xml"));
+ cssu::Reference<css::ucb::XCommandEnvironment> xFilter =
+ static_cast<css::ucb::XCommandEnvironment*>(
+ new FileDoesNotExistFilter(xCmdEnv));
+ ::ucbhelper::Content descContent(sDescriptionUri, xFilter);
+
+ //throws an com::sun::star::uno::Exception if the file is not available
+ cssu::Reference<css::io::XInputStream> xIn;
+ try
+ { //throws com.sun.star.ucb.InteractiveAugmentedIOException
+ xIn = descContent.openStream();
+ }
+ catch (cssu::Exception& )
+ {
+ if ( ! static_cast<FileDoesNotExistFilter*>(xFilter.get())->exist())
+ throw NoDescriptionException();
+ throw;
+ }
+ if (!xIn.is())
+ {
+ throw cssu::Exception(
+ OUSTR("Could not get XInputStream for description.xml of extension ") +
+ sDescriptionUri, 0);
+ }
+
+ //get root node of description.xml
+ cssu::Reference<css::xml::dom::XDocumentBuilder> xDocBuilder(
+ xContext->getServiceManager()->createInstanceWithContext(
+ OUSTR("com.sun.star.xml.dom.DocumentBuilder"),
+ xContext ), cssu::UNO_QUERY);
+ if (!xDocBuilder.is())
+ throw css::uno::Exception(OUSTR(" Could not create service com.sun.star.xml.dom.DocumentBuilder"), 0);
+
+ if (xDocBuilder->isNamespaceAware() == sal_False)
+ {
+ throw cssu::Exception(
+ OUSTR("Service com.sun.star.xml.dom.DocumentBuilder is not namespace aware."), 0);
+ }
+
+ cssu::Reference<css::xml::dom::XDocument> xDoc = xDocBuilder->parse(xIn);
+ if (!xDoc.is())
+ {
+ throw cssu::Exception(sDescriptionUri + OUSTR(" contains data which cannot be parsed. "), 0);
+ }
+
+ //check for proper root element and namespace
+ cssu::Reference<css::xml::dom::XElement> xRoot = xDoc->getDocumentElement();
+ if (!xRoot.is())
+ {
+ throw cssu::Exception(
+ sDescriptionUri + OUSTR(" contains no root element."), 0);
+ }
+
+ if ( ! xRoot->getTagName().equals(OUSTR("description")))
+ {
+ throw cssu::Exception(
+ sDescriptionUri + OUSTR(" does not contain the root element <description>."), 0);
+ }
+
+ m_xRoot = cssu::Reference<css::xml::dom::XNode>(
+ xRoot, cssu::UNO_QUERY_THROW);
+ ::rtl::OUString nsDescription = xRoot->getNamespaceURI();
+
+ //check if this namespace is supported
+ if ( ! nsDescription.equals(OUSTR("http://openoffice.org/extensions/description/2006")))
+ {
+ throw cssu::Exception(sDescriptionUri + OUSTR(" contains a root element with an unsupported namespace. "), 0);
+ }
+ } catch (css::uno::RuntimeException &) {
+ throw;
+ } catch (css::deployment::DeploymentException &) {
+ throw;
+ } catch (css::uno::Exception & e) {
+ css::uno::Any a(cppu::getCaughtException());
+ throw css::deployment::DeploymentException(
+ e.Message, css::uno::Reference< css::uno::XInterface >(), a);
+ }
+}
+
+ExtensionDescription::~ExtensionDescription()
+{
+}
+
+//======================================================================
+FileDoesNotExistFilter::FileDoesNotExistFilter(
+ const css::uno::Reference< css::ucb::XCommandEnvironment >& xCmdEnv):
+ m_bExist(true), m_xCommandEnv(xCmdEnv)
+{}
+
+FileDoesNotExistFilter::~FileDoesNotExistFilter()
+{
+};
+
+bool FileDoesNotExistFilter::exist()
+{
+ return m_bExist;
+}
+ // XCommandEnvironment
+cssu::Reference<css::task::XInteractionHandler >
+ FileDoesNotExistFilter::getInteractionHandler() throw (css::uno::RuntimeException)
+{
+ return static_cast<css::task::XInteractionHandler*>(this);
+}
+
+cssu::Reference<css::ucb::XProgressHandler >
+ FileDoesNotExistFilter::getProgressHandler() throw (css::uno::RuntimeException)
+{
+ return m_xCommandEnv.is()
+ ? m_xCommandEnv->getProgressHandler()
+ : cssu::Reference<css::ucb::XProgressHandler>();
+}
+
+// XInteractionHandler
+//If the interaction was caused by a non-existing file which is specified in the ctor
+//of FileDoesNotExistFilter, then we do nothing
+void FileDoesNotExistFilter::handle(
+ cssu::Reference<css::task::XInteractionRequest > const & xRequest )
+ throw (css::uno::RuntimeException)
+{
+ cssu::Any request( xRequest->getRequest() );
+
+ css::ucb::InteractiveAugmentedIOException ioexc;
+ if ((request>>= ioexc) && ioexc.Code == css::ucb::IOErrorCode_NOT_EXISTING )
+ {
+ m_bExist = false;
+ return;
+ }
+ css::uno::Reference<css::task::XInteractionHandler> xInteraction;
+ if (m_xCommandEnv.is()) {
+ xInteraction = m_xCommandEnv->getInteractionHandler();
+ }
+ if (xInteraction.is()) {
+ xInteraction->handle(xRequest);
+ }
+}
+
+
+} // namespace bundle
+} // namespace backend
+} // namespace dp_registry
+
diff --git a/desktop/source/deployment/registry/package/dp_description.hxx b/desktop/source/deployment/registry/package/dp_description.hxx
new file mode 100644
index 000000000000..154cd3c8d562
--- /dev/null
+++ b/desktop/source/deployment/registry/package/dp_description.hxx
@@ -0,0 +1,128 @@
+/*************************************************************************
+ *
+ * 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: dp_description.hxx,v $
+ * $Revision: 1.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.
+ *
+ ************************************************************************/
+
+#if !defined INCLUDED_DESKTOP_EXTENSION_DESCRIPTION_HXX
+#define INCLUDED_DESKTOP_EXTENSION_DESCRIPTION_HXX
+
+
+
+#include "com/sun/star/uno/Reference.hxx"
+
+#include "com/sun/star/ucb/XCommandEnvironment.hpp"
+#include "com/sun/star/uno/XComponentContext.hpp"
+#include "com/sun/star/xml/dom/XNode.hpp"
+#include "com/sun/star/task/XInteractionHandler.hpp"
+#include "cppuhelper/implbase2.hxx"
+
+
+namespace css = ::com::sun::star;
+
+namespace dp_registry {
+namespace backend {
+namespace bundle {
+
+/**The class uses the UCB to access the description.xml file in an
+ extension. The UCB must have been initialized already. It also
+ requires that the extension has already be unzipped to a particular
+ location.
+ */
+class ExtensionDescription
+{
+public:
+ /**throws an exception if the description.xml is not
+ available, cannot be read, does not contain the expected data,
+ or any other error occured. Therefore it shoult only be used with
+ new extensions.
+
+ Throws com::sun::star::uno::RuntimeException,
+ com::sun::star::deployment::DeploymentException,
+ dp_registry::backend::bundle::NoDescriptionException.
+ */
+ ExtensionDescription(
+ const css::uno::Reference<css::uno::XComponentContext>& xContext,
+ const ::rtl::OUString& installDir,
+ const css::uno::Reference< css::ucb::XCommandEnvironment >& xCmdEnv);
+
+ ~ExtensionDescription();
+
+ css::uno::Reference<css::xml::dom::XNode> getRootElement() const
+ {
+ return m_xRoot;
+ }
+
+ ::rtl::OUString getExtensionRootUrl() const
+ {
+ return m_sExtensionRootUrl;
+ }
+
+
+private:
+ css::uno::Reference<css::xml::dom::XNode> m_xRoot;
+ ::rtl::OUString m_sExtensionRootUrl;
+};
+
+class NoDescriptionException
+{
+};
+
+class FileDoesNotExistFilter
+ : public ::cppu::WeakImplHelper2< css::ucb::XCommandEnvironment,
+ css::task::XInteractionHandler >
+
+{
+ //css::uno::Reference<css::task::XInteractionHandler> m_xHandler;
+ bool m_bExist;
+ css::uno::Reference< css::ucb::XCommandEnvironment > m_xCommandEnv;
+
+public:
+ virtual ~FileDoesNotExistFilter();
+ FileDoesNotExistFilter(
+ const css::uno::Reference< css::ucb::XCommandEnvironment >& xCmdEnv);
+
+ bool exist();
+ // XCommandEnvironment
+ virtual css::uno::Reference<css::task::XInteractionHandler > SAL_CALL
+ getInteractionHandler() throw (css::uno::RuntimeException);
+ virtual css::uno::Reference<css::ucb::XProgressHandler >
+ SAL_CALL getProgressHandler() throw (css::uno::RuntimeException);
+
+ // XInteractionHandler
+ virtual void SAL_CALL handle(
+ css::uno::Reference<css::task::XInteractionRequest > const & xRequest )
+ throw (css::uno::RuntimeException);
+};
+
+
+} // namespace bundle
+} // namespace backend
+} // namespace dp_registry
+
+
+#endif // INCLUDED_DESKTOP_LICENSE_INTERACT_HXX
diff --git a/desktop/source/deployment/registry/package/dp_package.cxx b/desktop/source/deployment/registry/package/dp_package.cxx
new file mode 100644
index 000000000000..14075d0fca38
--- /dev/null
+++ b/desktop/source/deployment/registry/package/dp_package.cxx
@@ -0,0 +1,1547 @@
+/*************************************************************************
+ *
+ * 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: dp_package.cxx,v $
+ * $Revision: 1.34.16.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_desktop.hxx"
+
+#include "dp_package.hrc"
+#include "dp_backend.h"
+#include "dp_ucb.h"
+#include "dp_interact.h"
+#include "dp_dependencies.hxx"
+#include "dp_platform.hxx"
+#include "dp_description.hxx"
+#include "dp_descriptioninfoset.hxx"
+#include "dp_identifier.hxx"
+#include "rtl/uri.hxx"
+#include "cppuhelper/exc_hlp.hxx"
+#include "cppuhelper/implbase1.hxx"
+#include "ucbhelper/content.hxx"
+#include "svtools/inettype.hxx"
+#include "comphelper/anytostring.hxx"
+#include "comphelper/makesequence.hxx"
+#include "comphelper/sequence.hxx"
+#include "com/sun/star/lang/WrappedTargetException.hpp"
+#include "com/sun/star/lang/XServiceInfo.hpp"
+#include "com/sun/star/beans/UnknownPropertyException.hpp"
+#include "com/sun/star/graphic/XGraphic.hpp"
+#include "com/sun/star/graphic/XGraphicProvider.hpp"
+#include "com/sun/star/io/XOutputStream.hpp"
+#include "com/sun/star/io/XInputStream.hpp"
+#include "com/sun/star/task/InteractionClassification.hpp"
+#include "com/sun/star/task/XInteractionApprove.hpp"
+#include "com/sun/star/ucb/XInteractionReplaceExistingData.hpp"
+#include "com/sun/star/ucb/NameClashResolveRequest.hpp"
+#include "com/sun/star/ucb/XContentAccess.hpp"
+#include "com/sun/star/ucb/NameClash.hpp"
+#include "com/sun/star/ucb/UnsupportedCommandException.hpp"
+#include "com/sun/star/sdbc/XResultSet.hpp"
+#include "com/sun/star/sdbc/XRow.hpp"
+#include "com/sun/star/packages/manifest/XManifestReader.hpp"
+#include "com/sun/star/packages/manifest/XManifestWriter.hpp"
+#include "com/sun/star/deployment/DependencyException.hpp"
+#include "com/sun/star/deployment/LicenseException.hpp"
+#include "com/sun/star/deployment/LicenseIndividualAgreementException.hpp"
+#include "com/sun/star/deployment/PlatformException.hpp"
+#include "com/sun/star/xml/dom/XDocumentBuilder.hpp"
+#include "com/sun/star/xml/xpath/XXPathAPI.hpp"
+#include "com/sun/star/deployment/XPackageManager.hpp"
+
+#include <vector>
+#include <stdio.h>
+
+
+using namespace ::dp_misc;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::ucb;
+namespace css = ::com::sun::star;
+namespace cssu = ::com::sun::star::uno;
+using ::rtl::OUString;
+
+namespace dp_registry {
+namespace backend {
+namespace bundle {
+namespace {
+
+typedef cppu::ImplInheritanceHelper1<PackageRegistryBackend,
+ lang::XServiceInfo> ImplBaseT;
+
+//==============================================================================
+class BackendImpl : public ImplBaseT
+{
+ class PackageImpl : public ::dp_registry::backend::Package
+ {
+ BackendImpl * getMyBackend() const;
+ /** constains the old tooltip description for the Extension Manager GUI in OOo v.2.x
+ We keep it for backward compatibility.
+ */
+ OUString m_oldDescription;
+ OUString m_url_expanded;
+ const bool m_legacyBundle;
+ Sequence< Reference<deployment::XPackage> > m_bundle;
+ Sequence< Reference<deployment::XPackage> > * m_pBundle;
+
+ Reference<deployment::XPackage> bindBundleItem(
+ OUString const & url, OUString const & mediaType,
+ Reference<XCommandEnvironment> const & xCmdEnv,
+ bool notifyDetectionError = true );
+
+ typedef ::std::vector< Reference<deployment::XPackage> > t_packagevec;
+ void scanBundle(
+ t_packagevec & bundle,
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+ void scanLegacyBundle(
+ t_packagevec & bundle,
+ OUString const & url,
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv,
+ bool skip_registration = false );
+
+ bool checkPlatform(
+ css::uno::Reference< css::ucb::XCommandEnvironment > const & environment);
+
+ bool checkDependencies(
+ css::uno::Reference< css::ucb::XCommandEnvironment > const &
+ environment,
+ ExtensionDescription const & description);
+ // throws css::uno::RuntimeException,
+ // css::deployment::DeploymentException
+
+ ::sal_Bool checkLicense(
+ css::uno::Reference< css::ucb::XCommandEnvironment > const & xCmdEnv,
+ ExtensionDescription const& description, bool bInstalled,
+ OUString const & aContextName )
+ throw (css::deployment::DeploymentException,
+ css::ucb::CommandFailedException,
+ css::ucb::CommandAbortedException,
+ css::uno::RuntimeException);
+ // @throws DeploymentException
+ OUString getTextFromURL(
+ const css::uno::Reference< css::ucb::XCommandEnvironment >& xCmdEnv,
+ const OUString& licenseUrl);
+
+ DescriptionInfoset getDescriptionInfoset();
+
+ // Package
+ virtual beans::Optional< beans::Ambiguous<sal_Bool> > isRegistered_(
+ ::osl::ResettableMutexGuard & guard,
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+ virtual void processPackage_(
+ ::osl::ResettableMutexGuard & guard,
+ bool registerPackage,
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+
+ virtual void SAL_CALL disposing();
+
+
+
+ public:
+ PackageImpl(
+ ::rtl::Reference<PackageRegistryBackend> const & myBackend,
+ OUString const & url,
+ OUString const & name,
+ Reference<deployment::XPackageTypeInfo> const & xPackageType,
+ bool legacyBundle )
+ : Package( myBackend, url, name, name /* display-name */,
+ xPackageType ),
+ m_url_expanded( expandUnoRcUrl( url ) ),
+ m_legacyBundle( legacyBundle ),
+ m_pBundle( 0 )
+ {}
+
+ // XPackage
+ virtual sal_Bool SAL_CALL isBundle() throw (RuntimeException);
+ virtual Sequence< Reference<deployment::XPackage> > SAL_CALL getBundle(
+ Reference<task::XAbortChannel> const & xAbortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv )
+ throw (deployment::DeploymentException,
+ CommandFailedException, CommandAbortedException,
+ lang::IllegalArgumentException, RuntimeException);
+ virtual OUString SAL_CALL getDescription() throw (RuntimeException);
+ virtual void SAL_CALL exportTo(
+ OUString const & destFolderURL, OUString const & newTitle,
+ sal_Int32 nameClashAction,
+ Reference<XCommandEnvironment> const & xCmdEnv )
+ throw (CommandFailedException, CommandAbortedException,
+ RuntimeException);
+
+ virtual ::sal_Bool SAL_CALL checkPrerequisites(
+ const css::uno::Reference< css::task::XAbortChannel >& xAbortChannel,
+ const css::uno::Reference< css::ucb::XCommandEnvironment >& xCmdEnv,
+ ::sal_Bool bInstalled, OUString const & aContextName)
+ throw (css::deployment::DeploymentException,
+ css::ucb::CommandFailedException,
+ css::ucb::CommandAbortedException,
+ css::uno::RuntimeException);
+
+ virtual ::sal_Bool SAL_CALL checkDependencies(
+ const css::uno::Reference< css::ucb::XCommandEnvironment >& xCmdEnv )
+ throw (css::deployment::DeploymentException,
+ css::ucb::CommandFailedException,
+ css::uno::RuntimeException);
+
+ virtual beans::Optional<OUString> SAL_CALL getIdentifier()
+ throw (RuntimeException);
+
+ virtual OUString SAL_CALL getVersion() throw (RuntimeException);
+
+ virtual Sequence<OUString> SAL_CALL getUpdateInformationURLs()
+ throw (RuntimeException);
+
+ virtual css::beans::StringPair SAL_CALL getPublisherInfo() throw (css::uno::RuntimeException);
+
+ virtual OUString SAL_CALL getDisplayName() throw (RuntimeException);
+ virtual css::uno::Reference< css::graphic::XGraphic > SAL_CALL getIcon( ::sal_Bool bHighContrast ) throw (css::uno::RuntimeException);
+ };
+ friend class PackageImpl;
+
+ Reference<deployment::XPackageRegistry> m_xRootRegistry;
+ const Reference<deployment::XPackageTypeInfo> m_xBundleTypeInfo;
+ const Reference<deployment::XPackageTypeInfo> m_xLegacyBundleTypeInfo;
+ Sequence< Reference<deployment::XPackageTypeInfo> > m_typeInfos;
+
+ // PackageRegistryBackend
+ virtual Reference<deployment::XPackage> bindPackage_(
+ OUString const & url, OUString const & mediaType,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+
+ virtual void SAL_CALL disposing();
+
+public:
+ BackendImpl(
+ Sequence<Any> const & args,
+ Reference<XComponentContext> const & xComponentContext,
+ Reference<deployment::XPackageRegistry> const & xRootRegistry );
+
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName() throw (RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( OUString const& name )
+ throw (RuntimeException);
+ virtual Sequence<OUString> SAL_CALL getSupportedServiceNames()
+ throw (RuntimeException);
+
+ // XPackageRegistry
+ virtual Sequence< Reference<deployment::XPackageTypeInfo> > SAL_CALL
+ getSupportedPackageTypes() throw (RuntimeException);
+
+ using ImplBaseT::disposing;
+};
+
+//Used to find a XPackage with a particular URL
+class XPackage_eq : public std::unary_function<Reference<deployment::XPackage>, bool>
+{
+ OUString m_URL;
+public:
+ explicit XPackage_eq(const OUString & s) : m_URL(s) {}
+ bool operator() (const Reference<deployment::XPackage> & p) const
+ {
+ return m_URL.equals(p->getURL());
+ }
+};
+
+//______________________________________________________________________________
+BackendImpl::BackendImpl(
+ Sequence<Any> const & args,
+ Reference<XComponentContext> const & xComponentContext,
+ Reference<deployment::XPackageRegistry> const & xRootRegistry )
+ : ImplBaseT( args, xComponentContext ),
+ m_xRootRegistry( xRootRegistry ),
+ m_xBundleTypeInfo( new Package::TypeInfo(
+ OUSTR("application/vnd.sun.star.package-bundle"),
+ OUSTR("*.oxt;*.uno.pkg"),
+ getResourceString(RID_STR_PACKAGE_BUNDLE),
+ RID_IMG_DEF_PACKAGE_BUNDLE,
+ RID_IMG_DEF_PACKAGE_BUNDLE_HC ) ),
+ m_xLegacyBundleTypeInfo( new Package::TypeInfo(
+ OUSTR("application/"
+ "vnd.sun.star.legacy-package-bundle"),
+ OUSTR("*.zip"),
+ m_xBundleTypeInfo->getShortDescription(),
+ RID_IMG_DEF_PACKAGE_BUNDLE,
+ RID_IMG_DEF_PACKAGE_BUNDLE_HC ) ),
+ m_typeInfos( 2 )
+{
+ m_typeInfos[ 0 ] = m_xBundleTypeInfo;
+ m_typeInfos[ 1 ] = m_xLegacyBundleTypeInfo;
+}
+
+//______________________________________________________________________________
+void BackendImpl::disposing()
+{
+ m_xRootRegistry.clear();
+ PackageRegistryBackend::disposing();
+}
+
+// XServiceInfo
+OUString BackendImpl::getImplementationName() throw (RuntimeException)
+{
+ return OUSTR("com.sun.star.comp.deployment.bundle.PackageRegistryBackend");
+}
+
+sal_Bool BackendImpl::supportsService( OUString const& name )
+ throw (RuntimeException)
+{
+ return getSupportedServiceNames()[0].equals(name);
+}
+
+Sequence<OUString> BackendImpl::getSupportedServiceNames()
+ throw (RuntimeException)
+{
+ return comphelper::makeSequence(
+ OUString::createFromAscii(BACKEND_SERVICE_NAME) );
+}
+
+// XPackageRegistry
+//______________________________________________________________________________
+Sequence< Reference<deployment::XPackageTypeInfo> >
+BackendImpl::getSupportedPackageTypes() throw (RuntimeException)
+{
+ return m_typeInfos;
+}
+
+
+
+// PackageRegistryBackend
+//______________________________________________________________________________
+Reference<deployment::XPackage> BackendImpl::bindPackage_(
+ OUString const & url, OUString const & mediaType_,
+ Reference<XCommandEnvironment> const & xCmdEnv )
+{
+ OUString mediaType( mediaType_ );
+ if (mediaType.getLength() == 0)
+ {
+ // detect media-type:
+ ::ucbhelper::Content ucbContent;
+ if (create_ucb_content( &ucbContent, url, xCmdEnv ))
+ {
+ const OUString title( ucbContent.getPropertyValue(
+ StrTitle::get() ).get<OUString>() );
+ if (title.endsWithIgnoreAsciiCaseAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(".oxt") ) ||
+ title.endsWithIgnoreAsciiCaseAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(".uno.pkg") ))
+ mediaType = OUSTR("application/vnd.sun.star.package-bundle");
+ else if (title.endsWithIgnoreAsciiCaseAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(".zip") ))
+ mediaType =
+ OUSTR("application/vnd.sun.star.legacy-package-bundle");
+ }
+ if (mediaType.getLength() == 0)
+ throw lang::IllegalArgumentException(
+ StrCannotDetectMediaType::get() + url,
+ static_cast<OWeakObject *>(this), static_cast<sal_Int16>(-1) );
+ }
+
+ String type, subType;
+ INetContentTypeParameterList params;
+ if (INetContentTypes::parse( mediaType, type, subType, &params ))
+ {
+ if (type.EqualsIgnoreCaseAscii("application"))
+ {
+ ::ucbhelper::Content ucbContent( url, xCmdEnv );
+ if (subType.EqualsIgnoreCaseAscii("vnd.sun.star.package-bundle")) {
+ return new PackageImpl(
+ this, url, ucbContent.getPropertyValue(
+ StrTitle::get() ).get<OUString>(),
+ m_xBundleTypeInfo, false );
+ }
+ else if (subType.EqualsIgnoreCaseAscii(
+ "vnd.sun.star.legacy-package-bundle")) {
+ return new PackageImpl(
+ this, url, ucbContent.getPropertyValue(
+ StrTitle::get() ).get<OUString>(),
+ m_xLegacyBundleTypeInfo, true );
+ }
+ }
+ }
+ throw lang::IllegalArgumentException(
+ StrUnsupportedMediaType::get() + mediaType,
+ static_cast<OWeakObject *>(this),
+ static_cast<sal_Int16>(-1) );
+}
+
+//##############################################################################
+
+BackendImpl * BackendImpl::PackageImpl::getMyBackend() const
+{
+ BackendImpl * pBackend = static_cast<BackendImpl *>(m_myBackend.get());
+ if (NULL == pBackend)
+ {
+ //May throw a DisposedException
+ check();
+ //We should never get here...
+ throw RuntimeException(
+ OUSTR("Failed to get the BackendImpl"),
+ static_cast<OWeakObject*>(const_cast<PackageImpl *>(this)));
+ }
+ return pBackend;
+}
+//______________________________________________________________________________
+void BackendImpl::PackageImpl::disposing()
+{
+ sal_Int32 len = m_bundle.getLength();
+ Reference<deployment::XPackage> const * p = m_bundle.getConstArray();
+ for ( sal_Int32 pos = 0; pos < len; ++pos )
+ try_dispose( p[ pos ] );
+ m_bundle.realloc( 0 );
+
+ Package::disposing();
+}
+
+// Package
+//______________________________________________________________________________
+beans::Optional< beans::Ambiguous<sal_Bool> >
+BackendImpl::PackageImpl::isRegistered_(
+ ::osl::ResettableMutexGuard &,
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv )
+{
+ const Sequence< Reference<deployment::XPackage> > bundle(
+ getBundle( abortChannel.get(), xCmdEnv ) );
+ bool reg = false;
+ bool present = false;
+ bool ambig = false;
+ for ( sal_Int32 pos = bundle.getLength(); pos--; )
+ {
+ Reference<deployment::XPackage> const & xPackage = bundle[ pos ];
+ //disregard executable (application/vnd.sun.star.executable)
+ //it will not be disabled/enabled.
+ OUString sType = xPackage->getPackageType()->getMediaType();
+ if (sType.equals(OUSTR("application/vnd.sun.star.executable")))
+ continue;
+
+ Reference<task::XAbortChannel> xSubAbortChannel(
+ xPackage->createAbortChannel() );
+ AbortChannel::Chain chain( abortChannel, xSubAbortChannel );
+ beans::Optional< beans::Ambiguous<sal_Bool> > option(
+ xPackage->isRegistered( xSubAbortChannel, xCmdEnv ) );
+ if (option.IsPresent)
+ {
+ beans::Ambiguous<sal_Bool> const & status = option.Value;
+ if (present)
+ {
+ if (reg != (status.Value != sal_False)) {
+ ambig = true;
+ reg = false;
+ break;
+ }
+ }
+ else
+ {
+ reg = status.Value;
+ present = true;
+ }
+ }
+ }
+ return beans::Optional< beans::Ambiguous<sal_Bool> >(
+ present, beans::Ambiguous<sal_Bool>(reg, ambig) );
+}
+
+OUString BackendImpl::PackageImpl::getTextFromURL(
+ const css::uno::Reference< css::ucb::XCommandEnvironment >& xCmdEnv,
+ const OUString& licenseUrl)
+{
+ try
+ {
+ ::ucbhelper::Content descContent(licenseUrl, xCmdEnv);
+ ::rtl::ByteSequence seq = dp_misc::readFile(descContent);
+ return OUString( reinterpret_cast<sal_Char const *>(
+ seq.getConstArray()), seq.getLength(), RTL_TEXTENCODING_UTF8);
+ }
+ catch (css::uno::Exception&)
+ {
+ Any exc( ::cppu::getCaughtException() );
+ throw css::deployment::DeploymentException(
+ OUSTR("Could not read file ") + licenseUrl, 0, exc);
+ }
+
+}
+
+DescriptionInfoset BackendImpl::PackageImpl::getDescriptionInfoset()
+{
+ css::uno::Reference< css::xml::dom::XNode > root;
+ try {
+ root =
+ ExtensionDescription(
+ getMyBackend()->getComponentContext(), m_url_expanded,
+ css::uno::Reference< css::ucb::XCommandEnvironment >()).
+ getRootElement();
+ } catch (NoDescriptionException &) {
+ } catch (css::deployment::DeploymentException & e) {
+ throw RuntimeException(
+ (OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.deployment.DeploymentException: ")) +
+ e.Message),
+ static_cast< OWeakObject * >(this));
+ }
+ return DescriptionInfoset(getMyBackend()->getComponentContext(), root);
+}
+
+bool BackendImpl::PackageImpl::checkPlatform(
+ css::uno::Reference< css::ucb::XCommandEnvironment > const & environment)
+{
+ bool ret = false;
+ DescriptionInfoset info(getDescriptionInfoset());
+ Sequence<OUString> platforms(info.getSupportedPlaforms());
+ if (hasValidPlatform(platforms))
+ {
+ ret = true;
+ }
+ else
+ {
+ ret = false;
+ rtl::OUString msg(
+ RTL_CONSTASCII_USTRINGPARAM("unsupported platform"));
+ Any e(
+ css::deployment::PlatformException(
+ msg, static_cast<OWeakObject *>(this), this));
+ if (!interactContinuation(
+ e, cppu::UnoType< css::task::XInteractionApprove >::get(),
+ environment, NULL, NULL))
+ {
+ throw css::deployment::DeploymentException(
+ msg, static_cast<OWeakObject *>(this), e);
+ }
+ }
+ return ret;
+}
+
+
+bool BackendImpl::PackageImpl::checkDependencies(
+ css::uno::Reference< css::ucb::XCommandEnvironment > const & environment,
+ ExtensionDescription const & description)
+{
+ css::uno::Sequence< css::uno::Reference< css::xml::dom::XElement > >
+ unsatisfied(
+ dp_misc::Dependencies::check(
+ DescriptionInfoset(
+ getMyBackend()->getComponentContext(),
+ description.getRootElement())));
+ if (unsatisfied.getLength() == 0) {
+ return true;
+ } else {
+ rtl::OUString msg(
+ RTL_CONSTASCII_USTRINGPARAM("unsatisfied dependencies"));
+ Any e(
+ css::deployment::DependencyException(
+ msg, static_cast<OWeakObject *>(this), unsatisfied));
+ if (!interactContinuation(
+ e, cppu::UnoType< css::task::XInteractionApprove >::get(),
+ environment, NULL, NULL))
+ {
+ throw css::deployment::DeploymentException(
+ msg, static_cast<OWeakObject *>(this), e);
+ }
+ return false;
+ }
+}
+
+::sal_Bool BackendImpl::PackageImpl::checkLicense(
+ css::uno::Reference< css::ucb::XCommandEnvironment > const & xCmdEnv,
+ ExtensionDescription const & desc, bool bInstalled, OUString const & aContextName)
+ throw (css::deployment::DeploymentException,
+ css::ucb::CommandFailedException,
+ css::ucb::CommandAbortedException,
+ css::uno::RuntimeException)
+{
+ try
+ {
+ css::uno::Reference<css::xml::dom::XNode> xRoot = desc.getRootElement();
+ css::uno::Reference<css::xml::xpath::XXPathAPI> xPath =
+ getDescriptionInfoset().getXpath();
+
+ css::uno::Reference<css::xml::dom::XNode> nodeSimpleLic;
+ try {
+ nodeSimpleLic = xPath->selectSingleNode(xRoot,
+ OUSTR("/desc:description/desc:registration/desc:simple-license"));
+ } catch (css::xml::xpath::XPathException &) {
+ // ignore
+ }
+
+ if (!nodeSimpleLic.is())
+ return true;
+ OUString sLic = getDescriptionInfoset().getLocalizedLicenseURL();
+ //If we do not get a localized licence then there is an error in the description.xml
+ //This should be handled by using a validating parser. Therefore we assume that no
+ //license is available.
+ if (sLic.getLength() == 0)
+ throw css::deployment::DeploymentException(
+ OUSTR("Could not obtain path to license. Possible error in description.xml"), 0, Any());
+ OUString sHref = desc.getExtensionRootUrl() + OUSTR("/") + sLic;
+ OUString sLicense = getTextFromURL(xCmdEnv, sHref);
+ //determine who has to agree to the license
+ css::uno::Reference<css::xml::xpath::XXPathObject> nodeAttribWho3 =
+ xPath->eval(nodeSimpleLic,
+ OUSTR("@accept-by"));
+ OUString sAccept = nodeAttribWho3->getString().trim();
+ //check correct value for attribute
+ if ( ! (sAccept.equals(OUSTR("user")) || sAccept.equals(OUSTR("admin"))))
+ throw css::deployment::DeploymentException(
+ OUSTR("Could not obtain attribute simple-lincense@accept-by or it has no valid value"), 0, Any());
+
+ //If if @accept-by="user" then every user needs to accept the license before it can be installed.
+ //Therefore we must prevent the installation as shared extension.
+ OSL_ASSERT(aContextName.getLength());
+ if (sAccept.equals(OUSTR("user")) && aContextName.equals(OUSTR("shared")))
+ {
+ css::deployment::LicenseIndividualAgreementException exc =
+ css::deployment::LicenseIndividualAgreementException(OUString(), 0, m_name);
+
+ bool approve = false;
+ bool abort = false;
+ if (! interactContinuation(
+ Any(exc), task::XInteractionApprove::static_type(), xCmdEnv, &approve, &abort ))
+ throw css::deployment::DeploymentException(
+ OUSTR("Could not interact with user."), 0, Any());
+ if (abort == true)
+ return false;
+ //We should always prevent installation
+ OSL_ASSERT(0);
+ }
+
+ //determine optional attribute simple-license@suppressOnUpdate
+ css::uno::Reference<css::xml::dom::XElement> elemSimpleLic(nodeSimpleLic, css::uno::UNO_QUERY_THROW);
+ sal_Bool bSuppress = sal_False;
+ if (elemSimpleLic->hasAttribute(OUSTR("suppress-on-update")))
+ {
+ if (elemSimpleLic->getAttribute(OUSTR("suppress-on-update")).equals(OUSTR("true")))
+ bSuppress = sal_True;
+ }
+
+ //Only use interaction if there is no version of this extension already installed
+ //and the suppress-on-update flag is not set for the new extension
+ // bInstalled | bSuppress | show license
+ //----------------------------------------
+ // 0 | 0 | 1
+ // 0 | 1 | 1
+ // 1 | 0 | 1
+ // 1 | 1 | 0
+
+ if ( !(bInstalled && bSuppress))
+ {
+ css::deployment::LicenseException licExc =
+ css::deployment::LicenseException(OUString(), 0, m_name, sLicense);
+ bool approve = false;
+ bool abort = false;
+ if (! interactContinuation(
+ Any(licExc), task::XInteractionApprove::static_type(), xCmdEnv, &approve, &abort ))
+ throw css::deployment::DeploymentException(
+ OUSTR("Could not interact with user."), 0, Any());
+
+ if (approve == true)
+ return true;
+ else
+ return false;
+ //throw css::deployment::DeploymentException(
+ // OUSTR("Extension Manager: User declined the license."),
+ // static_cast<OWeakObject*>(this),
+ // Any( css::deployment::LicenseException(OUSTR("User declined the license."), 0, m_name, sLicense)));
+ }
+ return true;
+ } catch (css::ucb::CommandFailedException&) {
+ throw;
+ } catch (css::ucb::CommandAbortedException&) {
+ throw;
+ } catch (css::deployment::DeploymentException&) {
+ throw;
+ } catch (css::uno::RuntimeException&) {
+ throw;
+ } catch (css::uno::Exception&) {
+ Any anyExc = cppu::getCaughtException();
+ throw css::deployment::DeploymentException(OUSTR("Unexpected exception"), 0, anyExc);
+ }
+}
+
+::sal_Bool BackendImpl::PackageImpl::checkPrerequisites(
+ const css::uno::Reference< css::task::XAbortChannel >&,
+ const css::uno::Reference< css::ucb::XCommandEnvironment >& xCmdEnv,
+ sal_Bool bInstalled, OUString const & aContextName)
+ throw (css::deployment::DeploymentException,
+ css::ucb::CommandFailedException,
+ css::ucb::CommandAbortedException,
+ css::uno::RuntimeException)
+{
+ std::auto_ptr<ExtensionDescription> spDescription;
+ try {
+ spDescription.reset(
+ new ExtensionDescription(
+ getMyBackend()->getComponentContext(),
+ m_url_expanded,
+ xCmdEnv));
+ } catch (NoDescriptionException& ) {
+ return sal_True;
+ }
+ return checkPlatform(xCmdEnv)
+ && checkDependencies(xCmdEnv, *spDescription)
+ && checkLicense(xCmdEnv, *spDescription, bInstalled, aContextName);
+}
+
+::sal_Bool BackendImpl::PackageImpl::checkDependencies(
+ const css::uno::Reference< css::ucb::XCommandEnvironment >& xCmdEnv )
+ throw (css::deployment::DeploymentException,
+ css::ucb::CommandFailedException,
+ css::uno::RuntimeException)
+{
+ std::auto_ptr<ExtensionDescription> spDescription;
+ try {
+ spDescription.reset(
+ new ExtensionDescription( getMyBackend()->getComponentContext(), m_url_expanded, xCmdEnv ));
+ } catch (NoDescriptionException& ) {
+ return sal_True;
+ }
+ return checkDependencies(xCmdEnv, *spDescription);
+}
+
+beans::Optional<OUString> BackendImpl::PackageImpl::getIdentifier()
+ throw (RuntimeException)
+{
+ return beans::Optional<OUString>(
+ true,
+ dp_misc::generateIdentifier(
+ getDescriptionInfoset().getIdentifier(), m_name));
+}
+
+OUString BackendImpl::PackageImpl::getVersion() throw (RuntimeException)
+{
+ return getDescriptionInfoset().getVersion();
+}
+
+Sequence<OUString> BackendImpl::PackageImpl::getUpdateInformationURLs()
+ throw (RuntimeException)
+{
+ return getDescriptionInfoset().getUpdateInformationUrls();
+}
+
+beans::StringPair BackendImpl::PackageImpl::getPublisherInfo()
+ throw (RuntimeException)
+{
+ ::std::pair< OUString, OUString > aInfo = getDescriptionInfoset().getLocalizedPublisherNameAndURL();
+ beans::StringPair aStrPair( aInfo.first, aInfo.second );
+ return aStrPair;
+}
+
+//______________________________________________________________________________
+uno::Reference< graphic::XGraphic > BackendImpl::PackageImpl::getIcon( sal_Bool bHighContrast )
+ throw ( RuntimeException )
+{
+ uno::Reference< graphic::XGraphic > xGraphic;
+
+ OUString aIconURL = getDescriptionInfoset().getIconURL( bHighContrast );
+ if ( aIconURL.getLength() )
+ {
+ OUString aFullIconURL = m_url_expanded + OUSTR("/") + aIconURL;
+
+ uno::Reference< XComponentContext > xContext( getMyBackend()->getComponentContext() );
+ uno::Reference< graphic::XGraphicProvider > xGraphProvider(
+ xContext->getServiceManager()->createInstanceWithContext( OUSTR( "com.sun.star.graphic.GraphicProvider" ), xContext ),
+ uno::UNO_QUERY );
+
+ if ( xGraphProvider.is() )
+ {
+ uno::Sequence< beans::PropertyValue > aMediaProps( 1 );
+ aMediaProps[0].Name = OUSTR( "URL" );
+ aMediaProps[0].Value <<= aFullIconURL;
+
+ xGraphic = xGraphProvider->queryGraphic( aMediaProps );
+ }
+ }
+
+ return xGraphic;
+}
+
+//______________________________________________________________________________
+void BackendImpl::PackageImpl::processPackage_(
+ ::osl::ResettableMutexGuard &,
+ bool doRegisterPackage,
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv )
+{
+ const Sequence< Reference<deployment::XPackage> > bundle(
+ getBundle( abortChannel.get(), xCmdEnv ) );
+
+ if (doRegisterPackage)
+ {
+ const sal_Int32 len = bundle.getLength();
+ for ( sal_Int32 pos = 0; pos < len; ++pos )
+ {
+ checkAborted(abortChannel);
+ Reference<deployment::XPackage> const & xPackage = bundle[ pos ];
+ Reference<task::XAbortChannel> xSubAbortChannel(
+ xPackage->createAbortChannel() );
+ AbortChannel::Chain chain( abortChannel, xSubAbortChannel );
+ try {
+ xPackage->registerPackage( xSubAbortChannel, xCmdEnv );
+ }
+ catch (RuntimeException &) {
+ throw;
+ }
+ catch (CommandAbortedException &) {
+ throw;
+ }
+ catch (Exception &) {
+ // CommandFailedException, DeploymentException:
+ Any exc( ::cppu::getCaughtException() );
+ // try to handle exception, notify:
+ bool approve = false, abort = false;
+ if (! interactContinuation(
+ Any( lang::WrappedTargetException(
+ OUSTR("bundle item registration error!"),
+ static_cast<OWeakObject *>(this), exc ) ),
+ task::XInteractionApprove::static_type(), xCmdEnv,
+ &approve, &abort )) {
+ OSL_ASSERT( !approve && !abort );
+ if (m_legacyBundle) // default for legacy packages: ignore
+ continue;
+ // no selection at all, so rethrow;
+ // no C++ rethrow after getCaughtException(),
+ // see cppuhelper/exc_hlp.hxx:
+ ::cppu::throwException(exc);
+ }
+ if (approve && !abort) // ignore error, just continue
+ continue;
+
+ {
+ ProgressLevel progress(
+ xCmdEnv, OUSTR("rollback...") );
+ // try rollback
+ for ( ; pos--; )
+ {
+ try {
+ bundle[ pos ]->revokePackage(
+ xSubAbortChannel, xCmdEnv );
+ }
+ catch (RuntimeException &) {
+ throw;
+ }
+ catch (CommandAbortedException &) {
+ throw;
+ }
+ catch (Exception &) {
+ // bundle rollback error:
+ OSL_ENSURE( 0, ::rtl::OUStringToOString(
+ ::comphelper::anyToString(
+ ::cppu::getCaughtException() ),
+ RTL_TEXTENCODING_UTF8 ).getStr() );
+ // ignore any errors of rollback
+ }
+ }
+ progress.update( OUSTR("rollback finished.") );
+ }
+
+ deployment::DeploymentException dpExc;
+ if (exc >>= dpExc) {
+ throw CommandFailedException(
+ dpExc.Message, dpExc.Context, dpExc.Cause );
+ }
+ else {
+ // rethrow CommandFailedException
+ ::cppu::throwException(exc);
+ }
+ }
+ }
+ }
+ else
+ {
+ // revoke in reverse order:
+ for ( sal_Int32 pos = bundle.getLength(); pos--; )
+ {
+ checkAborted(abortChannel);
+ Reference<deployment::XPackage> const & xPackage = bundle[ pos ];
+ Reference<task::XAbortChannel> xSubAbortChannel(
+ xPackage->createAbortChannel() );
+ AbortChannel::Chain chain( abortChannel, xSubAbortChannel );
+ try {
+ bundle[ pos ]->revokePackage( xSubAbortChannel, xCmdEnv );
+ }
+ catch (RuntimeException &) {
+ throw;
+ }
+ catch (CommandAbortedException &) {
+ throw;
+ }
+ catch (Exception &) {
+ // CommandFailedException, DeploymentException:
+ Any exc( ::cppu::getCaughtException() );
+ // try to handle exception, notify:
+ bool approve = false, abort = false;
+ if (! interactContinuation(
+ Any( lang::WrappedTargetException(
+ OUSTR("bundle item revocation error!"),
+ static_cast<OWeakObject *>(this), exc ) ),
+ task::XInteractionApprove::static_type(), xCmdEnv,
+ &approve, &abort )) {
+ OSL_ASSERT( !approve && !abort );
+ if (m_legacyBundle) // default for legacy packages: ignore
+ continue;
+ // no selection at all, so rethrow
+ // no C++ rethrow after getCaughtException(),
+ // see cppuhelper/exc_hlp.hxx:
+ ::cppu::throwException(exc);
+ }
+ // ignore errors when revoking, although abort may have been
+ // selected
+ }
+ }
+ }
+}
+
+//______________________________________________________________________________
+OUString BackendImpl::PackageImpl::getDescription() throw (RuntimeException)
+{
+ const OUString sRelativeURL(getDescriptionInfoset().getLocalizedDescriptionURL());
+ OUString sDescription;
+ if (sRelativeURL.getLength())
+ {
+ OUString sURL = m_url_expanded + OUSTR("/") + sRelativeURL;
+ sDescription = getTextFromURL(
+ css::uno::Reference< css::ucb::XCommandEnvironment >(), sURL);
+
+ }
+ if (sDescription.getLength())
+ return sDescription;
+ else if(m_oldDescription.getLength())
+ return m_oldDescription;
+ else
+ return OUString();
+}
+
+//______________________________________________________________________________
+void BackendImpl::PackageImpl::exportTo(
+ OUString const & destFolderURL, OUString const & newTitle,
+ sal_Int32 nameClashAction, Reference<XCommandEnvironment> const & xCmdEnv )
+ throw (CommandFailedException, CommandAbortedException, RuntimeException)
+{
+ ::ucbhelper::Content sourceContent( m_url_expanded, xCmdEnv );
+ OUString title(newTitle);
+ if (title.getLength() == 0)
+ sourceContent.getPropertyValue( StrTitle::get() ) >>= title;
+ OUString destURL( makeURL( destFolderURL, ::rtl::Uri::encode(
+ title, rtl_UriCharClassPchar,
+ rtl_UriEncodeIgnoreEscapes,
+ RTL_TEXTENCODING_UTF8 ) ) );
+
+ if (nameClashAction == NameClash::ASK)
+ {
+ if (create_ucb_content(
+ 0, destURL, xCmdEnv, false /* no throw */ )) {
+ bool replace = false, abort = false;
+ if (! interactContinuation(
+ Any( NameClashResolveRequest(
+ OUSTR("file already exists: ") + title,
+ static_cast<OWeakObject *>(this),
+ task::InteractionClassification_QUERY,
+ destFolderURL, title, OUString() ) ),
+ XInteractionReplaceExistingData::static_type(), xCmdEnv,
+ &replace, &abort ) || !replace) {
+ return;
+ }
+ }
+ }
+ else if (nameClashAction != NameClash::OVERWRITE) {
+ throw CommandFailedException(
+ OUSTR("unsupported nameClashAction!"),
+ static_cast<OWeakObject *>(this), Any() );
+ }
+ erase_path( destURL, xCmdEnv );
+
+ ::rtl::OUStringBuffer buf;
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("vnd.sun.star.zip://") );
+ buf.append( ::rtl::Uri::encode( destURL,
+ rtl_UriCharClassRegName,
+ rtl_UriEncodeIgnoreEscapes,
+ RTL_TEXTENCODING_UTF8 ) );
+ buf.append( static_cast<sal_Unicode>('/') );
+ OUString destFolder( buf.makeStringAndClear() );
+
+ ::ucbhelper::Content destFolderContent( destFolder, xCmdEnv );
+ {
+ // transfer every item of folder into zip:
+ Reference<sdbc::XResultSet> xResultSet(
+ sourceContent.createCursor(
+ Sequence<OUString>(),
+ ::ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS ) );
+ ProgressLevel progress( xCmdEnv, OUString() );
+ while (xResultSet->next())
+ {
+ ::ucbhelper::Content subContent(
+ Reference<XContentAccess>(
+ xResultSet, UNO_QUERY_THROW )->queryContent(), xCmdEnv );
+ if (! destFolderContent.transferContent(
+ subContent, ::ucbhelper::InsertOperation_COPY,
+ OUString(), NameClash::OVERWRITE ))
+ throw RuntimeException( OUSTR("UCB transferContent() failed!"),
+ static_cast<OWeakObject *>(this) );
+ progress.update( Any() ); // animating progress bar
+ }
+ }
+
+ // assure META-INF folder:
+ ::ucbhelper::Content metainfFolderContent;
+ create_folder( &metainfFolderContent,
+ makeURL( destFolderContent.getURL(), OUSTR("META-INF") ),
+ xCmdEnv );
+
+ if (m_legacyBundle)
+ {
+ // easy to migrate legacy bundles to new format:
+ // just export them once using a .oxt name!
+ // set detected media-types of any bundle item:
+
+ // collect all manifest entries:
+ Sequence< Reference<deployment::XPackage> > bundle;
+ try {
+ bundle = getBundle( Reference<task::XAbortChannel>(), xCmdEnv );
+ }
+ // xxx todo: think about exception specs:
+ catch (deployment::DeploymentException &) {
+ OSL_ENSURE( 0, ::rtl::OUStringToOString(
+ ::comphelper::anyToString(
+ ::cppu::getCaughtException() ),
+ RTL_TEXTENCODING_UTF8 ).getStr() );
+ }
+ catch (lang::IllegalArgumentException & exc) {
+ (void) exc;
+ OSL_ENSURE( 0, ::rtl::OUStringToOString(
+ exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
+ }
+
+ ::std::vector< Sequence<beans::PropertyValue> > manifest;
+ manifest.reserve( bundle.getLength() );
+ sal_Int32 baseURLlen = m_url_expanded.getLength();
+ Reference<deployment::XPackage> const *pbundle = bundle.getConstArray();
+ const OUString strMediaType = OUSTR("MediaType");
+ const OUString strFullPath = OUSTR("FullPath");
+ const OUString strIsFolder = OUSTR("IsFolder");
+ for ( sal_Int32 pos = bundle.getLength(); pos--; )
+ {
+ Reference<deployment::XPackage> const & xPackage = pbundle[ pos ];
+ OUString url_( expandUnoRcUrl( xPackage->getURL() ) );
+ OSL_ASSERT( url_.getLength() >= baseURLlen );
+ OUString fullPath;
+ if (url_.getLength() > baseURLlen)
+ fullPath = url_.copy( baseURLlen + 1 );
+ ::ucbhelper::Content ucbContent( url_, xCmdEnv );
+ if (ucbContent.getPropertyValue(strIsFolder).get<bool>())
+ fullPath += OUSTR("/");
+ Sequence<beans::PropertyValue> attribs( 2 );
+ beans::PropertyValue * pattribs = attribs.getArray();
+ pattribs[ 0 ].Name = strFullPath;
+ pattribs[ 0 ].Value <<= fullPath;
+ pattribs[ 1 ].Name = strMediaType;
+ const Reference<deployment::XPackageTypeInfo> xPackageType(
+ xPackage->getPackageType() );
+ OUString mediaType;
+ OSL_ASSERT( xPackageType.is() );
+ if (xPackageType.is())
+ mediaType = xPackageType->getMediaType();
+ else
+ mediaType = OUSTR("unknown");
+ pattribs[ 1 ].Value <<= mediaType;
+ manifest.push_back( attribs );
+ }
+
+ // write into pipe:
+ Reference<XComponentContext> xContext(
+ getMyBackend()->getComponentContext() );
+ Reference<packages::manifest::XManifestWriter> xManifestWriter(
+ xContext->getServiceManager()->createInstanceWithContext(
+ OUSTR("com.sun.star.packages.manifest.ManifestWriter"),
+ xContext ), UNO_QUERY_THROW );
+ Reference<io::XOutputStream> xPipe(
+ xContext->getServiceManager()->createInstanceWithContext(
+ OUSTR("com.sun.star.io.Pipe"), xContext ), UNO_QUERY_THROW );
+ xManifestWriter->writeManifestSequence(
+ xPipe, comphelper::containerToSequence(manifest) );
+
+ // write buffered pipe data to content:
+ ::ucbhelper::Content manifestContent(
+ makeURL( metainfFolderContent.getURL(), OUSTR("manifest.xml") ),
+ xCmdEnv );
+ manifestContent.writeStream(
+ Reference<io::XInputStream>( xPipe, UNO_QUERY_THROW ),
+ true /* replace existing */ );
+ }
+ else
+ {
+ // overwrite manifest.xml:
+ ::ucbhelper::Content manifestContent;
+ if ( ! create_ucb_content(
+ &manifestContent,
+ makeURL( m_url_expanded, OUSTR("META-INF/manifest.xml") ),
+ xCmdEnv, false ) )
+ {
+ OSL_ENSURE( 0, "### missing META-INF/manifest.xml file!" );
+ return;
+ }
+
+ if (! metainfFolderContent.transferContent(
+ manifestContent, ::ucbhelper::InsertOperation_COPY,
+ OUString(), NameClash::OVERWRITE ))
+ throw RuntimeException( OUSTR("UCB transferContent() failed!"),
+ static_cast<OWeakObject *>(this) );
+ }
+
+ // xxx todo: maybe obsolete in the future
+ try {
+ destFolderContent.executeCommand( OUSTR("flush"), Any() );
+ }
+ catch (UnsupportedCommandException &) {
+ }
+}
+
+//______________________________________________________________________________
+sal_Bool BackendImpl::PackageImpl::isBundle() throw (RuntimeException)
+{
+ return true;
+}
+
+//______________________________________________________________________________
+Sequence< Reference<deployment::XPackage> > BackendImpl::PackageImpl::getBundle(
+ Reference<task::XAbortChannel> const & xAbortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv )
+ throw (deployment::DeploymentException,
+ CommandFailedException, CommandAbortedException,
+ lang::IllegalArgumentException, RuntimeException)
+{
+ Sequence< Reference<deployment::XPackage> > * pBundle = m_pBundle;
+ if (pBundle == 0)
+ {
+ t_packagevec bundle;
+ try {
+ if (m_legacyBundle)
+ {
+ // .zip legacy packages allow script.xlb, dialog.xlb in bundle
+ // root folder:
+ OUString mediaType;
+ // probe for script.xlb:
+ if (create_ucb_content(
+ 0, makeURL( m_url_expanded, OUSTR("script.xlb") ),
+ xCmdEnv, false /* no throw */ )) {
+ mediaType = OUSTR("application/vnd.sun.star.basic-library");
+ }
+ // probe for dialog.xlb:
+ else if (create_ucb_content(
+ 0, makeURL( m_url_expanded, OUSTR("dialog.xlb") ),
+ xCmdEnv, false /* no throw */ ))
+ mediaType = OUSTR("application/vnd.sun.star."
+ "dialog-library");
+
+ if (mediaType.getLength() > 0) {
+ const Reference<deployment::XPackage> xPackage(
+ bindBundleItem( getURL(), mediaType, xCmdEnv ) );
+ if (xPackage.is())
+ bundle.push_back( xPackage );
+ // continue scanning:
+ }
+ scanLegacyBundle( bundle, getURL(),
+ AbortChannel::get(xAbortChannel), xCmdEnv );
+ }
+ else
+ {
+ // .oxt:
+ scanBundle( bundle, AbortChannel::get(xAbortChannel), xCmdEnv );
+ }
+ }
+ catch (RuntimeException &) {
+ throw;
+ }
+ catch (CommandFailedException &) {
+ throw;
+ }
+ catch (CommandAbortedException &) {
+ throw;
+ }
+ catch (deployment::DeploymentException &) {
+ throw;
+ }
+ catch (Exception &) {
+ Any exc( ::cppu::getCaughtException() );
+ throw deployment::DeploymentException(
+ OUSTR("error scanning bundle: ") + getURL(),
+ static_cast<OWeakObject *>(this), exc );
+ }
+
+ // sort: schema before config data, typelibs before components:
+ Sequence< Reference<deployment::XPackage> > ret( bundle.size() );
+ Reference<deployment::XPackage> * pret = ret.getArray();
+ sal_Int32 lower_end = 0;
+ sal_Int32 upper_end = ret.getLength();
+ t_packagevec::const_iterator iPos( bundle.begin() );
+ t_packagevec::const_iterator const iEnd( bundle.end() );
+ for ( ; iPos != iEnd; ++iPos )
+ {
+ const Reference<deployment::XPackageTypeInfo> xPackageType(
+ (*iPos)->getPackageType() );
+ OSL_ASSERT( xPackageType.is() );
+ if (xPackageType.is()) {
+ const OUString mediaType( xPackageType->getMediaType() );
+ String type, subType;
+ INetContentTypeParameterList params;
+ if (INetContentTypes::parse(
+ mediaType, type, subType, &params ) &&
+ type.EqualsIgnoreCaseAscii("application") &&
+ (subType.EqualsIgnoreCaseAscii(
+ "vnd.sun.star.uno-component") ||
+ subType.EqualsIgnoreCaseAscii(
+ "vnd.sun.star.configuration-data")))
+ {
+ --upper_end;
+ pret[ upper_end ] = *iPos;
+ continue;
+ }
+ }
+ pret[ lower_end ] = *iPos;
+ ++lower_end;
+ }
+ OSL_ASSERT( lower_end == upper_end );
+
+ const ::osl::MutexGuard guard( getMutex() );
+ pBundle = m_pBundle;
+ if (pBundle == 0) {
+ m_bundle = ret;
+ pBundle = &m_bundle;
+ OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
+ m_pBundle = pBundle;
+ }
+ }
+ else {
+ OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
+ }
+ return *pBundle;
+}
+
+inline bool isBundle_( OUString const & mediaType )
+{
+ // xxx todo: additional parsing?
+ return mediaType.getLength() > 0 &&
+ (mediaType.matchIgnoreAsciiCaseAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(
+ "application/vnd.sun.star.package-bundle") ) ||
+ mediaType.matchIgnoreAsciiCaseAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(
+ "application/vnd.sun.star.legacy-package-bundle") ));
+}
+
+//______________________________________________________________________________
+Reference<deployment::XPackage> BackendImpl::PackageImpl::bindBundleItem(
+ OUString const & url, OUString const & mediaType,
+ Reference<XCommandEnvironment> const & xCmdEnv,
+ bool notifyDetectionError )
+{
+ // ignore any nested bundles:
+ if (isBundle_(mediaType))
+ return Reference<deployment::XPackage>();
+
+ Reference<deployment::XPackage>xPackage;
+ try {
+ xPackage.set( getMyBackend()->m_xRootRegistry->bindPackage(
+ url, mediaType, xCmdEnv ) );
+ OSL_ASSERT( xPackage.is() );
+ }
+ catch (RuntimeException &) {
+ throw;
+ }
+ catch (CommandFailedException &) {
+ // ignore already handled error
+ }
+ catch (Exception &) {
+ const Any exc( ::cppu::getCaughtException() );
+ if (notifyDetectionError ||
+ !exc.isExtractableTo(
+ ::getCppuType( reinterpret_cast<
+ lang::IllegalArgumentException const *>(0) ) ))
+ {
+ interactContinuation(
+ Any( lang::WrappedTargetException(
+ OUSTR("bundle item error!"),
+ static_cast<OWeakObject *>(this), exc ) ),
+ task::XInteractionApprove::static_type(), xCmdEnv, 0, 0 );
+ }
+ }
+
+ if (xPackage.is()) {
+ const Reference<deployment::XPackageTypeInfo> xPackageType(
+ xPackage->getPackageType() );
+ OSL_ASSERT( xPackageType.is() );
+ // ignore any nested bundles:
+ if (xPackageType.is() && isBundle_( xPackageType->getMediaType() ))
+ xPackage.clear();
+ }
+ return xPackage;
+}
+
+//______________________________________________________________________________
+void BackendImpl::PackageImpl::scanBundle(
+ t_packagevec & bundle,
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv )
+{
+ OSL_ASSERT( !m_legacyBundle );
+
+ ::ucbhelper::Content manifestContent;
+ if (! create_ucb_content(
+ &manifestContent,
+ makeURL( m_url_expanded, OUSTR("META-INF/manifest.xml") ),
+ xCmdEnv, false /* no throw */ ))
+ {
+ OSL_ENSURE( 0, "### missing META-INF/manifest.xml file!" );
+ return;
+}
+
+
+ const lang::Locale officeLocale = getOfficeLocale();
+ OUString descrFile;
+ lang::Locale descrFileLocale;
+
+ const Reference<XComponentContext> xContext(
+ getMyBackend()->getComponentContext() );
+ Reference<packages::manifest::XManifestReader> xManifestReader(
+ xContext->getServiceManager()->createInstanceWithContext(
+ OUSTR("com.sun.star.packages.manifest.ManifestReader"),
+ xContext ), UNO_QUERY_THROW );
+ const Sequence< Sequence<beans::PropertyValue> > manifestSeq(
+ xManifestReader->readManifestSequence( manifestContent.openStream() ) );
+ const OUString packageRootURL( getURL() );
+ for ( sal_Int32 pos = manifestSeq.getLength(); pos--; )
+ {
+ OUString fullPath, mediaType;
+ Sequence<beans::PropertyValue> const & attribs = manifestSeq[ pos ];
+ for ( sal_Int32 i = attribs.getLength(); i--; )
+ {
+ if (fullPath.getLength() > 0 && mediaType.getLength() > 0)
+ break;
+ if (attribs[i].Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("FullPath") ))
+ attribs[i].Value >>= fullPath;
+ else if (attribs[i].Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("MediaType") ))
+ attribs[i].Value >>= mediaType;
+ }
+
+ if (fullPath.getLength() == 0 || mediaType.getLength() == 0 ||
+ mediaType.equalsAsciiL( // opt: exclude common text/xml
+ RTL_CONSTASCII_STRINGPARAM("text/xml") ))
+ continue;
+
+ String type, subType;
+ INetContentTypeParameterList params;
+ if (! INetContentTypes::parse( mediaType, type, subType, &params ))
+ continue;
+
+ INetContentTypeParameter const * param = params.find(
+ ByteString("platform") );
+ if (param != 0 && !platform_fits( param->m_sValue ))
+ continue;
+ const OUString url( makeURL( packageRootURL, fullPath ) );
+
+ // check for bundle description:
+ if (type.EqualsIgnoreCaseAscii("application") &&
+ subType.EqualsIgnoreCaseAscii(
+ "vnd.sun.star.package-bundle-description"))
+ {
+ // check locale:
+ param = params.find( ByteString("locale") );
+ if (param == 0) {
+ if (descrFile.getLength() == 0)
+ descrFile = url;
+ }
+ else {
+ // match best locale:
+ lang::Locale locale( toLocale(param->m_sValue) );
+ if (locale.Language == officeLocale.Language)
+ {
+ if (descrFileLocale.Country == officeLocale.Country
+ && locale.Country != officeLocale.Country)
+ continue;
+ if (descrFileLocale.Variant == officeLocale.Variant
+ && locale.Variant != officeLocale.Variant)
+ continue;
+ descrFile = url;
+ descrFileLocale = locale;
+ }
+ }
+ continue;
+ }
+
+ checkAborted( abortChannel );
+
+ //We make sure that we only create one XPackage for a particular URL.
+ //Sometime programmers insert the same URL several times in the manifest
+ //which may lead to DisposedExceptions.
+ if (bundle.end() == std::find_if(bundle.begin(), bundle.end(), XPackage_eq(url)))
+ {
+ const Reference<deployment::XPackage> xPackage(
+ bindBundleItem( url, mediaType, xCmdEnv ) );
+ if (xPackage.is())
+ bundle.push_back( xPackage );
+ }
+ else
+ {
+ fprintf(stderr, "manifest.xml contains a duplicate entry!\n");
+ }
+ }
+
+ if (descrFile.getLength() > 0)
+ {
+ ::ucbhelper::Content descrFileContent;
+ if (create_ucb_content( &descrFileContent, descrFile,
+ xCmdEnv, false /* no throw */ ))
+ {
+ // patch description:
+ ::rtl::ByteSequence bytes( readFile( descrFileContent ) );
+ ::rtl::OUStringBuffer buf;
+ if ( bytes.getLength() )
+ {
+ buf.append( OUString( reinterpret_cast<sal_Char const *>(
+ bytes.getConstArray() ),
+ bytes.getLength(), RTL_TEXTENCODING_UTF8 ) );
+ }
+ else
+ {
+ buf.append( Package::getDescription() );
+ }
+ m_oldDescription = buf.makeStringAndClear();
+ }
+ }
+}
+
+//______________________________________________________________________________
+void BackendImpl::PackageImpl::scanLegacyBundle(
+ t_packagevec & bundle,
+ OUString const & url,
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv,
+ bool skip_registration )
+{
+ ::ucbhelper::Content ucbContent( url, xCmdEnv );
+
+ // check for platform pathes:
+ const OUString title( ucbContent.getPropertyValue(
+ StrTitle::get() ).get<OUString>() );
+ if (title.endsWithIgnoreAsciiCaseAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(".plt") ) &&
+ !platform_fits( title.copy( 0, title.getLength() - 4 ) )) {
+ return;
+ }
+ if (title.endsWithIgnoreAsciiCaseAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("skip_registration") ))
+ skip_registration = true;
+
+ OUString ar [] = { StrTitle::get(), OUSTR("IsFolder") };
+ Reference<sdbc::XResultSet> xResultSet(
+ ucbContent.createCursor(
+ Sequence<OUString>( ar, ARLEN(ar) ),
+ ::ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS ) );
+ while (xResultSet->next())
+ {
+ checkAborted( abortChannel );
+
+ const Reference<sdbc::XRow> xRow( xResultSet, UNO_QUERY_THROW );
+ const OUString title_enc( ::rtl::Uri::encode(
+ xRow->getString( 1 /* Title */ ),
+ rtl_UriCharClassPchar,
+ rtl_UriEncodeIgnoreEscapes,
+ RTL_TEXTENCODING_UTF8 ) );
+ const OUString path( makeURL( url, title_enc ) );
+
+ OUString mediaType;
+ const Reference<deployment::XPackage> xPackage(
+ bindBundleItem( path, OUString() /* detect */, xCmdEnv,
+ false /* ignore detection errors */ ) );
+ if (xPackage.is()) {
+ const Reference<deployment::XPackageTypeInfo> xPackageType(
+ xPackage->getPackageType() );
+ OSL_ASSERT( xPackageType.is() );
+ if (xPackageType.is())
+ mediaType = xPackageType->getMediaType();
+
+ if (skip_registration &&
+ // xxx todo: additional parsing?
+ mediaType.matchIgnoreAsciiCaseAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(
+ "application/vnd.sun.star.uno-component") ))
+ continue;
+
+ bundle.push_back( xPackage );
+ }
+
+ if (mediaType.getLength() == 0 ||
+ // script.xlb, dialog.xlb can be met everywhere:
+ mediaType.matchIgnoreAsciiCaseAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(
+ "application/vnd.sun.star.basic-library") ) ||
+ mediaType.matchIgnoreAsciiCaseAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(
+ "application/vnd.sun.star.dialog-library") ))
+ {
+ if (xRow->getBoolean( 2 /* IsFolder */ )) { // recurse into folder:
+ scanLegacyBundle(
+ bundle, path, abortChannel, xCmdEnv, skip_registration );
+ }
+ }
+ }
+}
+
+OUString BackendImpl::PackageImpl::getDisplayName() throw (RuntimeException)
+{
+ OUString sName = getDescriptionInfoset().getLocalizedDisplayName();
+ if (sName.getLength() == 0)
+ return m_displayName;
+ else
+ return sName;
+}
+
+} // anon namespace
+
+//==============================================================================
+Reference<deployment::XPackageRegistry> create(
+ Reference<deployment::XPackageRegistry> const & xRootRegistry,
+ OUString const & context, OUString const & cachePath, bool readOnly,
+ Reference<XComponentContext> const & xComponentContext )
+{
+ Sequence<Any> args(
+ cachePath.getLength() == 0 ? 1 : 3 );
+ args[ 0 ] <<= context;
+ if (cachePath.getLength() > 0) {
+ args[ 1 ] <<= cachePath;
+ args[ 2 ] <<= readOnly;
+ }
+ return new BackendImpl( args, xComponentContext, xRootRegistry );
+}
+
+} // namespace bundle
+} // namespace backend
+} // namespace dp_registry
+
diff --git a/desktop/source/deployment/registry/package/dp_package.hrc b/desktop/source/deployment/registry/package/dp_package.hrc
new file mode 100644
index 000000000000..df73bcdb80c4
--- /dev/null
+++ b/desktop/source/deployment/registry/package/dp_package.hrc
@@ -0,0 +1,38 @@
+/*************************************************************************
+ *
+ * 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: dp_package.hrc,v $
+ * $Revision: 1.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.
+ *
+ ************************************************************************/
+
+#if ! defined INCLUDED_DP_PACKAGE_HRC
+#define INCLUDED_DP_PACKAGE_HRC
+
+#include "deployment.hrc"
+
+#define RID_STR_PACKAGE_BUNDLE (RID_DEPLOYMENT_BUNDLE_START+10)
+
+#endif
diff --git a/desktop/source/deployment/registry/package/dp_package.src b/desktop/source/deployment/registry/package/dp_package.src
new file mode 100644
index 000000000000..6e77f8ae8934
--- /dev/null
+++ b/desktop/source/deployment/registry/package/dp_package.src
@@ -0,0 +1,37 @@
+/*************************************************************************
+ *
+ * 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: dp_package.src,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "dp_package.hrc"
+
+String RID_STR_PACKAGE_BUNDLE
+{
+ Text [ en-US ] = "Extension";
+};
+
diff --git a/desktop/source/deployment/registry/package/makefile.mk b/desktop/source/deployment/registry/package/makefile.mk
new file mode 100644
index 000000000000..007574eeff42
--- /dev/null
+++ b/desktop/source/deployment/registry/package/makefile.mk
@@ -0,0 +1,52 @@
+#*************************************************************************
+#
+# 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.6 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ = ..$/..$/..$/..
+
+PRJNAME = desktop
+TARGET = deployment_registry_package
+ENABLE_EXCEPTIONS = TRUE
+
+.INCLUDE : settings.mk
+
+SRS1NAME = $(TARGET)
+SRC1FILES = \
+ dp_package.src
+
+INCPRE += ..$/..$/inc
+
+SLOFILES = \
+ $(SLO)$/dp_package.obj \
+ $(SLO)$/dp_description.obj
+
+.INCLUDE : ..$/..$/target.pmk
+.INCLUDE : target.mk
+
diff --git a/desktop/source/deployment/registry/script/dp_lib_container.cxx b/desktop/source/deployment/registry/script/dp_lib_container.cxx
new file mode 100644
index 000000000000..c9bf36dc68ec
--- /dev/null
+++ b/desktop/source/deployment/registry/script/dp_lib_container.cxx
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * 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: dp_lib_container.cxx,v $
+ * $Revision: 1.12 $
+ *
+ * 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_desktop.hxx"
+
+#include "dp_script.hrc"
+#include "dp_resource.h"
+#include "dp_xml.h"
+#include "dp_lib_container.h"
+#include "ucbhelper/content.hxx"
+
+
+using namespace ::dp_misc;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::ucb;
+using ::rtl::OUString;
+
+namespace dp_registry {
+namespace backend {
+namespace script {
+
+namespace {
+struct StrCannotDetermineLibName : public StaticResourceString<
+ StrCannotDetermineLibName, RID_STR_CANNOT_DETERMINE_LIBNAME> {};
+}
+
+//______________________________________________________________________________
+OUString LibraryContainer::get_libname(
+ OUString const & url,
+ Reference<XCommandEnvironment> const & xCmdEnv,
+ Reference<XComponentContext> const & xContext )
+{
+ ::xmlscript::LibDescriptor import;
+ ::ucbhelper::Content ucb_content( url, xCmdEnv );
+ xml_parse( ::xmlscript::importLibrary( import ), ucb_content, xContext );
+
+ if (import.aName.getLength() == 0) {
+ throw Exception( StrCannotDetermineLibName::get(),
+ Reference<XInterface>() );
+ }
+ return import.aName;
+}
+
+}
+}
+}
+
diff --git a/desktop/source/deployment/registry/script/dp_lib_container.h b/desktop/source/deployment/registry/script/dp_lib_container.h
new file mode 100644
index 000000000000..3546dba7352d
--- /dev/null
+++ b/desktop/source/deployment/registry/script/dp_lib_container.h
@@ -0,0 +1,60 @@
+/*************************************************************************
+ *
+ * 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: dp_lib_container.h,v $
+ * $Revision: 1.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.
+ *
+ ************************************************************************/
+
+#if ! defined INCLUDED_DP_LIB_CONTAINER_H
+#define INCLUDED_DP_LIB_CONTAINER_H
+
+#include "rtl/ustring.hxx"
+#include "xmlscript/xmllib_imexp.hxx"
+#include "com/sun/star/uno/XComponentContext.hpp"
+#include "com/sun/star/ucb/XCommandEnvironment.hpp"
+
+
+namespace css = ::com::sun::star;
+
+namespace dp_registry {
+namespace backend {
+namespace script {
+
+//==============================================================================
+class LibraryContainer
+{
+public:
+ static ::rtl::OUString get_libname(
+ ::rtl::OUString const & url,
+ css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv,
+ css::uno::Reference<css::uno::XComponentContext> const & xContext );
+};
+
+}
+}
+}
+
+#endif
diff --git a/desktop/source/deployment/registry/script/dp_script.cxx b/desktop/source/deployment/registry/script/dp_script.cxx
new file mode 100644
index 000000000000..ba8a972d0624
--- /dev/null
+++ b/desktop/source/deployment/registry/script/dp_script.cxx
@@ -0,0 +1,476 @@
+/*************************************************************************
+ *
+ * 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: dp_script.cxx,v $
+ * $Revision: 1.15 $
+ *
+ * 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_desktop.hxx"
+
+#include "dp_script.hrc"
+#include "dp_lib_container.h"
+#include "dp_backend.h"
+#include "dp_ucb.h"
+#include "rtl/uri.hxx"
+#include "ucbhelper/content.hxx"
+#include "cppuhelper/exc_hlp.hxx"
+#include "cppuhelper/implbase1.hxx"
+#include "comphelper/servicedecl.hxx"
+#include "svtools/inettype.hxx"
+#include "com/sun/star/util/XUpdatable.hpp"
+#include "com/sun/star/script/XLibraryContainer.hpp"
+#include <com/sun/star/ucb/XSimpleFileAccess.hpp>
+#include <com/sun/star/util/XMacroExpander.hpp>
+#include <com/sun/star/uri/XUriReferenceFactory.hpp>
+#include <com/sun/star/uri/XVndSunStarExpandUrl.hpp>
+#include <memory>
+
+using namespace ::dp_misc;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::ucb;
+using ::rtl::OUString;
+namespace css = ::com::sun::star;
+
+namespace dp_registry {
+namespace backend {
+namespace script {
+namespace {
+
+typedef ::cppu::ImplInheritanceHelper1<
+ ::dp_registry::backend::PackageRegistryBackend, util::XUpdatable > t_helper;
+
+//==============================================================================
+class BackendImpl : public t_helper
+{
+ class PackageImpl : public ::dp_registry::backend::Package
+ {
+ BackendImpl * getMyBackend() const;
+
+ const OUString m_scriptURL;
+ const OUString m_dialogURL;
+ OUString m_dialogName;
+
+ // Package
+ virtual beans::Optional< beans::Ambiguous<sal_Bool> > isRegistered_(
+ ::osl::ResettableMutexGuard & guard,
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+ virtual void processPackage_(
+ ::osl::ResettableMutexGuard & guard,
+ bool registerPackage,
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+
+ public:
+ PackageImpl(
+ ::rtl::Reference<BackendImpl> const & myBackend,
+ OUString const & url,
+ Reference<XCommandEnvironment> const &xCmdEnv,
+ OUString const & scriptURL, OUString const & dialogURL );
+ };
+ friend class PackageImpl;
+
+ // PackageRegistryBackend
+ virtual Reference<deployment::XPackage> bindPackage_(
+ OUString const & url, OUString const & mediaType,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+
+ rtl::OUString getRegisteredFlagFileURL( Reference< deployment::XPackage > xPackage );
+ rtl::OUString expandURL( const rtl::OUString& aURL );
+ Reference< ucb::XSimpleFileAccess > getFileAccess( void );
+ Reference< ucb::XSimpleFileAccess > m_xSFA;
+
+ const Reference<deployment::XPackageTypeInfo> m_xBasicLibTypeInfo;
+ const Reference<deployment::XPackageTypeInfo> m_xDialogLibTypeInfo;
+ Sequence< Reference<deployment::XPackageTypeInfo> > m_typeInfos;
+
+public:
+ BackendImpl( Sequence<Any> const & args,
+ Reference<XComponentContext> const & xComponentContext );
+
+ // XUpdatable
+ virtual void SAL_CALL update() throw (RuntimeException);
+
+ // XPackageRegistry
+ virtual Sequence< Reference<deployment::XPackageTypeInfo> > SAL_CALL
+ getSupportedPackageTypes() throw (RuntimeException);
+};
+
+//______________________________________________________________________________
+BackendImpl::PackageImpl::PackageImpl(
+ ::rtl::Reference<BackendImpl> const & myBackend,
+ OUString const & url,
+ Reference<XCommandEnvironment> const &xCmdEnv,
+ OUString const & scriptURL, OUString const & dialogURL )
+ : Package( myBackend.get(), url,
+ OUString(), OUString(), // will be late-initialized
+ scriptURL.getLength() > 0 ? myBackend->m_xBasicLibTypeInfo
+ : myBackend->m_xDialogLibTypeInfo ),
+ m_scriptURL( scriptURL ),
+ m_dialogURL( dialogURL )
+{
+ // name, displayName:
+ if (dialogURL.getLength() > 0) {
+ m_dialogName = LibraryContainer::get_libname(
+ dialogURL, xCmdEnv, myBackend->getComponentContext() );
+ }
+ if (scriptURL.getLength() > 0) {
+ m_name = LibraryContainer::get_libname(
+ scriptURL, xCmdEnv, myBackend->getComponentContext() );
+ }
+ else
+ m_name = m_dialogName;
+ m_displayName = m_name;
+}
+
+//______________________________________________________________________________
+BackendImpl::BackendImpl(
+ Sequence<Any> const & args,
+ Reference<XComponentContext> const & xComponentContext )
+ : t_helper( args, xComponentContext ),
+ m_xBasicLibTypeInfo( new Package::TypeInfo(
+ OUSTR("application/"
+ "vnd.sun.star.basic-library"),
+ OUString() /* no file filter */,
+ getResourceString(RID_STR_BASIC_LIB),
+ RID_IMG_SCRIPTLIB, RID_IMG_SCRIPTLIB_HC ) ),
+ m_xDialogLibTypeInfo( new Package::TypeInfo(
+ OUSTR("application/"
+ "vnd.sun.star.dialog-library"),
+ OUString() /* no file filter */,
+ getResourceString(RID_STR_DIALOG_LIB),
+ RID_IMG_DIALOGLIB, RID_IMG_DIALOGLIB_HC ) ),
+ m_typeInfos( 2 )
+{
+ m_typeInfos[ 0 ] = m_xBasicLibTypeInfo;
+ m_typeInfos[ 1 ] = m_xDialogLibTypeInfo;
+
+ OSL_ASSERT( ! transientMode() );
+}
+
+// XUpdatable
+//______________________________________________________________________________
+void BackendImpl::update() throw (RuntimeException)
+{
+ // Nothing to do here after fixing i70283!?
+}
+
+// XPackageRegistry
+//______________________________________________________________________________
+Sequence< Reference<deployment::XPackageTypeInfo> >
+BackendImpl::getSupportedPackageTypes() throw (RuntimeException)
+{
+ return m_typeInfos;
+}
+
+// PackageRegistryBackend
+//______________________________________________________________________________
+Reference<deployment::XPackage> BackendImpl::bindPackage_(
+ OUString const & url, OUString const & mediaType_,
+ Reference<XCommandEnvironment> const & xCmdEnv )
+{
+ OUString mediaType( mediaType_ );
+ if (mediaType.getLength() == 0)
+ {
+ // detect media-type:
+ ::ucbhelper::Content ucbContent;
+ if (create_ucb_content( &ucbContent, url, xCmdEnv ) &&
+ ucbContent.isFolder())
+ {
+ // probe for script.xlb:
+ if (create_ucb_content(
+ 0, makeURL( url, OUSTR("script.xlb") ),
+ xCmdEnv, false /* no throw */ ))
+ mediaType = OUSTR("application/vnd.sun.star.basic-library");
+ // probe for dialog.xlb:
+ else if (create_ucb_content(
+ 0, makeURL( url, OUSTR("dialog.xlb") ),
+ xCmdEnv, false /* no throw */ ))
+ mediaType = OUSTR("application/vnd.sun.star.dialog-library");
+ }
+ if (mediaType.getLength() == 0)
+ throw lang::IllegalArgumentException(
+ StrCannotDetectMediaType::get() + url,
+ static_cast<OWeakObject *>(this), static_cast<sal_Int16>(-1) );
+ }
+
+ String type, subType;
+ INetContentTypeParameterList params;
+ if (INetContentTypes::parse( mediaType, type, subType, &params ))
+ {
+ if (type.EqualsIgnoreCaseAscii("application"))
+ {
+ if (subType.EqualsIgnoreCaseAscii("vnd.sun.star.basic-library"))
+ {
+ OUString dialogURL( makeURL( url, OUSTR("dialog.xlb") ) );
+ if (! create_ucb_content(
+ 0, dialogURL, xCmdEnv, false /* no throw */ )) {
+ dialogURL = OUString();
+ }
+ return new PackageImpl( this, url, xCmdEnv,
+ makeURL( url, OUSTR("script.xlb") ),
+ dialogURL );
+ }
+ else if (subType.EqualsIgnoreCaseAscii(
+ "vnd.sun.star.dialog-library")) {
+ return new PackageImpl( this, url, xCmdEnv,
+ OUString() /* no script lib */,
+ makeURL( url, OUSTR("dialog.xlb") ) );
+ }
+ }
+ }
+ throw lang::IllegalArgumentException(
+ StrUnsupportedMediaType::get() + mediaType,
+ static_cast<OWeakObject *>(this),
+ static_cast<sal_Int16>(-1) );
+}
+
+rtl::OUString BackendImpl::getRegisteredFlagFileURL( Reference< deployment::XPackage > xPackage )
+{
+ rtl::OUString aRetURL;
+ if( !xPackage.is() )
+ return aRetURL;
+ rtl::OUString aHelpURL = xPackage->getURL();
+ aRetURL = expandURL( aHelpURL );
+ aRetURL += rtl::OUString::createFromAscii( "/RegisteredFlag" );
+ return aRetURL;
+}
+
+rtl::OUString BackendImpl::expandURL( const rtl::OUString& aURL )
+{
+ static Reference< util::XMacroExpander > xMacroExpander;
+ static Reference< uri::XUriReferenceFactory > xFac;
+
+ if( !xMacroExpander.is() || !xFac.is() )
+ {
+ Reference<XComponentContext> const & xContext = getComponentContext();
+ if( xContext.is() )
+ {
+ xFac = Reference< uri::XUriReferenceFactory >(
+ xContext->getServiceManager()->createInstanceWithContext( rtl::OUString::createFromAscii(
+ "com.sun.star.uri.UriReferenceFactory"), xContext ) , UNO_QUERY );
+ }
+ if( !xFac.is() )
+ {
+ throw RuntimeException(
+ ::rtl::OUString::createFromAscii(
+ "dp_registry::backend::help::BackendImpl::expandURL(), "
+ "could not instatiate UriReferenceFactory." ),
+ Reference< XInterface >() );
+ }
+
+ xMacroExpander = Reference< util::XMacroExpander >(
+ xContext->getValueByName(
+ ::rtl::OUString::createFromAscii( "/singletons/com.sun.star.util.theMacroExpander" ) ),
+ UNO_QUERY_THROW );
+ }
+
+ rtl::OUString aRetURL = aURL;
+ if( xMacroExpander.is() )
+ {
+ Reference< uri::XUriReference > uriRef;
+ for (;;)
+ {
+ uriRef = Reference< uri::XUriReference >( xFac->parse( aRetURL ), UNO_QUERY );
+ if ( uriRef.is() )
+ {
+ Reference < uri::XVndSunStarExpandUrl > sxUri( uriRef, UNO_QUERY );
+ if( !sxUri.is() )
+ break;
+
+ aRetURL = sxUri->expand( xMacroExpander );
+ }
+ }
+ }
+ return aRetURL;
+}
+
+Reference< ucb::XSimpleFileAccess > BackendImpl::getFileAccess( void )
+{
+ if( !m_xSFA.is() )
+ {
+ Reference<XComponentContext> const & xContext = getComponentContext();
+ if( xContext.is() )
+ {
+ m_xSFA = Reference< ucb::XSimpleFileAccess >(
+ xContext->getServiceManager()->createInstanceWithContext(
+ rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ),
+ xContext ), UNO_QUERY );
+ }
+ if( !m_xSFA.is() )
+ {
+ throw RuntimeException(
+ ::rtl::OUString::createFromAscii(
+ "dp_registry::backend::help::BackendImpl::getFileAccess(), "
+ "could not instatiate SimpleFileAccess." ),
+ Reference< XInterface >() );
+ }
+ }
+ return m_xSFA;
+}
+
+//##############################################################################
+
+// Package
+BackendImpl * BackendImpl::PackageImpl::getMyBackend() const
+{
+ BackendImpl * pBackend = static_cast<BackendImpl *>(m_myBackend.get());
+ if (NULL == pBackend)
+ {
+ //May throw a DisposedException
+ check();
+ //We should never get here...
+ throw RuntimeException(
+ OUSTR("Failed to get the BackendImpl"),
+ static_cast<OWeakObject*>(const_cast<PackageImpl *>(this)));
+ }
+ return pBackend;
+}
+//______________________________________________________________________________
+beans::Optional< beans::Ambiguous<sal_Bool> >
+BackendImpl::PackageImpl::isRegistered_(
+ ::osl::ResettableMutexGuard &,
+ ::rtl::Reference<AbortChannel> const &,
+ Reference<XCommandEnvironment> const & xCmdEnv )
+{
+ (void)xCmdEnv;
+
+ BackendImpl * that = getMyBackend();
+ Reference< deployment::XPackage > xThisPackage( this );
+ rtl::OUString aRegisteredFlagFile = that->getRegisteredFlagFileURL( xThisPackage );
+
+ Reference< ucb::XSimpleFileAccess > xSFA = that->getFileAccess();
+ bool bReg = xSFA->exists( aRegisteredFlagFile );
+
+ return beans::Optional< beans::Ambiguous<sal_Bool> >(
+ true /* IsPresent */,
+ beans::Ambiguous<sal_Bool>( bReg, false /* IsAmbiguous */ ) );
+}
+
+//______________________________________________________________________________
+void BackendImpl::PackageImpl::processPackage_(
+ ::osl::ResettableMutexGuard &,
+ bool doRegisterPackage,
+ ::rtl::Reference<AbortChannel> const &,
+ Reference<XCommandEnvironment> const & xCmdEnv )
+{
+ (void)xCmdEnv;
+
+ BackendImpl * that = getMyBackend();
+
+ Reference< deployment::XPackage > xThisPackage( this );
+ rtl::OUString aRegisteredFlagFile = that->getRegisteredFlagFileURL( xThisPackage );
+ Reference< ucb::XSimpleFileAccess > xSFA = that->getFileAccess();
+ Reference<XComponentContext> const & xComponentContext = that->getComponentContext();
+
+ bool bScript = (m_scriptURL.getLength() > 0);
+ Reference<css::script::XLibraryContainer> xScriptLibs;
+
+ bool bDialog = (m_dialogURL.getLength() > 0);
+ Reference<css::script::XLibraryContainer> xDialogLibs;
+
+ bool bRunning = office_is_running();
+ if( bRunning )
+ {
+ if( bScript )
+ {
+ xScriptLibs.set(
+ xComponentContext->getServiceManager()->createInstanceWithContext(
+ OUSTR("com.sun.star.script.ApplicationScriptLibraryContainer"),
+ xComponentContext ), UNO_QUERY_THROW );
+ }
+
+ if( bDialog )
+ {
+ xDialogLibs.set(
+ xComponentContext->getServiceManager()->createInstanceWithContext(
+ OUSTR("com.sun.star.script.ApplicationDialogLibraryContainer"),
+ xComponentContext ), UNO_QUERY_THROW );
+ }
+ }
+
+ if( !doRegisterPackage )
+ {
+ if( xSFA->exists( aRegisteredFlagFile ) )
+ {
+ xSFA->kill( aRegisteredFlagFile );
+
+ if( bScript && xScriptLibs.is() && xScriptLibs->hasByName( m_name ) )
+ xScriptLibs->removeLibrary( m_name );
+
+ if( bDialog && xDialogLibs.is() && xDialogLibs->hasByName( m_dialogName ) )
+ xDialogLibs->removeLibrary( m_dialogName );
+ }
+ return;
+ }
+
+ if( xSFA->exists( aRegisteredFlagFile ) )
+ return; // Already registered
+
+ // Update LibraryContainer
+ bool bScriptSuccess = false;
+ const bool bReadOnly = false;
+ if( bScript && xScriptLibs.is() && !xScriptLibs->hasByName( m_name ) )
+ {
+ xScriptLibs->createLibraryLink( m_name, m_scriptURL, bReadOnly );
+ bScriptSuccess = xScriptLibs->hasByName( m_name );
+ }
+
+ bool bDialogSuccess = false;
+ if( bDialog && xDialogLibs.is() && !xDialogLibs->hasByName( m_dialogName ) )
+ {
+ xDialogLibs->createLibraryLink( m_dialogName, m_dialogURL, bReadOnly );
+ bDialogSuccess = xDialogLibs->hasByName( m_dialogName );
+ }
+
+ bool bSuccess = bScript || bDialog; // Something must have happened
+ if( bRunning )
+ if( (bScript && !bScriptSuccess) || (bDialog && !bDialogSuccess) )
+ bSuccess = false;
+
+ if( bSuccess && !xSFA->exists( aRegisteredFlagFile ) )
+ {
+ Reference< io::XOutputStream > xOutputStream = xSFA->openFileWrite( aRegisteredFlagFile );
+ if( xOutputStream.is() )
+ xOutputStream->closeOutput();
+ }
+}
+
+} // anon namespace
+
+namespace sdecl = comphelper::service_decl;
+sdecl::class_<BackendImpl, sdecl::with_args<true> > serviceBI;
+extern sdecl::ServiceDecl const serviceDecl(
+ serviceBI,
+ "com.sun.star.comp.deployment.script.PackageRegistryBackend",
+ BACKEND_SERVICE_NAME );
+
+} // namespace script
+} // namespace backend
+} // namespace dp_registry
+
diff --git a/desktop/source/deployment/registry/script/dp_script.hrc b/desktop/source/deployment/registry/script/dp_script.hrc
new file mode 100644
index 000000000000..df37ed091fec
--- /dev/null
+++ b/desktop/source/deployment/registry/script/dp_script.hrc
@@ -0,0 +1,42 @@
+/*************************************************************************
+ *
+ * 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: dp_script.hrc,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.
+ *
+ ************************************************************************/
+
+#if ! defined INCLUDED_DP_SCRIPT_HRC
+#define INCLUDED_DP_SCRIPT_HRC
+
+#include "deployment.hrc"
+
+#define RID_STR_BASIC_LIB (RID_DEPLOYMENT_SCRIPT_START+10)
+#define RID_STR_DIALOG_LIB (RID_DEPLOYMENT_SCRIPT_START+11)
+
+#define RID_STR_LIBNAME_ALREADY_EXISTS (RID_DEPLOYMENT_SCRIPT_START+15)
+#define RID_STR_CANNOT_DETERMINE_LIBNAME (RID_DEPLOYMENT_SCRIPT_START+16)
+
+#endif
diff --git a/desktop/source/deployment/registry/script/dp_script.src b/desktop/source/deployment/registry/script/dp_script.src
new file mode 100644
index 000000000000..7a8f10cd6f48
--- /dev/null
+++ b/desktop/source/deployment/registry/script/dp_script.src
@@ -0,0 +1,52 @@
+/*************************************************************************
+ *
+ * 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: dp_script.src,v $
+ * $Revision: 1.7 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "dp_script.hrc"
+
+String RID_STR_BASIC_LIB
+{
+ Text [ en-US ] = "%PRODUCTNAME Basic Library";
+};
+
+String RID_STR_DIALOG_LIB
+{
+ Text [ en-US ] = "Dialog Library";
+};
+
+String RID_STR_CANNOT_DETERMINE_LIBNAME
+{
+ Text [ en-US ] = "The library name could not be determined.";
+};
+
+String RID_STR_LIBNAME_ALREADY_EXISTS
+{
+ Text [ en-US ] = "This library name already exists. Please choose a different name.";
+};
+
diff --git a/desktop/source/deployment/registry/script/makefile.mk b/desktop/source/deployment/registry/script/makefile.mk
new file mode 100644
index 000000000000..76195895b227
--- /dev/null
+++ b/desktop/source/deployment/registry/script/makefile.mk
@@ -0,0 +1,52 @@
+#*************************************************************************
+#
+# 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.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.
+#
+#*************************************************************************
+
+PRJ = ..$/..$/..$/..
+
+PRJNAME = desktop
+TARGET = deployment_registry_script
+ENABLE_EXCEPTIONS = TRUE
+
+.INCLUDE : settings.mk
+
+SRS1NAME = $(TARGET)
+SRC1FILES = \
+ dp_script.src
+
+INCPRE += ..$/..$/inc
+
+SLOFILES = \
+ $(SLO)$/dp_script.obj \
+ $(SLO)$/dp_lib_container.obj
+
+.INCLUDE : ..$/..$/target.pmk
+.INCLUDE : target.mk
+
diff --git a/desktop/source/deployment/registry/sfwk/dp_parceldesc.cxx b/desktop/source/deployment/registry/sfwk/dp_parceldesc.cxx
new file mode 100644
index 000000000000..23d7c36cda79
--- /dev/null
+++ b/desktop/source/deployment/registry/sfwk/dp_parceldesc.cxx
@@ -0,0 +1,133 @@
+/*************************************************************************
+ *
+ * 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: dp_parceldesc.cxx,v $
+ * $Revision: 1.7.86.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_desktop.hxx"
+#include "dp_misc.h"
+#include "dp_parceldesc.hxx"
+
+
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+
+using ::rtl::OUString;
+
+namespace css = ::com::sun::star;
+namespace dp_registry
+{
+namespace backend
+{
+namespace sfwk
+{
+
+
+// XDocumentHandler
+void SAL_CALL
+ParcelDescDocHandler::startDocument()
+throw ( xml::sax::SAXException, RuntimeException )
+{
+ m_bIsParsed = false;
+}
+
+void SAL_CALL
+ParcelDescDocHandler::endDocument()
+throw ( xml::sax::SAXException, RuntimeException )
+{
+ m_bIsParsed = true;
+}
+
+void SAL_CALL
+ParcelDescDocHandler::characters( const OUString & )
+ throw ( xml::sax::SAXException, RuntimeException )
+{
+}
+
+void SAL_CALL
+ParcelDescDocHandler::ignorableWhitespace( const OUString & )
+ throw ( xml::sax::SAXException, RuntimeException )
+{
+}
+
+void SAL_CALL
+ParcelDescDocHandler::processingInstruction(
+ const OUString &, const OUString & )
+ throw ( xml::sax::SAXException, RuntimeException )
+{
+}
+
+void SAL_CALL
+ParcelDescDocHandler::setDocumentLocator(
+ const Reference< xml::sax::XLocator >& )
+ throw ( xml::sax::SAXException, RuntimeException )
+{
+}
+
+void SAL_CALL
+ParcelDescDocHandler::startElement( const OUString& aName,
+ const Reference< xml::sax::XAttributeList > & xAttribs )
+ throw ( xml::sax::SAXException,
+ RuntimeException )
+{
+
+ dp_misc::TRACE(OUSTR("ParcelDescDocHandler::startElement() for ") +
+ aName + OUSTR("\n"));
+ if ( !skipIndex )
+ {
+ if ( aName.equals( OUString::createFromAscii( "parcel" ) ) )
+ {
+ m_sLang = xAttribs->getValueByName( OUString::createFromAscii( "language" ) );
+ }
+ ++skipIndex;
+ }
+ else
+ {
+ dp_misc::TRACE(OUSTR("ParcelDescDocHandler::startElement() skipping for ")
+ + aName + OUSTR("\n"));
+ }
+
+}
+
+void SAL_CALL ParcelDescDocHandler::endElement( const OUString & aName )
+ throw ( xml::sax::SAXException, RuntimeException )
+{
+ if ( skipIndex )
+ {
+ --skipIndex;
+ dp_misc::TRACE(OUSTR("ParcelDescDocHandler::endElement() skipping for ")
+ + aName + OUSTR("\n"));
+ }
+}
+
+
+}
+}
+}
+
diff --git a/desktop/source/deployment/registry/sfwk/dp_parceldesc.hxx b/desktop/source/deployment/registry/sfwk/dp_parceldesc.hxx
new file mode 100644
index 000000000000..c7d15a297996
--- /dev/null
+++ b/desktop/source/deployment/registry/sfwk/dp_parceldesc.hxx
@@ -0,0 +1,92 @@
+/*************************************************************************
+ *
+ * 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: dp_parceldesc.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.
+ *
+ ************************************************************************/
+
+#include <cppuhelper/implbase1.hxx>
+
+#include <com/sun/star/xml/sax/XAttributeList.hpp>
+#include <com/sun/star/xml/sax/SAXException.hpp>
+#include <com/sun/star/xml/sax/XDocumentHandler.hpp>
+#include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
+#include <com/sun/star/xml/sax/XParser.hpp>
+
+#include <com/sun/star/lang/NoSupportException.hpp>
+#include <com/sun/star/lang/XMultiComponentFactory.hpp>
+namespace css = ::com::sun::star;
+namespace dp_registry
+{
+namespace backend
+{
+namespace sfwk
+{
+
+typedef ::cppu::WeakImplHelper1< css::xml::sax::XDocumentHandler > t_DocHandlerImpl;
+
+class ParcelDescDocHandler : public t_DocHandlerImpl
+{
+private:
+ bool m_bIsParsed;
+ ::rtl::OUString m_sLang;
+ sal_Int32 skipIndex;
+public:
+ ParcelDescDocHandler():m_bIsParsed( false ), skipIndex( 0 ){}
+ ::rtl::OUString getParcelLanguage() { return m_sLang; }
+ bool isParsed() { return m_bIsParsed; }
+ // XDocumentHandler
+ virtual void SAL_CALL startDocument()
+ throw ( css::xml::sax::SAXException, css::uno::RuntimeException );
+
+ virtual void SAL_CALL endDocument()
+ throw ( css::xml::sax::SAXException, css::uno::RuntimeException );
+
+ virtual void SAL_CALL startElement( const ::rtl::OUString& aName,
+ const css::uno::Reference< css::xml::sax::XAttributeList > & xAttribs )
+ throw ( css::xml::sax::SAXException,
+ css::uno::RuntimeException );
+
+ virtual void SAL_CALL endElement( const ::rtl::OUString & aName )
+ throw ( css::xml::sax::SAXException, css::uno::RuntimeException );
+
+ virtual void SAL_CALL characters( const ::rtl::OUString & aChars )
+ throw ( css::xml::sax::SAXException, css::uno::RuntimeException );
+
+ virtual void SAL_CALL ignorableWhitespace( const ::rtl::OUString & aWhitespaces )
+ throw ( css::xml::sax::SAXException, css::uno::RuntimeException );
+
+ virtual void SAL_CALL processingInstruction(
+ const ::rtl::OUString & aTarget, const ::rtl::OUString & aData )
+ throw ( css::xml::sax::SAXException, css::uno::RuntimeException );
+
+ virtual void SAL_CALL setDocumentLocator(
+ const css::uno::Reference< css::xml::sax::XLocator >& xLocator )
+ throw ( css::xml::sax::SAXException, css::uno::RuntimeException );
+};
+}
+}
+}
diff --git a/desktop/source/deployment/registry/sfwk/dp_sfwk.cxx b/desktop/source/deployment/registry/sfwk/dp_sfwk.cxx
new file mode 100644
index 000000000000..ff17da268dff
--- /dev/null
+++ b/desktop/source/deployment/registry/sfwk/dp_sfwk.cxx
@@ -0,0 +1,401 @@
+/*************************************************************************
+ *
+ * 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: dp_sfwk.cxx,v $
+ * $Revision: 1.16.66.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_desktop.hxx"
+#include "dp_sfwk.hrc"
+#include "dp_backend.h"
+#include "dp_ucb.h"
+#include "dp_parceldesc.hxx"
+#include "rtl/uri.hxx"
+#include "ucbhelper/content.hxx"
+#include "cppuhelper/exc_hlp.hxx"
+#include "comphelper/servicedecl.hxx"
+#include "svtools/inettype.hxx"
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/script/provider/XScriptProviderFactory.hpp>
+#include <memory>
+
+
+using namespace ::dp_misc;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::ucb;
+using namespace ::com::sun::star::script;
+
+using ::rtl::OUString;
+namespace css = ::com::sun::star;
+
+namespace dp_registry
+{
+namespace backend
+{
+namespace sfwk
+{
+
+//==============================================================================
+class BackendImpl : public ::dp_registry::backend::PackageRegistryBackend
+{
+ class PackageImpl : public ::dp_registry::backend::Package
+ {
+ BackendImpl * getMyBackend() const;
+
+ Reference< container::XNameContainer > m_xNameCntrPkgHandler;
+ OUString m_descr;
+
+ void initPackageHandler();
+
+ // Package
+ virtual beans::Optional< beans::Ambiguous<sal_Bool> > isRegistered_(
+ ::osl::ResettableMutexGuard & guard,
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+ virtual void processPackage_(
+ ::osl::ResettableMutexGuard & guard,
+ bool registerPackage,
+ ::rtl::Reference<AbortChannel> const & abortChannel,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+
+ public:
+ PackageImpl( ::rtl::Reference<BackendImpl> const & myBackend,
+ OUString const & url, OUString const & libType );
+ // XPackage
+ virtual OUString SAL_CALL getDescription() throw (RuntimeException);
+ };
+ friend class PackageImpl;
+
+ // PackageRegistryBackend
+ virtual Reference<deployment::XPackage> bindPackage_(
+ OUString const & url, OUString const & mediaType,
+ Reference<XCommandEnvironment> const & xCmdEnv );
+
+ const Reference<deployment::XPackageTypeInfo> m_xTypeInfo;
+
+public:
+ BackendImpl(
+ Sequence<Any> const & args,
+ Reference<XComponentContext> const & xComponentContext );
+
+ // XPackageRegistry
+ virtual Sequence< Reference<deployment::XPackageTypeInfo> > SAL_CALL
+ getSupportedPackageTypes() throw (RuntimeException);
+};
+
+BackendImpl * BackendImpl::PackageImpl::getMyBackend() const
+{
+ BackendImpl * pBackend = static_cast<BackendImpl *>(m_myBackend.get());
+ if (NULL == pBackend)
+ {
+ //May throw a DisposedException
+ check();
+ //We should never get here...
+ throw RuntimeException(
+ OUSTR("Failed to get the BackendImpl"),
+ static_cast<OWeakObject*>(const_cast<PackageImpl *>(this)));
+ }
+ return pBackend;
+}
+//______________________________________________________________________________
+OUString BackendImpl::PackageImpl::getDescription() throw (RuntimeException)
+{
+ if (m_descr.getLength() == 0)
+ return Package::getDescription();
+ else
+ return m_descr;
+}
+
+//______________________________________________________________________________
+BackendImpl::PackageImpl::PackageImpl(
+ ::rtl::Reference<BackendImpl> const & myBackend,
+ OUString const & url, OUString const & libType )
+ : Package( myBackend.get(), url, OUString(), OUString(),
+ myBackend->m_xTypeInfo ),
+ m_descr(libType)
+{
+ initPackageHandler();
+
+ sal_Int32 segmEnd = url.getLength();
+ if (url.getLength() > 0 && url[ url.getLength() - 1 ] == '/')
+ --segmEnd;
+ sal_Int32 segmStart = (url.lastIndexOf( '/', segmEnd ) + 1);
+ if (segmStart < 0)
+ segmStart = 0;
+ // name and display name default the same:
+ m_displayName = ::rtl::Uri::decode(
+ url.copy( segmStart, segmEnd - segmStart ),
+ rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 );
+ m_name = m_displayName;
+
+ dp_misc::TRACE(OUSTR("PakageImpl displayName is ") + m_displayName);
+}
+
+//______________________________________________________________________________
+BackendImpl::BackendImpl(
+ Sequence<Any> const & args,
+ Reference<XComponentContext> const & xComponentContext )
+ : PackageRegistryBackend( args, xComponentContext ),
+ m_xTypeInfo( new Package::TypeInfo(
+ OUSTR("application/vnd.sun.star.framework-script"),
+ OUString() /* no file filter */,
+ OUSTR("Scripting Framework Script Library"),
+ RID_IMG_SCRIPTLIB, RID_IMG_SCRIPTLIB_HC ) )
+{
+ if (! transientMode())
+ {
+/*
+ if (office_is_running())
+ {
+ Reference<XComponentContext> xContext( getComponentContext() );
+ m_xScriptLibs.set(
+ xContext->getServiceManager()->createInstanceWithContext(
+ OUSTR("com.sun.star."
+ "script.ApplicationScriptLibraryContainer"),
+ xContext ), UNO_QUERY_THROW );
+ m_xDialogLibs.set(
+ xContext->getServiceManager()->createInstanceWithContext(
+ OUSTR("com.sun.star."
+ "script.ApplicationDialogLibraryContainer"),
+ xContext ), UNO_QUERY_THROW );
+ }
+ else
+ {
+ OUString basic_path(
+ m_eContext == CONTEXT_USER
+ ? OUSTR("vnd.sun.star.expand:${$BRAND_BASE_DIR/program/"
+ SAL_CONFIGFILE("bootstrap")
+ ":UserInstallation}/user/basic")
+ : OUSTR("vnd.sun.star.expand:${$BRAND_BASE_DIR/program/"
+ SAL_CONFIGFILE("bootstrap")
+ ":BaseInstallation}/share/basic") );
+ m_basic_script_libs.reset(
+ new LibraryContainer(
+ makeURL( basic_path, OUSTR("script.xlc") ),
+ getMutex(),
+ getComponentContext() ) );
+ m_dialog_libs.reset(
+ new LibraryContainer(
+ makeURL( basic_path, OUSTR("dialog.xlc") ),
+ getMutex(),
+ getComponentContext() ) );
+ }
+*/
+ }
+}
+
+// XPackageRegistry
+//______________________________________________________________________________
+Sequence< Reference<deployment::XPackageTypeInfo> >
+BackendImpl::getSupportedPackageTypes() throw (RuntimeException)
+{
+ return Sequence< Reference<deployment::XPackageTypeInfo> >(&m_xTypeInfo, 1);
+}
+
+// PackageRegistryBackend
+//______________________________________________________________________________
+Reference<deployment::XPackage> BackendImpl::bindPackage_(
+ OUString const & url, OUString const & mediaType_,
+ Reference<XCommandEnvironment> const & xCmdEnv )
+{
+ OUString mediaType( mediaType_ );
+ if (mediaType.getLength() == 0)
+ {
+ // detect media-type:
+ ::ucbhelper::Content ucbContent;
+ if (create_ucb_content( &ucbContent, url, xCmdEnv ) &&
+ ucbContent.isFolder())
+ {
+ // probe for parcel-descriptor.xml:
+ if (create_ucb_content(
+ 0, makeURL( url, OUSTR("parcel-descriptor.xml") ),
+ xCmdEnv, false /* no throw */ ))
+ {
+ mediaType = OUSTR("application/vnd.sun.star.framework-script");
+ }
+ }
+ if (mediaType.getLength() == 0)
+ throw lang::IllegalArgumentException(
+ StrCannotDetectMediaType::get() + url,
+ static_cast<OWeakObject *>(this), static_cast<sal_Int16>(-1) );
+ }
+
+ String type, subType;
+ INetContentTypeParameterList params;
+ if (INetContentTypes::parse( mediaType, type, subType, &params ))
+ {
+ if (type.EqualsIgnoreCaseAscii("application"))
+ {
+ if (subType.EqualsIgnoreCaseAscii("vnd.sun.star.framework-script"))
+ {
+ OUString lang = OUString::createFromAscii("Script");
+ OUString sParcelDescURL = makeURL(
+ url, OUSTR("parcel-descriptor.xml") );
+
+ ::ucbhelper::Content ucb_content;
+
+ if (create_ucb_content( &ucb_content, sParcelDescURL,
+ xCmdEnv, false /* no throw */ ))
+ {
+ ParcelDescDocHandler* pHandler =
+ new ParcelDescDocHandler();
+ Reference< xml::sax::XDocumentHandler >
+ xDocHandler = pHandler;
+
+ Reference<XComponentContext>
+ xContext( getComponentContext() );
+
+ Reference< xml::sax::XParser > xParser(
+ xContext->getServiceManager()->createInstanceWithContext(
+ OUSTR("com.sun.star.xml.sax.Parser"), xContext ),
+ UNO_QUERY_THROW );
+
+ xParser->setDocumentHandler( xDocHandler );
+ xml::sax::InputSource source;
+ source.aInputStream = ucb_content.openStream();
+ source.sSystemId = ucb_content.getURL();
+ xParser->parseStream( source );
+
+ if ( pHandler->isParsed() )
+ {
+ lang = pHandler->getParcelLanguage();
+ }
+ }
+
+ OUString sfwkLibType = getResourceString( RID_STR_SFWK_LIB );
+ // replace %MACRONAME placeholder with language name
+ OUString MACRONAME( OUSTR("%MACROLANG" ) );
+ sal_Int32 startOfReplace = sfwkLibType.indexOf( MACRONAME );
+ sal_Int32 charsToReplace = MACRONAME.getLength();
+ sfwkLibType = sfwkLibType.replaceAt( startOfReplace, charsToReplace, lang );
+ dp_misc::TRACE("******************************\n");
+ dp_misc::TRACE(OUSTR(" BackEnd detected lang = ") + lang + OUSTR("\n"));
+ dp_misc::TRACE(OUSTR(" for url ") + sParcelDescURL + OUSTR("\n") );
+ dp_misc::TRACE("******************************\n");
+ return new PackageImpl( this, url, sfwkLibType );
+ }
+ }
+ }
+ throw lang::IllegalArgumentException(
+ StrUnsupportedMediaType::get() + mediaType,
+ static_cast<OWeakObject *>(this),
+ static_cast<sal_Int16>(-1) );
+}
+
+//##############################################################################
+
+void BackendImpl::PackageImpl:: initPackageHandler()
+{
+ if (m_xNameCntrPkgHandler.is())
+ return;
+
+ BackendImpl * that = getMyBackend();
+ Any aContext;
+
+ if ( that->m_eContext == CONTEXT_USER )
+ {
+ aContext <<= OUSTR("user");
+ }
+ else if ( that->m_eContext == CONTEXT_SHARED )
+ {
+ aContext <<= OUSTR("share");
+ }
+ else
+ {
+ OSL_ASSERT( 0 );
+ // NOT supported at the momemtn // TODO
+ }
+
+ Reference< provider::XScriptProviderFactory > xFac(
+ that->getComponentContext()->getValueByName(
+ OUSTR( "/singletons/com.sun.star.script.provider.theMasterScriptProviderFactory") ), UNO_QUERY );
+
+ if ( xFac.is() )
+ {
+ Reference< container::XNameContainer > xName( xFac->createScriptProvider( aContext ), UNO_QUERY );
+ if ( xName.is() )
+ {
+ m_xNameCntrPkgHandler.set( xName );
+ }
+ }
+ // TODO what happens if above fails??
+}
+
+// Package
+//______________________________________________________________________________
+beans::Optional< beans::Ambiguous<sal_Bool> >
+BackendImpl::PackageImpl::isRegistered_(
+ ::osl::ResettableMutexGuard &,
+ ::rtl::Reference<AbortChannel> const &,
+ Reference<XCommandEnvironment> const & )
+{
+ return beans::Optional< beans::Ambiguous<sal_Bool> >(
+ true /* IsPresent */,
+ beans::Ambiguous<sal_Bool>(
+ m_xNameCntrPkgHandler.is() && m_xNameCntrPkgHandler->hasByName(
+ m_url ),
+ false /* IsAmbiguous */ ) );
+}
+
+//______________________________________________________________________________
+void BackendImpl::PackageImpl::processPackage_(
+ ::osl::ResettableMutexGuard &,
+ bool doRegisterPackage,
+ ::rtl::Reference<AbortChannel> const &,
+ Reference<XCommandEnvironment> const & )
+{
+ if ( !m_xNameCntrPkgHandler.is() )
+ {
+ dp_misc::TRACE("no package handler!!!!\n");
+ throw RuntimeException( OUSTR("No package Handler " ),
+ Reference< XInterface >() );
+ }
+
+ if (doRegisterPackage)
+ {
+ // will throw if it fails
+ m_xNameCntrPkgHandler->insertByName( m_url, makeAny( Reference< XPackage >(this) ) );
+
+ }
+ else // revokePackage()
+ {
+ m_xNameCntrPkgHandler->removeByName( m_url );
+ }
+}
+
+namespace sdecl = comphelper::service_decl;
+sdecl::class_<BackendImpl, sdecl::with_args<true> > serviceBI;
+extern sdecl::ServiceDecl const serviceDecl(
+ serviceBI,
+ "com.sun.star.comp.deployment.sfwk.PackageRegistryBackend",
+ BACKEND_SERVICE_NAME );
+
+} // namespace sfwk
+} // namespace backend
+} // namespace dp_registry
+
diff --git a/desktop/source/deployment/registry/sfwk/dp_sfwk.hrc b/desktop/source/deployment/registry/sfwk/dp_sfwk.hrc
new file mode 100644
index 000000000000..922affecf252
--- /dev/null
+++ b/desktop/source/deployment/registry/sfwk/dp_sfwk.hrc
@@ -0,0 +1,38 @@
+/*************************************************************************
+ *
+ * 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: dp_sfwk.hrc,v $
+ * $Revision: 1.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.
+ *
+ ************************************************************************/
+
+#if ! defined INCLUDED_DP_SFWK_HRC
+#define INCLUDED_DP_SFWK_HRC
+
+#include "deployment.hrc"
+
+#define RID_STR_SFWK_LIB (RID_DEPLOYMENT_SCRIPT_START+20)
+
+#endif
diff --git a/desktop/source/deployment/registry/sfwk/dp_sfwk.src b/desktop/source/deployment/registry/sfwk/dp_sfwk.src
new file mode 100644
index 000000000000..bd9994693b36
--- /dev/null
+++ b/desktop/source/deployment/registry/sfwk/dp_sfwk.src
@@ -0,0 +1,38 @@
+/*************************************************************************
+ *
+ * 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: dp_sfwk.src,v $
+ * $Revision: 1.6 $
+ *
+ * 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 "dp_sfwk.hrc"
+
+String RID_STR_SFWK_LIB
+{
+ Text [ en-US ] = "%MACROLANG Library";
+};
+
+
diff --git a/desktop/source/deployment/registry/sfwk/makefile.mk b/desktop/source/deployment/registry/sfwk/makefile.mk
new file mode 100644
index 000000000000..2884e7986140
--- /dev/null
+++ b/desktop/source/deployment/registry/sfwk/makefile.mk
@@ -0,0 +1,52 @@
+#*************************************************************************
+#
+# 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.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 = ..$/..$/..$/..
+
+PRJNAME = desktop
+TARGET = deployment_registry_sfwk
+ENABLE_EXCEPTIONS = TRUE
+
+.INCLUDE : settings.mk
+SRS1NAME = $(TARGET)
+
+SRC1FILES = \
+ dp_sfwk.src
+
+INCPRE += ..$/..$/inc
+
+SLOFILES = \
+ $(SLO)$/dp_parceldesc.obj \
+ $(SLO)$/dp_sfwk.obj
+
+.INCLUDE : ..$/..$/target.pmk
+.INCLUDE : target.mk
+
diff --git a/desktop/source/deployment/target.pmk b/desktop/source/deployment/target.pmk
new file mode 100644
index 000000000000..067db401b150
--- /dev/null
+++ b/desktop/source/deployment/target.pmk
@@ -0,0 +1,40 @@
+#*************************************************************************
+#
+# 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: target.pmk,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.
+#
+#*************************************************************************
+
+.IF "$(debug)" != ""
+
+# MSVC: no inlining
+.IF "$(COM)" == "MSC"
+CFLAGS += /Ob0
+.ENDIF
+
+.ENDIF
+
diff --git a/desktop/source/deployment/unopkg/makefile.mk b/desktop/source/deployment/unopkg/makefile.mk
new file mode 100644
index 000000000000..c34f7e18253e
--- /dev/null
+++ b/desktop/source/deployment/unopkg/makefile.mk
@@ -0,0 +1,52 @@
+#*************************************************************************
+#
+# 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 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ = ..$/..$/..
+
+PRJNAME = desktop
+TARGET = deployment_unopkg
+ENABLE_EXCEPTIONS = TRUE
+
+.INCLUDE : settings.mk
+
+.IF "$(SYSTEM_DB)" == "YES"
+CFLAGS+=-DSYSTEM_DB -I$(DB_INCLUDES)
+.ENDIF
+
+SRS1NAME = $(TARGET)
+SRC1FILES = \
+ unopkg.src
+
+SLOFILES =
+
+.INCLUDE : ..$/target.pmk
+.INCLUDE : target.mk
+
diff --git a/desktop/source/deployment/unopkg/unopkg.src b/desktop/source/deployment/unopkg/unopkg.src
new file mode 100644
index 000000000000..bb5be7e8bbd6
--- /dev/null
+++ b/desktop/source/deployment/unopkg/unopkg.src
@@ -0,0 +1,92 @@
+/*************************************************************************
+ *
+ * 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: unopkg.src,v $
+ * $Revision: 1.6 $
+ *
+ * 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 "deployment.hrc"
+
+String RID_STR_UNOPKG_NO_SHARED_ALLOWED
+{
+ Text [ en-US ] = "The option \"--shared\" cannot be used to install the extension \'%NAME\', "
+ "because every user has to agree to the license agreement of the extension. The extension will not be installed.";
+};
+
+String RID_STR_UNOPKG_ACCEPT_LIC_1
+{
+ Text [ en-US ] = "Extension License Agreement:";
+};
+
+String RID_STR_UNOPKG_ACCEPT_LIC_2
+{
+ Text [ en-US ] = "Read the complete License Agreement displayed above. "
+ "Accept the License Agreement by typing \"yes\" on the console "
+ "then press the Return key. Type \"no\" to decline and to abort the "
+ "extension setup.";
+};
+
+String RID_STR_UNOPKG_ACCEPT_LIC_3
+{
+ Text [ en-US ] = "[Enter \"yes\" or \"no\"]:";
+};
+
+String RID_STR_UNOPKG_ACCEPT_LIC_4
+{
+ Text [ en-US ] = "Your input was not correct. Please enter \"yes\" or \"no\":";
+};
+
+String RID_STR_UNOPKG_ACCEPT_LIC_YES
+{
+ Text [ en-US ] = "YES";
+};
+
+String RID_STR_UNOPKG_ACCEPT_LIC_Y
+{
+ Text [ en-US ] = "Y";
+};
+
+String RID_STR_UNOPKG_ACCEPT_LIC_NO
+{
+ Text [ en-US ] = "NO";
+};
+
+String RID_STR_UNOPKG_ACCEPT_LIC_N
+{
+ Text [ en-US ] = "N";
+};
+
+String RID_STR_CONCURRENTINSTANCE
+{
+ Text [ en-US ] = "unopkg cannot be started. The lock file indicates it as already running. "
+ "If this does not apply, delete the lock file at:";
+};
+
+String RID_STR_UNOPKG_ERROR
+{
+ Text [ en-US ] = "ERROR: ";
+};
+